Changeset 38


Ignore:
Timestamp:
Nov 5, 2010, 7:13:11 PM (15 years ago)
Author:
markus
Message:

changes for drive geometry mapping

Location:
trunk/src/os2ahci
Files:
2 edited

Legend:

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

    r36 r38  
    431431  u16 *id_buf = add_workspace(iorb)->buf;
    432432
    433   /* Fill-in geometry information; os2ahci has been designed for devices
    434    * adhering to the ATA spec v8 or later, thus the real geometry doesn't
    435    * really matter (it's actually marked "obsolete" in the ATA 8 specs).
    436    * In order to maintain compatibitily to the BIOS and partition tables,
    437    * we'll use the same algorithm as used by typical PC BIOS versions:
     433  /* Fill-in geometry information; the ATA-8 spec declares the geometry
     434   * fields in the ATA ID buffer as obsolete but it's still the best
     435   * guess in most cases. If the information stored in the geometry
     436   * fields is apparently incorrect, we'll use the algorithm typically
     437   * used by SCSI adapters and modern PC BIOS releases:
    438438   *
    439439   *  - 512 bytes per sector
     
    459459   */
    460460  memset(geometry, 0x00, geometry_len);
     461  geometry->BytesPerSector  = 512;
    461462
    462463  /* extract total number of sectors */
    463464  if (id_buf[ATA_ID_CFS_ENABLE_2] & 0x40) {
    464465    /* 48-bit LBA supported */
    465     if (id_buf[ATA_ID_LBA_CAPACITY_2 + 2] != 0) {
     466    if (ATA_CAPACITY48_H(id_buf) != 0) {
    466467      /* more than 32 bits for number of sectors */
    467468      dprintf("warning: limiting disk %d.%d.%d to 2TB\n",
     
    470471      geometry->TotalSectors = 0xffffffffUL;
    471472    } else {
    472       geometry->TotalSectors = *((u32 *) (id_buf + ATA_ID_LBA_CAPACITY_2));
     473      geometry->TotalSectors = ATA_CAPACITY48_L(id_buf);
    473474    }
    474475  } else {
    475476    /* 28-bit LBA */
    476     geometry->TotalSectors = *((u32 *) (id_buf + ATA_ID_LBA_CAPACITY)) &
    477                              0x0fffffffUL;
    478   }
    479 
    480   geometry->BytesPerSector  = 512;
    481   geometry->NumHeads        = 255;
    482   geometry->SectorsPerTrack = 63;
    483   geometry->TotalCylinders  = geometry->TotalSectors /
    484                                ((u32) geometry->NumHeads *
    485                                 (u32) geometry->SectorsPerTrack);
     477    geometry->TotalSectors = ATA_CAPACITY(id_buf) & 0x0fffffffUL;
     478  }
     479
     480  /* see whether the "current" (read: BIOS-supplied) geometry looks OK */
     481  if (CUR_HEADS(id_buf) > 0 && CUR_CYLS(id_buf) > 0 &&
     482      CUR_SECTORS(id_buf) > 0 &&
     483      CUR_CAPACITY(id_buf) == CUR_HEADS(id_buf) *
     484                              CUR_CYLS(id_buf) *
     485                              CUR_SECTORS(id_buf)) {
     486    /* use BIOS-supplied values for geometry */
     487    geometry->NumHeads        = CUR_HEADS(id_buf);
     488    geometry->SectorsPerTrack = CUR_SECTORS(id_buf);
     489    geometry->TotalCylinders  = CUR_CYLS(id_buf);
     490
     491  } else if (ATA_HEADS(id_buf) > 0 && ATA_CYLS(id_buf) > 0 &&
     492             ATA_SECTORS(id_buf) > 0) {
     493    /* use ATA-supplied values for geometry */
     494    geometry->NumHeads        = ATA_HEADS(id_buf);
     495    geometry->SectorsPerTrack = ATA_SECTORS(id_buf);
     496    geometry->TotalCylinders  = ATA_CYLS(id_buf);
     497
     498  } else {
     499    /* construct values based on typical [SCSI] BIOS algorithms */
     500    geometry->NumHeads        = 255;
     501    geometry->SectorsPerTrack = 63;
     502    geometry->TotalCylinders  = geometry->TotalSectors /
     503                                 ((u32) geometry->NumHeads *
     504                                  (u32) geometry->SectorsPerTrack);
     505  }
     506
     507  if (debug > 1) {
     508    printf("geometry information:\n");
     509    printf("  heads:     %d\n", (u16) geometry->NumHeads);
     510    printf("  sectors:   %d\n", (u16) geometry->SectorsPerTrack);
     511    printf("  cylinders: %d\n", (u16) geometry->TotalCylinders);
     512    printf("  capacity:  %ldMB\n", (u32) (geometry->TotalSectors / 2048));
     513  }
    486514
    487515  /* tell interrupt handler that this IORB is complete */
  • trunk/src/os2ahci/ata.h

    r13 r38  
    2121
    2222/* -------------------------- macros and constants ------------------------- */
     23
     24/******************************************************************************
     25 * Macros to access geometry values in the ATA ID buffer
     26 */
     27#define ATA_CYLS(id_buf)            *((u32 *) (id_buf + ATA_ID_CYLS))
     28#define ATA_HEADS(id_buf)           *((u32 *) (id_buf + ATA_ID_HEADS))
     29#define ATA_SECTORS(id_buf)         *((u32 *) (id_buf + ATA_ID_SECTORS))
     30#define ATA_CAPACITY(id_buf)        *((u32 *) (id_buf + ATA_ID_LBA_CAPACITY))
     31
     32#define ATA_CAPACITY48_L(id_buf)    *((u32 *) (id_buf + ATA_ID_LBA_CAPACITY_2))
     33#define ATA_CAPACITY48_H(id_buf)    *((u32 *) (id_buf + ATA_ID_LBA_CAPACITY_2 + 2))
     34
     35#define CUR_CYLS(id_buf)            *((u32 *) (id_buf + ATA_ID_CUR_CYLS))
     36#define CUR_HEADS(id_buf)           *((u32 *) (id_buf + ATA_ID_CUR_HEADS))
     37#define CUR_SECTORS(id_buf)         *((u32 *) (id_buf + ATA_ID_CUR_SECTORS))
     38#define CUR_CAPACITY(id_buf)        *((u32 *) (id_buf + ATA_ID_CUR_CAPACITY))
     39
    2340
    2441/******************************************************************************
     
    5067#define ATA_ID_CUR_HEADS        55
    5168#define ATA_ID_CUR_SECTORS      56
     69#define ATA_ID_CUR_CAPACITY     57
    5270#define ATA_ID_MULTSECT         59
    5371#define ATA_ID_LBA_CAPACITY     60
Note: See TracChangeset for help on using the changeset viewer.