static unsigned int sata_fsl_fill_sg(struct ata_queued_cmd *qc, void *cmd_desc, u32 *ttl, dma_addr_t cmd_desc_paddr) { struct scatterlist *sg; unsigned int num_prde = 0; u32 ttl_dwords = 0; /* * NOTE : direct & indirect prdt's are contigiously allocated */ struct prde *prd = (struct prde *)&((struct command_desc *) cmd_desc)->prdt; struct prde *prd_ptr_to_indirect_ext = NULL; unsigned indirect_ext_segment_sz = 0; dma_addr_t indirect_ext_segment_paddr; VPRINTK("SATA FSL : cd = 0x%p, prd = 0x%p\n", cmd_desc, prd); indirect_ext_segment_paddr = cmd_desc_paddr + SATA_FSL_CMD_DESC_OFFSET_TO_PRDT + SATA_FSL_MAX_PRD_DIRECT * 16; ata_for_each_sg(sg, qc) { dma_addr_t sg_addr = sg_dma_address(sg); u32 sg_len = sg_dma_len(sg); VPRINTK("SATA FSL : fill_sg, sg_addr = 0x%x, sg_len = %d\n", sg_addr, sg_len); /* warn if each s/g element is not dword aligned */ if (sg_addr & 0x03) ata_port_printk(qc->ap, KERN_ERR, "s/g addr unaligned : 0x%x\n", sg_addr); if (sg_len & 0x03) ata_port_printk(qc->ap, KERN_ERR, "s/g len unaligned : 0x%x\n", sg_len); if (num_prde == (SATA_FSL_MAX_PRD_DIRECT - 1) && !ata_sg_is_last(sg, qc)) { VPRINTK("setting indirect prde\n"); prd_ptr_to_indirect_ext = prd; prd->dba = cpu_to_le32(indirect_ext_segment_paddr); indirect_ext_segment_sz = 0; ++prd; ++num_prde; } ttl_dwords += sg_len; prd->dba = cpu_to_le32(sg_addr); prd->ddc_and_ext = cpu_to_le32(DATA_SNOOP_ENABLE | (sg_len & ~0x03)); VPRINTK("sg_fill, ttl=%d, dba=0x%x, ddc=0x%x\n", ttl_dwords, prd->dba, prd->ddc_and_ext); ++num_prde; ++prd; if (prd_ptr_to_indirect_ext) indirect_ext_segment_sz += sg_len; }
/** * vt6420_prereset - prereset for vt6420 * @link: target ATA link * @deadline: deadline jiffies for the operation * * SCR registers on vt6420 are pieces of shit and may hang the * whole machine completely if accessed with the wrong timing. * To avoid such catastrophe, vt6420 doesn't provide generic SCR * access operations, but uses SStatus and SControl only during * boot probing in controlled way. * * As the old (pre EH update) probing code is proven to work, we * strictly follow the access pattern. * * LOCKING: * Kernel thread context (may sleep) * * RETURNS: * 0 on success, -errno otherwise. */ static int vt6420_prereset(struct ata_link *link, unsigned long deadline) { struct ata_port *ap = link->ap; struct ata_eh_context *ehc = &ap->link.eh_context; unsigned long timeout = jiffies + (HZ * 5); u32 sstatus, scontrol; int online; /* don't do any SCR stuff if we're not loading */ if (!(ap->pflags & ATA_PFLAG_LOADING)) goto skip_scr; /* Resume phy. This is the old SATA resume sequence */ svia_scr_write(link, SCR_CONTROL, 0x300); svia_scr_read(link, SCR_CONTROL, &scontrol); /* flush */ /* wait for phy to become ready, if necessary */ do { ata_msleep(link->ap, 200); svia_scr_read(link, SCR_STATUS, &sstatus); if ((sstatus & 0xf) != 1) break; } while (time_before(jiffies, timeout)); /* open code sata_print_link_status() */ svia_scr_read(link, SCR_STATUS, &sstatus); svia_scr_read(link, SCR_CONTROL, &scontrol); online = (sstatus & 0xf) == 0x3; #ifdef CONFIG_DEBUG_PRINTK ata_port_printk(ap, KERN_INFO, "SATA link %s 1.5 Gbps (SStatus %X SControl %X)\n", online ? "up" : "down", sstatus, scontrol); #else ata_port_; #endif /* SStatus is read one more time */ svia_scr_read(link, SCR_STATUS, &sstatus); if (!online) { /* tell EH to bail */ ehc->i.action &= ~ATA_EH_RESET; return 0; } skip_scr: /* wait for !BSY */ ata_sff_wait_ready(link, deadline); return 0; }
static int vt6420_prereset(struct ata_link *link, unsigned long deadline) { struct ata_port *ap = link->ap; struct ata_eh_context *ehc = &ap->link.eh_context; unsigned long timeout = jiffies + (HZ * 5); u32 sstatus, scontrol; int online; if (!(ap->pflags & ATA_PFLAG_LOADING)) goto skip_scr; svia_scr_write(link, SCR_CONTROL, 0x300); svia_scr_read(link, SCR_CONTROL, &scontrol); do { msleep(200); svia_scr_read(link, SCR_STATUS, &sstatus); if ((sstatus & 0xf) != 1) break; } while (time_before(jiffies, timeout)); svia_scr_read(link, SCR_STATUS, &sstatus); svia_scr_read(link, SCR_CONTROL, &scontrol); online = (sstatus & 0xf) == 0x3; ata_port_printk(ap, KERN_INFO, "SATA link %s 1.5 Gbps (SStatus %X SControl %X)\n", online ? "up" : "down", sstatus, scontrol); svia_scr_read(link, SCR_STATUS, &sstatus); if (!online) { ehc->i.action &= ~ATA_EH_RESET; return 0; } skip_scr: ata_sff_wait_ready(link, deadline); return 0; }
/** * vt6420_prereset - prereset for vt6420 * @ap: target ATA port * * SCR registers on vt6420 are pieces of shit and may hang the * whole machine completely if accessed with the wrong timing. * To avoid such catastrophe, vt6420 doesn't provide generic SCR * access operations, but uses SStatus and SControl only during * boot probing in controlled way. * * As the old (pre EH update) probing code is proven to work, we * strictly follow the access pattern. * * LOCKING: * Kernel thread context (may sleep) * * RETURNS: * 0 on success, -errno otherwise. */ static int vt6420_prereset(struct ata_port *ap) { struct ata_eh_context *ehc = &ap->eh_context; unsigned long timeout = jiffies + (HZ * 5); u32 sstatus, scontrol; int online; /* don't do any SCR stuff if we're not loading */ if (!(ap->pflags & ATA_PFLAG_LOADING)) goto skip_scr; /* Resume phy. This is the old resume sequence from * __sata_phy_reset(). */ svia_scr_write(ap, SCR_CONTROL, 0x300); svia_scr_read(ap, SCR_CONTROL); /* flush */ /* wait for phy to become ready, if necessary */ do { msleep(200); if ((svia_scr_read(ap, SCR_STATUS) & 0xf) != 1) break; } while (time_before(jiffies, timeout)); /* open code sata_print_link_status() */ sstatus = svia_scr_read(ap, SCR_STATUS); scontrol = svia_scr_read(ap, SCR_CONTROL); online = (sstatus & 0xf) == 0x3; ata_port_printk(ap, KERN_INFO, "SATA link %s 1.5 Gbps (SStatus %X SControl %X)\n", online ? "up" : "down", sstatus, scontrol); /* SStatus is read one more time */ svia_scr_read(ap, SCR_STATUS); if (!online) { /* tell EH to bail */ ehc->i.action &= ~ATA_EH_RESET_MASK; return 0; } skip_scr: /* wait for !BSY */ ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT); return 0; }
static int scc_std_softreset (struct ata_port *ap, unsigned int *classes) { unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS; unsigned int devmask = 0, err_mask; u8 err; DPRINTK("ENTER\n"); if (ata_port_offline(ap)) { classes[0] = ATA_DEV_NONE; goto out; } /* determine if device 0/1 are present */ if (scc_devchk(ap, 0)) devmask |= (1 << 0); if (slave_possible && scc_devchk(ap, 1)) devmask |= (1 << 1); /* select device 0 again */ ap->ops->dev_select(ap, 0); /* issue bus reset */ DPRINTK("about to softreset, devmask=%x\n", devmask); err_mask = scc_bus_softreset(ap, devmask); if (err_mask) { ata_port_printk(ap, KERN_ERR, "SRST failed (err_mask=0x%x)\n", err_mask); return -EIO; } /* determine by signature whether we have ATA or ATAPI devices */ classes[0] = ata_dev_try_classify(ap, 0, &err); if (slave_possible && err != 0x81) classes[1] = ata_dev_try_classify(ap, 1, &err); out: DPRINTK("EXIT, classes[0]=%u [1]=%u\n", classes[0], classes[1]); return 0; }
static void inic_host_intr(struct ata_port *ap) { void __iomem *port_base = inic_port_base(ap); struct ata_eh_info *ehi = &ap->link.eh_info; u8 irq_stat; /* fetch and clear irq */ irq_stat = readb(port_base + PORT_IRQ_STAT); writeb(irq_stat, port_base + PORT_IRQ_STAT); if (likely(!(irq_stat & PIRQ_ERR))) { struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->link.active_tag); if (unlikely(!qc || (qc->tf.flags & ATA_TFLAG_POLLING))) { ata_chk_status(ap); /* clear ATA interrupt */ return; } if (likely(ata_host_intr(ap, qc))) return; ata_chk_status(ap); /* clear ATA interrupt */ ata_port_printk(ap, KERN_WARNING, "unhandled " "interrupt, irq_stat=%x\n", irq_stat); return; } /* error */ ata_ehi_push_desc(ehi, "irq_stat=0x%x", irq_stat); if (irq_stat & (PIRQ_OFFLINE | PIRQ_ONLINE)) { ata_ehi_hotplugged(ehi); ata_port_freeze(ap); } else ata_port_abort(ap); }