]> Zhao Yanbai Git Server - kernel.git/commitdiff
硬盘PIO_EXT读支持一次读多个扇区 dev/202405/disk_pio_ext
authoracevest <zhaoyanbai@126.com>
Mon, 13 May 2024 11:11:27 +0000 (19:11 +0800)
committeracevest <zhaoyanbai@126.com>
Mon, 13 May 2024 11:11:27 +0000 (19:11 +0800)
drivers/ata.c
drivers/ata.h
gdbscript
kernel/task_disk.c

index fca0bba537669d0ab11150c1f4e18aa17d797ce3..3e226178199416d1e22962b196cdd9fde24e59df 100644 (file)
@@ -71,6 +71,7 @@ void ata_read_identity_string(const uint16_t *identify, int bgn, int end, char *
     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++) {
@@ -205,6 +206,8 @@ void ide_ata_init() {
             // 低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]);
@@ -473,6 +476,8 @@ int ata_dma_stop(int channel) {
 
 // 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));
 
@@ -504,7 +509,7 @@ int ata_pio_read_ext(int drv, uint64_t pos, uint16_t count) {
         nop();
     }
 
-    outb(ATA_CMD_READ_PIO_EXT, REG_CMD(drv));
+    outb(ATA_CMD_READ_MULTIPLE_EXT, REG_CMD(drv));
 
     return 0;
 }
index e62aee3f751e02142dbb2c04fb397bf6704c9f22..9cec84ad52dca79ee80edd61516cfd8dda4e554a 100644 (file)
@@ -71,21 +71,27 @@ extern unsigned int IDE_CHL1_CTL_BASE;
 #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
index d5fe482a83d2fdd7f994b9c54db182fcc81ff731..89fe90ee22007615d89383c1beb5896701f7a8fd 100644 (file)
--- a/gdbscript
+++ b/gdbscript
@@ -18,6 +18,8 @@ target remote localhost:1234
 
 set pagination off
 
+#b task_disk.c:97
+
 #b init_serial
 
 #b init_system_info
index 59bde4abfb7389746d65d4c5c1e24807eb320989..0cdb8660d83192aed5ae5596e024c223a5b632f9 100644 (file)
@@ -101,6 +101,7 @@ void disk_task_entry(void *arg) {
 #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) {
@@ -114,9 +115,9 @@ void disk_task_entry(void *arg) {
                 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) {
@@ -141,9 +142,9 @@ void disk_task_entry(void *arg) {
             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);
                 }
             }