Commit a7548431 authored by Jeff Garzik's avatar Jeff Garzik

[libata] Use scsi_finish_command as completion function,

in our error handling thread callback.

This also exports scsi_finish_command in the SCSI layer.

Thanks much to James Bottomley and his patience, as this solution
was figured out.
parent 49b5de25
...@@ -2005,6 +2005,14 @@ void ata_eng_timeout(struct ata_port *ap) ...@@ -2005,6 +2005,14 @@ void ata_eng_timeout(struct ata_port *ap)
goto out; goto out;
} }
/* hack alert! We cannot use the supplied completion
* function from inside the ->eh_strategy_handler() thread.
* libata is the only user of ->eh_strategy_handler() in
* any kernel, so the default scsi_done() assumes it is
* not being called from the SCSI EH.
*/
qc->scsidone = scsi_finish_command;
switch (qc->tf.protocol) { switch (qc->tf.protocol) {
case ATA_PROT_DMA_READ: case ATA_PROT_DMA_READ:
case ATA_PROT_DMA_WRITE: case ATA_PROT_DMA_WRITE:
......
...@@ -847,6 +847,7 @@ void scsi_finish_command(struct scsi_cmnd *cmd) ...@@ -847,6 +847,7 @@ void scsi_finish_command(struct scsi_cmnd *cmd)
cmd->done(cmd); cmd->done(cmd);
} }
EXPORT_SYMBOL(scsi_finish_command);
/* /*
* Function: scsi_adjust_queue_depth() * Function: scsi_adjust_queue_depth()
......
...@@ -77,7 +77,6 @@ extern int scsi_dispatch_cmd(struct scsi_cmnd *cmd); ...@@ -77,7 +77,6 @@ extern int scsi_dispatch_cmd(struct scsi_cmnd *cmd);
extern int scsi_setup_command_freelist(struct Scsi_Host *shost); extern int scsi_setup_command_freelist(struct Scsi_Host *shost);
extern void scsi_destroy_command_freelist(struct Scsi_Host *shost); extern void scsi_destroy_command_freelist(struct Scsi_Host *shost);
extern void scsi_done(struct scsi_cmnd *cmd); extern void scsi_done(struct scsi_cmnd *cmd);
extern void scsi_finish_command(struct scsi_cmnd *cmd);
extern int scsi_retry_command(struct scsi_cmnd *cmd); extern int scsi_retry_command(struct scsi_cmnd *cmd);
extern int scsi_insert_special_req(struct scsi_request *sreq, int); extern int scsi_insert_special_req(struct scsi_request *sreq, int);
extern void scsi_init_cmd_from_req(struct scsi_cmnd *cmd, extern void scsi_init_cmd_from_req(struct scsi_cmnd *cmd,
......
...@@ -159,5 +159,6 @@ struct scsi_cmnd { ...@@ -159,5 +159,6 @@ struct scsi_cmnd {
extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, int); extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, int);
extern void scsi_put_command(struct scsi_cmnd *); extern void scsi_put_command(struct scsi_cmnd *);
extern void scsi_io_completion(struct scsi_cmnd *, unsigned int, unsigned int); extern void scsi_io_completion(struct scsi_cmnd *, unsigned int, unsigned int);
extern void scsi_finish_command(struct scsi_cmnd *cmd);
#endif /* _SCSI_SCSI_CMND_H */ #endif /* _SCSI_SCSI_CMND_H */
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