patch do IDE (fwd)

Tomasz Kłoczko kloczek w rudy.mif.pg.gda.pl
Śro, 4 Paź 2000, 01:13:49 CEST


Mały forward od Andrzeja.

Dołaczony patch ma rozwiązywać sprawę czytania geometrii dysków IDE z BIOS
przy ide w module (tak jak to mamy obecnie). W tej chwili nie mam czasu go
przetestować (może jutro albo pojutrze) także jeżeli ktoś miałby chęć się
tym zająć to proszę. W razie czego jakieś uwagi czy raporty o
nieprawidłowosciach prośba żeby kierować do Andrzeja.

Prawdopodobnie w najbliższych dniach bende chciał przyszykować kolejną
wersje kernela. Plan rzeczy do zrobienia zakłada na razie wyłęczenie backw
compat do /proc/pci (lcpci załatwia to w zupełności, a wyłączenie tego
zmniejszy rozmiar kernela o dość spory kawałek). Włączenie chipsetu ALI.
Włączenie tego patcha do inicjacji geometrii przy ładowaniu modułu do ide
Wogóle moduł do ide-probe jest nieco skopany, bo mając załadowane ide z
modułu nie da się wykonać ponownie probingu bez wyładowania ide (a to moze
być potrzebne jeżeli jedno z urządzeń IDE wymienia sie i reinicjuje w
trakcie pracy systemu). Wyłaczenie modułu do xt (moduł w obecnej wersji
kernela jest praktycznie bezużyteczny).

Z innych rzeczy które można jeszcze zrobić w modułach to:
- obsługa konkretnych typów tablic partycji/slice-ów w modułach (patch do
  tego był kilka miesiecy temu na l-k i prawdopodobnie po odświerzeniu
  nadawałby się do użycia),
- obsługa poszczególnych chipsetów płyt głównych w modułach (Andrzej coś
  mówił, że będzie w tym kierunku działał),
- poprawienie obsługi ATM (w tej chwili nie jest to poprawnie 
  zmodularyzowane i dodatkowo atmtcp wyrzuca się na jednym urozwiązanym
  symbolu (prawdopodobnie gdzieś brak jest tylko eksportu odpowieniego
  symbolu),
- w kolejce jest także bridging w module (o czym była już mowa).

Jeżeli ktoś miałby jakieś jeszcze inne propozycje co do polepszenia
kernela w sytuacji kiedy jest on silnie zmodularyzowany to bardzo bym
prosił. Czy są chętni żeby popracować nad kernelem bazujacym na pre 18 ?
(tu już wiadome jest jedno, że jest dość ostry konflikt między poprawkami
Alana i Hedrica - chwilowo do czasu rozwiazania tego konfliktu wydaje mi
się, że możnaby wyłaczyć patch Hedrica). Backportem patcha do ide
zajmuje się ktoś z .pl (zapomniałem kto). W razie czego przydałoby się
nawiazać ściślejszy kontakt tutaj.

Jeżeli byliby chętnie na pracę nad pre 18 to takie prace prosiłbym w
brancha.

kloczek
-- 

---------- Forwarded message ----------
Date: Wed, 4 Oct 2000 00:35:46 +0200 (CEST)
From: Andrzej Krzysztofowicz <ankry w green.mif.pg.gda.pl>
To: kloczek w rudy.mif.pg.gda.pl
Subject: patch do IDE


Sprobuj tego pacza.
A.K.


diff -uNr linux-PLD/drivers/block/Makefile linux/drivers/block/Makefile
--- linux-PLD/drivers/block/Makefile	Tue Oct  3 18:38:40 2000
+++ linux/drivers/block/Makefile	Tue Oct  3 23:38:13 2000
@@ -20,10 +20,10 @@
 
 
 L_TARGET := block.a
-L_OBJS   := genhd.o ide-geometry.o
+L_OBJS   :=
 M_OBJS   :=
 MOD_LIST_NAME := BLOCK_MODULES
-LX_OBJS := ll_rw_blk.o
+LX_OBJS := ll_rw_blk.o genhd.o
 MX_OBJS :=
 
 ifeq ($(CONFIG_MAC_FLOPPY),y)
@@ -259,11 +259,11 @@
 ###Collect
 
 ifeq ($(CONFIG_BLK_DEV_IDE),y)
-  LX_OBJS += ide.o ide-features.o
+  LX_OBJS += ide.o ide-features.o ide-geometry.o
   L_OBJS += ide-probe.o $(IDE_OBJS)
 else
   ifeq ($(CONFIG_BLK_DEV_IDE),m)
-  MIX_OBJS += ide.o ide-features.o $(IDE_OBJS)
+  MIX_OBJS += ide.o ide-features.o ide-geometry.o $(IDE_OBJS)
   M_OBJS += ide-mod.o ide-probe-mod.o
   endif
 endif
@@ -408,8 +408,8 @@
 
 include $(TOPDIR)/Rules.make
 
-ide-mod.o: ide.o ide-features.o $(IDE_OBJS)
-	$(LD) $(LD_RFLAG) -r -o $@ ide.o ide-features.o $(IDE_OBJS)
+ide-mod.o: ide.o ide-features.o ide-geometry.o $(IDE_OBJS)
+	$(LD) $(LD_RFLAG) -r -o $@ ide.o ide-features.o ide-geometry.o $(IDE_OBJS)
 
-ide-probe-mod.o: ide-probe.o ide-geometry.o
-	$(LD) $(LD_RFLAG) -r -o $@ ide-probe.o ide-geometry.o
+ide-probe-mod.o: ide-probe.o
+	$(LD) $(LD_RFLAG) -r -o $@ ide-probe.o
diff -uNr linux-PLD/drivers/block/genhd.c linux/drivers/block/genhd.c
--- linux-PLD/drivers/block/genhd.c	Tue Oct  3 18:38:40 2000
+++ linux/drivers/block/genhd.c	Tue Oct  3 23:53:18 2000
@@ -29,6 +29,7 @@
 #include <linux/blk.h>
 #include <linux/init.h>
 #include <linux/raid/md.h>
+#include <linux/ide-geometry.h>
 
 #include <asm/system.h>
 #include <asm/byteorder.h>
@@ -72,6 +73,11 @@
 extern void note_bootable_part(kdev_t dev, int part);
 #endif
 
+/*
+ * This is a handler for ide_xlate_1024()
+ */
+idexlatefunc_t * ide_xlate_handler = NULL;
+
 static char *raid_name (struct gendisk *hd, int minor, int major_base,
                         char *buf)
 {
@@ -510,11 +516,9 @@
 	kdev_t bsd_kdev = 0;
 	int bsd_maxpart = BSD_MAXPARTITIONS;
 #endif
-#ifdef CONFIG_BLK_DEV_IDE
 	int tested_for_xlate = 0;
 
 read_mbr:
-#endif
 	if (!(bh = bread(dev,0,get_ptable_blocksize(dev)))) {
 		printk(" unable to read partition table\n");
 		return -1;
@@ -533,9 +537,7 @@
 	/*  of the drive (below), so ensure that   */
 	/*  nobody else tries to re-use this data. */
 	bh->b_state = 0;
-#ifdef CONFIG_BLK_DEV_IDE
 check_table:
-#endif
 	/* Use bforget(), because we have potentially changed the disk geometry */
 	if (*(unsigned short *)  (0x1fe + data) != cpu_to_le16(MSDOS_LABEL_MAGIC)) {
 		bforget(bh);	/* brelse(bh); */
@@ -543,12 +545,10 @@
 	}
 	p = (struct partition *) (0x1be + data);
 
-#ifdef CONFIG_BLK_DEV_IDE
-	if (!tested_for_xlate++) {	/* Do this only once per disk */
+	if (ide_xlate_handler && !tested_for_xlate++) {	/* Do this only once per disk */
 		/*
 		 * Look for various forms of IDE disk geometry translation
 		 */
-		extern int ide_xlate_1024(kdev_t, int, int, const char *);
 		unsigned int sig = le16_to_cpu(*(unsigned short *)(data + 2));
 		int heads = 0;
 
@@ -572,7 +573,7 @@
 			/*
 			 * Accesses to sector 0 must go to sector 1 instead.
 			 */
-			if (ide_xlate_1024(dev, -1, heads, " [EZD]")) {
+			if (ide_xlate_handler(dev, -1, heads, " [EZD]")) {
 				data += 512;
 				goto check_table;
 			}
@@ -582,7 +582,7 @@
 			 * Everything on the disk is offset by 63 sectors,
 			 * including a "new" MBR with its own partition table.
 			 */
-			if (ide_xlate_1024(dev, 1, heads, " [DM6:DDO]")) {
+			if (ide_xlate_handler(dev, 1, heads, " [DM6:DDO]")) {
 				bforget(bh);	/* brelse(bh); */
 				goto read_mbr;	/* start over with new MBR */
 			}
@@ -595,18 +595,17 @@
 			   (data[sig+2] & 1)) {
 #endif
 			/* DM6 signature in MBR, courtesy of OnTrack */
-			(void) ide_xlate_1024 (dev, 0, heads, " [DM6:MBR]");
+			(void) ide_xlate_handler(dev, 0, heads, " [DM6:MBR]");
 		} else if (SYS_IND(p) == DM6_AUX1PARTITION ||
 			   SYS_IND(p) == DM6_AUX3PARTITION) {
 			/*
 			 * DM6 on other than the first (boot) drive
 			 */
-			(void) ide_xlate_1024(dev, 0, heads, " [DM6:AUX]");
+			(void) ide_xlate_handler(dev, 0, heads, " [DM6:AUX]");
 		} else {
-			(void) ide_xlate_1024(dev, 2, heads, " [PTBL]");
+			(void) ide_xlate_handler(dev, 2, heads, " [PTBL]");
 		}
 	}
-#endif	/* CONFIG_BLK_DEV_IDE */
 
 	/*
          * The Linux code now honours the rules the MO people set and
@@ -1716,3 +1715,5 @@
 	return len;
 }
 #endif
+
+EXPORT_SYMBOL(ide_xlate_handler);
diff -uNr linux-PLD/drivers/block/ide-geometry.c linux/drivers/block/ide-geometry.c
--- linux-PLD/drivers/block/ide-geometry.c	Tue Oct  3 18:38:40 2000
+++ linux/drivers/block/ide-geometry.c	Tue Oct  3 22:53:48 2000
@@ -1,85 +1,8 @@
 /*
  * linux/drivers/ide/ide-geometry.c
  */
-#include <linux/config.h>
 #include <linux/ide.h>
-#include <asm/io.h>
-
-/*
- * We query CMOS about hard disks : it could be that we have a SCSI/ESDI/etc
- * controller that is BIOS compatible with ST-506, and thus showing up in our
- * BIOS table, but not register compatible, and therefore not present in CMOS.
- *
- * Furthermore, we will assume that our ST-506 drives <if any> are the primary
- * drives in the system -- the ones reflected as drive 1 or 2.  The first
- * drive is stored in the high nibble of CMOS byte 0x12, the second in the low
- * nibble.  This will be either a 4 bit drive type or 0xf indicating use byte
- * 0x19 for an 8 bit type, drive 1, 0x1a for drive 2 in CMOS.  A non-zero value
- * means we have an AT controller hard disk for that drive.
- *
- * Of course, there is no guarantee that either drive is actually on the
- * "primary" IDE interface, but we don't bother trying to sort that out here.
- * If a drive is not actually on the primary interface, then these parameters
- * will be ignored.  This results in the user having to supply the logical
- * drive geometry as a boot parameter for each drive not on the primary i/f.
- */
-/*
- * The only "perfect" way to handle this would be to modify the setup.[cS] code
- * to do BIOS calls Int13h/Fn08h and Int13h/Fn48h to get all of the drive info
- * for us during initialization.  I have the necessary docs -- any takers?  -ml
- */
-/*
- * I did this, but it doesnt work - there is no reasonable way to find the
- * correspondence between the BIOS numbering of the disks and the Linux
- * numbering. -aeb
- *
- * The code below is bad. One of the problems is that drives 1 and 2
- * may be SCSI disks (even when IDE disks are present), so that
- * the geometry we read here from BIOS is attributed to the wrong disks.
- * Consequently, also the former "drive->present = 1" below was a mistake.
- *
- * Eventually the entire routine below should be removed.
- */
-void probe_cmos_for_drives (ide_hwif_t *hwif)
-{
-#ifdef __i386__
-	extern struct drive_info_struct drive_info;
-	byte cmos_disks, *BIOS = (byte *) &drive_info;
-	int unit;
-
-#ifdef CONFIG_BLK_DEV_PDC4030
-	if (hwif->chipset == ide_pdc4030 && hwif->channel != 0)
-		return;
-#endif /* CONFIG_BLK_DEV_PDC4030 */
-	outb_p(0x12,0x70);		/* specify CMOS address 0x12 */
-	cmos_disks = inb_p(0x71);	/* read the data from 0x12 */
-	/* Extract drive geometry from CMOS+BIOS if not already setup */
-	for (unit = 0; unit < MAX_DRIVES; ++unit) {
-		ide_drive_t *drive = &hwif->drives[unit];
-
-		if ((cmos_disks & (0xf0 >> (unit*4)))
-		   && !drive->present && !drive->nobios) {
-			unsigned short cyl = *(unsigned short *)BIOS;
-			unsigned char head = *(BIOS+2);
-			unsigned char sect = *(BIOS+14);
-			if (cyl > 0 && head > 0 && sect > 0 && sect < 64) {
-				drive->cyl   = drive->bios_cyl  = cyl;
-				drive->head  = drive->bios_head = head;
-				drive->sect  = drive->bios_sect = sect;
-				drive->ctl   = *(BIOS+8);
-			} else {
-				printk("hd%d: C/H/S=%d/%d/%d from BIOS ignored\n",
-				       unit, cyl, head, sect);
-			}
-		}
-
-		BIOS += 16;
-	}
-#endif
-}
-
-
-#ifdef CONFIG_BLK_DEV_IDE
+#include <linux/ide-geometry.h>
 
 extern ide_drive_t * get_info_ptr(kdev_t);
 extern unsigned long current_capacity (ide_drive_t *);
@@ -118,6 +41,7 @@
 	*c = total / (63 * headp[0]);
 }
 
+
 /*
  * This routine is called from the partition-table code in pt/msdos.c.
  * It has two tasks:
@@ -211,4 +135,3 @@
 		       drive->bios_cyl, drive->bios_head, drive->bios_sect);
 	return ret;
 }
-#endif /* CONFIG_BLK_DEV_IDE */
diff -uNr linux-PLD/drivers/block/ide-probe.c linux/drivers/block/ide-probe.c
--- linux-PLD/drivers/block/ide-probe.c	Tue Oct  3 18:38:40 2000
+++ linux/drivers/block/ide-probe.c	Tue Oct  3 22:53:48 2000
@@ -431,6 +431,79 @@
 	return(region_errors);
 }
 
+/*
+ * We query CMOS about hard disks : it could be that we have a SCSI/ESDI/etc
+ * controller that is BIOS compatible with ST-506, and thus showing up in our
+ * BIOS table, but not register compatible, and therefore not present in CMOS.
+ *
+ * Furthermore, we will assume that our ST-506 drives <if any> are the primary
+ * drives in the system -- the ones reflected as drive 1 or 2.  The first
+ * drive is stored in the high nibble of CMOS byte 0x12, the second in the low
+ * nibble.  This will be either a 4 bit drive type or 0xf indicating use byte
+ * 0x19 for an 8 bit type, drive 1, 0x1a for drive 2 in CMOS.  A non-zero value
+ * means we have an AT controller hard disk for that drive.
+ *
+ * Of course, there is no guarantee that either drive is actually on the
+ * "primary" IDE interface, but we don't bother trying to sort that out here.
+ * If a drive is not actually on the primary interface, then these parameters
+ * will be ignored.  This results in the user having to supply the logical
+ * drive geometry as a boot parameter for each drive not on the primary i/f.
+ */
+/*
+ * The only "perfect" way to handle this would be to modify the setup.[cS] code
+ * to do BIOS calls Int13h/Fn08h and Int13h/Fn48h to get all of the drive info
+ * for us during initialization.  I have the necessary docs -- any takers?  -ml
+ */
+/*
+ * I did this, but it doesnt work - there is no reasonable way to find the
+ * correspondence between the BIOS numbering of the disks and the Linux
+ * numbering. -aeb
+ *
+ * The code below is bad. One of the problems is that drives 1 and 2
+ * may be SCSI disks (even when IDE disks are present), so that
+ * the geometry we read here from BIOS is attributed to the wrong disks.
+ * Consequently, also the former "drive->present = 1" below was a mistake.
+ *
+ * Eventually the entire routine below should be removed.
+ */
+static void probe_cmos_for_drives (ide_hwif_t *hwif)
+{
+#ifdef __i386__
+	extern struct drive_info_struct drive_info;
+	byte cmos_disks, *BIOS = (byte *) &drive_info;
+	int unit;
+
+#ifdef CONFIG_BLK_DEV_PDC4030
+	if (hwif->chipset == ide_pdc4030 && hwif->channel != 0)
+		return;
+#endif /* CONFIG_BLK_DEV_PDC4030 */
+	outb_p(0x12,0x70);		/* specify CMOS address 0x12 */
+	cmos_disks = inb_p(0x71);	/* read the data from 0x12 */
+	/* Extract drive geometry from CMOS+BIOS if not already setup */
+	for (unit = 0; unit < MAX_DRIVES; ++unit) {
+		ide_drive_t *drive = &hwif->drives[unit];
+
+		if ((cmos_disks & (0xf0 >> (unit*4)))
+		   && !drive->present && !drive->nobios) {
+			unsigned short cyl = *(unsigned short *)BIOS;
+			unsigned char head = *(BIOS+2);
+			unsigned char sect = *(BIOS+14);
+			if (cyl > 0 && head > 0 && sect > 0 && sect < 64) {
+				drive->cyl   = drive->bios_cyl  = cyl;
+				drive->head  = drive->bios_head = head;
+				drive->sect  = drive->bios_sect = sect;
+				drive->ctl   = *(BIOS+8);
+			} else {
+				printk("hd%d: C/H/S=%d/%d/%d from BIOS ignored\n",
+				       unit, cyl, head, sect);
+			}
+		}
+
+		BIOS += 16;
+	}
+#endif
+}
+
 static void hwif_register (ide_hwif_t *hwif)
 {
 	if ((hwif->io_ports[IDE_DATA_OFFSET] | 7) ==
@@ -477,8 +550,6 @@
 	if (hwif->noprobe)
 		return;
 	if (hwif->io_ports[IDE_DATA_OFFSET] == HD_DATA) {
-		extern void probe_cmos_for_drives(ide_hwif_t *);
-
 		probe_cmos_for_drives (hwif);
 	}
 
diff -uNr linux-PLD/drivers/block/ide.c linux/drivers/block/ide.c
--- linux-PLD/drivers/block/ide.c	Tue Oct  3 18:38:41 2000
+++ linux/drivers/block/ide.c	Tue Oct  3 20:35:17 2000
@@ -139,6 +139,7 @@
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/ide.h>
+#include <linux/ide-geometry.h>
 
 #include <asm/byteorder.h>
 #include <asm/irq.h>
@@ -1904,6 +1905,7 @@
 {
 	memset(rq, 0, sizeof(*rq));
 	rq->cmd = IDE_DRIVE_TASK_NO_DATA;
+	ide_xlate_handler = &ide_xlate_1024;
 }
 
 /*
@@ -4163,6 +4165,7 @@
 	for (index = 0; index < MAX_HWIFS; ++index)
 		ide_unregister(index);
 
+	ide_xlate_handler = NULL;
 #ifdef CONFIG_PROC_FS
 	proc_ide_destroy();
 #endif
diff -uNr linux-PLD/include/linux/ide-geometry.h linux/include/linux/ide-geometry.h
--- linux-PLD/include/linux/ide-geometry.h	Thu Jan  1 01:00:00 1970
+++ linux/include/linux/ide-geometry.h	Tue Oct  3 19:34:02 2000
@@ -0,0 +1,4 @@
+
+typedef int (idexlatefunc_t)(kdev_t, int, int, const char *);
+
+extern idexlatefunc_t  *ide_xlate_handler;




Więcej informacji o liście dyskusyjnej pld-devel-pl