* [PATCH RESEND 1/2] SCSI: use scsi_device->timeout consistently
@ 2006-11-19 12:51 Tejun Heo
2006-11-19 12:52 ` [PATCH RESEND 2/2] SCSI: add scsi_device->retries Tejun Heo
2006-11-19 22:01 ` [PATCH RESEND 1/2] SCSI: use scsi_device->timeout consistently Kai Makisara
0 siblings, 2 replies; 9+ messages in thread
From: Tejun Heo @ 2006-11-19 12:51 UTC (permalink / raw)
To: James.Bottomley, linux-scsi
Each high level driver uses scsi_device->timeout diffrently.
* sd sets sdev->timeout to SD_TIMEOUT if it's zero on attach.
sdev->timeout is used for commands received from block queue but
internal commands use SD_TIMEOUT directly.
* sr uses constant SR_TIMEOUT for all non-ioctl commands and
IOCTL_TIMEOUT for sr ioctls.
* st sets sdev->timeout to ST_TIMEOUT unconditionally. st uses
either sdev->timeout or scsi_tape->long_timeout depending on command
type.
* osst uses osst_tape->timeout and osst_tape->long_timeout.
This patch unifies differing behaviors as follows.
* All highlevel drivers initialize sdev->timeout to its default value
iff it's zero; otherwise, the specified value is used.
* All commands w/o specific timeout requirement use sdev->timeout.
Commands which require special timeout uses HL-specific value such
as IOCTL_TIMEOUT and scsi/osst_tape->long_timeout.
This patch also adds sdev local variable for shorter notation where
multiple references to sdev are added.
Signed-off-by: Tejun Heo <htejun@gmail.com>
---
Sorry, the original post had linux-scsi-owner@vger instead of
linux-scsi@vger. Reposting.
drivers/scsi/osst.c | 78 ++++++++++++++++++++++++++--------------------------
drivers/scsi/osst.h | 1
drivers/scsi/sd.c | 31 +++++++++++---------
drivers/scsi/sr.c | 49 ++++++++++++++++++--------------
drivers/scsi/st.c | 3 +-
5 files changed, 87 insertions(+), 75 deletions(-)
Index: scsi-misc-2.6/drivers/scsi/sd.c
===================================================================
--- scsi-misc-2.6.orig/drivers/scsi/sd.c
+++ scsi-misc-2.6/drivers/scsi/sd.c
@@ -186,7 +186,7 @@ static ssize_t sd_store_cache_type(struc
return -EINVAL;
rcd = ct & 0x01 ? 1 : 0;
wce = ct & 0x02 ? 1 : 0;
- if (scsi_mode_sense(sdp, 0x08, 8, buffer, sizeof(buffer), SD_TIMEOUT,
+ if (scsi_mode_sense(sdp, 0x08, 8, buffer, sizeof(buffer), sdp->timeout,
SD_MAX_RETRIES, &data, NULL))
return -EINVAL;
len = min_t(size_t, sizeof(buffer), data.length - data.header_length -
@@ -197,7 +197,7 @@ static ssize_t sd_store_cache_type(struc
buffer_data[2] |= wce << 2 | rcd;
sp = buffer_data[0] & 0x80 ? 1 : 0;
- if (scsi_mode_select(sdp, 1, sp, 8, buffer_data, len, SD_TIMEOUT,
+ if (scsi_mode_select(sdp, 1, sp, 8, buffer_data, len, sdp->timeout,
SD_MAX_RETRIES, &data, &sshdr)) {
if (scsi_sense_valid(&sshdr))
scsi_print_sense_hdr(sdkp->disk->disk_name, &sshdr);
@@ -370,7 +370,6 @@ static int sd_init_command(struct scsi_c
struct gendisk *disk = rq->rq_disk;
sector_t block = rq->sector;
unsigned int this_count = SCpnt->request_bufflen >> 9;
- unsigned int timeout = sdp->timeout;
SCSI_LOG_HLQUEUE(1, printk("sd_init_command: disk=%s, block=%llu, "
"count=%d\n", disk->disk_name,
@@ -511,7 +510,7 @@ static int sd_init_command(struct scsi_c
SCpnt->transfersize = sdp->sector_size;
SCpnt->underflow = this_count << 9;
SCpnt->allowed = SD_MAX_RETRIES;
- SCpnt->timeout_per_command = timeout;
+ SCpnt->timeout_per_command = sdp->timeout;
/*
* This is the completion routine we use. This is matched in terms
@@ -759,7 +758,7 @@ static int sd_media_changed(struct gendi
*/
retval = -ENODEV;
if (scsi_block_when_processing_errors(sdp))
- retval = scsi_test_unit_ready(sdp, SD_TIMEOUT, SD_MAX_RETRIES);
+ retval = scsi_test_unit_ready(sdp, sdp->timeout, SD_MAX_RETRIES);
/*
* Unable to test, unit probably not ready. This usually
@@ -805,7 +804,7 @@ static int sd_sync_cache(struct scsi_dev
* flush everything.
*/
res = scsi_execute_req(sdp, cmd, DMA_NONE, NULL, 0, &sshdr,
- SD_TIMEOUT, SD_MAX_RETRIES);
+ sdp->timeout, SD_MAX_RETRIES);
if (res == 0)
break;
}
@@ -838,9 +837,12 @@ static int sd_issue_flush(struct device
static void sd_prepare_flush(request_queue_t *q, struct request *rq)
{
+ struct device *dev = rq->rq_disk->driverfs_dev;
+ struct scsi_device *sdp = to_scsi_device(dev);
+
memset(rq->cmd, 0, sizeof(rq->cmd));
rq->cmd_type = REQ_TYPE_BLOCK_PC;
- rq->timeout = SD_TIMEOUT;
+ rq->timeout = sdp->timeout;
rq->cmd[0] = SYNCHRONIZE_CACHE;
rq->cmd_len = 10;
}
@@ -1028,6 +1030,7 @@ static int media_not_present(struct scsi
static void
sd_spinup_disk(struct scsi_disk *sdkp, char *diskname)
{
+ struct scsi_device *sdp = sdkp->device;
unsigned char cmd[10];
unsigned long spintime_expire = 0;
int retries, spintime;
@@ -1046,9 +1049,9 @@ sd_spinup_disk(struct scsi_disk *sdkp, c
cmd[0] = TEST_UNIT_READY;
memset((void *) &cmd[1], 0, 9);
- the_result = scsi_execute_req(sdkp->device, cmd,
+ the_result = scsi_execute_req(sdp, cmd,
DMA_NONE, NULL, 0,
- &sshdr, SD_TIMEOUT,
+ &sshdr, sdp->timeout,
SD_MAX_RETRIES);
/*
@@ -1079,7 +1082,7 @@ sd_spinup_disk(struct scsi_disk *sdkp, c
/*
* The device does not want the automatic start to be issued.
*/
- if (sdkp->device->no_start_on_add) {
+ if (sdp->no_start_on_add) {
break;
}
@@ -1103,9 +1106,9 @@ sd_spinup_disk(struct scsi_disk *sdkp, c
cmd[1] = 1; /* Return immediately */
memset((void *) &cmd[2], 0, 8);
cmd[4] = 1; /* Start spin cycle */
- scsi_execute_req(sdkp->device, cmd, DMA_NONE,
+ scsi_execute_req(sdp, cmd, DMA_NONE,
NULL, 0, &sshdr,
- SD_TIMEOUT, SD_MAX_RETRIES);
+ sdp->timeout, SD_MAX_RETRIES);
spintime_expire = jiffies + 100 * HZ;
spintime = 1;
}
@@ -1180,7 +1183,7 @@ repeat:
the_result = scsi_execute_req(sdp, cmd, DMA_FROM_DEVICE,
buffer, longrc ? 12 : 8, &sshdr,
- SD_TIMEOUT, SD_MAX_RETRIES);
+ sdp->timeout, SD_MAX_RETRIES);
if (media_not_present(sdkp, &sshdr))
return;
@@ -1345,7 +1348,7 @@ sd_do_mode_sense(struct scsi_device *sdp
struct scsi_sense_hdr *sshdr)
{
return scsi_mode_sense(sdp, dbd, modepage, buffer, len,
- SD_TIMEOUT, SD_MAX_RETRIES, data,
+ sdp->timeout, SD_MAX_RETRIES, data,
sshdr);
}
Index: scsi-misc-2.6/drivers/scsi/sr.c
===================================================================
--- scsi-misc-2.6.orig/drivers/scsi/sr.c
+++ scsi-misc-2.6/drivers/scsi/sr.c
@@ -177,6 +177,7 @@ static void scsi_cd_put(struct scsi_cd *
int sr_media_change(struct cdrom_device_info *cdi, int slot)
{
struct scsi_cd *cd = cdi->handle;
+ struct scsi_device *sdev = cd->device;
int retval;
if (CDSL_CURRENT != slot) {
@@ -184,19 +185,19 @@ int sr_media_change(struct cdrom_device_
return -EINVAL;
}
- retval = scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES);
+ retval = scsi_test_unit_ready(sdev, sdev->timeout, MAX_RETRIES);
if (retval) {
/* Unable to test, unit probably not ready. This usually
* means there is no disc in the drive. Mark as changed,
* and we will figure it out later once the drive is
* available again. */
- cd->device->changed = 1;
+ sdev->changed = 1;
return 1; /* This will force a flush, if called from
* check_disk_change */
};
- retval = cd->device->changed;
- cd->device->changed = 0;
+ retval = sdev->changed;
+ sdev->changed = 0;
/* If the disk changed, the capacity will now be different,
* so we force a re-read of this information */
if (retval) {
@@ -297,20 +298,21 @@ static void rw_intr(struct scsi_cmnd * S
static int sr_init_command(struct scsi_cmnd * SCpnt)
{
- int block=0, this_count, s_size, timeout = SR_TIMEOUT;
+ int block=0, this_count, s_size;
struct scsi_cd *cd = scsi_cd(SCpnt->request->rq_disk);
+ struct scsi_device *sdev = cd->device;
SCSI_LOG_HLQUEUE(1, printk("Doing sr request, dev = %s, block = %d\n",
cd->disk->disk_name, block));
- if (!cd->device || !scsi_device_online(cd->device)) {
+ if (!sdev || !scsi_device_online(sdev)) {
SCSI_LOG_HLQUEUE(2, printk("Finishing %ld sectors\n",
SCpnt->request->nr_sectors));
SCSI_LOG_HLQUEUE(2, printk("Retry with 0x%p\n", SCpnt));
return 0;
}
- if (cd->device->changed) {
+ if (sdev->changed) {
/*
* quietly refuse to do anything to a changed disc until the
* changed bit has been reset
@@ -322,7 +324,7 @@ static int sr_init_command(struct scsi_c
* we do lazy blocksize switching (when reading XA sectors,
* see CDROMREADMODE2 ioctl)
*/
- s_size = cd->device->sector_size;
+ s_size = sdev->sector_size;
if (s_size > 2048) {
if (!in_interrupt())
sr_set_blocklength(cd, 2048);
@@ -336,7 +338,7 @@ static int sr_init_command(struct scsi_c
}
if (rq_data_dir(SCpnt->request) == WRITE) {
- if (!cd->device->writeable)
+ if (!sdev->writeable)
return 0;
SCpnt->cmnd[0] = WRITE_10;
SCpnt->sc_data_direction = DMA_TO_DEVICE;
@@ -403,10 +405,10 @@ static int sr_init_command(struct scsi_c
* host adapter, it's safe to assume that we can at least transfer
* this many bytes between each connect / disconnect.
*/
- SCpnt->transfersize = cd->device->sector_size;
+ SCpnt->transfersize = sdev->sector_size;
SCpnt->underflow = this_count << 9;
SCpnt->allowed = MAX_RETRIES;
- SCpnt->timeout_per_command = timeout;
+ SCpnt->timeout_per_command = sdev->timeout;
/*
* This is the completion routine we use. This is matched in terms
@@ -579,6 +581,9 @@ static int sr_probe(struct device *dev)
cd->readcd_known = 0;
cd->readcd_cdda = 0;
+ if (!sdev->timeout)
+ sdev->timeout = SR_TIMEOUT;
+
cd->cdi.ops = &sr_dops;
cd->cdi.handle = cd;
cd->cdi.mask = 0;
@@ -619,6 +624,7 @@ fail:
static void get_sectorsize(struct scsi_cd *cd)
{
+ struct scsi_device *sdev = cd->device;
unsigned char cmd[10];
unsigned char *buffer;
int the_result, retries = 3;
@@ -635,8 +641,8 @@ static void get_sectorsize(struct scsi_c
memset(buffer, 0, 8);
/* Do the command and wait.. */
- the_result = scsi_execute_req(cd->device, cmd, DMA_FROM_DEVICE,
- buffer, 8, NULL, SR_TIMEOUT,
+ the_result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE,
+ buffer, 8, NULL, sdev->timeout,
MAX_RETRIES);
retries--;
@@ -681,7 +687,7 @@ static void get_sectorsize(struct scsi_c
cd->capacity = 0;
}
- cd->device->sector_size = sector_size;
+ sdev->sector_size = sector_size;
/*
* Add this so that we have the ability to correctly gauge
@@ -690,7 +696,7 @@ static void get_sectorsize(struct scsi_c
set_capacity(cd->disk, cd->capacity);
}
- queue = cd->device->request_queue;
+ queue = sdev->request_queue;
blk_queue_hardsect_size(queue, sector_size);
out:
kfree(buffer);
@@ -698,12 +704,13 @@ out:
Enomem:
cd->capacity = 0x1fffff;
- cd->device->sector_size = 2048; /* A guess, just in case */
+ sdev->sector_size = 2048; /* A guess, just in case */
goto out;
}
static void get_capabilities(struct scsi_cd *cd)
{
+ struct scsi_device *sdev = cd->device;
unsigned char *buffer;
struct scsi_mode_data data;
unsigned char cmd[MAX_COMMAND_SIZE];
@@ -739,8 +746,8 @@ static void get_capabilities(struct scsi
memset((void *)cmd, 0, MAX_COMMAND_SIZE);
cmd[0] = TEST_UNIT_READY;
- the_result = scsi_execute_req (cd->device, cmd, DMA_NONE, NULL,
- 0, &sshdr, SR_TIMEOUT,
+ the_result = scsi_execute_req (sdev, cmd, DMA_NONE, NULL,
+ 0, &sshdr, sdev->timeout,
MAX_RETRIES);
retries++;
@@ -750,8 +757,8 @@ static void get_capabilities(struct scsi
sshdr.sense_key == UNIT_ATTENTION)));
/* ask for mode page 0x2a */
- rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, 128,
- SR_TIMEOUT, 3, &data, NULL);
+ rc = scsi_mode_sense(sdev, 0, 0x2a, buffer, 128,
+ sdev->timeout, 3, &data, NULL);
if (!scsi_status_is_good(rc)) {
/* failed, drive doesn't have capabilities mode page */
@@ -816,7 +823,7 @@ static void get_capabilities(struct scsi
*/
if ((cd->cdi.mask & (CDC_DVD_RAM | CDC_MRW_W | CDC_RAM | CDC_CD_RW)) !=
(CDC_DVD_RAM | CDC_MRW_W | CDC_RAM | CDC_CD_RW)) {
- cd->device->writeable = 1;
+ sdev->writeable = 1;
}
kfree(buffer);
Index: scsi-misc-2.6/drivers/scsi/st.c
===================================================================
--- scsi-misc-2.6.orig/drivers/scsi/st.c
+++ scsi-misc-2.6/drivers/scsi/st.c
@@ -3986,7 +3986,8 @@ static int st_probe(struct device *dev)
tpnt->partition = 0;
tpnt->new_partition = 0;
tpnt->nbr_partitions = 0;
- tpnt->device->timeout = ST_TIMEOUT;
+ if (!SDp->timeout)
+ SDp->timeout = ST_TIMEOUT;
tpnt->long_timeout = ST_LONG_TIMEOUT;
tpnt->try_dio = try_direct_io && !SDp->host->unchecked_isa_dma;
Index: scsi-misc-2.6/drivers/scsi/osst.c
===================================================================
--- scsi-misc-2.6.orig/drivers/scsi/osst.c
+++ scsi-misc-2.6/drivers/scsi/osst.c
@@ -683,7 +683,7 @@ static int osst_wait_ready(struct osst_t
memset(cmd, 0, MAX_COMMAND_SIZE);
cmd[0] = TEST_UNIT_READY;
- SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
+ SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->device->timeout, MAX_RETRIES, 1);
*aSRpnt = SRpnt;
if (!SRpnt) return (-EBUSY);
@@ -704,7 +704,7 @@ static int osst_wait_ready(struct osst_t
memset(cmd, 0, MAX_COMMAND_SIZE);
cmd[0] = TEST_UNIT_READY;
- SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
+ SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->device->timeout, MAX_RETRIES, 1);
}
*aSRpnt = SRpnt;
#if DEBUG
@@ -744,7 +744,7 @@ static int osst_wait_for_medium(struct o
memset(cmd, 0, MAX_COMMAND_SIZE);
cmd[0] = TEST_UNIT_READY;
- SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
+ SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->device->timeout, MAX_RETRIES, 1);
*aSRpnt = SRpnt;
if (!SRpnt) return (-EBUSY);
@@ -762,7 +762,7 @@ static int osst_wait_for_medium(struct o
memset(cmd, 0, MAX_COMMAND_SIZE);
cmd[0] = TEST_UNIT_READY;
- SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
+ SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->device->timeout, MAX_RETRIES, 1);
}
*aSRpnt = SRpnt;
#if DEBUG
@@ -814,7 +814,7 @@ static int osst_flush_drive_buffer(struc
cmd[0] = WRITE_FILEMARKS;
cmd[1] = 1;
- SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
+ SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->device->timeout, MAX_RETRIES, 1);
*aSRpnt = SRpnt;
if (!SRpnt) return (-EBUSY);
if (STp->buffer->syscall_result) {
@@ -905,8 +905,8 @@ static int osst_recover_wait_frame(struc
memset(cmd, 0, MAX_COMMAND_SIZE);
cmd[0] = WRITE_FILEMARKS;
cmd[1] = 1;
- SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout,
- MAX_RETRIES, 1);
+ SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE,
+ STp->device->timeout, MAX_RETRIES, 1);
while (retval && time_before (jiffies, startwait + 5*60*HZ)) {
@@ -922,8 +922,8 @@ static int osst_recover_wait_frame(struc
memset(cmd, 0, MAX_COMMAND_SIZE);
cmd[0] = READ_POSITION;
- SRpnt = osst_do_scsi(SRpnt, STp, cmd, 20, DMA_FROM_DEVICE, STp->timeout,
- MAX_RETRIES, 1);
+ SRpnt = osst_do_scsi(SRpnt, STp, cmd, 20, DMA_FROM_DEVICE,
+ STp->device->timeout, MAX_RETRIES, 1);
retval = ( STp->buffer->syscall_result || (STp->buffer)->b_data[15] > 25 );
STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
@@ -969,7 +969,7 @@ static int osst_read_frame(struct osst_t
printk(OSST_DEB_MSG "%s:D: Reading frame from OnStream tape\n", name);
#endif
SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE,
- STp->timeout, MAX_RETRIES, 1);
+ STp->device->timeout, MAX_RETRIES, 1);
*aSRpnt = SRpnt;
if (!SRpnt)
return (-EBUSY);
@@ -1044,7 +1044,8 @@ static int osst_initiate_read(struct oss
#if DEBUG
printk(OSST_DEB_MSG "%s:D: Start Read Ahead on OnStream tape\n", name);
#endif
- SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
+ SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE,
+ STp->device->timeout, MAX_RETRIES, 1);
*aSRpnt = SRpnt;
if ((retval = STp->buffer->syscall_result))
printk(KERN_WARNING "%s:W: Error starting read ahead\n", name);
@@ -1426,7 +1427,7 @@ static int osst_read_back_buffer_and_rew
cmd[8] = 32768 & 0xff;
SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE,
- STp->timeout, MAX_RETRIES, 1);
+ STp->device->timeout, MAX_RETRIES, 1);
if ((STp->buffer)->syscall_result || !SRpnt) {
printk(KERN_ERR "%s:E: Failed to read frame back from OnStream buffer\n", name);
@@ -1498,7 +1499,7 @@ static int osst_read_back_buffer_and_rew
p[0], p[1], p[2], p[3]);
#endif
SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE,
- STp->timeout, MAX_RETRIES, 1);
+ STp->device->timeout, MAX_RETRIES, 1);
if (STp->buffer->syscall_result)
flag = 1;
@@ -1514,7 +1515,7 @@ static int osst_read_back_buffer_and_rew
cmd[0] = WRITE_FILEMARKS;
cmd[1] = 1;
SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
- STp->timeout, MAX_RETRIES, 1);
+ STp->device->timeout, MAX_RETRIES, 1);
#if DEBUG
if (debugging) {
printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name);
@@ -1528,8 +1529,8 @@ static int osst_read_back_buffer_and_rew
memset(cmd, 0, MAX_COMMAND_SIZE);
cmd[0] = TEST_UNIT_READY;
- SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->timeout,
- MAX_RETRIES, 1);
+ SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
+ STp->device->timeout, MAX_RETRIES, 1);
if (SRpnt->sense[2] == 2 && SRpnt->sense[12] == 4 &&
(SRpnt->sense[13] == 1 || SRpnt->sense[13] == 8)) {
@@ -1634,7 +1635,7 @@ static int osst_reposition_and_retry(str
name, STp->frame_seq_number-1, STp->first_frame_position);
#endif
SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE,
- STp->timeout, MAX_RETRIES, 1);
+ STp->device->timeout, MAX_RETRIES, 1);
*aSRpnt = SRpnt;
if (STp->buffer->syscall_result) { /* additional write error */
@@ -2091,7 +2092,7 @@ static void osst_set_retries(struct osst
if (debugging)
printk(OSST_DEB_MSG "%s:D: Setting number of retries on OnStream tape to %d\n", name, retries);
- SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
+ SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->device->timeout, 0, 1);
*aSRpnt = SRpnt;
if ((STp->buffer)->syscall_result)
@@ -2631,7 +2632,7 @@ static int osst_configure_onstream(struc
cmd[2] = BLOCK_SIZE_PAGE;
cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH;
- SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
+ SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->device->timeout, 0, 1);
if (SRpnt == NULL) {
#if DEBUG
printk(OSST_DEB_MSG "osst :D: Busy\n");
@@ -2668,7 +2669,7 @@ static int osst_configure_onstream(struc
cmd[1] = 0x10;
cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH;
- SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
+ SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->device->timeout, 0, 1);
*aSRpnt = SRpnt;
if ((STp->buffer)->syscall_result != 0) {
printk (KERN_ERR "%s:E: Couldn't set tape block size mode page\n", name);
@@ -2708,7 +2709,7 @@ static int osst_configure_onstream(struc
(STp->buffer)->b_data[MODE_HEADER_LENGTH + 6] = 0;
(STp->buffer)->b_data[MODE_HEADER_LENGTH + 7] = 0;
- SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
+ SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->device->timeout, 0, 1);
*aSRpnt = SRpnt;
if ((STp->buffer)->syscall_result != 0) {
@@ -2723,7 +2724,7 @@ static int osst_configure_onstream(struc
cmd[2] = CAPABILITIES_PAGE;
cmd[4] = CAPABILITIES_PAGE_LENGTH + MODE_HEADER_LENGTH;
- SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
+ SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->device->timeout, 0, 1);
*aSRpnt = SRpnt;
if ((STp->buffer)->syscall_result != 0) {
@@ -2743,7 +2744,7 @@ static int osst_configure_onstream(struc
cmd[2] = TAPE_PARAMTR_PAGE;
cmd[4] = TAPE_PARAMTR_PAGE_LENGTH + MODE_HEADER_LENGTH;
- SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
+ SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->device->timeout, 0, 1);
*aSRpnt = SRpnt;
if ((STp->buffer)->syscall_result != 0) {
@@ -2818,7 +2819,7 @@ static int osst_get_frame_position(struc
STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 20, DMA_FROM_DEVICE,
- STp->timeout, MAX_RETRIES, 1);
+ STp->device->timeout, MAX_RETRIES, 1);
if (!SRpnt) {
STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize;
return (-EBUSY);
@@ -2838,7 +2839,7 @@ static int osst_get_frame_position(struc
scmd[0] = READ_POSITION;
STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
SRpnt = osst_do_scsi(SRpnt, STp, scmd, 20, DMA_FROM_DEVICE,
- STp->timeout, MAX_RETRIES, 1);
+ STp->device->timeout, MAX_RETRIES, 1);
#if DEBUG
printk(OSST_DEB_MSG "%s:D: Reread position, reason=[%02x:%02x:%02x], result=[%s%02x:%02x:%02x]\n",
name, mysense[2], mysense[12], mysense[13], STp->buffer->syscall_result?"":"ok:",
@@ -3055,7 +3056,7 @@ static int osst_flush_write_buffer(struc
#endif
SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, transfer, DMA_TO_DEVICE,
- STp->timeout, MAX_RETRIES, 1);
+ STp->device->timeout, MAX_RETRIES, 1);
*aSRpnt = SRpnt;
if (!SRpnt)
return (-EBUSY);
@@ -3211,8 +3212,8 @@ static int osst_write_frame(struct osst_
if (!synchronous)
STp->write_pending = 1;
#endif
- SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE, STp->timeout,
- MAX_RETRIES, synchronous);
+ SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE, STp->device->timeout,
+ MAX_RETRIES, synchronous);
if (!SRpnt)
return (-EBUSY);
*aSRpnt = SRpnt;
@@ -3921,7 +3922,7 @@ static int osst_set_options(struct osst_
(value & ~MT_ST_SET_LONG_TIMEOUT));
}
else {
- STp->timeout = value * HZ;
+ STp->device->timeout = value * HZ;
printk(KERN_INFO "%s:I: Normal timeout set to %d seconds.\n", name, value);
}
}
@@ -4112,7 +4113,7 @@ static int osst_int_ioctl(struct osst_ta
cmd[2] = (arg >> 16);
cmd[3] = (arg >> 8);
cmd[4] = arg;
- timeout = STp->timeout;
+ timeout = STp->device->timeout;
#if DEBUG
if (debugging)
printk(OSST_DEB_MSG "%s:D: Writing %d setmark(s).\n", name,
@@ -4139,7 +4140,7 @@ static int osst_int_ioctl(struct osst_ta
cmd[4] = 3; /* retension then mount */
if (cmd_in == MTOFFL)
cmd[4] = 4; /* rewind then eject */
- timeout = STp->timeout;
+ timeout = STp->device->timeout;
#if DEBUG
if (debugging) {
switch (cmd_in) {
@@ -4464,7 +4465,7 @@ static int os_scsi_tape_open(struct inod
memset (cmd, 0, MAX_COMMAND_SIZE);
cmd[0] = TEST_UNIT_READY;
- SRpnt = osst_do_scsi(NULL, STp, cmd, 0, DMA_NONE, STp->timeout, MAX_RETRIES, 1);
+ SRpnt = osst_do_scsi(NULL, STp, cmd, 0, DMA_NONE, STp->device->timeout, MAX_RETRIES, 1);
if (!SRpnt) {
retval = (STp->buffer)->syscall_result; /* FIXME - valid? */
goto err_out;
@@ -4485,7 +4486,7 @@ static int os_scsi_tape_open(struct inod
cmd[1] = 1;
cmd[4] = 1;
SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
- STp->timeout, MAX_RETRIES, 1);
+ STp->device->timeout, MAX_RETRIES, 1);
}
osst_wait_ready(STp, &SRpnt, (SRpnt->sense[13]==1?15:3) * 60, 0);
}
@@ -4502,7 +4503,7 @@ static int os_scsi_tape_open(struct inod
cmd[0] = TEST_UNIT_READY;
SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
- STp->timeout, MAX_RETRIES, 1);
+ STp->device->timeout, MAX_RETRIES, 1);
if ((SRpnt->sense[0] & 0x70) != 0x70 ||
(SRpnt->sense[2] & 0x0f) != UNIT_ATTENTION)
break;
@@ -4538,7 +4539,7 @@ static int os_scsi_tape_open(struct inod
cmd[2] = VENDOR_IDENT_PAGE;
cmd[4] = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH;
- SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->timeout, 0, 1);
+ SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->device->timeout, 0, 1);
if (STp->buffer->syscall_result ||
STp->buffer->b_data[MODE_HEADER_LENGTH + 2] != 'L' ||
@@ -4601,7 +4602,7 @@ static int os_scsi_tape_open(struct inod
#if DEBUG
printk(OSST_DEB_MSG "%s:D: Applying soft reset\n", name);
#endif
- SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->timeout, 0, 1);
+ SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->device->timeout, 0, 1);
STp->header_ok = 0;
@@ -4611,7 +4612,7 @@ static int os_scsi_tape_open(struct inod
cmd[0] = TEST_UNIT_READY;
SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE,
- STp->timeout, MAX_RETRIES, 1);
+ STp->device->timeout, MAX_RETRIES, 1);
if ((SRpnt->sense[0] & 0x70) != 0x70 ||
(SRpnt->sense[2] & 0x0f) == NOT_READY)
break;
@@ -5822,7 +5823,8 @@ static int osst_probe(struct device *dev
tpnt->nbr_partitions = 0;
tpnt->min_block = 512;
tpnt->max_block = OS_DATA_SIZE;
- tpnt->timeout = OSST_TIMEOUT;
+ if (!SDp->timeout)
+ SDp->timeout = OSST_TIMEOUT;
tpnt->long_timeout = OSST_LONG_TIMEOUT;
/* Recognize OnStream tapes */
Index: scsi-misc-2.6/drivers/scsi/osst.h
===================================================================
--- scsi-misc-2.6.orig/drivers/scsi/osst.h
+++ scsi-misc-2.6/drivers/scsi/osst.h
@@ -548,7 +548,6 @@ struct osst_tape {
unsigned char default_drvbuffer; /* 0xff = don't touch, value 3 bits */
unsigned char pos_unknown; /* after reset position unknown */
int write_threshold;
- int timeout; /* timeout for normal commands */
int long_timeout; /* timeout for commands known to take long time*/
/* Mode characteristics */
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH RESEND 2/2] SCSI: add scsi_device->retries 2006-11-19 12:51 [PATCH RESEND 1/2] SCSI: use scsi_device->timeout consistently Tejun Heo @ 2006-11-19 12:52 ` Tejun Heo 2006-11-19 22:32 ` Kai Makisara 2006-11-19 22:01 ` [PATCH RESEND 1/2] SCSI: use scsi_device->timeout consistently Kai Makisara 1 sibling, 1 reply; 9+ messages in thread From: Tejun Heo @ 2006-11-19 12:52 UTC (permalink / raw) To: James.Bottomley, linux-scsi Add scsi_device->retries to provide generic control over command retries, which is very similar to sdev->timeout. The initial value is -1 and high level driver is free to override on attach if negative. Note that -1 has the same effect as 0 (no retry) and signifies that it's the default value. As with sdev->timeout, sdev->retries is exported under the device sysfs node. All high level drivers are converted to use it for retry value. However, there are exceptions. * sd_sync_cache() and sr::get_sectorsize() loop three more times around normal command execution on failure. * st uses three retry limits - MAX_RETRIES, MAX_WRITE_RETRIES and MAX_READY_RETRIES, which are all zero. This patch only converts MAX_RETRIES to sdev->retries. Defining WRITE and READY retries in terms of sdev->retries would make more sense. Signed-off-by: Tejun Heo <htejun@gmail.com> --- drivers/scsi/osst.c | 121 +++++++++++++++++++++++++++------------------ drivers/scsi/scsi_scan.c | 7 ++ drivers/scsi/scsi_sysfs.c | 28 ++++++++++ drivers/scsi/sd.c | 22 ++++---- drivers/scsi/sr.c | 10 ++- drivers/scsi/st.c | 10 ++- include/scsi/scsi_device.h | 1 7 files changed, 134 insertions(+), 65 deletions(-) Index: scsi-misc-2.6/drivers/scsi/sd.c =================================================================== --- scsi-misc-2.6.orig/drivers/scsi/sd.c +++ scsi-misc-2.6/drivers/scsi/sd.c @@ -187,7 +187,7 @@ static ssize_t sd_store_cache_type(struc rcd = ct & 0x01 ? 1 : 0; wce = ct & 0x02 ? 1 : 0; if (scsi_mode_sense(sdp, 0x08, 8, buffer, sizeof(buffer), sdp->timeout, - SD_MAX_RETRIES, &data, NULL)) + sdp->retries, &data, NULL)) return -EINVAL; len = min_t(size_t, sizeof(buffer), data.length - data.header_length - data.block_descriptor_length); @@ -198,7 +198,7 @@ static ssize_t sd_store_cache_type(struc sp = buffer_data[0] & 0x80 ? 1 : 0; if (scsi_mode_select(sdp, 1, sp, 8, buffer_data, len, sdp->timeout, - SD_MAX_RETRIES, &data, &sshdr)) { + sdp->retries, &data, &sshdr)) { if (scsi_sense_valid(&sshdr)) scsi_print_sense_hdr(sdkp->disk->disk_name, &sshdr); return -EINVAL; @@ -509,7 +509,7 @@ static int sd_init_command(struct scsi_c */ SCpnt->transfersize = sdp->sector_size; SCpnt->underflow = this_count << 9; - SCpnt->allowed = SD_MAX_RETRIES; + SCpnt->allowed = sdp->retries; SCpnt->timeout_per_command = sdp->timeout; /* @@ -758,7 +758,7 @@ static int sd_media_changed(struct gendi */ retval = -ENODEV; if (scsi_block_when_processing_errors(sdp)) - retval = scsi_test_unit_ready(sdp, sdp->timeout, SD_MAX_RETRIES); + retval = scsi_test_unit_ready(sdp, sdp->timeout, sdp->retries); /* * Unable to test, unit probably not ready. This usually @@ -804,7 +804,7 @@ static int sd_sync_cache(struct scsi_dev * flush everything. */ res = scsi_execute_req(sdp, cmd, DMA_NONE, NULL, 0, &sshdr, - sdp->timeout, SD_MAX_RETRIES); + sdp->timeout, sdp->retries); if (res == 0) break; } @@ -1052,7 +1052,7 @@ sd_spinup_disk(struct scsi_disk *sdkp, c the_result = scsi_execute_req(sdp, cmd, DMA_NONE, NULL, 0, &sshdr, sdp->timeout, - SD_MAX_RETRIES); + sdp->retries); /* * If the drive has indicated to us that it @@ -1108,7 +1108,7 @@ sd_spinup_disk(struct scsi_disk *sdkp, c cmd[4] = 1; /* Start spin cycle */ scsi_execute_req(sdp, cmd, DMA_NONE, NULL, 0, &sshdr, - sdp->timeout, SD_MAX_RETRIES); + sdp->timeout, sdp->retries); spintime_expire = jiffies + 100 * HZ; spintime = 1; } @@ -1183,7 +1183,7 @@ repeat: the_result = scsi_execute_req(sdp, cmd, DMA_FROM_DEVICE, buffer, longrc ? 12 : 8, &sshdr, - sdp->timeout, SD_MAX_RETRIES); + sdp->timeout, sdp->retries); if (media_not_present(sdkp, &sshdr)) return; @@ -1348,8 +1348,7 @@ sd_do_mode_sense(struct scsi_device *sdp struct scsi_sense_hdr *sshdr) { return scsi_mode_sense(sdp, dbd, modepage, buffer, len, - sdp->timeout, SD_MAX_RETRIES, data, - sshdr); + sdp->timeout, sdp->retries, data, sshdr); } /* @@ -1673,6 +1672,9 @@ static int sd_probe(struct device *dev) sdp->timeout = SD_MOD_TIMEOUT; } + if (sdp->retries < 0) + sdp->retries = SD_MAX_RETRIES; + gd->major = sd_major((index & 0xf0) >> 4); gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00); gd->minors = 16; Index: scsi-misc-2.6/include/scsi/scsi_device.h =================================================================== --- scsi-misc-2.6.orig/include/scsi/scsi_device.h +++ scsi-misc-2.6/include/scsi/scsi_device.h @@ -134,6 +134,7 @@ struct scsi_device { atomic_t ioerr_cnt; int timeout; + int retries; struct device sdev_gendev; struct class_device sdev_classdev; Index: scsi-misc-2.6/drivers/scsi/scsi_sysfs.c =================================================================== --- scsi-misc-2.6.orig/drivers/scsi/scsi_sysfs.c +++ scsi-misc-2.6/drivers/scsi/scsi_sysfs.c @@ -443,6 +443,33 @@ sdev_store_timeout (struct device *dev, static DEVICE_ATTR(timeout, S_IRUGO | S_IWUSR, sdev_show_timeout, sdev_store_timeout); static ssize_t +sdev_show_retries(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct scsi_device *sdev = to_scsi_device(dev); + int retries = sdev->retries; + + /* negative indicates uninitialized default */ + if (retries < 0) + retries = 0; + + return snprintf(buf, 20, "%d\n", retries); +} + +static ssize_t +sdev_store_retries(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +{ + struct scsi_device *sdev = to_scsi_device(dev); + int retries; + + sscanf(buf, "%d\n", &retries); + if (retries < 0) + return -EINVAL; + sdev->retries = retries; + return count; +} +static DEVICE_ATTR(retries, S_IRUGO | S_IWUSR, sdev_show_retries, sdev_store_retries); + +static ssize_t store_rescan_field (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { scsi_rescan_device(dev); @@ -548,6 +575,7 @@ static struct device_attribute *scsi_sys &dev_attr_delete, &dev_attr_state, &dev_attr_timeout, + &dev_attr_retries, &dev_attr_iocounterbits, &dev_attr_iorequest_cnt, &dev_attr_iodone_cnt, Index: scsi-misc-2.6/drivers/scsi/sr.c =================================================================== --- scsi-misc-2.6.orig/drivers/scsi/sr.c +++ scsi-misc-2.6/drivers/scsi/sr.c @@ -185,7 +185,7 @@ int sr_media_change(struct cdrom_device_ return -EINVAL; } - retval = scsi_test_unit_ready(sdev, sdev->timeout, MAX_RETRIES); + retval = scsi_test_unit_ready(sdev, sdev->timeout, sdev->retries); if (retval) { /* Unable to test, unit probably not ready. This usually * means there is no disc in the drive. Mark as changed, @@ -407,7 +407,7 @@ static int sr_init_command(struct scsi_c */ SCpnt->transfersize = sdev->sector_size; SCpnt->underflow = this_count << 9; - SCpnt->allowed = MAX_RETRIES; + SCpnt->allowed = sdev->retries; SCpnt->timeout_per_command = sdev->timeout; /* @@ -583,6 +583,8 @@ static int sr_probe(struct device *dev) if (!sdev->timeout) sdev->timeout = SR_TIMEOUT; + if (sdev->retries < 0) + sdev->retries = MAX_RETRIES; cd->cdi.ops = &sr_dops; cd->cdi.handle = cd; @@ -643,7 +645,7 @@ static void get_sectorsize(struct scsi_c /* Do the command and wait.. */ the_result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buffer, 8, NULL, sdev->timeout, - MAX_RETRIES); + sdev->retries); retries--; @@ -748,7 +750,7 @@ static void get_capabilities(struct scsi the_result = scsi_execute_req (sdev, cmd, DMA_NONE, NULL, 0, &sshdr, sdev->timeout, - MAX_RETRIES); + sdev->retries); retries++; } while (retries < 5 && Index: scsi-misc-2.6/drivers/scsi/st.c =================================================================== --- scsi-misc-2.6.orig/drivers/scsi/st.c +++ scsi-misc-2.6/drivers/scsi/st.c @@ -609,7 +609,7 @@ static int cross_eof(struct scsi_tape * tape_name(STp), forward ? "forward" : "backward")); SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE, - STp->device->timeout, MAX_RETRIES, 1); + STp->device->timeout, STp->device->retries, 1); if (!SRpnt) return (STp->buffer)->syscall_result; @@ -1787,7 +1787,7 @@ static long read_tape(struct scsi_tape * SRpnt = *aSRpnt; SRpnt = st_do_scsi(SRpnt, STp, cmd, bytes, DMA_FROM_DEVICE, - STp->device->timeout, MAX_RETRIES, 1); + STp->device->timeout, STp->device->retries, 1); release_buffering(STp, 1); *aSRpnt = SRpnt; if (!SRpnt) @@ -2451,7 +2451,7 @@ static int do_load_unload(struct scsi_ta ); SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE, - timeout, MAX_RETRIES, 1); + timeout, STp->device->retries, 1); if (!SRpnt) return (STp->buffer)->syscall_result; @@ -2751,7 +2751,7 @@ static int st_int_ioctl(struct scsi_tape } SRpnt = st_do_scsi(NULL, STp, cmd, datalen, direction, - timeout, MAX_RETRIES, 1); + timeout, STp->device->retries, 1); if (!SRpnt) return (STp->buffer)->syscall_result; @@ -3988,6 +3988,8 @@ static int st_probe(struct device *dev) tpnt->nbr_partitions = 0; if (!SDp->timeout) SDp->timeout = ST_TIMEOUT; + if (SDp->retries < 0) + SDp->retries = MAX_RETRIES; tpnt->long_timeout = ST_LONG_TIMEOUT; tpnt->try_dio = try_direct_io && !SDp->host->unchecked_isa_dma; Index: scsi-misc-2.6/drivers/scsi/osst.c =================================================================== --- scsi-misc-2.6.orig/drivers/scsi/osst.c +++ scsi-misc-2.6/drivers/scsi/osst.c @@ -667,6 +667,7 @@ err_out: static int osst_wait_ready(struct osst_tape * STp, struct osst_request ** aSRpnt, unsigned timeout, int initial_delay) { + struct scsi_device * sdev = STp->device; unsigned char cmd[MAX_COMMAND_SIZE]; struct osst_request * SRpnt; unsigned long startwait = jiffies; @@ -683,7 +684,8 @@ static int osst_wait_ready(struct osst_t memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = TEST_UNIT_READY; - SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->device->timeout, MAX_RETRIES, 1); + SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, + sdev->timeout, sdev->retries, 1); *aSRpnt = SRpnt; if (!SRpnt) return (-EBUSY); @@ -704,7 +706,8 @@ static int osst_wait_ready(struct osst_t memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = TEST_UNIT_READY; - SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->device->timeout, MAX_RETRIES, 1); + SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, + sdev->timeout, sdev->retries, 1); } *aSRpnt = SRpnt; #if DEBUG @@ -731,6 +734,7 @@ static int osst_wait_ready(struct osst_t */ static int osst_wait_for_medium(struct osst_tape * STp, struct osst_request ** aSRpnt, unsigned timeout) { + struct scsi_device * sdev = STp->device; unsigned char cmd[MAX_COMMAND_SIZE]; struct osst_request * SRpnt; unsigned long startwait = jiffies; @@ -744,7 +748,8 @@ static int osst_wait_for_medium(struct o memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = TEST_UNIT_READY; - SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->device->timeout, MAX_RETRIES, 1); + SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, + sdev->timeout, sdev->retries, 1); *aSRpnt = SRpnt; if (!SRpnt) return (-EBUSY); @@ -762,7 +767,8 @@ static int osst_wait_for_medium(struct o memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = TEST_UNIT_READY; - SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, STp->device->timeout, MAX_RETRIES, 1); + SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, + sdev->timeout, sdev->retries, 1); } *aSRpnt = SRpnt; #if DEBUG @@ -800,6 +806,7 @@ static int osst_position_tape_and_confir */ static int osst_flush_drive_buffer(struct osst_tape * STp, struct osst_request ** aSRpnt) { + struct scsi_device * sdev = STp->device; unsigned char cmd[MAX_COMMAND_SIZE]; struct osst_request * SRpnt; int result = 0; @@ -814,7 +821,8 @@ static int osst_flush_drive_buffer(struc cmd[0] = WRITE_FILEMARKS; cmd[1] = 1; - SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, STp->device->timeout, MAX_RETRIES, 1); + SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, + sdev->timeout, sdev->retries, 1); *aSRpnt = SRpnt; if (!SRpnt) return (-EBUSY); if (STp->buffer->syscall_result) { @@ -889,6 +897,7 @@ static int osst_wait_frame(struct osst_t static int osst_recover_wait_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int writing) { + struct scsi_device * sdev = STp->device; struct osst_request * SRpnt; unsigned char cmd[MAX_COMMAND_SIZE]; unsigned long startwait = jiffies; @@ -906,7 +915,7 @@ static int osst_recover_wait_frame(struc cmd[0] = WRITE_FILEMARKS; cmd[1] = 1; SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, - STp->device->timeout, MAX_RETRIES, 1); + sdev->timeout, sdev->retries, 1); while (retval && time_before (jiffies, startwait + 5*60*HZ)) { @@ -923,7 +932,7 @@ static int osst_recover_wait_frame(struc cmd[0] = READ_POSITION; SRpnt = osst_do_scsi(SRpnt, STp, cmd, 20, DMA_FROM_DEVICE, - STp->device->timeout, MAX_RETRIES, 1); + sdev->timeout, sdev->retries, 1); retval = ( STp->buffer->syscall_result || (STp->buffer)->b_data[15] > 25 ); STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize; @@ -947,6 +956,7 @@ static int osst_recover_wait_frame(struc */ static int osst_read_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int timeout) { + struct scsi_device * sdev = STp->device; unsigned char cmd[MAX_COMMAND_SIZE]; struct osst_request * SRpnt; int retval = 0; @@ -969,7 +979,7 @@ static int osst_read_frame(struct osst_t printk(OSST_DEB_MSG "%s:D: Reading frame from OnStream tape\n", name); #endif SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE, - STp->device->timeout, MAX_RETRIES, 1); + sdev->timeout, sdev->retries, 1); *aSRpnt = SRpnt; if (!SRpnt) return (-EBUSY); @@ -1018,6 +1028,7 @@ static int osst_read_frame(struct osst_t static int osst_initiate_read(struct osst_tape * STp, struct osst_request ** aSRpnt) { + struct scsi_device * sdev = STp->device; struct st_partstat * STps = &(STp->ps[STp->partition]); struct osst_request * SRpnt ; unsigned char cmd[MAX_COMMAND_SIZE]; @@ -1045,7 +1056,7 @@ static int osst_initiate_read(struct oss printk(OSST_DEB_MSG "%s:D: Start Read Ahead on OnStream tape\n", name); #endif SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, 0, DMA_NONE, - STp->device->timeout, MAX_RETRIES, 1); + sdev->timeout, sdev->retries, 1); *aSRpnt = SRpnt; if ((retval = STp->buffer->syscall_result)) printk(KERN_WARNING "%s:W: Error starting read ahead\n", name); @@ -1388,6 +1399,7 @@ static int osst_seek_sector(struct osst_ static int osst_read_back_buffer_and_rewrite(struct osst_tape * STp, struct osst_request ** aSRpnt, unsigned int frame, unsigned int skip, int pending) { + struct scsi_device * sdev = STp->device; struct osst_request * SRpnt = * aSRpnt; unsigned char * buffer, * p; unsigned char cmd[MAX_COMMAND_SIZE]; @@ -1427,7 +1439,7 @@ static int osst_read_back_buffer_and_rew cmd[8] = 32768 & 0xff; SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_FROM_DEVICE, - STp->device->timeout, MAX_RETRIES, 1); + sdev->timeout, sdev->retries, 1); if ((STp->buffer)->syscall_result || !SRpnt) { printk(KERN_ERR "%s:E: Failed to read frame back from OnStream buffer\n", name); @@ -1499,7 +1511,7 @@ static int osst_read_back_buffer_and_rew p[0], p[1], p[2], p[3]); #endif SRpnt = osst_do_scsi(SRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE, - STp->device->timeout, MAX_RETRIES, 1); + sdev->timeout, sdev->retries, 1); if (STp->buffer->syscall_result) flag = 1; @@ -1515,7 +1527,7 @@ static int osst_read_back_buffer_and_rew cmd[0] = WRITE_FILEMARKS; cmd[1] = 1; SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, - STp->device->timeout, MAX_RETRIES, 1); + sdev->timeout, sdev->retries, 1); #if DEBUG if (debugging) { printk(OSST_DEB_MSG "%s:D: Sleeping in re-write wait ready\n", name); @@ -1530,7 +1542,7 @@ static int osst_read_back_buffer_and_rew cmd[0] = TEST_UNIT_READY; SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, - STp->device->timeout, MAX_RETRIES, 1); + sdev->timeout, sdev->retries, 1); if (SRpnt->sense[2] == 2 && SRpnt->sense[12] == 4 && (SRpnt->sense[13] == 1 || SRpnt->sense[13] == 8)) { @@ -1586,6 +1598,7 @@ static int osst_read_back_buffer_and_rew static int osst_reposition_and_retry(struct osst_tape * STp, struct osst_request ** aSRpnt, unsigned int frame, unsigned int skip, int pending) { + struct scsi_device * sdev = STp->device; unsigned char cmd[MAX_COMMAND_SIZE]; struct osst_request * SRpnt; char * name = tape_name(STp); @@ -1635,7 +1648,7 @@ static int osst_reposition_and_retry(str name, STp->frame_seq_number-1, STp->first_frame_position); #endif SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE, - STp->device->timeout, MAX_RETRIES, 1); + sdev->timeout, sdev->retries, 1); *aSRpnt = SRpnt; if (STp->buffer->syscall_result) { /* additional write error */ @@ -2092,7 +2105,8 @@ static void osst_set_retries(struct osst if (debugging) printk(OSST_DEB_MSG "%s:D: Setting number of retries on OnStream tape to %d\n", name, retries); - SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->device->timeout, 0, 1); + SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, + STp->device->timeout, 0, 1); *aSRpnt = SRpnt; if ((STp->buffer)->syscall_result) @@ -2601,6 +2615,7 @@ static unsigned int osst_parse_firmware_ */ static int osst_configure_onstream(struct osst_tape *STp, struct osst_request ** aSRpnt) { + struct scsi_device * sdev = STp->device; unsigned char cmd[MAX_COMMAND_SIZE]; char * name = tape_name(STp); struct osst_request * SRpnt = * aSRpnt; @@ -2618,7 +2633,7 @@ static int osst_configure_onstream(struc } if (STp->os_fw_rev < 10600) { - printk(KERN_INFO "%s:I: Old OnStream firmware revision detected (%s),\n", name, STp->device->rev); + printk(KERN_INFO "%s:I: Old OnStream firmware revision detected (%s),\n", name, sdev->rev); printk(KERN_INFO "%s:I: an upgrade to version 1.06 or above is recommended\n", name); } @@ -2632,7 +2647,7 @@ static int osst_configure_onstream(struc cmd[2] = BLOCK_SIZE_PAGE; cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH; - SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->device->timeout, 0, 1); + SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, sdev->timeout, 0, 1); if (SRpnt == NULL) { #if DEBUG printk(OSST_DEB_MSG "osst :D: Busy\n"); @@ -2669,7 +2684,7 @@ static int osst_configure_onstream(struc cmd[1] = 0x10; cmd[4] = BLOCK_SIZE_PAGE_LENGTH + MODE_HEADER_LENGTH; - SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->device->timeout, 0, 1); + SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, sdev->timeout, 0, 1); *aSRpnt = SRpnt; if ((STp->buffer)->syscall_result != 0) { printk (KERN_ERR "%s:E: Couldn't set tape block size mode page\n", name); @@ -2709,7 +2724,7 @@ static int osst_configure_onstream(struc (STp->buffer)->b_data[MODE_HEADER_LENGTH + 6] = 0; (STp->buffer)->b_data[MODE_HEADER_LENGTH + 7] = 0; - SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->device->timeout, 0, 1); + SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, sdev->timeout, 0, 1); *aSRpnt = SRpnt; if ((STp->buffer)->syscall_result != 0) { @@ -2724,7 +2739,7 @@ static int osst_configure_onstream(struc cmd[2] = CAPABILITIES_PAGE; cmd[4] = CAPABILITIES_PAGE_LENGTH + MODE_HEADER_LENGTH; - SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->device->timeout, 0, 1); + SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, sdev->timeout, 0, 1); *aSRpnt = SRpnt; if ((STp->buffer)->syscall_result != 0) { @@ -2744,7 +2759,7 @@ static int osst_configure_onstream(struc cmd[2] = TAPE_PARAMTR_PAGE; cmd[4] = TAPE_PARAMTR_PAGE_LENGTH + MODE_HEADER_LENGTH; - SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->device->timeout, 0, 1); + SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, sdev->timeout, 0, 1); *aSRpnt = SRpnt; if ((STp->buffer)->syscall_result != 0) { @@ -2801,6 +2816,7 @@ static int cross_eof(struct osst_tape *S static int osst_get_frame_position(struct osst_tape *STp, struct osst_request ** aSRpnt) { + struct scsi_device * sdev = STp->device; unsigned char scmd[MAX_COMMAND_SIZE]; struct osst_request * SRpnt; int result = 0; @@ -2819,7 +2835,7 @@ static int osst_get_frame_position(struc STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24; SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 20, DMA_FROM_DEVICE, - STp->device->timeout, MAX_RETRIES, 1); + sdev->timeout, sdev->retries, 1); if (!SRpnt) { STp->buffer->b_data = olddata; STp->buffer->buffer_size = oldsize; return (-EBUSY); @@ -2839,7 +2855,7 @@ static int osst_get_frame_position(struc scmd[0] = READ_POSITION; STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24; SRpnt = osst_do_scsi(SRpnt, STp, scmd, 20, DMA_FROM_DEVICE, - STp->device->timeout, MAX_RETRIES, 1); + sdev->timeout, sdev->retries, 1); #if DEBUG printk(OSST_DEB_MSG "%s:D: Reread position, reason=[%02x:%02x:%02x], result=[%s%02x:%02x:%02x]\n", name, mysense[2], mysense[12], mysense[13], STp->buffer->syscall_result?"":"ok:", @@ -2917,8 +2933,8 @@ static int osst_set_frame_position(struc if (skip) scmd[9] = 0x80; - SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 0, DMA_NONE, STp->long_timeout, - MAX_RETRIES, 1); + SRpnt = osst_do_scsi(*aSRpnt, STp, scmd, 0, DMA_NONE, + STp->long_timeout, STp->device->retries, 1); if (!SRpnt) return (-EBUSY); *aSRpnt = SRpnt; @@ -2970,6 +2986,7 @@ out: /* Flush the write buffer (never need to write if variable blocksize). */ static int osst_flush_write_buffer(struct osst_tape *STp, struct osst_request ** aSRpnt) { + struct scsi_device * sdev = STp->device; int offset, transfer, blks = 0; int result = 0; unsigned char cmd[MAX_COMMAND_SIZE]; @@ -3056,7 +3073,7 @@ static int osst_flush_write_buffer(struc #endif SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, transfer, DMA_TO_DEVICE, - STp->device->timeout, MAX_RETRIES, 1); + sdev->timeout, sdev->retries, 1); *aSRpnt = SRpnt; if (!SRpnt) return (-EBUSY); @@ -3162,6 +3179,7 @@ static int osst_flush_buffer(struct osst static int osst_write_frame(struct osst_tape * STp, struct osst_request ** aSRpnt, int synchronous) { + struct scsi_device * sdev = STp->device; unsigned char cmd[MAX_COMMAND_SIZE]; struct osst_request * SRpnt; int blks; @@ -3212,8 +3230,8 @@ static int osst_write_frame(struct osst_ if (!synchronous) STp->write_pending = 1; #endif - SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE, STp->device->timeout, - MAX_RETRIES, synchronous); + SRpnt = osst_do_scsi(*aSRpnt, STp, cmd, OS_FRAME_SIZE, DMA_TO_DEVICE, + sdev->timeout, sdev->retries, synchronous); if (!SRpnt) return (-EBUSY); *aSRpnt = SRpnt; @@ -3817,6 +3835,7 @@ static void osst_log_options(struct osst static int osst_set_options(struct osst_tape *STp, long options) { + struct scsi_device * sdev = STp->device; int value; long code; struct st_modedef * STm; @@ -3844,7 +3863,7 @@ static int osst_set_options(struct osst_ STp->do_auto_lock = (options & MT_ST_AUTO_LOCK) != 0; STp->can_bsr = (options & MT_ST_CAN_BSR) != 0; STp->omit_blklims = (options & MT_ST_NO_BLKLIMS) != 0; - if ((STp->device)->scsi_level >= SCSI_2) + if (sdev->scsi_level >= SCSI_2) STp->can_partitions = (options & MT_ST_CAN_PARTITIONS) != 0; STp->scsi2_logical = (options & MT_ST_SCSI2LOGICAL) != 0; STm->sysv = (options & MT_ST_SYSV) != 0; @@ -3873,7 +3892,7 @@ static int osst_set_options(struct osst_ STp->can_bsr = value; if ((options & MT_ST_NO_BLKLIMS) != 0) STp->omit_blklims = value; - if ((STp->device)->scsi_level >= SCSI_2 && + if (sdev->scsi_level >= SCSI_2 && (options & MT_ST_CAN_PARTITIONS) != 0) STp->can_partitions = value; if ((options & MT_ST_SCSI2LOGICAL) != 0) @@ -3922,7 +3941,7 @@ static int osst_set_options(struct osst_ (value & ~MT_ST_SET_LONG_TIMEOUT)); } else { - STp->device->timeout = value * HZ; + sdev->timeout = value * HZ; printk(KERN_INFO "%s:I: Normal timeout set to %d seconds.\n", name, value); } } @@ -3974,6 +3993,7 @@ static int osst_set_options(struct osst_ static int osst_int_ioctl(struct osst_tape * STp, struct osst_request ** aSRpnt, unsigned int cmd_in, unsigned long arg) { + struct scsi_device * sdev = STp->device; int timeout; long ltmp; int i, ioctl_result; @@ -4113,7 +4133,7 @@ static int osst_int_ioctl(struct osst_ta cmd[2] = (arg >> 16); cmd[3] = (arg >> 8); cmd[4] = arg; - timeout = STp->device->timeout; + timeout = sdev->timeout; #if DEBUG if (debugging) printk(OSST_DEB_MSG "%s:D: Writing %d setmark(s).\n", name, @@ -4140,7 +4160,7 @@ static int osst_int_ioctl(struct osst_ta cmd[4] = 3; /* retension then mount */ if (cmd_in == MTOFFL) cmd[4] = 4; /* rewind then eject */ - timeout = STp->device->timeout; + timeout = sdev->timeout; #if DEBUG if (debugging) { switch (cmd_in) { @@ -4249,7 +4269,8 @@ static int osst_int_ioctl(struct osst_ta return (-ENOSYS); } - SRpnt = osst_do_scsi(SRpnt, STp, cmd, datalen, direction, timeout, MAX_RETRIES, 1); + SRpnt = osst_do_scsi(SRpnt, STp, cmd, datalen, direction, timeout, + sdev->retries, 1); ioctl_result = (STp->buffer)->syscall_result; @@ -4364,6 +4385,7 @@ static int os_scsi_tape_open(struct inod unsigned char cmd[MAX_COMMAND_SIZE]; struct osst_request * SRpnt = NULL; struct osst_tape * STp; + struct scsi_device * sdev; struct st_modedef * STm; struct st_partstat * STps; char * name; @@ -4385,6 +4407,7 @@ static int os_scsi_tape_open(struct inod } name = tape_name(STp); + sdev = STp->device; if (STp->in_use) { write_unlock(&os_scsi_tapes_lock); @@ -4393,7 +4416,7 @@ static int os_scsi_tape_open(struct inod #endif return (-EBUSY); } - if (scsi_device_get(STp->device)) { + if (scsi_device_get(sdev)) { write_unlock(&os_scsi_tapes_lock); #if DEBUG printk(OSST_DEB_MSG "%s:D: Failed scsi_device_get.\n", name); @@ -4405,7 +4428,7 @@ static int os_scsi_tape_open(struct inod write_unlock(&os_scsi_tapes_lock); STp->rew_at_close = TAPE_REWIND(inode); - if( !scsi_block_when_processing_errors(STp->device) ) { + if( !scsi_block_when_processing_errors(sdev) ) { return -ENXIO; } @@ -4465,7 +4488,8 @@ static int os_scsi_tape_open(struct inod memset (cmd, 0, MAX_COMMAND_SIZE); cmd[0] = TEST_UNIT_READY; - SRpnt = osst_do_scsi(NULL, STp, cmd, 0, DMA_NONE, STp->device->timeout, MAX_RETRIES, 1); + SRpnt = osst_do_scsi(NULL, STp, cmd, 0, DMA_NONE, + sdev->timeout, sdev->retries, 1); if (!SRpnt) { retval = (STp->buffer)->syscall_result; /* FIXME - valid? */ goto err_out; @@ -4486,7 +4510,7 @@ static int os_scsi_tape_open(struct inod cmd[1] = 1; cmd[4] = 1; SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, - STp->device->timeout, MAX_RETRIES, 1); + sdev->timeout, sdev->retries, 1); } osst_wait_ready(STp, &SRpnt, (SRpnt->sense[13]==1?15:3) * 60, 0); } @@ -4503,7 +4527,7 @@ static int os_scsi_tape_open(struct inod cmd[0] = TEST_UNIT_READY; SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, - STp->device->timeout, MAX_RETRIES, 1); + sdev->timeout, sdev->retries, 1); if ((SRpnt->sense[0] & 0x70) != 0x70 || (SRpnt->sense[2] & 0x0f) != UNIT_ATTENTION) break; @@ -4539,7 +4563,7 @@ static int os_scsi_tape_open(struct inod cmd[2] = VENDOR_IDENT_PAGE; cmd[4] = VENDOR_IDENT_PAGE_LENGTH + MODE_HEADER_LENGTH; - SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, STp->device->timeout, 0, 1); + SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, sdev->timeout, 0, 1); if (STp->buffer->syscall_result || STp->buffer->b_data[MODE_HEADER_LENGTH + 2] != 'L' || @@ -4602,7 +4626,7 @@ static int os_scsi_tape_open(struct inod #if DEBUG printk(OSST_DEB_MSG "%s:D: Applying soft reset\n", name); #endif - SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, STp->device->timeout, 0, 1); + SRpnt = osst_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, sdev->timeout, 0, 1); STp->header_ok = 0; @@ -4612,7 +4636,7 @@ static int os_scsi_tape_open(struct inod cmd[0] = TEST_UNIT_READY; SRpnt = osst_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, - STp->device->timeout, MAX_RETRIES, 1); + sdev->timeout, sdev->retries, 1); if ((SRpnt->sense[0] & 0x70) != 0x70 || (SRpnt->sense[2] & 0x0f) == NOT_READY) break; @@ -4640,7 +4664,7 @@ static int os_scsi_tape_open(struct inod printk(KERN_INFO "%s:I: Device did not become Ready in open\n", name); if ((STp->buffer)->syscall_result != 0) { - if ((STp->device)->scsi_level >= SCSI_2 && + if (sdev->scsi_level >= SCSI_2 && (SRpnt->sense[0] & 0x70) == 0x70 && (SRpnt->sense[2] & 0x0f) == NOT_READY && SRpnt->sense[12] == 0x3a) { /* Check ASC */ @@ -4718,7 +4742,7 @@ err_out: normalize_buffer(STp->buffer); STp->header_ok = 0; STp->in_use = 0; - scsi_device_put(STp->device); + scsi_device_put(sdev); return retval; } @@ -4849,6 +4873,7 @@ static int osst_ioctl(struct inode * ino struct st_partstat * STps; struct osst_request * SRpnt = NULL; struct osst_tape * STp = file->private_data; + struct scsi_device * sdev = STp->device; char * name = tape_name(STp); void __user * p = (void __user *)arg; @@ -4871,7 +4896,7 @@ static int osst_ioctl(struct inode * ino * may try and take the device offline, in which case all further * access to the device is prohibited. */ - if( !scsi_block_when_processing_errors(STp->device) ) { + if( !scsi_block_when_processing_errors(sdev) ) { retval = (-ENXIO); goto out; } @@ -4958,7 +4983,7 @@ static int osst_ioctl(struct inode * ino } reset_state(STp); /* remove this when the midlevel properly clears was_reset */ - STp->device->was_reset = 0; + sdev->was_reset = 0; } if (mtc.mt_op != MTCOMPRESSION && mtc.mt_op != MTLOCK && @@ -5165,7 +5190,7 @@ static int osst_ioctl(struct inode * ino up(&STp->lock); - return scsi_ioctl(STp->device, cmd_in, p); + return scsi_ioctl(sdev, cmd_in, p); out: if (SRpnt) osst_release_request(SRpnt); @@ -5825,6 +5850,8 @@ static int osst_probe(struct device *dev tpnt->max_block = OS_DATA_SIZE; if (!SDp->timeout) SDp->timeout = OSST_TIMEOUT; + if (SDp->retries < 0) + SDp->retries = MAX_RETRIES; tpnt->long_timeout = OSST_LONG_TIMEOUT; /* Recognize OnStream tapes */ Index: scsi-misc-2.6/drivers/scsi/scsi_scan.c =================================================================== --- scsi-misc-2.6.orig/drivers/scsi/scsi_scan.c +++ scsi-misc-2.6/drivers/scsi/scsi_scan.c @@ -261,6 +261,13 @@ static struct scsi_device *scsi_alloc_sd */ sdev->borken = 1; + /* + * -1 indicates uninitialized default and equivalent to zero + * in effect. High level driver is allowed to adjust retries + * if it's negative. + */ + sdev->retries = -1; + sdev->request_queue = scsi_alloc_queue(sdev); if (!sdev->request_queue) { /* release fn is set up in scsi_sysfs_device_initialise, so ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH RESEND 2/2] SCSI: add scsi_device->retries 2006-11-19 12:52 ` [PATCH RESEND 2/2] SCSI: add scsi_device->retries Tejun Heo @ 2006-11-19 22:32 ` Kai Makisara 2006-11-19 23:31 ` Tejun Heo 0 siblings, 1 reply; 9+ messages in thread From: Kai Makisara @ 2006-11-19 22:32 UTC (permalink / raw) To: Tejun Heo; +Cc: James.Bottomley, linux-scsi On Sun, 19 Nov 2006, Tejun Heo wrote: > Add scsi_device->retries to provide generic control over command > retries, which is very similar to sdev->timeout. The initial value is > -1 and high level driver is free to override on attach if negative. > Note that -1 has the same effect as 0 (no retry) and signifies that > it's the default value. As with sdev->timeout, sdev->retries is > exported under the device sysfs node. > > All high level drivers are converted to use it for retry value. > However, there are exceptions. > > * sd_sync_cache() and sr::get_sectorsize() loop three more times > around normal command execution on failure. > > * st uses three retry limits - MAX_RETRIES, MAX_WRITE_RETRIES and > MAX_READY_RETRIES, which are all zero. This patch only converts > MAX_RETRIES to sdev->retries. Defining WRITE and READY retries in > terms of sdev->retries would make more sense. > I am neither acking nor naking this now. The patch does not change st behavior but moves part of the retry strategy out of the driver. (Which is also good because it makes one of the retry limits user changeable.) Combining all retry counts is something that may not be a good thing. Below is justification why st has three different retry limits. For some devices one number of retries is not perfect for all functions. The firmware of tape devices usually retries quite thoroughly before returning error. This is why the default zero applies to most cases. MAX_WRITE_RETRIES is separate from MAX_RETRIES because a plausible strategy might be (maybe not any more) to allow no retries for write but allow retries for reading and repositioning. The writes should fail directly so that the minimum number of marginal errors will be written. The reads can be retried so that even marginal data can be recovered. (Note that this may lead to tape positioning errors and may not be a good strategy in all cases.) MAX_READY_RETRIES is used for commands that don't move the tape. This is a situation where retrying is probably harmless. -- Kai ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH RESEND 2/2] SCSI: add scsi_device->retries 2006-11-19 22:32 ` Kai Makisara @ 2006-11-19 23:31 ` Tejun Heo 2006-11-20 21:42 ` Kai Makisara 0 siblings, 1 reply; 9+ messages in thread From: Tejun Heo @ 2006-11-19 23:31 UTC (permalink / raw) To: Kai Makisara; +Cc: James.Bottomley, linux-scsi Hello, Kai Makisara wrote: >> * st uses three retry limits - MAX_RETRIES, MAX_WRITE_RETRIES and >> MAX_READY_RETRIES, which are all zero. This patch only converts >> MAX_RETRIES to sdev->retries. Defining WRITE and READY retries in >> terms of sdev->retries would make more sense. >> > I am neither acking nor naking this now. The patch does not change st > behavior but moves part of the retry strategy out of the driver. (Which is > also good because it makes one of the retry limits user changeable.) > > Combining all retry counts is something that may not be a good thing. > Below is justification why st has three different retry limits. > > For some devices one number of retries is not perfect for all functions. > > The firmware of tape devices usually retries quite thoroughly before > returning error. This is why the default zero applies to most cases. > > MAX_WRITE_RETRIES is separate from MAX_RETRIES because a plausible > strategy might be (maybe not any more) to allow no retries for write but > allow retries for reading and repositioning. The writes should fail > directly so that the minimum number of marginal errors will be written. > The reads can be retried so that even marginal data can be recovered. > (Note that this may lead to tape positioning errors and may not be a > good strategy in all cases.) > > MAX_READY_RETRIES is used for commands that don't move the tape. This is a > situation where retrying is probably harmless. I see. Then, how about adding and initializing STp->write_retries and STp->ready_retries according to SDp->retries (some reasonable default value, say write_retries is always zero while ready_retries is round up of retries * 1.1) and export both through sysfs? That will give lower level primitive control as other ULDs do and also allow users to configure each timeout separately if necessary. Thanks. -- tejun ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH RESEND 2/2] SCSI: add scsi_device->retries 2006-11-19 23:31 ` Tejun Heo @ 2006-11-20 21:42 ` Kai Makisara 0 siblings, 0 replies; 9+ messages in thread From: Kai Makisara @ 2006-11-20 21:42 UTC (permalink / raw) To: Tejun Heo; +Cc: James Bottomley, linux-scsi On Mon, 20 Nov 2006, Tejun Heo wrote: > Hello, > > Kai Makisara wrote: > > > * st uses three retry limits - MAX_RETRIES, MAX_WRITE_RETRIES and > > > MAX_READY_RETRIES, which are all zero. This patch only converts > > > MAX_RETRIES to sdev->retries. Defining WRITE and READY retries in > > > terms of sdev->retries would make more sense. > > > > > I am neither acking nor naking this now. The patch does not change st > > behavior but moves part of the retry strategy out of the driver. (Which is > > also good because it makes one of the retry limits user changeable.) > > > > Combining all retry counts is something that may not be a good thing. Below > > is justification why st has three different retry limits. > > > > For some devices one number of retries is not perfect for all functions. > > > > The firmware of tape devices usually retries quite thoroughly before > > returning error. This is why the default zero applies to most cases. > > > > MAX_WRITE_RETRIES is separate from MAX_RETRIES because a plausible strategy > > might be (maybe not any more) to allow no retries for write but allow > > retries for reading and repositioning. The writes should fail directly so > > that the minimum number of marginal errors will be written. The reads can be > > retried so that even marginal data can be recovered. (Note that this may > > lead to tape positioning errors and may not be a good strategy in all > > cases.) > > > > MAX_READY_RETRIES is used for commands that don't move the tape. This is a > > situation where retrying is probably harmless. > > I see. Then, how about adding and initializing STp->write_retries and > STp->ready_retries according to SDp->retries (some reasonable default value, > say write_retries is always zero while ready_retries is round up of retries * > 1.1) and export both through sysfs? That will give lower level primitive > control as other ULDs do and also allow users to configure each timeout > separately if necessary. > When I made the timeouts user changeable (using ioctl), I also thought about making retries changeable. However, there did not seem to be any real need to change the retry limits and I postponed the implementation. Now it would be easy to implement with sysfs but it may be still best to postpone that until someone asks for that feature. One possibility would be to transform the different retry limit philosophy into a comment in the source and use lowlevel retry limit for all commands. The different limits are actually comments also now because I don't think anyone changes the defaults. (If anyone does, please tell us!) If this is done, I will have the suspicion that someone some time changes the low-level retry limit to other than zero without knowing what this does to tapes. -- Kai ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH RESEND 1/2] SCSI: use scsi_device->timeout consistently 2006-11-19 12:51 [PATCH RESEND 1/2] SCSI: use scsi_device->timeout consistently Tejun Heo 2006-11-19 12:52 ` [PATCH RESEND 2/2] SCSI: add scsi_device->retries Tejun Heo @ 2006-11-19 22:01 ` Kai Makisara 2006-11-19 23:26 ` Tejun Heo 1 sibling, 1 reply; 9+ messages in thread From: Kai Makisara @ 2006-11-19 22:01 UTC (permalink / raw) To: Tejun Heo; +Cc: James Bottomley, linux-scsi On Sun, 19 Nov 2006, Tejun Heo wrote: > Each high level driver uses scsi_device->timeout diffrently. > ... > Index: scsi-misc-2.6/drivers/scsi/st.c > =================================================================== > --- scsi-misc-2.6.orig/drivers/scsi/st.c > +++ scsi-misc-2.6/drivers/scsi/st.c > @@ -3986,7 +3986,8 @@ static int st_probe(struct device *dev) > tpnt->partition = 0; > tpnt->new_partition = 0; > tpnt->nbr_partitions = 0; > - tpnt->device->timeout = ST_TIMEOUT; > + if (!SDp->timeout) > + SDp->timeout = ST_TIMEOUT; I don't think this should be done. It probably makes the default timeout way too short. The error recovery with tapes takes a long time. The user can change the timeout if the default (900 seconds) seems too long (or short). I don't think there is anything in the midlevel or low-level code to set the timeout based on the device characteristics. This is left to the ULD. -- Kai ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH RESEND 1/2] SCSI: use scsi_device->timeout consistently 2006-11-19 22:01 ` [PATCH RESEND 1/2] SCSI: use scsi_device->timeout consistently Kai Makisara @ 2006-11-19 23:26 ` Tejun Heo 2006-11-20 21:25 ` Kai Makisara 0 siblings, 1 reply; 9+ messages in thread From: Tejun Heo @ 2006-11-19 23:26 UTC (permalink / raw) To: Kai Makisara; +Cc: James Bottomley, linux-scsi Kai Makisara wrote: > On Sun, 19 Nov 2006, Tejun Heo wrote: > >> Each high level driver uses scsi_device->timeout diffrently. >> > ... >> Index: scsi-misc-2.6/drivers/scsi/st.c >> =================================================================== >> --- scsi-misc-2.6.orig/drivers/scsi/st.c >> +++ scsi-misc-2.6/drivers/scsi/st.c >> @@ -3986,7 +3986,8 @@ static int st_probe(struct device *dev) >> tpnt->partition = 0; >> tpnt->new_partition = 0; >> tpnt->nbr_partitions = 0; >> - tpnt->device->timeout = ST_TIMEOUT; >> + if (!SDp->timeout) >> + SDp->timeout = ST_TIMEOUT; > > I don't think this should be done. It probably makes the default timeout > way too short. The error recovery with tapes takes a long time. The user > can change the timeout if the default (900 seconds) seems too long (or > short). > > I don't think there is anything in the midlevel or low-level code to set > the timeout based on the device characteristics. This is left to the ULD. Low level driver should configure timeout or retries to a known value iff it knows what it's doing, when it knows both transport and device-type specific characteristic. AFAICS, the only driver which modifies sdev->timeout is ipr and it does so only when it knows the device is of certain type. So, I don't think it will cause any trouble, and using different initialization in different ULDs is too subtle. Thanks. -- tejun ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH RESEND 1/2] SCSI: use scsi_device->timeout consistently 2006-11-19 23:26 ` Tejun Heo @ 2006-11-20 21:25 ` Kai Makisara 2006-11-21 2:14 ` Tejun Heo 0 siblings, 1 reply; 9+ messages in thread From: Kai Makisara @ 2006-11-20 21:25 UTC (permalink / raw) To: Tejun Heo; +Cc: James Bottomley, linux-scsi On Mon, 20 Nov 2006, Tejun Heo wrote: > Kai Makisara wrote: > > On Sun, 19 Nov 2006, Tejun Heo wrote: > > > > > Each high level driver uses scsi_device->timeout diffrently. > > > > > ... > > > Index: scsi-misc-2.6/drivers/scsi/st.c > > > =================================================================== > > > --- scsi-misc-2.6.orig/drivers/scsi/st.c > > > +++ scsi-misc-2.6/drivers/scsi/st.c > >> @@ -3986,7 +3986,8 @@ static int st_probe(struct device *dev) > > > tpnt->partition = 0; > > > tpnt->new_partition = 0; > > > tpnt->nbr_partitions = 0; > > > - tpnt->device->timeout = ST_TIMEOUT; > > > + if (!SDp->timeout) > > > + SDp->timeout = ST_TIMEOUT; > > > > I don't think this should be done. It probably makes the default timeout way > > too short. The error recovery with tapes takes a long time. The user can > > change the timeout if the default (900 seconds) seems too long (or short). > > > > I don't think there is anything in the midlevel or low-level code to set the > > timeout based on the device characteristics. This is left to the ULD. > > Low level driver should configure timeout or retries to a known value iff it > knows what it's doing, when it knows both transport and device-type specific > characteristic. I am not so optimistic ;-) > AFAICS, the only driver which modifies sdev->timeout is ipr > and it does so only when it knows the device is of certain type. So, I don't > think it will cause any trouble, and using different initialization in > different ULDs is too subtle. > It does not cause trouble now but I think it is an accident waiting to happen. The ULD probably knows more about the device characteristics than the low-level driver. (I admit that there are other than device specific aspects in setting timeouts and these should not be in ULD.) What about this variant: if (SDp->timeout < ST_TIMEOUT) SDp->timeout = ST_TIMEOUT; It does guarantee that the timeout is long enough for tape drives. It also lets the low-level driver set a longer timeout if it has some reason to make it longer than the ULD does. -- Kai ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH RESEND 1/2] SCSI: use scsi_device->timeout consistently 2006-11-20 21:25 ` Kai Makisara @ 2006-11-21 2:14 ` Tejun Heo 0 siblings, 0 replies; 9+ messages in thread From: Tejun Heo @ 2006-11-21 2:14 UTC (permalink / raw) To: Kai Makisara; +Cc: James Bottomley, linux-scsi Hello, Kai Makisara wrote: >>> I don't think there is anything in the midlevel or low-level code to set the >>> timeout based on the device characteristics. This is left to the ULD. >> Low level driver should configure timeout or retries to a known value iff it >> knows what it's doing, when it knows both transport and device-type specific >> characteristic. > > I am not so optimistic ;-) > >> AFAICS, the only driver which modifies sdev->timeout is ipr >> and it does so only when it knows the device is of certain type. So, I don't >> think it will cause any trouble, and using different initialization in >> different ULDs is too subtle. >> > It does not cause trouble now but I think it is an accident waiting to > happen. The ULD probably knows more about the device characteristics than > the low-level driver. (I admit that there are other than device specific > aspects in setting timeouts and these should not be in ULD.) Yeah, in general, ULD should be in charge for determining default values but, then again, SCSI ULDs are driving extremely wide variety of devices hanging off all sorts of transports these days. > What about this variant: > if (SDp->timeout < ST_TIMEOUT) > SDp->timeout = ST_TIMEOUT; > > It does guarantee that the timeout is long enough for tape drives. It also > lets the low-level driver set a longer timeout if it has some reason to > make it longer than the ULD does. I don't know enough about tape devices to determine what's right here. I think it's better for me to leave st and osst to people who know better. I'll re-submit without os and osst changes. Thanks. -- tejun ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2006-11-21 2:14 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2006-11-19 12:51 [PATCH RESEND 1/2] SCSI: use scsi_device->timeout consistently Tejun Heo 2006-11-19 12:52 ` [PATCH RESEND 2/2] SCSI: add scsi_device->retries Tejun Heo 2006-11-19 22:32 ` Kai Makisara 2006-11-19 23:31 ` Tejun Heo 2006-11-20 21:42 ` Kai Makisara 2006-11-19 22:01 ` [PATCH RESEND 1/2] SCSI: use scsi_device->timeout consistently Kai Makisara 2006-11-19 23:26 ` Tejun Heo 2006-11-20 21:25 ` Kai Makisara 2006-11-21 2:14 ` Tejun Heo
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox