Loading drivers/scsi/ahci.c +67 −13 Original line number Diff line number Diff line Loading @@ -39,7 +39,7 @@ #include <asm/io.h> #define DRV_NAME "ahci" #define DRV_VERSION "1.00" #define DRV_VERSION "1.01" enum { Loading Loading @@ -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 { Loading Loading @@ -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, Loading Loading @@ -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, }; Loading Loading @@ -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) { Loading Loading @@ -879,16 +881,20 @@ 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) { Loading Loading @@ -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"); Loading @@ -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)); Loading Loading @@ -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) Loading @@ -1044,7 +1058,11 @@ 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) Loading @@ -1052,6 +1070,42 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) 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) { Loading Loading
drivers/scsi/ahci.c +67 −13 Original line number Diff line number Diff line Loading @@ -39,7 +39,7 @@ #include <asm/io.h> #define DRV_NAME "ahci" #define DRV_VERSION "1.00" #define DRV_VERSION "1.01" enum { Loading Loading @@ -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 { Loading Loading @@ -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, Loading Loading @@ -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, }; Loading Loading @@ -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) { Loading Loading @@ -879,16 +881,20 @@ 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) { Loading Loading @@ -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"); Loading @@ -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)); Loading Loading @@ -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) Loading @@ -1044,7 +1058,11 @@ 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) Loading @@ -1052,6 +1070,42 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) 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) { Loading