/* pcn: Present Cylinder Number */ static void ack_irq(uint8_t *pcn) { uint8_t ret; g_assert(get_irq(FLOPPY_IRQ)); floppy_send(CMD_SENSE_INT); floppy_recv(); ret = floppy_recv(); if (pcn != NULL) { *pcn = ret; } g_assert(!get_irq(FLOPPY_IRQ)); }
static void __init floppy_init(void) { uint8_t v; /* Install handler for IRQ6 */ set_irq_handler(6, floppy_isr, NULL); irq_on(6); dprintk("floppy: resetting floppy controllers\n"); floppy_reset(dprts); floppy_send(dprts, CMD_VERSION); v = floppy_recv(dprts); if ( v == 0x80 ) { printk("floppy: NEC765 controller detected\n"); }else{ printk("floppy: enhanced controller detected (0x%x)\n", v); } /* Reset disk-change flag */ inb(dprts->dir); blkdev_add(&floppy0); }
static void test_sense_interrupt(void) { int drive = 0; int head = 0; int cyl = 0; int ret = 0; floppy_send(CMD_SENSE_INT); ret = floppy_recv(); g_assert(ret == 0x80); floppy_send(CMD_SEEK); floppy_send(head << 2 | drive); g_assert(!get_irq(FLOPPY_IRQ)); floppy_send(cyl); floppy_send(CMD_SENSE_INT); ret = floppy_recv(); g_assert(ret == 0x20); floppy_recv(); }
static uint8_t send_read_command(uint8_t cmd) { uint8_t drive = 0; uint8_t head = 0; uint8_t cyl = 0; uint8_t sect_addr = 1; uint8_t sect_size = 2; uint8_t eot = 1; uint8_t gap = 0x1b; uint8_t gpl = 0xff; uint8_t msr = 0; uint8_t st0; uint8_t ret = 0; floppy_send(cmd); floppy_send(head << 2 | drive); g_assert(!get_irq(FLOPPY_IRQ)); floppy_send(cyl); floppy_send(head); floppy_send(sect_addr); floppy_send(sect_size); floppy_send(eot); floppy_send(gap); floppy_send(gpl); uint8_t i = 0; uint8_t n = 2; for (; i < n; i++) { msr = inb(FLOPPY_BASE + reg_msr); if (msr == 0xd0) { break; } sleep(1); } if (i >= n) { return 1; } st0 = floppy_recv(); if (st0 != 0x40) { ret = 1; } floppy_recv(); floppy_recv(); floppy_recv(); floppy_recv(); floppy_recv(); floppy_recv(); return ret; }
/* Interrupt service routine, remember ISRs are * re-entrant on scaraOS - for now anyway */ static void floppy_isr(int irq, void *priv) { unsigned long flags; lock_irq(flags); floppy_send(dprts,CMD_SENSEI); for(slen=0; slen<7 && (inb(dprts->msr)&MSR_BUSY); slen++) { status[slen]=floppy_recv(dprts); } unlock_irq(flags); wake_up(&floppyq); }
static void test_read_id(void) { uint8_t drive = 0; uint8_t head = 0; uint8_t cyl; uint8_t st0; /* Seek to track 0 and check with READ ID */ send_seek(0); floppy_send(CMD_READ_ID); g_assert(!get_irq(FLOPPY_IRQ)); floppy_send(head << 2 | drive); while (!get_irq(FLOPPY_IRQ)) { /* qemu involves a timer with READ ID... */ clock_step(1000000000LL / 50); } st0 = floppy_recv(); floppy_recv(); floppy_recv(); cyl = floppy_recv(); head = floppy_recv(); floppy_recv(); floppy_recv(); g_assert_cmpint(cyl, ==, 0); g_assert_cmpint(head, ==, 0); g_assert_cmpint(st0, ==, head << 2); /* Seek to track 8 on head 1 and check with READ ID */ head = 1; cyl = 8; floppy_send(CMD_SEEK); floppy_send(head << 2 | drive); g_assert(!get_irq(FLOPPY_IRQ)); floppy_send(cyl); g_assert(get_irq(FLOPPY_IRQ)); ack_irq(NULL); floppy_send(CMD_READ_ID); g_assert(!get_irq(FLOPPY_IRQ)); floppy_send(head << 2 | drive); while (!get_irq(FLOPPY_IRQ)) { /* qemu involves a timer with READ ID... */ clock_step(1000000000LL / 50); } st0 = floppy_recv(); floppy_recv(); floppy_recv(); cyl = floppy_recv(); head = floppy_recv(); floppy_recv(); floppy_recv(); g_assert_cmpint(cyl, ==, 8); g_assert_cmpint(head, ==, 1); g_assert_cmpint(st0, ==, head << 2); }
static uint8_t send_read_no_dma_command(int nb_sect, uint8_t expected_st0) { uint8_t drive = 0; uint8_t head = 0; uint8_t cyl = 0; uint8_t sect_addr = 1; uint8_t sect_size = 2; uint8_t eot = nb_sect; uint8_t gap = 0x1b; uint8_t gpl = 0xff; uint8_t msr = 0; uint8_t st0; uint8_t ret = 0; floppy_send(CMD_READ); floppy_send(head << 2 | drive); g_assert(!get_irq(FLOPPY_IRQ)); floppy_send(cyl); floppy_send(head); floppy_send(sect_addr); floppy_send(sect_size); floppy_send(eot); floppy_send(gap); floppy_send(gpl); uint16_t i = 0; uint8_t n = 2; for (; i < n; i++) { msr = inb(FLOPPY_BASE + reg_msr); if (msr == (BUSY | NONDMA | DIO | RQM)) { break; } sleep(1); } if (i >= n) { return 1; } /* Non-DMA mode */ for (i = 0; i < 512 * 2 * nb_sect; i++) { msr = inb(FLOPPY_BASE + reg_msr); assert_bit_set(msr, BUSY | RQM | DIO); inb(FLOPPY_BASE + reg_fifo); } st0 = floppy_recv(); if (st0 != expected_st0) { ret = 1; } floppy_recv(); floppy_recv(); floppy_recv(); floppy_recv(); floppy_recv(); floppy_recv(); return ret; }