#ifndef SCSICAM_H #define SCSICAM_H /** (from SCSICAM) converts a capacitity in sectors to CHS * keeps cylinders <= 1024 and sectors <= 62, * but may give very large head numbers, though. */ static int setsize(unsigned long capacity, unsigned int *cyls, unsigned int *hds, unsigned int *secs) { unsigned int rv = 0; unsigned long heads, sectors, cylinders, temp; cylinders = 1024L; /* Set number of cylinders to max */ sectors = 62L; /* Maximize sectors per track */ temp = cylinders * sectors; /* Compute divisor for heads */ heads = capacity / temp; /* Compute value for number of heads */ if (capacity % temp) { /* If no remainder, done! */ heads++; /* Else, increment number of heads */ temp = cylinders * heads; /* Compute divisor for sectors */ sectors = capacity / temp; /* Compute value for sectors per track */ if (capacity % temp) { /* If no remainder, done! */ sectors++; /* Else, increment number of sectors */ temp = heads * sectors; /* Compute divisor for cylinders */ cylinders = capacity / temp; /* Compute number of cylinders */ } } if (cylinders == 0) rv = (unsigned) -1; /* Give error if 0 cylinders */ *cyls = (unsigned int) cylinders; /* Stuff return values */ *secs = (unsigned int) sectors; *hds = (unsigned int) heads; return (rv); } static void guess_geometry(uint32_t num_sectors, unsigned int *cyls, unsigned int *hds, unsigned int *secs) { unsigned int cylinders, heads, sectors; // First try to use SCSI CAM approach if (setsize(num_sectors, &cylinders, &heads, §ors) != 0 || cylinders > 1024 || heads > 255 || sectors > 63) { // Didn't work. So now we just use max heads and sectors but a crazy number of cyls if (num_sectors <= 64 * 32 * 65534) { // This follows the same behavior as Linux, // which uses smaller values for heads/sects as long as cyls fits < 65535 heads = 64; sectors = 32; } else { heads = 255; sectors = 63; } cylinders = num_sectors / (heads * sectors); } *cyls = cylinders; *hds = heads; *secs = sectors; } #endif // SCSICAM_H