/** * We try to read tracks, but if we get too many errors, we * go back to reading just one sector at a time. * * This means we should be able to read a sector even if there * are other bad sectors on this track. * * @see rw_interrupt */ inline void setup_rw_floppy(void) { setup_DMA(); do_floppy = rw_interrupt; output_byte(command); if (command != FD_FORMAT) { if (read_track) { output_byte(current_drive); output_byte(track); output_byte(0); output_byte(1); } else { output_byte(head<<2 | current_drive); output_byte(track); output_byte(head); output_byte(sector); } output_byte(2); /* sector size = 512 */ output_byte(floppy->sect); output_byte(floppy->gap); output_byte(0xFF); /* sector size (0xff when n!=0 ?) */ } else { output_byte(head<<2 | current_drive); output_byte(2); output_byte(floppy->sect); output_byte(floppy->fmt_gap); output_byte(FD_FILL_BYTE); } if (reset) redo_fd_request(); }
/* * And now, it's time to implenent the read or write function, that's * all the floppy driver mean! * * Read/Write one sector once. */ static int floppy_rw(int sector, char *buf, int command) { int head; char *dma_buffer = buf; static char tmp_dma_buffer[512]; //LOG("TMP dma buffer: %p\n", tmp_dma_buffer); lba_to_chs(sector, &head, &track, §or); LOG("head: %d \ttrack: %d \tsector: %d\n", head, track, sector); /* turn it on if not */ motor_on(); if (inb_p(FD_DIR) & 0x80) { changed = TRUE; seek(1, head); /* clear "disk change" status */ recalibrate(); motor_off(); printk("floppy_rw: Disk change detected. You are going to DIE:)\n"); pause(); /* just put it in DIE */ } /* move head to the right track */ if (!seek(track, head)) { motor_off(); printk("floppy_rw: Error seeking to track#%d\n", track); return FALSE; } if ((unsigned long)buf >= 0xff000) { dma_buffer = tmp_dma_buffer; if (command == FD_WRITE) memcpy(dma_buffer, buf, 512); } setup_DMA((unsigned long)dma_buffer, command); send_byte(command); send_byte(head<<2 | 0); send_byte(track); send_byte(head); send_byte(sector); send_byte(2); /* sector size = 125 * 2^(2) */ send_byte(floppy.sector); send_byte(0); send_byte(0xFF); /* sector size(only two valid vaules, 0xff when n!=0*/ if (!wait_fdc(FALSE)) { //LOG("wait fdc failed!\n"); //return 0; /* printk("Time out, trying operation again after reset() \n"); reset(); return floppy_rw(sector, buf, command); */ } motor_off(); if (/*res != 7 || */(ST0 & 0xf8) || (ST1 & 0xbf) || (ST2 & 0x73) ) { if (ST1 & 0x02) LOG("Drive is write protected!\n"); else LOG("floppy_rw: bad interrupt!\n"); return -EIO; } else { LOG("floppy_rw: OK\n"); if ((unsigned long)buf >= 0xff000 && command == FD_READ) memcpy(buf, dma_buffer, 512); return 0; } }