2tb limit in sd.c
RFC 1/1 2tb limit in sd.c
Good day!
modern storage boxes support >2TB arrays, but READ CAPACITY may return 2TB only (with 512 bytes blocksize). According to SBC, target may return 0xffffffff as device size in order to notify initiator that device size can't fit into 32 bits and that initiator should use Long READ CAPACITY with 64bits LBA field. Following patch implements this logic. Is it possible to include patch into 2.5 ?
drivers/scsi/sd.c +33 -9
@@ -908,11 +908,15 @@struct scsi_device *sdp = sdkp->device;int the_result, retries;int sector_size; +int longrc =0 ; +repeat: retries =3 ; do { cmd[0] = READ_CAPACITY; memset((void *) &cmd[1], 0, 9); + if (longrc) + cmd[1] = 0x02; /* Long LBA */ memset((void *) buffer, 0, 8); SRpnt->sr_cmd_len = 0;
@@ -921,7 +925,7 @@ SRpnt->sr_data_direction =SCSI_DATA_READ ;scsi_wait_req (SRpnt, (void *) cmd, (void *) buffer, -8 ,SD_TIMEOUT ,SD_MAX_RETRIES ); + longrc ?12 :8 ,SD_TIMEOUT ,SD_MAX_RETRIES );if (media_not_present (sdkp, SRpnt))return ;
@@ -958,14 +962,34 @@return ; } - - sdkp->capacity =1 + (((sector_t )buffer[0 ] <<24 ) | - (buffer[1 ] <<16 ) | - (buffer[2 ] <<8 ) | - buffer[3 ]); - - sector_size = (buffer[4 ] <<24 ) | - (buffer[5 ] <<16 ) | (buffer[6 ] <<8 ) | buffer[7 ]; + +if (!longrc) { +if (buffer[0 ] ==0xff && buffer[1 ] ==0xff && + buffer[2 ] ==0xff && buffer[3 ] ==0xff ) { +printk ("very big device. try to send long\n" ); + longrc =1 ; + goto repeat; + } + sdkp->capacity =1 + (((sector_t )buffer[0 ] <<24 ) | + (buffer[1 ] <<16 ) | + (buffer[2 ] <<8 ) | + buffer[3 ]); + + sector_size = (buffer[4 ] <<24 ) | + (buffer[5 ] <<16 ) | (buffer[6 ] <<8 ) | buffer[7 ]; + }else { + sdkp->capacity =1 + (((sector_t )buffer[0 ] <<56 ) | + ((sector_t )buffer[1 ] <<48 ) | + ((sector_t )buffer[2 ] <<40 ) | + ((sector_t )buffer[3 ] <<32 ) | + ((sector_t )buffer[4 ] <<24 ) | + ((sector_t )buffer[5 ] <<16 ) | + ((sector_t )buffer[6 ] <<8 ) | + (sector_t )buffer[7 ]); + + sector_size = (buffer[8 ] <<24 ) | + (buffer[9 ] <<16 ) | (buffer[10 ] <<8 ) | buffer[11 ]; + }if (sector_size ==0 ) { sector_size =512 ;