/* Call this to initialize SDC/blkdev interface */ void devsdc_init() { blkdev_t *blk; kputs("SDC: "); if( devsdc_exist() ){ /* register first drive */ blk=blkdev_alloc(); blk->driver_data = 0 ; blk->transfer = devsdc_transfer; blk->flush = devsdc_flush; blk->drive_lba_count=-1; /* register second drive */ blk=blkdev_alloc(); blk->driver_data = 1 ; blk->transfer = devsdc_transfer; blk->flush = devsdc_flush; blk->drive_lba_count=-1; kputs("Ok.\n"); } else kprintf("Not Found.\n"); }
void devide_init_drive(uint8_t drive) { blkdev_t *blk; uint8_t *buffer, select; switch(drive){ case 0: select = 0xE0; break; case 1: select = 0xF0; break; default: return; } kprintf("IDE drive %d: ", drive); #ifdef IDE_8BIT_ONLY /* set 8-bit mode -- mostly only supported by CF cards */ devide_writeb(ide_reg_devhead, select); if(!devide_wait(IDE_STATUS_READY)) return; devide_writeb(ide_reg_features, 0x01); /* Enable 8-bit PIO transfer mode (CFA feature set only) */ devide_writeb(ide_reg_command, IDE_CMD_SET_FEATURES); #endif /* confirm drive has LBA support */ if(!devide_wait(IDE_STATUS_READY)) return; /* send identify command */ devide_writeb(ide_reg_devhead, select); devide_writeb(ide_reg_command, IDE_CMD_IDENTIFY); /* allocate temporary sector buffer memory */ buffer = (uint8_t *)tmpbuf(); if(!devide_wait(IDE_STATUS_DATAREQUEST)) goto failout; blk_op.is_user = false; blk_op.addr = buffer; blk_op.nblock = 1; devide_read_data(); if(!(buffer[99] & 0x02)){ kputs("LBA unsupported.\n"); goto failout; } blk = blkdev_alloc(); if(!blk) goto failout; blk->transfer = devide_transfer_sector; blk->flush = devide_flush_cache; blk->driver_data = drive & DRIVE_NR_MASK; if( !(((uint16_t*)buffer)[82] == 0x0000 && ((uint16_t*)buffer)[83] == 0x0000) || (((uint16_t*)buffer)[82] == 0xFFFF && ((uint16_t*)buffer)[83] == 0xFFFF) ){ /* command set notification is supported */ if(buffer[164] & 0x20){ /* write cache is supported */ blk->driver_data |= FLAG_WRITE_CACHE; } } /* read out the drive's sector count */ blk->drive_lba_count = le32_to_cpu(*((uint32_t*)&buffer[120])); /* done with our temporary memory */ brelse((bufptr)buffer); /* scan partitions */ blkdev_scan(blk, SWAPSCAN); return; failout: brelse((bufptr)buffer); return; }
void scsi_dev_init(uint8_t drive) { blkdev_t *blk; uint8_t *p; uint16_t secsize; /* FIXME: need to sort controller mapping policy here too */ si_dcb.device = drive; si_dcb.lun = 0; si_dcb.bus = 0; if (si_select()) /* Can't select it - probably not present */ return; /* FIXME: check if this would be better as a memcpy of fixed struct */ si_dcb.cb.cb0.opcode = SIINQUIRY; si_dcb.cb.cb0.hiblock = 0; si_dcb.cb.cb0.miblock = 0; si_dcb.cb.cb0.loblock = 0; si_dcb.cb.cb0.noblocks = 36; si_dcb.cb.cb0.control = 0; si_dcb.length = 36; si_dcb.direction = SIDIR_READ; si_user = 0; si_deselect(); /* As selects don't necessarily stack */ if (si_docmd(identify)) return; p = identify + 8; while (p < identify + 27) kputchar(*p++); kputchar('\n'); /* Ok the device exists, but we may not be able to drive it */ switch(identify[0] & 0x1F) { case 0x00: /* Hard Disk */ case 0x07: /* Optical */ case 0x0C: /* RAID */ case 0x0E: /* RBC */ break; default: return; } /* We should spin the device up I guess. We don't currently support removable media - that would need us to defer much of this to open and add an open hook to the blkdev layer */ /* FIXME: use Test Unit ready - but note that for SASI at least TUR is optional */ /* Read capacity tells us the disk size */ memset(&si_dcb.cb.cb0, 0, sizeof(si_dcb.cb.cb0)); si_dcb.cb.cb0.opcode = SIREAD_CAP; si_dcb.length = 8; si_dcb.direction = SIDIR_READ; si_user = 0; if (si_docmd(cap)) return; if (cap[4] || cap[5]) /* Block size over 64K */ return; secsize = (cap[6] << 8) | cap[7]; if (secsize != 512) { kprintf("scsi: unsupported sector size %d\n", secsize); return; } /* Ok we pass. Allocate a disk device */ blk = blkdev_alloc(); if (!blk) return; blk->transfer = si_cmd; blk->flush = si_flush; blk->driver_data = drive; /* Very big disks report FFFFFFFF if they overrun this. We don't care we currently only speak READ6 anyway ! */ blk->drive_lba_count = ((uint32_t)cap[0] << 24) | ((uint32_t)cap[1] << 16) | ((uint16_t)cap[2] << 8) | cap[3]; blkdev_scan(blk, SWAPSCAN); }
void devide_init_drive(uint_fast8_t drive) { blkdev_t *blk; uint8_t *buffer; uint_fast8_t select; select = (drive & 1) ? 0xF0 : 0xE0; ide_select(drive); devide_writeb(ide_reg_devhead, select); kprintf("IDE drive %d: ", drive); #ifdef IDE_8BIT_ONLY if (IDE_IS_8BIT(drive)) { /* set 8-bit mode -- mostly only supported by CF cards */ if (!devide_wait(IDE_STATUS_READY)) goto out; devide_writeb(ide_reg_devhead, select); if (!devide_wait(IDE_STATUS_READY)) goto out; devide_writeb(ide_reg_features, 0x01); /* Enable 8-bit PIO transfer mode (CFA feature set only) */ devide_writeb(ide_reg_command, IDE_CMD_SET_FEATURES); } #endif /* confirm drive has LBA support */ if (!devide_wait(IDE_STATUS_READY)) goto out; /* send identify command */ devide_writeb(ide_reg_devhead, select); devide_writeb(ide_reg_command, IDE_CMD_IDENTIFY); /* allocate temporary sector buffer memory */ buffer = (uint8_t *)tmpbuf(); if (!devide_wait(IDE_STATUS_DATAREQUEST)) goto failout; blk_op.is_user = false; blk_op.addr = buffer; blk_op.nblock = 1; devide_read_data(); #ifdef CONFIG_IDE_BSWAP if(!(buffer[98] & 0x02)) { #else if(!(buffer[99] & 0x02)) { #endif kputs("LBA unsupported.\n"); goto failout; } blk = blkdev_alloc(); if(!blk) goto failout; blk->transfer = devide_transfer_sector; blk->flush = devide_flush_cache; blk->driver_data = drive & IDE_DRIVE_NR_MASK; if( !(((uint16_t*)buffer)[82] == 0x0000 && ((uint16_t*)buffer)[83] == 0x0000) || (((uint16_t*)buffer)[82] == 0xFFFF && ((uint16_t*)buffer)[83] == 0xFFFF) ){ /* command set notification is supported */ if(buffer[164] & 0x20){ /* write cache is supported */ blk->driver_data |= FLAG_WRITE_CACHE; } } /* read out the drive's sector count */ blk->drive_lba_count = le32_to_cpu(*((uint32_t*)&buffer[120])); /* done with our temporary memory */ tmpfree(buffer); /* Deselect the IDE, as we will re-select it in the partition scan and it may not recursively stack de-selections */ ide_deselect(); /* scan partitions */ blkdev_scan(blk, SWAPSCAN); return; failout: tmpfree(buffer); out: ide_deselect(); return; } void devide_init(void) { uint_fast8_t d; #ifdef IDE_HAS_RESET devide_reset(); #endif for(d=0; d < IDE_DRIVE_COUNT; d++) devide_init_drive(d); }