Scsi - Index of
Scsi - Index of Scsi - Index of
1040 /* Interrupt the SCSI-device-scanning thread's time delay, and 1041 * wait for the thread to finish */ 1042 wake_up(&us->scsi_scan_wait); 1043 wait_for_completion(&us->scsi_scan_done); 1044 1045 /* Wait for the current command to finish, then remove the host */ 1046 down(&us->dev_semaphore); 1047 up(&us->dev_semaphore); 1048 scsi_remove_host(us->host); 1049 1050 /* Wait for everything to become idle and release all our resources */ 1051 usb_stor_release_resources(us); 1052 dissociate_dev(us); 1053 } 如果直到现在你还不知道1030 行在干嘛,那我想问一下你他妈的是不是在耍我?虽然 usb_get_intfdata()这个函数的确是第一次露面,但是这里的含义已然是司马昭之心路人皆 知.usb_get_infdata()我们是没有讲过,但是我们讲过usb_set_intfdata().想当年,associate_dev() 中, 我们调用usb_set_intfdata(intf,us),当时我们分析了,这样做的结果就是使得 %intf->dev->driver_data=us,而现在我们调用usb_get_intfdata(intf)的作用就是把us 从中取出 来, 赋给我们这里的临时指针us. 1036 行,全文中唯一一处设置US_FLIDX_DISCONNECTING 这个flag 的地方就在这里. 1037 行, usb_stor_stop_transport(us),这个函数我们可是刚刚才讲过,你别说你就忘记了,就在 command_abort()里调用的.目的就是停掉当前的urb 和sg,如果有的话. 1038 行, wake_up(&us->dev_reset_wait),我们也已经讲过了,就是在讲device_reset()讲到的, 当时在usb_stor_reset_common()中,会使用wait_event_interruptible_timeout()来进入睡眠,睡眠 的目的是给6 秒钟来让设备从reset 状态恢复过来,但是如果在这期间我们要断开设备了,那么当然就没有 必要再让那边继续睡眠了,设备都要断开了,还有什么恢复的意义呢?所以对于这种情况,我们回过头来看 usb_stor_reset_common(),会发现之后该函数立马从睡眠中醒来,然后清除掉为reset 而设置的 flag,US_FLIDX_RESETTING,然后就返回了,返回值是FAILED. 1042 行, wake_up(&us->scsi_scan_wait),和上面这种情况几乎相同,不同的是这次唤醒的是 usb_stor_scan_thread,这个函数里边也会因为delay_use 的设置而调用 wait_event_interrruptible_timeout 去等待去睡眠,所以这里机理是一样的.而与此同时,1043 行, wait_for_completion(&us->scsi_scan_done),恰恰是是等待对方的结束,我们注意到,在 usb_stor_scan_thread()中最后一句话, complete_and_exit(&us->scsi_scan_done, 0),即唤醒咱 们这里这个storage_disconnect()同时结束它自己.应该说这样就实现了一个同步机制.就是说因为我们 195 之后马上要做的就是清理门户了,把一些不要的资源都释放掉,所以我们首先必须保证我们的进程都退出来, 资源都不再被人使用,这样我们才可以放心的去做我们的清理工作. 1048 行,scsi_remove_host()被调用,这是和最早的scsi_add_host 相对应的.都是调用scsi core 提 供的函数. 1051 行,usb_stor_release_resources(us),这个则是和我们当初那个 usb_stor_acquire_resources(us)相对应.而1052 行的dissociate_dev(us)则是和当初那个
associate_dev()相对应.我们来看一下具体代码,来自drivers/usb/storage/usb.c,把这两个函数的代 码都一并贴出来: 815 /* Release all our dynamic resources */ 816 void usb_stor_release_resources(struct us_data *us) 817 { 818 US_DEBUGP("-- %s\n", __FUNCTION__); 819 820 /* Kill the control thread. The SCSI host must already have been 821 * removed so it won't try to queue any more commands. 822 */ 823 if (us->pid) { 824 825 /* Wait for the thread to be idle */ 826 down(&us->dev_semaphore); 827 US_DEBUGP("-- sending exit command to thread\n"); 828 829 /* If the SCSI midlayer queued a final command just before 830 * scsi_remove_host() was called, us->srb might not be 831 * NULL. We can overwrite it safely, because the midlayer 832 * will not wait for the command to finish. Also the 833 * control thread will already have been awakened. 834 * That's okay, an extra up() on us->sema won't hurt. 835 * 836 * Enqueue the command, wake up the thread, and wait for 837 * notification that it has exited. 838 */ 839 scsi_lock(us->host); 840 us->srb = NULL; 841 scsi_unlock(us->host); 842 up(&us->dev_semaphore); 843 844 up(&us->sema); 845 wait_for_completion(&us->notify); 846 } 847 848 /* Call the destructor routine, if it exists */ 196 849 if (us->extra_destructor) { 850 US_DEBUGP("-- calling extra_destructor()\n"); 851 us->extra_destructor(us->extra); 852 } 853 854 /* Finish the host removal sequence */ 855 if (us->host)
- Page 141 and 142: 请求,所以这里就判断abort
- Page 143 and 144: 112 case GPCMD_READ_HEADER: what =
- Page 145 and 146: 到北京,每每只有在夜深人
- Page 147 and 148: 580 /* 581 * If we have a failure,
- Page 149 and 150: 666 memcpy(srb->cmnd, old_cmnd, MAX
- Page 151 and 152: 950 struct bulk_cb_wrap *bcb = (str
- Page 153 and 154: 1034 /* get the status again */ 103
- Page 155 and 156: 426 /* store the actual length of t
- Page 157 and 158: 后她会给host 返回一个CSW.CB
- Page 159 and 160: 296 } 297 298 US_DEBUGP("-- transfe
- Page 161 and 162: 491 * scatter-gather or not, and ac
- Page 163 and 164: 迷雾重重的 Bulk 传输(五) us
- Page 165 and 166: 然后把她赋给了result.而us->
- Page 167 and 168: 而bcs->Status,标志命令执行
- Page 169 and 170: 就必须设置US_FL_IGNORE_RESIDUE
- Page 171 and 172: 485 }; 486 这是一个字符数组
- Page 173 and 174: srb->sense_buffer 里边的东西.S
- Page 175 and 176: 一个类似的函数,名叫usb_sto
- Page 177 and 178: 这种命令应该由mid level 来
- Page 179 and 180: Disk /dev/sda: 146.1 GB, 1461631057
- Page 181 and 182: through to the most significant bit
- Page 183 and 184: 1192 USB_TYPE_CLASS | USB_RECIP_INT
- Page 185 and 186: 315 行,scsi_report_device_reset(),
- Page 187 and 188: 285 US_DEBUGP("No reset during disc
- Page 189 and 190: 229 /* Wait for the aborted command
- Page 191: 两个函数中需要判断它,一
- Page 195 and 196: 束for 死循环,从而usb_stor_con
- Page 197 and 198: 317 for (i = 1; i < us->host->max_i
associate_dev()相对应.我们来看一下具体代码,来自drivers/usb/storage/usb.c,把这两个函数的代<br />
码都一并贴出来:<br />
815 /* Release all our dynamic resources */<br />
816 void usb_stor_release_resources(struct us_data *us)<br />
817 {<br />
818 US_DEBUGP("-- %s\n", __FUNCTION__);<br />
819<br />
820 /* Kill the control thread. The SCSI host must already have been<br />
821 * removed so it won't try to queue any more commands.<br />
822 */<br />
823 if (us->pid) {<br />
824<br />
825 /* Wait for the thread to be idle */<br />
826 down(&us->dev_semaphore);<br />
827 US_DEBUGP("-- sending exit command to thread\n");<br />
828<br />
829 /* If the SCSI midlayer queued a final command just before<br />
830 * scsi_remove_host() was called, us->srb might not be<br />
831 * NULL. We can overwrite it safely, because the midlayer<br />
832 * will not wait for the command to finish. Also the<br />
833 * control thread will already have been awakened.<br />
834 * That's okay, an extra up() on us->sema won't hurt.<br />
835 *<br />
836 * Enqueue the command, wake up the thread, and wait for<br />
837 * notification that it has exited.<br />
838 */<br />
839 scsi_lock(us->host);<br />
840 us->srb = NULL;<br />
841 scsi_unlock(us->host);<br />
842 up(&us->dev_semaphore);<br />
843<br />
844 up(&us->sema);<br />
845 wait_for_completion(&us->notify);<br />
846 }<br />
847<br />
848 /* Call the destructor routine, if it exists */<br />
196<br />
849 if (us->extra_destructor) {<br />
850 US_DEBUGP("-- calling extra_destructor()\n");<br />
851 us->extra_destructor(us->extra);<br />
852 }<br />
853<br />
854 /* Finish the host removal sequence */<br />
855 if (us->host)