Scsi - Index of

Scsi - Index of Scsi - Index of

07.06.2013 Views

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)

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)

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!