|
@@ -464,7 +464,6 @@ int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd,
|
|
|
|
|
|
/* use request field to save the ptr. to completion struct. */
|
|
/* use request field to save the ptr. to completion struct. */
|
|
scp->request = (struct request *)&wait;
|
|
scp->request = (struct request *)&wait;
|
|
- scp->timeout_per_command = timeout*HZ;
|
|
|
|
scp->cmd_len = 12;
|
|
scp->cmd_len = 12;
|
|
scp->cmnd = cmnd;
|
|
scp->cmnd = cmnd;
|
|
cmndinfo.priority = IOCTL_PRI;
|
|
cmndinfo.priority = IOCTL_PRI;
|
|
@@ -1995,23 +1994,12 @@ static void gdth_putq(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar priority)
|
|
register Scsi_Cmnd *pscp;
|
|
register Scsi_Cmnd *pscp;
|
|
register Scsi_Cmnd *nscp;
|
|
register Scsi_Cmnd *nscp;
|
|
ulong flags;
|
|
ulong flags;
|
|
- unchar b, t;
|
|
|
|
|
|
|
|
TRACE(("gdth_putq() priority %d\n",priority));
|
|
TRACE(("gdth_putq() priority %d\n",priority));
|
|
spin_lock_irqsave(&ha->smp_lock, flags);
|
|
spin_lock_irqsave(&ha->smp_lock, flags);
|
|
|
|
|
|
- if (!cmndinfo->internal_command) {
|
|
|
|
|
|
+ if (!cmndinfo->internal_command)
|
|
cmndinfo->priority = priority;
|
|
cmndinfo->priority = priority;
|
|
- b = scp->device->channel;
|
|
|
|
- t = scp->device->id;
|
|
|
|
- if (priority >= DEFAULT_PRI) {
|
|
|
|
- if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) ||
|
|
|
|
- (b==ha->virt_bus && t<MAX_HDRIVES && ha->hdr[t].lock)) {
|
|
|
|
- TRACE2(("gdth_putq(): locked IO ->update_timeout()\n"));
|
|
|
|
- cmndinfo->timeout = gdth_update_timeout(scp, 0);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
|
|
if (ha->req_first==NULL) {
|
|
if (ha->req_first==NULL) {
|
|
ha->req_first = scp; /* queue was empty */
|
|
ha->req_first = scp; /* queue was empty */
|
|
@@ -3899,6 +3887,39 @@ static const char *gdth_info(struct Scsi_Host *shp)
|
|
return ((const char *)ha->binfo.type_string);
|
|
return ((const char *)ha->binfo.type_string);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static enum blk_eh_timer_return gdth_timed_out(struct scsi_cmnd *scp)
|
|
|
|
+{
|
|
|
|
+ gdth_ha_str *ha = shost_priv(scp->device->host);
|
|
|
|
+ struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp);
|
|
|
|
+ unchar b, t;
|
|
|
|
+ ulong flags;
|
|
|
|
+ enum blk_eh_timer_return retval = BLK_EH_NOT_HANDLED;
|
|
|
|
+
|
|
|
|
+ TRACE(("%s() cmd 0x%x\n", scp->cmnd[0], __func__));
|
|
|
|
+ b = scp->device->channel;
|
|
|
|
+ t = scp->device->id;
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * We don't really honor the command timeout, but we try to
|
|
|
|
+ * honor 6 times of the actual command timeout! So reset the
|
|
|
|
+ * timer if this is less than 6th timeout on this command!
|
|
|
|
+ */
|
|
|
|
+ if (++cmndinfo->timeout_count < 6)
|
|
|
|
+ retval = BLK_EH_RESET_TIMER;
|
|
|
|
+
|
|
|
|
+ /* Reset the timeout if it is locked IO */
|
|
|
|
+ spin_lock_irqsave(&ha->smp_lock, flags);
|
|
|
|
+ if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha, b)].lock) ||
|
|
|
|
+ (b == ha->virt_bus && t < MAX_HDRIVES && ha->hdr[t].lock)) {
|
|
|
|
+ TRACE2(("%s(): locked IO, reset timeout\n", __func__));
|
|
|
|
+ retval = BLK_EH_RESET_TIMER;
|
|
|
|
+ }
|
|
|
|
+ spin_unlock_irqrestore(&ha->smp_lock, flags);
|
|
|
|
+
|
|
|
|
+ return retval;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
static int gdth_eh_bus_reset(Scsi_Cmnd *scp)
|
|
static int gdth_eh_bus_reset(Scsi_Cmnd *scp)
|
|
{
|
|
{
|
|
gdth_ha_str *ha = shost_priv(scp->device->host);
|
|
gdth_ha_str *ha = shost_priv(scp->device->host);
|
|
@@ -3992,7 +4013,7 @@ static int gdth_queuecommand(struct scsi_cmnd *scp,
|
|
BUG_ON(!cmndinfo);
|
|
BUG_ON(!cmndinfo);
|
|
|
|
|
|
scp->scsi_done = done;
|
|
scp->scsi_done = done;
|
|
- gdth_update_timeout(scp, scp->timeout_per_command * 6);
|
|
|
|
|
|
+ cmndinfo->timeout_count = 0;
|
|
cmndinfo->priority = DEFAULT_PRI;
|
|
cmndinfo->priority = DEFAULT_PRI;
|
|
|
|
|
|
return __gdth_queuecommand(ha, scp, cmndinfo);
|
|
return __gdth_queuecommand(ha, scp, cmndinfo);
|
|
@@ -4096,12 +4117,10 @@ static int ioc_lockdrv(void __user *arg)
|
|
ha->hdr[j].lock = 1;
|
|
ha->hdr[j].lock = 1;
|
|
spin_unlock_irqrestore(&ha->smp_lock, flags);
|
|
spin_unlock_irqrestore(&ha->smp_lock, flags);
|
|
gdth_wait_completion(ha, ha->bus_cnt, j);
|
|
gdth_wait_completion(ha, ha->bus_cnt, j);
|
|
- gdth_stop_timeout(ha, ha->bus_cnt, j);
|
|
|
|
} else {
|
|
} else {
|
|
spin_lock_irqsave(&ha->smp_lock, flags);
|
|
spin_lock_irqsave(&ha->smp_lock, flags);
|
|
ha->hdr[j].lock = 0;
|
|
ha->hdr[j].lock = 0;
|
|
spin_unlock_irqrestore(&ha->smp_lock, flags);
|
|
spin_unlock_irqrestore(&ha->smp_lock, flags);
|
|
- gdth_start_timeout(ha, ha->bus_cnt, j);
|
|
|
|
gdth_next(ha);
|
|
gdth_next(ha);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -4539,18 +4558,14 @@ static int gdth_ioctl(struct inode *inode, struct file *filep,
|
|
spin_lock_irqsave(&ha->smp_lock, flags);
|
|
spin_lock_irqsave(&ha->smp_lock, flags);
|
|
ha->raw[i].lock = 1;
|
|
ha->raw[i].lock = 1;
|
|
spin_unlock_irqrestore(&ha->smp_lock, flags);
|
|
spin_unlock_irqrestore(&ha->smp_lock, flags);
|
|
- for (j = 0; j < ha->tid_cnt; ++j) {
|
|
|
|
|
|
+ for (j = 0; j < ha->tid_cnt; ++j)
|
|
gdth_wait_completion(ha, i, j);
|
|
gdth_wait_completion(ha, i, j);
|
|
- gdth_stop_timeout(ha, i, j);
|
|
|
|
- }
|
|
|
|
} else {
|
|
} else {
|
|
spin_lock_irqsave(&ha->smp_lock, flags);
|
|
spin_lock_irqsave(&ha->smp_lock, flags);
|
|
ha->raw[i].lock = 0;
|
|
ha->raw[i].lock = 0;
|
|
spin_unlock_irqrestore(&ha->smp_lock, flags);
|
|
spin_unlock_irqrestore(&ha->smp_lock, flags);
|
|
- for (j = 0; j < ha->tid_cnt; ++j) {
|
|
|
|
- gdth_start_timeout(ha, i, j);
|
|
|
|
|
|
+ for (j = 0; j < ha->tid_cnt; ++j)
|
|
gdth_next(ha);
|
|
gdth_next(ha);
|
|
- }
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
@@ -4644,6 +4659,7 @@ static struct scsi_host_template gdth_template = {
|
|
.slave_configure = gdth_slave_configure,
|
|
.slave_configure = gdth_slave_configure,
|
|
.bios_param = gdth_bios_param,
|
|
.bios_param = gdth_bios_param,
|
|
.proc_info = gdth_proc_info,
|
|
.proc_info = gdth_proc_info,
|
|
|
|
+ .eh_timed_out = gdth_timed_out,
|
|
.proc_name = "gdth",
|
|
.proc_name = "gdth",
|
|
.can_queue = GDTH_MAXCMDS,
|
|
.can_queue = GDTH_MAXCMDS,
|
|
.this_id = -1,
|
|
.this_id = -1,
|