Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 234979
b: refs/heads/master
c: 0e0b494
h: refs/heads/master
i:
  234977: 8f559e8
  234975: c9d9bd1
v: v3
  • Loading branch information
James Bottomley authored and Jeff Garzik committed Mar 2, 2011
1 parent fe44603 commit fe14f8f
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 10 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c34aeebc06e8bdde93e8c8f40d9903b1aaab63c6
refs/heads/master: 0e0b494ca8c54a7297d0cc549405091019b3b77e
53 changes: 44 additions & 9 deletions trunk/drivers/ata/libata-eh.c
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,6 @@ static void ata_eh_unload(struct ata_port *ap)
void ata_scsi_error(struct Scsi_Host *host)
{
struct ata_port *ap = ata_shost_to_port(host);
int i;
unsigned long flags;
LIST_HEAD(eh_work_q);

Expand All @@ -597,6 +596,34 @@ void ata_scsi_error(struct Scsi_Host *host)
list_splice_init(&host->eh_cmd_q, &eh_work_q);
spin_unlock_irqrestore(host->host_lock, flags);

ata_scsi_cmd_error_handler(host, ap, &eh_work_q);

/* If we timed raced normal completion and there is nothing to
recover nr_timedout == 0 why exactly are we doing error recovery ? */
ata_scsi_port_error_handler(host, ap);

/* finish or retry handled scmd's and clean up */
WARN_ON(host->host_failed || !list_empty(&eh_work_q));

DPRINTK("EXIT\n");
}

/**
* ata_scsi_cmd_error_handler - error callback for a list of commands
* @host: scsi host containing the port
* @ap: ATA port within the host
* @eh_work_q: list of commands to process
*
* process the given list of commands and return those finished to the
* ap->eh_done_q. This function is the first part of the libata error
* handler which processes a given list of failed commands.
*/
void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port *ap,
struct list_head *eh_work_q)
{
int i;
unsigned long flags;

/* make sure sff pio task is not running */
ata_sff_flush_pio_task(ap);

Expand Down Expand Up @@ -632,7 +659,7 @@ void ata_scsi_error(struct Scsi_Host *host)
if (ap->ops->lost_interrupt)
ap->ops->lost_interrupt(ap);

list_for_each_entry_safe(scmd, tmp, &eh_work_q, eh_entry) {
list_for_each_entry_safe(scmd, tmp, eh_work_q, eh_entry) {
struct ata_queued_cmd *qc;

for (i = 0; i < ATA_MAX_QUEUE; i++) {
Expand Down Expand Up @@ -676,8 +703,20 @@ void ata_scsi_error(struct Scsi_Host *host)
} else
spin_unlock_wait(ap->lock);

/* If we timed raced normal completion and there is nothing to
recover nr_timedout == 0 why exactly are we doing error recovery ? */
}
EXPORT_SYMBOL(ata_scsi_cmd_error_handler);

/**
* ata_scsi_port_error_handler - recover the port after the commands
* @host: SCSI host containing the port
* @ap: the ATA port
*
* Handle the recovery of the port @ap after all the commands
* have been recovered.
*/
void ata_scsi_port_error_handler(struct Scsi_Host *host, struct ata_port *ap)
{
unsigned long flags;

/* invoke error handler */
if (ap->ops->error_handler) {
Expand Down Expand Up @@ -766,9 +805,6 @@ void ata_scsi_error(struct Scsi_Host *host)
ap->ops->eng_timeout(ap);
}

/* finish or retry handled scmd's and clean up */
WARN_ON(host->host_failed || !list_empty(&eh_work_q));

scsi_eh_flush_done_q(&ap->eh_done_q);

/* clean up */
Expand All @@ -789,9 +825,8 @@ void ata_scsi_error(struct Scsi_Host *host)
wake_up_all(&ap->eh_wait_q);

spin_unlock_irqrestore(ap->lock, flags);

DPRINTK("EXIT\n");
}
EXPORT_SYMBOL_GPL(ata_scsi_port_error_handler);

/**
* ata_port_wait_eh - Wait for the currently pending EH to complete
Expand Down
2 changes: 2 additions & 0 deletions trunk/include/linux/libata.h
Original file line number Diff line number Diff line change
Expand Up @@ -1050,6 +1050,8 @@ extern int ata_scsi_change_queue_depth(struct scsi_device *sdev,
int queue_depth, int reason);
extern struct ata_device *ata_dev_pair(struct ata_device *adev);
extern int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev);
extern void ata_scsi_port_error_handler(struct Scsi_Host *host, struct ata_port *ap);
extern void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port *ap, struct list_head *eh_q);

extern int ata_cable_40wire(struct ata_port *ap);
extern int ata_cable_80wire(struct ata_port *ap);
Expand Down

0 comments on commit fe14f8f

Please sign in to comment.