------_=_NextPart_000_01BE8B67.3CF84AF0
Content-Type: text/plain
There is a mail in Linux Gazette #39 from a user with a similar problem -
his hdc drive, formerly hda and partitioned with <inferior OS>, is no longer
handled correctly by fdisk now that it's hdc. This strikes me as (dare I
say it) not far removed from a bug.
As a start to clearing this up, I propose the attached code fragment.
Sorry, please be patient, I'm a total kernel newbie, I just got into all
this to try and fix a problem on my machine. No doubt there is some
protocol for submitting code, which I am failing to respect. Please tell me
gently what I need to do !
The attached fragment goes into setup.S (in 2.0.36 or 2.2.1, anyway) between
"call video" and the MCA detection code, replacing the existing code at the
place where the initial comment is currently "Get hd0 data". I would submit
diff output, but it would end up being specific to one version of setup.S, I
think.
The fragment is a functional replacement for the current code, but using INT
13h calls, so it (a) works around a bug in at least one BIOS (mine !)
whereby the INT 41h vector isn't pointing to the right disk's info, and (b)
can be readily expanded to handle any number of drives, provided only that
some space in INITSEG can be negotiated. This takes up Mark Lord's
challenge in the comment on the function probe_cmos_for_drives() in
ide-probe.c.
---------------------------------------------------------------
|\ | o _ |/ Life's like a jigsaw
| \| | |_ |\ You get the straight bits
But there's something missing in the middle
Nick Brown, Strasbourg, France (Nick(dot)Brown(at)coe(dot)fr)
---------------------------------------------------------------
<<setup.S.frag>>
------_=_NextPart_000_01BE8B67.3CF84AF0
Content-Type: application/octet-stream;
name="setup.S.frag"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="setup.S.frag"
Content-Location: ATT-0-3394F01F5EF6D211B03B0020484016FF-S
ETUPS%7E1.FRA
!++=0A=
! Modified 1999-04-20 Nick Brown (Nick.Brown@coe.fr)=0A=
! Get data about first and second IDE drives from BIOS. This will =
later be=0A=
! used in ide-probe.c (2.2.x) or ide.c (2.0.x),=0A=
! Because on some BIOSes (specifically, mine) the INT 41h vector =
does=0A=
! not point to the correct fixed disk parameter (FDP) table (in my =
case=0A=
! it points to the data for the first SCSI drive), we make a call =
to=0A=
! INT 13h to get the disk info and build a simulation of the FDP =
table.=0A=
! This could easily be expanded for more drives, except that I don't =
know=0A=
! whereabouts in INITSEG to put the data. At that point, it would =
also be=0A=
! a good idea to review the routine probe_cmos_for_drives() in =
ide-probe.c.=0A=
! (We only use 5 bytes per drive, so we could fit 6 drives into the =
current=0A=
! INITSEG space of 32 bytes if we rearranged things.)=0A=
!=0A=
mov ax,cs ! aka #SETUPSEG=0A=
sub ax,#DELTA_INITSEG ! aka #INITSEG=0A=
mov es,ax ! ES:DI is now target address=0A=
xor bl,bl ! drive index=0A=
mov di,#0x0080 ! target address for first drive's data=0A=
loop_ide_parm:=0A=
push di ! some BIOSes zap these on INT 0x13 AH=3D0x08...=0A=
push es ! ... as do we, right here (well, DI anyway)=0A=
mov cx,#0x0008 ! zero 8 words (quicker than 16 bytes :-) )...=0A=
xor ax,ax ! ... in case we don't find any disk data...=0A=
cld ! ... and also to simulate empty FDP fields=0A=
rep=0A=
stosw=0A=
!=0A=
mov dl,bl ! build drive number...=0A=
add dl,#0x80 ! ... offset from base of 0x80=0A=
mov ah,#0x08 ! get drive info=0A=
int 0x13 ! BIOS disk service=0A=
pop es ! retrieve...=0A=
pop di ! ... target buffer address=0A=
jc next_ide_parm ! go if BIOS call produced an error=0A=
!=0A=
! We got some info about a drive; convert it to FDP table format.=0A=
!=0A=
mov al, ch ! low 8 bits of cylinder count=0A=
mov ah, cl ! high 2 bits of cylinder count...=0A=
shr ah, 6 ! ... now snuggle up against low bits in AX=0A=
seg es=0A=
mov (di),ax ! simulate FDP entry for cylinders=0A=
seg es=0A=
mov (di+2),dh ! simulate FDP entry for head=0A=
and cl,#0x3f ! (sector is in low 6 bits)=0A=
seg es=0A=
mov (di+14),cl ! simulate FDP entry for sector=0A=
xor bh,bh ! build up control byte in BH=0A=
cmp dh,#8 ! more than 8 heads ?=0A=
jc ok_heads_8 ! go if not=0A=
or bh,#0x08 ! if more than 8 heads, set this bit=0A=
ok_heads_8:=0A=
seg es=0A=
mov (di+8),bh ! simulate FDP entry for control byte=0A=
!=0A=
! Come here after processing info (successfully or otherwise) for one =
drive.=0A=
!=0A=
next_ide_parm:=0A=
add di,#16 ! point past this drive's buffer=0A=
inc bl ! done one more drive=0A=
cmp bl,#2 ! have we reached our limit ?=0A=
jc loop_ide_parm ! no, go for next drive=0A=
!--=0A=
------_=_NextPart_000_01BE8B67.3CF84AF0--
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/