コード例 #1
0
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);
}
コード例 #2
0
ファイル: ata_kauai.c プロジェクト: dcui/FreeBSD-9.3_kernel
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);
}
コード例 #3
0
ファイル: pata_rb500_cf.c プロジェクト: mobilipia/iods
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;
}
コード例 #4
0
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);
    }
}