buf[i] = 0;
}
+uint16_t max_sectors_per_transfer = 0;
// 《AT Attachment 8 - ATA/ATAPI Command Set》
void ide_ata_init() {
for (int i = 0; i < MAX_IDE_DRIVE_CNT; i++) {
// 低8位0x00代表Reserved,0x01~0xFF代表每次最大传输扇区数
printk("A: %04x\n", identify[47]); // 高 8 位保留,低 8 位表示最大扇区数
+ max_sectors_per_transfer = identify[47];
+
// 第8位为1表示多扇区设置有效
// 当前设置的一次传送的扇区数
printk("B: %04x\n", identify[59]);
// ATA_CMD_READ_PIO_EXT
int ata_pio_read_ext(int drv, uint64_t pos, uint16_t count) {
+ assert(count <= max_sectors_per_transfer);
+
// 不再设置nIEN,需要中断
outb(0x00, REG_CTL(drv));
nop();
}
- outb(ATA_CMD_READ_PIO_EXT, REG_CMD(drv));
+ outb(ATA_CMD_READ_MULTIPLE_EXT, REG_CMD(drv));
return 0;
}
#define ATA_STATUS_ERR 0x01 /* error */
#define ATA_CMD_IDLE 0x00
+#define ATA_CMD_DEVICE_RESET 0x08
#define ATA_CMD_RECALIBRATE 0x10
#define ATA_CMD_READ_PIO 0x20 /* read data */
#define ATA_CMD_READ_PIO_EXT 0x24 /* read data (LBA-48 bit)*/
#define ATA_CMD_READ_DMA 0xC8
#define ATA_CMD_READ_DMA_EXT 0x25 /* read data DMA LBA48 */
+#define ATA_CMD_READ_MULTIPLE_EXT 0x29
#define ATA_CMD_WRITE_PIO 0x30
#define ATA_CMD_WRITE_PIO_EXT 0x34
#define ATA_CMD_WRITE_DMA 0xCA
#define ATA_CMD_WRITE_DMA_EXT 0X35
+#define ATA_CMD_WRITE_MULTIPLE_EXT 0x37
#define ATA_CMD_READ_VERIFY 0x40
#define ATA_CMD_FORMAT 0x50
#define ATA_CMD_SEEK 0x70
#define ATA_CMD_DIAG 0x90
#define ATA_CMD_SPECIFY 0x91
#define ATA_CMD_IDENTIFY_PACKET 0xA1
+#define ATA_CMD_READ_MULTIPLE 0xC4
+#define ATA_CMD_WRITE_MULTIPLE 0xC5
+#define ATA_CMD_SET_MULTIPLE_MODE 0xC6
#define ATA_CMD_IDENTIFY 0xEC
#define ATA_CTL 0
set pagination off
+#b task_disk.c:97
+
#b init_serial
#b init_system_info
#if !DISK_DMA_MODE
// 对于PIO的方式来说,一次只能操作一个扇区,所以有几个扇区就要重试几次
send_cmd_times = r->count;
+ send_cmd_times = 1;
#endif
for (int count = 0; count < send_cmd_times; count++) {
switch (r->command) {
assert(r->buf != NULL || r->bb->data != NULL);
#if !DISK_DMA_MODE
if (r->bb != 0) {
- ata_pio_read_ext(drv_no, pos + count, 1);
+ ata_pio_read_ext(drv_no, pos + count, r->count);
} else {
- ata_pio_read_ext(drv_no, pos + count, 1);
+ ata_pio_read_ext(drv_no, pos + count, r->count);
}
#else
if (r->bb != 0) {
if (DISK_REQ_READ == r->command || DISK_REQ_IDENTIFY == r->command) {
uint32_t offset = SECT_SIZE * count;
if (r->bb != 0) {
- ata_pio_read_data(drv_no, 1, r->bb->data + offset);
+ ata_pio_read_data(drv_no, r->count, r->bb->data + offset);
} else {
- ata_pio_read_data(drv_no, 1, r->buf + offset);
+ ata_pio_read_data(drv_no, r->count, r->buf + offset);
}
}