X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=drivers%2Fata%2Fsata_qstor.c;h=326c0cfc29b34c366c146ea0c2a6c128d5f7f2f4;hb=62ae67be31c2346b6d74653a148ddbd1b9a94424;hp=fa29dfe2a7b528de2eef33f648ddfb05a7225856;hpb=cca3974e48607c3775dc73b544a5700b2e37c21a;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c index fa29dfe..326c0cf 100644 --- a/drivers/ata/sata_qstor.c +++ b/drivers/ata/sata_qstor.c @@ -34,16 +34,16 @@ #include #include #include -#include #include #include -#include #include #define DRV_NAME "sata_qstor" -#define DRV_VERSION "0.06" +#define DRV_VERSION "0.09" enum { + QS_MMIO_BAR = 4, + QS_PORTS = 4, QS_MAX_PRD = LIBATA_MAX_PRD, QS_CPB_ORDER = 6, @@ -103,7 +103,7 @@ enum { QS_DMA_BOUNDARY = ~0UL }; -typedef enum { qs_state_idle, qs_state_pkt, qs_state_mmio } qs_state_t; +typedef enum { qs_state_mmio, qs_state_pkt } qs_state_t; struct qs_port_priv { u8 *pkt; @@ -111,82 +111,64 @@ struct qs_port_priv { qs_state_t state; }; -static u32 qs_scr_read (struct ata_port *ap, unsigned int sc_reg); -static void qs_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); -static int qs_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); -static irqreturn_t qs_intr (int irq, void *dev_instance, struct pt_regs *regs); +static int qs_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val); +static int qs_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val); +static int qs_ata_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); static int qs_port_start(struct ata_port *ap); static void qs_host_stop(struct ata_host *host); -static void qs_port_stop(struct ata_port *ap); -static void qs_phy_reset(struct ata_port *ap); static void qs_qc_prep(struct ata_queued_cmd *qc); static unsigned int qs_qc_issue(struct ata_queued_cmd *qc); static int qs_check_atapi_dma(struct ata_queued_cmd *qc); static void qs_bmdma_stop(struct ata_queued_cmd *qc); static u8 qs_bmdma_status(struct ata_port *ap); -static void qs_irq_clear(struct ata_port *ap); -static void qs_eng_timeout(struct ata_port *ap); +static void qs_freeze(struct ata_port *ap); +static void qs_thaw(struct ata_port *ap); +static int qs_prereset(struct ata_link *link, unsigned long deadline); +static void qs_error_handler(struct ata_port *ap); static struct scsi_host_template qs_ata_sht = { - .module = THIS_MODULE, - .name = DRV_NAME, - .ioctl = ata_scsi_ioctl, - .queuecommand = ata_scsi_queuecmd, - .can_queue = ATA_DEF_QUEUE, - .this_id = ATA_SHT_THIS_ID, + ATA_BASE_SHT(DRV_NAME), .sg_tablesize = QS_MAX_PRD, - .cmd_per_lun = ATA_SHT_CMD_PER_LUN, - .emulated = ATA_SHT_EMULATED, - //FIXME .use_clustering = ATA_SHT_USE_CLUSTERING, - .use_clustering = ENABLE_CLUSTERING, - .proc_name = DRV_NAME, .dma_boundary = QS_DMA_BOUNDARY, - .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, - .bios_param = ata_std_bios_param, }; -static const struct ata_port_operations qs_ata_ops = { - .port_disable = ata_port_disable, - .tf_load = ata_tf_load, - .tf_read = ata_tf_read, - .check_status = ata_check_status, +static struct ata_port_operations qs_ata_ops = { + .inherits = &ata_sff_port_ops, + .check_atapi_dma = qs_check_atapi_dma, - .exec_command = ata_exec_command, - .dev_select = ata_std_dev_select, - .phy_reset = qs_phy_reset, + .bmdma_stop = qs_bmdma_stop, + .bmdma_status = qs_bmdma_status, .qc_prep = qs_qc_prep, .qc_issue = qs_qc_issue, - .data_xfer = ata_mmio_data_xfer, - .eng_timeout = qs_eng_timeout, - .irq_handler = qs_intr, - .irq_clear = qs_irq_clear, + + .freeze = qs_freeze, + .thaw = qs_thaw, + .prereset = qs_prereset, + .softreset = ATA_OP_NULL, + .error_handler = qs_error_handler, + .post_internal_cmd = ATA_OP_NULL, + .lost_interrupt = ATA_OP_NULL, + .scr_read = qs_scr_read, .scr_write = qs_scr_write, + .port_start = qs_port_start, - .port_stop = qs_port_stop, .host_stop = qs_host_stop, - .bmdma_stop = qs_bmdma_stop, - .bmdma_status = qs_bmdma_status, }; static const struct ata_port_info qs_port_info[] = { /* board_2068_idx */ { - .sht = &qs_ata_sht, .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_SATA_RESET | - //FIXME ATA_FLAG_SRST | ATA_FLAG_MMIO | ATA_FLAG_PIO_POLLING, - .pio_mask = 0x10, /* pio4 */ - .udma_mask = 0x7f, /* udma0-6 */ + .pio_mask = ATA_PIO4_ONLY, + .udma_mask = ATA_UDMA6, .port_ops = &qs_ata_ops, }, }; static const struct pci_device_id qs_ata_pci_tbl[] = { - { PCI_VENDOR_ID_PDC, 0x2068, PCI_ANY_ID, PCI_ANY_ID, 0, 0, - board_2068_idx }, + { PCI_VDEVICE(PDC, 0x2068), board_2068_idx }, { } /* terminate list */ }; @@ -198,6 +180,11 @@ static struct pci_driver qs_ata_pci_driver = { .remove = ata_pci_remove_one, }; +static void __iomem *qs_mmio_base(struct ata_host *host) +{ + return host->iomap[QS_MMIO_BAR]; +} + static int qs_check_atapi_dma(struct ata_queued_cmd *qc) { return 1; /* ATAPI DMA not supported */ @@ -213,59 +200,69 @@ static u8 qs_bmdma_status(struct ata_port *ap) return 0; } -static void qs_irq_clear(struct ata_port *ap) -{ - /* nothing */ -} - static inline void qs_enter_reg_mode(struct ata_port *ap) { - u8 __iomem *chan = ap->host->mmio_base + (ap->port_no * 0x4000); + u8 __iomem *chan = qs_mmio_base(ap->host) + (ap->port_no * 0x4000); + struct qs_port_priv *pp = ap->private_data; + pp->state = qs_state_mmio; writeb(QS_CTR0_REG, chan + QS_CCT_CTR0); readb(chan + QS_CCT_CTR0); /* flush */ } static inline void qs_reset_channel_logic(struct ata_port *ap) { - u8 __iomem *chan = ap->host->mmio_base + (ap->port_no * 0x4000); + u8 __iomem *chan = qs_mmio_base(ap->host) + (ap->port_no * 0x4000); writeb(QS_CTR1_RCHN, chan + QS_CCT_CTR1); readb(chan + QS_CCT_CTR0); /* flush */ qs_enter_reg_mode(ap); } -static void qs_phy_reset(struct ata_port *ap) +static void qs_freeze(struct ata_port *ap) { - struct qs_port_priv *pp = ap->private_data; + u8 __iomem *mmio_base = qs_mmio_base(ap->host); - pp->state = qs_state_idle; - qs_reset_channel_logic(ap); - sata_phy_reset(ap); + writeb(0, mmio_base + QS_HCT_CTRL); /* disable host interrupts */ + qs_enter_reg_mode(ap); } -static void qs_eng_timeout(struct ata_port *ap) +static void qs_thaw(struct ata_port *ap) { - struct qs_port_priv *pp = ap->private_data; + u8 __iomem *mmio_base = qs_mmio_base(ap->host); + + qs_enter_reg_mode(ap); + writeb(1, mmio_base + QS_HCT_CTRL); /* enable host interrupts */ +} + +static int qs_prereset(struct ata_link *link, unsigned long deadline) +{ + struct ata_port *ap = link->ap; - if (pp->state != qs_state_idle) /* healthy paranoia */ - pp->state = qs_state_mmio; qs_reset_channel_logic(ap); - ata_eng_timeout(ap); + return ata_sff_prereset(link, deadline); } -static u32 qs_scr_read (struct ata_port *ap, unsigned int sc_reg) +static int qs_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val) { if (sc_reg > SCR_CONTROL) - return ~0U; - return readl((void __iomem *)(ap->ioaddr.scr_addr + (sc_reg * 8))); + return -EINVAL; + *val = readl(link->ap->ioaddr.scr_addr + (sc_reg * 8)); + return 0; +} + +static void qs_error_handler(struct ata_port *ap) +{ + qs_enter_reg_mode(ap); + ata_std_error_handler(ap); } -static void qs_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) +static int qs_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val) { if (sc_reg > SCR_CONTROL) - return; - writel(val, (void __iomem *)(ap->ioaddr.scr_addr + (sc_reg * 8))); + return -EINVAL; + writel(val, link->ap->ioaddr.scr_addr + (sc_reg * 8)); + return 0; } static unsigned int qs_fill_sg(struct ata_queued_cmd *qc) @@ -273,14 +270,10 @@ static unsigned int qs_fill_sg(struct ata_queued_cmd *qc) struct scatterlist *sg; struct ata_port *ap = qc->ap; struct qs_port_priv *pp = ap->private_data; - unsigned int nelem; u8 *prd = pp->pkt + QS_CPB_BYTES; + unsigned int si; - WARN_ON(qc->__sg == NULL); - WARN_ON(qc->n_elem == 0 && qc->pad_len == 0); - - nelem = 0; - ata_for_each_sg(sg, qc) { + for_each_sg(qc->sg, sg, qc->n_elem, si) { u64 addr; u32 len; @@ -292,12 +285,11 @@ static unsigned int qs_fill_sg(struct ata_queued_cmd *qc) *(__le32 *)prd = cpu_to_le32(len); prd += sizeof(u64); - VPRINTK("PRD[%u] = (0x%llX, 0x%X)\n", nelem, + VPRINTK("PRD[%u] = (0x%llX, 0x%X)\n", si, (unsigned long long)addr, len); - nelem++; } - return nelem; + return si; } static void qs_qc_prep(struct ata_queued_cmd *qc) @@ -312,7 +304,7 @@ static void qs_qc_prep(struct ata_queued_cmd *qc) qs_enter_reg_mode(qc->ap); if (qc->tf.protocol != ATA_PROT_DMA) { - ata_qc_prep(qc); + ata_sff_qc_prep(qc); return; } @@ -326,7 +318,7 @@ static void qs_qc_prep(struct ata_queued_cmd *qc) /* host control block (HCB) */ buf[ 0] = QS_HCB_HDR; buf[ 1] = hflags; - *(__le32 *)(&buf[ 4]) = cpu_to_le32(qc->nsect * ATA_SECT_SIZE); + *(__le32 *)(&buf[ 4]) = cpu_to_le32(qc->nbytes); *(__le32 *)(&buf[ 8]) = cpu_to_le32(nelem); addr = ((u64)pp->pkt_dma) + QS_CPB_BYTES; *(__le64 *)(&buf[16]) = cpu_to_le64(addr); @@ -336,13 +328,13 @@ static void qs_qc_prep(struct ata_queued_cmd *qc) buf[28] = dflags; /* frame information structure (FIS) */ - ata_tf_to_fis(&qc->tf, &buf[32], 0); + ata_tf_to_fis(&qc->tf, 0, 1, &buf[32]); } static inline void qs_packet_start(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; - u8 __iomem *chan = ap->host->mmio_base + (ap->port_no * 0x4000); + u8 __iomem *chan = qs_mmio_base(ap->host) + (ap->port_no * 0x4000); VPRINTK("ENTER, ap %p\n", ap); @@ -358,12 +350,11 @@ static unsigned int qs_qc_issue(struct ata_queued_cmd *qc) switch (qc->tf.protocol) { case ATA_PROT_DMA: - pp->state = qs_state_pkt; qs_packet_start(qc); return 0; - case ATA_PROT_ATAPI_DMA: + case ATAPI_PROT_DMA: BUG(); break; @@ -372,14 +363,34 @@ static unsigned int qs_qc_issue(struct ata_queued_cmd *qc) } pp->state = qs_state_mmio; - return ata_qc_issue_prot(qc); + return ata_sff_qc_issue(qc); +} + +static void qs_do_or_die(struct ata_queued_cmd *qc, u8 status) +{ + qc->err_mask |= ac_err_mask(status); + + if (!qc->err_mask) { + ata_qc_complete(qc); + } else { + struct ata_port *ap = qc->ap; + struct ata_eh_info *ehi = &ap->link.eh_info; + + ata_ehi_clear_desc(ehi); + ata_ehi_push_desc(ehi, "status 0x%02X", status); + + if (qc->err_mask == AC_ERR_DEV) + ata_port_abort(ap); + else + ata_port_freeze(ap); + } } static inline unsigned int qs_intr_pkt(struct ata_host *host) { unsigned int handled = 0; u8 sFFE; - u8 __iomem *mmio_base = host->mmio_base; + u8 __iomem *mmio_base = qs_mmio_base(host); do { u32 sff0 = readl(mmio_base + QS_HST_SFF); @@ -401,15 +412,13 @@ static inline unsigned int qs_intr_pkt(struct ata_host *host) struct qs_port_priv *pp = ap->private_data; if (!pp || pp->state != qs_state_pkt) continue; - qc = ata_qc_from_tag(ap, ap->active_tag); + qc = ata_qc_from_tag(ap, ap->link.active_tag); if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) { switch (sHST) { case 0: /* successful CPB */ case 3: /* device error */ - pp->state = qs_state_idle; qs_enter_reg_mode(qc->ap); - qc->err_mask |= ac_err_mask(sDST); - ata_qc_complete(qc); + qs_do_or_die(qc, sDST); break; default: break; @@ -431,47 +440,50 @@ static inline unsigned int qs_intr_mmio(struct ata_host *host) if (ap && !(ap->flags & ATA_FLAG_DISABLED)) { struct ata_queued_cmd *qc; - struct qs_port_priv *pp = ap->private_data; - if (!pp || pp->state != qs_state_mmio) - continue; - qc = ata_qc_from_tag(ap, ap->active_tag); - if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) { - - /* check main status, clearing INTRQ */ - u8 status = ata_check_status(ap); - if ((status & ATA_BUSY)) - continue; - DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n", - ap->id, qc->tf.protocol, status); - - /* complete taskfile transaction */ - pp->state = qs_state_idle; - qc->err_mask |= ac_err_mask(status); - ata_qc_complete(qc); + struct qs_port_priv *pp; + qc = ata_qc_from_tag(ap, ap->link.active_tag); + if (!qc || !(qc->flags & ATA_QCFLAG_ACTIVE)) { + /* + * The qstor hardware generates spurious + * interrupts from time to time when switching + * in and out of packet mode. + * There's no obvious way to know if we're + * here now due to that, so just ack the irq + * and pretend we knew it was ours.. (ugh). + * This does not affect packet mode. + */ + ata_sff_check_status(ap); handled = 1; + continue; } + pp = ap->private_data; + if (!pp || pp->state != qs_state_mmio) + continue; + if (!(qc->tf.flags & ATA_TFLAG_POLLING)) + handled |= ata_sff_host_intr(ap, qc); } } return handled; } -static irqreturn_t qs_intr(int irq, void *dev_instance, struct pt_regs *regs) +static irqreturn_t qs_intr(int irq, void *dev_instance) { struct ata_host *host = dev_instance; unsigned int handled = 0; + unsigned long flags; VPRINTK("ENTER\n"); - spin_lock(&host->lock); + spin_lock_irqsave(&host->lock, flags); handled = qs_intr_pkt(host) | qs_intr_mmio(host); - spin_unlock(&host->lock); + spin_unlock_irqrestore(&host->lock, flags); VPRINTK("EXIT\n"); return IRQ_RETVAL(handled); } -static void qs_ata_setup_port(struct ata_ioports *port, unsigned long base) +static void qs_ata_setup_port(struct ata_ioports *port, void __iomem *base) { port->cmd_addr = port->data_addr = base + 0x400; @@ -493,7 +505,7 @@ static int qs_port_start(struct ata_port *ap) { struct device *dev = ap->host->dev; struct qs_port_priv *pp; - void __iomem *mmio_base = ap->host->mmio_base; + void __iomem *mmio_base = qs_mmio_base(ap->host); void __iomem *chan = mmio_base + (ap->port_no * 0x4000); u64 addr; int rc; @@ -501,69 +513,41 @@ static int qs_port_start(struct ata_port *ap) rc = ata_port_start(ap); if (rc) return rc; - qs_enter_reg_mode(ap); - pp = kzalloc(sizeof(*pp), GFP_KERNEL); - if (!pp) { - rc = -ENOMEM; - goto err_out; - } - pp->pkt = dma_alloc_coherent(dev, QS_PKT_BYTES, &pp->pkt_dma, - GFP_KERNEL); - if (!pp->pkt) { - rc = -ENOMEM; - goto err_out_kfree; - } + pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL); + if (!pp) + return -ENOMEM; + pp->pkt = dmam_alloc_coherent(dev, QS_PKT_BYTES, &pp->pkt_dma, + GFP_KERNEL); + if (!pp->pkt) + return -ENOMEM; memset(pp->pkt, 0, QS_PKT_BYTES); ap->private_data = pp; + qs_enter_reg_mode(ap); addr = (u64)pp->pkt_dma; writel((u32) addr, chan + QS_CCF_CPBA); writel((u32)(addr >> 32), chan + QS_CCF_CPBA + 4); return 0; - -err_out_kfree: - kfree(pp); -err_out: - ata_port_stop(ap); - return rc; -} - -static void qs_port_stop(struct ata_port *ap) -{ - struct device *dev = ap->host->dev; - struct qs_port_priv *pp = ap->private_data; - - if (pp != NULL) { - ap->private_data = NULL; - if (pp->pkt != NULL) - dma_free_coherent(dev, QS_PKT_BYTES, pp->pkt, - pp->pkt_dma); - kfree(pp); - } - ata_port_stop(ap); } static void qs_host_stop(struct ata_host *host) { - void __iomem *mmio_base = host->mmio_base; - struct pci_dev *pdev = to_pci_dev(host->dev); + void __iomem *mmio_base = qs_mmio_base(host); writeb(0, mmio_base + QS_HCT_CTRL); /* disable host interrupts */ writeb(QS_CNFG3_GSRST, mmio_base + QS_HCF_CNFG3); /* global reset */ - - pci_iounmap(pdev, mmio_base); } -static void qs_host_init(unsigned int chip_id, struct ata_probe_ent *pe) +static void qs_host_init(struct ata_host *host, unsigned int chip_id) { - void __iomem *mmio_base = pe->mmio_base; + void __iomem *mmio_base = host->iomap[QS_MMIO_BAR]; unsigned int port_no; writeb(0, mmio_base + QS_HCT_CTRL); /* disable host interrupts */ writeb(QS_CNFG3_GSRST, mmio_base + QS_HCF_CNFG3); /* global reset */ /* reset each channel in turn */ - for (port_no = 0; port_no < pe->n_ports; ++port_no) { + for (port_no = 0; port_no < host->n_ports; ++port_no) { u8 __iomem *chan = mmio_base + (port_no * 0x4000); writeb(QS_CTR1_RDEV|QS_CTR1_RCHN, chan + QS_CCT_CTR1); writeb(QS_CTR0_REG, chan + QS_CCT_CTR0); @@ -571,7 +555,7 @@ static void qs_host_init(unsigned int chip_id, struct ata_probe_ent *pe) } writeb(QS_SERD3_PHY_ENA, mmio_base + QS_HVS_SERD3); /* enable phy */ - for (port_no = 0; port_no < pe->n_ports; ++port_no) { + for (port_no = 0; port_no < host->n_ports; ++port_no) { u8 __iomem *chan = mmio_base + (port_no * 0x4000); /* set FIFO depths to same settings as Windows driver */ writew(32, chan + QS_CFC_HUFT); @@ -600,10 +584,10 @@ static int qs_set_dma_masks(struct pci_dev *pdev, void __iomem *mmio_base) int rc, have_64bit_bus = (bus_info & QS_HPHY_64BIT); if (have_64bit_bus && - !pci_set_dma_mask(pdev, DMA_64BIT_MASK)) { - rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK); + !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { + rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); if (rc) { - rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); + rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); if (rc) { dev_printk(KERN_ERR, &pdev->dev, "64-bit DMA enable failed\n"); @@ -611,13 +595,13 @@ static int qs_set_dma_masks(struct pci_dev *pdev, void __iomem *mmio_base) } } } else { - rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK); + rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); if (rc) { dev_printk(KERN_ERR, &pdev->dev, "32-bit DMA enable failed\n"); return rc; } - rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); + rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); if (rc) { dev_printk(KERN_ERR, &pdev->dev, "32-bit consistent DMA enable failed\n"); @@ -631,83 +615,53 @@ static int qs_ata_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { static int printed_version; - struct ata_probe_ent *probe_ent = NULL; - void __iomem *mmio_base; unsigned int board_idx = (unsigned int) ent->driver_data; + const struct ata_port_info *ppi[] = { &qs_port_info[board_idx], NULL }; + struct ata_host *host; int rc, port_no; if (!printed_version++) dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); - rc = pci_enable_device(pdev); - if (rc) - return rc; + /* alloc host */ + host = ata_host_alloc_pinfo(&pdev->dev, ppi, QS_PORTS); + if (!host) + return -ENOMEM; - rc = pci_request_regions(pdev, DRV_NAME); + /* acquire resources and fill host */ + rc = pcim_enable_device(pdev); if (rc) - goto err_out; + return rc; - if ((pci_resource_flags(pdev, 4) & IORESOURCE_MEM) == 0) { - rc = -ENODEV; - goto err_out_regions; - } + if ((pci_resource_flags(pdev, QS_MMIO_BAR) & IORESOURCE_MEM) == 0) + return -ENODEV; - mmio_base = pci_iomap(pdev, 4, 0); - if (mmio_base == NULL) { - rc = -ENOMEM; - goto err_out_regions; - } + rc = pcim_iomap_regions(pdev, 1 << QS_MMIO_BAR, DRV_NAME); + if (rc) + return rc; + host->iomap = pcim_iomap_table(pdev); - rc = qs_set_dma_masks(pdev, mmio_base); + rc = qs_set_dma_masks(pdev, host->iomap[QS_MMIO_BAR]); if (rc) - goto err_out_iounmap; + return rc; - probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL); - if (probe_ent == NULL) { - rc = -ENOMEM; - goto err_out_iounmap; - } + for (port_no = 0; port_no < host->n_ports; ++port_no) { + struct ata_port *ap = host->ports[port_no]; + unsigned int offset = port_no * 0x4000; + void __iomem *chan = host->iomap[QS_MMIO_BAR] + offset; - memset(probe_ent, 0, sizeof(*probe_ent)); - probe_ent->dev = pci_dev_to_dev(pdev); - INIT_LIST_HEAD(&probe_ent->node); - - probe_ent->sht = qs_port_info[board_idx].sht; - probe_ent->port_flags = qs_port_info[board_idx].flags; - probe_ent->pio_mask = qs_port_info[board_idx].pio_mask; - probe_ent->mwdma_mask = qs_port_info[board_idx].mwdma_mask; - probe_ent->udma_mask = qs_port_info[board_idx].udma_mask; - probe_ent->port_ops = qs_port_info[board_idx].port_ops; - - probe_ent->irq = pdev->irq; - probe_ent->irq_flags = IRQF_SHARED; - probe_ent->mmio_base = mmio_base; - probe_ent->n_ports = QS_PORTS; - - for (port_no = 0; port_no < probe_ent->n_ports; ++port_no) { - unsigned long chan = (unsigned long)mmio_base + - (port_no * 0x4000); - qs_ata_setup_port(&probe_ent->port[port_no], chan); - } + qs_ata_setup_port(&ap->ioaddr, chan); - pci_set_master(pdev); + ata_port_pbar_desc(ap, QS_MMIO_BAR, -1, "mmio"); + ata_port_pbar_desc(ap, QS_MMIO_BAR, offset, "port"); + } /* initialize adapter */ - qs_host_init(board_idx, probe_ent); + qs_host_init(host, board_idx); - rc = ata_device_add(probe_ent); - kfree(probe_ent); - if (rc != QS_PORTS) - goto err_out_iounmap; - return 0; - -err_out_iounmap: - pci_iounmap(pdev, mmio_base); -err_out_regions: - pci_release_regions(pdev); -err_out: - pci_disable_device(pdev); - return rc; + pci_set_master(pdev); + return ata_host_activate(host, pdev->irq, qs_intr, IRQF_SHARED, + &qs_ata_sht); } static int __init qs_ata_init(void)