diff -ur lb-2.4.6-pre8/drivers/scsi/scsi.h lb-2.4.6-pre8.scsi/drivers/scsi/scsi.h --- lb-2.4.6-pre8/drivers/scsi/scsi.h Tue Jul 3 01:31:47 2001 +++ lb-2.4.6-pre8.scsi/drivers/scsi/scsi.h Tue Jul 3 22:03:16 2001 @@ -351,7 +351,7 @@ #define DRIVER_MASK 0x0f #define SUGGEST_MASK 0xf0 -#define MAX_COMMAND_SIZE 12 +#define MAX_COMMAND_SIZE 16 #define SCSI_SENSE_BUFFERSIZE 64 /* @@ -613,6 +613,7 @@ unsigned expecting_cc_ua:1; /* Expecting a CHECK_CONDITION/UNIT_ATTN * because we did a bus reset. */ unsigned device_blocked:1; /* Device returned QUEUE_FULL. */ + unsigned sixteen:1; /* use 16 byte read / write */ unsigned ten:1; /* support ten byte read / write */ unsigned remap:1; /* support remapping */ unsigned starved:1; /* unable to process commands because diff -ur lb-2.4.6-pre8/drivers/scsi/sd.c lb-2.4.6-pre8.scsi/drivers/scsi/sd.c --- lb-2.4.6-pre8/drivers/scsi/sd.c Tue Jul 3 22:08:28 2001 +++ lb-2.4.6-pre8.scsi/drivers/scsi/sd.c Tue Jul 3 22:05:46 2001 @@ -277,11 +277,12 @@ static int sd_init_command(Scsi_Cmnd * SCpnt) { - int dev, devm, block, this_count; + int dev, devm, this_count; Scsi_Disk *dpnt; #if CONFIG_SCSI_LOGGING char nbuff[6]; #endif + blkoff_t block; devm = SD_PARTITION(SCpnt->request.rq_dev); dev = DEVICE_NR(SCpnt->request.rq_dev); @@ -289,7 +290,7 @@ block = SCpnt->request.sector; this_count = SCpnt->request_bufflen >> 9; - SCSI_LOG_HLQUEUE(1, printk("Doing sd request, dev = %d, block = %d\n", devm, block)); + SCSI_LOG_HLQUEUE(1, printk("Doing sd request, dev = %d, block = %"BLKOFF_FMT"\n", devm, block)); dpnt = &rscsi_disks[dev]; if (devm >= (sd_template.dev_max << 4) || @@ -374,7 +375,21 @@ SCpnt->cmnd[1] = (SCpnt->lun << 5) & 0xe0; - if (((this_count > 0xff) || (block > 0x1fffff)) || SCpnt->device->ten) { + if (SCpnt->device->sixteen) { + SCpnt->cmnd[0] += READ_16 - READ_6; + SCpnt->cmnd[2] = (unsigned char) (block >> 56) & 0xff; + SCpnt->cmnd[3] = (unsigned char) (block >> 48) & 0xff; + SCpnt->cmnd[4] = (unsigned char) (block >> 40) & 0xff; + SCpnt->cmnd[5] = (unsigned char) (block >> 32) & 0xff; + SCpnt->cmnd[6] = (unsigned char) (block >> 24) & 0xff; + SCpnt->cmnd[7] = (unsigned char) (block >> 16) & 0xff; + SCpnt->cmnd[8] = (unsigned char) (block >> 8) & 0xff; + SCpnt->cmnd[9] = (unsigned char) block & 0xff; + SCpnt->cmnd[10] = (unsigned char) (this_count >> 24) & 0xff; + SCpnt->cmnd[11] = (unsigned char) (this_count >> 16) & 0xff; + SCpnt->cmnd[12] = (unsigned char) (this_count >> 8) & 0xff; + SCpnt->cmnd[13] = (unsigned char) this_count & 0xff; + } else if (SCpnt->device->ten || (this_count > 0xff) || (block > 0x1fffff)) { if (this_count > 0xffff) this_count = 0xffff; @@ -882,14 +897,61 @@ */ rscsi_disks[i].ready = 1; - rscsi_disks[i].capacity = 1 + ((buffer[0] << 24) | - (buffer[1] << 16) | - (buffer[2] << 8) | - buffer[3]); + rscsi_disks[i].capacity = buffer[0]; + rscsi_disks[i].capacity <<= 8; + rscsi_disks[i].capacity |= buffer[1]; + rscsi_disks[i].capacity <<= 8; + rscsi_disks[i].capacity |= buffer[2]; + rscsi_disks[i].capacity <<= 8; + rscsi_disks[i].capacity |= buffer[3]; + rscsi_disks[i].capacity += 1; sector_size = (buffer[4] << 24) | (buffer[5] << 16) | (buffer[6] << 8) | buffer[7]; + + /* Is this disk larger than 32 bits? */ + if (rscsi_disks[i].capacity == 0x100000000) { + cmd[0] = READ_CAPACITY; + cmd[1] = (rscsi_disks[i].device->lun << 5) & 0xe0; + cmd[1] |= 0x2; /* Longlba */ + memset((void *) &cmd[2], 0, 8); + memset((void *) buffer, 0, 8); + SRpnt->sr_cmd_len = 0; + SRpnt->sr_sense_buffer[0] = 0; + SRpnt->sr_sense_buffer[2] = 0; + + SRpnt->sr_data_direction = SCSI_DATA_READ; + scsi_wait_req(SRpnt, (void *) cmd, (void *) buffer, + 8, SD_TIMEOUT, MAX_RETRIES); + + /* cool! 64 bit goodness... */ + if (!SRpnt->sr_result) { + rscsi_disks[i].capacity = buffer[0]; + rscsi_disks[i].capacity <<= 8; + rscsi_disks[i].capacity |= buffer[1]; + rscsi_disks[i].capacity <<= 8; + rscsi_disks[i].capacity |= buffer[2]; + rscsi_disks[i].capacity <<= 8; + rscsi_disks[i].capacity |= buffer[3]; + rscsi_disks[i].capacity <<= 8; + rscsi_disks[i].capacity |= buffer[4]; + rscsi_disks[i].capacity <<= 8; + rscsi_disks[i].capacity |= buffer[5]; + rscsi_disks[i].capacity <<= 8; + rscsi_disks[i].capacity |= buffer[6]; + rscsi_disks[i].capacity <<= 8; + rscsi_disks[i].capacity |= buffer[7]; + rscsi_disks[i].capacity += 1; + + sector_size = (buffer[8] << 24) | + (buffer[9] << 16) | (buffer[10] << 8) | + buffer[11]; + + SRpnt->sr_device->sixteen = 1; + } + } + if (sector_size == 0) { sector_size = 512; printk("%s : sector size 0 reported, assuming 512.\n", @@ -930,7 +992,7 @@ */ int m; int hard_sector = sector_size; - int sz = rscsi_disks[i].capacity * (hard_sector/256); + blkoff_t sz = rscsi_disks[i].capacity * (hard_sector/256); /* There are 16 minors allocated for each major device */ for (m = i << 4; m < ((i + 1) << 4); m++) { @@ -938,7 +1000,7 @@ } printk("SCSI device %s: " - "%d %d-byte hdwr sectors (%d MB)\n", + "%"BLKOFF_FMT" %d-byte hdwr sectors (%"BLKOFF_FMT" MB)\n", nbuff, rscsi_disks[i].capacity, hard_sector, (sz/2 - sz/1250 + 974)/1950); } diff -ur lb-2.4.6-pre8/drivers/scsi/sd.h lb-2.4.6-pre8.scsi/drivers/scsi/sd.h --- lb-2.4.6-pre8/drivers/scsi/sd.h Tue Jul 3 01:31:47 2001 +++ lb-2.4.6-pre8.scsi/drivers/scsi/sd.h Tue Jul 3 22:03:16 2001 @@ -26,7 +26,7 @@ extern struct hd_struct *sd; typedef struct scsi_disk { - unsigned capacity; /* size in blocks */ + u64 capacity; /* size in blocks */ Scsi_Device *device; unsigned char ready; /* flag ready for FLOPTICAL */ unsigned char write_prot; /* flag write_protect for rmvable dev */ diff -ur lb-2.4.6-pre8/include/scsi/scsi.h lb-2.4.6-pre8.scsi/include/scsi/scsi.h --- lb-2.4.6-pre8/include/scsi/scsi.h Thu May 3 11:22:20 2001 +++ lb-2.4.6-pre8.scsi/include/scsi/scsi.h Tue Jul 3 18:06:43 2001 @@ -78,6 +78,9 @@ #define MODE_SENSE_10 0x5a #define PERSISTENT_RESERVE_IN 0x5e #define PERSISTENT_RESERVE_OUT 0x5f +#define READ_16 0x88 +#define WRITE_16 0x8a +#define WRITE_VERIFY_16 0x8e #define MOVE_MEDIUM 0xa5 #define READ_12 0xa8 #define WRITE_12 0xaa