From f27bac2761cab5a2e212dea602d22457a9aa6943 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 14 Jul 2008 14:59:30 +0900 Subject: [SCSI] sd: update index allocation and use ida instead of idr Update index allocation as follows. * sd_index_idr is used only for ID allocation and mapping functionality is not used. Use more memory efficient ida instead. * idr and ida have their own locks inside them and don't need them for operation. Drop it. * index wasn't freed if probing failed after index allocation. fix it. * ida allocation should be repeated if it fails with -EAGAIN. Signed-off-by: Tejun Heo Signed-off-by: James Bottomley --- drivers/scsi/sd.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) (limited to 'drivers/scsi/sd.c') diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 0c63947d8a9..99dddcae785 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -99,8 +99,7 @@ static void scsi_disk_release(struct device *cdev); static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *); static void sd_print_result(struct scsi_disk *, int); -static DEFINE_IDR(sd_index_idr); -static DEFINE_SPINLOCK(sd_index_lock); +static DEFINE_IDA(sd_index_ida); /* This semaphore is used to mediate the 0->1 reference get in the * face of object destruction (i.e. we can't allow a get on an @@ -1643,18 +1642,20 @@ static int sd_probe(struct device *dev) if (!gd) goto out_free; - if (!idr_pre_get(&sd_index_idr, GFP_KERNEL)) - goto out_put; + do { + if (!ida_pre_get(&sd_index_ida, GFP_KERNEL)) + goto out_put; - spin_lock(&sd_index_lock); - error = idr_get_new(&sd_index_idr, NULL, &index); - spin_unlock(&sd_index_lock); + error = ida_get_new(&sd_index_ida, &index); + } while (error == -EAGAIN); - if (index >= SD_MAX_DISKS) - error = -EBUSY; if (error) goto out_put; + error = -EBUSY; + if (index >= SD_MAX_DISKS) + goto out_free_index; + sdkp->device = sdp; sdkp->driver = &sd_template; sdkp->disk = gd; @@ -1675,7 +1676,7 @@ static int sd_probe(struct device *dev) strncpy(sdkp->dev.bus_id, sdp->sdev_gendev.bus_id, BUS_ID_SIZE); if (device_add(&sdkp->dev)) - goto out_put; + goto out_free_index; get_device(&sdp->sdev_gendev); @@ -1717,6 +1718,8 @@ static int sd_probe(struct device *dev) return 0; + out_free_index: + ida_remove(&sd_index_ida, index); out_put: put_disk(gd); out_free: @@ -1766,9 +1769,7 @@ static void scsi_disk_release(struct device *dev) struct scsi_disk *sdkp = to_scsi_disk(dev); struct gendisk *disk = sdkp->disk; - spin_lock(&sd_index_lock); - idr_remove(&sd_index_idr, sdkp->index); - spin_unlock(&sd_index_lock); + ida_remove(&sd_index_ida, sdkp->index); disk->private_data = NULL; put_disk(disk); -- cgit v1.2.3 From e0597d70012c82e16ee152270a55d89d8bf66693 Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Thu, 17 Jul 2008 04:28:34 -0400 Subject: [SCSI] sd: Identify DIF protection type and application tag ownership If a disk is formatted with protection information (Inquiry bit PROTECT=1) it is required to support Read Capacity(16). Force use of the 16-bit command in this case and extract the P_TYPE field which indicates whether the disk is formatted using DIF Type 1, 2 or 3. The ATO (App Tag Own) bit in the Control Mode Page indicates whether the storage device or the initiator own the contents of the DIF application tag. Signed-off-by: Martin K. Petersen Signed-off-by: James Bottomley --- drivers/scsi/sd.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 118 insertions(+), 4 deletions(-) (limited to 'drivers/scsi/sd.c') diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 99dddcae785..56b9501d12f 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -233,6 +233,24 @@ sd_show_allow_restart(struct device *dev, struct device_attribute *attr, return snprintf(buf, 40, "%d\n", sdkp->device->allow_restart); } +static ssize_t +sd_show_protection_type(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct scsi_disk *sdkp = to_scsi_disk(dev); + + return snprintf(buf, 20, "%u\n", sdkp->protection_type); +} + +static ssize_t +sd_show_app_tag_own(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct scsi_disk *sdkp = to_scsi_disk(dev); + + return snprintf(buf, 20, "%u\n", sdkp->ATO); +} + static struct device_attribute sd_disk_attrs[] = { __ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type, sd_store_cache_type), @@ -241,6 +259,8 @@ static struct device_attribute sd_disk_attrs[] = { sd_store_allow_restart), __ATTR(manage_start_stop, S_IRUGO|S_IWUSR, sd_show_manage_start_stop, sd_store_manage_start_stop), + __ATTR(protection_type, S_IRUGO, sd_show_protection_type, NULL), + __ATTR(app_tag_own, S_IRUGO, sd_show_app_tag_own, NULL), __ATTR_NULL, }; @@ -1164,6 +1184,49 @@ sd_spinup_disk(struct scsi_disk *sdkp) } } + +/* + * Determine whether disk supports Data Integrity Field. + */ +void sd_read_protection_type(struct scsi_disk *sdkp, unsigned char *buffer) +{ + struct scsi_device *sdp = sdkp->device; + u8 type; + + if (scsi_device_protection(sdp) == 0 || (buffer[12] & 1) == 0) + type = 0; + else + type = ((buffer[12] >> 1) & 7) + 1; /* P_TYPE 0 = Type 1 */ + + switch (type) { + case SD_DIF_TYPE0_PROTECTION: + sdkp->protection_type = 0; + break; + + case SD_DIF_TYPE1_PROTECTION: + case SD_DIF_TYPE3_PROTECTION: + sdkp->protection_type = type; + break; + + case SD_DIF_TYPE2_PROTECTION: + sd_printk(KERN_ERR, sdkp, "formatted with DIF Type 2 " \ + "protection which is currently unsupported. " \ + "Disabling disk!\n"); + goto disable; + + default: + sd_printk(KERN_ERR, sdkp, "formatted with unknown " \ + "protection type %d. Disabling disk!\n", type); + goto disable; + } + + return; + +disable: + sdkp->protection_type = 0; + sdkp->capacity = 0; +} + /* * read disk capacity */ @@ -1173,7 +1236,8 @@ sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer) unsigned char cmd[16]; int the_result, retries; int sector_size = 0; - int longrc = 0; + /* Force READ CAPACITY(16) when PROTECT=1 */ + int longrc = scsi_device_protection(sdkp->device) ? 1 : 0; struct scsi_sense_hdr sshdr; int sense_valid = 0; struct scsi_device *sdp = sdkp->device; @@ -1185,8 +1249,8 @@ repeat: memset((void *) cmd, 0, 16); cmd[0] = SERVICE_ACTION_IN; cmd[1] = SAI_READ_CAPACITY_16; - cmd[13] = 12; - memset((void *) buffer, 0, 12); + cmd[13] = 13; + memset((void *) buffer, 0, 13); } else { cmd[0] = READ_CAPACITY; memset((void *) &cmd[1], 0, 9); @@ -1194,7 +1258,7 @@ repeat: } the_result = scsi_execute_req(sdp, cmd, DMA_FROM_DEVICE, - buffer, longrc ? 12 : 8, &sshdr, + buffer, longrc ? 13 : 8, &sshdr, SD_TIMEOUT, SD_MAX_RETRIES); if (media_not_present(sdkp, &sshdr)) @@ -1269,6 +1333,8 @@ repeat: sector_size = (buffer[8] << 24) | (buffer[9] << 16) | (buffer[10] << 8) | buffer[11]; + + sd_read_protection_type(sdkp, buffer); } /* Some devices return the total number of sectors, not the @@ -1530,6 +1596,52 @@ defaults: sdkp->DPOFUA = 0; } +/* + * The ATO bit indicates whether the DIF application tag is available + * for use by the operating system. + */ +void sd_read_app_tag_own(struct scsi_disk *sdkp, unsigned char *buffer) +{ + int res, offset; + struct scsi_device *sdp = sdkp->device; + struct scsi_mode_data data; + struct scsi_sense_hdr sshdr; + + if (sdp->type != TYPE_DISK) + return; + + if (sdkp->protection_type == 0) + return; + + res = scsi_mode_sense(sdp, 1, 0x0a, buffer, 36, SD_TIMEOUT, + SD_MAX_RETRIES, &data, &sshdr); + + if (!scsi_status_is_good(res) || !data.header_length || + data.length < 6) { + sd_printk(KERN_WARNING, sdkp, + "getting Control mode page failed, assume no ATO\n"); + + if (scsi_sense_valid(&sshdr)) + sd_print_sense_hdr(sdkp, &sshdr); + + return; + } + + offset = data.header_length + data.block_descriptor_length; + + if ((buffer[offset] & 0x3f) != 0x0a) { + sd_printk(KERN_ERR, sdkp, "ATO Got wrong page\n"); + return; + } + + if ((buffer[offset + 5] & 0x80) == 0) + return; + + sdkp->ATO = 1; + + return; +} + /** * sd_revalidate_disk - called the first time a new disk is seen, * performs disk spin up, read_capacity, etc. @@ -1566,6 +1678,7 @@ static int sd_revalidate_disk(struct gendisk *disk) sdkp->write_prot = 0; sdkp->WCE = 0; sdkp->RCD = 0; + sdkp->ATO = 0; sd_spinup_disk(sdkp); @@ -1577,6 +1690,7 @@ static int sd_revalidate_disk(struct gendisk *disk) sd_read_capacity(sdkp, buffer); sd_read_write_protect_flag(sdkp, buffer); sd_read_cache_type(sdkp, buffer); + sd_read_app_tag_own(sdkp, buffer); } /* -- cgit v1.2.3 From af55ff675a8461da6a632320710b050af4366e0c Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Thu, 17 Jul 2008 04:28:35 -0400 Subject: [SCSI] sd: Support for SCSI disk (SBC) Data Integrity Field Support for controllers and disks that implement DIF protection information: - During command preparation the RDPROTECT/WRPROTECT must be set correctly if the target has DIF enabled. - READ(6) and WRITE(6) are not supported when DIF is on. - The controller must be told how to handle the I/O via the protection operation field in scsi_cmnd. - Refactor the I/O completion code that extracts failed LBA from the returned sense data and handle DIF failures correctly. - sd_dif.c implements the functions required to prepare and complete requests with protection information attached. Signed-off-by: Martin K. Petersen Signed-off-by: James Bottomley --- drivers/scsi/sd.c | 121 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 81 insertions(+), 40 deletions(-) (limited to 'drivers/scsi/sd.c') diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 56b9501d12f..8e08d51a0f0 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -373,6 +373,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) struct scsi_cmnd *SCpnt; struct scsi_device *sdp = q->queuedata; struct gendisk *disk = rq->rq_disk; + struct scsi_disk *sdkp; sector_t block = rq->sector; unsigned int this_count = rq->nr_sectors; unsigned int timeout = sdp->timeout; @@ -389,6 +390,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) if (ret != BLKPREP_OK) goto out; SCpnt = rq->special; + sdkp = scsi_disk(disk); /* from here on until we're complete, any goto out * is used for a killable error condition */ @@ -478,6 +480,11 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) } SCpnt->cmnd[0] = WRITE_6; SCpnt->sc_data_direction = DMA_TO_DEVICE; + + if (blk_integrity_rq(rq) && + sd_dif_prepare(rq, block, sdp->sector_size) == -EIO) + goto out; + } else if (rq_data_dir(rq) == READ) { SCpnt->cmnd[0] = READ_6; SCpnt->sc_data_direction = DMA_FROM_DEVICE; @@ -492,8 +499,12 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) "writing" : "reading", this_count, rq->nr_sectors)); - SCpnt->cmnd[1] = 0; - + /* Set RDPROTECT/WRPROTECT if disk is formatted with DIF */ + if (scsi_host_dif_capable(sdp->host, sdkp->protection_type)) + SCpnt->cmnd[1] = 1 << 5; + else + SCpnt->cmnd[1] = 0; + if (block > 0xffffffff) { SCpnt->cmnd[0] += READ_16 - READ_6; SCpnt->cmnd[1] |= blk_fua_rq(rq) ? 0x8 : 0; @@ -511,6 +522,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) SCpnt->cmnd[13] = (unsigned char) this_count & 0xff; SCpnt->cmnd[14] = SCpnt->cmnd[15] = 0; } else if ((this_count > 0xff) || (block > 0x1fffff) || + scsi_device_protection(SCpnt->device) || SCpnt->device->use_10_for_rw) { if (this_count > 0xffff) this_count = 0xffff; @@ -545,6 +557,10 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) } SCpnt->sdb.length = this_count * sdp->sector_size; + /* If DIF or DIX is enabled, tell HBA how to handle request */ + if (sdkp->protection_type || scsi_prot_sg_count(SCpnt)) + sd_dif_op(SCpnt, sdkp->protection_type, scsi_prot_sg_count(SCpnt)); + /* * We shouldn't disconnect in the middle of a sector, so with a dumb * host adapter, it's safe to assume that we can at least transfer @@ -939,6 +955,48 @@ static struct block_device_operations sd_fops = { .revalidate_disk = sd_revalidate_disk, }; +static unsigned int sd_completed_bytes(struct scsi_cmnd *scmd) +{ + u64 start_lba = scmd->request->sector; + u64 end_lba = scmd->request->sector + (scsi_bufflen(scmd) / 512); + u64 bad_lba; + int info_valid; + + if (!blk_fs_request(scmd->request)) + return 0; + + info_valid = scsi_get_sense_info_fld(scmd->sense_buffer, + SCSI_SENSE_BUFFERSIZE, + &bad_lba); + if (!info_valid) + return 0; + + if (scsi_bufflen(scmd) <= scmd->device->sector_size) + return 0; + + if (scmd->device->sector_size < 512) { + /* only legitimate sector_size here is 256 */ + start_lba <<= 1; + end_lba <<= 1; + } else { + /* be careful ... don't want any overflows */ + u64 factor = scmd->device->sector_size / 512; + do_div(start_lba, factor); + do_div(end_lba, factor); + } + + /* The bad lba was reported incorrectly, we have no idea where + * the error is. + */ + if (bad_lba < start_lba || bad_lba >= end_lba) + return 0; + + /* This computation should always be done in terms of + * the resolution of the device's medium. + */ + return (bad_lba - start_lba) * scmd->device->sector_size; +} + /** * sd_done - bottom half handler: called when the lower level * driver has completed (successfully or otherwise) a scsi command. @@ -949,15 +1007,10 @@ static struct block_device_operations sd_fops = { static int sd_done(struct scsi_cmnd *SCpnt) { int result = SCpnt->result; - unsigned int xfer_size = scsi_bufflen(SCpnt); - unsigned int good_bytes = result ? 0 : xfer_size; - u64 start_lba = SCpnt->request->sector; - u64 end_lba = SCpnt->request->sector + (xfer_size / 512); - u64 bad_lba; + unsigned int good_bytes = result ? 0 : scsi_bufflen(SCpnt); struct scsi_sense_hdr sshdr; int sense_valid = 0; int sense_deferred = 0; - int info_valid; if (result) { sense_valid = scsi_command_normalize_sense(SCpnt, &sshdr); @@ -982,36 +1035,7 @@ static int sd_done(struct scsi_cmnd *SCpnt) switch (sshdr.sense_key) { case HARDWARE_ERROR: case MEDIUM_ERROR: - if (!blk_fs_request(SCpnt->request)) - goto out; - info_valid = scsi_get_sense_info_fld(SCpnt->sense_buffer, - SCSI_SENSE_BUFFERSIZE, - &bad_lba); - if (!info_valid) - goto out; - if (xfer_size <= SCpnt->device->sector_size) - goto out; - if (SCpnt->device->sector_size < 512) { - /* only legitimate sector_size here is 256 */ - start_lba <<= 1; - end_lba <<= 1; - } else { - /* be careful ... don't want any overflows */ - u64 factor = SCpnt->device->sector_size / 512; - do_div(start_lba, factor); - do_div(end_lba, factor); - } - - if (bad_lba < start_lba || bad_lba >= end_lba) - /* the bad lba was reported incorrectly, we have - * no idea where the error is - */ - goto out; - - /* This computation should always be done in terms of - * the resolution of the device's medium. - */ - good_bytes = (bad_lba - start_lba)*SCpnt->device->sector_size; + good_bytes = sd_completed_bytes(SCpnt); break; case RECOVERED_ERROR: case NO_SENSE: @@ -1021,10 +1045,23 @@ static int sd_done(struct scsi_cmnd *SCpnt) scsi_print_sense("sd", SCpnt); SCpnt->result = 0; memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); - good_bytes = xfer_size; + good_bytes = scsi_bufflen(SCpnt); + break; + case ABORTED_COMMAND: + if (sshdr.asc == 0x10) { /* DIF: Disk detected corruption */ + scsi_print_result(SCpnt); + scsi_print_sense("sd", SCpnt); + good_bytes = sd_completed_bytes(SCpnt); + } break; case ILLEGAL_REQUEST: - if (SCpnt->device->use_10_for_rw && + if (sshdr.asc == 0x10) { /* DIX: HBA detected corruption */ + scsi_print_result(SCpnt); + scsi_print_sense("sd", SCpnt); + good_bytes = sd_completed_bytes(SCpnt); + } + if (!scsi_device_protection(SCpnt->device) && + SCpnt->device->use_10_for_rw && (SCpnt->cmnd[0] == READ_10 || SCpnt->cmnd[0] == WRITE_10)) SCpnt->device->use_10_for_rw = 0; @@ -1037,6 +1074,9 @@ static int sd_done(struct scsi_cmnd *SCpnt) break; } out: + if (rq_data_dir(SCpnt->request) == READ && scsi_prot_sg_count(SCpnt)) + sd_dif_complete(SCpnt, good_bytes); + return good_bytes; } @@ -1826,6 +1866,7 @@ static int sd_probe(struct device *dev) dev_set_drvdata(dev, sdkp); add_disk(gd); + sd_dif_config_host(sdkp); sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n", sdp->removable ? "removable " : ""); -- cgit v1.2.3 From 2b142900784c6e38c8d39fa57d5f95ef08e735d8 Mon Sep 17 00:00:00 2001 From: Alan Jenkins Date: Sun, 27 Jul 2008 09:38:42 +0100 Subject: [SCSI] extend the last_sector_bug flag to cover more sectors The last_sector_bug flag was added to work around a bug in certain usb cardreaders, where they would crash if a multiple sector read included the last sector. The original implementation avoids this by e.g. splitting an 8 sector read which includes the last sector into a 7 sector read, and a single sector read for the last sector. The flag is enabled for all USB devices. This revealed a second bug in other usb cardreaders, which crash when they get a multiple sector read which stops 1 sector short of the last sector. Affected hardware includes the Kingston "MobileLite" external USB cardreader and the internal USB cardreader on the Asus EeePC. Extend the last_sector_bug workaround to ensure that any access which touches the last 8 hardware sectors of the device is a single sector long. Requests are shrunk as necessary to meet this constraint. This gives us a safety margin against potential unknown or future bugs affecting multi-sector access to the end of the device. The two known bugs only affect the last 2 sectors. However, they suggest that these devices are prone to fencepost errors and that multi-sector access to the end of the device is not well tested. Popular OS's use multi-sector accesses, but they rarely read the last few sectors. Linux (with udev & vol_id) automatically reads sectors from the end of the device on insertion. It is assumed that single sector accesses are more thoroughly tested during development. Signed-off-by: Alan Jenkins Tested-by: Alan Jenkins Signed-off-by: James Bottomley --- drivers/scsi/sd.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'drivers/scsi/sd.c') diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 8e08d51a0f0..e5e7d785645 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -375,6 +375,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) struct gendisk *disk = rq->rq_disk; struct scsi_disk *sdkp; sector_t block = rq->sector; + sector_t threshold; unsigned int this_count = rq->nr_sectors; unsigned int timeout = sdp->timeout; int ret; @@ -422,13 +423,21 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) } /* - * Some devices (some sdcards for one) don't like it if the - * last sector gets read in a larger then 1 sector read. + * Some SD card readers can't handle multi-sector accesses which touch + * the last one or two hardware sectors. Split accesses as needed. */ - if (unlikely(sdp->last_sector_bug && - rq->nr_sectors > sdp->sector_size / 512 && - block + this_count == get_capacity(disk))) - this_count -= sdp->sector_size / 512; + threshold = get_capacity(disk) - SD_LAST_BUGGY_SECTORS * + (sdp->sector_size / 512); + + if (unlikely(sdp->last_sector_bug && block + this_count > threshold)) { + if (block < threshold) { + /* Access up to the threshold but not beyond */ + this_count = threshold - block; + } else { + /* Access only a single hardware sector */ + this_count = sdp->sector_size / 512; + } + } SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, "block=%llu\n", (unsigned long long)block)); -- cgit v1.2.3 From fca082c9f1e11ec07efa8d2f9f13688521253f36 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 4 Aug 2008 16:36:20 -0700 Subject: Revert "[SCSI] extend the last_sector_bug flag to cover more sectors" This reverts commit 2b142900784c6e38c8d39fa57d5f95ef08e735d8, since it seems to break some other USB storage devices (at least a JMicron USB to ATA bridge). As such, while it apparently fixes some cardreaders, it would need to be made conditional on the exact reader it fixes in order to avoid causing regressions. Cc: Alan Jenkins Cc: James Bottomley Signed-off-by: Linus Torvalds --- drivers/scsi/sd.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) (limited to 'drivers/scsi/sd.c') diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index e5e7d785645..8e08d51a0f0 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -375,7 +375,6 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) struct gendisk *disk = rq->rq_disk; struct scsi_disk *sdkp; sector_t block = rq->sector; - sector_t threshold; unsigned int this_count = rq->nr_sectors; unsigned int timeout = sdp->timeout; int ret; @@ -423,21 +422,13 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) } /* - * Some SD card readers can't handle multi-sector accesses which touch - * the last one or two hardware sectors. Split accesses as needed. + * Some devices (some sdcards for one) don't like it if the + * last sector gets read in a larger then 1 sector read. */ - threshold = get_capacity(disk) - SD_LAST_BUGGY_SECTORS * - (sdp->sector_size / 512); - - if (unlikely(sdp->last_sector_bug && block + this_count > threshold)) { - if (block < threshold) { - /* Access up to the threshold but not beyond */ - this_count = threshold - block; - } else { - /* Access only a single hardware sector */ - this_count = sdp->sector_size / 512; - } - } + if (unlikely(sdp->last_sector_bug && + rq->nr_sectors > sdp->sector_size / 512 && + block + this_count == get_capacity(disk))) + this_count -= sdp->sector_size / 512; SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, "block=%llu\n", (unsigned long long)block)); -- cgit v1.2.3 From 18351070b86d155713cf790b26af4f21b1fd0b29 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 5 Aug 2008 21:42:21 -0700 Subject: Re-introduce "[SCSI] extend the last_sector_bug flag to cover more sectors" This re-introduces commit 2b142900784c6e38c8d39fa57d5f95ef08e735d8, which was reverted due to the regression it caused by commit fca082c9f1e11ec07efa8d2f9f13688521253f36. That regression was not root-caused by the original commit, it was just uncovered by it, and the real fix was done by Alan Stern in commit 580da34847488b404218d1d7f53b156f245f5555 ("Fix USB storage hang on command abort"). We can thus re-introduce the change that was confirmed by Alan Jenkins to be still required by his odd card reader. Cc: Alan Jenkins Cc: Alan Stern Cc: James Bottomley Signed-off-by: Linus Torvalds --- drivers/scsi/sd.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'drivers/scsi/sd.c') diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 8e08d51a0f0..e5e7d785645 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -375,6 +375,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) struct gendisk *disk = rq->rq_disk; struct scsi_disk *sdkp; sector_t block = rq->sector; + sector_t threshold; unsigned int this_count = rq->nr_sectors; unsigned int timeout = sdp->timeout; int ret; @@ -422,13 +423,21 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) } /* - * Some devices (some sdcards for one) don't like it if the - * last sector gets read in a larger then 1 sector read. + * Some SD card readers can't handle multi-sector accesses which touch + * the last one or two hardware sectors. Split accesses as needed. */ - if (unlikely(sdp->last_sector_bug && - rq->nr_sectors > sdp->sector_size / 512 && - block + this_count == get_capacity(disk))) - this_count -= sdp->sector_size / 512; + threshold = get_capacity(disk) - SD_LAST_BUGGY_SECTORS * + (sdp->sector_size / 512); + + if (unlikely(sdp->last_sector_bug && block + this_count > threshold)) { + if (block < threshold) { + /* Access up to the threshold but not beyond */ + this_count = threshold - block; + } else { + /* Access only a single hardware sector */ + this_count = sdp->sector_size / 512; + } + } SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, "block=%llu\n", (unsigned long long)block)); -- cgit v1.2.3 From bb23b431db7405f6d79f989ad0236bf6428ba1cb Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Fri, 29 Aug 2008 11:47:07 +0200 Subject: remove blk_register_filter and blk_unregister_filter in gendisk This patch remove blk_register_filter and blk_unregister_filter in gendisk, and adds them to sd.c, sr.c. and ide-cd.c The commit abf5439370491dd6fbb4fe1a7939680d2a9bc9d4 moved cmdfilter from gendisk to request_queue. It turned out that in some subsystems multiple gendisks share a single request_queue. So we get: Using physmap partition information Creating 3 MTD partitions on "physmap-flash": 0x00000000-0x01c00000 : "User FS" 0x01c00000-0x01c40000 : "booter" kobject (8511c410): tried to init an initialized object, something is seriously wrong. Call Trace: [<8036644c>] dump_stack+0x8/0x34 [<8021f050>] kobject_init+0x50/0xcc [<8021fa18>] kobject_init_and_add+0x24/0x58 [<8021d20c>] blk_register_filter+0x4c/0x64 [<8021c194>] add_disk+0x78/0xe0 [<8027d14c>] add_mtd_blktrans_dev+0x254/0x278 [<8027c8f0>] blktrans_notify_add+0x40/0x78 [<80279c00>] add_mtd_device+0xd0/0x150 [<8027b090>] add_mtd_partitions+0x568/0x5d8 [<80285458>] physmap_flash_probe+0x2ac/0x334 [<802644f8>] driver_probe_device+0x12c/0x244 [<8026465c>] __driver_attach+0x4c/0x84 [<80263c64>] bus_for_each_dev+0x58/0xac [<802633ec>] bus_add_driver+0xc4/0x24c [<802648e0>] driver_register+0xcc/0x184 [<80100460>] _stext+0x60/0x1bc In the long term, we need to fix such subsystems but we need a quick fix now. This patch add the command filter support to only sd and sr though it might be useful for other SG_IO users (such as cciss). Signed-off-by: FUJITA Tomonori Reported-by: Manuel Lauss Signed-off-by: Jens Axboe --- drivers/scsi/sd.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/scsi/sd.c') diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index e5e7d785645..2a2bc89aba8 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1875,6 +1875,7 @@ static int sd_probe(struct device *dev) dev_set_drvdata(dev, sdkp); add_disk(gd); + blk_register_filter(gd); sd_dif_config_host(sdkp); sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n", @@ -1908,6 +1909,7 @@ static int sd_remove(struct device *dev) struct scsi_disk *sdkp = dev_get_drvdata(dev); device_del(&sdkp->dev); + blk_unregister_filter(sdkp->disk); del_gendisk(sdkp->disk); sd_shutdown(dev); -- cgit v1.2.3 From 2dc75d3c3b49c64fd26b4832a7efb75546cb3fc5 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 11 Sep 2008 14:20:23 +0200 Subject: block: disable sysfs parts of the disk command filter We still have life time issues with the sysfs command filter kobject, so disable it for 2.6.27 release. We can revisit this and make it work properly for 2.6.28, for 2.6.27 release it's too risky. Signed-off-by: Jens Axboe --- drivers/scsi/sd.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/scsi/sd.c') diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 2a2bc89aba8..e5e7d785645 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1875,7 +1875,6 @@ static int sd_probe(struct device *dev) dev_set_drvdata(dev, sdkp); add_disk(gd); - blk_register_filter(gd); sd_dif_config_host(sdkp); sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n", @@ -1909,7 +1908,6 @@ static int sd_remove(struct device *dev) struct scsi_disk *sdkp = dev_get_drvdata(dev); device_del(&sdkp->dev); - blk_unregister_filter(sdkp->disk); del_gendisk(sdkp->disk); sd_shutdown(dev); -- cgit v1.2.3 From 7404ad3b6d04efbd918e9e2e776bf560fbedf47d Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Sun, 31 Aug 2008 10:41:52 -0500 Subject: [SCSI] sd: use generic helper to print capacities in both binary and SI Signed-off-by: James Bottomley --- drivers/scsi/sd.c | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) (limited to 'drivers/scsi/sd.c') diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index e5e7d785645..af9e406a3ad 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -1429,27 +1430,21 @@ got_data: */ sector_size = 512; } + blk_queue_hardsect_size(sdp->request_queue, sector_size); + { - /* - * The msdos fs needs to know the hardware sector size - * So I have created this table. See ll_rw_blk.c - * Jacques Gelinas (Jacques@solucorp.qc.ca) - */ - int hard_sector = sector_size; - sector_t sz = (sdkp->capacity/2) * (hard_sector/256); - struct request_queue *queue = sdp->request_queue; - sector_t mb = sz; + char cap_str_2[10], cap_str_10[10]; + u64 sz = sdkp->capacity << ffz(~sector_size); - blk_queue_hardsect_size(queue, hard_sector); - /* avoid 64-bit division on 32-bit platforms */ - sector_div(sz, 625); - mb -= sz - 974; - sector_div(mb, 1950); + string_get_size(sz, STRING_UNITS_2, cap_str_2, + sizeof(cap_str_2)); + string_get_size(sz, STRING_UNITS_10, cap_str_10, + sizeof(cap_str_10)); sd_printk(KERN_NOTICE, sdkp, - "%llu %d-byte hardware sectors (%llu MB)\n", + "%llu %d-byte hardware sectors: (%s/%s)\n", (unsigned long long)sdkp->capacity, - hard_sector, (unsigned long long)mb); + sector_size, cap_str_10, cap_str_2); } /* Rescale capacity to 512-byte units */ -- cgit v1.2.3 From f615b48cc7df7cac3865ec76ac1a5bb04d3e07f4 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 25 Aug 2008 19:47:24 +0900 Subject: sd/ide-disk: apply extended minors to sd and ide Update sd and ide-disk such that they can take advantage of extended minors. ide-disk already has 64 minors per device and currently doesn't use extended minors although after this patch it can be turned on by simply tweaking constants. sd only had 16 minors per device causing problems on certain peculiar configurations. This patch lifts the restriction and enables it to use upto 64 minors. Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- drivers/scsi/sd.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/scsi/sd.c') diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index e5e7d785645..d1bb0e1d2d2 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -86,6 +86,10 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_DISK); MODULE_ALIAS_SCSI_DEVICE(TYPE_MOD); MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC); +#define SD_PARTS 64 +#define SD_MINORS 16 +#define SD_EXT_MINORS (SD_PARTS - SD_MINORS) + static int sd_revalidate_disk(struct gendisk *); static int sd_probe(struct device *); static int sd_remove(struct device *); @@ -1801,7 +1805,7 @@ static int sd_probe(struct device *dev) if (!sdkp) goto out; - gd = alloc_disk(16); + gd = alloc_disk_ext(SD_MINORS, SD_EXT_MINORS); if (!gd) goto out_free; @@ -1845,7 +1849,8 @@ static int sd_probe(struct device *dev) gd->major = sd_major((index & 0xf0) >> 4); gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00); - gd->minors = 16; + gd->minors = SD_MINORS; + gd->ext_minors = SD_EXT_MINORS; gd->fops = &sd_fops; if (index < 26) { -- cgit v1.2.3 From 870d6656126add8e383645732b03df2b7ccd4f94 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 25 Aug 2008 19:47:25 +0900 Subject: block: implement CONFIG_DEBUG_BLOCK_EXT_DEVT Extended devt introduces non-contiguos device numbers. This patch implements a debug option which forces most devt allocations to be from the extended area and spreads them out. This is enabled by default if DEBUG_KERNEL is set and achieves... 1. Detects code paths in kernel or userland which expect predetermined consecutive device numbers. 2. When something goes wrong, avoid corruption as adding to the minor of earlier partition won't lead to the wrong but valid device. Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- drivers/scsi/sd.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/scsi/sd.c') diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index d1bb0e1d2d2..280d231a86e 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -87,7 +87,13 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_MOD); MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC); #define SD_PARTS 64 + +#if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT) #define SD_MINORS 16 +#else +#define SD_MINORS 1 +#endif + #define SD_EXT_MINORS (SD_PARTS - SD_MINORS) static int sd_revalidate_disk(struct gendisk *); -- cgit v1.2.3 From 689d6fac40b41c7bf154f362deaf442548e4dc81 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 25 Aug 2008 19:56:16 +0900 Subject: block: replace @ext_minors with GENHD_FL_EXT_DEVT With previous changes, it's meaningless to limit the number of partitions. Replace @ext_minors with GENHD_FL_EXT_DEVT such that setting the flag allows the disk to have maximum number of allowed partitions (only limited by the number of entries in parsed_partitions as determined by MAX_PART constant). This kills not-too-pretty alloc_disk_ext[_node]() functions and makes @minors parameter to alloc_disk[_node]() unnecessary. The parameter is left alone to avoid disturbing the users. Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- drivers/scsi/sd.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'drivers/scsi/sd.c') diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 280d231a86e..6598024531d 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -86,16 +86,12 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_DISK); MODULE_ALIAS_SCSI_DEVICE(TYPE_MOD); MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC); -#define SD_PARTS 64 - #if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT) #define SD_MINORS 16 #else #define SD_MINORS 1 #endif -#define SD_EXT_MINORS (SD_PARTS - SD_MINORS) - static int sd_revalidate_disk(struct gendisk *); static int sd_probe(struct device *); static int sd_remove(struct device *); @@ -1811,7 +1807,7 @@ static int sd_probe(struct device *dev) if (!sdkp) goto out; - gd = alloc_disk_ext(SD_MINORS, SD_EXT_MINORS); + gd = alloc_disk(SD_MINORS); if (!gd) goto out_free; @@ -1856,7 +1852,6 @@ static int sd_probe(struct device *dev) gd->major = sd_major((index & 0xf0) >> 4); gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00); gd->minors = SD_MINORS; - gd->ext_minors = SD_EXT_MINORS; gd->fops = &sd_fops; if (index < 26) { @@ -1880,7 +1875,7 @@ static int sd_probe(struct device *dev) blk_queue_prep_rq(sdp->request_queue, sd_prep_fn); gd->driverfs_dev = &sdp->sdev_gendev; - gd->flags = GENHD_FL_DRIVERFS; + gd->flags = GENHD_FL_EXT_DEVT | GENHD_FL_DRIVERFS; if (sdp->removable) gd->flags |= GENHD_FL_REMOVABLE; -- cgit v1.2.3 From 3e1a7ff8a0a7b948f2684930166954f9e8e776fe Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 25 Aug 2008 19:56:17 +0900 Subject: block: allow disk to have extended device number Now that disk and partition handlings are mostly unified, it's easy to allow disk to have extended device number. This patch makes add_disk() use extended device number if disk->minors is zero. Both sd and ide-disk are updated to use this. * sd_format_disk_name() is implemented which can generically determine the drive name. This removes disk number restriction stemming from limited device names. * If sd index goes over SD_MAX_DISKS (which can be increased now BTW), sd simply doesn't initialize minors letting block layer choose extended device number. * If CONFIG_DEBUG_EXT_DEVT is set, both sd and ide-disk always set minors to 0 and use extended device numbers. Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- drivers/scsi/sd.c | 74 ++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 54 insertions(+), 20 deletions(-) (limited to 'drivers/scsi/sd.c') diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 6598024531d..bcb04b2a767 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -89,7 +89,7 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC); #if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT) #define SD_MINORS 16 #else -#define SD_MINORS 1 +#define SD_MINORS 0 #endif static int sd_revalidate_disk(struct gendisk *); @@ -1769,6 +1769,52 @@ static int sd_revalidate_disk(struct gendisk *disk) return 0; } +/** + * sd_format_disk_name - format disk name + * @prefix: name prefix - ie. "sd" for SCSI disks + * @index: index of the disk to format name for + * @buf: output buffer + * @buflen: length of the output buffer + * + * SCSI disk names starts at sda. The 26th device is sdz and the + * 27th is sdaa. The last one for two lettered suffix is sdzz + * which is followed by sdaaa. + * + * This is basically 26 base counting with one extra 'nil' entry + * at the beggining from the second digit on and can be + * determined using similar method as 26 base conversion with the + * index shifted -1 after each digit is computed. + * + * CONTEXT: + * Don't care. + * + * RETURNS: + * 0 on success, -errno on failure. + */ +static int sd_format_disk_name(char *prefix, int index, char *buf, int buflen) +{ + const int base = 'z' - 'a' + 1; + char *begin = buf + strlen(prefix); + char *end = buf + buflen; + char *p; + int unit; + + p = end - 1; + *p = '\0'; + unit = base; + do { + if (p == begin) + return -EINVAL; + *--p = 'a' + (index % unit); + index = (index / unit) - 1; + } while (index >= 0); + + memmove(begin, p, end - p); + memcpy(buf, prefix, strlen(prefix)); + + return 0; +} + /** * sd_probe - called during driver initialization and whenever a * new scsi device is attached to the system. It is called once @@ -1821,8 +1867,8 @@ static int sd_probe(struct device *dev) if (error) goto out_put; - error = -EBUSY; - if (index >= SD_MAX_DISKS) + error = sd_format_disk_name("sd", index, gd->disk_name, DISK_NAME_LEN); + if (error) goto out_free_index; sdkp->device = sdp; @@ -1849,24 +1895,12 @@ static int sd_probe(struct device *dev) get_device(&sdp->sdev_gendev); - gd->major = sd_major((index & 0xf0) >> 4); - gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00); - gd->minors = SD_MINORS; - gd->fops = &sd_fops; - - if (index < 26) { - sprintf(gd->disk_name, "sd%c", 'a' + index % 26); - } else if (index < (26 + 1) * 26) { - sprintf(gd->disk_name, "sd%c%c", - 'a' + index / 26 - 1,'a' + index % 26); - } else { - const unsigned int m1 = (index / 26 - 1) / 26 - 1; - const unsigned int m2 = (index / 26 - 1) % 26; - const unsigned int m3 = index % 26; - sprintf(gd->disk_name, "sd%c%c%c", - 'a' + m1, 'a' + m2, 'a' + m3); + if (index < SD_MAX_DISKS) { + gd->major = sd_major((index & 0xf0) >> 4); + gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00); + gd->minors = SD_MINORS; } - + gd->fops = &sd_fops; gd->private_data = &sdkp->driver; gd->queue = sdkp->device->request_queue; -- cgit v1.2.3 From f98a8cae12f2b2a8f9bfd7a53c990a1a405e880e Mon Sep 17 00:00:00 2001 From: Andrew Patterson Date: Thu, 4 Sep 2008 14:27:35 -0600 Subject: SCSI sd driver calls revalidate_disk wrapper. Modify the SCSI disk driver to call the revalidate_disk() wrapper. This allows us to do some housekeeping such as accounting for a disk being resized online. The wrapper will call sd_revalidate_disk() at the appropriate time. Signed-off-by: Andrew Patterson Signed-off-by: Jens Axboe --- drivers/scsi/sd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/scsi/sd.c') diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index bcb04b2a767..cb115d1bf22 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -165,7 +165,7 @@ sd_store_cache_type(struct device *dev, struct device_attribute *attr, sd_print_sense_hdr(sdkp, &sshdr); return -EINVAL; } - sd_revalidate_disk(sdkp->disk); + revalidate_disk(sdkp->disk); return count; } @@ -916,7 +916,7 @@ static void sd_rescan(struct device *dev) struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev); if (sdkp) { - sd_revalidate_disk(sdkp->disk); + revalidate_disk(sdkp->disk); scsi_disk_put(sdkp); } } -- cgit v1.2.3 From 242f9dcb8ba6f68fcd217a119a7648a4f69290e9 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Sun, 14 Sep 2008 05:55:09 -0700 Subject: block: unify request timeout handling Right now SCSI and others do their own command timeout handling. Move those bits to the block layer. Instead of having a timer per command, we try to be a bit more clever and simply have one per-queue. This avoids the overhead of having to tear down and setup a timer for each command, so it will result in a lot less timer fiddling. Signed-off-by: Mike Anderson Signed-off-by: Jens Axboe --- drivers/scsi/sd.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers/scsi/sd.c') diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index cb115d1bf22..c0cf4acda7d 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -383,7 +383,6 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) sector_t block = rq->sector; sector_t threshold; unsigned int this_count = rq->nr_sectors; - unsigned int timeout = sdp->timeout; int ret; if (rq->cmd_type == REQ_TYPE_BLOCK_PC) { @@ -584,7 +583,6 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) SCpnt->transfersize = sdp->sector_size; SCpnt->underflow = this_count << 9; SCpnt->allowed = SD_MAX_RETRIES; - SCpnt->timeout_per_command = timeout; /* * This indicates that the command is ready from our end to be @@ -1878,11 +1876,12 @@ static int sd_probe(struct device *dev) sdkp->openers = 0; sdkp->previous_state = 1; - if (!sdp->timeout) { + if (!sdp->request_queue->rq_timeout) { if (sdp->type != TYPE_MOD) - sdp->timeout = SD_TIMEOUT; + blk_queue_rq_timeout(sdp->request_queue, SD_TIMEOUT); else - sdp->timeout = SD_MOD_TIMEOUT; + blk_queue_rq_timeout(sdp->request_queue, + SD_MOD_TIMEOUT); } device_initialize(&sdkp->dev); -- cgit v1.2.3