···22 * sata_mv.c - Marvell SATA support33 *44 * Copyright 2005: EMC Corporation, all rights reserved.55+ * Copyright 2005 Red Hat, Inc. All rights reserved.56 *67 * Please ALWAYS copy linux-ide@vger.kernel.org on emails.78 *···3736#include <asm/io.h>38373938#define DRV_NAME "sata_mv"4040-#define DRV_VERSION "0.25"3939+#define DRV_VERSION "0.5"41404241enum {4342 /* BAR's are enumerated in terms of pci_resource_start() terms */
+160-37
drivers/scsi/sata_sil24.c
···55 *66 * Based on preview driver from Silicon Image.77 *88- * NOTE: No NCQ/ATAPI support yet. The preview driver didn't support99- * NCQ nor ATAPI, and, unfortunately, I couldn't find out how to make1010- * those work. Enabling those shouldn't be difficult. Basic1111- * structure is all there (in libata-dev tree). If you have any1212- * information about this hardware, please contact me or linux-ide.1313- * Info is needed on...1414- *1515- * - How to issue tagged commands and turn on sactive on issue accordingly.1616- * - Where to put an ATAPI command and how to tell the device to send it.1717- * - How to enable/use 64bit.1818- *198 * This program is free software; you can redistribute it and/or modify it209 * under the terms of the GNU General Public License as published by the2110 * Free Software Foundation; either version 2, or (at your option) any···3142#include <asm/io.h>32433344#define DRV_NAME "sata_sil24"3434-#define DRV_VERSION "0.22" /* Silicon Image's preview driver was 0.10 */4545+#define DRV_VERSION "0.23"35463647/*3748 * Port request block (PRB) 32 bytes···210221 IRQ_STAT_4PORTS = 0xf,211222};212223213213-struct sil24_cmd_block {224224+struct sil24_ata_block {214225 struct sil24_prb prb;215226 struct sil24_sge sge[LIBATA_MAX_PRD];227227+};228228+229229+struct sil24_atapi_block {230230+ struct sil24_prb prb;231231+ u8 cdb[16];232232+ struct sil24_sge sge[LIBATA_MAX_PRD - 1];233233+};234234+235235+union sil24_cmd_block {236236+ struct sil24_ata_block ata;237237+ struct sil24_atapi_block atapi;216238};217239218240/*···233233 * here from the previous interrupt.234234 */235235struct sil24_port_priv {236236- struct sil24_cmd_block *cmd_block; /* 32 cmd blocks */236236+ union sil24_cmd_block *cmd_block; /* 32 cmd blocks */237237 dma_addr_t cmd_block_dma; /* DMA base addr for them */238238 struct ata_taskfile tf; /* Cached taskfile registers */239239};···244244 void __iomem *port_base; /* port registers (4 * 8192 bytes @BAR2) */245245};246246247247+static void sil24_dev_config(struct ata_port *ap, struct ata_device *dev);247248static u8 sil24_check_status(struct ata_port *ap);248249static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg);249250static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val);···298297static const struct ata_port_operations sil24_ops = {299298 .port_disable = ata_port_disable,300299300300+ .dev_config = sil24_dev_config,301301+301302 .check_status = sil24_check_status,302303 .check_altstatus = sil24_check_status,303304 .dev_select = ata_noop_dev_select,···336333 {337334 .sht = &sil24_sht,338335 .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |339339- ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |336336+ ATA_FLAG_SRST | ATA_FLAG_MMIO |340337 ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(4),341338 .pio_mask = 0x1f, /* pio0-4 */342339 .mwdma_mask = 0x07, /* mwdma0-2 */···347344 {348345 .sht = &sil24_sht,349346 .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |350350- ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |347347+ ATA_FLAG_SRST | ATA_FLAG_MMIO |351348 ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(2),352349 .pio_mask = 0x1f, /* pio0-4 */353350 .mwdma_mask = 0x07, /* mwdma0-2 */···358355 {359356 .sht = &sil24_sht,360357 .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |361361- ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO |358358+ ATA_FLAG_SRST | ATA_FLAG_MMIO |362359 ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(1),363360 .pio_mask = 0x1f, /* pio0-4 */364361 .mwdma_mask = 0x07, /* mwdma0-2 */···366363 .port_ops = &sil24_ops,367364 },368365};366366+367367+static void sil24_dev_config(struct ata_port *ap, struct ata_device *dev)368368+{369369+ void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;370370+371371+ if (ap->cdb_len == 16)372372+ writel(PORT_CS_CDB16, port + PORT_CTRL_STAT);373373+ else374374+ writel(PORT_CS_CDB16, port + PORT_CTRL_CLR);375375+}369376370377static inline void sil24_update_tf(struct ata_port *ap)371378{···428415 *tf = pp->tf;429416}430417418418+static int sil24_issue_SRST(struct ata_port *ap)419419+{420420+ void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;421421+ struct sil24_port_priv *pp = ap->private_data;422422+ struct sil24_prb *prb = &pp->cmd_block[0].ata.prb;423423+ dma_addr_t paddr = pp->cmd_block_dma;424424+ u32 irq_enable, irq_stat;425425+ int cnt;426426+427427+ /* temporarily turn off IRQs during SRST */428428+ irq_enable = readl(port + PORT_IRQ_ENABLE_SET);429429+ writel(irq_enable, port + PORT_IRQ_ENABLE_CLR);430430+431431+ /*432432+ * XXX: Not sure whether the following sleep is needed or not.433433+ * The original driver had it. So....434434+ */435435+ msleep(10);436436+437437+ prb->ctrl = PRB_CTRL_SRST;438438+ prb->fis[1] = 0; /* no PM yet */439439+440440+ writel((u32)paddr, port + PORT_CMD_ACTIVATE);441441+442442+ for (cnt = 0; cnt < 100; cnt++) {443443+ irq_stat = readl(port + PORT_IRQ_STAT);444444+ writel(irq_stat, port + PORT_IRQ_STAT); /* clear irq */445445+446446+ irq_stat >>= PORT_IRQ_RAW_SHIFT;447447+ if (irq_stat & (PORT_IRQ_COMPLETE | PORT_IRQ_ERROR))448448+ break;449449+450450+ msleep(1);451451+ }452452+453453+ /* restore IRQs */454454+ writel(irq_enable, port + PORT_IRQ_ENABLE_SET);455455+456456+ if (!(irq_stat & PORT_IRQ_COMPLETE))457457+ return -1;458458+459459+ /* update TF */460460+ sil24_update_tf(ap);461461+ return 0;462462+}463463+431464static void sil24_phy_reset(struct ata_port *ap)432465{466466+ struct sil24_port_priv *pp = ap->private_data;467467+433468 __sata_phy_reset(ap);434434- /*435435- * No ATAPI yet. Just unconditionally indicate ATA device.436436- * If ATAPI device is attached, it will fail ATA_CMD_ID_ATA437437- * and libata core will ignore the device.438438- */439439- if (!(ap->flags & ATA_FLAG_PORT_DISABLED))440440- ap->device[0].class = ATA_DEV_ATA;469469+ if (ap->flags & ATA_FLAG_PORT_DISABLED)470470+ return;471471+472472+ if (sil24_issue_SRST(ap) < 0) {473473+ printk(KERN_ERR DRV_NAME474474+ " ata%u: SRST failed, disabling port\n", ap->id);475475+ ap->ops->port_disable(ap);476476+ return;477477+ }478478+479479+ ap->device->class = ata_dev_classify(&pp->tf);441480}442481443482static inline void sil24_fill_sg(struct ata_queued_cmd *qc,444444- struct sil24_cmd_block *cb)483483+ struct sil24_sge *sge)445484{446446- struct sil24_sge *sge = cb->sge;447485 struct scatterlist *sg;448486 unsigned int idx = 0;449487···515451{516452 struct ata_port *ap = qc->ap;517453 struct sil24_port_priv *pp = ap->private_data;518518- struct sil24_cmd_block *cb = pp->cmd_block + qc->tag;519519- struct sil24_prb *prb = &cb->prb;454454+ union sil24_cmd_block *cb = pp->cmd_block + qc->tag;455455+ struct sil24_prb *prb;456456+ struct sil24_sge *sge;520457521458 switch (qc->tf.protocol) {522459 case ATA_PROT_PIO:523460 case ATA_PROT_DMA:524461 case ATA_PROT_NODATA:462462+ prb = &cb->ata.prb;463463+ sge = cb->ata.sge;464464+ prb->ctrl = 0;525465 break;466466+467467+ case ATA_PROT_ATAPI:468468+ case ATA_PROT_ATAPI_DMA:469469+ case ATA_PROT_ATAPI_NODATA:470470+ prb = &cb->atapi.prb;471471+ sge = cb->atapi.sge;472472+ memset(cb->atapi.cdb, 0, 32);473473+ memcpy(cb->atapi.cdb, qc->cdb, ap->cdb_len);474474+475475+ if (qc->tf.protocol != ATA_PROT_ATAPI_NODATA) {476476+ if (qc->tf.flags & ATA_TFLAG_WRITE)477477+ prb->ctrl = PRB_CTRL_PACKET_WRITE;478478+ else479479+ prb->ctrl = PRB_CTRL_PACKET_READ;480480+ } else481481+ prb->ctrl = 0;482482+483483+ break;484484+526485 default:527527- /* ATAPI isn't supported yet */486486+ prb = NULL; /* shut up, gcc */487487+ sge = NULL;528488 BUG();529489 }530490531491 ata_tf_to_fis(&qc->tf, prb->fis, 0);532492533493 if (qc->flags & ATA_QCFLAG_DMAMAP)534534- sil24_fill_sg(qc, cb);494494+ sil24_fill_sg(qc, sge);535495}536496537497static int sil24_qc_issue(struct ata_queued_cmd *qc)···572484static void sil24_irq_clear(struct ata_port *ap)573485{574486 /* unused */487487+}488488+489489+static int __sil24_restart_controller(void __iomem *port)490490+{491491+ u32 tmp;492492+ int cnt;493493+494494+ writel(PORT_CS_INIT, port + PORT_CTRL_STAT);495495+496496+ /* Max ~10ms */497497+ for (cnt = 0; cnt < 10000; cnt++) {498498+ tmp = readl(port + PORT_CTRL_STAT);499499+ if (tmp & PORT_CS_RDY)500500+ return 0;501501+ udelay(1);502502+ }503503+504504+ return -1;505505+}506506+507507+static void sil24_restart_controller(struct ata_port *ap)508508+{509509+ if (__sil24_restart_controller((void __iomem *)ap->ioaddr.cmd_addr))510510+ printk(KERN_ERR DRV_NAME511511+ " ata%u: failed to restart controller\n", ap->id);575512}576513577514static int __sil24_reset_controller(void __iomem *port)···618505619506 if (tmp & PORT_CS_DEV_RST)620507 return -1;621621- return 0;508508+509509+ if (tmp & PORT_CS_RDY)510510+ return 0;511511+512512+ return __sil24_restart_controller(port);622513}623514624515static void sil24_reset_controller(struct ata_port *ap)···684567 if (serror)685568 writel(serror, port + PORT_SERROR);686569687687- printk(KERN_ERR DRV_NAME " ata%u: error interrupt on port%d\n"688688- " stat=0x%x irq=0x%x cmd_err=%d sstatus=0x%x serror=0x%x\n",689689- ap->id, ap->port_no, slot_stat, irq_stat, cmd_err, sstatus, serror);570570+ /*571571+ * Don't log ATAPI device errors. They're supposed to happen572572+ * and any serious errors will be logged using sense data by573573+ * the SCSI layer.574574+ */575575+ if (ap->device[0].class != ATA_DEV_ATAPI || cmd_err > PORT_CERR_SDB)576576+ printk("ata%u: error interrupt on port%d\n"577577+ " stat=0x%x irq=0x%x cmd_err=%d sstatus=0x%x serror=0x%x\n",578578+ ap->id, ap->port_no, slot_stat, irq_stat, cmd_err, sstatus, serror);690579691580 if (cmd_err == PORT_CERR_DEV || cmd_err == PORT_CERR_SDB) {692581 /*···700577 */701578 sil24_update_tf(ap);702579 err_mask = ac_err_mask(pp->tf.command);580580+ sil24_restart_controller(ap);703581 } else {704582 /*705583 * Other errors. libata currently doesn't have any···708584 * ATA_ERR.709585 */710586 err_mask = AC_ERR_OTHER;587587+ sil24_reset_controller(ap);711588 }712589713590 if (qc)714591 ata_qc_complete(qc, err_mask);715715-716716- sil24_reset_controller(ap);717592}718593719594static inline void sil24_host_intr(struct ata_port *ap)···788665{789666 struct device *dev = ap->host_set->dev;790667 struct sil24_port_priv *pp;791791- struct sil24_cmd_block *cb;668668+ union sil24_cmd_block *cb;792669 size_t cb_size = sizeof(*cb);793670 dma_addr_t cb_dma;794671 int rc = -ENOMEM;