diff options
Diffstat (limited to 'drivers/scsi/scsi_tgt_lib.c')
-rw-r--r-- | drivers/scsi/scsi_tgt_lib.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/drivers/scsi/scsi_tgt_lib.c b/drivers/scsi/scsi_tgt_lib.c index 39da5cd6fb6f..386dbae17b44 100644 --- a/drivers/scsi/scsi_tgt_lib.c +++ b/drivers/scsi/scsi_tgt_lib.c | |||
@@ -185,10 +185,11 @@ static void cmd_hashlist_del(struct scsi_cmnd *cmd) | |||
185 | spin_unlock_irqrestore(&qdata->cmd_hash_lock, flags); | 185 | spin_unlock_irqrestore(&qdata->cmd_hash_lock, flags); |
186 | } | 186 | } |
187 | 187 | ||
188 | static void scsi_tgt_cmd_destroy(void *data) | 188 | static void scsi_tgt_cmd_destroy(struct work_struct *work) |
189 | { | 189 | { |
190 | struct scsi_cmnd *cmd = data; | 190 | struct scsi_tgt_cmd *tcmd = |
191 | struct scsi_tgt_cmd *tcmd = cmd->request->end_io_data; | 191 | container_of(work, struct scsi_tgt_cmd, work); |
192 | struct scsi_cmnd *cmd = tcmd->rq->special; | ||
192 | 193 | ||
193 | dprintk("cmd %p %d %lu\n", cmd, cmd->sc_data_direction, | 194 | dprintk("cmd %p %d %lu\n", cmd, cmd->sc_data_direction, |
194 | rq_data_dir(cmd->request)); | 195 | rq_data_dir(cmd->request)); |
@@ -214,6 +215,7 @@ static void init_scsi_tgt_cmd(struct request *rq, struct scsi_tgt_cmd *tcmd, | |||
214 | struct list_head *head; | 215 | struct list_head *head; |
215 | 216 | ||
216 | tcmd->tag = tag; | 217 | tcmd->tag = tag; |
218 | INIT_WORK(&tcmd->work, scsi_tgt_cmd_destroy); | ||
217 | spin_lock_irqsave(&qdata->cmd_hash_lock, flags); | 219 | spin_lock_irqsave(&qdata->cmd_hash_lock, flags); |
218 | head = &qdata->cmd_hash[cmd_hashfn(tag)]; | 220 | head = &qdata->cmd_hash[cmd_hashfn(tag)]; |
219 | list_add(&tcmd->hash_list, head); | 221 | list_add(&tcmd->hash_list, head); |
@@ -303,7 +305,7 @@ void scsi_tgt_free_queue(struct Scsi_Host *shost) | |||
303 | cmd = tcmd->rq->special; | 305 | cmd = tcmd->rq->special; |
304 | 306 | ||
305 | shost->hostt->eh_abort_handler(cmd); | 307 | shost->hostt->eh_abort_handler(cmd); |
306 | scsi_tgt_cmd_destroy(cmd); | 308 | scsi_tgt_cmd_destroy(&tcmd->work); |
307 | } | 309 | } |
308 | } | 310 | } |
309 | EXPORT_SYMBOL_GPL(scsi_tgt_free_queue); | 311 | EXPORT_SYMBOL_GPL(scsi_tgt_free_queue); |
@@ -347,7 +349,6 @@ static void scsi_tgt_cmd_done(struct scsi_cmnd *cmd) | |||
347 | dprintk("cmd %p %lu\n", cmd, rq_data_dir(cmd->request)); | 349 | dprintk("cmd %p %lu\n", cmd, rq_data_dir(cmd->request)); |
348 | 350 | ||
349 | scsi_tgt_uspace_send_status(cmd, tcmd->tag); | 351 | scsi_tgt_uspace_send_status(cmd, tcmd->tag); |
350 | INIT_WORK(&tcmd->work, scsi_tgt_cmd_destroy, cmd); | ||
351 | queue_work(scsi_tgtd, &tcmd->work); | 352 | queue_work(scsi_tgtd, &tcmd->work); |
352 | } | 353 | } |
353 | 354 | ||
@@ -549,13 +550,15 @@ static int scsi_tgt_copy_sense(struct scsi_cmnd *cmd, unsigned long uaddr, | |||
549 | 550 | ||
550 | static int scsi_tgt_abort_cmd(struct Scsi_Host *shost, struct scsi_cmnd *cmd) | 551 | static int scsi_tgt_abort_cmd(struct Scsi_Host *shost, struct scsi_cmnd *cmd) |
551 | { | 552 | { |
553 | struct scsi_tgt_cmd *tcmd; | ||
552 | int err; | 554 | int err; |
553 | 555 | ||
554 | err = shost->hostt->eh_abort_handler(cmd); | 556 | err = shost->hostt->eh_abort_handler(cmd); |
555 | if (err) | 557 | if (err) |
556 | eprintk("fail to abort %p\n", cmd); | 558 | eprintk("fail to abort %p\n", cmd); |
557 | 559 | ||
558 | scsi_tgt_cmd_destroy(cmd); | 560 | tcmd = cmd->request->end_io_data; |
561 | scsi_tgt_cmd_destroy(&tcmd->work); | ||
559 | return err; | 562 | return err; |
560 | } | 563 | } |
561 | 564 | ||