diff options
Diffstat (limited to 'drivers/scsi/ahci.c')
-rw-r--r-- | drivers/scsi/ahci.c | 52 |
1 files changed, 32 insertions, 20 deletions
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c index e3b9692b9688..179c95c878ac 100644 --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c | |||
@@ -1,26 +1,34 @@ | |||
1 | /* | 1 | /* |
2 | * ahci.c - AHCI SATA support | 2 | * ahci.c - AHCI SATA support |
3 | * | 3 | * |
4 | * Copyright 2004 Red Hat, Inc. | 4 | * Maintained by: Jeff Garzik <jgarzik@pobox.com> |
5 | * Please ALWAYS copy linux-ide@vger.kernel.org | ||
6 | * on emails. | ||
5 | * | 7 | * |
6 | * The contents of this file are subject to the Open | 8 | * Copyright 2004-2005 Red Hat, Inc. |
7 | * Software License version 1.1 that can be found at | ||
8 | * http://www.opensource.org/licenses/osl-1.1.txt and is included herein | ||
9 | * by reference. | ||
10 | * | 9 | * |
11 | * Alternatively, the contents of this file may be used under the terms | ||
12 | * of the GNU General Public License version 2 (the "GPL") as distributed | ||
13 | * in the kernel source COPYING file, in which case the provisions of | ||
14 | * the GPL are applicable instead of the above. If you wish to allow | ||
15 | * the use of your version of this file only under the terms of the | ||
16 | * GPL and not to allow others to use your version of this file under | ||
17 | * the OSL, indicate your decision by deleting the provisions above and | ||
18 | * replace them with the notice and other provisions required by the GPL. | ||
19 | * If you do not delete the provisions above, a recipient may use your | ||
20 | * version of this file under either the OSL or the GPL. | ||
21 | * | 10 | * |
22 | * Version 1.0 of the AHCI specification: | 11 | * This program is free software; you can redistribute it and/or modify |
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation; either version 2, or (at your option) | ||
14 | * any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this program; see the file COPYING. If not, write to | ||
23 | * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | ||
24 | * | ||
25 | * | ||
26 | * libata documentation is available via 'make {ps|pdf}docs', | ||
27 | * as Documentation/DocBook/libata.* | ||
28 | * | ||
29 | * AHCI hardware documentation: | ||
23 | * http://www.intel.com/technology/serialata/pdf/rev1_0.pdf | 30 | * http://www.intel.com/technology/serialata/pdf/rev1_0.pdf |
31 | * http://www.intel.com/technology/serialata/pdf/rev1_1.pdf | ||
24 | * | 32 | * |
25 | */ | 33 | */ |
26 | 34 | ||
@@ -269,6 +277,8 @@ static struct pci_device_id ahci_pci_tbl[] = { | |||
269 | board_ahci }, /* ESB2 */ | 277 | board_ahci }, /* ESB2 */ |
270 | { PCI_VENDOR_ID_INTEL, 0x2683, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 278 | { PCI_VENDOR_ID_INTEL, 0x2683, PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
271 | board_ahci }, /* ESB2 */ | 279 | board_ahci }, /* ESB2 */ |
280 | { PCI_VENDOR_ID_INTEL, 0x27c6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
281 | board_ahci }, /* ICH7-M DH */ | ||
272 | { } /* terminate list */ | 282 | { } /* terminate list */ |
273 | }; | 283 | }; |
274 | 284 | ||
@@ -584,12 +594,16 @@ static void ahci_intr_error(struct ata_port *ap, u32 irq_stat) | |||
584 | 594 | ||
585 | static void ahci_eng_timeout(struct ata_port *ap) | 595 | static void ahci_eng_timeout(struct ata_port *ap) |
586 | { | 596 | { |
587 | void *mmio = ap->host_set->mmio_base; | 597 | struct ata_host_set *host_set = ap->host_set; |
598 | void *mmio = host_set->mmio_base; | ||
588 | void *port_mmio = ahci_port_base(mmio, ap->port_no); | 599 | void *port_mmio = ahci_port_base(mmio, ap->port_no); |
589 | struct ata_queued_cmd *qc; | 600 | struct ata_queued_cmd *qc; |
601 | unsigned long flags; | ||
590 | 602 | ||
591 | DPRINTK("ENTER\n"); | 603 | DPRINTK("ENTER\n"); |
592 | 604 | ||
605 | spin_lock_irqsave(&host_set->lock, flags); | ||
606 | |||
593 | ahci_intr_error(ap, readl(port_mmio + PORT_IRQ_STAT)); | 607 | ahci_intr_error(ap, readl(port_mmio + PORT_IRQ_STAT)); |
594 | 608 | ||
595 | qc = ata_qc_from_tag(ap, ap->active_tag); | 609 | qc = ata_qc_from_tag(ap, ap->active_tag); |
@@ -607,6 +621,7 @@ static void ahci_eng_timeout(struct ata_port *ap) | |||
607 | ata_qc_complete(qc, ATA_ERR); | 621 | ata_qc_complete(qc, ATA_ERR); |
608 | } | 622 | } |
609 | 623 | ||
624 | spin_unlock_irqrestore(&host_set->lock, flags); | ||
610 | } | 625 | } |
611 | 626 | ||
612 | static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc) | 627 | static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc) |
@@ -696,9 +711,6 @@ static int ahci_qc_issue(struct ata_queued_cmd *qc) | |||
696 | struct ata_port *ap = qc->ap; | 711 | struct ata_port *ap = qc->ap; |
697 | void *port_mmio = (void *) ap->ioaddr.cmd_addr; | 712 | void *port_mmio = (void *) ap->ioaddr.cmd_addr; |
698 | 713 | ||
699 | writel(1, port_mmio + PORT_SCR_ACT); | ||
700 | readl(port_mmio + PORT_SCR_ACT); /* flush */ | ||
701 | |||
702 | writel(1, port_mmio + PORT_CMD_ISSUE); | 714 | writel(1, port_mmio + PORT_CMD_ISSUE); |
703 | readl(port_mmio + PORT_CMD_ISSUE); /* flush */ | 715 | readl(port_mmio + PORT_CMD_ISSUE); /* flush */ |
704 | 716 | ||