Commit 677e0194 authored by Finn Thain's avatar Finn Thain Committed by Martin K. Petersen

ncr5380: Refactor command completion

Implement a 'complete_cmd' function to complete commands. This is needed
by the following patch; the new function provides a site for the logic
needed to correctly handle REQUEST SENSE commands.
Signed-off-by: default avatarFinn Thain <fthain@telegraphics.com.au>
Reviewed-by: default avatarHannes Reinecke <hare@suse.com>
Tested-by: default avatarOndrej Zary <linux@rainbow-software.org>
Tested-by: default avatarMichael Schmitz <schmitzmic@gmail.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 32b26a10
...@@ -725,6 +725,24 @@ static void NCR5380_exit(struct Scsi_Host *instance) ...@@ -725,6 +725,24 @@ static void NCR5380_exit(struct Scsi_Host *instance)
destroy_workqueue(hostdata->work_q); destroy_workqueue(hostdata->work_q);
} }
/**
* complete_cmd - finish processing a command and return it to the SCSI ML
* @instance: the host instance
* @cmd: command to complete
*/
static void complete_cmd(struct Scsi_Host *instance,
struct scsi_cmnd *cmd)
{
struct NCR5380_hostdata *hostdata = shost_priv(instance);
dsprintk(NDEBUG_QUEUES, instance, "complete_cmd: cmd %p\n", cmd);
hostdata->busy[scmd_id(cmd)] &= ~(1 << cmd->device->lun);
cmd->scsi_done(cmd);
}
/** /**
* NCR5380_queue_command - queue a command * NCR5380_queue_command - queue a command
* @instance: the relevant SCSI adapter * @instance: the relevant SCSI adapter
...@@ -1171,7 +1189,7 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd) ...@@ -1171,7 +1189,7 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
spin_lock_irq(&hostdata->lock); spin_lock_irq(&hostdata->lock);
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
cmd->result = DID_BAD_TARGET << 16; cmd->result = DID_BAD_TARGET << 16;
cmd->scsi_done(cmd); complete_cmd(instance, cmd);
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
dprintk(NDEBUG_SELECTION, "scsi%d : target did not respond within 250ms\n", dprintk(NDEBUG_SELECTION, "scsi%d : target did not respond within 250ms\n",
instance->host_no); instance->host_no);
...@@ -1759,7 +1777,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) { ...@@ -1759,7 +1777,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
sink = 1; sink = 1;
do_abort(instance); do_abort(instance);
cmd->result = DID_ERROR << 16; cmd->result = DID_ERROR << 16;
cmd->scsi_done(cmd); complete_cmd(instance, cmd);
return; return;
#endif #endif
case PHASE_DATAIN: case PHASE_DATAIN:
...@@ -1804,7 +1822,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) { ...@@ -1804,7 +1822,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
sink = 1; sink = 1;
do_abort(instance); do_abort(instance);
cmd->result = DID_ERROR << 16; cmd->result = DID_ERROR << 16;
cmd->scsi_done(cmd); complete_cmd(instance, cmd);
/* XXX - need to source or sink data here, as appropriate */ /* XXX - need to source or sink data here, as appropriate */
} else } else
cmd->SCp.this_residual -= transfersize - len; cmd->SCp.this_residual -= transfersize - len;
...@@ -1834,7 +1852,6 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) { ...@@ -1834,7 +1852,6 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
cmd, scmd_id(cmd), cmd->device->lun); cmd, scmd_id(cmd), cmd->device->lun);
hostdata->connected = NULL; hostdata->connected = NULL;
hostdata->busy[cmd->device->id] &= ~(1 << (cmd->device->lun & 0xFF));
/* /*
* I'm not sure what the correct thing to do here is : * I'm not sure what the correct thing to do here is :
...@@ -1870,8 +1887,9 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) { ...@@ -1870,8 +1887,9 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
dsprintk(NDEBUG_AUTOSENSE | NDEBUG_QUEUES, dsprintk(NDEBUG_AUTOSENSE | NDEBUG_QUEUES,
instance, "REQUEST SENSE cmd %p added to head of issue queue\n", instance, "REQUEST SENSE cmd %p added to head of issue queue\n",
cmd); cmd);
hostdata->busy[cmd->device->id] &= ~(1 << (cmd->device->lun & 0xFF));
} else { } else {
cmd->scsi_done(cmd); complete_cmd(instance, cmd);
} }
/* /*
...@@ -2018,10 +2036,9 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) { ...@@ -2018,10 +2036,9 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
hostdata->last_message = msgout; hostdata->last_message = msgout;
NCR5380_transfer_pio(instance, &phase, &len, &data); NCR5380_transfer_pio(instance, &phase, &len, &data);
if (msgout == ABORT) { if (msgout == ABORT) {
hostdata->busy[cmd->device->id] &= ~(1 << (cmd->device->lun & 0xFF));
hostdata->connected = NULL; hostdata->connected = NULL;
cmd->result = DID_ERROR << 16; cmd->result = DID_ERROR << 16;
cmd->scsi_done(cmd); complete_cmd(instance, cmd);
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
return; return;
} }
......
...@@ -764,6 +764,27 @@ static void NCR5380_exit(struct Scsi_Host *instance) ...@@ -764,6 +764,27 @@ static void NCR5380_exit(struct Scsi_Host *instance)
destroy_workqueue(hostdata->work_q); destroy_workqueue(hostdata->work_q);
} }
/**
* complete_cmd - finish processing a command and return it to the SCSI ML
* @instance: the host instance
* @cmd: command to complete
*/
static void complete_cmd(struct Scsi_Host *instance,
struct scsi_cmnd *cmd)
{
struct NCR5380_hostdata *hostdata = shost_priv(instance);
dsprintk(NDEBUG_QUEUES, instance, "complete_cmd: cmd %p\n", cmd);
#ifdef SUPPORT_TAGS
cmd_free_tag(cmd);
#else
hostdata->busy[scmd_id(cmd)] &= ~(1 << cmd->device->lun);
#endif
cmd->scsi_done(cmd);
}
/** /**
* NCR5380_queue_command - queue a command * NCR5380_queue_command - queue a command
* @instance: the relevant SCSI adapter * @instance: the relevant SCSI adapter
...@@ -1352,10 +1373,7 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd) ...@@ -1352,10 +1373,7 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
spin_lock_irq(&hostdata->lock); spin_lock_irq(&hostdata->lock);
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
cmd->result = DID_BAD_TARGET << 16; cmd->result = DID_BAD_TARGET << 16;
#ifdef SUPPORT_TAGS complete_cmd(instance, cmd);
cmd_free_tag(cmd);
#endif
cmd->scsi_done(cmd);
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
dprintk(NDEBUG_SELECTION, "scsi%d: target did not respond within 250ms\n", HOSTNO); dprintk(NDEBUG_SELECTION, "scsi%d: target did not respond within 250ms\n", HOSTNO);
return 0; return 0;
...@@ -1866,7 +1884,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) ...@@ -1866,7 +1884,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
sink = 1; sink = 1;
do_abort(instance); do_abort(instance);
cmd->result = DID_ERROR << 16; cmd->result = DID_ERROR << 16;
cmd->scsi_done(cmd); complete_cmd(instance, cmd);
return; return;
#endif #endif
case PHASE_DATAIN: case PHASE_DATAIN:
...@@ -1926,7 +1944,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) ...@@ -1926,7 +1944,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
sink = 1; sink = 1;
do_abort(instance); do_abort(instance);
cmd->result = DID_ERROR << 16; cmd->result = DID_ERROR << 16;
cmd->scsi_done(cmd); complete_cmd(instance, cmd);
/* XXX - need to source or sink data here, as appropriate */ /* XXX - need to source or sink data here, as appropriate */
} else { } else {
#ifdef REAL_DMA #ifdef REAL_DMA
...@@ -1982,8 +2000,6 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) ...@@ -1982,8 +2000,6 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
if (ta->queue_size > ta->nr_allocated) if (ta->queue_size > ta->nr_allocated)
ta->queue_size = ta->nr_allocated; ta->queue_size = ta->nr_allocated;
} }
#else
hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
#endif #endif
/* /*
...@@ -2021,8 +2037,13 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) ...@@ -2021,8 +2037,13 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
dsprintk(NDEBUG_AUTOSENSE | NDEBUG_QUEUES, dsprintk(NDEBUG_AUTOSENSE | NDEBUG_QUEUES,
instance, "REQUEST SENSE cmd %p added to head of issue queue\n", instance, "REQUEST SENSE cmd %p added to head of issue queue\n",
cmd); cmd);
#ifdef SUPPORT_TAGS
cmd_free_tag(cmd);
#else
hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
#endif
} else { } else {
cmd->scsi_done(cmd); complete_cmd(instance, cmd);
} }
/* /*
...@@ -2193,15 +2214,10 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) ...@@ -2193,15 +2214,10 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
hostdata->last_message = msgout; hostdata->last_message = msgout;
NCR5380_transfer_pio(instance, &phase, &len, &data); NCR5380_transfer_pio(instance, &phase, &len, &data);
if (msgout == ABORT) { if (msgout == ABORT) {
#ifdef SUPPORT_TAGS
cmd_free_tag(cmd);
#else
hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
#endif
hostdata->connected = NULL; hostdata->connected = NULL;
cmd->result = DID_ERROR << 16; cmd->result = DID_ERROR << 16;
complete_cmd(instance, cmd);
maybe_release_dma_irq(instance); maybe_release_dma_irq(instance);
cmd->scsi_done(cmd);
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
return; return;
} }
......
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