Commit 583bcb77 authored by David Jeffery's avatar David Jeffery Committed by James Simmons

[PATCH] ips driver 6/6

2 bug fixes for scsi pass through

When talking directly to scsi devices, the driver would
sometimes get two things wrong.  We could set too short
of a timeout. Or, we could confuse the adapter by having
non-zero values in certain fields which we shouldn't have
been using.  This patch corrects these problems.
parent 1417bd08
...@@ -4222,6 +4222,7 @@ ips_send_cmd(ips_ha_t *ha, ips_scb_t *scb) { ...@@ -4222,6 +4222,7 @@ ips_send_cmd(ips_ha_t *ha, ips_scb_t *scb) {
char *sp; char *sp;
int device_error; int device_error;
IPS_DCDB_TABLE_TAPE *tapeDCDB; IPS_DCDB_TABLE_TAPE *tapeDCDB;
int TimeOut;
METHOD_TRACE("ips_send_cmd", 1); METHOD_TRACE("ips_send_cmd", 1);
...@@ -4460,11 +4461,13 @@ ips_send_cmd(ips_ha_t *ha, ips_scb_t *scb) { ...@@ -4460,11 +4461,13 @@ ips_send_cmd(ips_ha_t *ha, ips_scb_t *scb) {
ha->dcdb_active[scb->bus-1] |= (1 << scb->target_id); ha->dcdb_active[scb->bus-1] |= (1 << scb->target_id);
scb->cmd.dcdb.command_id = IPS_COMMAND_ID(ha, scb); scb->cmd.dcdb.command_id = IPS_COMMAND_ID(ha, scb);
scb->cmd.dcdb.dcdb_address = cpu_to_le32(scb->scb_busaddr + scb->cmd.dcdb.dcdb_address = cpu_to_le32(scb->scb_busaddr +
(unsigned long)&scb->dcdb - (unsigned long)&scb->dcdb -
(unsigned long)scb); (unsigned long)scb);
scb->cmd.dcdb.reserved = 0; scb->cmd.dcdb.reserved = 0;
scb->cmd.dcdb.reserved2 = 0; scb->cmd.dcdb.reserved2 = 0;
scb->cmd.dcdb.reserved3 = 0; scb->cmd.dcdb.reserved3 = 0;
TimeOut = scb->scsi_cmd->timeout_per_command;
if (ha->subsys->param[4] & 0x00100000) { /* If NEW Tape DCDB is Supported */ if (ha->subsys->param[4] & 0x00100000) { /* If NEW Tape DCDB is Supported */
if (!scb->sg_len) if (!scb->sg_len)
...@@ -4475,47 +4478,52 @@ ips_send_cmd(ips_ha_t *ha, ips_scb_t *scb) { ...@@ -4475,47 +4478,52 @@ ips_send_cmd(ips_ha_t *ha, ips_scb_t *scb) {
tapeDCDB = (IPS_DCDB_TABLE_TAPE *) &scb->dcdb; /* Use Same Data Area as Old DCDB Struct */ tapeDCDB = (IPS_DCDB_TABLE_TAPE *) &scb->dcdb; /* Use Same Data Area as Old DCDB Struct */
tapeDCDB->device_address = ((scb->bus - 1) << 4) | scb->target_id; tapeDCDB->device_address = ((scb->bus - 1) << 4) | scb->target_id;
tapeDCDB->cmd_attribute |= IPS_DISCONNECT_ALLOWED; tapeDCDB->cmd_attribute |= IPS_DISCONNECT_ALLOWED;
tapeDCDB->cmd_attribute &= ~IPS_TRANSFER64K; /* Always Turn OFF 64K Size Flag */
if (scb->timeout) {
if (scb->timeout <= 10) if (TimeOut) {
tapeDCDB->cmd_attribute |= IPS_TIMEOUT10; if (TimeOut < ( 10 * HZ ))
else if (scb->timeout <= 60) tapeDCDB->cmd_attribute |= IPS_TIMEOUT10; /* TimeOut is 10 Seconds */
tapeDCDB->cmd_attribute |= IPS_TIMEOUT60; else if (TimeOut < (60 * HZ))
else tapeDCDB->cmd_attribute |= IPS_TIMEOUT60; /* TimeOut is 60 Seconds */
tapeDCDB->cmd_attribute |= IPS_TIMEOUT20M; else if (TimeOut < (1200 * HZ))
tapeDCDB->cmd_attribute |= IPS_TIMEOUT20M; /* TimeOut is 20 Minutes */
} }
if (!(tapeDCDB->cmd_attribute & IPS_TIMEOUT20M)) tapeDCDB->cdb_length = scb->scsi_cmd->cmd_len;
tapeDCDB->cmd_attribute |= IPS_TIMEOUT20M; tapeDCDB->reserved_for_LUN = 0;
tapeDCDB->sense_length = sizeof(tapeDCDB->sense_info);
tapeDCDB->transfer_length = scb->data_len; tapeDCDB->transfer_length = scb->data_len;
tapeDCDB->buffer_pointer = cpu_to_le32(scb->data_busaddr); tapeDCDB->buffer_pointer = cpu_to_le32(scb->data_busaddr);
tapeDCDB->sg_count = scb->sg_len; tapeDCDB->sg_count = scb->sg_len;
tapeDCDB->cdb_length = scb->scsi_cmd->cmd_len; tapeDCDB->sense_length = sizeof(tapeDCDB->sense_info);
tapeDCDB->scsi_status = 0;
tapeDCDB->reserved = 0;
memcpy(tapeDCDB->scsi_cdb, scb->scsi_cmd->cmnd, scb->scsi_cmd->cmd_len); memcpy(tapeDCDB->scsi_cdb, scb->scsi_cmd->cmnd, scb->scsi_cmd->cmd_len);
} else { } else {
scb->dcdb.device_address = ((scb->bus - 1) << 4) | scb->target_id; scb->dcdb.device_address = ((scb->bus - 1) << 4) | scb->target_id;
scb->dcdb.cmd_attribute |= IPS_DISCONNECT_ALLOWED; scb->dcdb.cmd_attribute |= IPS_DISCONNECT_ALLOWED;
if (scb->timeout) { if (TimeOut) {
if (scb->timeout <= 10) if (TimeOut < (10 * HZ))
scb->dcdb.cmd_attribute |= IPS_TIMEOUT10; scb->dcdb.cmd_attribute |= IPS_TIMEOUT10; /* TimeOut is 10 Seconds */
else if (scb->timeout <= 60) else if (TimeOut < (60 * HZ))
scb->dcdb.cmd_attribute |= IPS_TIMEOUT60; scb->dcdb.cmd_attribute |= IPS_TIMEOUT60; /* TimeOut is 60 Seconds */
else else if (TimeOut < (1200 * HZ))
scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M; scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M; /* TimeOut is 20 Minutes */
} }
if (!(scb->dcdb.cmd_attribute & IPS_TIMEOUT20M))
scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M;
scb->dcdb.sense_length = sizeof(scb->dcdb.sense_info);
scb->dcdb.transfer_length = scb->data_len; scb->dcdb.transfer_length = scb->data_len;
if ( scb->dcdb.cmd_attribute & IPS_TRANSFER64K )
scb->dcdb.transfer_length = 0;
scb->dcdb.buffer_pointer = cpu_to_le32(scb->data_busaddr); scb->dcdb.buffer_pointer = cpu_to_le32(scb->data_busaddr);
scb->dcdb.sg_count = scb->sg_len;
scb->dcdb.cdb_length = scb->scsi_cmd->cmd_len; scb->dcdb.cdb_length = scb->scsi_cmd->cmd_len;
scb->dcdb.sense_length = sizeof(scb->dcdb.sense_info);
scb->dcdb.sg_count = scb->sg_len;
scb->dcdb.reserved = 0;
memcpy(scb->dcdb.scsi_cdb, scb->scsi_cmd->cmnd, scb->scsi_cmd->cmd_len); memcpy(scb->dcdb.scsi_cdb, scb->scsi_cmd->cmnd, scb->scsi_cmd->cmd_len);
scb->dcdb.scsi_status = 0;
scb->dcdb.reserved2[0] = 0;
scb->dcdb.reserved2[1] = 0;
scb->dcdb.reserved2[2] = 0;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment