aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMatthew Wilcox <matthew@wil.cx>2007-09-09 10:56:33 -0400
committerJames Bottomley <jejb@mulgrave.localdomain>2007-10-12 14:47:52 -0400
commit6ed1ef0786094f06d2462aeeb6ad7bf9f5f9fc18 (patch)
tree5dbbceb48294b66ea0635a8717c790740d244125 /drivers
parent7686f02aa8a380b3b0322179090f3c83ee4df977 (diff)
[SCSI] advansys: Remove `done' queue
- Move the guts of asc_scsi_done_list() into a new function, asc_scsi_done. - Call asc_scsi_done() in asc_isr_callback() and adv_isr_callback(). The comment was wrong; scsi_done cannot enable interrupts. - All other places which queued an scp on the done list are error paths for queuecommand, and so we can just call asc_scsi_done() in queuecommand if we receive an error. - We no longer need to keep a list of done requests in advansys_interrupt Signed-off-by: Matthew Wilcox <matthew@wil.cx> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/advansys.c120
1 files changed, 24 insertions, 96 deletions
diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c
index cd17f28fd3ba..90f05c52be7e 100644
--- a/drivers/scsi/advansys.c
+++ b/drivers/scsi/advansys.c
@@ -2852,7 +2852,6 @@ typedef struct asc_board {
2852 } dvc_cfg; 2852 } dvc_cfg;
2853 ushort asc_n_io_port; /* Number I/O ports. */ 2853 ushort asc_n_io_port; /* Number I/O ports. */
2854 asc_queue_t active; /* Active command queue */ 2854 asc_queue_t active; /* Active command queue */
2855 asc_queue_t done; /* Done command queue */
2856 ADV_SCSI_BIT_ID_TYPE init_tidmask; /* Target init./valid mask */ 2855 ADV_SCSI_BIT_ID_TYPE init_tidmask; /* Target init./valid mask */
2857 struct scsi_device *device[ADV_MAX_TID + 1]; /* Mid-Level Scsi Device */ 2856 struct scsi_device *device[ADV_MAX_TID + 1]; /* Mid-Level Scsi Device */
2858 ushort reqcnt[ADV_MAX_TID + 1]; /* Starvation request count */ 2857 ushort reqcnt[ADV_MAX_TID + 1]; /* Starvation request count */
@@ -3258,6 +3257,23 @@ static const char *advansys_info(struct Scsi_Host *shost)
3258 return info; 3257 return info;
3259} 3258}
3260 3259
3260static void asc_scsi_done(struct scsi_cmnd *scp)
3261{
3262 struct asc_board *boardp = ASC_BOARDP(scp->device->host);
3263
3264 if (scp->use_sg)
3265 dma_unmap_sg(boardp->dev,
3266 (struct scatterlist *)scp->request_buffer,
3267 scp->use_sg, scp->sc_data_direction);
3268 else if (scp->request_bufflen)
3269 dma_unmap_single(boardp->dev, scp->SCp.dma_handle,
3270 scp->request_bufflen, scp->sc_data_direction);
3271
3272 ASC_STATS(scp->device->host, done);
3273
3274 scp->scsi_done(scp);
3275}
3276
3261/* 3277/*
3262 * advansys_queuecommand() - interrupt-driven I/O entrypoint. 3278 * advansys_queuecommand() - interrupt-driven I/O entrypoint.
3263 * 3279 *
@@ -3270,7 +3286,6 @@ advansys_queuecommand(struct scsi_cmnd *scp, void (*done) (struct scsi_cmnd *))
3270 struct Scsi_Host *shost; 3286 struct Scsi_Host *shost;
3271 asc_board_t *boardp; 3287 asc_board_t *boardp;
3272 ulong flags; 3288 ulong flags;
3273 struct scsi_cmnd *done_scp;
3274 int asc_res, result = 0; 3289 int asc_res, result = 0;
3275 3290
3276 shost = scp->device->host; 3291 shost = scp->device->host;
@@ -3291,9 +3306,8 @@ advansys_queuecommand(struct scsi_cmnd *scp, void (*done) (struct scsi_cmnd *))
3291 break; 3306 break;
3292 case ASC_ERROR: 3307 case ASC_ERROR:
3293 default: 3308 default:
3294 done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL);
3295 /* Interrupts could be enabled here. */ 3309 /* Interrupts could be enabled here. */
3296 asc_scsi_done_list(done_scp); 3310 asc_scsi_done(scp);
3297 break; 3311 break;
3298 } 3312 }
3299 spin_unlock_irqrestore(&boardp->lock, flags); 3313 spin_unlock_irqrestore(&boardp->lock, flags);
@@ -3410,12 +3424,6 @@ static int advansys_reset(struct scsi_cmnd *scp)
3410 /* Board lock is held. */ 3424 /* Board lock is held. */
3411 3425
3412 /* 3426 /*
3413 * Dequeue all board 'done' requests. A pointer to the last request
3414 * is returned in 'last_scp'.
3415 */
3416 done_scp = asc_dequeue_list(&boardp->done, &last_scp, ASC_TID_ALL);
3417
3418 /*
3419 * Dequeue all board 'active' requests for all devices and set 3427 * Dequeue all board 'active' requests for all devices and set
3420 * the request status to DID_RESET. A pointer to the last request 3428 * the request status to DID_RESET. A pointer to the last request
3421 * is returned in 'last_scp'. 3429 * is returned in 'last_scp'.
@@ -3548,8 +3556,6 @@ static struct scsi_host_template advansys_template = {
3548static irqreturn_t advansys_interrupt(int irq, void *dev_id) 3556static irqreturn_t advansys_interrupt(int irq, void *dev_id)
3549{ 3557{
3550 unsigned long flags; 3558 unsigned long flags;
3551 struct scsi_cmnd *done_scp = NULL, *last_scp = NULL;
3552 struct scsi_cmnd *new_last_scp;
3553 struct Scsi_Host *shost = dev_id; 3559 struct Scsi_Host *shost = dev_id;
3554 asc_board_t *boardp = ASC_BOARDP(shost); 3560 asc_board_t *boardp = ASC_BOARDP(shost);
3555 irqreturn_t result = IRQ_NONE; 3561 irqreturn_t result = IRQ_NONE;
@@ -3577,49 +3583,13 @@ static irqreturn_t advansys_interrupt(int irq, void *dev_id)
3577 } 3583 }
3578 } 3584 }
3579 3585
3580 /*
3581 * Create a list of completed requests.
3582 *
3583 * If a reset request is being performed for the board, the reset
3584 * handler will complete pending requests after it has completed.
3585 */
3586 if ((boardp->flags & ASC_HOST_IN_RESET) == 0) {
3587 ASC_DBG2(1, "advansys_interrupt: done_scp 0x%p, "
3588 "last_scp 0x%p\n", done_scp, last_scp);
3589
3590 /*
3591 * Add to the list of requests that must be completed.
3592 *
3593 * 'done_scp' will always be NULL on the first iteration of
3594 * this loop. 'last_scp' is set at the same time as 'done_scp'.
3595 */
3596 if (done_scp == NULL) {
3597 done_scp = asc_dequeue_list(&boardp->done,
3598 &last_scp, ASC_TID_ALL);
3599 } else {
3600 ASC_ASSERT(last_scp != NULL);
3601 last_scp->host_scribble =
3602 (unsigned char *)asc_dequeue_list(&boardp->
3603 done,
3604 &new_last_scp,
3605 ASC_TID_ALL);
3606 if (new_last_scp != NULL) {
3607 ASC_ASSERT(REQPNEXT(last_scp) != NULL);
3608 last_scp = new_last_scp;
3609 }
3610 }
3611 }
3612 spin_unlock_irqrestore(&boardp->lock, flags); 3586 spin_unlock_irqrestore(&boardp->lock, flags);
3613 3587
3614 /* 3588 /*
3615 * If interrupts were enabled on entry, then they 3589 * If interrupts were enabled on entry, then they
3616 * are now enabled here. 3590 * are now enabled here.
3617 *
3618 * Complete all requests on the done list.
3619 */ 3591 */
3620 3592
3621 asc_scsi_done_list(done_scp);
3622
3623 ASC_DBG(1, "advansys_interrupt: end\n"); 3593 ASC_DBG(1, "advansys_interrupt: end\n");
3624 return result; 3594 return result;
3625} 3595}
@@ -3836,27 +3806,11 @@ static void asc_scsi_done_list(struct scsi_cmnd *scp)
3836 3806
3837 ASC_DBG(2, "asc_scsi_done_list: begin\n"); 3807 ASC_DBG(2, "asc_scsi_done_list: begin\n");
3838 while (scp != NULL) { 3808 while (scp != NULL) {
3839 asc_board_t *boardp;
3840
3841 ASC_DBG1(3, "asc_scsi_done_list: scp 0x%lx\n", (ulong)scp); 3809 ASC_DBG1(3, "asc_scsi_done_list: scp 0x%lx\n", (ulong)scp);
3842 tscp = REQPNEXT(scp); 3810 tscp = REQPNEXT(scp);
3843 scp->host_scribble = NULL; 3811 scp->host_scribble = NULL;
3844 3812
3845 boardp = ASC_BOARDP(scp->device->host); 3813 asc_scsi_done(scp);
3846
3847 if (scp->use_sg)
3848 dma_unmap_sg(boardp->dev,
3849 (struct scatterlist *)scp->request_buffer,
3850 scp->use_sg, scp->sc_data_direction);
3851 else if (scp->request_bufflen)
3852 dma_unmap_single(boardp->dev, scp->SCp.dma_handle,
3853 scp->request_bufflen,
3854 scp->sc_data_direction);
3855
3856 ASC_STATS(scp->device->host, done);
3857 ASC_ASSERT(scp->scsi_done != NULL);
3858
3859 scp->scsi_done(scp);
3860 3814
3861 scp = tscp; 3815 scp = tscp;
3862 } 3816 }
@@ -3904,8 +3858,8 @@ static void asc_scsi_done_list(struct scsi_cmnd *scp)
3904 * on the board's 'active' queue and will be completed from the 3858 * on the board's 'active' queue and will be completed from the
3905 * interrupt handler. 3859 * interrupt handler.
3906 * 3860 *
3907 * If this function returns ASC_NOERROR the request has been enqueued 3861 * If this function returns ASC_ERROR the host error code has been set,
3908 * on the board's 'done' queue and must be completed by the caller. 3862 * and the called must call asc_scsi_done.
3909 * 3863 *
3910 * If ASC_BUSY is returned the request will be returned to the midlayer 3864 * If ASC_BUSY is returned the request will be returned to the midlayer
3911 * and re-tried later. 3865 * and re-tried later.
@@ -3972,7 +3926,6 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
3972 boardp->id, asc_dvc_varp->err_code); 3926 boardp->id, asc_dvc_varp->err_code);
3973 ASC_STATS(scp->device->host, exe_error); 3927 ASC_STATS(scp->device->host, exe_error);
3974 scp->result = HOST_BYTE(DID_ERROR); 3928 scp->result = HOST_BYTE(DID_ERROR);
3975 asc_enqueue(&boardp->done, scp, ASC_BACK);
3976 break; 3929 break;
3977 default: 3930 default:
3978 ASC_PRINT2("asc_execute_scsi_cmnd: board %d: " 3931 ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
@@ -3980,7 +3933,6 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
3980 boardp->id, asc_dvc_varp->err_code); 3933 boardp->id, asc_dvc_varp->err_code);
3981 ASC_STATS(scp->device->host, exe_unknown); 3934 ASC_STATS(scp->device->host, exe_unknown);
3982 scp->result = HOST_BYTE(DID_ERROR); 3935 scp->result = HOST_BYTE(DID_ERROR);
3983 asc_enqueue(&boardp->done, scp, ASC_BACK);
3984 break; 3936 break;
3985 } 3937 }
3986 } else { 3938 } else {
@@ -4011,11 +3963,6 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
4011 */ 3963 */
4012 return ASC_BUSY; 3964 return ASC_BUSY;
4013 case ASC_ERROR: 3965 case ASC_ERROR:
4014 /*
4015 * If an error is returned, then the request has been
4016 * queued on the board done queue. It will be completed
4017 * by the caller.
4018 */
4019 default: 3966 default:
4020 ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req " 3967 ASC_DBG(1, "asc_execute_scsi_cmnd: adv_build_req "
4021 "ASC_ERROR\n"); 3968 "ASC_ERROR\n");
@@ -4048,7 +3995,6 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
4048 boardp->id, adv_dvc_varp->err_code); 3995 boardp->id, adv_dvc_varp->err_code);
4049 ASC_STATS(scp->device->host, exe_error); 3996 ASC_STATS(scp->device->host, exe_error);
4050 scp->result = HOST_BYTE(DID_ERROR); 3997 scp->result = HOST_BYTE(DID_ERROR);
4051 asc_enqueue(&boardp->done, scp, ASC_BACK);
4052 break; 3998 break;
4053 default: 3999 default:
4054 ASC_PRINT2("asc_execute_scsi_cmnd: board %d: " 4000 ASC_PRINT2("asc_execute_scsi_cmnd: board %d: "
@@ -4056,7 +4002,6 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
4056 boardp->id, adv_dvc_varp->err_code); 4002 boardp->id, adv_dvc_varp->err_code);
4057 ASC_STATS(scp->device->host, exe_unknown); 4003 ASC_STATS(scp->device->host, exe_unknown);
4058 scp->result = HOST_BYTE(DID_ERROR); 4004 scp->result = HOST_BYTE(DID_ERROR);
4059 asc_enqueue(&boardp->done, scp, ASC_BACK);
4060 break; 4005 break;
4061 } 4006 }
4062 } 4007 }
@@ -4071,8 +4016,7 @@ static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp)
4071 * The global structures 'asc_scsi_q' and 'asc_sg_head' are 4016 * The global structures 'asc_scsi_q' and 'asc_sg_head' are
4072 * used to build the request. 4017 * used to build the request.
4073 * 4018 *
4074 * If an error occurs, then queue the request on the board done 4019 * If an error occurs, then return ASC_ERROR.
4075 * queue and return ASC_ERROR.
4076 */ 4020 */
4077static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp) 4021static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp)
4078{ 4022{
@@ -4098,7 +4042,6 @@ static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp)
4098 "ASC_MAX_CDB_LEN %d\n", boardp->id, scp->cmd_len, 4042 "ASC_MAX_CDB_LEN %d\n", boardp->id, scp->cmd_len,
4099 ASC_MAX_CDB_LEN); 4043 ASC_MAX_CDB_LEN);
4100 scp->result = HOST_BYTE(DID_ERROR); 4044 scp->result = HOST_BYTE(DID_ERROR);
4101 asc_enqueue(&boardp->done, scp, ASC_BACK);
4102 return ASC_ERROR; 4045 return ASC_ERROR;
4103 } 4046 }
4104 asc_scsi_q.cdbptr = &scp->cmnd[0]; 4047 asc_scsi_q.cdbptr = &scp->cmnd[0];
@@ -4167,7 +4110,6 @@ static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp)
4167 dma_unmap_sg(boardp->dev, slp, scp->use_sg, 4110 dma_unmap_sg(boardp->dev, slp, scp->use_sg,
4168 scp->sc_data_direction); 4111 scp->sc_data_direction);
4169 scp->result = HOST_BYTE(DID_ERROR); 4112 scp->result = HOST_BYTE(DID_ERROR);
4170 asc_enqueue(&boardp->done, scp, ASC_BACK);
4171 return ASC_ERROR; 4113 return ASC_ERROR;
4172 } 4114 }
4173 4115
@@ -4274,7 +4216,6 @@ adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp,
4274 ("adv_build_req: board %d: cmd_len %d > ADV_MAX_CDB_LEN %d\n", 4216 ("adv_build_req: board %d: cmd_len %d > ADV_MAX_CDB_LEN %d\n",
4275 boardp->id, scp->cmd_len, ADV_MAX_CDB_LEN); 4217 boardp->id, scp->cmd_len, ADV_MAX_CDB_LEN);
4276 scp->result = HOST_BYTE(DID_ERROR); 4218 scp->result = HOST_BYTE(DID_ERROR);
4277 asc_enqueue(&boardp->done, scp, ASC_BACK);
4278 return ASC_ERROR; 4219 return ASC_ERROR;
4279 } 4220 }
4280 scsiqp->cdb_len = scp->cmd_len; 4221 scsiqp->cdb_len = scp->cmd_len;
@@ -4342,7 +4283,6 @@ adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp,
4342 dma_unmap_sg(boardp->dev, slp, scp->use_sg, 4283 dma_unmap_sg(boardp->dev, slp, scp->use_sg,
4343 scp->sc_data_direction); 4284 scp->sc_data_direction);
4344 scp->result = HOST_BYTE(DID_ERROR); 4285 scp->result = HOST_BYTE(DID_ERROR);
4345 asc_enqueue(&boardp->done, scp, ASC_BACK);
4346 4286
4347 /* 4287 /*
4348 * Free the 'adv_req_t' structure by adding it back 4288 * Free the 'adv_req_t' structure by adding it back
@@ -4628,13 +4568,7 @@ static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
4628 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id); 4568 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
4629 } 4569 }
4630 4570
4631 /* 4571 asc_scsi_done(scp);
4632 * Because interrupts may be enabled by the 'struct scsi_cmnd' done
4633 * function, add the command to the end of the board's done queue.
4634 * The done function for the command will be called from
4635 * advansys_interrupt().
4636 */
4637 asc_enqueue(&boardp->done, scp, ASC_BACK);
4638 4572
4639 return; 4573 return;
4640} 4574}
@@ -4790,13 +4724,7 @@ static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp)
4790 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id); 4724 boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id);
4791 } 4725 }
4792 4726
4793 /* 4727 asc_scsi_done(scp);
4794 * Because interrupts may be enabled by the 'struct scsi_cmnd' done
4795 * function, add the command to the end of the board's done queue.
4796 * The done function for the command will be called from
4797 * advansys_interrupt().
4798 */
4799 asc_enqueue(&boardp->done, scp, ASC_BACK);
4800 4728
4801 /* 4729 /*
4802 * Free all 'adv_sgblk_t' structures allocated for the request. 4730 * Free all 'adv_sgblk_t' structures allocated for the request.