2 * Copyright (C) 2003 Osamu Tomita <tomita@cinet.co.jp>
4 * PC9801 BIOS geometry handling.
7 #include <linux/module.h>
9 #include <linux/kernel.h>
10 #include <linux/genhd.h>
11 #include <linux/blkdev.h>
12 #include <asm/pc9800.h>
18 static int pc98_first_bios_param(struct scsi_device
*sdev
, int *ip
)
20 const u8
*p
= (&__PC9800SCA(u8
, PC9800SCA_SCSI_PARAMS
) + sdev
->id
* 4);
22 ip
[0] = p
[1]; /* # of heads */
23 ip
[1] = p
[0]; /* # of sectors/track */
24 ip
[2] = *(u16
*)&p
[2] & 0x0fff; /* # of cylinders */
25 if (p
[3] & (1 << 6)) { /* #-of-cylinders is 16-bit */
26 ip
[2] |= (ip
[0] & 0xf0) << 8;
33 int pc98_bios_param(struct scsi_device
*sdev
, struct block_device
*bdev
,
34 sector_t capacity
, int *ip
)
36 struct Scsi_Host
*first_real
= first_real_host();
40 * XXX This needs to become a sysfs attribute that's set
41 * XXX by code that knows which host is the first one.
43 * XXX Currently we support only one host on with a
47 if (1 || sdev
->host
== first_real
&& sdev
->id
< 7 &&
48 __PC9800SCA_TEST_BIT(PC9800SCA_DISK_EQUIPS
, sdev
->id
))
49 return pc98_first_bios_param(sdev
, ip
);
51 /* Assume PC-9801-92 compatible parameters for HAs without BIOS. */
54 ip
[2] = capacity
/ (8 * 32);
55 if (ip
[2] > 65535) { /* if capacity >= 8GB */
56 /* Recent on-board adapters seem to use this parameter. */
58 ip
[2] = capacity
/ (8 * 128);
59 if (ip
[2] > 65535) { /* if capacity >= 32GB */
60 /* Clip the number of cylinders. Currently
61 this is the limit that we deal with. */
69 EXPORT_SYMBOL(pc98_bios_param
);