|
发表于 2006-7-26 16:28:01
|
显示全部楼层
我想请问一下 ,在LINUX-2.6.11的USB 驱动程序中, 当你插入一个U盘进行识别时,会调用usb/storage/usb.c中usb_stor_acquire_resource 函数,该函数定义如下:
/* Initialize all the dynamic resources we need */
static int usb_stor_acquire_resources(struct us_data *us)
{
int p;
us->current_urb = usb_alloc_urb(0, GFP_KERNEL); //分配URB结构对象空间
if (!us->current_urb) {
US_DEBUGP("URB allocation failed\n");
return -ENOMEM;
}
/* Lock the device while we carry out the next two operations */
down(&us->dev_semaphore);
/* For bulk-only devices, determine the max LUN value */
if (us->protocol == US_PR_BULK) {
p = usb_stor_Bulk_max_lun(us);
if (p < 0) {
up(&us->dev_semaphore);
return p;
}
us->max_lun = p;
}
/* Just before we start our control thread, initialize
* the device if it needs initialization */
if (us->unusual_dev->initFunction)
us->unusual_dev->initFunction(us);
up(&us->dev_semaphore);
/*
* Since this is a new device, we need to register a SCSI
* host definition with the higher SCSI layers.
*/
us->host = scsi_host_alloc(&usb_stor_host_template, sizeof(us));
if (!us->host) {
printk(KERN_WARNING USB_STORAGE
"Unable to allocate the scsi host\n");
return -EBUSY;
}
/* Set the hostdata to prepare for scanning */
us->host->hostdata[0] = (unsigned long) us;
/* Start up our control thread */
p = kernel_thread(usb_stor_control_thread, us, CLONE_VM);
if (p < 0) {
printk(KERN_WARNING USB_STORAGE
"Unable to start control thread\n");
return p;
}
us->pid = p;
/* Wait for the thread to start */
wait_for_completion(&(us->notify));
return 0;
}
这个函数定义中有这么一步:
p = usb_stor_Bulk_max_lun(us);
注释说这主要是对批量的设备(U盘等),得到最大逻辑单元值.我查了一下,好象在SCSI协议模型中,每个逻辑单元用来操作SCSI设备,但还是不是很懂.
请问各位高手,LUN到底是什么东西,有什么用?在USB识别过程中获取LUN值有什么用啊?
为什么我多数U盘获得的LUN值都是0呢?
usb_stor_Bulk_max_lun函数在usb/storage/transport.c中定义为
/*
* Bulk only transport
*/
/* Determine what the maximum LUN supported is */
int usb_stor_Bulk_max_lun(struct us_data *us)
{
int result;
/* issue the command */
result = usb_stor_control_msg(us, us->recv_ctrl_pipe,
US_BULK_GET_MAX_LUN,
USB_DIR_IN | USB_TYPE_CLASS |
USB_RECIP_INTERFACE,
0, us->ifnum, us->iobuf, 1, HZ);
US_DEBUGP("GetMaxLUN command result is %d, data is %d\n",
result, us->iobuf[0]);
/* if we have a successful request, return the result */
if (result > 0)
return us->iobuf[0];
/*
* Some devices (i.e. Iomega Zip100) need this -- apparently
* the bulk pipes get STALLed when the GetMaxLUN request is
* processed. This is, in theory, harmless to all other devices
* (regardless of if they stall or not).
*/
if (result == -EPIPE) {
usb_stor_clear_halt(us, us->recv_bulk_pipe);
usb_stor_clear_halt(us, us->send_bulk_pipe);
}
/*
* Some devices don't like GetMaxLUN. They may STALL the control
* pipe, they may return a zero-length result, they may do nothing at
* all and timeout, or they may fail in even more bizarrely creative
* ways. In these cases the best approach is to use the default
* value: only one LUN.
*/
return 0;
} |
|