Automatic merge of /spare/repo/libata-dev branch ahci-msi
This commit is contained in:
commit
d3c39d14d1
@ -39,7 +39,7 @@
|
|||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
|
||||||
#define DRV_NAME "ahci"
|
#define DRV_NAME "ahci"
|
||||||
#define DRV_VERSION "1.00"
|
#define DRV_VERSION "1.01"
|
||||||
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@ -134,6 +134,9 @@ enum {
|
|||||||
PORT_CMD_ICC_ACTIVE = (0x1 << 28), /* Put i/f in active state */
|
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_PARTIAL = (0x2 << 28), /* Put i/f in partial state */
|
||||||
PORT_CMD_ICC_SLUMBER = (0x6 << 28), /* Put i/f in slumber 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 {
|
struct ahci_cmd_hdr {
|
||||||
@ -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_status(struct ata_port *ap);
|
||||||
static u8 ahci_check_err(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 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 = {
|
static Scsi_Host_Template ahci_sht = {
|
||||||
.module = THIS_MODULE,
|
.module = THIS_MODULE,
|
||||||
@ -272,7 +276,7 @@ static struct pci_driver ahci_pci_driver = {
|
|||||||
.name = DRV_NAME,
|
.name = DRV_NAME,
|
||||||
.id_table = ahci_pci_tbl,
|
.id_table = ahci_pci_tbl,
|
||||||
.probe = ahci_init_one,
|
.probe = ahci_init_one,
|
||||||
.remove = ata_pci_remove_one,
|
.remove = ahci_remove_one,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -795,8 +799,6 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hpriv->flags |= HOST_CAP_64;
|
|
||||||
} else {
|
} else {
|
||||||
rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
|
rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
@ -879,15 +881,19 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* move to PCI layer, integrate w/ MSI stuff */
|
/* 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);
|
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);
|
pci_write_config_word(pdev, PCI_COMMAND, pci_command);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ahci_print_info(struct ata_probe_ent *probe_ent)
|
static void ahci_print_info(struct ata_probe_ent *probe_ent)
|
||||||
@ -969,7 +975,7 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||||||
unsigned long base;
|
unsigned long base;
|
||||||
void *mmio_base;
|
void *mmio_base;
|
||||||
unsigned int board_idx = (unsigned int) ent->driver_data;
|
unsigned int board_idx = (unsigned int) ent->driver_data;
|
||||||
int pci_dev_busy = 0;
|
int have_msi, pci_dev_busy = 0;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
VPRINTK("ENTER\n");
|
VPRINTK("ENTER\n");
|
||||||
@ -987,12 +993,17 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||||||
goto err_out;
|
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);
|
probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
|
||||||
if (probe_ent == NULL) {
|
if (probe_ent == NULL) {
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
goto err_out_regions;
|
goto err_out_msi;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(probe_ent, 0, sizeof(*probe_ent));
|
memset(probe_ent, 0, sizeof(*probe_ent));
|
||||||
@ -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->mmio_base = mmio_base;
|
||||||
probe_ent->private_data = hpriv;
|
probe_ent->private_data = hpriv;
|
||||||
|
|
||||||
|
if (have_msi)
|
||||||
|
hpriv->flags |= AHCI_FLAG_MSI;
|
||||||
|
|
||||||
/* initialize adapter */
|
/* initialize adapter */
|
||||||
rc = ahci_host_init(probe_ent);
|
rc = ahci_host_init(probe_ent);
|
||||||
if (rc)
|
if (rc)
|
||||||
@ -1044,7 +1058,11 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||||||
iounmap(mmio_base);
|
iounmap(mmio_base);
|
||||||
err_out_free_ent:
|
err_out_free_ent:
|
||||||
kfree(probe_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);
|
pci_release_regions(pdev);
|
||||||
err_out:
|
err_out:
|
||||||
if (!pci_dev_busy)
|
if (!pci_dev_busy)
|
||||||
@ -1052,6 +1070,42 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||||||
return rc;
|
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)
|
static int __init ahci_init(void)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user