Changeset 82 for trunk


Ignore:
Timestamp:
Mar 2, 2011, 11:48:03 PM (14 years ago)
Author:
chris
Message:

Version 1.09
============

  • Added new command line parameter, "/4", which will force a track size of 56 sectors to be reported in geometry requests. This will improve performance for newer HDs with 4K sectors and file systems which use block sizes larger than 512 bytes (FAT, JFS, ...) because all partitions will be aligned on 4K (8 sector) boundaries.
  • Changed AP_DEVICE parameter to ata_cmd() from 16 bits to 8 bits -- the corresponding field in ATA_CMD has always been 8 bits and there's no point discarding the lower 8 bits of the AP_DEVICE parameter as a general rule. Besides, it confused me in the end...
  • Always return some kind of error in ata_req_sense() because this function will only be called when we received an error interrupt; atapi_req_sense() already does this.
  • Cosmetic changes
Location:
trunk/src/os2ahci
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/os2ahci/ahci.c

    r80 r82  
    298298      ai->pci->vendor == PCI_VENDOR_ID_INTEL) {
    299299
    300     /* This BIOS apparently accesses this controller via SATA registers and
     300    /* This BIOS apparently accesses the controller via SATA registers and
    301301     * the AHCI spec says that we should issue a COMRESET on each port after
    302302     * disabling AHCI mode to allow the SATA controller to re-recognize attached
     
    402402  if (ai->bios_config[HOST_CTL / sizeof(u32)] & HOST_AHCI_EN) {
    403403    /* 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 what
     404     * restoring PORT_CMD may well start the port again but that's what
    405405     * this function is all about.
    406406     */
     
    579579    }
    580580  }
    581 
    582581  if (i >= irq_map_cnt) {
    583582    dprintf("registering interrupt #%d\n", ai->irq);
    584 
    585583    if (DevHelp_SetIRQ(mk_NPFN(irq_handlers[irq_map_cnt]), ai->irq, 1) != 0) {
    586584      dprintf("failed to register shared interrupt\n");
    587 
    588585      if (DevHelp_SetIRQ(mk_NPFN(irq_handlers[irq_map_cnt]), ai->irq, 0) != 0) {
    589586        dprintf("failed to register exclusive interrupt\n");
     
    672669
    673670  /* set link speed and power management options */
     671  ddprintf("setting link speed and power management options\n");
    674672  tmp = readl(port_mmio + PORT_SCR_CTL) & ~0x00000ff0UL;
    675673  tmp |= ((u32) link_speed[ad_no(ai)][p] & 0x0f) << 4;
     
    678676
    679677  /* issue COMRESET on the port */
     678  ddprintf("issuing COMRESET on port\n");
    680679  tmp = readl(port_mmio + PORT_SCR_CTL) & ~0x0000000fUL;
    681680  writel(port_mmio + PORT_SCR_CTL, tmp | 1);
     
    704703
    705704  /* start port so we can receive the COMRESET FIS */
     705  ddprintf("starting port again\n");
    706706  ahci_start_port(ai, p, ei);
    707707
     
    989989
    990990    if (!init_complete) {
     991      /* no IRQ handlers or context hooks availabe at this point */
    991992      ai->busy = 1;
    992993      spin_unlock(drv_lock);
     
    10141015
    10151016      if ((*cmds & (1UL << port->cmd_slot)) == 0) {
    1016         /* prepare command */
     1017        /* found idle command slot; prepare command */
    10171018        if (func(iorb, port->cmd_slot)) {
    10181019          /* Command preparation failed, or no HW command required; IORB
  • trunk/src/os2ahci/ata.c

    r80 r82  
    137137      /* ATA device byte; note that this byte contains the highest
    138138       * 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;
    140140      break;
    141141
     
    202202  memset(cmd_hdr, 0x00, sizeof(*cmd_hdr));
    203203  cmd_hdr->options  = ((d & 0x0f) << 12);
    204   cmd_hdr->options |= ahci_flags;  /* AHCI commaand flags */
     204  cmd_hdr->options |= ahci_flags;  /* AHCI command flags */
    205205  cmd_hdr->options |= 5;           /* length of command FIS in 32-bit words */
    206206  cmd_hdr->tbl_addr = dma_base_phys + offsetof(AHCI_PORT_DMA, cmd_tbl[slot]);
     
    435435  USHORT geometry_len =  ((IORB_GEOMETRY _far *) iorb)->GeometryLen;
    436436  u16 *id_buf = add_workspace(iorb)->buf;
     437  int a = iorb_unit_adapter(iorb);
     438  int p = iorb_unit_port(iorb);
    437439
    438440  /* Fill-in geometry information; the ATA-8 spec declares the geometry
     
    444446   *  - 512 bytes per sector
    445447   *  - 255 heads
    446    *  -  63 sectors per track
     448   *  -  63 sectors per track (or 56 with the parameter "/4")
    447449   *  -   x cylinders (calculated)
    448450   *
    449    * Please note that os2ahci currently does not support ATA sectors larger
    450    * than 512 bytes, therefore relies on the translation logic built into the
    451    * corresponding ATA disks. In theory, partitions should be aligned to the
    452    * large sectors to prevent needless mapping all over the place but HPFS
    453    * uses logical block sizes smaller than the typical large sectors found on
    454    * modern hard disks so this won't make much of a difference. Large sector
    455    * support will be evaluated at a later time (it's unclear right now whether
    456    * 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.
    457459   *
    458460   * Another limitation is that OS/2 has a 32-bit variable for the total number
     
    464466   */
    465467  memset(geometry, 0x00, geometry_len);
    466   geometry->BytesPerSector  = 512;
     468  geometry->BytesPerSector = ATA_SECTOR_SIZE;
    467469
    468470  /* extract total number of sectors */
     
    483485  }
    484486
    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 */
    492505    geometry->NumHeads        = CUR_HEADS(id_buf);
    493506    geometry->SectorsPerTrack = CUR_SECTORS(id_buf);
     
    496509  } else if (ATA_HEADS(id_buf) > 0 && ATA_CYLS(id_buf) > 0 &&
    497510             ATA_SECTORS(id_buf) > 0) {
    498     /* use ATA-supplied values for geometry */
     511    /* ATA-supplied values for geometry look valid */
    499512    geometry->NumHeads        = ATA_HEADS(id_buf);
    500513    geometry->SectorsPerTrack = ATA_SECTORS(id_buf);
     
    549562  int d = iorb_unit_device(iorb);
    550563  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  }
    551574
    552575  /* prepare read command while keeping an eye on S/G count limitations */
     
    568591                     AP_COUNT,     (u16) (slot << 3), /* tag = slot */
    569592                     AP_SGLIST,    io->pSGList + sg_indx, (u16) sg_cnt,
    570                      AP_DEVICE,    0x4000,
     593                     AP_DEVICE,    0x40,
    571594                     AP_END);
    572595      } else {
     
    575598                     AP_COUNT,     (u16) count,
    576599                     AP_SGLIST,    io->pSGList + sg_indx, (u16) sg_cnt,
    577                      AP_DEVICE,    0x4000,
     600                     AP_DEVICE,    0x40,
    578601                     AP_END);
    579602      }
     
    584607                   AP_COUNT,     (u16) count & 0xffU,
    585608                   AP_SGLIST,    io->pSGList + sg_indx, (u16) sg_cnt,
    586                    AP_DEVICE,    0x4000,
     609                   AP_DEVICE,    0x40,
    587610                   AP_END);
    588611    }
     
    650673                 AP_SECTOR_48, (u32) io->RBA, (u16) 0,
    651674                 AP_COUNT,     (u16) io->BlockCount,
    652                  AP_DEVICE,    0x4000,
     675                 AP_DEVICE,    0x40,
    653676                 AP_END);
    654677  } else {
     
    695718                     AP_COUNT,     (u16) (slot << 3), /* tag = slot */
    696719                     AP_SGLIST,    io->pSGList + sg_indx, (u16) sg_cnt,
    697                      AP_DEVICE,    0x4000,
     720                     AP_DEVICE,    0x40,
    698721                     AP_DEVICE,    (io->Flags & XIO_DISABLE_HW_WRITE_CACHE) ?
    699                                    0x8000 : 0, /* force unit access */
     722                                   0x80 : 0, /* force unit access */
    700723                     AP_WRITE,     1,
    701724                     AP_END);
     
    705728                     AP_COUNT,     (u16) count,
    706729                     AP_SGLIST,    io->pSGList + sg_indx, (u16) sg_cnt,
    707                      AP_DEVICE,    0x4000,
     730                     AP_DEVICE,    0x40,
    708731                     AP_WRITE,     1,
    709732                     AP_END);
     
    715738                   AP_COUNT,     (u16) count & 0xffU,
    716739                   AP_SGLIST,    io->pSGList + sg_indx, (u16) sg_cnt,
    717                    AP_DEVICE,    0x4000,
     740                   AP_DEVICE,    0x40,
    718741                   AP_WRITE,     1,
    719742                   AP_END);
     
    826849      iorb_seterr(iorb, IOERR_DEVICE_NONSPECIFIC);
    827850    }
     851  } else {
     852    /* this function only gets called when we received an error interrupt */
     853    iorb_seterr(iorb, IOERR_DEVICE_NONSPECIFIC);
    828854  }
    829855
  • trunk/src/os2ahci/ata.h

    r76 r82  
    2121
    2222/* -------------------------- 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
    2329
    2430/******************************************************************************
     
    411417  AP_SECTOR_28,    /* [u32]               28-bit sector address              */
    412418  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             */
    414420  AP_SGLIST,       /* [void _far *, u16]  buffer S/G (SCATGATENTRY/count)    */
    415421  AP_VADDR,        /* [void _far *, u16]  buffer virtual address (buf/len)   */
  • trunk/src/os2ahci/atapi.c

    r77 r82  
    9696                 AP_ATAPI_CMD, (void _far *) &cdb, sizeof(cdb),
    9797                 AP_SGLIST,    io->pSGList + sg_indx, (u16) sg_cnt,
    98                  AP_DEVICE,    0x4000,
     98                 AP_DEVICE,    0x40,
    9999                 AP_FEATURES,  ATAPI_FEAT_DMA | ATAPI_FEAT_DMA_TO_HOST,
    100100                 AP_END);
  • trunk/src/os2ahci/ctxhook.c

    r80 r82  
    7575 *    they couldn't be reordered by the device) with the 'no_ncq' flag set
    7676 *    in the IORB and reset the port. Then those comands will be executed as
    77  *    regular commands. The error, if it reoccurrs, can be then handled by
     77 *    regular commands. The error, if it reoccurs, can then be handled by
    7878 *    one of the above cases.
    7979 *
  • trunk/src/os2ahci/libc.c

    r77 r82  
    246246
    247247/******************************************************************************
    248  * Print messages to COM
     248 * Print messages to serial port
    249249 *
    250250 * NOTES: This function uses a 1K buffer for the resulting message. Thus,
     
    260260  vsprintf(buf, fmt, va);
    261261
    262   /* write debug message to COM1 */
     262  /* write debug message to serial port */
    263263  for (s = buf; *s != '\0'; s++) {
    264264
     
    547547 * Calibrate 'mdelay()' loop. This is done by setting up a 1 second timer
    548548 * with a callback that sets 'mdelay_done' to MD_CALIBRATION_END. Then it
    549  * calls mdelay() with a large milliseond value an initial delay loop counter
    550  * of 1,000,000. When the timer triggers, 'mdelay()' will stop and update
    551  * the delay loop counter.
     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.
    552552 *
    553553 * This function needs to be called at device driver init time. Since it uses
  • trunk/src/os2ahci/os2ahci.c

    r80 r82  
    104104u8              link_speed[MAX_AD][AHCI_MAX_PORTS];
    105105u8              link_power[MAX_AD][AHCI_MAX_PORTS];
     106u8              track_size[MAX_AD][AHCI_MAX_PORTS];
    106107
    107108static char     init_msg[] = "OS2AHCI driver version %d.%02d\n";
     
    260261
    261262      case 'n':
    262         /* disable NCQ */
     263        /* enable NCQ */
    263264        set_port_option(enable_ncq, !invert_option);
    264265        break;
     
    286287        break;
    287288
     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
    288296      default:
    289297        cprintf("invalid option: /%c\n", *s);
  • trunk/src/os2ahci/os2ahci.def

    r81 r82  
    11library os2ahci
    2 Description '$@#thi.guten (www.thiguten.de):1.00.20110301#@OS/2 AHCI Adapter Device Driver'
     2Description '$@#thi.guten (www.thiguten.de):1.00.20110302#@OS/2 AHCI Adapter Device Driver'
    33protmode
    44
  • trunk/src/os2ahci/os2ahci.h

    r81 r82  
    513513extern u8            link_speed[MAX_AD][AHCI_MAX_PORTS];
    514514extern u8            link_power[MAX_AD][AHCI_MAX_PORTS];
    515 
     515extern u8            track_size[MAX_AD][AHCI_MAX_PORTS];
     516
  • trunk/src/os2ahci/pci.c

    r81 r82  
    10081008
    10091009  ddprintf("BAR #%d: type = %s, addr = 0x%08lx, size = %ld\n", i,
    1010            (resource->ResourceType == RS_TYPE_IO) ? "I/O" : "MMIO",
     1010           (resource->ResourceType == RS_TYPE_IO) ? "I/O" : "MEM",
    10111011           bar_addr, bar_size);
    10121012
  • trunk/src/os2ahci/version.h

    r81 r82  
    66
    77
    8 #define VERSION            107       /* driver version (2 implied decimals) */
     8#define VERSION            109       /* driver version (2 implied decimals) */
    99
    1010/* BLDLEVEL information (in C source modules added via macro
Note: See TracChangeset for help on using the changeset viewer.