/* * Copyright (C) 2003 Osamu Tomita * * PC9801 BIOS geometry handling. */ #include #include #include #include #include #include #include "scsi.h" #include "hosts.h" static int pc98_first_bios_param(struct scsi_device *sdev, int *ip) { const u8 *p = (&__PC9800SCA(u8, PC9800SCA_SCSI_PARAMS) + sdev->id * 4); ip[0] = p[1]; /* # of heads */ ip[1] = p[0]; /* # of sectors/track */ ip[2] = *(u16 *)&p[2] & 0x0fff; /* # of cylinders */ if (p[3] & (1 << 6)) { /* #-of-cylinders is 16-bit */ ip[2] |= (ip[0] & 0xf0) << 8; ip[0] &= 0x0f; } return 0; } int pc98_bios_param(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int *ip) { struct Scsi_Host *first_real = first_real_host(); /* * XXX * XXX This needs to become a sysfs attribute that's set * XXX by code that knows which host is the first one. * XXX * XXX Currently we support only one host on with a * XXX PC98ish HBA. * XXX */ if (1 || sdev->host == first_real && sdev->id < 7 && __PC9800SCA_TEST_BIT(PC9800SCA_DISK_EQUIPS, sdev->id)) return pc98_first_bios_param(sdev, ip); /* Assume PC-9801-92 compatible parameters for HAs without BIOS. */ ip[0] = 8; ip[1] = 32; ip[2] = capacity / (8 * 32); if (ip[2] > 65535) { /* if capacity >= 8GB */ /* Recent on-board adapters seem to use this parameter. */ ip[1] = 128; ip[2] = capacity / (8 * 128); if (ip[2] > 65535) { /* if capacity >= 32GB */ /* Clip the number of cylinders. Currently this is the limit that we deal with. */ ip[2] = 65535; } } return 0; } EXPORT_SYMBOL(pc98_bios_param);