static int ata_macio_begin_transaction(struct ata_request *request) { struct ata_macio_softc *sc = device_get_softc(request->parent); bus_write_4(sc->sc_mem, ATA_MACIO_TIMINGREG, sc->udmaconf[request->unit] | sc->wdmaconf[request->unit] | sc->pioconf[request->unit]); return ata_begin_transaction(request); }
static int ata_kauai_begin_transaction(struct ata_request *request) { struct ata_kauai_softc *sc = device_get_softc(request->parent); bus_write_4(sc->sc_memr, UDMA_CONFIG_REG, sc->udmaconf[request->unit]); bus_write_4(sc->sc_memr, PIO_CONFIG_REG, sc->wdmaconf[request->unit] | sc->pioconf[request->unit]); return ata_begin_transaction(request); }
static int sata_channel_begin_transaction(struct ata_request *request) { struct sata_softc *sc; struct ata_channel *ch; struct sata_crqb *crqb; uint32_t req_in; int error, slot; sc = device_get_softc(device_get_parent(request->parent)); ch = device_get_softc(request->parent); mtx_assert(&ch->state_mtx, MA_OWNED); /* Only DMA R/W goes through the EDMA machine. */ if (request->u.ata.command != ATA_READ_DMA && request->u.ata.command != ATA_WRITE_DMA && request->u.ata.command != ATA_READ_DMA48 && request->u.ata.command != ATA_WRITE_DMA48) { /* Disable EDMA before accessing legacy registers */ if (sata_edma_is_running(request->parent)) { error = sata_edma_ctrl(request->parent, 0); if (error) { request->result = error; return (ATA_OP_FINISHED); } } return (ata_begin_transaction(request)); } /* Prepare data for DMA */ if ((error = ch->dma.load(request, NULL, NULL))) { device_printf(request->parent, "setting up DMA failed!\n"); request->result = error; return ATA_OP_FINISHED; } /* Get next free queue slot */ req_in = SATA_INL(sc, SATA_EDMA_REQIPR(ch->unit)); slot = (req_in & sc->sc_edma_reqis_mask) >> SATA_EDMA_REQIS_OFS; crqb = (struct sata_crqb *)(ch->dma.work + (slot << SATA_EDMA_REQIS_OFS)); /* Fill in request */ bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); crqb->crqb_prdlo = htole32((uint64_t)request->dma->sg_bus & 0xFFFFFFFF); crqb->crqb_prdhi = htole32((uint64_t)request->dma->sg_bus >> 32); crqb->crqb_flags = htole32((request->flags & ATA_R_READ ? 0x01 : 0x00) | (request->tag << 1)); crqb->crqb_ata_command = request->u.ata.command; crqb->crqb_ata_feature = request->u.ata.feature; crqb->crqb_ata_lba_low = request->u.ata.lba; crqb->crqb_ata_lba_mid = request->u.ata.lba >> 8; crqb->crqb_ata_lba_high = request->u.ata.lba >> 16; crqb->crqb_ata_device = ((request->u.ata.lba >> 24) & 0x0F) | (1 << 6); crqb->crqb_ata_lba_low_p = request->u.ata.lba >> 24; crqb->crqb_ata_lba_mid_p = request->u.ata.lba >> 32; crqb->crqb_ata_lba_high_p = request->u.ata.lba >> 40; crqb->crqb_ata_feature_p = request->u.ata.feature >> 8; crqb->crqb_ata_count = request->u.ata.count; crqb->crqb_ata_count_p = request->u.ata.count >> 8; bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); /* Enable EDMA if disabled */ if (!sata_edma_is_running(request->parent)) { error = sata_edma_ctrl(request->parent, 1); if (error) { ch->dma.unload(request); request->result = error; return (ATA_OP_FINISHED); } } /* Tell EDMA about new request */ req_in = (req_in & ~sc->sc_edma_reqis_mask) | (((slot + 1) << SATA_EDMA_REQIS_OFS) & sc->sc_edma_reqis_mask); SATA_OUTL(sc, SATA_EDMA_REQIPR(ch->unit), req_in); return (ATA_OP_CONTINUES); }