diff options
Diffstat (limited to 'drivers/scsi/ahci.c')
-rw-r--r-- | drivers/scsi/ahci.c | 57 |
1 files changed, 27 insertions, 30 deletions
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c index c840d5ec12a7..98ce6bb62ff8 100644 --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c | |||
@@ -206,6 +206,7 @@ static struct scsi_host_template ahci_sht = { | |||
206 | .name = DRV_NAME, | 206 | .name = DRV_NAME, |
207 | .ioctl = ata_scsi_ioctl, | 207 | .ioctl = ata_scsi_ioctl, |
208 | .queuecommand = ata_scsi_queuecmd, | 208 | .queuecommand = ata_scsi_queuecmd, |
209 | .eh_timed_out = ata_scsi_timed_out, | ||
209 | .eh_strategy_handler = ata_scsi_error, | 210 | .eh_strategy_handler = ata_scsi_error, |
210 | .can_queue = ATA_DEF_QUEUE, | 211 | .can_queue = ATA_DEF_QUEUE, |
211 | .this_id = ATA_SHT_THIS_ID, | 212 | .this_id = ATA_SHT_THIS_ID, |
@@ -506,6 +507,15 @@ static unsigned int ahci_dev_classify(struct ata_port *ap) | |||
506 | return ata_dev_classify(&tf); | 507 | return ata_dev_classify(&tf); |
507 | } | 508 | } |
508 | 509 | ||
510 | static void ahci_fill_cmd_slot(struct ata_port *ap, u32 opts) | ||
511 | { | ||
512 | struct ahci_port_priv *pp = ap->private_data; | ||
513 | pp->cmd_slot[0].opts = cpu_to_le32(opts); | ||
514 | pp->cmd_slot[0].status = 0; | ||
515 | pp->cmd_slot[0].tbl_addr = cpu_to_le32(pp->cmd_tbl_dma & 0xffffffff); | ||
516 | pp->cmd_slot[0].tbl_addr_hi = cpu_to_le32((pp->cmd_tbl_dma >> 16) >> 16); | ||
517 | } | ||
518 | |||
509 | static void ahci_phy_reset(struct ata_port *ap) | 519 | static void ahci_phy_reset(struct ata_port *ap) |
510 | { | 520 | { |
511 | void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; | 521 | void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; |
@@ -584,42 +594,35 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc) | |||
584 | { | 594 | { |
585 | struct ata_port *ap = qc->ap; | 595 | struct ata_port *ap = qc->ap; |
586 | struct ahci_port_priv *pp = ap->private_data; | 596 | struct ahci_port_priv *pp = ap->private_data; |
597 | int is_atapi = is_atapi_taskfile(&qc->tf); | ||
587 | u32 opts; | 598 | u32 opts; |
588 | const u32 cmd_fis_len = 5; /* five dwords */ | 599 | const u32 cmd_fis_len = 5; /* five dwords */ |
589 | unsigned int n_elem; | 600 | unsigned int n_elem; |
590 | 601 | ||
591 | /* | 602 | /* |
592 | * Fill in command slot information (currently only one slot, | ||
593 | * slot 0, is currently since we don't do queueing) | ||
594 | */ | ||
595 | |||
596 | opts = cmd_fis_len; | ||
597 | if (qc->tf.flags & ATA_TFLAG_WRITE) | ||
598 | opts |= AHCI_CMD_WRITE; | ||
599 | if (is_atapi_taskfile(&qc->tf)) | ||
600 | opts |= AHCI_CMD_ATAPI; | ||
601 | |||
602 | pp->cmd_slot[0].opts = cpu_to_le32(opts); | ||
603 | pp->cmd_slot[0].status = 0; | ||
604 | pp->cmd_slot[0].tbl_addr = cpu_to_le32(pp->cmd_tbl_dma & 0xffffffff); | ||
605 | pp->cmd_slot[0].tbl_addr_hi = cpu_to_le32((pp->cmd_tbl_dma >> 16) >> 16); | ||
606 | |||
607 | /* | ||
608 | * Fill in command table information. First, the header, | 603 | * Fill in command table information. First, the header, |
609 | * a SATA Register - Host to Device command FIS. | 604 | * a SATA Register - Host to Device command FIS. |
610 | */ | 605 | */ |
611 | ata_tf_to_fis(&qc->tf, pp->cmd_tbl, 0); | 606 | ata_tf_to_fis(&qc->tf, pp->cmd_tbl, 0); |
612 | if (opts & AHCI_CMD_ATAPI) { | 607 | if (is_atapi) { |
613 | memset(pp->cmd_tbl + AHCI_CMD_TBL_CDB, 0, 32); | 608 | memset(pp->cmd_tbl + AHCI_CMD_TBL_CDB, 0, 32); |
614 | memcpy(pp->cmd_tbl + AHCI_CMD_TBL_CDB, qc->cdb, ap->cdb_len); | 609 | memcpy(pp->cmd_tbl + AHCI_CMD_TBL_CDB, qc->cdb, ap->cdb_len); |
615 | } | 610 | } |
616 | 611 | ||
617 | if (!(qc->flags & ATA_QCFLAG_DMAMAP)) | 612 | n_elem = 0; |
618 | return; | 613 | if (qc->flags & ATA_QCFLAG_DMAMAP) |
614 | n_elem = ahci_fill_sg(qc); | ||
619 | 615 | ||
620 | n_elem = ahci_fill_sg(qc); | 616 | /* |
617 | * Fill in command slot information. | ||
618 | */ | ||
619 | opts = cmd_fis_len | n_elem << 16; | ||
620 | if (qc->tf.flags & ATA_TFLAG_WRITE) | ||
621 | opts |= AHCI_CMD_WRITE; | ||
622 | if (is_atapi) | ||
623 | opts |= AHCI_CMD_ATAPI; | ||
621 | 624 | ||
622 | pp->cmd_slot[0].opts |= cpu_to_le32(n_elem << 16); | 625 | ahci_fill_cmd_slot(ap, opts); |
623 | } | 626 | } |
624 | 627 | ||
625 | static void ahci_restart_port(struct ata_port *ap, u32 irq_stat) | 628 | static void ahci_restart_port(struct ata_port *ap, u32 irq_stat) |
@@ -676,19 +679,13 @@ static void ahci_eng_timeout(struct ata_port *ap) | |||
676 | 679 | ||
677 | spin_lock_irqsave(&host_set->lock, flags); | 680 | spin_lock_irqsave(&host_set->lock, flags); |
678 | 681 | ||
682 | ahci_restart_port(ap, readl(port_mmio + PORT_IRQ_STAT)); | ||
679 | qc = ata_qc_from_tag(ap, ap->active_tag); | 683 | qc = ata_qc_from_tag(ap, ap->active_tag); |
680 | if (!qc) { | 684 | qc->err_mask |= AC_ERR_TIMEOUT; |
681 | printk(KERN_ERR "ata%u: BUG: timeout without command\n", | ||
682 | ap->id); | ||
683 | } else { | ||
684 | ahci_restart_port(ap, readl(port_mmio + PORT_IRQ_STAT)); | ||
685 | qc->err_mask |= AC_ERR_TIMEOUT; | ||
686 | } | ||
687 | 685 | ||
688 | spin_unlock_irqrestore(&host_set->lock, flags); | 686 | spin_unlock_irqrestore(&host_set->lock, flags); |
689 | 687 | ||
690 | if (qc) | 688 | ata_eh_qc_complete(qc); |
691 | ata_eh_qc_complete(qc); | ||
692 | } | 689 | } |
693 | 690 | ||
694 | static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc) | 691 | static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc) |