Treat iSCSI targets as block devices.
[yaboot.git] / second / partition.c
index a95a1b25a6aa25844ee6215ee0868151a5c3b703..4381770fcca5facc0171fc52308b273478235608 100644 (file)
@@ -40,6 +40,8 @@
 #include "linux/iso_fs.h"
 #include "debug.h"
 #include "errors.h"
 #include "linux/iso_fs.h"
 #include "debug.h"
 #include "errors.h"
+#include "bootinfo.h"
+#include "byteorder.h"
 
 /* We currently don't check the partition type, some users
  * are putting crap there and still expect it to work...
 
 /* We currently don't check the partition type, some users
  * are putting crap there and still expect it to work...
@@ -56,10 +58,7 @@ static const char *valid_mac_partition_types[] = {
      NULL
 };
 #endif
      NULL
 };
 #endif
-    
 
 
-/* Local functions */
-static unsigned long swab32(unsigned long value);
 
 #define MAX_BLOCK_SIZE 2048
 static unsigned char block_buffer[MAX_BLOCK_SIZE];
 
 #define MAX_BLOCK_SIZE 2048
 static unsigned char block_buffer[MAX_BLOCK_SIZE];
@@ -71,7 +70,7 @@ add_new_partition(struct partition_t**        list, int part_number, const char *part_t
 {
      struct partition_t*       part;
      part = (struct partition_t*)malloc(sizeof(struct partition_t));
 {
      struct partition_t*       part;
      part = (struct partition_t*)malloc(sizeof(struct partition_t));
-       
+
      part->part_number = part_number;
      strncpy(part->part_type, part_type, MAX_PART_NAME);
      strncpy(part->part_name, part_name, MAX_PART_NAME);
      part->part_number = part_number;
      strncpy(part->part_type, part_type, MAX_PART_NAME);
      strncpy(part->part_name, part_name, MAX_PART_NAME);
@@ -99,7 +98,7 @@ partition_mac_lookup( const char *dev_name, prom_handle disk,
      struct mac_partition* part = (struct mac_partition *)block_buffer;
      unsigned short ptable_block_size =
          ((struct mac_driver_desc *)block_buffer)->block_size;
      struct mac_partition* part = (struct mac_partition *)block_buffer;
      unsigned short ptable_block_size =
          ((struct mac_driver_desc *)block_buffer)->block_size;
-       
+
      map_size = 1;
      for (block=1; block < map_size + 1; block++)
      {
      map_size = 1;
      for (block=1; block < map_size + 1; block++)
      {
@@ -119,9 +118,9 @@ partition_mac_lookup( const char *dev_name, prom_handle disk,
          }
          if (block == 1)
               map_size = part->map_count;
          }
          if (block == 1)
               map_size = part->map_count;
-               
+
 #ifdef CHECK_FOR_VALID_MAC_PARTITION_TYPE
 #ifdef CHECK_FOR_VALID_MAC_PARTITION_TYPE
-         /* We don't bother looking at swap partitions of any type, 
+         /* We don't bother looking at swap partitions of any type,
           * and the rest are the ones we know about */
          for (ptype = valid_mac_partition_types; ptype; ptype++)
               if (!strcmp (part->type, ptype))
           * and the rest are the ones we know about */
          for (ptype = valid_mac_partition_types; ptype; ptype++)
               if (!strcmp (part->type, ptype))
@@ -155,7 +154,7 @@ partition_mac_lookup( const char *dev_name, prom_handle disk,
      }
 }
 
      }
 }
 
-/* 
+/*
  * Same function as partition_mac_lookup(), except for fdisk
  * partitioned disks.
  */
  * Same function as partition_mac_lookup(), except for fdisk
  * partitioned disks.
  */
@@ -168,7 +167,7 @@ partition_fdisk_lookup( const char *dev_name, prom_handle disk,
      /* fdisk partition tables start at offset 0x1be
       * from byte 0 of the boot drive.
       */
      /* fdisk partition tables start at offset 0x1be
       * from byte 0 of the boot drive.
       */
-     struct fdisk_partition* part = 
+     struct fdisk_partition* part =
          (struct fdisk_partition *) (block_buffer + 0x1be);
 
      for (partition=1; partition <= 4 ;partition++, part++) {
          (struct fdisk_partition *) (block_buffer + 0x1be);
 
      for (partition=1; partition <= 4 ;partition++, part++) {
@@ -177,8 +176,8 @@ partition_fdisk_lookup( const char *dev_name, prom_handle disk,
                                   partition,
                                   "Linux", /* type */
                                   '\0', /* name */
                                   partition,
                                   "Linux", /* type */
                                   '\0', /* name */
-                                  swab32(*(unsigned int *)(part->start4)),
-                                  swab32(*(unsigned int *)(part->size4)),
+                                  le32_to_cpu(*(unsigned int *)part->start4),
+                                  le32_to_cpu(*(unsigned int *)part->size4),
                                   512 /*blksize*/,
                                   part->sys_ind /* partition type */ );
          }
                                   512 /*blksize*/,
                                   part->sys_ind /* partition type */ );
          }
@@ -203,11 +202,11 @@ identify_iso_fs(ihandle device, unsigned int *iso_root_block)
               prom_printf("Can't read volume desc block %d\n", block);
               break;
          }
               prom_printf("Can't read volume desc block %d\n", block);
               break;
          }
-               
+
          vdp = (struct iso_volume_descriptor *)block_buffer;
          vdp = (struct iso_volume_descriptor *)block_buffer;
-           
-         /* Due to the overlapping physical location of the descriptors, 
-          * ISO CDs can match hdp->id==HS_STANDARD_ID as well. To ensure 
+
+         /* Due to the overlapping physical location of the descriptors,
+          * ISO CDs can match hdp->id==HS_STANDARD_ID as well. To ensure
           * proper identification in this case, we first check for ISO.
           */
          if (strncmp (vdp->id, ISO_STANDARD_ID, sizeof vdp->id) == 0) {
           * proper identification in this case, we first check for ISO.
           */
          if (strncmp (vdp->id, ISO_STANDARD_ID, sizeof vdp->id) == 0) {
@@ -215,11 +214,11 @@ identify_iso_fs(ihandle device, unsigned int *iso_root_block)
               return 1;
          }
      }
               return 1;
          }
      }
-       
+
      return 0;
 }
 
      return 0;
 }
 
-/* 
+/*
  * Detects and read amiga partition tables.
  */
 
  * Detects and read amiga partition tables.
  */
 
@@ -251,7 +250,7 @@ _amiga_find_rdb (const char *dev_name, prom_handle disk, unsigned int prom_blksi
                        if (prom_readblocks(disk, i, 1, block_buffer) != 1) {
                                prom_printf("Can't read boot block %d\n", i);
                                break;
                        if (prom_readblocks(disk, i, 1, block_buffer) != 1) {
                                prom_printf("Can't read boot block %d\n", i);
                                break;
-                       }       
+                       }
                }
                if ((amiga_block[AMIGA_ID] == AMIGA_ID_RDB) && (_amiga_checksum (prom_blksize) == 0))
                        return 1;
                }
                if ((amiga_block[AMIGA_ID] == AMIGA_ID_RDB) && (_amiga_checksum (prom_blksize) == 0))
                        return 1;
@@ -260,7 +259,7 @@ _amiga_find_rdb (const char *dev_name, prom_handle disk, unsigned int prom_blksi
        if (prom_readblocks(disk, 0, 1, block_buffer) != 1) {
                prom_printf("Can't read boot blocks\n");
                return 0; /* TODO: something bad happened, should fail more verbosely */
        if (prom_readblocks(disk, 0, 1, block_buffer) != 1) {
                prom_printf("Can't read boot blocks\n");
                return 0; /* TODO: something bad happened, should fail more verbosely */
-       }       
+       }
        return 0;
 }
 
        return 0;
 }
 
@@ -280,18 +279,22 @@ partition_amiga_lookup( const char *dev_name, prom_handle disk,
        possible = amiga_block[AMIGA_RDBLIMIT]/32 +1;
 
        used = (unsigned int *) malloc (sizeof (unsigned int) * (possible + 1));
        possible = amiga_block[AMIGA_RDBLIMIT]/32 +1;
 
        used = (unsigned int *) malloc (sizeof (unsigned int) * (possible + 1));
+       if (!used) {
+               prom_printf("Can't allocate memory\n");
+               return;
+       }
 
        for (i=0; i < possible; i++) used[i] = 0;
 
 
 
        for (i=0; i < possible; i++) used[i] = 0;
 
 
-       for (part = amiga_block[AMIGA_PARTITIONS], partition = 0;
+       for (part = amiga_block[AMIGA_PARTITIONS], partition = 1;
                part != AMIGA_END;
                part = amiga_block[AMIGA_PART_NEXT], partition++)
        {
                if (prom_readblocks(disk, part, 1, block_buffer) != 1) {
                        prom_printf("Can't read partition block %d\n", part);
                        break;
                part != AMIGA_END;
                part = amiga_block[AMIGA_PART_NEXT], partition++)
        {
                if (prom_readblocks(disk, part, 1, block_buffer) != 1) {
                        prom_printf("Can't read partition block %d\n", part);
                        break;
-               }       
+               }
                checksum = _amiga_checksum (prom_blksize);
                if ((amiga_block[AMIGA_ID] == AMIGA_ID_PART) &&
                        (checksum == 0) &&
                checksum = _amiga_checksum (prom_blksize);
                if ((amiga_block[AMIGA_ID] == AMIGA_ID_PART) &&
                        (checksum == 0) &&
@@ -322,6 +325,8 @@ partition_amiga_lookup( const char *dev_name, prom_handle disk,
                    prom_blksize,
                    0 );
        }
                    prom_blksize,
                    0 );
        }
+       if (used)
+               free(used);
 }
 
 struct partition_t*
 }
 
 struct partition_t*
@@ -331,10 +336,11 @@ partitions_lookup(const char *device)
      struct mac_driver_desc *desc = (struct mac_driver_desc *)block_buffer;
      struct partition_t* list = NULL;
      unsigned int prom_blksize, iso_root_block;
      struct mac_driver_desc *desc = (struct mac_driver_desc *)block_buffer;
      struct partition_t* list = NULL;
      unsigned int prom_blksize, iso_root_block;
-       
+
      strncpy(block_buffer, device, 2040);
      strncpy(block_buffer, device, 2040);
-     strcat(block_buffer, ":0");
-       
+     if (_machine != _MACH_bplan)
+         strcat(block_buffer, ":0");
+
      /* Open device */
      disk = prom_open(block_buffer);
      if (disk == NULL) {
      /* Open device */
      disk = prom_open(block_buffer);
      if (disk == NULL) {
@@ -350,12 +356,12 @@ partitions_lookup(const char *device)
          prom_printf("block_size %d not supported !\n", prom_blksize);
          goto bail;
      }
          prom_printf("block_size %d not supported !\n", prom_blksize);
          goto bail;
      }
-       
+
      /* Read boot blocs */
      if (prom_readblocks(disk, 0, 1, block_buffer) != 1) {
          prom_printf("Can't read boot blocks\n");
          goto bail;
      /* Read boot blocs */
      if (prom_readblocks(disk, 0, 1, block_buffer) != 1) {
          prom_printf("Can't read boot blocks\n");
          goto bail;
-     } 
+     }
      if (desc->signature == MAC_DRIVER_MAGIC) {
          /* pdisk partition format */
          partition_mac_lookup(device, disk, prom_blksize, &list);
      if (desc->signature == MAC_DRIVER_MAGIC) {
          /* pdisk partition format */
          partition_mac_lookup(device, disk, prom_blksize, &list);
@@ -382,7 +388,7 @@ partitions_lookup(const char *device)
 
 bail:
      prom_close(disk);
 
 bail:
      prom_close(disk);
-       
+
      return list;
 }
 
      return list;
 }
 
@@ -394,7 +400,8 @@ get_part_type(char *device, int partition)
      struct partition_t*       found;
      char *type = NULL;
 
      struct partition_t*       found;
      char *type = NULL;
 
-     if (prom_get_devtype(device) != FILE_DEVICE_BLOCK)
+     int device_kind = prom_get_devtype(device);
+     if (device_kind != FILE_DEVICE_BLOCK && device_kind != FILE_DEVICE_ISCSI)
          return NULL;
 
      parts = partitions_lookup(device);
          return NULL;
 
      parts = partitions_lookup(device);
@@ -409,7 +416,7 @@ get_part_type(char *device, int partition)
          if ((partition >= 0) && (partition == p->part_number)) {
               type = strdup(p->part_type);
               break;
          if ((partition >= 0) && (partition == p->part_number)) {
               type = strdup(p->part_type);
               break;
-         }       
+         }
      }
      if (parts)
          partitions_free(parts);
      }
      if (parts)
          partitions_free(parts);
@@ -421,28 +428,16 @@ void
 partitions_free(struct partition_t* list)
 {
      struct partition_t*       next;
 partitions_free(struct partition_t* list)
 {
      struct partition_t*       next;
-       
+
      while(list) {
          next = list->next;
          free(list);
          list = next;
      }
 }
      while(list) {
          next = list->next;
          free(list);
          list = next;
      }
 }
-unsigned long
-swab32(unsigned long value)
-{
-     __u32 result;
-
-     __asm__("rlwimi %0,%1,24,16,23\n\t"
-            "rlwimi %0,%1,8,8,15\n\t"
-            "rlwimi %0,%1,24,0,7"
-            : "=r" (result)
-            : "r" (value), "0" (value >> 24));
-     return result;
-}
 
 
 
 
-/* 
+/*
  * Local variables:
  * c-file-style: "k&r"
  * c-basic-offset: 5
  * Local variables:
  * c-file-style: "k&r"
  * c-basic-offset: 5