1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
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
|