From 23700c6b87cb76f9cfc6952aa5c0bc307a128a86 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Wed, 22 Oct 2003 04:33:31 -0400 Subject: [PATCH] [libata] fill in a lot more Promise PDC20621 support --- drivers/scsi/sata_promise.c | 426 +++++++++++++++++++++++++++++------- 1 file changed, 346 insertions(+), 80 deletions(-) diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c index 91da614ceb931..c7fb28a564e0a 100644 --- a/drivers/scsi/sata_promise.c +++ b/drivers/scsi/sata_promise.c @@ -41,6 +41,7 @@ enum { PDC_PRD_TBL = 0x44, /* Direct command DMA table addr */ PDC_PKT_SUBMIT = 0x40, /* Command packet pointer addr */ + PDC_HDMA_PKT_SUBMIT = 0x100, /* Host DMA packet pointer addr */ PDC_INT_SEQMASK = 0x40, /* Mask of asserted SEQ INTs */ PDC_TBG_MODE = 0x41, /* TBG mode */ PDC_FLASH_CTL = 0x44, /* Flash control register */ @@ -50,6 +51,12 @@ enum { PDC_20621_SEQCTL = 0x400, PDC_20621_SEQMASK = 0x480, + /* chosen, not constant, values; we design our own DIMM mem map */ + PDC_20621_DIMM_WINDOW = 0x0C, /* page# for 32K DIMM window */ + PDC_20621_DIMM_BASE = 0x00200000, + PDC_20621_HOST_PRD = 64, + PDC_20621_ATA_PRD = 72, + PDC_CHIP0_OFS = 0xC0000, /* offset of chip #0 */ board_2037x = 0, /* FastTrak S150 TX2plus */ @@ -61,6 +68,8 @@ enum { struct pdc_port_priv { + u8 prd_buf[ATA_PRD_SZ * ATA_MAX_PRD]; + u8 pkt_buf[256]; u8 *pkt; dma_addr_t pkt_dma; }; @@ -74,14 +83,20 @@ static void pdc_sata_set_udmamode (struct ata_port *ap, struct ata_device *adev, unsigned int udma); static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static void pdc_dma_start(struct ata_queued_cmd *qc); +static void pdc20621_dma_start(struct ata_queued_cmd *qc); static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *regs); +static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance, struct pt_regs *regs); static void pdc_eng_timeout(struct ata_port *ap); static void pdc_20621_phy_reset (struct ata_port *ap); static int pdc_port_start(struct ata_port *ap); static void pdc_port_stop(struct ata_port *ap); static void pdc_fill_sg(struct ata_queued_cmd *qc); +static void pdc20621_fill_sg(struct ata_queued_cmd *qc); static void pdc_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf); static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf); +static void pdc20621_host_stop(struct ata_host_set *host_set); +static inline void pdc_dma_complete (struct ata_port *ap, + struct ata_queued_cmd *qc); static Scsi_Host_Template pdc_sata_sht = { @@ -131,12 +146,13 @@ static struct ata_port_operations pdc_20621_ops = { .exec_command = pdc_exec_command_mmio, .phy_reset = pdc_20621_phy_reset, .phy_config = pata_phy_config, /* not a typo */ - .bmdma_start = pdc_dma_start, - .fill_sg = pdc_fill_sg, + .bmdma_start = pdc20621_dma_start, + .fill_sg = pdc20621_fill_sg, .eng_timeout = pdc_eng_timeout, - .irq_handler = pdc_interrupt, + .irq_handler = pdc20621_interrupt, .port_start = pdc_port_start, .port_stop = pdc_port_stop, + .host_stop = pdc20621_host_stop, }; static struct ata_port_info pdc_port_info[] = { @@ -182,10 +198,8 @@ static struct pci_device_id pdc_sata_pci_tbl[] = { board_20319 }, { PCI_VENDOR_ID_PROMISE, 0x3319, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_20319 }, -#if 0 /* broken currently */ { PCI_VENDOR_ID_PROMISE, 0x6622, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_20621 }, -#endif { } /* terminate list */ }; @@ -198,6 +212,14 @@ static struct pci_driver pdc_sata_pci_driver = { }; +static void pdc20621_host_stop(struct ata_host_set *host_set) +{ + void *mmio = host_set->private_data; + + assert(mmio != NULL); + iounmap(mmio); +} + static int pdc_port_start(struct ata_port *ap) { struct pci_dev *pdev = ap->host_set->pdev; @@ -284,6 +306,7 @@ static void pdc_sata_set_udmamode (struct ata_port *ap, struct ata_device *adev, enum pdc_packet_bits { PDC_PKT_READ = (1 << 2), PDC_PKT_NODATA = (1 << 3), + PDC20621_PKT_READ = (1 << 4), PDC_PKT_SIZEMASK = (1 << 7) | (1 << 6) | (1 << 5), PDC_PKT_CLEAR_BSY = (1 << 4), @@ -293,8 +316,9 @@ enum pdc_packet_bits { PDC_REG_DEVCTL = (1 << 3) | (1 << 2) | (1 << 1), }; -static inline void pdc_pkt_header(struct ata_taskfile *tf, dma_addr_t sg_table, - unsigned int devno, u8 *buf) +static inline unsigned int pdc_pkt_header(struct ata_taskfile *tf, + dma_addr_t sg_table, + unsigned int devno, u8 *buf) { u8 dev_reg; u32 *buf32 = (u32 *) buf; @@ -335,9 +359,11 @@ static inline void pdc_pkt_header(struct ata_taskfile *tf, dma_addr_t sg_table, /* device control register */ buf[14] = (1 << 5) | PDC_REG_DEVCTL; buf[15] = tf->ctl; + + return 16; /* offset of next byte */ } -static inline void pdc_pkt_footer(struct ata_taskfile *tf, u8 *buf, +static inline unsigned int pdc_pkt_footer(struct ata_taskfile *tf, u8 *buf, unsigned int i) { if (tf->flags & ATA_TFLAG_DEVICE) { @@ -348,19 +374,14 @@ static inline void pdc_pkt_footer(struct ata_taskfile *tf, u8 *buf, /* and finally the command itself; also includes end-of-pkt marker */ buf[i++] = (1 << 5) | PDC_LAST_REG | ATA_REG_CMD; buf[i++] = tf->command; + + return i; } -static void pdc_prep_lba28(struct ata_taskfile *tf, dma_addr_t sg_table, - unsigned int devno, u8 *buf) +static inline unsigned int pdc_prep_lba28(struct ata_taskfile *tf, u8 *buf, unsigned int i) { - unsigned int i; - - pdc_pkt_header(tf, sg_table, devno, buf); - /* the "(1 << 5)" should be read "(count << 5)" */ - i = 16; - /* ATA command block registers */ buf[i++] = (1 << 5) | ATA_REG_FEATURE; buf[i++] = tf->feature; @@ -377,20 +398,13 @@ static void pdc_prep_lba28(struct ata_taskfile *tf, dma_addr_t sg_table, buf[i++] = (1 << 5) | ATA_REG_LBAH; buf[i++] = tf->lbah; - pdc_pkt_footer(tf, buf, i); + return i; } -static void pdc_prep_lba48(struct ata_taskfile *tf, dma_addr_t sg_table, - unsigned int devno, u8 *buf) +static inline unsigned int pdc_prep_lba48(struct ata_taskfile *tf, u8 *buf, unsigned int i) { - unsigned int i; - - pdc_pkt_header(tf, sg_table, devno, buf); - /* the "(2 << 5)" should be read "(count << 5)" */ - i = 16; - /* ATA command block registers */ buf[i++] = (2 << 5) | ATA_REG_FEATURE; buf[i++] = tf->hob_feature; @@ -412,41 +426,299 @@ static void pdc_prep_lba48(struct ata_taskfile *tf, dma_addr_t sg_table, buf[i++] = tf->hob_lbah; buf[i++] = tf->lbah; - pdc_pkt_footer(tf, buf, i); + return i; } -static void pdc_fill_sg(struct ata_queued_cmd *qc) +static inline unsigned int pdc20621_pkt_header(struct ata_taskfile *tf, + unsigned int portno, + unsigned int devno, + u8 *buf, + unsigned int total_len) { - struct pdc_port_priv *pp = qc->ap->private_data; + u8 dev_reg; + u32 *buf32 = (u32 *) buf; + unsigned int ofs, i = 0; + + /* + * Set up Host DMA packet + */ + if (tf->protocol == ATA_PROT_DMA_READ) + buf[i++] = PDC20621_PKT_READ; + else + buf[i++] = 0; + buf[i++] = 0; /* reserved */ + buf[i++] = portno + 1 + 4; /* seq. id */ + buf[i++] = 0xff; /* delay seq. id */ + buf32[i / 4] = cpu_to_le32(PDC_20621_DIMM_BASE + (4 * 1024) + + (2 * 1024 * portno)); + i += 4; + buf32[i / 4] = cpu_to_le32(PDC_20621_DIMM_BASE + (portno * 1024) + + PDC_20621_HOST_PRD); + i += 4; + buf32[i / 4] = 0; + i += 4; + + ofs = PDC_20621_HOST_PRD / 4; + buf32[ofs] = cpu_to_le32(PDC_20621_DIMM_BASE + (32 * 1024) + + (256 * 1024 * portno)); + buf32[ofs + 1] = cpu_to_le32(total_len | ATA_PRD_EOT); + + /* + * Set up ATA packet + */ + if (tf->protocol == ATA_PROT_DMA_READ) + buf[i++] = PDC_PKT_READ; + else if (tf->protocol == ATA_PROT_NODATA) + buf[i++] = PDC_PKT_NODATA; + else + buf[i++] = 0; + buf[i++] = 0; /* reserved */ + buf[i++] = portno + 1; /* seq. id */ + buf[i++] = 0xff; /* delay seq. id */ + buf32[i / 4] = cpu_to_le32(PDC_20621_DIMM_BASE + (portno * 1024) + + PDC_20621_ATA_PRD); + i += 4; + buf32[i / 4] = 0; /* no next-packet */ + i += 4; + + ofs = PDC_20621_ATA_PRD / 4; + buf32[ofs] = cpu_to_le32(PDC_20621_DIMM_BASE + (32 * 1024) + + (256 * 1024 * portno)); + buf32[ofs + 1] = cpu_to_le32(total_len | ATA_PRD_EOT); + + if (devno == 0) + dev_reg = ATA_DEVICE_OBS; + else + dev_reg = ATA_DEVICE_OBS | ATA_DEV1; + + /* select device */ + buf[i++] = (1 << 5) | PDC_PKT_CLEAR_BSY | ATA_REG_DEVICE; + buf[i++] = dev_reg; + + /* device control register */ + buf[i++] = (1 << 5) | PDC_REG_DEVCTL; + buf[i++] = tf->ctl; + + return i; /* offset of next byte */ +} + +static void pdc20621_fill_sg(struct ata_queued_cmd *qc) +{ + struct scatterlist *sg = qc->sg; + struct ata_port *ap = qc->ap; + struct pdc_port_priv *pp = ap->private_data; + void *dimm_mmio = ap->host_set->private_data; + unsigned int portno = ap->port_no; + unsigned int i, last, idx, total_len = 0; + u32 *buf = (u32 *) &pp->prd_buf; + + /* + * Build S/G table + */ + last = qc->n_elem; + idx = 0; + for (i = 0; i < last; i++) { + buf[idx++] = cpu_to_le32(sg[i].dma_address); + buf[idx++] = cpu_to_le32(sg[i].length); + total_len += sg[i].length; + } + idx--; + buf[idx] |= cpu_to_le32(ATA_PRD_EOT); + + /* + * Build ATA, host DMA packets + */ + i = pdc20621_pkt_header(&qc->tf, portno, qc->dev->devno, + &pp->pkt_buf[0], total_len); - ata_fill_sg(qc); if (qc->tf.flags & ATA_TFLAG_LBA48) - pdc_prep_lba48(&qc->tf, qc->ap->prd_dma, - qc->dev->devno, pp->pkt); + i = pdc_prep_lba48(&qc->tf, &pp->pkt_buf[0], i); else - pdc_prep_lba28(&qc->tf, qc->ap->prd_dma, - qc->dev->devno, pp->pkt); + i = pdc_prep_lba28(&qc->tf, &pp->pkt_buf[0], i); + + i = pdc_pkt_footer(&qc->tf, &pp->pkt_buf[0], i); + + /* copy two packets and three S/G tables to DIMM MMIO window */ + memcpy_toio(dimm_mmio + (portno * 1024), &pp->pkt_buf, i); + memcpy_toio(dimm_mmio + (4 * 1024) + (2 * 1024 * portno), + buf, idx * 4); +} + +static void pdc20621_dma_start(struct ata_queued_cmd *qc) +{ + struct ata_port *ap = qc->ap; + struct ata_host_set *host_set = ap->host_set; + unsigned int port_no = ap->port_no; + void *mmio = host_set->mmio_base; + unsigned int rw = (qc->flags & ATA_QCFLAG_WRITE); + u8 seq = (u8) (port_no + 1); + u32 pkt_addr; + unsigned int doing_hdma = 0; + + /* hard-code chip #0 */ + mmio += PDC_CHIP0_OFS; + + VPRINTK("ENTER, ap %p, mmio %p\n", ap, mmio); + + /* if writing, we (1) DMA to DIMM, then (2) do ATA command */ + if (rw) { + doing_hdma = 1; + seq += 4; + pkt_addr = PDC_20621_DIMM_BASE + (4 * port_no); + } + + /* if reading, we (1) do ATA command, then (2) DMA from DIMM */ + else { + pkt_addr = PDC_20621_DIMM_BASE + (4 * port_no) + 16; + } + + wmb(); /* flush PRD, pkt writes */ + writel(0x00000001, mmio + PDC_20621_SEQCTL + (seq * 4)); + if (doing_hdma) + writel(pkt_addr, mmio + PDC_HDMA_PKT_SUBMIT); + else + writel(pkt_addr, (void *) ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT); +} + +static inline unsigned int pdc20621_host_intr( struct ata_port *ap, + struct ata_queued_cmd *qc, + unsigned int doing_hdma, + void *mmio) +{ + unsigned int port_no = ap->port_no; + u8 status; + unsigned int handled = 0; + + switch (qc->tf.protocol) { + case ATA_PROT_DMA_READ: + /* step two - DMA from DIMM to host */ + if (doing_hdma) + pdc_dma_complete(ap, qc); + + /* step one - exec ATA command */ + else { + u32 pkt_addr = PDC_20621_DIMM_BASE + (4 * port_no); + u8 seq = (u8) (port_no + 1 + 4); + + /* submit hdma pkt */ + writel(0x00000001, mmio + PDC_20621_SEQCTL + (seq * 4)); + writel(pkt_addr, mmio + PDC_HDMA_PKT_SUBMIT); + } + handled = 1; + break; + + case ATA_PROT_DMA_WRITE: + /* step one - DMA from host to DIMM */ + if (doing_hdma) { + u32 pkt_addr = PDC_20621_DIMM_BASE + (4 * port_no) + 16; + u8 seq = (u8) (port_no + 1); + + /* submit ata pkt */ + writel(0x00000001, mmio + PDC_20621_SEQCTL + (seq * 4)); + writel(pkt_addr, (void *) + ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT); + /* step two - execute ATA command */ + } else + pdc_dma_complete(ap, qc); + handled = 1; + break; + + case ATA_PROT_NODATA: /* command completion, but no data xfer */ + status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000); + DPRINTK("BUS_NODATA (drv_stat 0x%X)\n", status); + ata_qc_complete(qc, status, 0); + handled = 1; + break; + + default: + ap->stats.idle_irq++; + break; + } + + return handled; } -static inline void __pdc_dma_complete (struct ata_port *ap, - struct ata_queued_cmd *qc) +static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance, struct pt_regs *regs) { - void *dmactl = (void *) ap->ioaddr.cmd_addr + PDC_CTLSTAT; - u32 val; + struct ata_host_set *host_set = dev_instance; + struct ata_port *ap; + u32 mask = 0; + unsigned int i, tmp, port_no; + unsigned int handled = 0; + void *mmio_base; + + VPRINTK("ENTER\n"); + + if (!host_set || !host_set->mmio_base) { + VPRINTK("QUICK EXIT\n"); + return IRQ_NONE; + } + + mmio_base = host_set->mmio_base; + + /* reading should also clear interrupts */ + mmio_base += PDC_CHIP0_OFS; + mask = readl(mmio_base + PDC_20621_SEQMASK); + + if (mask == 0xffffffff) { + VPRINTK("QUICK EXIT 2\n"); + return IRQ_NONE; + } + mask &= 0xf; /* only 16 tags possible */ + if (!mask) { + VPRINTK("QUICK EXIT 3\n"); + return IRQ_NONE; + } + + spin_lock_irq(&host_set->lock); + + for (i = 1; i < 9; i++) { + VPRINTK("port %u\n", port_no); + port_no = i - 1; + if (port_no > 3) + port_no -= 4; + if (port_no >= host_set->n_ports) + ap = NULL; + else + ap = host_set->ports[port_no]; + tmp = mask & (1 << i); + if (tmp && ap && (!(ap->flags & ATA_FLAG_PORT_DISABLED))) { + struct ata_queued_cmd *qc; + + qc = ata_qc_from_tag(ap, ap->active_tag); + if (qc && ((qc->flags & ATA_QCFLAG_POLL) == 0)) + handled += pdc20621_host_intr(ap, qc, (i > 4), + mmio_base); + } + } - /* clear DMA start/stop bit (bit 7) */ - val = readl(dmactl); - writel(val & ~(1 << 7), dmactl); + spin_unlock_irq(&host_set->lock); + + VPRINTK("EXIT\n"); - /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */ - ata_altstatus(ap); /* dummy read */ + return IRQ_RETVAL(handled); +} + +static void pdc_fill_sg(struct ata_queued_cmd *qc) +{ + struct pdc_port_priv *pp = qc->ap->private_data; + unsigned int i; + + ata_fill_sg(qc); + + i = pdc_pkt_header(&qc->tf, qc->ap->prd_dma, qc->dev->devno, pp->pkt); + + if (qc->tf.flags & ATA_TFLAG_LBA48) + i = pdc_prep_lba48(&qc->tf, pp->pkt, i); + else + i = pdc_prep_lba28(&qc->tf, pp->pkt, i); + + pdc_pkt_footer(&qc->tf, pp->pkt, i); } static inline void pdc_dma_complete (struct ata_port *ap, struct ata_queued_cmd *qc) { - __pdc_dma_complete(ap, qc); - /* get drive status; clear intr; complete txn */ ata_qc_complete(ata_qc_from_tag(ap, ap->active_tag), ata_wait_idle(ap), 0); @@ -470,7 +742,6 @@ static void pdc_eng_timeout(struct ata_port *ap) case ATA_PROT_DMA_READ: case ATA_PROT_DMA_WRITE: printk(KERN_ERR "ata%u: DMA timeout\n", ap->id); - __pdc_dma_complete(ap, qc); ata_qc_complete(ata_qc_from_tag(ap, ap->active_tag), ata_wait_idle(ap) | ATA_ERR, 0); break; @@ -532,7 +803,7 @@ static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *r struct ata_port *ap; u32 mask = 0; unsigned int i, tmp; - unsigned int handled = 0, have_20621 = 0; + unsigned int handled = 0; void *mmio_base; VPRINTK("ENTER\n"); @@ -544,21 +815,8 @@ static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *r mmio_base = host_set->mmio_base; - for (i = 0; i < host_set->n_ports; i++) { - ap = host_set->ports[i]; - if (ap && (ap->flags & PDC_FLAG_20621)) { - have_20621 = 1; - break; - } - } - /* reading should also clear interrupts */ - if (have_20621) { - mmio_base += PDC_CHIP0_OFS; - mask = readl(mmio_base + PDC_20621_SEQMASK); - } else { - mask = readl(mmio_base + PDC_INT_SEQMASK); - } + mask = readl(mmio_base + PDC_INT_SEQMASK); if (mask == 0xffffffff) { VPRINTK("QUICK EXIT 2\n"); @@ -596,20 +854,12 @@ static void pdc_dma_start(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; struct pdc_port_priv *pp = ap->private_data; - struct ata_host_set *host_set = ap->host_set; unsigned int port_no = ap->port_no; - void *mmio = host_set->mmio_base; u8 seq = (u8) (port_no + 1); - if (ap->flags & PDC_FLAG_20621) - mmio += PDC_CHIP0_OFS; + VPRINTK("ENTER, ap %p\n", ap); - VPRINTK("ENTER, ap %p, mmio %p\n", ap, mmio); - - if (ap->flags & PDC_FLAG_20621) - writel(0x00000001, mmio + PDC_20621_SEQCTL + (seq * 4)); - else - writel(0x00000001, mmio + (seq * 4)); + writel(0x00000001, ap->host_set->mmio_base + (seq * 4)); pp->pkt[2] = seq; wmb(); /* flush PRD, pkt writes */ @@ -648,6 +898,14 @@ static void pdc_sata_setup_port(struct ata_ioports *port, unsigned long base) static void pdc_20621_init(struct ata_probe_ent *pe) { + u32 tmp; + void *mmio = pe->mmio_base; + + mmio += PDC_CHIP0_OFS; + + tmp = readl(mmio + PDC_20621_DIMM_WINDOW) & 0xffff0000; + tmp |= 0x40; /* page 40h; arbitrarily selected */ + writel(tmp, mmio + PDC_20621_DIMM_WINDOW); } static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe) @@ -691,8 +949,9 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id * static int printed_version; struct ata_probe_ent *probe_ent = NULL; unsigned long base; - void *mmio_base; + void *mmio_base, *dimm_mmio = NULL; unsigned int board_idx = (unsigned int) ent->driver_data; + unsigned int have_20621 = (board_idx == board_20621); int rc; if (!printed_version++) @@ -732,6 +991,15 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id * } base = (unsigned long) mmio_base; + if (have_20621) { + dimm_mmio = ioremap(pci_resource_start(pdev, 4), + pci_resource_len(pdev, 4)); + if (!dimm_mmio) { + rc = -ENOMEM; + goto err_out_iounmap; + } + } + probe_ent->sht = pdc_port_info[board_idx].sht; probe_ent->host_flags = pdc_port_info[board_idx].host_flags; probe_ent->pio_mask = pdc_port_info[board_idx].pio_mask; @@ -742,8 +1010,10 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id * probe_ent->irq_flags = SA_SHIRQ; probe_ent->mmio_base = mmio_base; - if (board_idx == board_20621) + if (have_20621) { + probe_ent->private_data = dimm_mmio; base += PDC_CHIP0_OFS; + } pdc_sata_setup_port(&probe_ent->port[0], base + 0x200); probe_ent->port[0].scr_addr = base + 0x400; @@ -774,15 +1044,10 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id * pci_set_master(pdev); /* initialize adapter */ - switch (board_idx) { - case board_20621: + if (have_20621) pdc_20621_init(probe_ent); - break; - - default: + else pdc_host_init(board_idx, probe_ent); - break; - } /* FIXME: check ata_device_add return value */ ata_device_add(probe_ent); @@ -790,6 +1055,8 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id * return 0; +err_out_iounmap: + iounmap(mmio_base); err_out_free_ent: kfree(probe_ent); err_out_regions: @@ -800,7 +1067,6 @@ err_out: } - static int __init pdc_sata_init(void) { int rc; -- 2.53.0