grml...
[seabios.git] / src / ahci.c
index 55ada5f7499a198f47bab90f66e03a2e2d5cb2ed..9b3ce2f391f56bc4d6e8f282454574e146e01f9b 100644 (file)
@@ -383,7 +383,7 @@ ahci_port_reset(struct ahci_ctrl_s *ctrl, u32 pnr)
 static struct ahci_port_s*
 ahci_port_alloc(struct ahci_ctrl_s *ctrl, u32 pnr)
 {
-    struct ahci_port_s *port = malloc_fseg(sizeof(*port));
+    struct ahci_port_s *port = malloc_tmp(sizeof(*port));
 
     if (!port) {
         warn_noalloc();
@@ -407,10 +407,16 @@ ahci_port_alloc(struct ahci_ctrl_s *ctrl, u32 pnr)
     return port;
 }
 
-static void ahci_port_realloc(struct ahci_port_s *port)
+static struct ahci_port_s* ahci_port_realloc(struct ahci_port_s *port)
 {
+    struct ahci_port_s *tmp;
     u32 cmd;
 
+    tmp = malloc_fseg(sizeof(*port));
+    *tmp = *port;
+    free(port);
+    port = tmp;
+
     ahci_port_reset(port->ctrl, port->pnr);
 
     free(port->list);
@@ -426,6 +432,8 @@ static void ahci_port_realloc(struct ahci_port_s *port)
     cmd = ahci_port_readl(port->ctrl, port->pnr, PORT_CMD);
     cmd |= (PORT_CMD_FIS_RX|PORT_CMD_START);
     ahci_port_writel(port->ctrl, port->pnr, PORT_CMD, cmd);
+
+    return port;
 }
 
 static void ahci_port_release(struct ahci_port_s *port)
@@ -531,35 +539,28 @@ static int ahci_port_init(struct ahci_port_s *port)
             adjsize >>= 10;
             adjprefix = 'G';
         }
-        char *desc = znprintf(MAXDESCSIZE
+        port->desc = znprintf(MAXDESCSIZE
                               , "AHCI/%d: %s ATA-%d Hard-Disk (%u %ciBytes)"
                               , port->pnr
                               , ata_extract_model(model, MAXMODEL, buffer)
                               , ata_extract_version(buffer)
                               , (u32)adjsize, adjprefix);
-        dprintf(1, "%s\n", desc);
-
-        // Register with bcv system.
-        int prio = bootprio_find_ata_device(ctrl->pci_tmp, pnr, 0);
-        boot_add_hd(&port->drive, desc, prio);
+        port->prio = bootprio_find_ata_device(ctrl->pci_tmp, pnr, 0);
     } else {
         // found cdrom (atapi)
         port->drive.blksize = CDROM_SECTOR_SIZE;
         port->drive.sectors = (u64)-1;
         u8 iscd = ((buffer[0] >> 8) & 0x1f) == 0x05;
-        char *desc = znprintf(MAXDESCSIZE
-                              , "DVD/CD [AHCI/%d: %s ATAPI-%d %s]"
+        if (!iscd) {
+            dprintf(1, "AHCI/%d: atapi device is'nt a cdrom\n", port->pnr);
+            return -1;
+        }
+        port->desc = znprintf(MAXDESCSIZE
+                              , "DVD/CD [AHCI/%d: %s ATAPI-%d DVD/CD]"
                               , port->pnr
                               , ata_extract_model(model, MAXMODEL, buffer)
-                              , ata_extract_version(buffer)
-                              , (iscd ? "DVD/CD" : "Device"));
-        dprintf(1, "%s\n", desc);
-
-        // fill cdidmap
-        if (iscd) {
-            int prio = bootprio_find_ata_device(ctrl->pci_tmp, pnr, 0);
-            boot_add_cd(&port->drive, desc, prio);
-        }
+                              , ata_extract_version(buffer));
+        port->prio = bootprio_find_ata_device(ctrl->pci_tmp, pnr, 0);
     }
     return 0;
 }
@@ -576,8 +577,17 @@ ahci_port_detect(void *data)
     rc = ahci_port_init(port);
     if (rc < 0)
         ahci_port_release(port);
-    else
-        ahci_port_realloc(port);
+    else {
+        port = ahci_port_realloc(port);
+        dprintf(1, "AHCI/%d: registering: \"%s\"\n", port->pnr, port->desc);
+        if (!port->atapi) {
+            // Register with bcv system.
+            boot_add_hd(&port->drive, port->desc, port->prio);
+        } else {
+            // fill cdidmap
+            boot_add_cd(&port->drive, port->desc, port->prio);
+        }
+    }
 }
 
 // Initialize an ata controller and detect its drives.