30 #include <linux/kernel.h>
31 #include <linux/module.h>
33 #include <linux/pci.h>
38 #include <linux/device.h>
42 #define DRV_NAME "sata_qstor"
43 #define DRV_VERSION "0.09"
118 static int qs_port_start(
struct ata_port *ap);
123 static void qs_freeze(
struct ata_port *ap);
124 static void qs_thaw(
struct ata_port *ap);
125 static int qs_prereset(
struct ata_link *
link,
unsigned long deadline);
126 static void qs_error_handler(
struct ata_port *ap);
137 .check_atapi_dma = qs_check_atapi_dma,
138 .qc_prep = qs_qc_prep,
139 .qc_issue = qs_qc_issue,
143 .prereset = qs_prereset,
145 .error_handler = qs_error_handler,
148 .scr_read = qs_scr_read,
149 .scr_write = qs_scr_write,
151 .port_start = qs_port_start,
152 .host_stop = qs_host_stop,
161 .port_ops = &qs_ata_ops,
171 static struct pci_driver qs_ata_pci_driver = {
173 .id_table = qs_ata_pci_tbl,
174 .probe = qs_ata_init_one,
175 .remove = ata_pci_remove_one,
188 static inline void qs_enter_reg_mode(
struct ata_port *ap)
198 static inline void qs_reset_channel_logic(
struct ata_port *ap)
204 qs_enter_reg_mode(ap);
207 static void qs_freeze(
struct ata_port *ap)
212 qs_enter_reg_mode(ap);
215 static void qs_thaw(
struct ata_port *ap)
219 qs_enter_reg_mode(ap);
223 static int qs_prereset(
struct ata_link *
link,
unsigned long deadline)
227 qs_reset_channel_logic(ap);
235 *val =
readl(link->
ap->ioaddr.scr_addr + (sc_reg * 8));
239 static void qs_error_handler(
struct ata_port *ap)
241 qs_enter_reg_mode(ap);
245 static int qs_scr_write(
struct ata_link *link,
unsigned int sc_reg,
u32 val)
249 writel(val, link->
ap->ioaddr.scr_addr + (sc_reg * 8));
273 VPRINTK(
"PRD[%u] = (0x%llX, 0x%X)\n", si,
274 (
unsigned long long)addr, len);
290 qs_enter_reg_mode(qc->
ap);
294 nelem = qs_fill_sg(qc);
334 switch (qc->
tf.protocol) {
354 qc->
err_mask |= ac_err_mask(status);
372 static inline unsigned int qs_intr_pkt(
struct ata_host *
host)
374 unsigned int handled = 0;
381 u8 sEVLD = (sff1 >> 30) & 0x01;
385 u8 sDST = sff0 >> 16;
386 u8 sHST = sff1 & 0x3f;
387 unsigned int port_no = (sff1 >> 8) & 0x03;
392 DPRINTK(
"SFF=%08x%08x: sCHAN=%u sHST=%d sDST=%02x\n",
393 sff1, sff0, port_no, sHST, sDST);
397 qc = ata_qc_from_tag(ap, ap->
link.active_tag);
402 qs_enter_reg_mode(qc->
ap);
403 qs_do_or_die(qc, sDST);
414 static inline unsigned int qs_intr_mmio(
struct ata_host *host)
416 unsigned int handled = 0,
port_no;
423 qc = ata_qc_from_tag(ap, ap->
link.active_tag);
447 static irqreturn_t qs_intr(
int irq,
void *dev_instance)
449 struct ata_host *host = dev_instance;
450 unsigned int handled = 0;
456 handled = qs_intr_pkt(host) | qs_intr_mmio(host);
457 spin_unlock_irqrestore(&host->
lock, flags);
464 static void qs_ata_setup_port(
struct ata_ioports *
port,
void __iomem *base)
467 port->data_addr = base + 0x400;
469 port->feature_addr = base + 0x408;
470 port->nsect_addr = base + 0x410;
471 port->lbal_addr = base + 0x418;
472 port->lbam_addr = base + 0x420;
473 port->lbah_addr = base + 0x428;
474 port->device_addr = base + 0x430;
476 port->command_addr = base + 0x438;
477 port->altstatus_addr =
478 port->ctl_addr = base + 0x440;
479 port->scr_addr = base + 0xc00;
482 static int qs_port_start(
struct ata_port *ap)
500 qs_enter_reg_mode(ap);
507 static void qs_host_stop(
struct ata_host *host)
509 void __iomem *mmio_base = qs_mmio_base(host);
525 u8 __iomem *chan = mmio_base + (port_no * 0x4000);
533 u8 __iomem *chan = mmio_base + (port_no * 0x4000);
555 static int qs_set_dma_masks(
struct pci_dev *pdev,
void __iomem *mmio_base)
560 if (have_64bit_bus &&
562 rc = pci_set_consistent_dma_mask(pdev,
DMA_BIT_MASK(64));
564 rc = pci_set_consistent_dma_mask(pdev,
DMA_BIT_MASK(32));
567 "64-bit DMA enable failed\n");
574 dev_err(&pdev->
dev,
"32-bit DMA enable failed\n");
577 rc = pci_set_consistent_dma_mask(pdev,
DMA_BIT_MASK(32));
580 "32-bit consistent DMA enable failed\n");
587 static int qs_ata_init_one(
struct pci_dev *pdev,
621 unsigned int offset = port_no * 0x4000;
624 qs_ata_setup_port(&ap->ioaddr, chan);
627 ata_port_pbar_desc(ap,
QS_MMIO_BAR, offset,
"port");
631 qs_host_init(host, board_idx);