Esempio n. 1
0
static void
ata_boot_attach(void)
{
    struct ata_channel *ch;
    int ctlr;

    get_mplock();

    /* kick of probe and attach on all channels */
    for (ctlr = 0; ctlr < devclass_get_maxunit(ata_devclass); ctlr++) {
	if ((ch = devclass_get_softc(ata_devclass, ctlr))) {
	    ata_identify(ch->dev);
	}
    }

    rel_mplock();
}
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;
    bzero(&ch->state_mtx, sizeof(struct mtx));
    mtx_init(&ch->state_mtx, "ATA state lock", NULL, MTX_DEF);
    bzero(&ch->queue_mtx, sizeof(struct mtx));
    mtx_init(&ch->queue_mtx, "ATA queue lock", NULL, MTX_DEF);
    TAILQ_INIT(&ch->ata_queue);

    /* reset the controller HW, the channel and device(s) */
    while (ATA_LOCKING(dev, ATA_LF_LOCK) != ch->unit)
	pause("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, NULL,
				ata_interrupt, ch, &ch->ih))) {
	device_printf(dev, "unable to setup interrupt\n");
	return error;
    }

    /* probe and attach devices on this channel unless we are in early boot */
    if (!ata_delayed_attach)
	ata_identify(dev);
    return 0;
}
Esempio n. 3
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;
}
Esempio n. 4
0
void kmain(ol_mmap_register_t mmr)
{
	textinit();
	clearscreen();

	println("The openLoader kernel is executing. \n");

	print("Current stack pointer: ");
	ol_registers_t regs = getregs();
	printnum(regs->esp, 16, FALSE, FALSE);
	putc(0xa);

	char status = inb(0x60);
	if((status & 2) == 2)
	{
		println("The A20 gate is open.");
		putc(0xa);
	}
	
	pic_init();
	setIDT();
	outb(OL_KBC_COMMAND, OL_KB_INIT);	// enable the keyboard

// display mmap
	init_mmap(mmr);
	println("Multiboot memory map:\n");
	display_mmap(mmr);

#if 0
	uint8_t active = ide_init(bootdrive);
	ide_read(0x100, 1<<20, &bootdrive[active], 60);
	uint8_t eax = ata_identify();
	printnum(active, 16, FALSE, FALSE);
#endif

	putc(0xa);

	println("Waiting for service interrupts..");
	while(1) halt();
	println("End of program reached!");
	endprogram();
}
Esempio n. 5
0
/*
$$
$$ XXX ata_readsectors is for Primary Controller
$$
*/
void ata_readsectors(unsigned char drive, 
					 unsigned int lba,
					 unsigned char num_sectors, 
					 unsigned char *in_buffer
					) {
	unsigned short *sector_buffer_pointer;
	unsigned int cylinder, head, sector;
	unsigned char Laufwerk=(drive==0 ? 0xa0:0xb0);
	unsigned int i;
	unsigned char d;

	if ((sectors_per_track[drive]==0) || (numheads[drive]==0)) {
		ata_identify();
	}	

	ata_lba2chs(lba, &cylinder, &head, &sector, drive);

	sector_buffer_pointer=(unsigned short*) in_buffer;

	ata_waitbsy();
	
	IRQ14_called=0;

	outportb(REG_SEKTORENZAHL, num_sectors);		// Anzahl der zu lesenden Sektoren
	outportb(REG_SEKTORNUMMER, sector);				// Sektornummer
	outportb(REG_ZYLINDER_LSB, cylinder & 0xff);	// Zylinder LSB		LSB+MSB=10Bit
	outportb(REG_ZYLINDER_MSB, cylinder & 0x300);	// Zylinder MSB
	outportb(REG_LAUFWERK_KOPF, Laufwerk+head);		// Laufwerk/Kopf, enthält den Kopf und das Laufwerk
	outportb(REG_BEFEHL, CMD_SEKTORENLESEN);

	while (IRQ14_called != 1);

	for (i=0; i<num_sectors; i++) {
		ata_read_pio_sector(sector_buffer_pointer);
		sector_buffer_pointer+=256;
	}

	ata_waitbsy();
}
Esempio n. 6
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;
}
static void
ata_boot_attach(void)
{
    struct ata_channel *ch;
    int ctlr;

    mtx_lock(&Giant);       /* newbus suckage it needs Giant */

    /* kick of probe and attach on all channels */
    for (ctlr = 0; ctlr < devclass_get_maxunit(ata_devclass); ctlr++) {
	if ((ch = devclass_get_softc(ata_devclass, ctlr))) {
	    ata_identify(ch->dev);
	}
    }

    /* release the hook that got us here, we are only needed once during boot */
    if (ata_delayed_attach) {
	config_intrhook_disestablish(ata_delayed_attach);
	free(ata_delayed_attach, M_TEMP);
	ata_delayed_attach = NULL;
    }

    mtx_unlock(&Giant);     /* newbus suckage dealt with, release Giant */
}
Esempio n. 8
0
static int ata_power_up(void)
{
    ata_set_active();
    if (ata_powered) return 0;
    ide_power_enable(true);
    long spinup_start = current_tick;
    if (ceata)
    {
        PWRCON(0) &= ~(1 << 9);
        SDCI_RESET = 0xa5;
        sleep(HZ / 100);
        *((uint32_t volatile*)0x3cf00380) = 0;
        *((uint32_t volatile*)0x3cf0010c) = 0xff;
        SDCI_CTRL = SDCI_CTRL_SDCIEN | SDCI_CTRL_CLK_SEL_SDCLK
                  | SDCI_CTRL_BIT_8 | SDCI_CTRL_BIT_14;
        SDCI_CDIV = SDCI_CDIV_CLKDIV(260);
        *((uint32_t volatile*)0x3cf00200) = 0xb000f;
        SDCI_IRQ_MASK = SDCI_IRQ_MASK_MASK_DAT_DONE_INT | SDCI_IRQ_MASK_MASK_IOCARD_IRQ_INT;
        PASS_RC(mmc_init(), 2, 0);
        SDCI_CDIV = SDCI_CDIV_CLKDIV(4);
        sleep(HZ / 100);
        PASS_RC(ceata_init(8), 2, 1);
        PASS_RC(ata_identify(ata_identify_data), 2, 2);
        dma_mode = 0x44;
    }
    else
    {
        PWRCON(0) &= ~(1 << 5);
        ATA_CFG = BIT(0);
        sleep(HZ / 100);
        ATA_CFG = 0;
        sleep(HZ / 100);
        ATA_SWRST = BIT(0);
        sleep(HZ / 100);
        ATA_SWRST = 0;
        sleep(HZ / 10);
        ATA_CONTROL = BIT(0);
        sleep(HZ / 5);
        ATA_PIO_TIME = 0x191f7;
        ATA_PIO_LHR = 0;
        if (!ata_swap) ATA_CFG = BIT(6);
        while (!(ATA_PIO_READY & BIT(1))) yield();
        PASS_RC(ata_identify(ata_identify_data), 2, 0);
        uint32_t piotime = 0x11f3;
        uint32_t mdmatime = 0x1c175;
        uint32_t udmatime = 0x5071152;
        uint32_t param = 0;
        ata_dma_flags = 0;
        ata_lba48 = ata_identify_data[83] & BIT(10) ? true : false;
        if (ata_identify_data[53] & BIT(1))
        {
            if (ata_identify_data[64] & BIT(1)) piotime = 0x2072;
            else if (ata_identify_data[64] & BIT(0)) piotime = 0x7083;
        }
        if (ata_identify_data[63] & BIT(2))
        {
            mdmatime = 0x5072;
            param = 0x22;
        }
        else if (ata_identify_data[63] & BIT(1))
        {
            mdmatime = 0x7083;
            param = 0x21;
        }
        if (ata_identify_data[63] & BITRANGE(0, 2))
        {
            ata_dma_flags = BIT(3) | BIT(10);
            param |= 0x20;
        }
        if (ata_identify_data[53] & BIT(2))
        {
            if (ata_identify_data[88] & BIT(4))
            {
                udmatime = 0x2010a52;
                param = 0x44;
            }
            else if (ata_identify_data[88] & BIT(3))
            {
                udmatime = 0x2020a52;
                param = 0x43;
            }
            else if (ata_identify_data[88] & BIT(2))
            {
                udmatime = 0x3030a52;
                param = 0x42;
            }
            else if (ata_identify_data[88] & BIT(1))
            {
                udmatime = 0x3050a52;
                param = 0x41;
            }
            if (ata_identify_data[88] & BITRANGE(0, 4))
            {
                ata_dma_flags = BIT(2) | BIT(3) | BIT(9) | BIT(10);
                param |= 0x40;
            }
        }
        ata_dma = param ? true : false;
        dma_mode = param;
        PASS_RC(ata_set_feature(0xef, param), 2, 1);
        if (ata_identify_data[82] & BIT(5)) PASS_RC(ata_set_feature(0x02, 0), 2, 2);
        if (ata_identify_data[82] & BIT(6)) PASS_RC(ata_set_feature(0x55, 0), 2, 3);
        ATA_PIO_TIME = piotime;
        ATA_MDMA_TIME = mdmatime;
        ATA_UDMA_TIME = udmatime;
    }
    spinup_time = current_tick - spinup_start;
    if (ata_lba48)
        ata_total_sectors = ata_identify_data[100]
                            | (((uint64_t)ata_identify_data[101]) << 16)
                            | (((uint64_t)ata_identify_data[102]) << 32)
                            | (((uint64_t)ata_identify_data[103]) << 48);
    else ata_total_sectors = ata_identify_data[60] | (((uint32_t)ata_identify_data[61]) << 16);
    ata_total_sectors >>= 3;
    ata_powered = true;
    ata_set_active();
    return 0;
}
Esempio n. 9
0
static struct sk_buff * ata(struct aoedev *d, struct sk_buff *skb)
{
	struct aoe_hdr *aoe;
	struct aoe_atahdr *ata;
	struct aoereq *rq, *e;
	struct bio *bio;
	sector_t lba;
	int len, rw;
	struct page *page;
	ulong bcnt, offset;

	aoe = (struct aoe_hdr *) skb_mac_header(skb);
	ata = (struct aoe_atahdr *) aoe->data;
	lba = readlba(ata->lba);
	len = sizeof *aoe + sizeof *ata;
	switch (ata->cmdstat) {
	do {
	case ATA_CMD_PIO_READ:
		lba &= ATA_LBA28MAX;
	case ATA_CMD_PIO_READ_EXT:
		lba &= 0x0000FFFFFFFFFFFFULL;
		rw = READ;
		break;
	case ATA_CMD_PIO_WRITE:
		lba &= ATA_LBA28MAX;
	case ATA_CMD_PIO_WRITE_EXT:
		lba &= 0x0000FFFFFFFFFFFFULL;
		rw = WRITE;
	} while (0);
		if ((lba + ata->scnt) > d->scnt) {
			printk(KERN_ERR "sector I/O is out of range: %Lu (%d), max %Lu\n",
				(long long) lba, ata->scnt, d->scnt);
			ata->cmdstat = ATA_ERR;
			ata->errfeat = ATA_IDNF;
			break;
		}
		rq = d->reqs;
		e = rq + nelem(d->reqs);
		for (; rq<e; rq++)
			if (rq->skb == NULL)
				break;
		if (rq == e)
			goto drop;
		
		bio = bio_alloc(GFP_ATOMIC, 1);
		if (bio == NULL) {
			eprintk("can't alloc bio\n");
			goto drop;
		}
		rq->bio = bio;
		rq->d = d;

		bio->bi_sector = lba;
		bio->bi_bdev = d->blkdev;
		bio->bi_end_io = ata_io_complete;
		bio->bi_private = rq;

		page = virt_to_page(ata->data);
		bcnt = ata->scnt << 9;
		offset = offset_in_page(ata->data);

		if (bio_add_page(bio, page, bcnt, offset) < bcnt) {
			printk(KERN_ERR "Can't bio_add_page for %d sectors\n", ata->scnt);
			bio_put(bio);
			goto drop;
		}

		rq->skb = skb;
		atomic_inc(&d->busy);
		submit_bio(rw, bio);
		return NULL;
	default:
		printk(KERN_ERR "Unknown ATA command 0x%02X\n", ata->cmdstat);
		ata->cmdstat = ATA_ERR;
		ata->errfeat = ATA_ABORTED;
		break;
	case ATA_CMD_ID_ATA:
		len += ata_identify(d, ata);
	case ATA_CMD_FLUSH:
		ata->cmdstat = ATA_DRDY;
		ata->errfeat = 0;
		break;
	}
	skb_trim(skb, len);
	return skb;
drop:
	dev_kfree_skb(skb);
	return NULL;
}