Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 2170
b: refs/heads/master
c: 1700c80
h: refs/heads/master
v: v3
  • Loading branch information
unknown authored and Jeff Garzik committed Jun 4, 2005
1 parent 8221eb7 commit 22ccd5c
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 14 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: ae20ea8525a80a863f70d332cf47b71bd9f54c1f
refs/heads/master: 1700c80d8778cf0d024bf6cbdd1c9e9014764530
80 changes: 67 additions & 13 deletions trunk/drivers/scsi/ahci.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
#include <asm/io.h>

#define DRV_NAME "ahci"
#define DRV_VERSION "1.00"
#define DRV_VERSION "1.01"


enum {
Expand Down Expand Up @@ -134,6 +134,9 @@ enum {
PORT_CMD_ICC_ACTIVE = (0x1 << 28), /* Put i/f in active state */
PORT_CMD_ICC_PARTIAL = (0x2 << 28), /* Put i/f in partial state */
PORT_CMD_ICC_SLUMBER = (0x6 << 28), /* Put i/f in slumber state */

/* hpriv->flags bits */
AHCI_FLAG_MSI = (1 << 0),
};

struct ahci_cmd_hdr {
Expand Down Expand Up @@ -183,6 +186,7 @@ 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 void ahci_remove_one (struct pci_dev *pdev);

static Scsi_Host_Template ahci_sht = {
.module = THIS_MODULE,
Expand Down Expand Up @@ -272,7 +276,7 @@ static struct pci_driver ahci_pci_driver = {
.name = DRV_NAME,
.id_table = ahci_pci_tbl,
.probe = ahci_init_one,
.remove = ata_pci_remove_one,
.remove = ahci_remove_one,
};


Expand Down Expand Up @@ -795,8 +799,6 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent)
return rc;
}
}

hpriv->flags |= HOST_CAP_64;
} else {
rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
if (rc) {
Expand Down Expand Up @@ -879,15 +881,19 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent)
}

/* move to PCI layer, integrate w/ MSI stuff */
static void pci_enable_intx(struct pci_dev *pdev)
static void pci_intx(struct pci_dev *pdev, int enable)
{
u16 pci_command;
u16 pci_command, new;

pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
if (pci_command & PCI_COMMAND_INTX_DISABLE) {
pci_command &= ~PCI_COMMAND_INTX_DISABLE;

if (enable)
new = pci_command & ~PCI_COMMAND_INTX_DISABLE;
else
new = pci_command | PCI_COMMAND_INTX_DISABLE;

if (new != pci_command)
pci_write_config_word(pdev, PCI_COMMAND, pci_command);
}
}

static void ahci_print_info(struct ata_probe_ent *probe_ent)
Expand Down Expand Up @@ -969,7 +975,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 have_msi, pci_dev_busy = 0;
int rc;

VPRINTK("ENTER\n");
Expand All @@ -987,12 +993,17 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_out;
}

pci_enable_intx(pdev);
if (pci_enable_msi(pdev) == 0)
have_msi = 1;
else {
pci_intx(pdev, 1);
have_msi = 0;
}

probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
if (probe_ent == NULL) {
rc = -ENOMEM;
goto err_out_regions;
goto err_out_msi;
}

memset(probe_ent, 0, sizeof(*probe_ent));
Expand Down Expand Up @@ -1025,6 +1036,9 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
probe_ent->mmio_base = mmio_base;
probe_ent->private_data = hpriv;

if (have_msi)
hpriv->flags |= AHCI_FLAG_MSI;

/* initialize adapter */
rc = ahci_host_init(probe_ent);
if (rc)
Expand All @@ -1044,14 +1058,54 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
iounmap(mmio_base);
err_out_free_ent:
kfree(probe_ent);
err_out_regions:
err_out_msi:
if (have_msi)
pci_disable_msi(pdev);
else
pci_intx(pdev, 0);
pci_release_regions(pdev);
err_out:
if (!pci_dev_busy)
pci_disable_device(pdev);
return rc;
}

static void ahci_remove_one (struct pci_dev *pdev)
{
struct device *dev = pci_dev_to_dev(pdev);
struct ata_host_set *host_set = dev_get_drvdata(dev);
struct ahci_host_priv *hpriv = host_set->private_data;
struct ata_port *ap;
unsigned int i;
int have_msi;

for (i = 0; i < host_set->n_ports; i++) {
ap = host_set->ports[i];

scsi_remove_host(ap->host);
}

have_msi = hpriv->flags & AHCI_FLAG_MSI;
free_irq(host_set->irq, host_set);

for (i = 0; i < host_set->n_ports; i++) {
ap = host_set->ports[i];

ata_scsi_release(ap->host);
scsi_host_put(ap->host);
}

host_set->ops->host_stop(host_set);
kfree(host_set);

if (have_msi)
pci_disable_msi(pdev);
else
pci_intx(pdev, 0);
pci_release_regions(pdev);
pci_disable_device(pdev);
dev_set_drvdata(dev, NULL);
}

static int __init ahci_init(void)
{
Expand Down

0 comments on commit 22ccd5c

Please sign in to comment.