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