Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 42102
b: refs/heads/master
c: 648a88b
h: refs/heads/master
v: v3
  • Loading branch information
Tejun Heo authored and Jeff Garzik committed Dec 2, 2006
1 parent e808901 commit eab226c
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 29 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: 0df0d0a0ea9ffcee4e56f96cd9d9e32b0644eb21
refs/heads/master: 648a88be4a016d2637ace3ae74b85a0512255ee8
95 changes: 67 additions & 28 deletions trunk/drivers/ata/ahci.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@

enum {
AHCI_PCI_BAR = 5,
AHCI_MAX_PORTS = 32,
AHCI_MAX_SG = 168, /* hardware max is 64K */
AHCI_DMA_BOUNDARY = 0xffffffff,
AHCI_USE_CLUSTERING = 0,
Expand All @@ -77,8 +78,9 @@ enum {
RX_FIS_UNK = 0x60, /* offset of Unknown FIS data */

board_ahci = 0,
board_ahci_vt8251 = 1,
board_ahci_ign_iferr = 2,
board_ahci_pi = 1,
board_ahci_vt8251 = 2,
board_ahci_ign_iferr = 3,

/* global controller registers */
HOST_CAP = 0x00, /* host capabilities */
Expand Down Expand Up @@ -169,6 +171,7 @@ enum {
/* ap->flags bits */
AHCI_FLAG_NO_NCQ = (1 << 24),
AHCI_FLAG_IGN_IRQ_IF_ERR = (1 << 25), /* ignore IRQ_IF_ERR */
AHCI_FLAG_HONOR_PI = (1 << 26), /* honor PORTS_IMPL */
};

struct ahci_cmd_hdr {
Expand Down Expand Up @@ -317,6 +320,16 @@ static const struct ata_port_info ahci_port_info[] = {
.udma_mask = 0x7f, /* udma0-6 ; FIXME */
.port_ops = &ahci_ops,
},
/* board_ahci_pi */
{
.sht = &ahci_sht,
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
ATA_FLAG_SKIP_D2H_BSY | AHCI_FLAG_HONOR_PI,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = 0x7f, /* udma0-6 ; FIXME */
.port_ops = &ahci_ops,
},
/* board_ahci_vt8251 */
{
.sht = &ahci_sht,
Expand Down Expand Up @@ -353,22 +366,22 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, 0x2682), board_ahci }, /* ESB2 */
{ PCI_VDEVICE(INTEL, 0x2683), board_ahci }, /* ESB2 */
{ PCI_VDEVICE(INTEL, 0x27c6), board_ahci }, /* ICH7-M DH */
{ PCI_VDEVICE(INTEL, 0x2821), board_ahci }, /* ICH8 */
{ PCI_VDEVICE(INTEL, 0x2822), board_ahci }, /* ICH8 */
{ PCI_VDEVICE(INTEL, 0x2824), board_ahci }, /* ICH8 */
{ PCI_VDEVICE(INTEL, 0x2829), board_ahci }, /* ICH8M */
{ PCI_VDEVICE(INTEL, 0x282a), board_ahci }, /* ICH8M */
{ PCI_VDEVICE(INTEL, 0x2922), board_ahci }, /* ICH9 */
{ PCI_VDEVICE(INTEL, 0x2923), board_ahci }, /* ICH9 */
{ PCI_VDEVICE(INTEL, 0x2924), board_ahci }, /* ICH9 */
{ PCI_VDEVICE(INTEL, 0x2925), board_ahci }, /* ICH9 */
{ PCI_VDEVICE(INTEL, 0x2927), board_ahci }, /* ICH9 */
{ PCI_VDEVICE(INTEL, 0x2929), board_ahci }, /* ICH9M */
{ PCI_VDEVICE(INTEL, 0x292a), board_ahci }, /* ICH9M */
{ PCI_VDEVICE(INTEL, 0x292b), board_ahci }, /* ICH9M */
{ PCI_VDEVICE(INTEL, 0x292f), board_ahci }, /* ICH9M */
{ PCI_VDEVICE(INTEL, 0x294d), board_ahci }, /* ICH9 */
{ PCI_VDEVICE(INTEL, 0x294e), board_ahci }, /* ICH9M */
{ PCI_VDEVICE(INTEL, 0x2821), board_ahci_pi }, /* ICH8 */
{ PCI_VDEVICE(INTEL, 0x2822), board_ahci_pi }, /* ICH8 */
{ PCI_VDEVICE(INTEL, 0x2824), board_ahci_pi }, /* ICH8 */
{ PCI_VDEVICE(INTEL, 0x2829), board_ahci_pi }, /* ICH8M */
{ PCI_VDEVICE(INTEL, 0x282a), board_ahci_pi }, /* ICH8M */
{ PCI_VDEVICE(INTEL, 0x2922), board_ahci_pi }, /* ICH9 */
{ PCI_VDEVICE(INTEL, 0x2923), board_ahci_pi }, /* ICH9 */
{ PCI_VDEVICE(INTEL, 0x2924), board_ahci_pi }, /* ICH9 */
{ PCI_VDEVICE(INTEL, 0x2925), board_ahci_pi }, /* ICH9 */
{ PCI_VDEVICE(INTEL, 0x2927), board_ahci_pi }, /* ICH9 */
{ PCI_VDEVICE(INTEL, 0x2929), board_ahci_pi }, /* ICH9M */
{ PCI_VDEVICE(INTEL, 0x292a), board_ahci_pi }, /* ICH9M */
{ PCI_VDEVICE(INTEL, 0x292b), board_ahci_pi }, /* ICH9M */
{ PCI_VDEVICE(INTEL, 0x292f), board_ahci_pi }, /* ICH9M */
{ PCI_VDEVICE(INTEL, 0x294d), board_ahci_pi }, /* ICH9 */
{ PCI_VDEVICE(INTEL, 0x294e), board_ahci_pi }, /* ICH9M */

/* JMicron */
{ PCI_VDEVICE(JMICRON, 0x2360), board_ahci_ign_iferr }, /* JMB360 */
Expand Down Expand Up @@ -691,7 +704,8 @@ static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev)
}

static void ahci_init_controller(void __iomem *mmio, struct pci_dev *pdev,
int n_ports, u32 cap)
int n_ports, unsigned int port_flags,
struct ahci_host_priv *hpriv)
{
int i, rc;
u32 tmp;
Expand All @@ -700,13 +714,12 @@ static void ahci_init_controller(void __iomem *mmio, struct pci_dev *pdev,
void __iomem *port_mmio = ahci_port_base(mmio, i);
const char *emsg = NULL;

#if 0 /* BIOSen initialize this incorrectly */
if (!(hpriv->port_map & (1 << i)))
if ((port_flags & AHCI_FLAG_HONOR_PI) &&
!(hpriv->port_map & (1 << i)))
continue;
#endif

/* make sure port is not active */
rc = ahci_deinit_port(port_mmio, cap, &emsg);
rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg);
if (rc)
dev_printk(KERN_WARNING, &pdev->dev,
"%s (%d)\n", emsg, rc);
Expand Down Expand Up @@ -1363,7 +1376,8 @@ static int ahci_pci_device_resume(struct pci_dev *pdev)
if (rc)
return rc;

ahci_init_controller(mmio, pdev, host->n_ports, hpriv->cap);
ahci_init_controller(mmio, pdev, host->n_ports,
host->ports[0]->flags, hpriv);
}

ata_host_resume(host);
Expand Down Expand Up @@ -1475,7 +1489,7 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent)
struct ahci_host_priv *hpriv = probe_ent->private_data;
struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
void __iomem *mmio = probe_ent->mmio_base;
unsigned int i, using_dac;
unsigned int i, cap_n_ports, using_dac;
int rc;

rc = ahci_reset_controller(mmio, pdev);
Expand All @@ -1484,10 +1498,34 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent)

hpriv->cap = readl(mmio + HOST_CAP);
hpriv->port_map = readl(mmio + HOST_PORTS_IMPL);
probe_ent->n_ports = ahci_nr_ports(hpriv->cap);
cap_n_ports = ahci_nr_ports(hpriv->cap);

VPRINTK("cap 0x%x port_map 0x%x n_ports %d\n",
hpriv->cap, hpriv->port_map, probe_ent->n_ports);
hpriv->cap, hpriv->port_map, cap_n_ports);

if (probe_ent->port_flags & AHCI_FLAG_HONOR_PI) {
unsigned int n_ports = cap_n_ports;
u32 port_map = hpriv->port_map;
int max_port = 0;

for (i = 0; i < AHCI_MAX_PORTS && n_ports; i++) {
if (port_map & (1 << i)) {
n_ports--;
port_map &= ~(1 << i);
max_port = i;
} else
probe_ent->dummy_port_mask |= 1 << i;
}

if (n_ports || port_map)
dev_printk(KERN_WARNING, &pdev->dev,
"nr_ports (%u) and implemented port map "
"(0x%x) don't match\n",
cap_n_ports, hpriv->port_map);

probe_ent->n_ports = max_port + 1;
} else
probe_ent->n_ports = cap_n_ports;

using_dac = hpriv->cap & HOST_CAP_64;
if (using_dac &&
Expand Down Expand Up @@ -1519,7 +1557,8 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent)
for (i = 0; i < probe_ent->n_ports; i++)
ahci_setup_port(&probe_ent->port[i], (unsigned long) mmio, i);

ahci_init_controller(mmio, pdev, probe_ent->n_ports, hpriv->cap);
ahci_init_controller(mmio, pdev, probe_ent->n_ports,
probe_ent->port_flags, hpriv);

pci_set_master(pdev);

Expand Down

0 comments on commit eab226c

Please sign in to comment.