|
|
1.1 root 1: // Low level ATA disk access
2: //
3: // Copyright (C) 2008,2009 Kevin O'Connor <[email protected]>
4: // Copyright (C) 2002 MandrakeSoft S.A.
5: //
6: // This file may be distributed under the terms of the GNU LGPLv3 license.
7:
8: #include "types.h" // u8
9: #include "ioport.h" // inb
10: #include "util.h" // dprintf
11: #include "cmos.h" // inb_cmos
12: #include "pic.h" // enable_hwirq
13: #include "biosvar.h" // GET_EBDA
14: #include "pci.h" // foreachpci
15: #include "pci_ids.h" // PCI_CLASS_STORAGE_OTHER
16: #include "pci_regs.h" // PCI_INTERRUPT_LINE
17: #include "boot.h" // add_bcv_hd
18: #include "disk.h" // struct ata_s
19: #include "ata.h" // ATA_CB_STAT
1.1.1.3 ! root 20: #include "blockcmd.h" // CDB_CMD_READ_10
1.1 root 21:
22: #define IDE_TIMEOUT 32000 //32 seconds max for IDE ops
23:
24:
25: /****************************************************************
26: * Helper functions
27: ****************************************************************/
28:
29: // Wait for the specified ide state
30: static inline int
31: await_ide(u8 mask, u8 flags, u16 base, u16 timeout)
32: {
33: u64 end = calc_future_tsc(timeout);
34: for (;;) {
35: u8 status = inb(base+ATA_CB_STAT);
36: if ((status & mask) == flags)
37: return status;
1.1.1.3 ! root 38: if (check_tsc(end)) {
! 39: warn_timeout();
1.1 root 40: return -1;
41: }
42: yield();
43: }
44: }
45:
46: // Wait for the device to be not-busy.
47: static int
48: await_not_bsy(u16 base)
49: {
50: return await_ide(ATA_CB_STAT_BSY, 0, base, IDE_TIMEOUT);
51: }
52:
53: // Wait for the device to be ready.
54: static int
55: await_rdy(u16 base)
56: {
57: return await_ide(ATA_CB_STAT_RDY, ATA_CB_STAT_RDY, base, IDE_TIMEOUT);
58: }
59:
60: // Wait for ide state - pauses for one ata cycle first.
61: static inline int
62: pause_await_not_bsy(u16 iobase1, u16 iobase2)
63: {
64: // Wait one PIO transfer cycle.
65: inb(iobase2 + ATA_CB_ASTAT);
66:
67: return await_not_bsy(iobase1);
68: }
69:
70: // Wait for ide state - pause for 400ns first.
71: static inline int
72: ndelay_await_not_bsy(u16 iobase1)
73: {
74: ndelay(400);
75: return await_not_bsy(iobase1);
76: }
77:
78: // Reset a drive
79: static void
1.1.1.3 ! root 80: ata_reset(struct atadrive_s *adrive_g)
1.1 root 81: {
1.1.1.3 ! root 82: struct ata_channel_s *chan_gf = GET_GLOBAL(adrive_g->chan_gf);
! 83: u8 slave = GET_GLOBAL(adrive_g->slave);
! 84: u16 iobase1 = GET_GLOBALFLAT(chan_gf->iobase1);
! 85: u16 iobase2 = GET_GLOBALFLAT(chan_gf->iobase2);
1.1 root 86:
1.1.1.3 ! root 87: dprintf(6, "ata_reset drive=%p\n", &adrive_g->drive);
1.1 root 88: // Pulse SRST
89: outb(ATA_CB_DC_HD15 | ATA_CB_DC_NIEN | ATA_CB_DC_SRST, iobase2+ATA_CB_DC);
90: udelay(5);
91: outb(ATA_CB_DC_HD15 | ATA_CB_DC_NIEN, iobase2+ATA_CB_DC);
92: msleep(2);
93:
94: // wait for device to become not busy.
95: int status = await_not_bsy(iobase1);
96: if (status < 0)
97: goto done;
98: if (slave) {
99: // Change device.
100: u64 end = calc_future_tsc(IDE_TIMEOUT);
101: for (;;) {
102: outb(ATA_CB_DH_DEV1, iobase1 + ATA_CB_DH);
103: status = ndelay_await_not_bsy(iobase1);
104: if (status < 0)
105: goto done;
106: if (inb(iobase1 + ATA_CB_DH) == ATA_CB_DH_DEV1)
107: break;
108: // Change drive request failed to take effect - retry.
1.1.1.3 ! root 109: if (check_tsc(end)) {
! 110: warn_timeout();
1.1 root 111: goto done;
112: }
113: }
114: } else {
115: // QEMU doesn't reset dh on reset, so set it explicitly.
116: outb(ATA_CB_DH_DEV0, iobase1 + ATA_CB_DH);
117: }
118:
119: // On a user-reset request, wait for RDY if it is an ATA device.
1.1.1.3 ! root 120: u8 type=GET_GLOBAL(adrive_g->drive.type);
1.1 root 121: if (type == DTYPE_ATA)
122: status = await_rdy(iobase1);
123:
124: done:
125: // Enable interrupts
126: outb(ATA_CB_DC_HD15, iobase2+ATA_CB_DC);
127:
128: dprintf(6, "ata_reset exit status=%x\n", status);
129: }
130:
1.1.1.2 root 131: // Check for drive RDY for 16bit interface command.
1.1 root 132: static int
1.1.1.3 ! root 133: isready(struct atadrive_s *adrive_g)
1.1 root 134: {
135: // Read the status from controller
1.1.1.3 ! root 136: struct ata_channel_s *chan_gf = GET_GLOBAL(adrive_g->chan_gf);
! 137: u16 iobase1 = GET_GLOBALFLAT(chan_gf->iobase1);
1.1 root 138: u8 status = inb(iobase1 + ATA_CB_STAT);
139: if ((status & (ATA_CB_STAT_BSY|ATA_CB_STAT_RDY)) == ATA_CB_STAT_RDY)
140: return DISK_RET_SUCCESS;
141: return DISK_RET_ENOTREADY;
142: }
143:
1.1.1.2 root 144: // Default 16bit command demuxer for ATA and ATAPI devices.
1.1 root 145: static int
146: process_ata_misc_op(struct disk_op_s *op)
147: {
148: if (!CONFIG_ATA)
149: return 0;
150:
1.1.1.3 ! root 151: struct atadrive_s *adrive_g = container_of(
! 152: op->drive_g, struct atadrive_s, drive);
1.1 root 153: switch (op->command) {
154: case CMD_RESET:
1.1.1.3 ! root 155: ata_reset(adrive_g);
1.1 root 156: return DISK_RET_SUCCESS;
157: case CMD_ISREADY:
1.1.1.3 ! root 158: return isready(adrive_g);
1.1 root 159: case CMD_FORMAT:
160: case CMD_VERIFY:
161: case CMD_SEEK:
162: return DISK_RET_SUCCESS;
163: default:
164: op->count = 0;
165: return DISK_RET_EPARAM;
166: }
167: }
168:
169:
170: /****************************************************************
171: * ATA send command
172: ****************************************************************/
173:
174: struct ata_pio_command {
175: u8 feature;
176: u8 sector_count;
177: u8 lba_low;
178: u8 lba_mid;
179: u8 lba_high;
180: u8 device;
181: u8 command;
182:
1.1.1.2 root 183: u8 feature2;
1.1 root 184: u8 sector_count2;
185: u8 lba_low2;
186: u8 lba_mid2;
187: u8 lba_high2;
188: };
189:
190: // Send an ata command to the drive.
191: static int
1.1.1.3 ! root 192: send_cmd(struct atadrive_s *adrive_g, struct ata_pio_command *cmd)
1.1 root 193: {
1.1.1.3 ! root 194: struct ata_channel_s *chan_gf = GET_GLOBAL(adrive_g->chan_gf);
! 195: u8 slave = GET_GLOBAL(adrive_g->slave);
! 196: u16 iobase1 = GET_GLOBALFLAT(chan_gf->iobase1);
1.1 root 197:
198: // Select device
199: int status = await_not_bsy(iobase1);
200: if (status < 0)
201: return status;
202: u8 newdh = ((cmd->device & ~ATA_CB_DH_DEV1)
203: | (slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0));
204: u8 olddh = inb(iobase1 + ATA_CB_DH);
205: outb(newdh, iobase1 + ATA_CB_DH);
206: if ((olddh ^ newdh) & (1<<4)) {
207: // Was a device change - wait for device to become not busy.
208: status = ndelay_await_not_bsy(iobase1);
209: if (status < 0)
210: return status;
211: }
212:
1.1.1.2 root 213: // Check for ATA_CMD_(READ|WRITE)_(SECTORS|DMA)_EXT commands.
214: if ((cmd->command & ~0x11) == ATA_CMD_READ_SECTORS_EXT) {
215: outb(cmd->feature2, iobase1 + ATA_CB_FR);
1.1 root 216: outb(cmd->sector_count2, iobase1 + ATA_CB_SC);
217: outb(cmd->lba_low2, iobase1 + ATA_CB_SN);
218: outb(cmd->lba_mid2, iobase1 + ATA_CB_CL);
219: outb(cmd->lba_high2, iobase1 + ATA_CB_CH);
220: }
221: outb(cmd->feature, iobase1 + ATA_CB_FR);
222: outb(cmd->sector_count, iobase1 + ATA_CB_SC);
223: outb(cmd->lba_low, iobase1 + ATA_CB_SN);
224: outb(cmd->lba_mid, iobase1 + ATA_CB_CL);
225: outb(cmd->lba_high, iobase1 + ATA_CB_CH);
226: outb(cmd->command, iobase1 + ATA_CB_CMD);
227:
1.1.1.2 root 228: return 0;
229: }
230:
231: // Wait for data after calling 'send_cmd'.
232: static int
233: ata_wait_data(u16 iobase1)
234: {
235: int status = ndelay_await_not_bsy(iobase1);
1.1 root 236: if (status < 0)
237: return status;
238:
239: if (status & ATA_CB_STAT_ERR) {
240: dprintf(6, "send_cmd : read error (status=%02x err=%02x)\n"
241: , status, inb(iobase1 + ATA_CB_ERR));
242: return -4;
243: }
244: if (!(status & ATA_CB_STAT_DRQ)) {
245: dprintf(6, "send_cmd : DRQ not set (status %02x)\n", status);
246: return -5;
247: }
248:
249: return 0;
250: }
251:
1.1.1.2 root 252: // Send an ata command that does not transfer any further data.
253: int
1.1.1.3 ! root 254: ata_cmd_nondata(struct atadrive_s *adrive_g, struct ata_pio_command *cmd)
1.1.1.2 root 255: {
1.1.1.3 ! root 256: struct ata_channel_s *chan_gf = GET_GLOBAL(adrive_g->chan_gf);
! 257: u16 iobase1 = GET_GLOBALFLAT(chan_gf->iobase1);
! 258: u16 iobase2 = GET_GLOBALFLAT(chan_gf->iobase2);
1.1.1.2 root 259:
260: // Disable interrupts
261: outb(ATA_CB_DC_HD15 | ATA_CB_DC_NIEN, iobase2 + ATA_CB_DC);
262:
1.1.1.3 ! root 263: int ret = send_cmd(adrive_g, cmd);
1.1.1.2 root 264: if (ret)
265: goto fail;
266: ret = ndelay_await_not_bsy(iobase1);
267: if (ret < 0)
268: goto fail;
269:
270: if (ret & ATA_CB_STAT_ERR) {
271: dprintf(6, "nondata cmd : read error (status=%02x err=%02x)\n"
272: , ret, inb(iobase1 + ATA_CB_ERR));
273: ret = -4;
274: goto fail;
275: }
276: if (ret & ATA_CB_STAT_DRQ) {
277: dprintf(6, "nondata cmd : DRQ set (status %02x)\n", ret);
278: ret = -5;
279: goto fail;
280: }
281:
282: fail:
283: // Enable interrupts
284: outb(ATA_CB_DC_HD15, iobase2+ATA_CB_DC);
285:
286: return ret;
287: }
288:
1.1 root 289:
290: /****************************************************************
1.1.1.2 root 291: * ATA PIO transfers
1.1 root 292: ****************************************************************/
293:
294: // Transfer 'op->count' blocks (of 'blocksize' bytes) to/from drive
295: // 'op->drive_g'.
296: static int
1.1.1.2 root 297: ata_pio_transfer(struct disk_op_s *op, int iswrite, int blocksize)
1.1 root 298: {
1.1.1.2 root 299: dprintf(16, "ata_pio_transfer id=%p write=%d count=%d bs=%d buf=%p\n"
1.1 root 300: , op->drive_g, iswrite, op->count, blocksize, op->buf_fl);
301:
1.1.1.3 ! root 302: struct atadrive_s *adrive_g = container_of(
! 303: op->drive_g, struct atadrive_s, drive);
! 304: struct ata_channel_s *chan_gf = GET_GLOBAL(adrive_g->chan_gf);
! 305: u16 iobase1 = GET_GLOBALFLAT(chan_gf->iobase1);
! 306: u16 iobase2 = GET_GLOBALFLAT(chan_gf->iobase2);
1.1 root 307: int count = op->count;
308: void *buf_fl = op->buf_fl;
309: int status;
310: for (;;) {
311: if (iswrite) {
312: // Write data to controller
313: dprintf(16, "Write sector id=%p dest=%p\n", op->drive_g, buf_fl);
314: if (CONFIG_ATA_PIO32)
315: outsl_fl(iobase1, buf_fl, blocksize / 4);
316: else
317: outsw_fl(iobase1, buf_fl, blocksize / 2);
318: } else {
319: // Read data from controller
320: dprintf(16, "Read sector id=%p dest=%p\n", op->drive_g, buf_fl);
321: if (CONFIG_ATA_PIO32)
322: insl_fl(iobase1, buf_fl, blocksize / 4);
323: else
324: insw_fl(iobase1, buf_fl, blocksize / 2);
325: }
326: buf_fl += blocksize;
327:
328: status = pause_await_not_bsy(iobase1, iobase2);
329: if (status < 0) {
330: // Error
331: op->count -= count;
332: return status;
333: }
334:
335: count--;
336: if (!count)
337: break;
338: status &= (ATA_CB_STAT_BSY | ATA_CB_STAT_DRQ | ATA_CB_STAT_ERR);
339: if (status != ATA_CB_STAT_DRQ) {
1.1.1.2 root 340: dprintf(6, "ata_pio_transfer : more sectors left (status %02x)\n"
1.1 root 341: , status);
342: op->count -= count;
343: return -6;
344: }
345: }
346:
347: status &= (ATA_CB_STAT_BSY | ATA_CB_STAT_DF | ATA_CB_STAT_DRQ
348: | ATA_CB_STAT_ERR);
349: if (!iswrite)
350: status &= ~ATA_CB_STAT_DF;
351: if (status != 0) {
1.1.1.2 root 352: dprintf(6, "ata_pio_transfer : no sectors left (status %02x)\n", status);
1.1 root 353: return -7;
354: }
355:
356: return 0;
357: }
358:
359:
360: /****************************************************************
1.1.1.2 root 361: * ATA DMA transfers
362: ****************************************************************/
363:
364: #define BM_CMD 0
365: #define BM_CMD_MEMWRITE 0x08
366: #define BM_CMD_START 0x01
367: #define BM_STATUS 2
368: #define BM_STATUS_IRQ 0x04
369: #define BM_STATUS_ERROR 0x02
370: #define BM_STATUS_ACTIVE 0x01
371: #define BM_TABLE 4
372:
373: struct sff_dma_prd {
374: u32 buf_fl;
375: u32 count;
376: };
377:
378: // Check if DMA available and setup transfer if so.
379: static int
380: ata_try_dma(struct disk_op_s *op, int iswrite, int blocksize)
381: {
1.1.1.3 ! root 382: if (! CONFIG_ATA_DMA)
! 383: return -1;
1.1.1.2 root 384: u32 dest = (u32)op->buf_fl;
385: if (dest & 1)
386: // Need minimum alignment of 1.
387: return -1;
1.1.1.3 ! root 388: struct atadrive_s *adrive_g = container_of(
! 389: op->drive_g, struct atadrive_s, drive);
! 390: struct ata_channel_s *chan_gf = GET_GLOBAL(adrive_g->chan_gf);
! 391: u16 iomaster = GET_GLOBALFLAT(chan_gf->iomaster);
1.1.1.2 root 392: if (! iomaster)
393: return -1;
394: u32 bytes = op->count * blocksize;
395: if (! bytes)
396: return -1;
397:
398: // Build PRD dma structure.
399: struct sff_dma_prd *dma = MAKE_FLATPTR(
400: get_ebda_seg()
401: , (void*)offsetof(struct extended_bios_data_area_s, extra_stack));
402: struct sff_dma_prd *origdma = dma;
403: while (bytes) {
404: if (dma >= &origdma[16])
405: // Too many descriptors..
406: return -1;
407: u32 count = bytes;
408: u32 max = 0x10000 - (dest & 0xffff);
409: if (count > max)
410: count = max;
411:
412: SET_FLATPTR(dma->buf_fl, dest);
413: bytes -= count;
414: if (!bytes)
415: // Last descriptor.
416: count |= 1<<31;
417: dprintf(16, "dma@%p: %08x %08x\n", dma, dest, count);
418: dest += count;
419: SET_FLATPTR(dma->count, count);
420: dma++;
421: }
422:
423: // Program bus-master controller.
424: outl((u32)origdma, iomaster + BM_TABLE);
425: u8 oldcmd = inb(iomaster + BM_CMD) & ~(BM_CMD_MEMWRITE|BM_CMD_START);
426: outb(oldcmd | (iswrite ? 0x00 : BM_CMD_MEMWRITE), iomaster + BM_CMD);
427: outb(BM_STATUS_ERROR|BM_STATUS_IRQ, iomaster + BM_STATUS);
428:
429: return 0;
430: }
431:
432: // Transfer data using DMA.
433: static int
434: ata_dma_transfer(struct disk_op_s *op)
435: {
1.1.1.3 ! root 436: if (! CONFIG_ATA_DMA)
! 437: return -1;
! 438: dprintf(16, "ata_dma_transfer id=%p buf=%p\n", op->drive_g, op->buf_fl);
1.1.1.2 root 439:
1.1.1.3 ! root 440: struct atadrive_s *adrive_g = container_of(
! 441: op->drive_g, struct atadrive_s, drive);
! 442: struct ata_channel_s *chan_gf = GET_GLOBAL(adrive_g->chan_gf);
! 443: u16 iomaster = GET_GLOBALFLAT(chan_gf->iomaster);
1.1.1.2 root 444:
445: // Start bus-master controller.
446: u8 oldcmd = inb(iomaster + BM_CMD);
447: outb(oldcmd | BM_CMD_START, iomaster + BM_CMD);
448:
449: u64 end = calc_future_tsc(IDE_TIMEOUT);
450: u8 status;
451: for (;;) {
452: status = inb(iomaster + BM_STATUS);
453: if (status & BM_STATUS_IRQ)
454: break;
455: // Transfer in progress
1.1.1.3 ! root 456: if (check_tsc(end)) {
1.1.1.2 root 457: // Timeout.
1.1.1.3 ! root 458: warn_timeout();
1.1.1.2 root 459: break;
460: }
461: yield();
462: }
463: outb(oldcmd & ~BM_CMD_START, iomaster + BM_CMD);
464:
1.1.1.3 ! root 465: u16 iobase1 = GET_GLOBALFLAT(chan_gf->iobase1);
! 466: u16 iobase2 = GET_GLOBALFLAT(chan_gf->iobase2);
1.1.1.2 root 467: int idestatus = pause_await_not_bsy(iobase1, iobase2);
468:
469: if ((status & (BM_STATUS_IRQ|BM_STATUS_ACTIVE)) == BM_STATUS_IRQ
470: && idestatus >= 0x00
471: && (idestatus & (ATA_CB_STAT_BSY | ATA_CB_STAT_DF | ATA_CB_STAT_DRQ
472: | ATA_CB_STAT_ERR)) == 0x00)
473: // Success.
474: return 0;
475:
476: dprintf(6, "IDE DMA error (dma=%x ide=%x/%x/%x)\n", status, idestatus
477: , inb(iobase2 + ATA_CB_ASTAT), inb(iobase1 + ATA_CB_ERR));
478: op->count = 0;
479: return -1;
480: }
481:
482:
483: /****************************************************************
1.1 root 484: * ATA hard drive functions
485: ****************************************************************/
486:
1.1.1.2 root 487: // Transfer data to harddrive using PIO protocol.
1.1 root 488: static int
1.1.1.2 root 489: ata_pio_cmd_data(struct disk_op_s *op, int iswrite, struct ata_pio_command *cmd)
1.1 root 490: {
1.1.1.3 ! root 491: struct atadrive_s *adrive_g = container_of(
! 492: op->drive_g, struct atadrive_s, drive);
! 493: struct ata_channel_s *chan_gf = GET_GLOBAL(adrive_g->chan_gf);
! 494: u16 iobase1 = GET_GLOBALFLAT(chan_gf->iobase1);
! 495: u16 iobase2 = GET_GLOBALFLAT(chan_gf->iobase2);
1.1.1.2 root 496:
497: // Disable interrupts
498: outb(ATA_CB_DC_HD15 | ATA_CB_DC_NIEN, iobase2 + ATA_CB_DC);
499:
1.1.1.3 ! root 500: int ret = send_cmd(adrive_g, cmd);
1.1.1.2 root 501: if (ret)
502: goto fail;
503: ret = ata_wait_data(iobase1);
504: if (ret)
505: goto fail;
506: ret = ata_pio_transfer(op, iswrite, DISK_SECTOR_SIZE);
507:
508: fail:
509: // Enable interrupts
510: outb(ATA_CB_DC_HD15, iobase2+ATA_CB_DC);
511: return ret;
512: }
513:
514: // Transfer data to harddrive using DMA protocol.
515: static int
516: ata_dma_cmd_data(struct disk_op_s *op, struct ata_pio_command *cmd)
517: {
1.1.1.3 ! root 518: if (! CONFIG_ATA_DMA)
! 519: return -1;
! 520: struct atadrive_s *adrive_g = container_of(
! 521: op->drive_g, struct atadrive_s, drive);
! 522: int ret = send_cmd(adrive_g, cmd);
1.1.1.2 root 523: if (ret)
524: return ret;
525: return ata_dma_transfer(op);
526: }
527:
528: // Read/write count blocks from a harddrive.
529: static int
530: ata_readwrite(struct disk_op_s *op, int iswrite)
531: {
1.1 root 532: u64 lba = op->lba;
533:
1.1.1.2 root 534: int usepio = ata_try_dma(op, iswrite, DISK_SECTOR_SIZE);
535:
1.1 root 536: struct ata_pio_command cmd;
537: memset(&cmd, 0, sizeof(cmd));
538:
539: if (op->count >= (1<<8) || lba + op->count >= (1<<28)) {
540: cmd.sector_count2 = op->count >> 8;
541: cmd.lba_low2 = lba >> 24;
542: cmd.lba_mid2 = lba >> 32;
543: cmd.lba_high2 = lba >> 40;
544: lba &= 0xffffff;
1.1.1.2 root 545:
546: if (usepio)
547: cmd.command = (iswrite ? ATA_CMD_WRITE_SECTORS_EXT
548: : ATA_CMD_READ_SECTORS_EXT);
549: else
550: cmd.command = (iswrite ? ATA_CMD_WRITE_DMA_EXT
551: : ATA_CMD_READ_DMA_EXT);
552: } else {
553: if (usepio)
554: cmd.command = (iswrite ? ATA_CMD_WRITE_SECTORS
555: : ATA_CMD_READ_SECTORS);
556: else
557: cmd.command = (iswrite ? ATA_CMD_WRITE_DMA
558: : ATA_CMD_READ_DMA);
1.1 root 559: }
560:
561: cmd.sector_count = op->count;
562: cmd.lba_low = lba;
563: cmd.lba_mid = lba >> 8;
564: cmd.lba_high = lba >> 16;
565: cmd.device = ((lba >> 24) & 0xf) | ATA_CB_DH_LBA;
566:
1.1.1.2 root 567: int ret;
568: if (usepio)
569: ret = ata_pio_cmd_data(op, iswrite, &cmd);
570: else
571: ret = ata_dma_cmd_data(op, &cmd);
1.1 root 572: if (ret)
1.1.1.2 root 573: return DISK_RET_EBADTRACK;
574: return DISK_RET_SUCCESS;
1.1 root 575: }
576:
1.1.1.2 root 577: // 16bit command demuxer for ATA harddrives.
1.1 root 578: int
579: process_ata_op(struct disk_op_s *op)
580: {
581: if (!CONFIG_ATA)
582: return 0;
583:
584: switch (op->command) {
585: case CMD_READ:
1.1.1.2 root 586: return ata_readwrite(op, 0);
1.1 root 587: case CMD_WRITE:
1.1.1.2 root 588: return ata_readwrite(op, 1);
1.1 root 589: default:
590: return process_ata_misc_op(op);
591: }
592: }
593:
594:
595: /****************************************************************
596: * ATAPI functions
597: ****************************************************************/
598:
1.1.1.3 ! root 599: #define CDROM_CDB_SIZE 12
! 600:
1.1 root 601: // Low-level atapi command transmit function.
1.1.1.3 ! root 602: int
! 603: atapi_cmd_data(struct disk_op_s *op, void *cdbcmd, u16 blocksize)
1.1 root 604: {
1.1.1.3 ! root 605: struct atadrive_s *adrive_g = container_of(
! 606: op->drive_g, struct atadrive_s, drive);
! 607: struct ata_channel_s *chan_gf = GET_GLOBAL(adrive_g->chan_gf);
! 608: u16 iobase1 = GET_GLOBALFLAT(chan_gf->iobase1);
! 609: u16 iobase2 = GET_GLOBALFLAT(chan_gf->iobase2);
1.1 root 610:
611: struct ata_pio_command cmd;
1.1.1.2 root 612: memset(&cmd, 0, sizeof(cmd));
1.1 root 613: cmd.lba_mid = blocksize;
614: cmd.lba_high = blocksize >> 8;
615: cmd.command = ATA_CMD_PACKET;
616:
617: // Disable interrupts
618: outb(ATA_CB_DC_HD15 | ATA_CB_DC_NIEN, iobase2 + ATA_CB_DC);
619:
1.1.1.3 ! root 620: int ret = send_cmd(adrive_g, &cmd);
1.1 root 621: if (ret)
622: goto fail;
1.1.1.2 root 623: ret = ata_wait_data(iobase1);
624: if (ret)
625: goto fail;
1.1 root 626:
627: // Send command to device
1.1.1.3 ! root 628: outsw_fl(iobase1, MAKE_FLATPTR(GET_SEG(SS), cdbcmd), CDROM_CDB_SIZE / 2);
1.1 root 629:
630: int status = pause_await_not_bsy(iobase1, iobase2);
631: if (status < 0) {
632: ret = status;
633: goto fail;
634: }
635:
636: if (status & ATA_CB_STAT_ERR) {
637: u8 err = inb(iobase1 + ATA_CB_ERR);
638: // skip "Not Ready"
639: if (err != 0x20)
640: dprintf(6, "send_atapi_cmd : read error (status=%02x err=%02x)\n"
641: , status, err);
642: ret = -2;
643: goto fail;
644: }
645: if (!(status & ATA_CB_STAT_DRQ)) {
646: dprintf(6, "send_atapi_cmd : DRQ not set (status %02x)\n", status);
647: ret = -3;
648: goto fail;
649: }
650:
1.1.1.2 root 651: ret = ata_pio_transfer(op, 0, blocksize);
1.1 root 652:
653: fail:
654: // Enable interrupts
655: outb(ATA_CB_DC_HD15, iobase2+ATA_CB_DC);
1.1.1.3 ! root 656: if (ret)
! 657: return DISK_RET_EBADTRACK;
! 658: return DISK_RET_SUCCESS;
1.1 root 659: }
660:
1.1.1.2 root 661: // 16bit command demuxer for ATAPI cdroms.
1.1 root 662: int
663: process_atapi_op(struct disk_op_s *op)
664: {
1.1.1.3 ! root 665: if (!CONFIG_ATA)
! 666: return 0;
1.1 root 667: switch (op->command) {
668: case CMD_READ:
1.1.1.3 ! root 669: return cdb_read(op);
1.1 root 670: case CMD_FORMAT:
671: case CMD_WRITE:
672: return DISK_RET_EWRITEPROTECT;
673: default:
674: return process_ata_misc_op(op);
675: }
676: }
677:
678:
679: /****************************************************************
680: * ATA detect and init
681: ****************************************************************/
682:
1.1.1.2 root 683: // Send an identify device or identify device packet command.
684: static int
1.1.1.3 ! root 685: send_ata_identity(struct atadrive_s *adrive_g, u16 *buffer, int command)
1.1.1.2 root 686: {
687: memset(buffer, 0, DISK_SECTOR_SIZE);
688:
689: struct disk_op_s dop;
690: memset(&dop, 0, sizeof(dop));
1.1.1.3 ! root 691: dop.drive_g = &adrive_g->drive;
1.1.1.2 root 692: dop.count = 1;
693: dop.lba = 1;
694: dop.buf_fl = MAKE_FLATPTR(GET_SEG(SS), buffer);
695:
696: struct ata_pio_command cmd;
697: memset(&cmd, 0, sizeof(cmd));
698: cmd.command = command;
699:
700: return ata_pio_cmd_data(&dop, 0, &cmd);
701: }
702:
1.1 root 703: // Extract the ATA/ATAPI version info.
704: static int
705: extract_version(u16 *buffer)
706: {
707: // Extract ATA/ATAPI version.
708: u16 ataversion = buffer[80];
709: u8 version;
710: for (version=15; version>0; version--)
711: if (ataversion & (1<<version))
712: break;
713: return version;
714: }
715:
1.1.1.3 ! root 716: #define MAXMODEL 40
1.1 root 717:
1.1.1.3 ! root 718: // Extract the ATA/ATAPI model info.
! 719: static char *
! 720: extract_model(char *model, u16 *buffer)
! 721: {
1.1 root 722: // Read model name
723: int i;
1.1.1.3 ! root 724: for (i=0; i<MAXMODEL/2; i++)
! 725: *(u16*)&model[i*2] = ntohs(buffer[27+i]);
! 726: model[MAXMODEL] = 0x00;
1.1 root 727:
728: // Trim trailing spaces from model name.
1.1.1.3 ! root 729: for (i=MAXMODEL-1; i>0 && model[i] == 0x20; i--)
1.1 root 730: model[i] = 0x00;
731:
1.1.1.3 ! root 732: return model;
1.1 root 733: }
734:
1.1.1.3 ! root 735: // Common init code between ata and atapi
! 736: static struct atadrive_s *
! 737: init_atadrive(struct atadrive_s *dummy, u16 *buffer)
! 738: {
! 739: char *desc = malloc_tmp(MAXDESCSIZE);
! 740: struct atadrive_s *adrive_g = malloc_fseg(sizeof(*adrive_g));
! 741: if (!adrive_g || !desc) {
! 742: warn_noalloc();
! 743: free(desc);
! 744: free(adrive_g);
! 745: return NULL;
! 746: }
! 747: memset(adrive_g, 0, sizeof(*adrive_g));
! 748: adrive_g->drive.desc = desc;
! 749: adrive_g->chan_gf = dummy->chan_gf;
! 750: adrive_g->slave = dummy->slave;
! 751: adrive_g->drive.cntl_id = adrive_g->chan_gf->chanid * 2 + dummy->slave;
! 752: adrive_g->drive.removable = (buffer[0] & 0x80) ? 1 : 0;
! 753: return adrive_g;
1.1 root 754: }
755:
1.1.1.2 root 756: // Detect if the given drive is an atapi - initialize it if so.
1.1.1.3 ! root 757: static struct atadrive_s *
! 758: init_drive_atapi(struct atadrive_s *dummy, u16 *buffer)
1.1 root 759: {
760: // Send an IDENTIFY_DEVICE_PACKET command to device
1.1.1.2 root 761: int ret = send_ata_identity(dummy, buffer, ATA_CMD_IDENTIFY_PACKET_DEVICE);
1.1 root 762: if (ret)
763: return NULL;
764:
765: // Success - setup as ATAPI.
1.1.1.3 ! root 766: struct atadrive_s *adrive_g = init_atadrive(dummy, buffer);
! 767: if (!adrive_g)
1.1 root 768: return NULL;
1.1.1.3 ! root 769: adrive_g->drive.type = DTYPE_ATAPI;
! 770: adrive_g->drive.blksize = CDROM_SECTOR_SIZE;
! 771: adrive_g->drive.sectors = (u64)-1;
1.1 root 772: u8 iscd = ((buffer[0] >> 8) & 0x1f) == 0x05;
1.1.1.3 ! root 773: char model[MAXMODEL+1];
! 774: snprintf(adrive_g->drive.desc, MAXDESCSIZE, "ata%d-%d: %s ATAPI-%d %s"
! 775: , adrive_g->chan_gf->chanid, adrive_g->slave
! 776: , extract_model(model, buffer), extract_version(buffer)
! 777: , (iscd ? "DVD/CD" : "Device"));
! 778: dprintf(1, "%s\n", adrive_g->drive.desc);
1.1 root 779:
780: // fill cdidmap
781: if (iscd)
1.1.1.3 ! root 782: map_cd_drive(&adrive_g->drive);
1.1 root 783:
1.1.1.3 ! root 784: return adrive_g;
1.1 root 785: }
786:
1.1.1.2 root 787: // Detect if the given drive is a regular ata drive - initialize it if so.
1.1.1.3 ! root 788: static struct atadrive_s *
! 789: init_drive_ata(struct atadrive_s *dummy, u16 *buffer)
1.1 root 790: {
791: // Send an IDENTIFY_DEVICE command to device
1.1.1.2 root 792: int ret = send_ata_identity(dummy, buffer, ATA_CMD_IDENTIFY_DEVICE);
1.1 root 793: if (ret)
794: return NULL;
795:
796: // Success - setup as ATA.
1.1.1.3 ! root 797: struct atadrive_s *adrive_g = init_atadrive(dummy, buffer);
! 798: if (!adrive_g)
1.1 root 799: return NULL;
1.1.1.3 ! root 800: adrive_g->drive.type = DTYPE_ATA;
! 801: adrive_g->drive.blksize = DISK_SECTOR_SIZE;
! 802:
! 803: adrive_g->drive.pchs.cylinders = buffer[1];
! 804: adrive_g->drive.pchs.heads = buffer[3];
! 805: adrive_g->drive.pchs.spt = buffer[6];
1.1 root 806:
807: u64 sectors;
808: if (buffer[83] & (1 << 10)) // word 83 - lba48 support
809: sectors = *(u64*)&buffer[100]; // word 100-103
810: else
811: sectors = *(u32*)&buffer[60]; // word 60 and word 61
1.1.1.3 ! root 812: adrive_g->drive.sectors = sectors;
! 813: u64 adjsize = sectors >> 11;
! 814: char adjprefix = 'M';
! 815: if (adjsize >= (1 << 16)) {
! 816: adjsize >>= 10;
! 817: adjprefix = 'G';
! 818: }
! 819: char model[MAXMODEL+1];
! 820: snprintf(adrive_g->drive.desc, MAXDESCSIZE
! 821: , "ata%d-%d: %s ATA-%d Hard-Disk (%u %ciBytes)"
! 822: , adrive_g->chan_gf->chanid, adrive_g->slave
! 823: , extract_model(model, buffer), extract_version(buffer)
! 824: , (u32)adjsize, adjprefix);
! 825: dprintf(1, "%s\n", adrive_g->drive.desc);
1.1 root 826:
827: // Setup disk geometry translation.
1.1.1.3 ! root 828: setup_translation(&adrive_g->drive);
1.1 root 829:
830: // Register with bcv system.
1.1.1.3 ! root 831: add_bcv_internal(&adrive_g->drive);
1.1 root 832:
1.1.1.3 ! root 833: return adrive_g;
1.1 root 834: }
835:
836: static u64 SpinupEnd;
837:
1.1.1.2 root 838: // Wait for non-busy status and check for "floating bus" condition.
1.1 root 839: static int
840: powerup_await_non_bsy(u16 base)
841: {
842: u8 orstatus = 0;
843: u8 status;
844: for (;;) {
845: status = inb(base+ATA_CB_STAT);
846: if (!(status & ATA_CB_STAT_BSY))
847: break;
848: orstatus |= status;
849: if (orstatus == 0xff) {
1.1.1.3 ! root 850: dprintf(4, "powerup IDE floating\n");
1.1 root 851: return orstatus;
852: }
1.1.1.3 ! root 853: if (check_tsc(SpinupEnd)) {
! 854: warn_timeout();
1.1 root 855: return -1;
856: }
857: yield();
858: }
859: dprintf(6, "powerup iobase=%x st=%x\n", base, status);
860: return status;
861: }
862:
1.1.1.2 root 863: // Detect any drives attached to a given controller.
1.1 root 864: static void
865: ata_detect(void *data)
866: {
1.1.1.3 ! root 867: struct ata_channel_s *chan_gf = data;
! 868: struct atadrive_s dummy;
1.1 root 869: memset(&dummy, 0, sizeof(dummy));
1.1.1.3 ! root 870: dummy.chan_gf = chan_gf;
1.1 root 871: // Device detection
1.1.1.3 ! root 872: int didreset = 0;
! 873: u8 slave;
! 874: for (slave=0; slave<=1; slave++) {
1.1 root 875: // Wait for not-bsy.
1.1.1.3 ! root 876: u16 iobase1 = chan_gf->iobase1;
1.1 root 877: int status = powerup_await_non_bsy(iobase1);
878: if (status < 0)
879: continue;
880: u8 newdh = slave ? ATA_CB_DH_DEV1 : ATA_CB_DH_DEV0;
881: outb(newdh, iobase1+ATA_CB_DH);
882: ndelay(400);
883: status = powerup_await_non_bsy(iobase1);
884: if (status < 0)
885: continue;
886:
887: // Check if ioport registers look valid.
888: outb(newdh, iobase1+ATA_CB_DH);
889: u8 dh = inb(iobase1+ATA_CB_DH);
890: outb(0x55, iobase1+ATA_CB_SC);
891: outb(0xaa, iobase1+ATA_CB_SN);
892: u8 sc = inb(iobase1+ATA_CB_SC);
893: u8 sn = inb(iobase1+ATA_CB_SN);
1.1.1.3 ! root 894: dprintf(6, "ata_detect ata%d-%d: sc=%x sn=%x dh=%x\n"
! 895: , chan_gf->chanid, slave, sc, sn, dh);
1.1 root 896: if (sc != 0x55 || sn != 0xaa || dh != newdh)
897: continue;
898:
899: // Prepare new drive.
1.1.1.3 ! root 900: dummy.slave = slave;
1.1 root 901:
902: // reset the channel
1.1.1.3 ! root 903: if (!didreset) {
1.1 root 904: ata_reset(&dummy);
1.1.1.3 ! root 905: didreset = 1;
1.1 root 906: }
907:
908: // check for ATAPI
909: u16 buffer[256];
1.1.1.3 ! root 910: struct atadrive_s *adrive_g = init_drive_atapi(&dummy, buffer);
! 911: if (!adrive_g) {
1.1 root 912: // Didn't find an ATAPI drive - look for ATA drive.
913: u8 st = inb(iobase1+ATA_CB_STAT);
914: if (!st)
915: // Status not set - can't be a valid drive.
916: continue;
917:
918: // Wait for RDY.
919: int ret = await_rdy(iobase1);
920: if (ret < 0)
921: continue;
922:
923: // check for ATA.
1.1.1.3 ! root 924: adrive_g = init_drive_ata(&dummy, buffer);
! 925: if (!adrive_g)
1.1 root 926: // No ATA drive found
927: continue;
928: }
929:
930: u16 resetresult = buffer[93];
931: dprintf(6, "ata_detect resetresult=%04x\n", resetresult);
932: if (!slave && (resetresult & 0xdf61) == 0x4041)
933: // resetresult looks valid and device 0 is responding to
934: // device 1 requests - device 1 must not be present - skip
935: // detection.
1.1.1.3 ! root 936: break;
1.1 root 937: }
938: }
939:
1.1.1.2 root 940: // Initialize an ata controller and detect its drives.
1.1 root 941: static void
1.1.1.3 ! root 942: init_controller(int chanid, int bdf, int irq, u32 port1, u32 port2, u32 master)
1.1 root 943: {
1.1.1.3 ! root 944: struct ata_channel_s *chan_gf = malloc_fseg(sizeof(*chan_gf));
! 945: if (!chan_gf) {
! 946: warn_noalloc();
! 947: return;
! 948: }
! 949: chan_gf->chanid = chanid;
! 950: chan_gf->irq = irq;
! 951: chan_gf->pci_bdf = bdf;
! 952: chan_gf->iobase1 = port1;
! 953: chan_gf->iobase2 = port2;
! 954: chan_gf->iomaster = master;
1.1.1.2 root 955: dprintf(1, "ATA controller %d at %x/%x/%x (irq %d dev %x)\n"
1.1.1.3 ! root 956: , chanid, port1, port2, master, irq, bdf);
! 957: run_thread(ata_detect, chan_gf);
1.1 root 958: }
959:
960: #define IRQ_ATA1 14
961: #define IRQ_ATA2 15
962:
1.1.1.2 root 963: // Locate and init ata controllers.
1.1 root 964: static void
1.1.1.2 root 965: ata_init(void)
1.1 root 966: {
967: // Scan PCI bus for ATA adapters
968: int count=0, pcicount=0;
969: int bdf, max;
970: foreachpci(bdf, max) {
971: pcicount++;
972: if (pci_config_readw(bdf, PCI_CLASS_DEVICE) != PCI_CLASS_STORAGE_IDE)
973: continue;
974:
975: u8 pciirq = pci_config_readb(bdf, PCI_INTERRUPT_LINE);
976: u8 prog_if = pci_config_readb(bdf, PCI_CLASS_PROG);
1.1.1.2 root 977: int master = 0;
1.1.1.3 ! root 978: if (CONFIG_ATA_DMA && prog_if & 0x80) {
1.1.1.2 root 979: // Check for bus-mastering.
980: u32 bar = pci_config_readl(bdf, PCI_BASE_ADDRESS_4);
981: if (bar & PCI_BASE_ADDRESS_SPACE_IO) {
982: master = bar & PCI_BASE_ADDRESS_IO_MASK;
983: pci_config_maskw(bdf, PCI_COMMAND, 0, PCI_COMMAND_MASTER);
984: }
985: }
986:
1.1 root 987: u32 port1, port2, irq;
988: if (prog_if & 1) {
1.1.1.3 ! root 989: port1 = (pci_config_readl(bdf, PCI_BASE_ADDRESS_0)
! 990: & PCI_BASE_ADDRESS_IO_MASK);
! 991: port2 = (pci_config_readl(bdf, PCI_BASE_ADDRESS_1)
! 992: & PCI_BASE_ADDRESS_IO_MASK);
1.1 root 993: irq = pciirq;
994: } else {
995: port1 = PORT_ATA1_CMD_BASE;
996: port2 = PORT_ATA1_CTRL_BASE;
997: irq = IRQ_ATA1;
998: }
1.1.1.3 ! root 999: init_controller(count, bdf, irq, port1, port2, master);
1.1 root 1000: count++;
1001:
1002: if (prog_if & 4) {
1.1.1.3 ! root 1003: port1 = (pci_config_readl(bdf, PCI_BASE_ADDRESS_2)
! 1004: & PCI_BASE_ADDRESS_IO_MASK);
! 1005: port2 = (pci_config_readl(bdf, PCI_BASE_ADDRESS_3)
! 1006: & PCI_BASE_ADDRESS_IO_MASK);
1.1 root 1007: irq = pciirq;
1008: } else {
1009: port1 = PORT_ATA2_CMD_BASE;
1010: port2 = PORT_ATA2_CTRL_BASE;
1011: irq = IRQ_ATA2;
1012: }
1.1.1.3 ! root 1013: init_controller(count, bdf, irq, port1, port2, master ? master + 8 : 0);
1.1 root 1014: count++;
1015: }
1016:
1.1.1.3 ! root 1017: if (!CONFIG_COREBOOT && !pcicount) {
1.1 root 1018: // No PCI devices found - probably a QEMU "-M isapc" machine.
1019: // Try using ISA ports for ATA controllers.
1.1.1.3 ! root 1020: init_controller(0, -1, IRQ_ATA1
1.1.1.2 root 1021: , PORT_ATA1_CMD_BASE, PORT_ATA1_CTRL_BASE, 0);
1.1.1.3 ! root 1022: init_controller(1, -1, IRQ_ATA2
1.1.1.2 root 1023: , PORT_ATA2_CMD_BASE, PORT_ATA2_CTRL_BASE, 0);
1.1 root 1024: }
1025: }
1026:
1027: void
1.1.1.2 root 1028: ata_setup(void)
1.1 root 1029: {
1.1.1.3 ! root 1030: ASSERT32FLAT();
1.1 root 1031: if (!CONFIG_ATA)
1032: return;
1033:
1034: dprintf(3, "init hard drives\n");
1035:
1036: SpinupEnd = calc_future_tsc(IDE_TIMEOUT);
1037: ata_init();
1038:
1039: SET_BDA(disk_control_byte, 0xc0);
1040:
1041: enable_hwirq(14, entry_76);
1042: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.