patch-2.1.126 linux/drivers/block/genhd.c

Next file: linux/drivers/block/ide-cd.c
Previous file: linux/drivers/block/floppy.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.125/linux/drivers/block/genhd.c linux/drivers/block/genhd.c
@@ -71,7 +71,7 @@
 {
 	unsigned int part;
 	const char *maj = hd->major_name;
-	char unit = (minor >> hd->minor_shift) + 'a';
+	int unit = (minor >> hd->minor_shift) + 'a';
 
 	/*
 	 * IDE devices use multiple major numbers, but the drives
@@ -91,8 +91,19 @@
 			unit += 2;
 		case IDE0_MAJOR:
 			maj = "hd";
+			break;
 	}
 	part = minor & ((1 << hd->minor_shift) - 1);
+	if (hd->major >= SCSI_DISK1_MAJOR && hd->major <= SCSI_DISK7_MAJOR) {
+		unit = unit + (hd->major - SCSI_DISK1_MAJOR + 1) * 16;
+		if (unit > 'z') {
+			unit -= 'z' + 1;
+			sprintf(buf, "sd%c%c", 'a' + unit / 26, 'a' + unit % 26);
+			if (part)
+				sprintf(buf + 4, "%d", part);
+			return buf;
+		}
+	}
 	if (part)
 		sprintf(buf, "%s%c%d", maj, unit, part);
 	else
@@ -647,6 +658,74 @@
 
 #endif /* CONFIG_SUN_PARTITION */
 
+#ifdef CONFIG_SGI_PARTITION
+
+static int sgi_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector)
+{
+	int i, csum;
+	unsigned int *ui;
+	struct buffer_head *bh;
+	struct sgi_disklabel {
+		int magic_mushroom;         /* Big fat spliff... */
+		short root_part_num;        /* Root partition number */
+		short swap_part_num;        /* Swap partition number */
+		char boot_file[16];         /* Name of boot file for ARCS */
+		unsigned char _unused0[48]; /* Device parameter useless crapola.. */
+		struct sgi_volume {
+			char name[8];       /* Name of volume */
+			int  block_num;     /* Logical block number */
+			int  num_bytes;     /* How big, in bytes */
+		} volume[15];
+		struct sgi_partition {
+			int num_blocks;     /* Size in logical blocks */
+			int first_block;    /* First logical block */
+			int type;           /* Type of this partition */
+		} partitions[16];
+		int csum;                   /* Disk label checksum */
+		int _unused1;               /* Padding */
+	} *label;
+	struct sgi_partition *p;
+#define SGI_LABEL_MAGIC 0x0be5a941
+
+	if(!(bh = bread(dev, 0, 1024))) {
+		printk("Dev %s: unable to read partition table\n", kdevname(dev));
+		return -1;
+	}
+	label = (struct sgi_disklabel *) bh->b_data;
+	p = &label->partitions[0];
+	if(label->magic_mushroom != SGI_LABEL_MAGIC) {
+		printk("Dev %s SGI disklabel: bad magic %08x\n",
+		       kdevname(dev), label->magic_mushroom);
+		brelse(bh);
+		return 0;
+	}
+	ui = ((unsigned int *) (label + 1)) - 1;
+	for(csum = 0; ui >= ((unsigned int *) label);)
+		csum += *ui--;
+	if(csum) {
+		printk("Dev %s SGI disklabel: csum bad, label corrupted\n",
+		       kdevname(dev));
+		brelse(bh);
+		return 0;
+	}
+	/* All SGI disk labels have 16 partitions, disks under Linux only
+	 * have 15 minor's.  Luckily there are always a few zero length
+	 * partitions which we don't care about so we never overflow the
+	 * current_minor.
+	 */
+	for(i = 0; i < 16; i++, p++) {
+		if(!(p->num_blocks))
+			continue;
+		add_partition(hd, current_minor, p->first_block, p->num_blocks);
+		current_minor++;
+	}
+	printk("\n");
+	brelse(bh);
+	return 1;
+}
+
+#endif
+
 #ifdef CONFIG_AMIGA_PARTITION
 #include <asm/byteorder.h>
 #include <linux/affs_hardblocks.h>
@@ -1037,6 +1116,10 @@
 #endif
 #ifdef CONFIG_MAC_PARTITION
 	if (mac_partition(hd, dev, first_sector))
+		return;
+#endif
+#ifdef CONFIG_SGI_PARTITION
+	if(sgi_partition(hd, dev, first_sector))
 		return;
 #endif
 	printk(" unknown partition table\n");

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov