- Timestamp:
- Mar 2, 2011, 11:48:03 PM (14 years ago)
- Location:
- trunk/src/os2ahci
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/os2ahci/ahci.c
r80 r82 298 298 ai->pci->vendor == PCI_VENDOR_ID_INTEL) { 299 299 300 /* This BIOS apparently accesses th iscontroller via SATA registers and300 /* This BIOS apparently accesses the controller via SATA registers and 301 301 * the AHCI spec says that we should issue a COMRESET on each port after 302 302 * disabling AHCI mode to allow the SATA controller to re-recognize attached … … 402 402 if (ai->bios_config[HOST_CTL / sizeof(u32)] & HOST_AHCI_EN) { 403 403 /* BIOS uses AHCI, too, so we need to restore the port settings; 404 * restoring PORT_CMD way well start the port again but that's what404 * restoring PORT_CMD may well start the port again but that's what 405 405 * this function is all about. 406 406 */ … … 579 579 } 580 580 } 581 582 581 if (i >= irq_map_cnt) { 583 582 dprintf("registering interrupt #%d\n", ai->irq); 584 585 583 if (DevHelp_SetIRQ(mk_NPFN(irq_handlers[irq_map_cnt]), ai->irq, 1) != 0) { 586 584 dprintf("failed to register shared interrupt\n"); 587 588 585 if (DevHelp_SetIRQ(mk_NPFN(irq_handlers[irq_map_cnt]), ai->irq, 0) != 0) { 589 586 dprintf("failed to register exclusive interrupt\n"); … … 672 669 673 670 /* set link speed and power management options */ 671 ddprintf("setting link speed and power management options\n"); 674 672 tmp = readl(port_mmio + PORT_SCR_CTL) & ~0x00000ff0UL; 675 673 tmp |= ((u32) link_speed[ad_no(ai)][p] & 0x0f) << 4; … … 678 676 679 677 /* issue COMRESET on the port */ 678 ddprintf("issuing COMRESET on port\n"); 680 679 tmp = readl(port_mmio + PORT_SCR_CTL) & ~0x0000000fUL; 681 680 writel(port_mmio + PORT_SCR_CTL, tmp | 1); … … 704 703 705 704 /* start port so we can receive the COMRESET FIS */ 705 ddprintf("starting port again\n"); 706 706 ahci_start_port(ai, p, ei); 707 707 … … 989 989 990 990 if (!init_complete) { 991 /* no IRQ handlers or context hooks availabe at this point */ 991 992 ai->busy = 1; 992 993 spin_unlock(drv_lock); … … 1014 1015 1015 1016 if ((*cmds & (1UL << port->cmd_slot)) == 0) { 1016 /* prepare command */1017 /* found idle command slot; prepare command */ 1017 1018 if (func(iorb, port->cmd_slot)) { 1018 1019 /* Command preparation failed, or no HW command required; IORB -
trunk/src/os2ahci/ata.c
r80 r82 137 137 /* ATA device byte; note that this byte contains the highest 138 138 * 4 bits of LBA-28 address; we have to leave them alone here. */ 139 ata_cmd.device |= (va_arg(va, u16) & 0xf000U) >> 8;139 ata_cmd.device |= va_arg(va, u16) & 0xf0U; 140 140 break; 141 141 … … 202 202 memset(cmd_hdr, 0x00, sizeof(*cmd_hdr)); 203 203 cmd_hdr->options = ((d & 0x0f) << 12); 204 cmd_hdr->options |= ahci_flags; /* AHCI comma and flags */204 cmd_hdr->options |= ahci_flags; /* AHCI command flags */ 205 205 cmd_hdr->options |= 5; /* length of command FIS in 32-bit words */ 206 206 cmd_hdr->tbl_addr = dma_base_phys + offsetof(AHCI_PORT_DMA, cmd_tbl[slot]); … … 435 435 USHORT geometry_len = ((IORB_GEOMETRY _far *) iorb)->GeometryLen; 436 436 u16 *id_buf = add_workspace(iorb)->buf; 437 int a = iorb_unit_adapter(iorb); 438 int p = iorb_unit_port(iorb); 437 439 438 440 /* Fill-in geometry information; the ATA-8 spec declares the geometry … … 444 446 * - 512 bytes per sector 445 447 * - 255 heads 446 * - 63 sectors per track 448 * - 63 sectors per track (or 56 with the parameter "/4") 447 449 * - x cylinders (calculated) 448 450 * 449 * Please note that os2ahci currently does not support ATA sectors larger450 * than 512 bytes, therefore relies on the translation logic built into the451 * corresponding ATA disks. In theory, partitions should be aligned to the452 * large sectors to prevent needless mapping all over the place but HPFS453 * uses logical block sizes smaller than the typical large sectors found on454 * modern hard disks so this won't make much of a difference. Large sector455 * support will be evaluated at a later time (it's unclear right now whether456 * HPFS would even support anything larger than 512 bytes).451 * Please note that os2ahci currently does not natively support ATA sectors 452 * larger than 512 bytes, therefore relies on the translation logic built 453 * into the corresponding ATA disks. In order to prevent file systems that 454 * use block sizes larger than 512 bytes (FAT, JFS, ...) from ending up on 455 * incorrectly aligned physical sector accesses, hence using more physical 456 * I/Os than necessary, the command line parameter "/4" can be used to force 457 * a track size of 56 sectors. This way, partitions will start on 4K 458 * boundaries. 457 459 * 458 460 * Another limitation is that OS/2 has a 32-bit variable for the total number … … 464 466 */ 465 467 memset(geometry, 0x00, geometry_len); 466 geometry->BytesPerSector = 512;468 geometry->BytesPerSector = ATA_SECTOR_SIZE; 467 469 468 470 /* extract total number of sectors */ … … 483 485 } 484 486 485 /* see whether the "current" (read: BIOS-supplied) geometry looks OK */ 486 if (CUR_HEADS(id_buf) > 0 && CUR_CYLS(id_buf) > 0 && 487 CUR_SECTORS(id_buf) > 0 && 488 CUR_CAPACITY(id_buf) == CUR_HEADS(id_buf) * 489 CUR_CYLS(id_buf) * 490 CUR_SECTORS(id_buf)) { 491 /* use BIOS-supplied values for geometry */ 487 /* fabricate the remaining geometry fields */ 488 if (track_size[a][p] != 0) { 489 /* A specific track size has been requested for this port; this is 490 * typically done for disks with 4K sectors to make sure partitions 491 * start on 8-sector boundaries (parameter "/4"). 492 */ 493 geometry->NumHeads = 255; 494 geometry->SectorsPerTrack = track_size[a][p]; 495 geometry->TotalCylinders = geometry->TotalSectors / 496 ((u32) geometry->NumHeads * 497 (u32) geometry->SectorsPerTrack); 498 499 } else if (CUR_HEADS(id_buf) > 0 && CUR_CYLS(id_buf) > 0 && 500 CUR_SECTORS(id_buf) > 0 && 501 CUR_CAPACITY(id_buf) == CUR_HEADS(id_buf) * 502 CUR_CYLS(id_buf) * 503 CUR_SECTORS(id_buf)) { 504 /* BIOS-supplied (aka "current") geometry values look valid */ 492 505 geometry->NumHeads = CUR_HEADS(id_buf); 493 506 geometry->SectorsPerTrack = CUR_SECTORS(id_buf); … … 496 509 } else if (ATA_HEADS(id_buf) > 0 && ATA_CYLS(id_buf) > 0 && 497 510 ATA_SECTORS(id_buf) > 0) { 498 /* use ATA-supplied values for geometry*/511 /* ATA-supplied values for geometry look valid */ 499 512 geometry->NumHeads = ATA_HEADS(id_buf); 500 513 geometry->SectorsPerTrack = ATA_SECTORS(id_buf); … … 549 562 int d = iorb_unit_device(iorb); 550 563 int rc; 564 565 /* Kludge: some I/O commands during boot use excessive S/G buffer lengths 566 * which cause NCQ commands to lock up. If there's only one S/G element 567 * and this element is already larger than what we can derive from the sector 568 * count, we'll adjust that element. 569 */ 570 if (io->BlocksXferred == 0 && io->cSGList == 1 && 571 io->pSGList[0].XferBufLen > io->BlockCount * io->BlockSize) { 572 io->pSGList[0].XferBufLen = io->BlockCount * io->BlockSize; 573 } 551 574 552 575 /* prepare read command while keeping an eye on S/G count limitations */ … … 568 591 AP_COUNT, (u16) (slot << 3), /* tag = slot */ 569 592 AP_SGLIST, io->pSGList + sg_indx, (u16) sg_cnt, 570 AP_DEVICE, 0x40 00,593 AP_DEVICE, 0x40, 571 594 AP_END); 572 595 } else { … … 575 598 AP_COUNT, (u16) count, 576 599 AP_SGLIST, io->pSGList + sg_indx, (u16) sg_cnt, 577 AP_DEVICE, 0x40 00,600 AP_DEVICE, 0x40, 578 601 AP_END); 579 602 } … … 584 607 AP_COUNT, (u16) count & 0xffU, 585 608 AP_SGLIST, io->pSGList + sg_indx, (u16) sg_cnt, 586 AP_DEVICE, 0x40 00,609 AP_DEVICE, 0x40, 587 610 AP_END); 588 611 } … … 650 673 AP_SECTOR_48, (u32) io->RBA, (u16) 0, 651 674 AP_COUNT, (u16) io->BlockCount, 652 AP_DEVICE, 0x40 00,675 AP_DEVICE, 0x40, 653 676 AP_END); 654 677 } else { … … 695 718 AP_COUNT, (u16) (slot << 3), /* tag = slot */ 696 719 AP_SGLIST, io->pSGList + sg_indx, (u16) sg_cnt, 697 AP_DEVICE, 0x40 00,720 AP_DEVICE, 0x40, 698 721 AP_DEVICE, (io->Flags & XIO_DISABLE_HW_WRITE_CACHE) ? 699 0x80 00: 0, /* force unit access */722 0x80 : 0, /* force unit access */ 700 723 AP_WRITE, 1, 701 724 AP_END); … … 705 728 AP_COUNT, (u16) count, 706 729 AP_SGLIST, io->pSGList + sg_indx, (u16) sg_cnt, 707 AP_DEVICE, 0x40 00,730 AP_DEVICE, 0x40, 708 731 AP_WRITE, 1, 709 732 AP_END); … … 715 738 AP_COUNT, (u16) count & 0xffU, 716 739 AP_SGLIST, io->pSGList + sg_indx, (u16) sg_cnt, 717 AP_DEVICE, 0x40 00,740 AP_DEVICE, 0x40, 718 741 AP_WRITE, 1, 719 742 AP_END); … … 826 849 iorb_seterr(iorb, IOERR_DEVICE_NONSPECIFIC); 827 850 } 851 } else { 852 /* this function only gets called when we received an error interrupt */ 853 iorb_seterr(iorb, IOERR_DEVICE_NONSPECIFIC); 828 854 } 829 855 -
trunk/src/os2ahci/ata.h
r76 r82 21 21 22 22 /* -------------------------- macros and constants ------------------------- */ 23 24 /****************************************************************************** 25 * Right now, os2ahci uses a fixed sector size of 512 bytes for hard disks. 26 * This may change in the future... 27 */ 28 #define ATA_SECTOR_SIZE 512 23 29 24 30 /****************************************************************************** … … 411 417 AP_SECTOR_28, /* [u32] 28-bit sector address */ 412 418 AP_SECTOR_48, /* [u32, u16] 48-bit sector address */ 413 AP_DEVICE, /* [u16] ATA cmd "device" field (LSB masked)*/419 AP_DEVICE, /* [u16] ATA cmd "device" field */ 414 420 AP_SGLIST, /* [void _far *, u16] buffer S/G (SCATGATENTRY/count) */ 415 421 AP_VADDR, /* [void _far *, u16] buffer virtual address (buf/len) */ -
trunk/src/os2ahci/atapi.c
r77 r82 96 96 AP_ATAPI_CMD, (void _far *) &cdb, sizeof(cdb), 97 97 AP_SGLIST, io->pSGList + sg_indx, (u16) sg_cnt, 98 AP_DEVICE, 0x40 00,98 AP_DEVICE, 0x40, 99 99 AP_FEATURES, ATAPI_FEAT_DMA | ATAPI_FEAT_DMA_TO_HOST, 100 100 AP_END); -
trunk/src/os2ahci/ctxhook.c
r80 r82 75 75 * they couldn't be reordered by the device) with the 'no_ncq' flag set 76 76 * in the IORB and reset the port. Then those comands will be executed as 77 * regular commands. The error, if it reoccur rs, can be thenhandled by77 * regular commands. The error, if it reoccurs, can then be handled by 78 78 * one of the above cases. 79 79 * -
trunk/src/os2ahci/libc.c
r77 r82 246 246 247 247 /****************************************************************************** 248 * Print messages to COM248 * Print messages to serial port 249 249 * 250 250 * NOTES: This function uses a 1K buffer for the resulting message. Thus, … … 260 260 vsprintf(buf, fmt, va); 261 261 262 /* write debug message to COM1*/262 /* write debug message to serial port */ 263 263 for (s = buf; *s != '\0'; s++) { 264 264 … … 547 547 * Calibrate 'mdelay()' loop. This is done by setting up a 1 second timer 548 548 * with a callback that sets 'mdelay_done' to MD_CALIBRATION_END. Then it 549 * calls mdelay() with a large milliseond value a n initial delay loop counter550 * of 1,000,000. When the timer triggers, 'mdelay()' will stop and update551 * the delay loopcounter.549 * calls mdelay() with a large milliseond value as initial delay loop counter. 550 * When the timer triggers, 'mdelay()' will stop and update the delay loop 551 * counter. 552 552 * 553 553 * This function needs to be called at device driver init time. Since it uses -
trunk/src/os2ahci/os2ahci.c
r80 r82 104 104 u8 link_speed[MAX_AD][AHCI_MAX_PORTS]; 105 105 u8 link_power[MAX_AD][AHCI_MAX_PORTS]; 106 u8 track_size[MAX_AD][AHCI_MAX_PORTS]; 106 107 107 108 static char init_msg[] = "OS2AHCI driver version %d.%02d\n"; … … 260 261 261 262 case 'n': 262 /* disable NCQ */263 /* enable NCQ */ 263 264 set_port_option(enable_ncq, !invert_option); 264 265 break; … … 286 287 break; 287 288 289 case '4': 290 /* enable 4K sector geometry enhancement (track size = 56) */ 291 if (!invert_option) { 292 set_port_option(track_size, 56); 293 } 294 break; 295 288 296 default: 289 297 cprintf("invalid option: /%c\n", *s); -
trunk/src/os2ahci/os2ahci.def
r81 r82 1 1 library os2ahci 2 Description '$@#thi.guten (www.thiguten.de):1.00.2011030 1#@OS/2 AHCI Adapter Device Driver'2 Description '$@#thi.guten (www.thiguten.de):1.00.20110302#@OS/2 AHCI Adapter Device Driver' 3 3 protmode 4 4 -
trunk/src/os2ahci/os2ahci.h
r81 r82 513 513 extern u8 link_speed[MAX_AD][AHCI_MAX_PORTS]; 514 514 extern u8 link_power[MAX_AD][AHCI_MAX_PORTS]; 515 515 extern u8 track_size[MAX_AD][AHCI_MAX_PORTS]; 516 -
trunk/src/os2ahci/pci.c
r81 r82 1008 1008 1009 1009 ddprintf("BAR #%d: type = %s, addr = 0x%08lx, size = %ld\n", i, 1010 (resource->ResourceType == RS_TYPE_IO) ? "I/O" : "M MIO",1010 (resource->ResourceType == RS_TYPE_IO) ? "I/O" : "MEM", 1011 1011 bar_addr, bar_size); 1012 1012 -
trunk/src/os2ahci/version.h
r81 r82 6 6 7 7 8 #define VERSION 10 7/* driver version (2 implied decimals) */8 #define VERSION 109 /* driver version (2 implied decimals) */ 9 9 10 10 /* BLDLEVEL information (in C source modules added via macro
Note:
See TracChangeset
for help on using the changeset viewer.