Scsi - Index of
Scsi - Index of Scsi - Index of
至此,get_pipes函数结束了,信息都保存到了us里面.下面us该发挥她的作用了.回到storage_probe() 函数,998行,把us作为参数传递给了usb_stor_acquire_resources()函数.而这个函数才是故事的高潮. 每一个有识之士在看过这个函数之后就会豁然开朗,都会感慨,一下子就看到了春天,看到了光明,原来 Linux 中的设备驱动程序就是这么工作的啊! 996 997 /* Acquire all the other resources and add the host */ 998 result = usb_stor_acquire_resources(us); 999 if (result) 1000 goto BadDevice; 1001 result = scsi_add_host(us->host, &intf->dev); 1002 if (result) { 1003 printk(KERN_WARNING USB_STORAGE 1004 "Unable to add the scsi host\n"); 1005 goto BadDevice; 1006 } 我们来看usb_stor_acquire_resources 函数.它被定义于drivers/usb/storage/usb.c 中: 755 /* Initialize all the dynamic resources we need */ 756 static int usb_stor_acquire_resources(struct us_data *us) 757 { 758 int p; 759 760 us->current_urb = usb_alloc_urb(0, GFP_KERNEL); 761 if (!us->current_urb) { 762 US_DEBUGP("URB allocation failed\n"); 763 return -ENOMEM; 62 764 } 765 766 /* Lock the device while we carry out the next two operations */ 767 down(&us->dev_semaphore); 768 769 /* For bulk-only devices, determine the max LUN value */ 770 if (us->protocol == US_PR_BULK) { 771 p = usb_stor_Bulk_max_lun(us); 772 if (p < 0) { 773 up(&us->dev_semaphore); 774 return p; 775 } 776 us->max_lun = p; 777 } 778 779 /* Just before we start our control thread, initialize 780 * the device if it needs initialization */ 781 if (us->unusual_dev->initFunction)
782 us->unusual_dev->initFunction(us); 783 784 up(&us->dev_semaphore); 785 786 /* 787 * Since this is a new device, we need to register a SCSI 788 * host definition with the higher SCSI layers. 789 */ 790 us->host = scsi_host_alloc(&usb_stor_host_template, sizeof(us)); 791 if (!us->host) { 792 printk(KERN_WARNING USB_STORAGE 793 "Unable to allocate the scsi host\n"); 794 return -EBUSY; 795 } 796 797 /* Set the hostdata to prepare for scanning */ 798 us->host->hostdata[0] = (unsigned long) us; 799 800 /* Start up our control thread */ 801 p = kernel_thread(usb_stor_control_thread, us, CLONE_VM); 802 if (p < 0) { 803 printk(KERN_WARNING USB_STORAGE 804 "Unable to start control thread\n"); 805 return p; 806 } 807 us->pid = p; 63 808 809 /* Wait for the thread to start */ 810 wait_for_completion(&(us->notify)); 811 812 return 0; 813 } 待到山花浪漫时,她在丛中笑.一个悟性高的人应该一眼就能从这个函数中找出那行在丛中笑的代码来, 没错,她就是801 行,kernel_thread,这个函数造就了许多的经典的Linux 内核模块,正是因为她的存 在,Linux 中某些设备驱动程序的编写变得非常简单.可以说,对某些设备驱动程序来说,kernel_thread 几 乎是整个driver 的灵魂,或者说是该Linux 内核模块的灵魂.不管她隐藏的多么深,她总像漆黑中的萤火虫, 那样的鲜明,那样的出众.甚至不夸张的说,对于很多模块来说,只要找到kernel_thread 这一行,基本上你 就 知道这个模块是怎么工作的了.
- Page 13 and 14: 只 是一个usb 接口.这些口
- Page 15 and 16: 中也定义了这么一些数据
- Page 17 and 18: 511 * @driver: the driver model cor
- Page 19 and 20: 233 .owner = THIS_MODULE, 234 .name
- Page 21 and 22: 91 * construct these entries. Each
- Page 23 and 24: 324 struct usb_host_config *actconf
- Page 25 and 26: 22 88 * @class_dev: driver model's
- Page 27 and 28: 必须给各个地方取名,完了
- Page 29 and 30: 26 136 trans_cmnd transport; /* tra
- Page 31 and 32: 944 init_MUTEX_LOCKED(&(us->sema));
- Page 33 and 34: 147 #if !defined(CONFIG_BLK_DEV_UB)
- Page 35 and 36: 124 #define USB_DEVICE_ID_MATCH_DEV
- Page 37 and 38: intf 来代替. us 之所以重要,
- Page 39 and 40: 睡眠,那就得用GPF_ATOMIC,这
- Page 41 and 42: 504 if (msg >= 0 && !(unusual_dev->
- Page 43 and 44: 179 } 180 181 static struct us_unus
- Page 45 and 46: 711 /* Submitted by Hartmut Wahl */
- Page 47 and 48: 3. useProtocol 为US_SC_DEVICE, use
- Page 49 and 50: Bus 004 Device 001: ID 0000:0000 Bu
- Page 51 and 52: 993 result = get_pipes(us); 994 if
- Page 53 and 54: 631 us->transport_reset = usb_stor_
- Page 55 and 56: 659 us->max_lun = 0; 660 break; 661
- Page 57 and 58: 740 /* Calculate and store the pipe
- Page 59 and 60: storage 会有两个bulk 端点,用
- Page 61 and 62: 比如说,复旦大学,有一个主
- Page 63: 1079 #define PIPE_ISOCHRONOUS 0 108
- Page 67 and 68: 630 * each frame is in the fields o
- Page 69 and 70: 716 * Bulk URBs may 717 * use the U
- Page 71 and 72: 802 int number_of_packets; /* (in)
- Page 73 and 74: 先说互斥锁.它诞生于这样
- Page 75 and 76: 920 US_DEBUGP("GetMaxLUN command re
- Page 77 and 78: 148 /* set up data structures for t
- Page 79 and 80: 90 * @wValue: matches the USB wValu
- Page 81 and 82: 830 void *transfer_buffer, 831 int
- Page 83 and 84: 25 { 26 x->done = 0; 27 init_waitqu
- Page 85 and 86: 都会过期,我开始怀疑,在这
- Page 87 and 88: 是实际长度,要么就是不成
- Page 89 and 90: 87 258 行,usb_pipeendpoint,定义
- Page 91 and 92: 对爱你的人掘了一条无法
- Page 93 and 94: Type: Direct-Access ANSI SCSI revis
- Page 95 and 96: 416 /* 417 * this defines our host
- Page 97 and 98: 69 * Ioctl interface 70 * 71 * Stat
- Page 99 and 100: 155 * "is this a new device" checks
- Page 101 and 102: 241 char *proc_name; 242 243 /* 244
- Page 103 and 104: 328 * True if the low-level driver
- Page 105 and 106: 可以看到这个函数的参数
- Page 107 and 108: 451 short unsigned int max_sectors;
- Page 109 and 110: 地 说明了为啥咱们要显式
- Page 111 and 112: usb_stor_acquire_resources()函数
- Page 113 and 114: 341 } 342 343 /* reject if target !
至此,get_pipes函数结束了,信息都保存到了us里面.下面us该发挥她的作用了.回到storage_probe()<br />
函数,998行,把us作为参数传递给了usb_stor_acquire_resources()函数.而这个函数才是故事的高潮.<br />
每一个有识之士在看过这个函数之后就会豁然开朗,都会感慨,一下子就看到了春天,看到了光明,原来<br />
Linux 中的设备驱动程序就是这么工作的啊!<br />
996<br />
997 /* Acquire all the other resources and add the host */<br />
998 result = usb_stor_acquire_resources(us);<br />
999 if (result)<br />
1000 goto BadDevice;<br />
1001 result = scsi_add_host(us->host, &intf->dev);<br />
1002 if (result) {<br />
1003 printk(KERN_WARNING USB_STORAGE<br />
1004 "Unable to add the scsi host\n");<br />
1005 goto BadDevice;<br />
1006 }<br />
我们来看usb_stor_acquire_resources 函数.它被定义于drivers/usb/storage/usb.c 中:<br />
755 /* Initialize all the dynamic resources we need */<br />
756 static int usb_stor_acquire_resources(struct us_data *us)<br />
757 {<br />
758 int p;<br />
759<br />
760 us->current_urb = usb_alloc_urb(0, GFP_KERNEL);<br />
761 if (!us->current_urb) {<br />
762 US_DEBUGP("URB allocation failed\n");<br />
763 return -ENOMEM;<br />
62<br />
764 }<br />
765<br />
766 /* Lock the device while we carry out the next two operations */<br />
767 down(&us->dev_semaphore);<br />
768<br />
769 /* For bulk-only devices, determine the max LUN value */<br />
770 if (us->protocol == US_PR_BULK) {<br />
771 p = usb_stor_Bulk_max_lun(us);<br />
772 if (p < 0) {<br />
773 up(&us->dev_semaphore);<br />
774 return p;<br />
775 }<br />
776 us->max_lun = p;<br />
777 }<br />
778<br />
779 /* Just before we start our control thread, initialize<br />
780 * the device if it needs initialization */<br />
781 if (us->unusual_dev->initFunction)