Changeset 169 for trunk


Ignore:
Timestamp:
Aug 9, 2013, 12:17:15 AM (12 years ago)
Author:
David Azarewicz
Message:

Added a check for bad geometries reported by the BIOS and fix them.

Location:
trunk/src/os2ahci
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/os2ahci/Makefile

    r166 r169  
    3030# Define default build version if not specified in environment
    3131BLD_MAJOR=1
    32 BLD_MINOR=30 # must be 2 digits
     32BLD_MINOR=31 # must be 2 digits
    3333BLD_REV=0 # not used at this time
    3434FIXPACK=
     
    9292CFLAGS= -ei -6 -d0 -bt=os2 -ms -zu -wx -ecc -zp1 -q -s -zgp -zfp -oi
    9393CFLAGS_DEBUG = -ei -6 -d3 -hc -bt=os2 -ms -zu -ecc -zp1 -q -s -zgp -zfp -od
     94!ifneq FIXPACK
     95CFLAGS+= -DTESTVER
     96!endif
    9497
    9598###############################################################################
  • trunk/src/os2ahci/README

    r166 r169  
    394394==========
    395395
     396v.1.31 04-Aug-2013 - David Azarewicz
     397  Enhanced debug output.
     398  Added code to check for bad geometries reported by the BIOS and fix them.
     399
    396400v.1.30 29-Jun-2013 - David Azarewicz
    397401  Enhanced debug log output
  • trunk/src/os2ahci/ahci.c

    r167 r169  
    265265  }
    266266  ai->flags = initial_flags[ai->pci->board];
     267  ai->hw_ports = (ai->cap & 0x1f) + 1;
    267268
    268269  if ((ai->cap & HOST_CAP_64) && (ai->flags & AHCI_HFLAG_32BIT_ONLY)) {
     
    298299    dprintf("JMB361 has only one port, port_map 0x%lx -> 0x%lx\n", ai->port_map, 1);
    299300    ai->port_map = 1;
     301    ai->hw_ports = 1;
    300302  }
    301303
     
    309311   *       in ahci_scan_ports().
    310312   */
    311   ports = (ai->cap & 0x1f) + 1;
     313  ports = ai->hw_ports;
    312314  for (i = 0; i < AHCI_MAX_PORTS; i++) {
    313315    if (ai->port_map & (1UL << i)) {
     
    317319  if (ports < 0) {
    318320    /* more ports in port_map than in HOST_CAP & 0x1f */
    319     ports = (ai->cap & 0x1f) + 1;
     321    ports = ai->hw_ports;
    320322    dprintf("implemented port map (0x%lx) contains more "
    321323            "ports than nr_ports (%d), using nr_ports\n",
  • trunk/src/os2ahci/ata.c

    r165 r169  
    440440
    441441  return(rc);
     442}
     443
     444/* Adjust the cylinder count in the physical
     445 * geometry to the last full cylinder.
     446 */
     447int adjust_cylinders(GEOMETRY _far *geometry, ULONG TotalSectors) {
     448  USHORT SecPerCyl;
     449  int rc = FALSE;
     450
     451  geometry->TotalSectors = TotalSectors;
     452  SecPerCyl = geometry->SectorsPerTrack * geometry->NumHeads;
     453  if (SecPerCyl > 0) {
     454    ULONG TotalCylinders  = TotalSectors / SecPerCyl;
     455
     456    geometry->TotalSectors   = TotalCylinders * SecPerCyl;
     457    geometry->TotalCylinders = TotalCylinders;
     458    if (TotalCylinders >> 16) {
     459      geometry->TotalCylinders = 65535;
     460      rc = TRUE;
     461    }
     462  }
     463  return (rc);
     464}
     465
     466/* Calculate the logical geometry based on the input physcial geometry
     467 * using the LBA Assist Translation algorithm.
     468 */
     469#define BIOS_MAX_CYLINDERS       1024l
     470#define BIOS_MAX_NUMHEADS         255
     471#define BIOS_MAX_SECTORSPERTRACK   63
     472void log_geom_calculate_LBA_assist(GEOMETRY _far *geometry, ULONG TotalSectors)
     473{
     474  UCHAR numSpT   = BIOS_MAX_SECTORSPERTRACK;
     475  UCHAR numHeads = BIOS_MAX_NUMHEADS;
     476  ULONG Cylinders;
     477
     478  if (TotalSectors <= (BIOS_MAX_CYLINDERS * 128 * BIOS_MAX_SECTORSPERTRACK)) {
     479    USHORT temp = (TotalSectors - 1) / (BIOS_MAX_CYLINDERS * BIOS_MAX_SECTORSPERTRACK);
     480
     481    if (temp < 16)      numHeads = 16;
     482    else if (temp < 32) numHeads = 32;
     483    else if (temp < 64) numHeads = 64;
     484    else                numHeads = 128;
     485  }
     486
     487  do {
     488    Cylinders = TotalSectors / (USHORT)(numHeads * numSpT);
     489    if (Cylinders >> 16) {
     490      if (numSpT < 128)
     491        numSpT = (numSpT << 1) | 1;
     492      else
     493        Cylinders = 65535; // overflow !
     494    }
     495  } while (Cylinders >> 16);
     496
     497  geometry->TotalCylinders  = Cylinders;
     498  geometry->NumHeads        = numHeads;
     499  geometry->SectorsPerTrack = numSpT;
    442500}
    443501
     
    574632    geometry->NumHeads        = 255;
    575633    geometry->SectorsPerTrack = track_size[a][p];
    576     geometry->TotalCylinders  = geometry->TotalSectors /
    577                                  ((u32) geometry->NumHeads *
    578                                   (u32) geometry->SectorsPerTrack);
     634    geometry->TotalCylinders  = geometry->TotalSectors / ((u32) geometry->NumHeads * (u32) geometry->SectorsPerTrack);
    579635    Method = "Custom";
    580   } else if (CUR_HEADS(id_buf) > 0 && CUR_CYLS(id_buf) > 0 &&
    581              CUR_SECTORS(id_buf) > 0 &&
    582              CUR_CAPACITY(id_buf) == (u32) CUR_HEADS(id_buf) *
    583                                      (u32) CUR_CYLS(id_buf) *
    584                                      (u32) CUR_SECTORS(id_buf)) {
     636  } else if (CUR_HEADS(id_buf) > 0 && CUR_CYLS(id_buf) > 0 && CUR_SECTORS(id_buf) > 0 &&
     637             CUR_CAPACITY(id_buf) == (u32) CUR_HEADS(id_buf) * (u32) CUR_CYLS(id_buf) * (u32) CUR_SECTORS(id_buf)) {
    585638    /* BIOS-supplied (aka "current") geometry values look valid */
    586639    geometry->NumHeads        = CUR_HEADS(id_buf);
     
    588641    geometry->TotalCylinders  = CUR_CYLS(id_buf);
    589642    Method = "BIOS";
    590   } else if (ATA_HEADS(id_buf) > 0 && ATA_CYLS(id_buf) > 0 &&
    591              ATA_SECTORS(id_buf) > 0) {
     643  } else if (ATA_HEADS(id_buf) > 0 && ATA_CYLS(id_buf) > 0 && ATA_SECTORS(id_buf) > 0) {
    592644    /* ATA-supplied values for geometry look valid */
    593645    geometry->NumHeads        = ATA_HEADS(id_buf);
     
    599651    geometry->NumHeads        = 255;
    600652    geometry->SectorsPerTrack = 63;
    601     geometry->TotalCylinders  = geometry->TotalSectors /
    602                                  ((u32) geometry->NumHeads *
    603                                   (u32) geometry->SectorsPerTrack);
     653    geometry->TotalCylinders  = geometry->TotalSectors / ((u32) geometry->NumHeads * (u32) geometry->SectorsPerTrack);
    604654    Method = "SCSI";
    605655  }
     656
     657  dprintf("Physical geometry: %ld cylinders, %d heads, %d sectors per track (%ldMB) (%s)\n",
     658      (u32) geometry->TotalCylinders, (u16) geometry->NumHeads, (u16) geometry->SectorsPerTrack,
     659      (u32) (geometry->TotalSectors / 2048), Method);
     660
     661  /* Fixup the geometry in case the geometry reported by the BIOS is bad */
     662  if (adjust_cylinders(geometry, geometry->TotalSectors)) { // cylinder overflow
     663    log_geom_calculate_LBA_assist(geometry, geometry->TotalSectors);
     664    geometry->TotalSectors = (USHORT)(geometry->NumHeads * geometry->SectorsPerTrack) * (ULONG)geometry->TotalCylinders;
     665  }
     666  adjust_cylinders(geometry, geometry->TotalSectors);
     667
     668  dprintf("Logical geometry: %ld cylinders, %d heads, %d sectors per track (%ldMB) (%s)\n",
     669      (u32) geometry->TotalCylinders, (u16) geometry->NumHeads, (u16) geometry->SectorsPerTrack,
     670      (u32) (geometry->TotalSectors / 2048), Method);
    606671
    607672  if (is_lvm_geometry(iorb)) Method = "LVM";
     
    612677  ad_infos[a].ports[p].devs[0].dev_info.Method = Method;
    613678
    614   dprintf("Drive geometry: %ld cylinders, %d heads, %d sectors per track (%ldMB) (%s)\n",
     679  dprintf("Reported geometry: %ld cylinders, %d heads, %d sectors per track (%ldMB) (%s)\n",
    615680      (u32) geometry->TotalCylinders, (u16) geometry->NumHeads, (u16) geometry->SectorsPerTrack,
    616681      (u32) (geometry->TotalSectors / 2048), Method);
  • trunk/src/os2ahci/libc.c

    r165 r169  
    215215
    216216      case 'd':
    217         long_to_asc((lmod) ? va_arg(va, long)
    218                            : va_arg(va, int), buf, 10, zero, flen);
     217        long_to_asc((lmod) ? va_arg(va, long) : va_arg(va, int), buf, 10, zero, flen);
    219218        buf += strlen(buf);
    220219        break;
    221220
    222221      case 'x':
    223         long_to_asc((lmod) ? va_arg(va, u32)
    224                            : va_arg(va, u16), buf, 16, zero, flen);
     222        long_to_asc((lmod) ? va_arg(va, u32) : va_arg(va, u16), buf, 16, zero, flen);
    225223        buf += strlen(buf);
    226224        break;
  • trunk/src/os2ahci/os2ahci.c

    r166 r169  
    418418  ciprintf(init_msg, drv_name, VERSION / 100, VERSION % 100);
    419419
     420  #ifdef TESTVER
     421  #include "testver.c"
     422  #endif
     423
    420424  /* scan PCI bus for supported devices */
    421425  scan_pci_bus();
     
    424428    /* initialization succeeded and we found at least one AHCI adapter */
    425429    ADD_InitTimer(timer_pool, sizeof(timer_pool));
    426     //NOT_USED mdelay_cal();
    427430
    428431    if (DevHelp_RegisterDeviceClass(drv_name, (PFN) add_entry, 0, 1, &add_handle)) {
  • trunk/src/os2ahci/os2ahci.h

    r166 r169  
    373373  unsigned      port_scan_done : 1;    /* if != 0, port scan already done */
    374374  unsigned      busy : 1;              /* if != 0, adapter is busy */
     375
     376  unsigned      hw_ports : 6;          /* number of ports as reported by the hardware */
    375377
    376378  u32           port_map;              /* bitmap of active ports */
     
    558560extern void        free          (void *ptr);
    559561extern ULONG       virt_to_phys  (void _far *ptr);
    560 //NOT_USED extern void        mdelay_cal    (void);
    561 //NOT_USED extern void        mdelay        (u32 millies);
    562562extern void        msleep        (u32 millies);
    563563extern void        panic         (char *msg);
     
    625625extern ULONG         drv_lock;      /* driver-level spinlock */
    626626extern ULONG         com_lock;      /* debug log spinlock */
     627extern volatile PGINFOSEG gis;
    627628extern IORB_QUEUE    driver_queue;  /* driver-level IORB queue */
    628629extern AD_INFO       ad_infos[];    /* adapter information list */
  • trunk/src/os2ahci/trace.c

    r166 r169  
    226226      ai->bios_config[HOST_VERSION / sizeof(u32)]);
    227227
    228     for (p = 0; p <= ai->port_max; p++) {
     228    for (p = 0; p < ai->hw_ports; p++) {
    229229      P_INFO *pi = &ai->ports[p];
    230230
     
    232232
    233233      for (d = 0; d <= pi->dev_max; d++) {
    234         if (!pi->devs[d].present) continue;
    235 
    236         ntprintf("    Drive %d:", d);
    237         if (pi->devs[d].atapi) ntprintf(" atapi");
    238         if (pi->devs[d].removable) ntprintf(" removable");
    239         if (pi->devs[d].dev_info.Method != NULL)
    240           ntprintf(" %d cylinders, %d heads, %d sectors per track (%ldMB) (%s)",
    241             pi->devs[d].dev_info.Cylinders, pi->devs[d].dev_info.HeadsPerCylinder, pi->devs[d].dev_info.SectorsPerTrack,
    242             pi->devs[d].dev_info.TotalSectors/2048, pi->devs[d].dev_info.Method);
    243         ntprintf("\n");
    244       }
    245     }
    246   }
    247 }
    248 
     234        if (!pi->devs[d].present) {
     235          ntprintf("    No drive present\n");
     236        } else {
     237          ntprintf("    Drive %d:", d);
     238          if (pi->devs[d].atapi) ntprintf(" atapi");
     239          if (pi->devs[d].removable) ntprintf(" removable");
     240          if (pi->devs[d].dev_info.Method != NULL) {
     241            ntprintf(" %ld cylinders, %d heads, %d sectors per track (%ldMB) (%s)",
     242              (u32)pi->devs[d].dev_info.Cylinders, pi->devs[d].dev_info.HeadsPerCylinder, pi->devs[d].dev_info.SectorsPerTrack,
     243              pi->devs[d].dev_info.TotalSectors/2048, pi->devs[d].dev_info.Method);
     244          } else ntprintf(" Drive present but no information available. Not queried by OS.");
     245          ntprintf("\n");
     246        } /* if */
     247      } /* for d */
     248    } /* for p */
     249  } /* for a */
     250}
     251
Note: See TracChangeset for help on using the changeset viewer.