diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_txrxif.c b/drivers/aic8800/aic8800_fdrv/aicwf_txrxif.c index c15dcf6..b8795bf 100644 --- a/drivers/aic8800/aic8800_fdrv/aicwf_txrxif.c +++ b/drivers/aic8800/aic8800_fdrv/aicwf_txrxif.c @@ -210,11 +210,8 @@ void aicwf_bus_deinit(struct device *dev) AICWFDBG(LOGINFO, "%s Enter\r\n", __func__); bus_if = dev_get_drvdata(dev); - /* 入口判空:本函数在探测失败路径上会被调用**两次** - * aicwf_bus_init() 的 `fail:` 先调一次,随后 aicwf_usb_probe() 的 - * `out_free_bus:` 再调一次(用局部 bus_if 做 kfree,不依赖 drvdata)。 - * 第二次进入时 drvdata 已在**上一次调用的末尾**被清空 → 必然命中本判空。 - * 若不清空,第二次会对已完整拆解的对象重复执行整套 teardown。 */ + /* Probe rollback can call deinit again after aicwf_bus_init() fails. + * A completed teardown clears drvdata so sequential calls are harmless. */ if (!bus_if) { AICWFDBG(LOGINFO, "%s: already deinitialized, skip\n", __func__); return; @@ -269,18 +266,9 @@ void aicwf_bus_deinit(struct device *dev) tasklet_kill(&usb->xmit_tasklet); #endif - /* 清空 drvdata:全部拆解完成之后、对象由调用方释放之前。 - * (评审 shenmintao/aic8800d80#103 指出的顺序问题:此前清空点位于 - * bus_stop 之后、URB/platform/rx/cmd 拆解与 TX 线程 join 之前。) - * 1) 顺序双 deinit:第二次调用靠上方入口判空在本行之后必然 skip; - * 2) 过早清空会伤害仍在运行的读者——TX 链 - * usb_bustx_thread → aicwf_bus_txdata(usbdev->bus_if) → - * ops->txdata = aicwf_usb_bus_txdata()(usb.c 在该处重读 - * dev_get_drvdata)仅靠 state 检查做 check-then-act、无锁, - * 且该线程直到上方 kthread_stop(bustx_thread) 才被 join—— - * 必须先 join 再清; - * 3) cmd/rx/platform 拆解与 rwnx_close() 等读者在本行之前全程 - * 看到非空 drvdata,行为与未打补丁树一致。 */ + /* Keep drvdata valid through platform callbacks, the TX thread join, + * and RX/command teardown. Clear it only after these users have stopped. + * The caller still serializes teardown and frees the bus object. */ dev_set_drvdata(dev, NULL); AICWFDBG(LOGINFO, "%s Exit \n", __func__); diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_usb.c b/drivers/aic8800/aic8800_fdrv/aicwf_usb.c index 63dc94f..b0ceb87 100644 --- a/drivers/aic8800/aic8800_fdrv/aicwf_usb.c +++ b/drivers/aic8800/aic8800_fdrv/aicwf_usb.c @@ -1409,9 +1409,7 @@ static int aicwf_usb_bus_txmsg(struct device *dev, u8 *buf, u32 len) { int ret = 0; struct aicwf_bus *bus_if = dev_get_drvdata(dev); - /* Defense in depth (review #103): with the parent commit's ordering the - * cmd thread is quiesced before drvdata is cleared, so this should be - * unreachable — guard anyway against a future/premature caller. */ + /* Normal command teardown keeps drvdata valid until its users stop. */ if (bus_if == NULL) return -ENODEV; struct aic_usb_dev *usb_dev = bus_if->bus_priv.usb; @@ -1672,8 +1670,7 @@ static int aicwf_usb_bus_txdata(struct device *dev, struct sk_buff *pkt) uint prio; int ret = -EBADE; struct aicwf_bus *bus_if = dev_get_drvdata(dev); - /* Defense in depth (review #103): usb_bustx_thread is joined before - * drvdata is cleared; guard any other/premature caller. */ + /* Reject a TX callback without an attached bus. */ if (bus_if == NULL) return -ENODEV; struct aic_usb_dev *usbdev = bus_if->bus_priv.usb; @@ -1712,8 +1709,7 @@ static int aicwf_usb_bus_txdata(struct device *dev, struct sk_buff *skb) int ret = 0; unsigned long flags; struct aicwf_bus *bus_if = dev_get_drvdata(dev); - /* Defense in depth (review #103): usb_bustx_thread is joined before - * drvdata is cleared; guard any other/premature caller. */ + /* Reject a TX callback without an attached bus. */ if (bus_if == NULL) return -ENODEV; struct aic_usb_dev *usb_dev = bus_if->bus_priv.usb; @@ -1962,9 +1958,7 @@ static void aicwf_usb_bus_stop(struct device *dev) struct aic_usb_dev *usb_dev; AICWFDBG(LOGINFO, "%s\r\n", __func__); - /* 正常时序下 aicwf_bus_init() 已 set_drvdata、且 aicwf_bus_deinit() - * 调到本函数时 drvdata 尚未清空(清空在 deinit 末尾),故此处应非空; - * 判空为纵深防御:覆盖 probe 早期失败(set_drvdata 之前)等异常来源。 */ + /* Normal teardown clears drvdata after stop and the remaining cleanup. */ if (bus_if == NULL) return; usb_dev = bus_if->bus_priv.usb; diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_main.c b/drivers/aic8800/aic8800_fdrv/rwnx_main.c index 4e9c534..8e2207f 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_main.c +++ b/drivers/aic8800/aic8800_fdrv/rwnx_main.c @@ -1666,11 +1666,9 @@ static int rwnx_close(struct net_device *dev) rwnx_ipc_tx_drain(rwnx_hw); #else #if defined(AICWF_USB_SUPPORT) - /* 002 在 deinit 时摘 drvdata,disconnect→close 时序下本函数读到 - * usbdev=NULL:实测断开在此裸解引用 usbdev->bus_if 崩溃 - * (rwnx_close 偏移处 reloc=rwnx_send_reset,CR2=0x8)。 - * 上游 usbdev 为悬挂非空、此条件求值为假而侥幸跳过——本判空 - * 对两种情形给出同一语义:bus 已断 → 跳过 reset/重配。 */ + /* Skip firmware reset if no bus is attached or the device is down. + * Normal USB unregister calls close during platform teardown, + * before drvdata is cleared; also guard other close paths. */ if (usbdev != NULL && usbdev->bus_if != NULL && usbdev->bus_if->state != BUS_DOWN_ST && usbdev->state != USB_DOWN_ST) #else