예제 #1
0
int
ata_attach(device_t dev)
{
    struct ata_channel *ch = device_get_softc(dev);
    int error, rid;

    /* check that we have a virgin channel to attach */
    if (ch->r_irq)
	return EEXIST;

    /* initialize the softc basics */
    ch->dev = dev;
    ch->state = ATA_IDLE;
    lockinit(&ch->state_mtx, "ataattach_state", 0, 0);
    lockinit(&ch->queue_mtx, "ataattach_queue", 0, 0);
    ata_queue_init(ch);

    /* reset the controller HW, the channel and device(s) */
    while (ATA_LOCKING(dev, ATA_LF_LOCK) != ch->unit)
	tsleep(&error, 0, "ataatch", 1);
    ATA_RESET(dev);
    ATA_LOCKING(dev, ATA_LF_UNLOCK);

    /* setup interrupt delivery */
    rid = ATA_IRQ_RID;
    ch->r_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
				       RF_SHAREABLE | RF_ACTIVE);
    if (!ch->r_irq) {
	device_printf(dev, "unable to allocate interrupt\n");
	return ENXIO;
    }
    if ((error = bus_setup_intr(dev, ch->r_irq, ATA_INTR_FLAGS,
				(driver_intr_t *)ata_interrupt, ch, &ch->ih,
				NULL))) {
	device_printf(dev, "unable to setup interrupt\n");
	return error;
    }

    /* probe and attach devices on this channel unless we are in early boot */
    ata_identify(dev);
    return 0;
}
예제 #2
0
static int
ata_usbchannel_attach(device_t dev)
{
    struct ata_channel *ch = device_get_softc(dev);

    /* initialize the softc basics */
    ch->dev = dev;
    ch->state = ATA_IDLE;
    ch->hw.begin_transaction = ata_usbchannel_begin_transaction;
    ch->hw.end_transaction = ata_usbchannel_end_transaction;
    ch->hw.status = NULL;
    ch->hw.command = NULL;
    spin_init(&ch->state_mtx);
    spin_init(&ch->queue_mtx);
    ata_queue_init(ch);

    /* XXX SOS reset the controller HW, the channel and device(s) */
    /* ATA_RESET(dev); */

    /* probe and attach device on this channel */
    ch->devices = ATA_ATAPI_MASTER;
    ata_identify(dev);
    return 0;
}