|
|
|
@ -204,6 +204,22 @@ int usb_stor_info(void) |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static unsigned int usb_get_max_lun(struct us_data *us) |
|
|
|
|
{ |
|
|
|
|
int len; |
|
|
|
|
unsigned char result; |
|
|
|
|
len = usb_control_msg(us->pusb_dev, |
|
|
|
|
usb_rcvctrlpipe(us->pusb_dev, 0), |
|
|
|
|
US_BBB_GET_MAX_LUN, |
|
|
|
|
USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, |
|
|
|
|
0, us->ifnum, |
|
|
|
|
&result, sizeof(result), |
|
|
|
|
USB_CNTL_TIMEOUT * 5); |
|
|
|
|
USB_STOR_PRINTF("Get Max LUN -> len = %i, result = %i\n", |
|
|
|
|
len, (int) result); |
|
|
|
|
return (len > 0) ? result : 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*******************************************************************************
|
|
|
|
|
* scan the usb and reports device info |
|
|
|
|
* to the user if mode = 1 |
|
|
|
@ -241,13 +257,22 @@ int usb_stor_scan(int mode) |
|
|
|
|
break; /* no more devices avaiable */ |
|
|
|
|
|
|
|
|
|
if (usb_storage_probe(dev, 0, &usb_stor[usb_max_devs])) { |
|
|
|
|
/* ok, it is a storage devices
|
|
|
|
|
* get info and fill it in |
|
|
|
|
/* OK, it's a storage device. Iterate over its LUNs
|
|
|
|
|
* and populate `usb_dev_desc'. |
|
|
|
|
*/ |
|
|
|
|
if (usb_stor_get_info(dev, &usb_stor[usb_max_devs], |
|
|
|
|
&usb_dev_desc[usb_max_devs]) == 1) |
|
|
|
|
int lun, max_lun, start = usb_max_devs; |
|
|
|
|
|
|
|
|
|
max_lun = usb_get_max_lun(&usb_stor[usb_max_devs]); |
|
|
|
|
for (lun = 0; |
|
|
|
|
lun <= max_lun && usb_max_devs < USB_MAX_STOR_DEV; |
|
|
|
|
lun++) { |
|
|
|
|
usb_dev_desc[usb_max_devs].lun = lun; |
|
|
|
|
if (usb_stor_get_info(dev, &usb_stor[start], |
|
|
|
|
&usb_dev_desc[usb_max_devs]) == 1) { |
|
|
|
|
usb_max_devs++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
/* if storage device */ |
|
|
|
|
if (usb_max_devs == USB_MAX_STOR_DEV) { |
|
|
|
|
printf("max USB Storage Device reached: %d stopping\n", |
|
|
|
@ -882,6 +907,7 @@ static int usb_inquiry(ccb *srb, struct us_data *ss) |
|
|
|
|
do { |
|
|
|
|
memset(&srb->cmd[0], 0, 12); |
|
|
|
|
srb->cmd[0] = SCSI_INQUIRY; |
|
|
|
|
srb->cmd[1] = srb->lun << 5; |
|
|
|
|
srb->cmd[4] = 36; |
|
|
|
|
srb->datalen = 36; |
|
|
|
|
srb->cmdlen = 12; |
|
|
|
@ -905,6 +931,7 @@ static int usb_request_sense(ccb *srb, struct us_data *ss) |
|
|
|
|
ptr = (char *)srb->pdata; |
|
|
|
|
memset(&srb->cmd[0], 0, 12); |
|
|
|
|
srb->cmd[0] = SCSI_REQ_SENSE; |
|
|
|
|
srb->cmd[1] = srb->lun << 5; |
|
|
|
|
srb->cmd[4] = 18; |
|
|
|
|
srb->datalen = 18; |
|
|
|
|
srb->pdata = &srb->sense_buf[0]; |
|
|
|
@ -924,6 +951,7 @@ static int usb_test_unit_ready(ccb *srb, struct us_data *ss) |
|
|
|
|
do { |
|
|
|
|
memset(&srb->cmd[0], 0, 12); |
|
|
|
|
srb->cmd[0] = SCSI_TST_U_RDY; |
|
|
|
|
srb->cmd[1] = srb->lun << 5; |
|
|
|
|
srb->datalen = 0; |
|
|
|
|
srb->cmdlen = 12; |
|
|
|
|
if (ss->transport(srb, ss) == USB_STOR_TRANSPORT_GOOD) |
|
|
|
@ -943,6 +971,7 @@ static int usb_read_capacity(ccb *srb, struct us_data *ss) |
|
|
|
|
do { |
|
|
|
|
memset(&srb->cmd[0], 0, 12); |
|
|
|
|
srb->cmd[0] = SCSI_RD_CAPAC; |
|
|
|
|
srb->cmd[1] = srb->lun << 5; |
|
|
|
|
srb->datalen = 8; |
|
|
|
|
srb->cmdlen = 12; |
|
|
|
|
if (ss->transport(srb, ss) == USB_STOR_TRANSPORT_GOOD) |
|
|
|
@ -957,6 +986,7 @@ static int usb_read_10(ccb *srb, struct us_data *ss, unsigned long start, |
|
|
|
|
{ |
|
|
|
|
memset(&srb->cmd[0], 0, 12); |
|
|
|
|
srb->cmd[0] = SCSI_READ10; |
|
|
|
|
srb->cmd[1] = srb->lun << 5; |
|
|
|
|
srb->cmd[2] = ((unsigned char) (start >> 24)) & 0xff; |
|
|
|
|
srb->cmd[3] = ((unsigned char) (start >> 16)) & 0xff; |
|
|
|
|
srb->cmd[4] = ((unsigned char) (start >> 8)) & 0xff; |
|
|
|
@ -973,6 +1003,7 @@ static int usb_write_10(ccb *srb, struct us_data *ss, unsigned long start, |
|
|
|
|
{ |
|
|
|
|
memset(&srb->cmd[0], 0, 12); |
|
|
|
|
srb->cmd[0] = SCSI_WRITE10; |
|
|
|
|
srb->cmd[1] = srb->lun << 5; |
|
|
|
|
srb->cmd[2] = ((unsigned char) (start >> 24)) & 0xff; |
|
|
|
|
srb->cmd[3] = ((unsigned char) (start >> 16)) & 0xff; |
|
|
|
|
srb->cmd[4] = ((unsigned char) (start >> 8)) & 0xff; |
|
|
|
|