static void ata_periodic_poll(void *data) { struct ata_channel *ch = (struct ata_channel *)data; callout_reset(&ch->poll_callout, hz, ata_periodic_poll, ch); ata_interrupt(ch); }
static int ata_kauai_dma_interrupt(struct ata_kauai_softc *sc) { /* Clear the DMA interrupt bits */ bus_write_4(sc->sc_memr, DMA_IRQ_REG, 0x80000000); return ata_interrupt(sc); }
static irqreturn_t rb500_pata_irq_handler(int irq, void *dev_instance) { struct ata_host *ah = dev_instance; struct rb500_cf_info *info = ah->private_data; if (gpio_get_value(info->gpio_line)) { set_irq_type(info->irq, IRQ_TYPE_LEVEL_LOW); if (!info->frozen) ata_interrupt(info->irq, dev_instance); } else { set_irq_type(info->irq, IRQ_TYPE_LEVEL_HIGH); } return IRQ_HANDLED; }
static void atausb_bbb_finish(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status err) { struct atausb_softc *sc = (struct atausb_softc *)priv; struct ata_request *request = sc->ata_request; usbd_xfer_handle next_xfer; /* device_printf(sc->dev, "BBB state %d: %s\n", sc->state, usbd_errstr(err)); */ if (sc->state == ATAUSB_S_DETACH) { device_printf(sc->dev, "WARNING - device has been removed\n"); return; } switch (sc->state) { case ATAUSB_S_BBB_COMMAND: /* command transport phase */ if (err) { if (atausbdebug) device_printf(sc->dev, "failed to send CBW\n"); request->result = EIO; atausb_bbb_reset(sc); return; } /* next is data transport phase, setup transfer */ sc->state = ATAUSB_S_BBB_DATA; if (request->flags & ATA_R_READ) { if (atausb_start(sc, sc->bulkin_pipe, request->data, request->bytecount, USBD_SHORT_XFER_OK, sc->transfer[ATAUSB_T_BBB_DATA])) { request->result = EIO; atausb_bbb_reset(sc); } return; } if (request->flags & ATA_R_WRITE) { if (atausb_start(sc, sc->bulkout_pipe, request->data, request->bytecount, 0, sc->transfer[ATAUSB_T_BBB_DATA])) { request->result = EIO; atausb_bbb_reset(sc); } return; } /* FALLTHROUGH */ case ATAUSB_S_BBB_DATA: /* data transport phase */ if (request->flags & (ATA_R_READ | ATA_R_WRITE)) { usbd_get_xfer_status(xfer, NULL, NULL, &request->donecount, NULL); if (err) { if (atausbdebug) device_printf(sc->dev, "data %s count %d failed: %s\n", (request->flags & ATA_R_READ?"read":"write"), request->bytecount, usbd_errstr(err)); if (err == USBD_STALLED) { atausb_clear_stall(sc, (request->flags & ATA_R_READ ? sc->bulkin : sc->bulkout), (request->flags & ATA_R_READ ? sc->bulkin_pipe : sc->bulkout_pipe), ATAUSB_S_BBB_DCLEAR, sc->transfer[ATAUSB_T_BBB_DCLEAR]); } else { request->result = EIO; atausb_bbb_reset(sc); } return; } } /* FALLTHROUGH */ case ATAUSB_S_BBB_DCLEAR: /* stall clear after data phase */ case ATAUSB_S_BBB_SCLEAR: /* stall clear after status phase */ if (err) { if (atausbdebug) device_printf(sc->dev, "bulk%s stall clear failed %s\n", (request->flags & ATA_R_READ ? "in" : "out"), usbd_errstr(err)); request->result = EIO; atausb_bbb_reset(sc); return; } if (sc->state == ATAUSB_S_BBB_COMMAND || sc->state == ATAUSB_S_BBB_DATA || sc->state == ATAUSB_S_BBB_DCLEAR) { /* first attempt on status transport phase setup transfer */ sc->state = ATAUSB_S_BBB_STATUS1; next_xfer = sc->transfer[ATAUSB_T_BBB_CSW1]; } else { /* second attempt of fetching status */ sc->state = ATAUSB_S_BBB_STATUS2; next_xfer = sc->transfer[ATAUSB_T_BBB_CSW2]; } if (atausb_start(sc, sc->bulkin_pipe, &sc->csw, sizeof(struct bbb_csw), USBD_SHORT_XFER_OK, next_xfer)) { request->result = EIO; atausb_bbb_reset(sc); } return; case ATAUSB_S_BBB_STATUS1: /* status transfer first attempt */ case ATAUSB_S_BBB_STATUS2: /* status transfer second attempt */ if (err) { if (atausbdebug) device_printf(sc->dev, "cannot get CSW, %s%s\n", usbd_errstr(err), sc->state == ATAUSB_S_BBB_STATUS1 ? ", retry":""); if (sc->state == ATAUSB_S_BBB_STATUS1) { atausb_clear_stall(sc, sc->bulkin, sc->bulkin_pipe, ATAUSB_S_BBB_SCLEAR, sc->transfer[ATAUSB_T_BBB_SCLEAR]); } else { request->result = EIO; atausb_bbb_reset(sc); } return; } int residue = UGETDW(sc->csw.residue); if (!residue && (request->bytecount - request->donecount)) residue = request->bytecount - request->donecount; /* check CSW and handle eventual error */ if (UGETDW(sc->csw.signature) != CSWSIGNATURE) { if (atausbdebug) device_printf(sc->dev, "bad CSW signature 0x%08x != 0x%08x\n", UGETDW(sc->csw.signature), CSWSIGNATURE); request->result = EIO; atausb_bbb_reset(sc); return; } else if (UGETDW(sc->csw.tag) != UGETDW(sc->cbw.tag)) { if (atausbdebug) device_printf(sc->dev, "bad CSW tag %d != %d\n", UGETDW(sc->csw.tag), UGETDW(sc->cbw.tag)); request->result = EIO; atausb_bbb_reset(sc); return; } else if (sc->csw.status > CSWSTATUS_PHASE) { if (atausbdebug) device_printf(sc->dev, "bad CSW status %d > %d\n", sc->csw.status, CSWSTATUS_PHASE); request->result = EIO; atausb_bbb_reset(sc); return; } else if (sc->csw.status == CSWSTATUS_PHASE) { if (atausbdebug) device_printf(sc->dev, "phase error residue = %d\n", residue); request->result = EIO; atausb_bbb_reset(sc); return; } else if (request->donecount > request->bytecount) { if (atausbdebug) device_printf(sc->dev, "buffer overrun %d > %d", request->donecount, request->bytecount); request->result = EIO; atausb_bbb_reset(sc); return; } else if (sc->csw.status == CSWSTATUS_FAILED) { if (atausbdebug) device_printf(sc->dev, "CSWSTATUS_FAILED\n"); request->error = ATA_E_ATAPI_SENSE_MASK ; sc->state = ATAUSB_S_IDLE; ata_interrupt(device_get_softc(request->parent)); return; } else { sc->state = ATAUSB_S_IDLE; ata_interrupt(device_get_softc(request->parent)); return; } /* NOT REACHED */ case ATAUSB_S_BBB_RESET1: if (err) if (atausbdebug) device_printf(sc->dev, "BBB reset failure: %s\n", usbd_errstr(err)); atausb_clear_stall(sc, sc->bulkin, sc->bulkin_pipe, ATAUSB_S_BBB_RESET2, sc->transfer[ATAUSB_T_BBB_RESET2]); return; case ATAUSB_S_BBB_RESET2: if (err) if (atausbdebug) device_printf(sc->dev, "BBB bulkin clear stall failure: %s\n", usbd_errstr(err)); atausb_clear_stall(sc, sc->bulkout, sc->bulkout_pipe, ATAUSB_S_BBB_RESET3, sc->transfer[ATAUSB_T_BBB_RESET3]); return; case ATAUSB_S_BBB_RESET3: if (err) if (atausbdebug) device_printf(sc->dev, "BBB bulk-out clear stall failure: %s\n", usbd_errstr(err)); sc->state = ATAUSB_S_IDLE; if (request) { if (err) request->result = ENXIO; else request->result = EIO; ata_interrupt(device_get_softc(request->parent)); } return; default: if (atausbdebug) device_printf(sc->dev, "unknown state %d", sc->state); } }