Move common "command data block" functions to new file blockcmd.c.
[seabios.git] / src / ata.c
index add1d67b4cd7de8d7c5ccf1216d17c42afef864a..3c57f9f3b7045ae4dc91186f521833e4ac9801ac 100644 (file)
--- a/src/ata.c
+++ b/src/ata.c
@@ -17,6 +17,7 @@
 #include "boot.h" // add_bcv_hd
 #include "disk.h" // struct ata_s
 #include "ata.h" // ATA_CB_STAT
+#include "blockcmd.h" // CDB_CMD_READ_10
 
 #define IDE_TIMEOUT 32000 //32 seconds max for IDE ops
 
@@ -37,7 +38,7 @@ await_ide(u8 mask, u8 flags, u16 base, u16 timeout)
         if ((status & mask) == flags)
             return status;
         if (check_time(end)) {
-            dprintf(1, "IDE time out\n");
+            warn_timeout();
             return -1;
         }
         yield();
@@ -109,7 +110,7 @@ ata_reset(struct drive_s *drive_g)
                 break;
             // Change drive request failed to take effect - retry.
             if (check_time(end)) {
-                dprintf(1, "ata_reset slave time out\n");
+                warn_timeout();
                 goto done;
             }
         }
@@ -381,6 +382,8 @@ struct sff_dma_prd {
 static int
 ata_try_dma(struct disk_op_s *op, int iswrite, int blocksize)
 {
+    if (! CONFIG_ATA_DMA)
+        return -1;
     u32 dest = (u32)op->buf_fl;
     if (dest & 1)
         // Need minimum alignment of 1.
@@ -434,6 +437,8 @@ ata_try_dma(struct disk_op_s *op, int iswrite, int blocksize)
 static int
 ata_dma_transfer(struct disk_op_s *op)
 {
+    if (! CONFIG_ATA_DMA)
+        return -1;
     dprintf(16, "ata_dma_transfer id=%p buf=%p\n"
             , op->drive_g, op->buf_fl);
 
@@ -454,7 +459,7 @@ ata_dma_transfer(struct disk_op_s *op)
         // Transfer in progress
         if (check_time(end)) {
             // Timeout.
-            dprintf(1, "IDE DMA timeout\n");
+            warn_timeout();
             break;
         }
         yield();
@@ -513,6 +518,8 @@ fail:
 static int
 ata_dma_cmd_data(struct disk_op_s *op, struct ata_pio_command *cmd)
 {
+    if (! CONFIG_ATA_DMA)
+        return -1;
     int ret = send_cmd(op->drive_g, cmd);
     if (ret)
         return ret;
@@ -590,9 +597,11 @@ process_ata_op(struct disk_op_s *op)
  * ATAPI functions
  ****************************************************************/
 
+#define CDROM_CDB_SIZE 12
+
 // Low-level atapi command transmit function.
-static int
-atapi_cmd_data(struct disk_op_s *op, u8 *cmdbuf, u8 cmdlen, u16 blocksize)
+int
+atapi_cmd_data(struct disk_op_s *op, void *cdbcmd, u16 blocksize)
 {
     u8 ataid = GET_GLOBAL(op->drive_g->cntl_id);
     u8 channel = ataid / 2;
@@ -616,7 +625,7 @@ atapi_cmd_data(struct disk_op_s *op, u8 *cmdbuf, u8 cmdlen, u16 blocksize)
         goto fail;
 
     // Send command to device
-    outsw_fl(iobase1, MAKE_FLATPTR(GET_SEG(SS), cmdbuf), cmdlen / 2);
+    outsw_fl(iobase1, MAKE_FLATPTR(GET_SEG(SS), cdbcmd), CDROM_CDB_SIZE / 2);
 
     int status = pause_await_not_bsy(iobase1, iobase2);
     if (status < 0) {
@@ -644,37 +653,18 @@ atapi_cmd_data(struct disk_op_s *op, u8 *cmdbuf, u8 cmdlen, u16 blocksize)
 fail:
     // Enable interrupts
     outb(ATA_CB_DC_HD15, iobase2+ATA_CB_DC);
-    return ret;
-}
-
-// Read sectors from the cdrom.
-int
-cdrom_read(struct disk_op_s *op)
-{
-    u8 atacmd[12];
-    memset(atacmd, 0, sizeof(atacmd));
-    atacmd[0]=0x28;                         // READ command
-    atacmd[7]=(op->count & 0xff00) >> 8;    // Sectors
-    atacmd[8]=(op->count & 0x00ff);
-    atacmd[2]=(op->lba & 0xff000000) >> 24; // LBA
-    atacmd[3]=(op->lba & 0x00ff0000) >> 16;
-    atacmd[4]=(op->lba & 0x0000ff00) >> 8;
-    atacmd[5]=(op->lba & 0x000000ff);
-
-    return atapi_cmd_data(op, atacmd, sizeof(atacmd), CDROM_SECTOR_SIZE);
+    if (ret)
+        return DISK_RET_EBADTRACK;
+    return DISK_RET_SUCCESS;
 }
 
 // 16bit command demuxer for ATAPI cdroms.
 int
 process_atapi_op(struct disk_op_s *op)
 {
-    int ret;
     switch (op->command) {
     case CMD_READ:
-        ret = cdrom_read(op);
-        if (ret)
-            return DISK_RET_EBADTRACK;
-        return DISK_RET_SUCCESS;
+        return cdb_read(op);
     case CMD_FORMAT:
     case CMD_WRITE:
         return DISK_RET_EWRITEPROTECT;
@@ -683,20 +673,6 @@ process_atapi_op(struct disk_op_s *op)
     }
 }
 
-// Send a simple atapi command to a drive.
-int
-ata_cmd_packet(struct drive_s *drive_g, u8 *cmdbuf, u8 cmdlen
-               , u32 length, void *buf_fl)
-{
-    struct disk_op_s dop;
-    memset(&dop, 0, sizeof(dop));
-    dop.drive_g = drive_g;
-    dop.count = 1;
-    dop.buf_fl = buf_fl;
-
-    return atapi_cmd_data(&dop, cmdbuf, cmdlen, length);
-}
-
 
 /****************************************************************
  * ATA detect and init
@@ -785,9 +761,12 @@ init_drive_atapi(struct drive_s *dummy, u16 *buffer)
         return NULL;
 
     // Success - setup as ATAPI.
-    struct drive_s *drive_g = allocDrive();
-    if (! drive_g)
+    struct drive_s *drive_g = malloc_fseg(sizeof(*drive_g));
+    if (! drive_g) {
+        warn_noalloc();
         return NULL;
+    }
+    memset(drive_g, 0, sizeof(*drive_g));
     SET_GLOBAL(drive_g->cntl_id, dummy->cntl_id);
     extract_identify(drive_g, buffer);
     SET_GLOBAL(drive_g->type, DTYPE_ATAPI);
@@ -831,9 +810,12 @@ init_drive_ata(struct drive_s *dummy, u16 *buffer)
         return NULL;
 
     // Success - setup as ATA.
-    struct drive_s *drive_g = allocDrive();
-    if (! drive_g)
+    struct drive_s *drive_g = malloc_fseg(sizeof(*drive_g));
+    if (! drive_g) {
+        warn_noalloc();
         return NULL;
+    }
+    memset(drive_g, 0, sizeof(*drive_g));
     SET_GLOBAL(drive_g->cntl_id, dummy->cntl_id);
     extract_identify(drive_g, buffer);
     SET_GLOBAL(drive_g->type, DTYPE_ATA);
@@ -877,7 +859,7 @@ powerup_await_non_bsy(u16 base)
             return orstatus;
         }
         if (check_time(SpinupEnd)) {
-            dprintf(1, "powerup IDE time out\n");
+            warn_timeout();
             return -1;
         }
         yield();
@@ -1005,7 +987,7 @@ ata_init(void)
         u8 pciirq = pci_config_readb(bdf, PCI_INTERRUPT_LINE);
         u8 prog_if = pci_config_readb(bdf, PCI_CLASS_PROG);
         int master = 0;
-        if (prog_if & 0x80) {
+        if (CONFIG_ATA_DMA && prog_if & 0x80) {
             // Check for bus-mastering.
             u32 bar = pci_config_readl(bdf, PCI_BASE_ADDRESS_4);
             if (bar & PCI_BASE_ADDRESS_SPACE_IO) {
@@ -1054,6 +1036,7 @@ ata_init(void)
 void
 ata_setup(void)
 {
+    ASSERT32FLAT();
     if (!CONFIG_ATA)
         return;