@ -168,6 +168,8 @@ int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,
struct us_data * ss ) ;
unsigned long usb_stor_read ( int device , unsigned long blknr ,
unsigned long blkcnt , void * buffer ) ;
unsigned long usb_stor_write ( int device , unsigned long blknr ,
unsigned long blkcnt , const void * buffer ) ;
struct usb_device * usb_get_dev_index ( int index ) ;
void uhci_show_temp_int_td ( void ) ;
@ -227,6 +229,7 @@ int usb_stor_scan(int mode)
usb_dev_desc [ i ] . dev = i ;
usb_dev_desc [ i ] . part_type = PART_TYPE_UNKNOWN ;
usb_dev_desc [ i ] . block_read = usb_stor_read ;
usb_dev_desc [ i ] . block_write = usb_stor_write ;
}
usb_max_devs = 0 ;
@ -964,6 +967,22 @@ static int usb_read_10(ccb *srb, struct us_data *ss, unsigned long start,
return ss - > transport ( srb , ss ) ;
}
static int usb_write_10 ( ccb * srb , struct us_data * ss , unsigned long start ,
unsigned short blocks )
{
memset ( & srb - > cmd [ 0 ] , 0 , 12 ) ;
srb - > cmd [ 0 ] = SCSI_WRITE10 ;
srb - > cmd [ 2 ] = ( ( unsigned char ) ( start > > 24 ) ) & 0xff ;
srb - > cmd [ 3 ] = ( ( unsigned char ) ( start > > 16 ) ) & 0xff ;
srb - > cmd [ 4 ] = ( ( unsigned char ) ( start > > 8 ) ) & 0xff ;
srb - > cmd [ 5 ] = ( ( unsigned char ) ( start ) ) & 0xff ;
srb - > cmd [ 7 ] = ( ( unsigned char ) ( blocks > > 8 ) ) & 0xff ;
srb - > cmd [ 8 ] = ( unsigned char ) blocks & 0xff ;
srb - > cmdlen = 12 ;
USB_STOR_PRINTF ( " write10: start %lx blocks %x \n " , start , blocks ) ;
return ss - > transport ( srb , ss ) ;
}
# ifdef CONFIG_USB_BIN_FIXUP
/*
@ -1065,6 +1084,86 @@ retry_it:
return blkcnt ;
}
# define USB_MAX_WRITE_BLK 20
unsigned long usb_stor_write ( int device , unsigned long blknr ,
unsigned long blkcnt , const void * buffer )
{
unsigned long start , blks , buf_addr ;
unsigned short smallblks ;
struct usb_device * dev ;
int retry , i ;
ccb * srb = & usb_ccb ;
if ( blkcnt = = 0 )
return 0 ;
device & = 0xff ;
/* Setup device */
USB_STOR_PRINTF ( " \n usb_write: dev %d \n " , device ) ;
dev = NULL ;
for ( i = 0 ; i < USB_MAX_DEVICE ; i + + ) {
dev = usb_get_dev_index ( i ) ;
if ( dev = = NULL )
return 0 ;
if ( dev - > devnum = = usb_dev_desc [ device ] . target )
break ;
}
usb_disable_asynch ( 1 ) ; /* asynch transfer not allowed */
srb - > lun = usb_dev_desc [ device ] . lun ;
buf_addr = ( unsigned long ) buffer ;
start = blknr ;
blks = blkcnt ;
if ( usb_test_unit_ready ( srb , ( struct us_data * ) dev - > privptr ) ) {
printf ( " Device NOT ready \n Request Sense returned %02X %02X "
" %02X \n " , srb - > sense_buf [ 2 ] , srb - > sense_buf [ 12 ] ,
srb - > sense_buf [ 13 ] ) ;
return 0 ;
}
USB_STOR_PRINTF ( " \n usb_write: dev %d startblk %lx, blccnt %lx "
" buffer %lx \n " , device , start , blks , buf_addr ) ;
do {
/* If write fails retry for max retry count else
* return with number of blocks written successfully .
*/
retry = 2 ;
srb - > pdata = ( unsigned char * ) buf_addr ;
if ( blks > USB_MAX_WRITE_BLK )
smallblks = USB_MAX_WRITE_BLK ;
else
smallblks = ( unsigned short ) blks ;
retry_it :
if ( smallblks = = USB_MAX_WRITE_BLK )
usb_show_progress ( ) ;
srb - > datalen = usb_dev_desc [ device ] . blksz * smallblks ;
srb - > pdata = ( unsigned char * ) buf_addr ;
if ( usb_write_10 ( srb , ( struct us_data * ) dev - > privptr , start ,
smallblks ) ) {
USB_STOR_PRINTF ( " Write ERROR \n " ) ;
usb_request_sense ( srb , ( struct us_data * ) dev - > privptr ) ;
if ( retry - - )
goto retry_it ;
blkcnt - = blks ;
break ;
}
start + = smallblks ;
blks - = smallblks ;
buf_addr + = srb - > datalen ;
} while ( blks ! = 0 ) ;
USB_STOR_PRINTF ( " usb_write: end startblk %lx, blccnt %x buffer %lx \n " ,
start , smallblks , buf_addr ) ;
usb_disable_asynch ( 0 ) ; /* asynch transfer allowed */
if ( blkcnt > = USB_MAX_WRITE_BLK )
printf ( " \n " ) ;
return blkcnt ;
}
/* Probe to see if a new device is actually a Storage device */
int usb_storage_probe ( struct usb_device * dev , unsigned int ifnum ,