diff options
Diffstat (limited to 'drivers/scsi/ahci.c')
| -rw-r--r-- | drivers/scsi/ahci.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c index 48e9e1a0c2e0..9bf037efa2a2 100644 --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c @@ -179,6 +179,7 @@ static void ahci_port_stop(struct ata_port *ap); static void ahci_host_stop(struct ata_host_set *host_set); static void ahci_qc_prep(struct ata_queued_cmd *qc); static u8 ahci_check_status(struct ata_port *ap); +static u8 ahci_check_err(struct ata_port *ap); static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc); static Scsi_Host_Template ahci_sht = { @@ -204,6 +205,8 @@ static struct ata_port_operations ahci_ops = { .port_disable = ata_port_disable, .check_status = ahci_check_status, + .check_altstatus = ahci_check_status, + .check_err = ahci_check_err, .dev_select = ata_noop_dev_select, .phy_reset = ahci_phy_reset, @@ -452,6 +455,13 @@ static u8 ahci_check_status(struct ata_port *ap) return readl(mmio + PORT_TFDATA) & 0xFF; } +static u8 ahci_check_err(struct ata_port *ap) +{ + void *mmio = (void *) ap->ioaddr.cmd_addr; + + return (readl(mmio + PORT_TFDATA) >> 8) & 0xFF; +} + static void ahci_fill_sg(struct ata_queued_cmd *qc) { struct ahci_port_priv *pp = qc->ap->private_data; @@ -940,6 +950,7 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) unsigned long base; void *mmio_base; unsigned int board_idx = (unsigned int) ent->driver_data; + int pci_dev_busy = 0; int rc; VPRINTK("ENTER\n"); @@ -952,8 +963,10 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) return rc; rc = pci_request_regions(pdev, DRV_NAME); - if (rc) + if (rc) { + pci_dev_busy = 1; goto err_out; + } pci_enable_intx(pdev); @@ -1015,7 +1028,8 @@ err_out_free_ent: err_out_regions: pci_release_regions(pdev); err_out: - pci_disable_device(pdev); + if (!pci_dev_busy) + pci_disable_device(pdev); return rc; } |
