Scsi - Index of
Scsi - Index of Scsi - Index of
看出区别了吗?没错,最下面多了一项,这是一个Leidisk 生产的U盘.这里本没有一个真实的host,但是写 代码的高手们却让你觉得也许似乎大概有,甚至连scsi core 都被欺骗了一样.那么这些高手们是如何实现 的呢?让我们来慢慢的看,让我们来看看这个神奇的host 究竟是如何出现的,看看它是否像如今的房价一 样, 是否像林志玲的胸一样,看着坚挺,实际里面全是泡沫... 谁是最变态的结构体 scsi 子系统里的设备使用scsi 命令来通信,scsi spec 定义了一大堆的命令,spec 里称这个为命令集,即 所谓的command set.其中一些命令是每一个scsi 设备都必须支持的,另一些命令则是可选的.而作为U 盘,它所支持的是scsi transparent command set,所以它基本上就是支持所有的scsi 命令了,不过我们 其实并不关心任何一个具体的命令,只需要了解一些最基本的命令就是了.比如我们需要知道,所有的scsi 设备都至少需要支持以下这四个scsi 命令:INQUIRY,REQUEST SENSE,SEND DIAGNOSTIC,TEST UNIT READY.一会我们在代码中会遇见其中的几个,暂且不表.另外对于磁盘设备,它还需要支持另外一些 命令,比如读方面的READ 命令,写方面的WRITE 命令,又比如我们经常做的格式化操作,它就对应 FORMAT UNIT 命令.对于磁盘这样的设备,SCSI 协议里边称它为direct-access devices.这就是为什么 你刚才在cat /proc/scsi/scsi 的输出中能看到一个”Type:Direct-Access”这么一项. 知道了scsi 总线上使用scsi 命令来通信,那么我们下一步需要知道scsi host 的作用,它主要就是负责发 送命令给设备,然后设备就去执行命令.所以scsi host 也被称为initiator(发起者),而scsi 设备被称为 target(目的地). 那么我们就知道,如果我们没有scsi host,但是我们有遵守scsi 协议接受scsi 命令的device,那怎么办? 谁来发起命令?没有硬件我们用软件,命令是谁传递过来的?应用层?或者scsi core?不管是谁,只要我们能 够把上层的命令传递给设备,那就Ok 了对不对?scsi 核心层把一切都做好了,我们只要为一个scsi host 申 请相应的数据结构,让命令来了能够发送给设备,能够让设备接收到命令,那就万事大吉了对不对?或者说整 个usb-storage 的真正的功能也就实现了对不对?到这里我们就可以开始继续来看我们的代码了.别忘了 我们还在usb_stor_acquire_resources()函数中,只不过刚刚讲完usb_stor_Bulk_max_lun()函数而 已. 781 行,us->unusual_dev->initFunction 是什么?不要说你一点印象也没有.在分析 unusual_devs.h 文件的时候曾经专门举过例子的,说有些设备需要一些初始化函数,它就定义在 unusual_devs.h 文件中,而我们通过UNUSUAL_DEV 的定义已经把这些初始化函数给赋给了 us->unusual_dev 的initFunction 指针了.所以这时候,在传输开始之前,我们判断,是不是有这样一个函 数,即这个函数指针是否为空,如果不为空,很好办,执行这个函数就是了.比如当时我们举例子的时候说的那 两个惠普的CD 刻录机就有个初始化函数init_8200e,那么就让它执行好了.当然,一般的设备肯定不需要 这么一个函数.至于传递给这个函数的参数,在struct us_unusual_dev 结构体定义的时候,就把这个函数 需要什么样的参数定义好了,需要的就是一个struct us_data *,那么很自然,传递的就是us. 然后790 行,scsi_host_alloc 就是scsi 子系统提供的函数,它的作用就是申请一个scsi host 相应的数 据结构.不过我们要注意的是它的参数,尤其是第一个参数, &usb_stor_host_template,其实这是一个 93 struct scsi_host_template 的结构体指针,从这一刻开始,我们需要开始了解 drivers/usb/storage/scsiglue.c 这个文件了,glue 就是胶水的意思,与scsi 相关联的代码我们就都准 备 在这个文件里了. usb_stor_host_template 的定义就在drivers/usb/storage/scsiglue.c 中,
416 /* 417 * this defines our host template, with which we'll allocate hosts 418 */ 419 420 struct scsi_host_template usb_stor_host_template = { 421 /* basic userland interface stuff */ 422 .name = "usb-storage", 423 .proc_name = "usb-storage", 424 .proc_info = proc_info, 425 .info = host_info, 426 427 /* command interface -- queued only */ 428 .queuecommand = queuecommand, 429 430 /* error and abort handlers */ 431 .eh_abort_handler = command_abort, 432 .eh_device_reset_handler = device_reset, 433 .eh_bus_reset_handler = bus_reset, 434 435 /* queue commands only, only one command per LUN */ 436 .can_queue = 1, 437 .cmd_per_lun = 1, 438 439 /* unknown initiator id */ 440 .this_id = -1, 441 442 .slave_alloc = slave_alloc, 443 .slave_configure = slave_configure, 444 445 /* lots of sg segments can be handled */ 446 .sg_tablesize = SG_ALL, 447 448 /* limit the total size of a transfer to 120 KB */ 449 .max_sectors = 240, 450 451 /* merge commands... this seems to help performance, but 452 * periodically someone should test to see which setting is more 453 * optimal. 454 */ 94 455 .use_clustering = 1, 456 456 457 /* emulated HBA */
- 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 and 64: 1079 #define PIPE_ISOCHRONOUS 0 108
- Page 65 and 66: 782 us->unusual_dev->initFunction(u
- 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: Type: Direct-Access ANSI SCSI revis
- 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 !
- Page 115 and 116: 内核的核心位置,kernel/exit.c
- Page 117 and 118: 1023 dissociate_dev(us); 1024 retur
- Page 119 and 120: 917 行,再次判断设备有没有
- Page 121 and 122: 181 182 /* fail the command if we a
- Page 123 and 124: 83 struct timer_list eh_timeout; /*
- Page 125 and 126: 123 两个scsi_done,一个是struct
- Page 127 and 128: 56 jiffie count on our counter, the
- Page 129 and 130: 中 看到如下的定义: UNUSUAL_
- Page 131 and 132: 269 memcpy(data+16, us->unusual_dev
- Page 133 and 134: 一切准备好了之后,我们就
- Page 135 and 136: 238 (sg->offset + *offset) & (PAGE_
- Page 137 and 138: 所以对于那些不能相应INQUI
- Page 139 and 140: 239 行对unsigned int sglen 赋值
- Page 141 and 142: 请求,所以这里就判断abort
- Page 143 and 144: 112 case GPCMD_READ_HEADER: what =
416 /*<br />
417 * this defines our host template, with which we'll allocate hosts<br />
418 */<br />
419<br />
420 struct scsi_host_template usb_stor_host_template = {<br />
421 /* basic userland interface stuff */<br />
422 .name = "usb-storage",<br />
423 .proc_name = "usb-storage",<br />
424 .proc_info = proc_info,<br />
425 .info = host_info,<br />
426<br />
427 /* command interface -- queued only */<br />
428 .queuecommand = queuecommand,<br />
429<br />
430 /* error and abort handlers */<br />
431 .eh_abort_handler = command_abort,<br />
432 .eh_device_reset_handler = device_reset,<br />
433 .eh_bus_reset_handler = bus_reset,<br />
434<br />
435 /* queue commands only, only one command per LUN */<br />
436 .can_queue = 1,<br />
437 .cmd_per_lun = 1,<br />
438<br />
439 /* unknown initiator id */<br />
440 .this_id = -1,<br />
441<br />
442 .slave_alloc = slave_alloc,<br />
443 .slave_configure = slave_configure,<br />
444<br />
445 /* lots <strong>of</strong> sg segments can be handled */<br />
446 .sg_tablesize = SG_ALL,<br />
447<br />
448 /* limit the total size <strong>of</strong> a transfer to 120 KB */<br />
449 .max_sectors = 240,<br />
450<br />
451 /* merge commands... this seems to help performance, but<br />
452 * periodically someone should test to see which setting is more<br />
453 * optimal.<br />
454 */<br />
94<br />
455 .use_clustering = 1,<br />
456<br />
456<br />
457 /* emulated HBA */