13 #include <linux/module.h>
14 #include <linux/slab.h>
17 #include <linux/kernel.h>
19 #include <asm/unaligned.h>
24 static int setsize(
unsigned long capacity,
unsigned int *cyls,
unsigned int *hds,
43 memcpy(res, data + 0x1be, 66);
78 ret =
scsi_partsize(p, (
unsigned long)capacity, (
unsigned int *)ip + 2,
79 (
unsigned int *)ip + 0, (
unsigned int *)ip + 1);
82 if (ret == -1 && capacity64 < (1ULL << 32)) {
86 ret = setsize((
unsigned long)capacity, (
unsigned int *)ip + 2,
87 (
unsigned int *)ip + 0, (
unsigned int *)ip + 1);
92 if (ret || ip[0] > 255 || ip[1] > 63) {
93 if ((capacity >> 11) > 65534) {
101 if (capacity > 65535*63*255)
104 ip[2] = (
unsigned long)capacity / (ip[0] * ip[1]);
126 unsigned int *cyls,
unsigned int *hds,
unsigned int *secs)
131 unsigned int logical_end, physical_end, ext_physical_end;
134 if (*(
unsigned short *) (buf + 64) == 0xAA55) {
135 for (largest_cyl = -1, i = 0; i < 4; ++
i, ++
p) {
139 printk(
"scsicam_bios_param : partition %d has system \n",
142 cyl = p->cyl + ((p->sector & 0xc0) << 2);
143 if (cyl > largest_cyl) {
150 end_cyl = largest->end_cyl + ((largest->end_sector & 0xc0) << 2);
151 end_head = largest->end_head;
152 end_sector = largest->end_sector & 0x3f;
154 if (end_head + 1 == 0 || end_sector == 0)
158 printk(
"scsicam_bios_param : end at h = %d, c = %d, s = %d\n",
159 end_head, end_cyl, end_sector);
162 physical_end = end_cyl * (end_head + 1) * end_sector +
163 end_head * end_sector + end_sector;
170 ext_cyl = (logical_end - (end_head * end_sector +
end_sector))
171 / (end_head + 1) / end_sector;
172 ext_physical_end = ext_cyl * (end_head + 1) * end_sector +
173 end_head * end_sector + end_sector;
176 printk(
"scsicam_bios_param : logical_end=%d physical_end=%d ext_physical_end=%d ext_cyl=%d\n"
177 ,logical_end, physical_end, ext_physical_end, ext_cyl);
180 if ((logical_end == physical_end) ||
181 (end_cyl == 1023 && ext_physical_end == logical_end)) {
184 *cyls = capacity / ((end_head + 1) * end_sector);
188 printk(
"scsicam_bios_param : logical (%u) != physical (%u)\n",
189 logical_end, physical_end);
230 static int setsize(
unsigned long capacity,
unsigned int *cyls,
unsigned int *hds,
240 heads = capacity /
temp;
241 if (capacity % temp) {
243 temp = cylinders *
heads;
244 sectors = capacity /
temp;
246 if (capacity % temp) {
249 cylinders = capacity /
temp;
255 *cyls = (
unsigned int) cylinders;
256 *secs = (
unsigned int) sectors;
257 *hds = (
unsigned int) heads;