diff options
| author | Javier <dev.git@javispedro.com> | 2026-10-26 00:50:06 +0100 |
|---|---|---|
| committer | Javier <dev.git@javispedro.com> | 2026-10-26 00:50:06 +0100 |
| commit | 6b8a368c51082fdd010ef5e1b0be4eb9b5059d1a (patch) | |
| tree | e274d41a8dd5e912e20617a937a1fda5af91f8de /inc/scsi.h | |
| parent | 9b1cf601360fb194047e6dcc2af75c2f38c611ec (diff) | |
| download | chu-6b8a368c51082fdd010ef5e1b0be4eb9b5059d1a.tar.gz chu-6b8a368c51082fdd010ef5e1b0be4eb9b5059d1a.zip | |
refactor common parts into inc/ch375.h and add win9x, linux drivers
Diffstat (limited to 'inc/scsi.h')
| -rw-r--r-- | inc/scsi.h | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/inc/scsi.h b/inc/scsi.h new file mode 100644 index 0000000..a9d8b05 --- /dev/null +++ b/inc/scsi.h @@ -0,0 +1,61 @@ +#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 |
