VirtualBox

source: vbox/trunk/src/VBox/Devices/PC/BIOS/ata.c@ 76553

Last change on this file since 76553 was 76553, checked in by vboxsync, 6 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 40.1 KB
Line 
1/* $Id: ata.c 76553 2019-01-01 01:45:53Z vboxsync $ */
2/** @file
3 * PC BIOS - ???
4 */
5
6/*
7 * Copyright (C) 2006-2019 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 * --------------------------------------------------------------------
17 *
18 * This code is based on:
19 *
20 * ROM BIOS for use with Bochs/Plex86/QEMU emulation environment
21 *
22 * Copyright (C) 2002 MandrakeSoft S.A.
23 *
24 * MandrakeSoft S.A.
25 * 43, rue d'Aboukir
26 * 75002 Paris - France
27 * http://www.linux-mandrake.com/
28 * http://www.mandrakesoft.com/
29 *
30 * This library is free software; you can redistribute it and/or
31 * modify it under the terms of the GNU Lesser General Public
32 * License as published by the Free Software Foundation; either
33 * version 2 of the License, or (at your option) any later version.
34 *
35 * This library is distributed in the hope that it will be useful,
36 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
38 * Lesser General Public License for more details.
39 *
40 * You should have received a copy of the GNU Lesser General Public
41 * License along with this library; if not, write to the Free Software
42 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
43 *
44 */
45
46/*
47 * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
48 * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
49 * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
50 * a choice of LGPL license versions is made available with the language indicating
51 * that LGPLv2 or any later version may be used, or where a choice of which version
52 * of the LGPL is applied is otherwise unspecified.
53 */
54
55
56#include <stdint.h>
57#include <stdarg.h>
58#include "inlines.h"
59#include "biosint.h"
60#include "ebda.h"
61#include "ata.h"
62
63#if DEBUG_ATA
64# define BX_DEBUG_ATA(...) BX_DEBUG(__VA_ARGS__)
65#else
66# define BX_DEBUG_ATA(...)
67#endif
68
69
70// ---------------------------------------------------------------------------
71// Start of ATA/ATAPI Driver
72// ---------------------------------------------------------------------------
73
74void insw_discard(unsigned nwords, unsigned port);
75#pragma aux insw_discard = \
76 ".286" \
77 "again:" \
78 "in ax,dx" \
79 "loop again" \
80 parm [cx] [dx] modify exact [cx ax] nomemory;
81
82void insd_discard(unsigned ndwords, unsigned port);
83#if VBOX_BIOS_CPU >= 80386
84# pragma aux insd_discard = \
85 ".386" \
86 "push eax" \
87 "again:" \
88 "in eax,dx" \
89 "loop again" \
90 "pop eax" \
91 parm [cx] [dx] modify exact [cx] nomemory;
92#endif
93
94// ---------------------------------------------------------------------------
95// ATA/ATAPI driver : initialization
96// ---------------------------------------------------------------------------
97void BIOSCALL ata_init(void)
98{
99 uint8_t channel, device;
100 bio_dsk_t __far *bios_dsk;
101
102 bios_dsk = read_word(0x0040, 0x000E) :> &EbdaData->bdisk;
103
104 // Channels info init.
105 for (channel=0; channel<BX_MAX_ATA_INTERFACES; channel++) {
106 bios_dsk->channels[channel].iface = ATA_IFACE_NONE;
107 bios_dsk->channels[channel].iobase1 = 0x0;
108 bios_dsk->channels[channel].iobase2 = 0x0;
109 bios_dsk->channels[channel].irq = 0;
110 }
111
112 // Devices info init.
113 for (device=0; device<BX_MAX_ATA_DEVICES; device++) {
114 bios_dsk->devices[device].type = DSK_TYPE_NONE;
115 bios_dsk->devices[device].device = DSK_DEVICE_NONE;
116 bios_dsk->devices[device].removable = 0;
117 bios_dsk->devices[device].lock = 0;
118 bios_dsk->devices[device].mode = ATA_MODE_NONE;
119 bios_dsk->devices[device].blksize = 0x200;
120 bios_dsk->devices[device].translation = GEO_TRANSLATION_NONE;
121 bios_dsk->devices[device].lchs.heads = 0;
122 bios_dsk->devices[device].lchs.cylinders = 0;
123 bios_dsk->devices[device].lchs.spt = 0;
124 bios_dsk->devices[device].pchs.heads = 0;
125 bios_dsk->devices[device].pchs.cylinders = 0;
126 bios_dsk->devices[device].pchs.spt = 0;
127 bios_dsk->devices[device].sectors = 0;
128 }
129
130 // hdidmap and cdidmap init.
131 for (device=0; device<BX_MAX_STORAGE_DEVICES; device++) {
132 bios_dsk->hdidmap[device] = BX_MAX_STORAGE_DEVICES;
133 bios_dsk->cdidmap[device] = BX_MAX_STORAGE_DEVICES;
134 }
135
136 bios_dsk->hdcount = 0;
137 bios_dsk->cdcount = 0;
138}
139
140// ---------------------------------------------------------------------------
141// ATA/ATAPI driver : software reset
142// ---------------------------------------------------------------------------
143// ATA-3
144// 8.2.1 Software reset - Device 0
145
146void ata_reset(uint16_t device)
147{
148 uint16_t iobase1, iobase2;
149 uint8_t channel, slave, sn, sc;
150 uint16_t max;
151 uint16_t pdelay;
152 bio_dsk_t __far *bios_dsk;
153
154 bios_dsk = read_word(0x0040, 0x000E) :> &EbdaData->bdisk;
155 channel = device / 2;
156 slave = device % 2;
157
158 iobase1 = bios_dsk->channels[channel].iobase1;
159 iobase2 = bios_dsk->channels[channel].iobase2;
160
161 // Reset
162
163 // 8.2.1 (a) -- set SRST in DC
164 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN | ATA_CB_DC_SRST);
165
166 // 8.2.1 (b) -- wait for BSY
167 max=0xff;
168 while(--max>0) {
169 uint8_t status = inb(iobase1+ATA_CB_STAT);
170 if ((status & ATA_CB_STAT_BSY) != 0)
171 break;
172 }
173
174 // 8.2.1 (f) -- clear SRST
175 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN);
176
177 if (bios_dsk->devices[device].type != DSK_TYPE_NONE) {
178 // 8.2.1 (g) -- check for sc==sn==0x01
179 // select device
180 outb(iobase1+ATA_CB_DH, slave?ATA_CB_DH_DEV1:ATA_CB_DH_DEV0);
181 sc = inb(iobase1+ATA_CB_SC);
182 sn = inb(iobase1+ATA_CB_SN);
183
184 if ( (sc==0x01) && (sn==0x01) ) {
185 // 8.2.1 (h) -- wait for not BSY
186 max=0xffff; /* The ATA specification says that the drive may be busy for up to 30 seconds. */
187 while(--max>0) {
188 uint8_t status = inb(iobase1+ATA_CB_STAT);
189 if ((status & ATA_CB_STAT_BSY) == 0)
190 break;
191 pdelay=0xffff;
192 while (--pdelay>0) {
193 /* nothing */
194 }
195 }
196 }
197 }
198
199 // 8.2.1 (i) -- wait for DRDY
200 max = 0x10; /* Speed up for virtual drives. Disks are immediately ready, CDs never */
201 while(--max>0) {
202 uint8_t status = inb(iobase1+ATA_CB_STAT);
203 if ((status & ATA_CB_STAT_RDY) != 0)
204 break;
205 }
206
207 // Enable interrupts
208 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
209}
210
211// ---------------------------------------------------------------------------
212// ATA/ATAPI driver : execute a data-in command
213// ---------------------------------------------------------------------------
214 // returns
215 // 0 : no error
216 // 1 : BUSY bit set
217 // 2 : read error
218 // 3 : expected DRQ=1
219 // 4 : no sectors left to read/verify
220 // 5 : more sectors to read/verify
221 // 6 : no sectors left to write
222 // 7 : more sectors to write
223uint16_t ata_cmd_data_in(bio_dsk_t __far *bios_dsk, uint16_t command, uint16_t count)
224{
225 uint16_t iobase1, iobase2, blksize, mult_blk_cnt;
226 uint16_t cylinder;
227 uint8_t head;
228 uint8_t sector;
229 uint8_t device;
230 uint8_t status, mode;
231 char __far *buffer;
232
233 device = bios_dsk->drqp.dev_id;
234
235 iobase1 = bios_dsk->channels[device / 2].iobase1;
236 iobase2 = bios_dsk->channels[device / 2].iobase2;
237 mode = bios_dsk->devices[device].mode;
238 blksize = bios_dsk->devices[device].blksize;
239 if (blksize == 0) { /* If transfer size is exactly 64K */
240#if VBOX_BIOS_CPU >= 80386
241 if (mode == ATA_MODE_PIO32)
242 blksize = 0x4000;
243 else
244#endif
245 blksize = 0x8000;
246 } else {
247#if VBOX_BIOS_CPU >= 80386
248 if (mode == ATA_MODE_PIO32)
249 blksize >>= 2;
250 else
251#endif
252 blksize >>= 1;
253 }
254
255 status = inb(iobase1 + ATA_CB_STAT);
256 if (status & ATA_CB_STAT_BSY)
257 {
258 BX_DEBUG_ATA("%s: disk busy\n", __func__);
259 // Enable interrupts
260 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
261 return 1;
262 }
263
264 buffer = bios_dsk->drqp.buffer;
265 sector = bios_dsk->drqp.sector;
266 cylinder = bios_dsk->drqp.cylinder;
267 head = bios_dsk->drqp.head;
268
269 // sector will be 0 only on lba access. Convert to lba-chs
270 if (sector == 0) {
271 if (bios_dsk->drqp.lba + count >= 268435456)
272 {
273 sector = (bios_dsk->drqp.lba >> 24) & 0x00ff;
274 cylinder = (bios_dsk->drqp.lba >> 32) & 0xffff;
275 outb(iobase1 + ATA_CB_SC, (count & 0xff00) >> 8);
276 outb(iobase1 + ATA_CB_SN, sector);
277 outb(iobase1 + ATA_CB_CL, cylinder & 0x00ff);
278 outb(iobase1 + ATA_CB_CH, cylinder >> 8);
279 /* Leave the bottom 24 bits as is, they are treated correctly by the
280 * LBA28 code path. */
281 }
282 sector = bios_dsk->drqp.lba & 0x000000ffL;
283 cylinder = (bios_dsk->drqp.lba >> 8) & 0x0000ffffL;
284 head = ((bios_dsk->drqp.lba >> 24) & 0x0000000fL) | 0x40;
285 }
286
287 outb(iobase2 + ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN);
288 outb(iobase1 + ATA_CB_FR, 0x00);
289 outb(iobase1 + ATA_CB_SC, count);
290 outb(iobase1 + ATA_CB_SN, sector);
291 outb(iobase1 + ATA_CB_CL, cylinder & 0x00ff);
292 outb(iobase1 + ATA_CB_CH, cylinder >> 8);
293 outb(iobase1 + ATA_CB_DH, ((device & 1) ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0) | head );
294 outb(iobase1 + ATA_CB_CMD, command);
295
296 if (command == ATA_CMD_READ_MULTIPLE || command == ATA_CMD_READ_MULTIPLE_EXT) {
297 mult_blk_cnt = count;
298 count = 1;
299 } else {
300 mult_blk_cnt = 1;
301 }
302
303 while (1) {
304 status = inb(iobase1 + ATA_CB_STAT);
305 if ( !(status & ATA_CB_STAT_BSY) )
306 break;
307 }
308
309 if (status & ATA_CB_STAT_ERR) {
310 BX_DEBUG_ATA("%s: read error\n", __func__);
311 // Enable interrupts
312 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
313 return 2;
314 } else if ( !(status & ATA_CB_STAT_DRQ) ) {
315 BX_DEBUG_ATA("%s: DRQ not set (status %02x)\n", __func__, (unsigned) status);
316 // Enable interrupts
317 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
318 return 3;
319 }
320
321 // FIXME : move seg/off translation here
322
323 int_enable(); // enable higher priority interrupts
324
325 while (1) {
326
327 // adjust if there will be an overrun. 2K max sector size
328 if (FP_OFF(buffer) >= 0xF800)
329 buffer = MK_FP(FP_SEG(buffer) + 0x80, FP_OFF(buffer) - 0x800);
330
331#if VBOX_BIOS_CPU >= 80386
332 if (mode == ATA_MODE_PIO32)
333 buffer = rep_insd(buffer, blksize, iobase1);
334 else
335#endif
336 buffer = rep_insw(buffer, blksize, iobase1);
337 bios_dsk->drqp.trsfsectors += mult_blk_cnt;
338 count--;
339 while (1) {
340 status = inb(iobase1 + ATA_CB_STAT);
341 if ( !(status & ATA_CB_STAT_BSY) )
342 break;
343 }
344 if (count == 0) {
345 if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) )
346 != ATA_CB_STAT_RDY ) {
347 BX_DEBUG_ATA("%s: no sectors left (status %02x)\n", __func__, (unsigned) status);
348 // Enable interrupts
349 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
350 return 4;
351 }
352 break;
353 }
354 else {
355 if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) )
356 != (ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ) ) {
357 BX_DEBUG_ATA("%s: more sectors left (status %02x)\n", __func__, (unsigned) status);
358 // Enable interrupts
359 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
360 return 5;
361 }
362 continue;
363 }
364 }
365 // Enable interrupts
366 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
367 return 0;
368}
369
370// ---------------------------------------------------------------------------
371// ATA/ATAPI driver : device detection
372// ---------------------------------------------------------------------------
373
374void BIOSCALL ata_detect(void)
375{
376 uint16_t ebda_seg = read_word(0x0040,0x000E);
377 uint8_t hdcount, cdcount, device, type;
378 uint8_t buffer[0x0200];
379 bio_dsk_t __far *bios_dsk;
380
381 bios_dsk = ebda_seg :> &EbdaData->bdisk;
382
383#if BX_MAX_ATA_INTERFACES > 0
384 bios_dsk->channels[0].iface = ATA_IFACE_ISA;
385 bios_dsk->channels[0].iobase1 = 0x1f0;
386 bios_dsk->channels[0].iobase2 = 0x3f0;
387 bios_dsk->channels[0].irq = 14;
388#endif
389#if BX_MAX_ATA_INTERFACES > 1
390 bios_dsk->channels[1].iface = ATA_IFACE_ISA;
391 bios_dsk->channels[1].iobase1 = 0x170;
392 bios_dsk->channels[1].iobase2 = 0x370;
393 bios_dsk->channels[1].irq = 15;
394#endif
395#if 0 /// @todo - temporarily removed to avoid conflict with AHCI
396#if BX_MAX_ATA_INTERFACES > 2
397 bios_dsk->channels[2].iface = ATA_IFACE_ISA;
398 bios_dsk->channels[2].iobase1 = 0x1e8;
399 bios_dsk->channels[2].iobase2 = 0x3e0;
400 bios_dsk->channels[2].irq = 12;
401#endif
402#if BX_MAX_ATA_INTERFACES > 3
403 bios_dsk->channels[3].iface = ATA_IFACE_ISA;
404 bios_dsk->channels[3].iobase1 = 0x168;
405 bios_dsk->channels[3].iobase2 = 0x360;
406 bios_dsk->channels[3].irq = 11;
407#endif
408#endif
409#if BX_MAX_ATA_INTERFACES > 4
410#error Please fill the ATA interface informations
411#endif
412
413 // Device detection
414 hdcount = cdcount = 0;
415
416 for (device = 0; device < BX_MAX_ATA_DEVICES; device++) {
417 uint16_t iobase1, iobase2;
418 uint8_t channel, slave;
419 uint8_t sc, sn, cl, ch, st;
420
421 channel = device / 2;
422 slave = device % 2;
423
424 iobase1 = bios_dsk->channels[channel].iobase1;
425 iobase2 = bios_dsk->channels[channel].iobase2;
426
427 // Disable interrupts
428 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN);
429
430 // Look for device
431 outb(iobase1+ATA_CB_DH, slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0);
432 outb(iobase1+ATA_CB_SC, 0x55);
433 outb(iobase1+ATA_CB_SN, 0xaa);
434 outb(iobase1+ATA_CB_SC, 0xaa);
435 outb(iobase1+ATA_CB_SN, 0x55);
436 outb(iobase1+ATA_CB_SC, 0x55);
437 outb(iobase1+ATA_CB_SN, 0xaa);
438
439 // If we found something
440 sc = inb(iobase1+ATA_CB_SC);
441 sn = inb(iobase1+ATA_CB_SN);
442
443 if ( (sc == 0x55) && (sn == 0xaa) ) {
444 bios_dsk->devices[device].type = DSK_TYPE_UNKNOWN;
445
446 // reset the channel
447 ata_reset(device);
448
449 // check for ATA or ATAPI
450 outb(iobase1+ATA_CB_DH, slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0);
451 sc = inb(iobase1+ATA_CB_SC);
452 sn = inb(iobase1+ATA_CB_SN);
453 if ((sc==0x01) && (sn==0x01)) {
454 cl = inb(iobase1+ATA_CB_CL);
455 ch = inb(iobase1+ATA_CB_CH);
456 st = inb(iobase1+ATA_CB_STAT);
457
458 if ((cl==0x14) && (ch==0xeb)) {
459 bios_dsk->devices[device].type = DSK_TYPE_ATAPI;
460 } else if ((cl==0x00) && (ch==0x00) && (st!=0x00)) {
461 bios_dsk->devices[device].type = DSK_TYPE_ATA;
462 } else if ((cl==0xff) && (ch==0xff)) {
463 bios_dsk->devices[device].type = DSK_TYPE_NONE;
464 }
465 }
466 }
467
468 // Enable interrupts
469 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
470
471 type = bios_dsk->devices[device].type;
472
473 // Now we send a IDENTIFY command to ATA device
474 if (type == DSK_TYPE_ATA) {
475 uint64_t sectors;
476 uint16_t cylinders, heads, spt, blksize;
477 chs_t lgeo;
478 uint8_t chsgeo_base;
479 uint8_t removable, mode;
480
481 //Temporary values to do the transfer
482 bios_dsk->devices[device].device = DSK_DEVICE_HD;
483 bios_dsk->devices[device].mode = ATA_MODE_PIO16;
484 bios_dsk->drqp.buffer = buffer;
485 bios_dsk->drqp.dev_id = device;
486
487 if (ata_cmd_data_in(bios_dsk, ATA_CMD_IDENTIFY_DEVICE, 1) !=0 )
488 BX_PANIC("ata-detect: Failed to detect ATA device\n");
489
490 removable = (*(buffer+0) & 0x80) ? 1 : 0;
491#if VBOX_BIOS_CPU >= 80386
492 mode = *(buffer+96) ? ATA_MODE_PIO32 : ATA_MODE_PIO16;
493#else
494 mode = ATA_MODE_PIO16;
495#endif
496 blksize = 512; /* There is no sector size field any more. */
497
498 cylinders = *(uint16_t *)(buffer+(1*2)); // word 1
499 heads = *(uint16_t *)(buffer+(3*2)); // word 3
500 spt = *(uint16_t *)(buffer+(6*2)); // word 6
501
502 sectors = *(uint32_t *)(buffer+(60*2)); // word 60 and word 61
503 if (sectors == 0x0FFFFFFF) /* For disks bigger than ~128GB */
504 sectors = *(uint64_t *)(buffer+(100*2)); // words 100 to 103
505 switch (device)
506 {
507 case 0:
508 chsgeo_base = 0x1e;
509 break;
510 case 1:
511 chsgeo_base = 0x26;
512 break;
513 case 2:
514 chsgeo_base = 0x67;
515 break;
516 case 3:
517 chsgeo_base = 0x70;
518 break;
519 default:
520 chsgeo_base = 0;
521 }
522 if (chsgeo_base)
523 {
524 lgeo.cylinders = inb_cmos(chsgeo_base) + (inb_cmos(chsgeo_base + 1) << 8);
525 lgeo.heads = inb_cmos(chsgeo_base + 2);
526 lgeo.spt = inb_cmos(chsgeo_base + 7);
527 }
528 else
529 set_geom_lba(&lgeo, sectors); /* Default EDD-style translated LBA geometry. */
530
531 BX_INFO("ata%d-%d: PCHS=%u/%u/%u LCHS=%u/%u/%u\n", channel, slave,
532 cylinders, heads, spt, lgeo.cylinders, lgeo.heads, lgeo.spt);
533
534 bios_dsk->devices[device].device = DSK_DEVICE_HD;
535 bios_dsk->devices[device].removable = removable;
536 bios_dsk->devices[device].mode = mode;
537 bios_dsk->devices[device].blksize = blksize;
538 bios_dsk->devices[device].pchs.heads = heads;
539 bios_dsk->devices[device].pchs.cylinders = cylinders;
540 bios_dsk->devices[device].pchs.spt = spt;
541 bios_dsk->devices[device].sectors = sectors;
542 bios_dsk->devices[device].lchs = lgeo;
543 if (device < 2)
544 {
545 uint8_t sum, i;
546 fdpt_t __far *fdpt;
547 void __far * __far *int_vec;
548
549 if (device == 0)
550 fdpt = ebda_seg :> &EbdaData->fdpt0;
551 else
552 fdpt = ebda_seg :> &EbdaData->fdpt1;
553
554#if 0
555 /* Place the FDPT outside of conventional memory. Needed for
556 * 286 XENIX 2.1.3/2.2.1 because it completely wipes out
557 * the EBDA and low memory. Hack!
558 */
559 fdpt = MK_FP(0xE200, 0xf00);
560 fdpt += device;
561#endif
562
563 /* Set the INT 41h or 46h pointer. */
564 int_vec = MK_FP(0, (0x41 + device * 5) * sizeof(void __far *));
565 *int_vec = fdpt;
566
567 /* Update the DPT for drive 0/1 pointed to by Int41/46. This used
568 * to be done at POST time with lots of ugly assembler code, which
569 * isn't worth the effort of converting from AMI to Award CMOS
570 * format. Just do it here. */
571 fdpt->resvd1 = fdpt->resvd2 = 0;
572
573 fdpt->lcyl = lgeo.cylinders;
574 fdpt->lhead = lgeo.heads;
575 fdpt->sig = 0xa0;
576 fdpt->spt = spt;
577 fdpt->cyl = cylinders;
578 fdpt->head = heads;
579 fdpt->lspt = lgeo.spt;
580 sum = 0;
581 for (i = 0; i < 0xf; i++)
582 sum += *((uint8_t __far *)fdpt + i);
583 sum = -sum;
584 fdpt->csum = sum;
585 }
586
587 // fill hdidmap
588 bios_dsk->hdidmap[hdcount] = device;
589 hdcount++;
590 }
591
592 // Now we send an IDENTIFY command to ATAPI device
593 if (type == DSK_TYPE_ATAPI) {
594 uint8_t type, removable, mode;
595 uint16_t blksize;
596
597 // Temporary values to do the transfer
598 bios_dsk->devices[device].device = DSK_DEVICE_CDROM;
599 bios_dsk->devices[device].mode = ATA_MODE_PIO16;
600 bios_dsk->drqp.buffer = buffer;
601 bios_dsk->drqp.dev_id = device;
602
603 if (ata_cmd_data_in(bios_dsk, ATA_CMD_IDENTIFY_PACKET, 1) != 0)
604 BX_PANIC("ata-detect: Failed to detect ATAPI device\n");
605
606 type = *(buffer+1) & 0x1f;
607 removable = (*(buffer+0) & 0x80) ? 1 : 0;
608#if VBOX_BIOS_CPU >= 80386
609 mode = *(buffer+96) ? ATA_MODE_PIO32 : ATA_MODE_PIO16;
610#else
611 mode = ATA_MODE_PIO16;
612#endif
613 blksize = 2048;
614
615 bios_dsk->devices[device].device = type;
616 bios_dsk->devices[device].removable = removable;
617 bios_dsk->devices[device].mode = mode;
618 bios_dsk->devices[device].blksize = blksize;
619
620 // fill cdidmap
621 bios_dsk->cdidmap[cdcount] = device;
622 cdcount++;
623 }
624
625 {
626 uint32_t sizeinmb;
627 uint16_t ataversion;
628 uint8_t version, model[41];
629 int i;
630
631 switch (type) {
632 case DSK_TYPE_ATA:
633 sizeinmb = (bios_dsk->devices[device].sectors >> 11);
634 case DSK_TYPE_ATAPI:
635 // Read ATA/ATAPI version
636 ataversion = ((uint16_t)(*(buffer+161))<<8) | *(buffer+160);
637 for (version = 15; version > 0; version--) {
638 if ((ataversion & (1 << version)) !=0 )
639 break;
640 }
641
642 // Read model name
643 for (i = 0; i < 20; i++ ) {
644 *(model+(i*2)) = *(buffer+(i*2)+54+1);
645 *(model+(i*2)+1) = *(buffer+(i*2)+54);
646 }
647
648 // Reformat
649 *(model+40) = 0x00;
650 for ( i = 39; i > 0; i-- ){
651 if (*(model+i) == 0x20)
652 *(model+i) = 0x00;
653 else
654 break;
655 }
656 break;
657 }
658
659#ifdef VBOXz
660 // we don't want any noisy output for now
661#else /* !VBOX */
662 switch (type) {
663 int c;
664 case DSK_TYPE_ATA:
665 printf("ata%d %s: ", channel, slave ? " slave" : "master");
666 i=0;
667 while(c=*(model+i++))
668 printf("%c", c);
669 printf(" ATA-%d Hard-Disk (%lu MBytes)\n", version, sizeinmb);
670 break;
671 case DSK_TYPE_ATAPI:
672 printf("ata%d %s: ", channel, slave ? " slave" : "master");
673 i=0;
674 while(c=*(model+i++))
675 printf("%c", c);
676 if (bios_dsk->devices[device].device == DSK_DEVICE_CDROM)
677 printf(" ATAPI-%d CD-ROM/DVD-ROM\n", version);
678 else
679 printf(" ATAPI-%d Device\n", version);
680 break;
681 case DSK_TYPE_UNKNOWN:
682 printf("ata%d %s: Unknown device\n", channel , slave ? " slave" : "master");
683 break;
684 }
685#endif /* !VBOX */
686 }
687 }
688
689 // Store the devices counts
690 bios_dsk->hdcount = hdcount;
691 bios_dsk->cdcount = cdcount;
692 write_byte(0x40,0x75, hdcount);
693
694#ifdef VBOX
695 // we don't want any noisy output for now
696#else /* !VBOX */
697 printf("\n");
698#endif /* !VBOX */
699
700 // FIXME : should use bios=cmos|auto|disable bits
701 // FIXME : should know about translation bits
702 // FIXME : move hard_drive_post here
703
704}
705
706// ---------------------------------------------------------------------------
707// ATA/ATAPI driver : execute a data-out command
708// ---------------------------------------------------------------------------
709 // returns
710 // 0 : no error
711 // 1 : BUSY bit set
712 // 2 : read error
713 // 3 : expected DRQ=1
714 // 4 : no sectors left to read/verify
715 // 5 : more sectors to read/verify
716 // 6 : no sectors left to write
717 // 7 : more sectors to write
718uint16_t ata_cmd_data_out(bio_dsk_t __far *bios_dsk, uint16_t command, uint16_t count)
719{
720 uint64_t lba;
721 char __far *buffer;
722 uint16_t iobase1, iobase2, blksize;
723 uint16_t cylinder;
724 uint16_t head;
725 uint16_t sector;
726 uint16_t device;
727 uint8_t channel, slave;
728 uint8_t status, mode;
729
730 device = bios_dsk->drqp.dev_id;
731 channel = device / 2;
732 slave = device % 2;
733
734 iobase1 = bios_dsk->channels[channel].iobase1;
735 iobase2 = bios_dsk->channels[channel].iobase2;
736 mode = bios_dsk->devices[device].mode;
737 blksize = 0x200; // was = bios_dsk->devices[device].blksize;
738#if VBOX_BIOS_CPU >= 80386
739 if (mode == ATA_MODE_PIO32)
740 blksize >>= 2;
741 else
742#endif
743 blksize >>= 1;
744
745 status = inb(iobase1 + ATA_CB_STAT);
746 if (status & ATA_CB_STAT_BSY)
747 {
748 // Enable interrupts
749 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
750 return 1;
751 }
752
753 lba = bios_dsk->drqp.lba;
754 buffer = bios_dsk->drqp.buffer;
755 sector = bios_dsk->drqp.sector;
756 cylinder = bios_dsk->drqp.cylinder;
757 head = bios_dsk->drqp.head;
758
759 // sector will be 0 only on lba access. Convert to lba-chs
760 if (sector == 0) {
761 if (lba + count >= 268435456)
762 {
763 sector = (lba >> 24) & 0x00ff;
764 cylinder = (lba >> 32) & 0xffff;
765 outb(iobase1 + ATA_CB_SC, (count & 0xff00) >> 8);
766 outb(iobase1 + ATA_CB_SN, sector);
767 outb(iobase1 + ATA_CB_CL, cylinder & 0x00ff);
768 outb(iobase1 + ATA_CB_CH, cylinder >> 8);
769 /* Leave the bottom 24 bits as is, they are treated correctly by the
770 * LBA28 code path. */
771 lba &= 0xffffff;
772 }
773 sector = (uint16_t) (lba & 0x000000ffL);
774 lba >>= 8;
775 cylinder = (uint16_t) (lba & 0x0000ffffL);
776 lba >>= 16;
777 head = ((uint16_t) (lba & 0x0000000fL)) | 0x40;
778 }
779
780 outb(iobase2 + ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN);
781 outb(iobase1 + ATA_CB_FR, 0x00);
782 outb(iobase1 + ATA_CB_SC, count);
783 outb(iobase1 + ATA_CB_SN, sector);
784 outb(iobase1 + ATA_CB_CL, cylinder & 0x00ff);
785 outb(iobase1 + ATA_CB_CH, cylinder >> 8);
786 outb(iobase1 + ATA_CB_DH, (slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0) | (uint8_t) head );
787 outb(iobase1 + ATA_CB_CMD, command);
788
789 while (1) {
790 status = inb(iobase1 + ATA_CB_STAT);
791 if ( !(status & ATA_CB_STAT_BSY) )
792 break;
793 }
794
795 if (status & ATA_CB_STAT_ERR) {
796 BX_DEBUG_ATA("%s: write error\n", __func__);
797 // Enable interrupts
798 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
799 return 2;
800 } else if ( !(status & ATA_CB_STAT_DRQ) ) {
801 BX_DEBUG_ATA("%s: DRQ not set (status %02x)\n", __func__, (unsigned) status);
802 // Enable interrupts
803 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
804 return 3;
805 }
806
807 // FIXME : move seg/off translation here
808
809 int_enable(); // enable higher priority interrupts
810
811 while (1) {
812
813 // adjust if there will be an overrun. 2K max sector size
814 if (FP_OFF(buffer) >= 0xF800)
815 buffer = MK_FP(FP_SEG(buffer) + 0x80, FP_OFF(buffer) - 0x800);
816
817#if VBOX_BIOS_CPU >= 80386
818 if (mode == ATA_MODE_PIO32)
819 buffer = rep_outsd(buffer, blksize, iobase1);
820 else
821#endif
822 buffer = rep_outsw(buffer, blksize, iobase1);
823
824 bios_dsk->drqp.trsfsectors++;
825 count--;
826 while (1) {
827 status = inb(iobase1 + ATA_CB_STAT);
828 if ( !(status & ATA_CB_STAT_BSY) )
829 break;
830 }
831 if (count == 0) {
832 if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DF | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) )
833 != ATA_CB_STAT_RDY ) {
834 BX_DEBUG_ATA("%s: no sectors left (status %02x)\n", __func__, (unsigned) status);
835 // Enable interrupts
836 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
837 return 6;
838 }
839 break;
840 }
841 else {
842 if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR) )
843 != (ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ) ) {
844 BX_DEBUG_ATA("%s: more sectors left (status %02x)\n", __func__, (unsigned) status);
845 // Enable interrupts
846 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
847 return 7;
848 }
849 continue;
850 }
851 }
852 // Enable interrupts
853 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
854 return 0;
855}
856
857
858/**
859 * Read sectors from an attached ATA device.
860 *
861 * @returns status code.
862 * @param bios_dsk Pointer to disk request packet (in the
863 * EBDA).
864 */
865int ata_read_sectors(bio_dsk_t __far *bios_dsk)
866{
867 uint16_t n_sect;
868 int status;
869 uint8_t device_id;
870
871 device_id = bios_dsk->drqp.dev_id;
872 n_sect = bios_dsk->drqp.nsect;
873
874 if (bios_dsk->drqp.sector) {
875 /* CHS addressing. */
876 bios_dsk->devices[device_id].blksize = n_sect * 0x200;
877 BX_DEBUG_ATA("%s: reading %u sectors (CHS)\n", __func__, n_sect);
878 status = ata_cmd_data_in(bios_dsk, ATA_CMD_READ_MULTIPLE, n_sect);
879 bios_dsk->devices[device_id].blksize = 0x200;
880 } else {
881 /* LBA addressing. */
882 if (bios_dsk->drqp.lba + n_sect >= 268435456) {
883 BX_DEBUG_ATA("%s: reading %u sector (LBA,EXT)\n", __func__, n_sect);
884 status = ata_cmd_data_in(bios_dsk, ATA_CMD_READ_SECTORS_EXT, n_sect);
885 } else {
886 bios_dsk->devices[device_id].blksize = n_sect * 0x200;
887 BX_DEBUG_ATA("%s: reading %u sector (LBA,MULT)\n", __func__, n_sect);
888 status = ata_cmd_data_in(bios_dsk, ATA_CMD_READ_MULTIPLE, n_sect);
889 bios_dsk->devices[device_id].blksize = 0x200;
890 }
891 }
892 return status;
893}
894
895/**
896 * Write sectors to an attached ATA device.
897 *
898 * @returns status code.
899 * @param bios_dsk Pointer to disk request packet (in the
900 * EBDA).
901 */
902int ata_write_sectors(bio_dsk_t __far *bios_dsk)
903{
904 uint16_t n_sect;
905
906 n_sect = bios_dsk->drqp.nsect;
907
908 if (bios_dsk->drqp.sector) {
909 /* CHS addressing. */
910 return ata_cmd_data_out(bios_dsk, ATA_CMD_WRITE_SECTORS, n_sect);
911 } else {
912 /* LBA addressing. */
913 if (bios_dsk->drqp.lba + n_sect >= 268435456)
914 return ata_cmd_data_out(bios_dsk, ATA_CMD_WRITE_SECTORS_EXT, n_sect);
915 else
916 return ata_cmd_data_out(bios_dsk, ATA_CMD_WRITE_SECTORS, n_sect);
917 }
918}
919
920
921// ---------------------------------------------------------------------------
922// ATA/ATAPI driver : execute a packet command
923// ---------------------------------------------------------------------------
924 // returns
925 // 0 : no error
926 // 1 : error in parameters
927 // 2 : BUSY bit set
928 // 3 : error
929 // 4 : not ready
930uint16_t ata_cmd_packet(uint16_t device, uint8_t cmdlen, char __far *cmdbuf,
931 uint16_t header, uint32_t length, uint8_t inout, char __far *buffer)
932{
933 uint16_t iobase1, iobase2;
934 uint16_t lcount, lbefore, lafter, count;
935 uint8_t channel, slave;
936 uint8_t status, mode, lmode;
937 uint32_t transfer;
938 bio_dsk_t __far *bios_dsk;
939
940 bios_dsk = read_word(0x0040, 0x000E) :> &EbdaData->bdisk;
941
942 channel = device / 2;
943 slave = device % 2;
944
945 // Data out is not supported yet
946 if (inout == ATA_DATA_OUT) {
947 BX_INFO("%s: DATA_OUT not supported yet\n", __func__);
948 return 1;
949 }
950
951 // The header length must be even
952 if (header & 1) {
953 BX_DEBUG_ATA("%s: header must be even (%04x)\n", __func__, header);
954 return 1;
955 }
956
957 iobase1 = bios_dsk->channels[channel].iobase1;
958 iobase2 = bios_dsk->channels[channel].iobase2;
959 mode = bios_dsk->devices[device].mode;
960 transfer = 0L;
961
962 if (cmdlen < 12)
963 cmdlen = 12;
964 if (cmdlen > 12)
965 cmdlen = 16;
966 cmdlen >>= 1;
967
968 // Reset count of transferred data
969 /// @todo clear in calling code?
970 bios_dsk->drqp.trsfsectors = 0;
971 bios_dsk->drqp.trsfbytes = 0;
972
973 status = inb(iobase1 + ATA_CB_STAT);
974 if (status & ATA_CB_STAT_BSY)
975 return 2;
976
977 outb(iobase2 + ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN);
978 // outb(iobase1 + ATA_CB_FR, 0x00);
979 // outb(iobase1 + ATA_CB_SC, 0x00);
980 // outb(iobase1 + ATA_CB_SN, 0x00);
981 outb(iobase1 + ATA_CB_CL, 0xfff0 & 0x00ff);
982 outb(iobase1 + ATA_CB_CH, 0xfff0 >> 8);
983 outb(iobase1 + ATA_CB_DH, slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0);
984 outb(iobase1 + ATA_CB_CMD, ATA_CMD_PACKET);
985
986 // Device should ok to receive command
987 while (1) {
988 status = inb(iobase1 + ATA_CB_STAT);
989 if ( !(status & ATA_CB_STAT_BSY) ) break;
990 }
991
992 if (status & ATA_CB_STAT_CHK) {
993 BX_DEBUG_ATA("%s: error, status is %02x\n", __func__, status);
994 // Enable interrupts
995 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
996 return 3;
997 } else if ( !(status & ATA_CB_STAT_DRQ) ) {
998 BX_DEBUG_ATA("%s: DRQ not set (status %02x)\n", __func__, (unsigned) status);
999 // Enable interrupts
1000 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
1001 return 4;
1002 }
1003
1004 int_enable(); // enable higher priority interrupts
1005
1006 // Normalize address
1007 BX_DEBUG_ATA("acp1 buffer ptr: %04x:%04x wlen %04x\n", FP_SEG(cmdbuf), FP_OFF(cmdbuf), cmdlen);
1008 cmdbuf = MK_FP(FP_SEG(cmdbuf) + FP_OFF(cmdbuf) / 16 , FP_OFF(cmdbuf) % 16);
1009 // cmdseg += (cmdoff / 16);
1010 // cmdoff %= 16;
1011
1012 // Send command to device
1013 rep_outsw(cmdbuf, cmdlen, iobase1);
1014
1015 if (inout == ATA_DATA_NO) {
1016 status = inb(iobase1 + ATA_CB_STAT);
1017 }
1018 else {
1019 while (1) {
1020
1021 while (1) {
1022 status = inb(iobase1 + ATA_CB_STAT);
1023 if ( !(status & ATA_CB_STAT_BSY) )
1024 break;
1025 }
1026
1027 // Check if command completed
1028 if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_DRQ) ) ==0 )
1029 break;
1030
1031 if (status & ATA_CB_STAT_CHK) {
1032 BX_DEBUG_ATA("%s: error (status %02x)\n", __func__, status);
1033 // Enable interrupts
1034 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
1035 return 3;
1036 }
1037
1038 // Device must be ready to send data
1039 if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ | ATA_CB_STAT_CHK) )
1040 != (ATA_CB_STAT_RDY | ATA_CB_STAT_DRQ) ) {
1041 BX_DEBUG_ATA("%s: not ready (status %02x)\n", __func__, status);
1042 // Enable interrupts
1043 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
1044 return 4;
1045 }
1046
1047 // Normalize address
1048 BX_DEBUG_ATA("acp2 buffer ptr: %04x:%04x\n", FP_SEG(buffer), FP_OFF(buffer));
1049 buffer = MK_FP(FP_SEG(buffer) + FP_OFF(buffer) / 16 , FP_OFF(buffer) % 16);
1050 // bufseg += (bufoff / 16);
1051 // bufoff %= 16;
1052
1053 // Get the byte count
1054 lcount = ((uint16_t)(inb(iobase1 + ATA_CB_CH))<<8)+inb(iobase1 + ATA_CB_CL);
1055
1056 // adjust to read what we want
1057 if (header>lcount) {
1058 lbefore = lcount;
1059 header -= lcount;
1060 lcount = 0;
1061 }
1062 else {
1063 lbefore = header;
1064 header = 0;
1065 lcount -= lbefore;
1066 }
1067
1068 if (lcount>length) {
1069 lafter = lcount - length;
1070 lcount = length;
1071 length = 0;
1072 }
1073 else {
1074 lafter = 0;
1075 length -= lcount;
1076 }
1077
1078 // Save byte count
1079 count = lcount;
1080
1081 BX_DEBUG_ATA("Trying to read %04x bytes (%04x %04x %04x) ",lbefore+lcount+lafter,lbefore,lcount,lafter);
1082 BX_DEBUG_ATA("to 0x%04x:0x%04x\n",FP_SEG(buffer),FP_OFF(buffer));
1083
1084 // If counts not dividable by 4, use 16bits mode
1085 lmode = mode;
1086 if (lbefore & 0x03)
1087 lmode = ATA_MODE_PIO16;
1088 if (lcount & 0x03)
1089 lmode = ATA_MODE_PIO16;
1090 if (lafter & 0x03)
1091 lmode = ATA_MODE_PIO16;
1092
1093 // adds an extra byte if count are odd. before is always even
1094 if (lcount & 0x01) {
1095 lcount += 1;
1096 if ((lafter > 0) && (lafter & 0x01)) {
1097 lafter -= 1;
1098 }
1099 }
1100
1101#if VBOX_BIOS_CPU >= 80386
1102 if (lmode == ATA_MODE_PIO32) {
1103 lcount >>= 2;
1104 lbefore >>= 2;
1105 lafter >>= 2;
1106 } else
1107#endif
1108 {
1109 lcount >>= 1;
1110 lbefore >>= 1;
1111 lafter >>= 1;
1112 }
1113
1114#if VBOX_BIOS_CPU >= 80386
1115 if (lmode == ATA_MODE_PIO32) {
1116 if (lbefore)
1117 insd_discard(lbefore, iobase1);
1118 rep_insd(buffer, lcount, iobase1);
1119 if (lafter)
1120 insd_discard(lafter, iobase1);
1121 } else
1122#endif
1123 {
1124 if (lbefore)
1125 insw_discard(lbefore, iobase1);
1126 rep_insw(buffer, lcount, iobase1);
1127 if (lafter)
1128 insw_discard(lafter, iobase1);
1129 }
1130
1131
1132 // Compute new buffer address
1133 buffer += count;
1134
1135 // Save transferred bytes count
1136 transfer += count;
1137 bios_dsk->drqp.trsfbytes = transfer;
1138 }
1139 }
1140
1141 // Final check, device must be ready
1142 if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DF | ATA_CB_STAT_DRQ | ATA_CB_STAT_CHK) )
1143 != ATA_CB_STAT_RDY ) {
1144 BX_DEBUG_ATA("%s: not ready (status %02x)\n", __func__, (unsigned) status);
1145 // Enable interrupts
1146 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
1147 return 4;
1148 }
1149
1150 // Enable interrupts
1151 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
1152 return 0;
1153}
1154
1155// ---------------------------------------------------------------------------
1156// ATA/ATAPI driver : reset device; intended for ATAPI devices
1157// ---------------------------------------------------------------------------
1158 // returns
1159 // 0 : no error
1160 // 1 : error
1161uint16_t ata_soft_reset(uint16_t device)
1162{
1163 uint16_t iobase1, iobase2;
1164 uint8_t channel, slave;
1165 uint8_t status;
1166 bio_dsk_t __far *bios_dsk;
1167
1168 bios_dsk = read_word(0x0040, 0x000E) :> &EbdaData->bdisk;
1169
1170 channel = device / 2;
1171 slave = device % 2;
1172
1173 iobase1 = bios_dsk->channels[channel].iobase1;
1174 iobase2 = bios_dsk->channels[channel].iobase2;
1175
1176 /* Send a reset command to the device. */
1177 outb(iobase2 + ATA_CB_DC, ATA_CB_DC_HD15 | ATA_CB_DC_NIEN);
1178 outb(iobase1 + ATA_CB_DH, slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0);
1179 outb(iobase1 + ATA_CB_CMD, ATA_CMD_DEVICE_RESET);
1180
1181 /* Wait for the device to clear BSY. */
1182 while (1) {
1183 status = inb(iobase1 + ATA_CB_STAT);
1184 if ( !(status & ATA_CB_STAT_BSY) ) break;
1185 }
1186
1187 /* Final check, device must be ready */
1188 if ( (status & (ATA_CB_STAT_BSY | ATA_CB_STAT_RDY | ATA_CB_STAT_DF | ATA_CB_STAT_DRQ | ATA_CB_STAT_CHK) )
1189 != ATA_CB_STAT_RDY ) {
1190 BX_DEBUG_ATA("%s: not ready (status %02x)\n", __func__, (unsigned) status);
1191 /* Enable interrupts */
1192 outb(iobase2 + ATA_CB_DC, ATA_CB_DC_HD15);
1193 return 1;
1194 }
1195
1196 /* Enable interrupts */
1197 outb(iobase2+ATA_CB_DC, ATA_CB_DC_HD15);
1198 return 0;
1199}
1200
1201
1202// ---------------------------------------------------------------------------
1203// End of ATA/ATAPI Driver
1204// ---------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette