Commit 9dbf0015 authored by Martin Dalecki's avatar Martin Dalecki Committed by Linus Torvalds

[PATCH] 2.5.10 IDE 42

- Streamline the usage of sector_t over the strategy routines in question a
   bit. Streamline the do_request code in ide-disk.c.

- Improve the readability of start_request in ide.c.

- Remove obsolete/nowhere used stuff from hdreg.h.

- Splitup special_t into classical flag field.

- Use only a single field to determine the capacity of a drive.  Make this
   field and the code paths it follows as far as possible use the sector_t
   instead of a hard coded integer types.  This increases the chances that at
   some distant point in time we will indeed be able to use 64 bit wide sector_t
   entities. (Disks are getting huge those times now...)
parent f62e2b90
...@@ -732,15 +732,12 @@ static struct ioctl32_list ioctl32_handler_table[] = { ...@@ -732,15 +732,12 @@ static struct ioctl32_list ioctl32_handler_table[] = {
IOCTL32_HANDLER(HDIO_GETGEO, hdio_getgeo), /* hdreg.h ioctls */ IOCTL32_HANDLER(HDIO_GETGEO, hdio_getgeo), /* hdreg.h ioctls */
IOCTL32_HANDLER(HDIO_GET_UNMASKINTR, hdio_ioctl_trans), IOCTL32_HANDLER(HDIO_GET_UNMASKINTR, hdio_ioctl_trans),
IOCTL32_HANDLER(HDIO_GET_MULTCOUNT, hdio_ioctl_trans), IOCTL32_HANDLER(HDIO_GET_MULTCOUNT, hdio_ioctl_trans),
// HDIO_OBSOLETE_IDENTITY
IOCTL32_HANDLER(HDIO_GET_KEEPSETTINGS, hdio_ioctl_trans), IOCTL32_HANDLER(HDIO_GET_KEEPSETTINGS, hdio_ioctl_trans),
IOCTL32_HANDLER(HDIO_GET_32BIT, hdio_ioctl_trans), IOCTL32_HANDLER(HDIO_GET_32BIT, hdio_ioctl_trans),
IOCTL32_HANDLER(HDIO_GET_NOWERR, hdio_ioctl_trans), IOCTL32_HANDLER(HDIO_GET_NOWERR, hdio_ioctl_trans),
IOCTL32_HANDLER(HDIO_GET_DMA, hdio_ioctl_trans), IOCTL32_HANDLER(HDIO_GET_DMA, hdio_ioctl_trans),
IOCTL32_HANDLER(HDIO_GET_NICE, hdio_ioctl_trans), IOCTL32_HANDLER(HDIO_GET_NICE, hdio_ioctl_trans),
IOCTL32_DEFAULT(HDIO_GET_IDENTITY), IOCTL32_DEFAULT(HDIO_GET_IDENTITY),
// HDIO_TRISTATE_HWIF /* not implemented */
// HDIO_DRIVE_TASK /* To do, need specs */
IOCTL32_DEFAULT(HDIO_DRIVE_CMD), IOCTL32_DEFAULT(HDIO_DRIVE_CMD),
IOCTL32_DEFAULT(HDIO_SET_MULTCOUNT), IOCTL32_DEFAULT(HDIO_SET_MULTCOUNT),
IOCTL32_DEFAULT(HDIO_SET_UNMASKINTR), IOCTL32_DEFAULT(HDIO_SET_UNMASKINTR),
......
...@@ -338,7 +338,7 @@ void blk_queue_assign_lock(request_queue_t *q, spinlock_t *lock) ...@@ -338,7 +338,7 @@ void blk_queue_assign_lock(request_queue_t *q, spinlock_t *lock)
static char *rq_flags[] = { "REQ_RW", "REQ_RW_AHEAD", "REQ_BARRIER", static char *rq_flags[] = { "REQ_RW", "REQ_RW_AHEAD", "REQ_BARRIER",
"REQ_CMD", "REQ_NOMERGE", "REQ_STARTED", "REQ_CMD", "REQ_NOMERGE", "REQ_STARTED",
"REQ_DONTPREP", "REQ_DRIVE_CMD", "REQ_DRIVE_TASK", "REQ_DONTPREP", "REQ_DRIVE_CMD",
"REQ_DRIVE_ACB", "REQ_PC", "REQ_BLOCK_PC", "REQ_DRIVE_ACB", "REQ_PC", "REQ_BLOCK_PC",
"REQ_SENSE", "REQ_SPECIAL" }; "REQ_SENSE", "REQ_SPECIAL" };
......
...@@ -1162,11 +1162,12 @@ static ide_startstop_t cdrom_seek_intr (ide_drive_t *drive) ...@@ -1162,11 +1162,12 @@ static ide_startstop_t cdrom_seek_intr (ide_drive_t *drive)
return ide_stopped; return ide_stopped;
} }
static ide_startstop_t cdrom_start_seek_continuation (ide_drive_t *drive) static ide_startstop_t cdrom_start_seek_continuation(struct ata_device *drive)
{ {
unsigned char cmd[CDROM_PACKET_SIZE]; unsigned char cmd[CDROM_PACKET_SIZE];
struct request *rq = HWGROUP(drive)->rq; struct request *rq = HWGROUP(drive)->rq;
int sector, frame, nskip; sector_t sector;
int frame, nskip;
sector = rq->sector; sector = rq->sector;
nskip = (sector % SECTORS_PER_FRAME); nskip = (sector % SECTORS_PER_FRAME);
...@@ -1181,14 +1182,14 @@ static ide_startstop_t cdrom_start_seek_continuation (ide_drive_t *drive) ...@@ -1181,14 +1182,14 @@ static ide_startstop_t cdrom_start_seek_continuation (ide_drive_t *drive)
return cdrom_transfer_packet_command(drive, cmd, WAIT_CMD, &cdrom_seek_intr); return cdrom_transfer_packet_command(drive, cmd, WAIT_CMD, &cdrom_seek_intr);
} }
static ide_startstop_t cdrom_start_seek (ide_drive_t *drive, unsigned int block) static ide_startstop_t cdrom_start_seek(struct ata_device *drive, sector_t block)
{ {
struct cdrom_info *info = drive->driver_data; struct cdrom_info *info = drive->driver_data;
info->dma = 0; info->dma = 0;
info->cmd = 0; info->cmd = 0;
info->start_seek = jiffies; info->start_seek = jiffies;
return cdrom_start_packet_command (drive, 0, cdrom_start_seek_continuation); return cdrom_start_packet_command(drive, 0, cdrom_start_seek_continuation);
} }
/* /*
...@@ -1199,7 +1200,7 @@ static ide_startstop_t cdrom_start_seek (ide_drive_t *drive, unsigned int block) ...@@ -1199,7 +1200,7 @@ static ide_startstop_t cdrom_start_seek (ide_drive_t *drive, unsigned int block)
static void restore_request (struct request *rq) static void restore_request (struct request *rq)
{ {
if (rq->buffer != bio_data(rq->bio)) { if (rq->buffer != bio_data(rq->bio)) {
int n = (rq->buffer - (char *) bio_data(rq->bio)) / SECTOR_SIZE; sector_t n = (rq->buffer - (char *) bio_data(rq->bio)) / SECTOR_SIZE;
rq->buffer = bio_data(rq->bio); rq->buffer = bio_data(rq->bio);
rq->nr_sectors += n; rq->nr_sectors += n;
rq->sector -= n; rq->sector -= n;
...@@ -1213,7 +1214,7 @@ static void restore_request (struct request *rq) ...@@ -1213,7 +1214,7 @@ static void restore_request (struct request *rq)
/* /*
* Start a read request from the CD-ROM. * Start a read request from the CD-ROM.
*/ */
static ide_startstop_t cdrom_start_read (ide_drive_t *drive, unsigned int block) static ide_startstop_t cdrom_start_read(struct ata_device *drive, sector_t block)
{ {
struct cdrom_info *info = drive->driver_data; struct cdrom_info *info = drive->driver_data;
struct request *rq = HWGROUP(drive)->rq; struct request *rq = HWGROUP(drive)->rq;
...@@ -1634,8 +1635,6 @@ ide_cdrom_do_request(struct ata_device *drive, struct request *rq, sector_t bloc ...@@ -1634,8 +1635,6 @@ ide_cdrom_do_request(struct ata_device *drive, struct request *rq, sector_t bloc
struct cdrom_info *info = drive->driver_data; struct cdrom_info *info = drive->driver_data;
if (rq->flags & REQ_CMD) { if (rq->flags & REQ_CMD) {
if (CDROM_CONFIG_FLAGS(drive)->seeking) { if (CDROM_CONFIG_FLAGS(drive)->seeking) {
unsigned long elpased = jiffies - info->start_seek; unsigned long elpased = jiffies - info->start_seek;
int stat = GET_STAT(); int stat = GET_STAT();
...@@ -1650,7 +1649,7 @@ ide_cdrom_do_request(struct ata_device *drive, struct request *rq, sector_t bloc ...@@ -1650,7 +1649,7 @@ ide_cdrom_do_request(struct ata_device *drive, struct request *rq, sector_t bloc
CDROM_CONFIG_FLAGS(drive)->seeking = 0; CDROM_CONFIG_FLAGS(drive)->seeking = 0;
} }
if (IDE_LARGE_SEEK(info->last_block, block, IDECD_SEEK_THRESHOLD) && drive->dsc_overlap) if (IDE_LARGE_SEEK(info->last_block, block, IDECD_SEEK_THRESHOLD) && drive->dsc_overlap)
action = cdrom_start_seek (drive, block); action = cdrom_start_seek(drive, block);
else { else {
if (rq_data_dir(rq) == READ) if (rq_data_dir(rq) == READ)
action = cdrom_start_read(drive, block); action = cdrom_start_read(drive, block);
...@@ -1837,7 +1836,7 @@ static int cdrom_eject(ide_drive_t *drive, int ejectflag, ...@@ -1837,7 +1836,7 @@ static int cdrom_eject(ide_drive_t *drive, int ejectflag,
return cdrom_queue_packet_command(drive, cmd, sense, &pc); return cdrom_queue_packet_command(drive, cmd, sense, &pc);
} }
static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, static int cdrom_read_capacity(ide_drive_t *drive, u32 *capacity,
struct request_sense *sense) struct request_sense *sense)
{ {
struct { struct {
...@@ -2027,7 +2026,8 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense) ...@@ -2027,7 +2026,8 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
/* Now try to get the total cdrom capacity. */ /* Now try to get the total cdrom capacity. */
minor = (drive->select.b.unit) << PARTN_BITS; minor = (drive->select.b.unit) << PARTN_BITS;
dev = mk_kdev(drive->channel->major, minor); dev = mk_kdev(drive->channel->major, minor);
stat = cdrom_get_last_written(dev, &toc->capacity); /* FIXME: This is making worng assumptions about register layout. */
stat = cdrom_get_last_written(dev, (unsigned long *) &toc->capacity);
if (stat) if (stat)
stat = cdrom_read_capacity(drive, &toc->capacity, sense); stat = cdrom_read_capacity(drive, &toc->capacity, sense);
if (stat) if (stat)
...@@ -2686,7 +2686,7 @@ static void ide_cdrom_add_settings(ide_drive_t *drive) ...@@ -2686,7 +2686,7 @@ static void ide_cdrom_add_settings(ide_drive_t *drive)
} }
static static
int ide_cdrom_setup (ide_drive_t *drive) int ide_cdrom_setup(ide_drive_t *drive)
{ {
struct cdrom_info *info = drive->driver_data; struct cdrom_info *info = drive->driver_data;
struct cdrom_device_info *cdi = &info->devinfo; struct cdrom_device_info *cdi = &info->devinfo;
...@@ -2702,7 +2702,6 @@ int ide_cdrom_setup (ide_drive_t *drive) ...@@ -2702,7 +2702,6 @@ int ide_cdrom_setup (ide_drive_t *drive)
blk_queue_prep_rq(&drive->queue, ll_10byte_cmd_build); blk_queue_prep_rq(&drive->queue, ll_10byte_cmd_build);
drive->special.all = 0;
drive->ready_stat = 0; drive->ready_stat = 0;
CDROM_STATE_FLAGS (drive)->media_changed = 1; CDROM_STATE_FLAGS (drive)->media_changed = 1;
...@@ -2891,10 +2890,9 @@ void ide_cdrom_revalidate (ide_drive_t *drive) ...@@ -2891,10 +2890,9 @@ void ide_cdrom_revalidate (ide_drive_t *drive)
set_blocksize(mk_kdev(drive->channel->major, minor), CD_FRAMESIZE); set_blocksize(mk_kdev(drive->channel->major, minor), CD_FRAMESIZE);
} }
static static sector_t ide_cdrom_capacity(struct ata_device *drive)
unsigned long ide_cdrom_capacity (ide_drive_t *drive)
{ {
unsigned long capacity; u32 capacity;
if (cdrom_read_capacity(drive, &capacity, NULL)) if (cdrom_read_capacity(drive, &capacity, NULL))
return 0; return 0;
...@@ -2934,9 +2932,7 @@ static struct ata_operations ide_cdrom_driver = { ...@@ -2934,9 +2932,7 @@ static struct ata_operations ide_cdrom_driver = {
release: ide_cdrom_release, release: ide_cdrom_release,
check_media_change: ide_cdrom_check_media_change, check_media_change: ide_cdrom_check_media_change,
revalidate: ide_cdrom_revalidate, revalidate: ide_cdrom_revalidate,
pre_reset: NULL,
capacity: ide_cdrom_capacity, capacity: ide_cdrom_capacity,
special: NULL,
proc: NULL proc: NULL
}; };
......
...@@ -153,10 +153,9 @@ struct atapi_toc_entry { ...@@ -153,10 +153,9 @@ struct atapi_toc_entry {
struct atapi_toc { struct atapi_toc {
int last_session_lba; int last_session_lba;
int xa_flag; int xa_flag;
unsigned long capacity; u32 capacity;
struct atapi_toc_header hdr; struct atapi_toc_header hdr;
struct atapi_toc_entry ent[MAX_TRACKS+1]; struct atapi_toc_entry ent[MAX_TRACKS+1]; /* one extra for the leadout. */
/* One extra for the leadout. */
}; };
......
...@@ -132,10 +132,8 @@ static u8 get_command(ide_drive_t *drive, int cmd) ...@@ -132,10 +132,8 @@ static u8 get_command(ide_drive_t *drive, int cmd)
return WIN_NOP; return WIN_NOP;
} }
static ide_startstop_t chs_do_request(ide_drive_t *drive, struct request *rq, unsigned long block) static ide_startstop_t chs_do_request(struct ata_device *drive, struct request *rq, sector_t block)
{ {
struct hd_drive_task_hdr taskfile;
struct hd_drive_hob_hdr hobfile;
struct ata_taskfile args; struct ata_taskfile args;
int sectors; int sectors;
...@@ -144,22 +142,21 @@ static ide_startstop_t chs_do_request(ide_drive_t *drive, struct request *rq, un ...@@ -144,22 +142,21 @@ static ide_startstop_t chs_do_request(ide_drive_t *drive, struct request *rq, un
unsigned int head = (track % drive->head); unsigned int head = (track % drive->head);
unsigned int cyl = (track / drive->head); unsigned int cyl = (track / drive->head);
memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
sectors = rq->nr_sectors; sectors = rq->nr_sectors;
if (sectors == 256) if (sectors == 256)
sectors = 0; sectors = 0;
taskfile.sector_count = sectors; memset(&args, 0, sizeof(args));
args.taskfile.sector_count = sectors;
taskfile.sector_number = sect; args.taskfile.sector_number = sect;
taskfile.low_cylinder = cyl; args.taskfile.low_cylinder = cyl;
taskfile.high_cylinder = (cyl>>8); args.taskfile.high_cylinder = (cyl>>8);
taskfile.device_head = head; args.taskfile.device_head = head;
taskfile.device_head |= drive->select.all; args.taskfile.device_head |= drive->select.all;
taskfile.command = get_command(drive, rq_data_dir(rq)); args.taskfile.command = get_command(drive, rq_data_dir(rq));
#ifdef DEBUG #ifdef DEBUG
printk("%s: %sing: ", drive->name, printk("%s: %sing: ", drive->name,
...@@ -167,21 +164,17 @@ static ide_startstop_t chs_do_request(ide_drive_t *drive, struct request *rq, un ...@@ -167,21 +164,17 @@ static ide_startstop_t chs_do_request(ide_drive_t *drive, struct request *rq, un
if (lba) printk("LBAsect=%lld, ", block); if (lba) printk("LBAsect=%lld, ", block);
else printk("CHS=%d/%d/%d, ", cyl, head, sect); else printk("CHS=%d/%d/%d, ", cyl, head, sect);
printk("sectors=%ld, ", rq->nr_sectors); printk("sectors=%ld, ", rq->nr_sectors);
printk("buffer=0x%08lx\n", (unsigned long) rq->buffer); printk("buffer=%p\n", rq->buffer);
#endif #endif
args.taskfile = taskfile;
args.hobfile = hobfile;
ide_cmd_type_parser(&args); ide_cmd_type_parser(&args);
rq->special = &args; rq->special = &args;
return ata_taskfile(drive, &args, rq); return ata_taskfile(drive, &args, rq);
} }
static ide_startstop_t lba28_do_request(ide_drive_t *drive, struct request *rq, unsigned long block) static ide_startstop_t lba28_do_request(struct ata_device *drive, struct request *rq, sector_t block)
{ {
struct hd_drive_task_hdr taskfile;
struct hd_drive_hob_hdr hobfile;
struct ata_taskfile args; struct ata_taskfile args;
int sectors; int sectors;
...@@ -189,18 +182,17 @@ static ide_startstop_t lba28_do_request(ide_drive_t *drive, struct request *rq, ...@@ -189,18 +182,17 @@ static ide_startstop_t lba28_do_request(ide_drive_t *drive, struct request *rq,
if (sectors == 256) if (sectors == 256)
sectors = 0; sectors = 0;
memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr)); memset(&args, 0, sizeof(args));
memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
taskfile.sector_count = sectors; args.taskfile.sector_count = sectors;
taskfile.sector_number = block; args.taskfile.sector_number = block;
taskfile.low_cylinder = (block >>= 8); args.taskfile.low_cylinder = (block >>= 8);
taskfile.high_cylinder = (block >>= 8); args.taskfile.high_cylinder = (block >>= 8);
taskfile.device_head = ((block >> 8) & 0x0f); args.taskfile.device_head = ((block >> 8) & 0x0f);
taskfile.device_head |= drive->select.all; args.taskfile.device_head |= drive->select.all;
taskfile.command = get_command(drive, rq_data_dir(rq)); args.taskfile.command = get_command(drive, rq_data_dir(rq));
#ifdef DEBUG #ifdef DEBUG
printk("%s: %sing: ", drive->name, printk("%s: %sing: ", drive->name,
...@@ -208,11 +200,9 @@ static ide_startstop_t lba28_do_request(ide_drive_t *drive, struct request *rq, ...@@ -208,11 +200,9 @@ static ide_startstop_t lba28_do_request(ide_drive_t *drive, struct request *rq,
if (lba) printk("LBAsect=%lld, ", block); if (lba) printk("LBAsect=%lld, ", block);
else printk("CHS=%d/%d/%d, ", cyl, head, sect); else printk("CHS=%d/%d/%d, ", cyl, head, sect);
printk("sectors=%ld, ", rq->nr_sectors); printk("sectors=%ld, ", rq->nr_sectors);
printk("buffer=0x%08lx\n", (unsigned long) rq->buffer); printk("buffer=%p\n", rq->buffer);
#endif #endif
args.taskfile = taskfile;
args.hobfile = hobfile;
ide_cmd_type_parser(&args); ide_cmd_type_parser(&args);
rq->special = &args; rq->special = &args;
...@@ -225,40 +215,32 @@ static ide_startstop_t lba28_do_request(ide_drive_t *drive, struct request *rq, ...@@ -225,40 +215,32 @@ static ide_startstop_t lba28_do_request(ide_drive_t *drive, struct request *rq,
* 1073741822 == 549756 MB or 48bit addressing fake drive * 1073741822 == 549756 MB or 48bit addressing fake drive
*/ */
static ide_startstop_t lba48_do_request(ide_drive_t *drive, struct request *rq, unsigned long long block) static ide_startstop_t lba48_do_request(struct ata_device *drive, struct request *rq, sector_t block)
{ {
struct hd_drive_task_hdr taskfile;
struct hd_drive_hob_hdr hobfile;
struct ata_taskfile args; struct ata_taskfile args;
int sectors; int sectors;
memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
sectors = rq->nr_sectors; sectors = rq->nr_sectors;
if (sectors == 65536) if (sectors == 65536)
sectors = 0; sectors = 0;
taskfile.sector_count = sectors; memset(&args, 0, sizeof(args));
hobfile.sector_count = sectors >> 8;
if (rq->nr_sectors == 65536) { args.taskfile.sector_count = sectors;
taskfile.sector_count = 0x00; args.hobfile.sector_count = sectors >> 8;
hobfile.sector_count = 0x00;
}
taskfile.sector_number = block; /* low lba */ args.taskfile.sector_number = block; /* low lba */
taskfile.low_cylinder = (block >>= 8); /* mid lba */ args.taskfile.low_cylinder = (block >>= 8); /* mid lba */
taskfile.high_cylinder = (block >>= 8); /* hi lba */ args.taskfile.high_cylinder = (block >>= 8); /* hi lba */
hobfile.sector_number = (block >>= 8); /* low lba */ args.hobfile.sector_number = (block >>= 8); /* low lba */
hobfile.low_cylinder = (block >>= 8); /* mid lba */ args.hobfile.low_cylinder = (block >>= 8); /* mid lba */
hobfile.high_cylinder = (block >>= 8); /* hi lba */ args.hobfile.high_cylinder = (block >>= 8); /* hi lba */
taskfile.device_head = drive->select.all; args.taskfile.device_head = drive->select.all;
hobfile.device_head = taskfile.device_head; args.hobfile.device_head = args.taskfile.device_head;
hobfile.control = (drive->ctl|0x80); args.hobfile.control = (drive->ctl|0x80);
taskfile.command = get_command(drive, rq_data_dir(rq)); args.taskfile.command = get_command(drive, rq_data_dir(rq));
#ifdef DEBUG #ifdef DEBUG
printk("%s: %sing: ", drive->name, printk("%s: %sing: ", drive->name,
...@@ -266,11 +248,9 @@ static ide_startstop_t lba48_do_request(ide_drive_t *drive, struct request *rq, ...@@ -266,11 +248,9 @@ static ide_startstop_t lba48_do_request(ide_drive_t *drive, struct request *rq,
if (lba) printk("LBAsect=%lld, ", block); if (lba) printk("LBAsect=%lld, ", block);
else printk("CHS=%d/%d/%d, ", cyl, head, sect); else printk("CHS=%d/%d/%d, ", cyl, head, sect);
printk("sectors=%ld, ", rq->nr_sectors); printk("sectors=%ld, ", rq->nr_sectors);
printk("buffer=0x%08lx\n", (unsigned long) rq->buffer); printk("buffer=%p\n",rq->buffer);
#endif #endif
args.taskfile = taskfile;
args.hobfile = hobfile;
ide_cmd_type_parser(&args); ide_cmd_type_parser(&args);
rq->special = &args; rq->special = &args;
...@@ -282,7 +262,7 @@ static ide_startstop_t lba48_do_request(ide_drive_t *drive, struct request *rq, ...@@ -282,7 +262,7 @@ static ide_startstop_t lba48_do_request(ide_drive_t *drive, struct request *rq,
* otherwise, to address sectors. It also takes care of issuing special * otherwise, to address sectors. It also takes care of issuing special
* DRIVE_CMDs. * DRIVE_CMDs.
*/ */
static ide_startstop_t idedisk_do_request(ide_drive_t *drive, struct request *rq, unsigned long block) static ide_startstop_t idedisk_do_request(struct ata_device *drive, struct request *rq, sector_t block)
{ {
/* /*
* Wait until all request have bin finished. * Wait until all request have bin finished.
...@@ -290,7 +270,7 @@ static ide_startstop_t idedisk_do_request(ide_drive_t *drive, struct request *rq ...@@ -290,7 +270,7 @@ static ide_startstop_t idedisk_do_request(ide_drive_t *drive, struct request *rq
while (drive->blocked) { while (drive->blocked) {
yield(); yield();
printk("ide: Request while drive blocked?"); printk(KERN_ERR "ide: Request while drive blocked?");
} }
if (!(rq->flags & REQ_CMD)) { if (!(rq->flags & REQ_CMD)) {
...@@ -300,7 +280,7 @@ static ide_startstop_t idedisk_do_request(ide_drive_t *drive, struct request *rq ...@@ -300,7 +280,7 @@ static ide_startstop_t idedisk_do_request(ide_drive_t *drive, struct request *rq
} }
if (IS_PDC4030_DRIVE) { if (IS_PDC4030_DRIVE) {
extern ide_startstop_t promise_rw_disk(ide_drive_t *, struct request *, unsigned long); extern ide_startstop_t promise_rw_disk(struct ata_device *, struct request *, unsigned long);
return promise_rw_disk(drive, rq, block); return promise_rw_disk(drive, rq, block);
} }
...@@ -386,256 +366,19 @@ static int idedisk_check_media_change (ide_drive_t *drive) ...@@ -386,256 +366,19 @@ static int idedisk_check_media_change (ide_drive_t *drive)
return drive->removable; return drive->removable;
} }
/* static sector_t idedisk_capacity(struct ata_device *drive)
* Queries for true maximum capacity of the drive.
* Returns maximum LBA address (> 0) of the drive, 0 if failed.
*/
static unsigned long idedisk_read_native_max_address(ide_drive_t *drive)
{ {
struct ata_taskfile args; return drive->capacity - drive->sect0;
unsigned long addr = 0;
if (!(drive->id->command_set_1 & 0x0400) &&
!(drive->id->cfs_enable_2 & 0x0100))
return addr;
/* Create IDE/ATA command request structure */
memset(&args, 0, sizeof(args));
args.taskfile.device_head = 0x40;
args.taskfile.command = WIN_READ_NATIVE_MAX;
args.handler = task_no_data_intr;
/* submit command request */
ide_raw_taskfile(drive, &args, NULL);
/* if OK, compute maximum address value */
if ((args.taskfile.command & 0x01) == 0) {
addr = ((args.taskfile.device_head & 0x0f) << 24)
| (args.taskfile.high_cylinder << 16)
| (args.taskfile.low_cylinder << 8)
| args.taskfile.sector_number;
}
addr++; /* since the return value is (maxlba - 1), we add 1 */
return addr;
} }
static unsigned long long idedisk_read_native_max_address_ext(ide_drive_t *drive) static ide_startstop_t idedisk_special(struct ata_device *drive)
{ {
struct ata_taskfile args; unsigned char special_cmd = drive->special_cmd;
unsigned long long addr = 0;
/* Create IDE/ATA command request structure */
memset(&args, 0, sizeof(args));
args.taskfile.device_head = 0x40;
args.taskfile.command = WIN_READ_NATIVE_MAX_EXT;
args.handler = task_no_data_intr;
/* submit command request */
ide_raw_taskfile(drive, &args, NULL);
/* if OK, compute maximum address value */
if ((args.taskfile.command & 0x01) == 0) {
u32 high = (args.hobfile.high_cylinder << 16) |
(args.hobfile.low_cylinder << 8) |
args.hobfile.sector_number;
u32 low = (args.taskfile.high_cylinder << 16) |
(args.taskfile.low_cylinder << 8) |
args.taskfile.sector_number;
addr = ((__u64)high << 24) | low;
}
addr++; /* since the return value is (maxlba - 1), we add 1 */
return addr;
}
#ifdef CONFIG_IDEDISK_STROKE if (special_cmd & ATA_SPECIAL_GEOMETRY) {
/*
* Sets maximum virtual LBA address of the drive.
* Returns new maximum virtual LBA address (> 0) or 0 on failure.
*/
static unsigned long idedisk_set_max_address(ide_drive_t *drive, unsigned long addr_req)
{
struct ata_taskfile args; struct ata_taskfile args;
unsigned long addr_set = 0;
addr_req--; drive->special_cmd &= ~ATA_SPECIAL_GEOMETRY;
/* Create IDE/ATA command request structure */
memset(&args, 0, sizeof(args));
args.taskfile.sector_number = (addr_req >> 0);
args.taskfile.low_cylinder = (addr_req >> 8);
args.taskfile.high_cylinder = (addr_req >> 16);
args.taskfile.device_head = ((addr_req >> 24) & 0x0f) | 0x40;
args.taskfile.command = WIN_SET_MAX;
args.handler = task_no_data_intr;
/* submit command request */
ide_raw_taskfile(drive, &args, NULL);
/* if OK, read new maximum address value */
if ((args.taskfile.command & 0x01) == 0) {
addr_set = ((args.taskfile.device_head & 0x0f) << 24)
| (args.taskfile.high_cylinder << 16)
| (args.taskfile.low_cylinder << 8)
| args.taskfile.sector_number;
}
addr_set++;
return addr_set;
}
static unsigned long long idedisk_set_max_address_ext(ide_drive_t *drive, unsigned long long addr_req)
{
struct ata_taskfile args;
unsigned long long addr_set = 0;
addr_req--;
/* Create IDE/ATA command request structure */
memset(&args, 0, sizeof(args));
args.taskfile.sector_number = (addr_req >> 0);
args.taskfile.low_cylinder = (addr_req >>= 8);
args.taskfile.high_cylinder = (addr_req >>= 8);
args.taskfile.device_head = 0x40;
args.taskfile.command = WIN_SET_MAX_EXT;
args.hobfile.sector_number = (addr_req >>= 8);
args.hobfile.low_cylinder = (addr_req >>= 8);
args.hobfile.high_cylinder = (addr_req >>= 8);
args.hobfile.device_head = 0x40;
args.hobfile.control = (drive->ctl | 0x80);
args.handler = task_no_data_intr;
/* submit command request */
ide_raw_taskfile(drive, &args, NULL);
/* if OK, compute maximum address value */
if ((args.taskfile.command & 0x01) == 0) {
u32 high = (args.hobfile.high_cylinder << 16) |
(args.hobfile.low_cylinder << 8) |
args.hobfile.sector_number;
u32 low = (args.taskfile.high_cylinder << 16) |
(args.taskfile.low_cylinder << 8) |
args.taskfile.sector_number;
addr_set = ((__u64)high << 24) | low;
}
return addr_set;
}
/*
* Tests if the drive supports Host Protected Area feature.
* Returns true if supported, false otherwise.
*/
static inline int idedisk_supports_host_protected_area(ide_drive_t *drive)
{
int flag = (drive->id->cfs_enable_1 & 0x0400) ? 1 : 0;
printk("%s: host protected area => %d\n", drive->name, flag);
return flag;
}
#endif
/*
* Compute drive->capacity, the full capacity of the drive
* Called with drive->id != NULL.
*
* To compute capacity, this uses either of
*
* 1. CHS value set by user (whatever user sets will be trusted)
* 2. LBA value from target drive (require new ATA feature)
* 3. LBA value from system BIOS (new one is OK, old one may break)
* 4. CHS value from system BIOS (traditional style)
*
* in above order (i.e., if value of higher priority is available,
* reset will be ignored).
*/
static void init_idedisk_capacity (ide_drive_t *drive)
{
struct hd_driveid *id = drive->id;
unsigned long capacity = drive->cyl * drive->head * drive->sect;
unsigned long set_max = idedisk_read_native_max_address(drive);
unsigned long long capacity_2 = capacity;
unsigned long long set_max_ext;
drive->capacity48 = 0;
drive->select.b.lba = 0;
if (id->cfs_enable_2 & 0x0400) {
capacity_2 = id->lba_capacity_2;
drive->cyl = (unsigned int) capacity_2 / (drive->head * drive->sect);
drive->head = drive->bios_head = 255;
drive->sect = drive->bios_sect = 63;
drive->select.b.lba = 1;
set_max_ext = idedisk_read_native_max_address_ext(drive);
if (set_max_ext > capacity_2) {
#ifdef CONFIG_IDEDISK_STROKE
set_max_ext = idedisk_read_native_max_address_ext(drive);
set_max_ext = idedisk_set_max_address_ext(drive, set_max_ext);
if (set_max_ext) {
drive->capacity48 = capacity_2 = set_max_ext;
drive->cyl = (unsigned int) set_max_ext / (drive->head * drive->sect);
drive->select.b.lba = 1;
drive->id->lba_capacity_2 = capacity_2;
}
#else
printk("%s: setmax_ext LBA %llu, native %llu\n",
drive->name, set_max_ext, capacity_2);
#endif
}
drive->bios_cyl = drive->cyl;
drive->capacity48 = capacity_2;
drive->capacity = (unsigned long) capacity_2;
return;
/* Determine capacity, and use LBA if the drive properly supports it */
} else if ((id->capability & 2) && lba_capacity_is_ok(id)) {
capacity = id->lba_capacity;
drive->cyl = capacity / (drive->head * drive->sect);
drive->select.b.lba = 1;
}
if (set_max > capacity) {
#ifdef CONFIG_IDEDISK_STROKE
set_max = idedisk_read_native_max_address(drive);
set_max = idedisk_set_max_address(drive, set_max);
if (set_max) {
drive->capacity = capacity = set_max;
drive->cyl = set_max / (drive->head * drive->sect);
drive->select.b.lba = 1;
drive->id->lba_capacity = capacity;
}
#else
printk("%s: setmax LBA %lu, native %lu\n",
drive->name, set_max, capacity);
#endif
}
drive->capacity = capacity;
if ((id->command_set_2 & 0x0400) && (id->cfs_enable_2 & 0x0400)) {
drive->capacity48 = id->lba_capacity_2;
drive->head = 255;
drive->sect = 63;
drive->cyl = (unsigned long)(drive->capacity48) / (drive->head * drive->sect);
}
}
static unsigned long idedisk_capacity (ide_drive_t *drive)
{
if (drive->id->cfs_enable_2 & 0x0400)
return (drive->capacity48 - drive->sect0);
return (drive->capacity - drive->sect0);
}
static ide_startstop_t idedisk_special (ide_drive_t *drive)
{
special_t *s = &drive->special;
if (s->b.set_geometry) {
struct ata_taskfile args;
s->b.set_geometry = 0;
memset(&args, 0, sizeof(args)); memset(&args, 0, sizeof(args));
args.taskfile.sector_number = drive->sect; args.taskfile.sector_number = drive->sect;
...@@ -648,8 +391,9 @@ static ide_startstop_t idedisk_special (ide_drive_t *drive) ...@@ -648,8 +391,9 @@ static ide_startstop_t idedisk_special (ide_drive_t *drive)
args.handler = set_geometry_intr;; args.handler = set_geometry_intr;;
} }
ata_taskfile(drive, &args, NULL); ata_taskfile(drive, &args, NULL);
} else if (s->b.recalibrate) { } else if (special_cmd & ATA_SPECIAL_RECALIBRATE) {
s->b.recalibrate = 0; drive->special_cmd &= ~ATA_SPECIAL_RECALIBRATE;
if (!IS_PDC4030_DRIVE) { if (!IS_PDC4030_DRIVE) {
struct ata_taskfile args; struct ata_taskfile args;
...@@ -659,8 +403,8 @@ static ide_startstop_t idedisk_special (ide_drive_t *drive) ...@@ -659,8 +403,8 @@ static ide_startstop_t idedisk_special (ide_drive_t *drive)
args.handler = recal_intr; args.handler = recal_intr;
ata_taskfile(drive, &args, NULL); ata_taskfile(drive, &args, NULL);
} }
} else if (s->b.set_multmode) { } else if (special_cmd & ATA_SPECIAL_MMODE) {
s->b.set_multmode = 0; drive->special_cmd &= ~ATA_SPECIAL_MMODE;
if (drive->id && drive->mult_req > drive->id->max_multsect) if (drive->id && drive->mult_req > drive->id->max_multsect)
drive->mult_req = drive->id->max_multsect; drive->mult_req = drive->id->max_multsect;
if (!IS_PDC4030_DRIVE) { if (!IS_PDC4030_DRIVE) {
...@@ -673,10 +417,10 @@ static ide_startstop_t idedisk_special (ide_drive_t *drive) ...@@ -673,10 +417,10 @@ static ide_startstop_t idedisk_special (ide_drive_t *drive)
ata_taskfile(drive, &args, NULL); ata_taskfile(drive, &args, NULL);
} }
} else if (s->all) { } else if (special_cmd) {
int special = s->all; drive->special_cmd = 0;
s->all = 0;
printk(KERN_ERR "%s: bad special flag: 0x%02x\n", drive->name, special); printk(KERN_ERR "%s: bad special flag: 0x%02x\n", drive->name, special_cmd);
return ide_stopped; return ide_stopped;
} }
return IS_PDC4030_DRIVE ? ide_stopped : ide_started; return IS_PDC4030_DRIVE ? ide_stopped : ide_started;
...@@ -686,13 +430,14 @@ static void idedisk_pre_reset (ide_drive_t *drive) ...@@ -686,13 +430,14 @@ static void idedisk_pre_reset (ide_drive_t *drive)
{ {
int legacy = (drive->id->cfs_enable_2 & 0x0400) ? 0 : 1; int legacy = (drive->id->cfs_enable_2 & 0x0400) ? 0 : 1;
drive->special.all = 0; if (legacy)
drive->special.b.set_geometry = legacy; drive->special_cmd = (ATA_SPECIAL_GEOMETRY | ATA_SPECIAL_RECALIBRATE);
drive->special.b.recalibrate = legacy; else
drive->special_cmd = 0;
if (OK_TO_RESET_CONTROLLER) if (OK_TO_RESET_CONTROLLER)
drive->mult_count = 0; drive->mult_count = 0;
if (drive->mult_req != drive->mult_count) if (drive->mult_req != drive->mult_count)
drive->special.b.set_multmode = 1; drive->special_cmd |= ATA_SPECIAL_MMODE;
} }
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
...@@ -812,19 +557,23 @@ static ide_proc_entry_t idedisk_proc[] = { ...@@ -812,19 +557,23 @@ static ide_proc_entry_t idedisk_proc[] = {
#endif /* CONFIG_PROC_FS */ #endif /* CONFIG_PROC_FS */
/* /*
* This is tightly woven into the driver->do_special can not touch. * This is tightly woven into the driver->special can not touch.
* DON'T do it again until a total personality rewrite is committed. * DON'T do it again until a total personality rewrite is committed.
*/ */
static int set_multcount(ide_drive_t *drive, int arg) static int set_multcount(ide_drive_t *drive, int arg)
{ {
struct request rq; struct ata_taskfile args;
if (drive->special.b.set_multmode) if (drive->special_cmd & ATA_SPECIAL_MMODE)
return -EBUSY; return -EBUSY;
ide_init_drive_cmd (&rq);
memset(&args, 0, sizeof(args));
drive->mult_req = arg; drive->mult_req = arg;
drive->special.b.set_multmode = 1; drive->special_cmd |= ATA_SPECIAL_MMODE;
ide_do_drive_cmd (drive, &rq, ide_wait);
ide_raw_taskfile(drive, &args, NULL);
return (drive->mult_count == arg) ? 0 : -EIO; return (drive->mult_count == arg) ? 0 : -EIO;
} }
...@@ -835,6 +584,7 @@ static int set_nowerr(ide_drive_t *drive, int arg) ...@@ -835,6 +584,7 @@ static int set_nowerr(ide_drive_t *drive, int arg)
drive->nowerr = arg; drive->nowerr = arg;
drive->bad_wstat = arg ? BAD_R_STAT : BAD_W_STAT; drive->bad_wstat = arg ? BAD_R_STAT : BAD_W_STAT;
spin_unlock_irq(&ide_lock); spin_unlock_irq(&ide_lock);
return 0; return 0;
} }
...@@ -968,12 +718,153 @@ static struct device_driver idedisk_devdrv = { ...@@ -968,12 +718,153 @@ static struct device_driver idedisk_devdrv = {
resume: idedisk_resume, resume: idedisk_resume,
}; };
static void idedisk_setup(ide_drive_t *drive) /*
* Queries for true maximum capacity of the drive.
* Returns maximum LBA address (> 0) of the drive, 0 if failed.
*/
static unsigned long native_max_address(struct ata_device *drive)
{
struct ata_taskfile args;
unsigned long addr = 0;
if (!(drive->id->command_set_1 & 0x0400) &&
!(drive->id->cfs_enable_2 & 0x0100))
return addr;
/* Create IDE/ATA command request structure */
memset(&args, 0, sizeof(args));
args.taskfile.device_head = 0x40;
args.taskfile.command = WIN_READ_NATIVE_MAX;
args.handler = task_no_data_intr;
/* submit command request */
ide_raw_taskfile(drive, &args, NULL);
/* if OK, compute maximum address value */
if ((args.taskfile.command & 0x01) == 0) {
addr = ((args.taskfile.device_head & 0x0f) << 24)
| (args.taskfile.high_cylinder << 16)
| (args.taskfile.low_cylinder << 8)
| args.taskfile.sector_number;
}
addr++; /* since the return value is (maxlba - 1), we add 1 */
return addr;
}
static u64 native_max_address_ext(struct ata_device *drive)
{
struct ata_taskfile args;
u64 addr = 0;
/* Create IDE/ATA command request structure */
memset(&args, 0, sizeof(args));
args.taskfile.device_head = 0x40;
args.taskfile.command = WIN_READ_NATIVE_MAX_EXT;
args.handler = task_no_data_intr;
/* submit command request */
ide_raw_taskfile(drive, &args, NULL);
/* if OK, compute maximum address value */
if ((args.taskfile.command & 0x01) == 0) {
u32 high = (args.hobfile.high_cylinder << 16) |
(args.hobfile.low_cylinder << 8) |
args.hobfile.sector_number;
u32 low = (args.taskfile.high_cylinder << 16) |
(args.taskfile.low_cylinder << 8) |
args.taskfile.sector_number;
addr = ((u64)high << 24) | low;
}
addr++; /* since the return value is (maxlba - 1), we add 1 */
return addr;
}
#ifdef CONFIG_IDEDISK_STROKE
/*
* Sets maximum virtual LBA address of the drive.
* Returns new maximum virtual LBA address (> 0) or 0 on failure.
*/
static sector_t set_max_address(ide_drive_t *drive, sector_t addr_req)
{
struct ata_taskfile args;
sector_t addr_set = 0;
addr_req--;
/* Create IDE/ATA command request structure */
memset(&args, 0, sizeof(args));
args.taskfile.sector_number = (addr_req >> 0);
args.taskfile.low_cylinder = (addr_req >> 8);
args.taskfile.high_cylinder = (addr_req >> 16);
args.taskfile.device_head = ((addr_req >> 24) & 0x0f) | 0x40;
args.taskfile.command = WIN_SET_MAX;
args.handler = task_no_data_intr;
/* submit command request */
ide_raw_taskfile(drive, &args, NULL);
/* if OK, read new maximum address value */
if ((args.taskfile.command & 0x01) == 0) {
addr_set = ((args.taskfile.device_head & 0x0f) << 24)
| (args.taskfile.high_cylinder << 16)
| (args.taskfile.low_cylinder << 8)
| args.taskfile.sector_number;
}
addr_set++;
return addr_set;
}
static u64 set_max_address_ext(ide_drive_t *drive, u64 addr_req)
{
struct ata_taskfile args;
u64 addr_set = 0;
addr_req--;
/* Create IDE/ATA command request structure */
memset(&args, 0, sizeof(args));
args.taskfile.sector_number = (addr_req >> 0);
args.taskfile.low_cylinder = (addr_req >>= 8);
args.taskfile.high_cylinder = (addr_req >>= 8);
args.taskfile.device_head = 0x40;
args.taskfile.command = WIN_SET_MAX_EXT;
args.hobfile.sector_number = (addr_req >>= 8);
args.hobfile.low_cylinder = (addr_req >>= 8);
args.hobfile.high_cylinder = (addr_req >>= 8);
args.hobfile.device_head = 0x40;
args.hobfile.control = (drive->ctl | 0x80);
args.handler = task_no_data_intr;
/* submit command request */
ide_raw_taskfile(drive, &args, NULL);
/* if OK, compute maximum address value */
if ((args.taskfile.command & 0x01) == 0) {
u32 high = (args.hobfile.high_cylinder << 16) |
(args.hobfile.low_cylinder << 8) |
args.hobfile.sector_number;
u32 low = (args.taskfile.high_cylinder << 16) |
(args.taskfile.low_cylinder << 8) |
args.taskfile.sector_number;
addr_set = ((u64)high << 24) | low;
}
return addr_set;
}
#endif
static void idedisk_setup(struct ata_device *drive)
{ {
int i; int i;
struct hd_driveid *id = drive->id; struct hd_driveid *id = drive->id;
unsigned long capacity; sector_t capacity;
sector_t set_max;
int drvid = -1; int drvid = -1;
idedisk_add_settings(drive); idedisk_add_settings(drive);
...@@ -1024,7 +915,7 @@ static void idedisk_setup(ide_drive_t *drive) ...@@ -1024,7 +915,7 @@ static void idedisk_setup(ide_drive_t *drive)
drive->sect = drive->bios_sect = id->sectors; drive->sect = drive->bios_sect = id->sectors;
} }
/* Handle logical geometry translation by the drive */ /* Handle logical geometry translation by the drive. */
if ((id->field_valid & 1) && id->cur_cyls && if ((id->field_valid & 1) && id->cur_cyls &&
id->cur_heads && (id->cur_heads <= 16) && id->cur_sectors) { id->cur_heads && (id->cur_heads <= 16) && id->cur_sectors) {
drive->cyl = id->cur_cyls; drive->cyl = id->cur_cyls;
...@@ -1032,31 +923,126 @@ static void idedisk_setup(ide_drive_t *drive) ...@@ -1032,31 +923,126 @@ static void idedisk_setup(ide_drive_t *drive)
drive->sect = id->cur_sectors; drive->sect = id->cur_sectors;
} }
/* Use physical geometry if what we have still makes no sense */ /* Use physical geometry if what we have still makes no sense. */
if (drive->head > 16 && id->heads && id->heads <= 16) { if (drive->head > 16 && id->heads && id->heads <= 16) {
drive->cyl = id->cyls; drive->cyl = id->cyls;
drive->head = id->heads; drive->head = id->heads;
drive->sect = id->sectors; drive->sect = id->sectors;
} }
/* calculate drive capacity, and select LBA if possible */ /* Calculate drive capacity, and select LBA if possible.
init_idedisk_capacity (drive); * drive->id != NULL is spected
*
* To compute capacity, this uses either of
*
* 1. CHS value set by user (whatever user sets will be trusted)
* 2. LBA value from target drive (require new ATA feature)
* 3. LBA value from system BIOS (new one is OK, old one may break)
* 4. CHS value from system BIOS (traditional style)
*
* in above order (i.e., if value of higher priority is available,
* reset will be ignored).
*/
capacity = drive->cyl * drive->head * drive->sect;
set_max = native_max_address(drive);
drive->capacity = 0;
drive->select.b.lba = 0;
if (id->cfs_enable_2 & 0x0400) {
u64 set_max_ext;
u64 capacity_2;
capacity_2 = capacity;
capacity_2 = id->lba_capacity_2;
drive->cyl = (unsigned int) capacity_2 / (drive->head * drive->sect);
drive->head = drive->bios_head = 255;
drive->sect = drive->bios_sect = 63;
drive->select.b.lba = 1;
set_max_ext = native_max_address_ext(drive);
if (set_max_ext > capacity_2) {
#ifdef CONFIG_IDEDISK_STROKE
set_max_ext = native_max_address_ext(drive);
set_max_ext = set_max_address_ext(drive, set_max_ext);
if (set_max_ext) {
drive->capacity = capacity_2 = set_max_ext;
drive->cyl = (unsigned int) set_max_ext / (drive->head * drive->sect);
drive->select.b.lba = 1;
drive->id->lba_capacity_2 = capacity_2;
}
#else
printk("%s: setmax_ext LBA %llu, native %llu\n",
drive->name, set_max_ext, capacity_2);
#endif
}
drive->bios_cyl = drive->cyl;
drive->capacity = capacity_2;
} else {
/*
* Determine capacity, and use LBA if the drive properly
* supports it.
*/
if ((id->capability & 2) && lba_capacity_is_ok(id)) {
capacity = id->lba_capacity;
drive->cyl = capacity / (drive->head * drive->sect);
drive->select.b.lba = 1;
}
if (set_max > capacity) {
#ifdef CONFIG_IDEDISK_STROKE
set_max = native_max_address(drive);
set_max = set_max_address(drive, set_max);
if (set_max) {
drive->capacity = capacity = set_max;
drive->cyl = set_max / (drive->head * drive->sect);
drive->select.b.lba = 1;
drive->id->lba_capacity = capacity;
}
#else
printk("%s: setmax LBA %lu, native %lu\n",
drive->name, set_max, capacity);
#endif
}
drive->capacity = capacity;
if ((id->command_set_2 & 0x0400) && (id->cfs_enable_2 & 0x0400)) {
drive->capacity = id->lba_capacity_2;
drive->head = 255;
drive->sect = 63;
drive->cyl = (unsigned long)(drive->capacity) / (drive->head * drive->sect);
}
}
/* /*
* if possible, give fdisk access to more of the drive, * If possible, give fdisk access to more of the drive,
* by correcting bios_cyls: * by correcting bios_cyls:
*/ */
capacity = idedisk_capacity (drive); capacity = idedisk_capacity(drive);
if ((capacity >= (drive->bios_cyl * drive->bios_sect * drive->bios_head)) && if ((capacity >= (drive->bios_cyl * drive->bios_sect * drive->bios_head)) &&
(!drive->forced_geom) && drive->bios_sect && drive->bios_head) (!drive->forced_geom) && drive->bios_sect && drive->bios_head)
drive->bios_cyl = (capacity / drive->bios_sect) / drive->bios_head; drive->bios_cyl = (capacity / drive->bios_sect) / drive->bios_head;
printk(KERN_INFO "%s: %ld sectors", drive->name, capacity); printk(KERN_INFO "%s: %ld sectors", drive->name, capacity);
/* Give size in megabytes (MB), not mebibytes (MiB). */ #if 0
/* We compute the exact rounded value, avoiding overflow. */
/* Right now we avoid this calculation, since it can result in the
* usage of not supported compiler internal functions on 32 bit hosts.
* However since the calculation appears to be an interesting piece of
* number theory let's preserve the formula here.
*/
/* Give size in megabytes (MB), not mebibytes (MiB).
* We compute the exact rounded value, avoiding overflow.
*/
printk(" (%ld MB)", (capacity - capacity/625 + 974)/1950); printk(" (%ld MB)", (capacity - capacity/625 + 974)/1950);
#endif
/* Only print cache size when it was specified */ /* Only print cache size when it was specified.
*/
if (id->buf_size) if (id->buf_size)
printk (" w/%dKiB Cache", id->buf_size/2); printk (" w/%dKiB Cache", id->buf_size/2);
...@@ -1074,14 +1060,15 @@ static void idedisk_setup(ide_drive_t *drive) ...@@ -1074,14 +1060,15 @@ static void idedisk_setup(ide_drive_t *drive)
id->multsect = ((id->max_multsect/2) > 1) ? id->max_multsect : 0; id->multsect = ((id->max_multsect/2) > 1) ? id->max_multsect : 0;
id->multsect_valid = id->multsect ? 1 : 0; id->multsect_valid = id->multsect ? 1 : 0;
drive->mult_req = id->multsect_valid ? id->max_multsect : INITIAL_MULT_COUNT; drive->mult_req = id->multsect_valid ? id->max_multsect : INITIAL_MULT_COUNT;
drive->special.b.set_multmode = drive->mult_req ? 1 : 0; if (drive->mult_req)
drive->special_cmd |= ATA_SPECIAL_MMODE;
#else #else
/* original, pre IDE-NFG, per request of AC */ /* original, pre IDE-NFG, per request of AC */
drive->mult_req = INITIAL_MULT_COUNT; drive->mult_req = INITIAL_MULT_COUNT;
if (drive->mult_req > id->max_multsect) if (drive->mult_req > id->max_multsect)
drive->mult_req = id->max_multsect; drive->mult_req = id->max_multsect;
if (drive->mult_req || ((id->multsect_valid & 1) && id->multsect)) if (drive->mult_req || ((id->multsect_valid & 1) && id->multsect))
drive->special.b.set_multmode = 1; drive->special_cmd |= ATA_SPECIAL_MMODE;
#endif #endif
} }
...@@ -1095,6 +1082,7 @@ static void idedisk_setup(ide_drive_t *drive) ...@@ -1095,6 +1082,7 @@ static void idedisk_setup(ide_drive_t *drive)
if (drive->id->cfs_enable_2 & 0x3000) if (drive->id->cfs_enable_2 & 0x3000)
write_cache(drive, (id->cfs_enable_2 & 0x3000)); write_cache(drive, (id->cfs_enable_2 & 0x3000));
probe_lba_addressing(drive, 1); probe_lba_addressing(drive, 1);
} }
......
...@@ -295,7 +295,7 @@ int ide_build_dmatable (ide_drive_t *drive, ide_dma_action_t func) ...@@ -295,7 +295,7 @@ int ide_build_dmatable (ide_drive_t *drive, ide_dma_action_t func)
int i; int i;
struct scatterlist *sg; struct scatterlist *sg;
if (HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE) { if (HWGROUP(drive)->rq->flags & REQ_DRIVE_ACB) {
hwif->sg_nents = i = raw_build_sglist(hwif, HWGROUP(drive)->rq); hwif->sg_nents = i = raw_build_sglist(hwif, HWGROUP(drive)->rq);
} else { } else {
hwif->sg_nents = i = ide_build_sglist(hwif, HWGROUP(drive)->rq); hwif->sg_nents = i = ide_build_sglist(hwif, HWGROUP(drive)->rq);
...@@ -590,9 +590,10 @@ int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive) ...@@ -590,9 +590,10 @@ int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
BUG_ON(HWGROUP(drive)->handler); BUG_ON(HWGROUP(drive)->handler);
ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, dma_timer_expiry); /* issue cmd to drive */ ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, dma_timer_expiry); /* issue cmd to drive */
if ((HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE) && if ((HWGROUP(drive)->rq->flags & REQ_DRIVE_ACB) &&
(drive->addressing == 1)) { (drive->addressing == 1)) {
struct ata_taskfile *args = HWGROUP(drive)->rq->special; struct ata_taskfile *args = HWGROUP(drive)->rq->special;
OUT_BYTE(args->taskfile.command, IDE_COMMAND_REG); OUT_BYTE(args->taskfile.command, IDE_COMMAND_REG);
} else if (drive->addressing) { } else if (drive->addressing) {
OUT_BYTE(reading ? WIN_READDMA_EXT : WIN_WRITEDMA_EXT, IDE_COMMAND_REG); OUT_BYTE(reading ? WIN_READDMA_EXT : WIN_WRITEDMA_EXT, IDE_COMMAND_REG);
......
...@@ -1255,7 +1255,7 @@ static void idefloppy_create_test_unit_ready_cmd(idefloppy_pc_t *pc) ...@@ -1255,7 +1255,7 @@ static void idefloppy_create_test_unit_ready_cmd(idefloppy_pc_t *pc)
pc->c[0] = IDEFLOPPY_TEST_UNIT_READY_CMD; pc->c[0] = IDEFLOPPY_TEST_UNIT_READY_CMD;
} }
static void idefloppy_create_rw_cmd (idefloppy_floppy_t *floppy, idefloppy_pc_t *pc, struct request *rq, unsigned long sector) static void idefloppy_create_rw_cmd(idefloppy_floppy_t *floppy, idefloppy_pc_t *pc, struct request *rq, sector_t sector)
{ {
int block = sector / floppy->bs_factor; int block = sector / floppy->bs_factor;
int blocks = rq->nr_sectors / floppy->bs_factor; int blocks = rq->nr_sectors / floppy->bs_factor;
...@@ -1287,9 +1287,9 @@ static void idefloppy_create_rw_cmd (idefloppy_floppy_t *floppy, idefloppy_pc_t ...@@ -1287,9 +1287,9 @@ static void idefloppy_create_rw_cmd (idefloppy_floppy_t *floppy, idefloppy_pc_t
} }
/* /*
* idefloppy_do_request is our request handling function. * This is our request handling function.
*/ */
static ide_startstop_t idefloppy_do_request (ide_drive_t *drive, struct request *rq, unsigned long block) static ide_startstop_t idefloppy_do_request(struct ata_device *drive, struct request *rq, sector_t block)
{ {
idefloppy_floppy_t *floppy = drive->driver_data; idefloppy_floppy_t *floppy = drive->driver_data;
idefloppy_pc_t *pc; idefloppy_pc_t *pc;
...@@ -1297,7 +1297,7 @@ static ide_startstop_t idefloppy_do_request (ide_drive_t *drive, struct request ...@@ -1297,7 +1297,7 @@ static ide_startstop_t idefloppy_do_request (ide_drive_t *drive, struct request
#if IDEFLOPPY_DEBUG_LOG #if IDEFLOPPY_DEBUG_LOG
printk (KERN_INFO "rq_status: %d, rq_dev: %u, flags: %lx, errors: %d\n",rq->rq_status,(unsigned int) rq->rq_dev,rq->flags,rq->errors); printk (KERN_INFO "rq_status: %d, rq_dev: %u, flags: %lx, errors: %d\n",rq->rq_status,(unsigned int) rq->rq_dev,rq->flags,rq->errors);
printk (KERN_INFO "sector: %ld, nr_sectors: %ld, current_nr_sectors: %d\n",rq->sector,rq->nr_sectors,rq->current_nr_sectors); printk (KERN_INFO "sector: %ld, nr_sectors: %ld, current_nr_sectors: %d\n",rq->sector,rq->nr_sectors,rq->current_nr_sectors);
#endif /* IDEFLOPPY_DEBUG_LOG */ #endif
if (rq->errors >= ERROR_MAX) { if (rq->errors >= ERROR_MAX) {
if (floppy->failed_pc != NULL) if (floppy->failed_pc != NULL)
...@@ -1314,7 +1314,7 @@ static ide_startstop_t idefloppy_do_request (ide_drive_t *drive, struct request ...@@ -1314,7 +1314,7 @@ static ide_startstop_t idefloppy_do_request (ide_drive_t *drive, struct request
idefloppy_end_request(drive, 0); idefloppy_end_request(drive, 0);
return ide_stopped; return ide_stopped;
} }
pc = idefloppy_next_pc_storage (drive); pc = idefloppy_next_pc_storage(drive);
idefloppy_create_rw_cmd (floppy, pc, rq, block); idefloppy_create_rw_cmd (floppy, pc, rq, block);
} else if (rq->flags & IDEFLOPPY_RQ) { } else if (rq->flags & IDEFLOPPY_RQ) {
pc = (idefloppy_pc_t *) rq->buffer; pc = (idefloppy_pc_t *) rq->buffer;
...@@ -2063,9 +2063,7 @@ static struct ata_operations idefloppy_driver = { ...@@ -2063,9 +2063,7 @@ static struct ata_operations idefloppy_driver = {
release: idefloppy_release, release: idefloppy_release,
check_media_change: idefloppy_check_media_change, check_media_change: idefloppy_check_media_change,
revalidate: NULL, /* use default method */ revalidate: NULL, /* use default method */
pre_reset: NULL,
capacity: idefloppy_capacity, capacity: idefloppy_capacity,
special: NULL,
proc: idefloppy_proc proc: idefloppy_proc
}; };
......
...@@ -1109,7 +1109,7 @@ pmac_ide_build_dmatable(ide_drive_t *drive, int ix, int wr) ...@@ -1109,7 +1109,7 @@ pmac_ide_build_dmatable(ide_drive_t *drive, int ix, int wr)
udelay(1); udelay(1);
/* Build sglist */ /* Build sglist */
if (rq->flags & REQ_DRIVE_TASKFILE) { if (rq->flags & REQ_DRIVE_ACB) {
pmac_ide[ix].sg_nents = i = pmac_raw_build_sglist(ix, rq); pmac_ide[ix].sg_nents = i = pmac_raw_build_sglist(ix, rq);
} else { } else {
pmac_ide[ix].sg_nents = i = pmac_ide_build_sglist(ix, rq); pmac_ide[ix].sg_nents = i = pmac_ide_build_sglist(ix, rq);
...@@ -1386,7 +1386,7 @@ int pmac_ide_dmaproc(ide_dma_action_t func, ide_drive_t *drive) ...@@ -1386,7 +1386,7 @@ int pmac_ide_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
return 0; return 0;
BUG_ON(HWGROUP(drive)->handler); BUG_ON(HWGROUP(drive)->handler);
ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
if ((HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE) && if ((HWGROUP(drive)->rq->flags & REQ_DRIVE_ACB) &&
(drive->addressing == 1)) { (drive->addressing == 1)) {
struct ata_taskfile *args = HWGROUP(drive)->rq->special; struct ata_taskfile *args = HWGROUP(drive)->rq->special;
OUT_BYTE(args->taskfile.command, IDE_COMMAND_REG); OUT_BYTE(args->taskfile.command, IDE_COMMAND_REG);
......
...@@ -160,8 +160,8 @@ static int proc_ide_read_imodel ...@@ -160,8 +160,8 @@ static int proc_ide_read_imodel
PROC_IDE_READ_RETURN(page,start,off,count,eof,len); PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
} }
static int proc_ide_read_channel static int proc_ide_read_channel(char *page, char **start,
(char *page, char **start, off_t off, int count, int *eof, void *data) off_t off, int count, int *eof, void *data)
{ {
struct ata_channel *hwif = data; struct ata_channel *hwif = data;
int len; int len;
......
...@@ -2614,9 +2614,9 @@ static void idetape_create_write_cmd (idetape_tape_t *tape, idetape_pc_t *pc, un ...@@ -2614,9 +2614,9 @@ static void idetape_create_write_cmd (idetape_tape_t *tape, idetape_pc_t *pc, un
} }
/* /*
* idetape_do_request is our request handling function. * This is our request handling function.
*/ */
static ide_startstop_t idetape_do_request (ide_drive_t *drive, struct request *rq, unsigned long block) static ide_startstop_t idetape_do_request(struct ata_device *drive, struct request *rq, sector_t block)
{ {
idetape_tape_t *tape = drive->driver_data; idetape_tape_t *tape = drive->driver_data;
idetape_pc_t *pc; idetape_pc_t *pc;
......
...@@ -476,15 +476,15 @@ ide_startstop_t ata_taskfile(ide_drive_t *drive, ...@@ -476,15 +476,15 @@ ide_startstop_t ata_taskfile(ide_drive_t *drive,
/* /*
* This is invoked on completion of a WIN_SETMULT cmd. * This is invoked on completion of a WIN_SETMULT cmd.
*/ */
ide_startstop_t set_multmode_intr (ide_drive_t *drive) ide_startstop_t set_multmode_intr(struct ata_device *drive)
{ {
byte stat; u8 stat;
if (OK_STAT(stat=GET_STAT(),READY_STAT,BAD_STAT)) { if (OK_STAT(stat=GET_STAT(),READY_STAT,BAD_STAT)) {
drive->mult_count = drive->mult_req; drive->mult_count = drive->mult_req;
} else { } else {
drive->mult_req = drive->mult_count = 0; drive->mult_req = drive->mult_count = 0;
drive->special.b.recalibrate = 1; drive->special_cmd |= ATA_SPECIAL_RECALIBRATE;
ide_dump_status(drive, "set_multmode", stat); ide_dump_status(drive, "set_multmode", stat);
} }
return ide_stopped; return ide_stopped;
...@@ -879,20 +879,12 @@ void ide_cmd_type_parser(struct ata_taskfile *args) ...@@ -879,20 +879,12 @@ void ide_cmd_type_parser(struct ata_taskfile *args)
} }
} }
/*
* This function is intended to be used prior to invoking ide_do_drive_cmd().
*/
static void init_taskfile_request(struct request *rq)
{
memset(rq, 0, sizeof(*rq));
rq->flags = REQ_DRIVE_TASKFILE;
}
int ide_raw_taskfile(ide_drive_t *drive, struct ata_taskfile *args, byte *buf) int ide_raw_taskfile(ide_drive_t *drive, struct ata_taskfile *args, byte *buf)
{ {
struct request rq; struct request rq;
init_taskfile_request(&rq);
memset(&rq, 0, sizeof(rq));
rq.flags = REQ_DRIVE_ACB;
rq.buffer = buf; rq.buffer = buf;
if (args->command_type != IDE_DRIVE_TASK_NO_DATA) if (args->command_type != IDE_DRIVE_TASK_NO_DATA)
...@@ -909,13 +901,8 @@ int ide_raw_taskfile(ide_drive_t *drive, struct ata_taskfile *args, byte *buf) ...@@ -909,13 +901,8 @@ int ide_raw_taskfile(ide_drive_t *drive, struct ata_taskfile *args, byte *buf)
* Implement generic ioctls invoked from userspace to imlpement specific * Implement generic ioctls invoked from userspace to imlpement specific
* functionality. * functionality.
* *
* FIXME: * Unfortunately every single low level programm out there is using this
* * interface.
* 1. Rewrite hdparm to use the ide_task_ioctl function.
*
* 2. Publish it.
*
* 3. Kill this and HDIO_DRIVE_CMD alltogether.
*/ */
int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg) int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)
...@@ -923,22 +910,19 @@ int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg) ...@@ -923,22 +910,19 @@ int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)
int err = 0; int err = 0;
u8 vals[4]; u8 vals[4];
u8 *argbuf = vals; u8 *argbuf = vals;
byte xfer_rate = 0; u8 xfer_rate = 0;
int argsize = 4; int argsize = 4;
struct ata_taskfile args; struct ata_taskfile args;
struct request rq; struct request rq;
/*
* First phase.
*/
if (NULL == (void *) arg) {
struct request rq;
ide_init_drive_cmd(&rq); ide_init_drive_cmd(&rq);
/* Wait for drive ready.
*/
if (!arg)
return ide_do_drive_cmd(drive, &rq, ide_wait); return ide_do_drive_cmd(drive, &rq, ide_wait);
}
/* /* Second phase.
* Second phase.
*/ */
if (copy_from_user(vals, (void *)arg, 4)) if (copy_from_user(vals, (void *)arg, 4))
return -EFAULT; return -EFAULT;
...@@ -960,6 +944,8 @@ int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg) ...@@ -960,6 +944,8 @@ int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)
memset(argbuf + 4, 0, argsize - 4); memset(argbuf + 4, 0, argsize - 4);
} }
/* Always make sure the transfer reate has been setup.
*/
if (set_transfer(drive, &args)) { if (set_transfer(drive, &args)) {
xfer_rate = vals[1]; xfer_rate = vals[1];
if (ide_ata66_check(drive, &args)) if (ide_ata66_check(drive, &args))
...@@ -968,7 +954,6 @@ int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg) ...@@ -968,7 +954,6 @@ int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)
/* Issue ATA command and wait for completion. /* Issue ATA command and wait for completion.
*/ */
ide_init_drive_cmd(&rq);
rq.buffer = argbuf; rq.buffer = argbuf;
err = ide_do_drive_cmd(drive, &rq, ide_wait); err = ide_do_drive_cmd(drive, &rq, ide_wait);
...@@ -978,44 +963,22 @@ int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg) ...@@ -978,44 +963,22 @@ int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)
drive->channel->speedproc(drive, xfer_rate); drive->channel->speedproc(drive, xfer_rate);
ide_driveid_update(drive); ide_driveid_update(drive);
} }
abort: abort:
if (copy_to_user((void *)arg, argbuf, argsize)) if (copy_to_user((void *)arg, argbuf, argsize))
err = -EFAULT; err = -EFAULT;
if (argsize > 4) if (argsize > 4)
kfree(argbuf); kfree(argbuf);
return err; return err;
} }
int ide_task_ioctl(ide_drive_t *drive, unsigned long arg)
{
int err = 0;
u8 args[7];
u8 *argbuf;
int argsize = 7;
struct request rq;
argbuf = args;
if (copy_from_user(args, (void *)arg, 7))
return -EFAULT;
ide_init_drive_cmd(&rq);
rq.flags = REQ_DRIVE_TASK;
rq.buffer = argbuf;
err = ide_do_drive_cmd(drive, &rq, ide_wait);
if (copy_to_user((void *)arg, argbuf, argsize))
err = -EFAULT;
return err;
}
EXPORT_SYMBOL(drive_is_ready); EXPORT_SYMBOL(drive_is_ready);
EXPORT_SYMBOL(ata_read); EXPORT_SYMBOL(ata_read);
EXPORT_SYMBOL(ata_write); EXPORT_SYMBOL(ata_write);
EXPORT_SYMBOL(atapi_read); EXPORT_SYMBOL(atapi_read);
EXPORT_SYMBOL(atapi_write); EXPORT_SYMBOL(atapi_write);
EXPORT_SYMBOL(ata_taskfile); EXPORT_SYMBOL(ata_taskfile);
EXPORT_SYMBOL(recal_intr); EXPORT_SYMBOL(recal_intr);
EXPORT_SYMBOL(set_geometry_intr); EXPORT_SYMBOL(set_geometry_intr);
...@@ -1023,6 +986,4 @@ EXPORT_SYMBOL(set_multmode_intr); ...@@ -1023,6 +986,4 @@ EXPORT_SYMBOL(set_multmode_intr);
EXPORT_SYMBOL(task_no_data_intr); EXPORT_SYMBOL(task_no_data_intr);
EXPORT_SYMBOL(ide_raw_taskfile); EXPORT_SYMBOL(ide_raw_taskfile);
EXPORT_SYMBOL(ide_cmd_type_parser); EXPORT_SYMBOL(ide_cmd_type_parser);
EXPORT_SYMBOL(ide_cmd_ioctl); EXPORT_SYMBOL(ide_cmd_ioctl);
EXPORT_SYMBOL(ide_task_ioctl);
...@@ -283,6 +283,7 @@ static void init_hwif_data(struct ata_channel *hwif, unsigned int index) ...@@ -283,6 +283,7 @@ static void init_hwif_data(struct ata_channel *hwif, unsigned int index)
hwif->major = ide_major[index]; hwif->major = ide_major[index];
sprintf(hwif->name, "ide%d", index); sprintf(hwif->name, "ide%d", index);
hwif->bus_state = BUSSTATE_ON; hwif->bus_state = BUSSTATE_ON;
for (unit = 0; unit < MAX_DRIVES; ++unit) { for (unit = 0; unit < MAX_DRIVES; ++unit) {
ide_drive_t *drive = &hwif->drives[unit]; ide_drive_t *drive = &hwif->drives[unit];
...@@ -292,10 +293,10 @@ static void init_hwif_data(struct ata_channel *hwif, unsigned int index) ...@@ -292,10 +293,10 @@ static void init_hwif_data(struct ata_channel *hwif, unsigned int index)
drive->ctl = 0x08; drive->ctl = 0x08;
drive->ready_stat = READY_STAT; drive->ready_stat = READY_STAT;
drive->bad_wstat = BAD_W_STAT; drive->bad_wstat = BAD_W_STAT;
drive->special.b.recalibrate = 1; drive->special_cmd = (ATA_SPECIAL_RECALIBRATE | ATA_SPECIAL_GEOMETRY);
drive->special.b.set_geometry = 1;
sprintf(drive->name, "hd%c", 'a' + (index * MAX_DRIVES) + unit); sprintf(drive->name, "hd%c", 'a' + (index * MAX_DRIVES) + unit);
drive->max_failures = IDE_DEFAULT_MAX_FAILURES; drive->max_failures = IDE_DEFAULT_MAX_FAILURES;
init_waitqueue_head(&drive->wqueue); init_waitqueue_head(&drive->wqueue);
} }
} }
...@@ -455,7 +456,7 @@ static void ata_pre_reset(ide_drive_t *drive) ...@@ -455,7 +456,7 @@ static void ata_pre_reset(ide_drive_t *drive)
* The capacity of a drive according to its current geometry/LBA settings in * The capacity of a drive according to its current geometry/LBA settings in
* sectors. * sectors.
*/ */
unsigned long ata_capacity(ide_drive_t *drive) sector_t ata_capacity(struct ata_device *drive)
{ {
if (!drive->present || !drive->driver) if (!drive->present || !drive->driver)
return 0; return 0;
...@@ -472,31 +473,31 @@ unsigned long ata_capacity(ide_drive_t *drive) ...@@ -472,31 +473,31 @@ unsigned long ata_capacity(ide_drive_t *drive)
/* /*
* This is used to issue WIN_SPECIFY, WIN_RESTORE, and WIN_SETMULT commands to * This is used to issue WIN_SPECIFY, WIN_RESTORE, and WIN_SETMULT commands to
* a drive. It used to do much more, but has been scaled back. * a drive.
*/ */
static ide_startstop_t ata_special (ide_drive_t *drive) static ide_startstop_t ata_special(struct ata_device *drive)
{ {
special_t *s = &drive->special; unsigned char special_cmd = drive->special_cmd;
#ifdef DEBUG #ifdef DEBUG
printk("%s: ata_special: 0x%02x\n", drive->name, s->all); printk("%s: ata_special: 0x%02x\n", drive->name, special_cmd);
#endif #endif
if (s->b.set_tune) { if (special_cmd & ATA_SPECIAL_TUNE) {
s->b.set_tune = 0; drive->special_cmd &= ~ATA_SPECIAL_TUNE;
if (drive->channel->tuneproc != NULL) if (drive->channel->tuneproc != NULL)
drive->channel->tuneproc(drive, drive->tune_req); drive->channel->tuneproc(drive, drive->tune_req);
} else if (drive->driver != NULL) { } else if (drive->driver != NULL) {
if (ata_ops(drive)->special) if (ata_ops(drive)->special)
return ata_ops(drive)->special(drive); return ata_ops(drive)->special(drive);
else { else {
drive->special.all = 0; drive->special_cmd = 0;
drive->mult_req = 0; drive->mult_req = 0;
return ide_stopped; return ide_stopped;
} }
} else if (s->all) { } else if (special_cmd) {
printk("%s: bad special flag: 0x%02x\n", drive->name, s->all); printk("%s: bad special flag: 0x%02x\n", drive->name, special_cmd);
s->all = 0; drive->special_cmd = 0;
} }
return ide_stopped; return ide_stopped;
...@@ -584,27 +585,25 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive) ...@@ -584,27 +585,25 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive)
drive->failures = 0; drive->failures = 0;
} else { } else {
drive->failures++; drive->failures++;
char *msg = "";
#if FANCY_STATUS_DUMPS #if FANCY_STATUS_DUMPS
printk("master: "); printk("master:");
switch (tmp & 0x7f) { switch (tmp & 0x7f) {
case 1: printk("passed"); case 1: msg = " passed";
break; break;
case 2: printk("formatter device error"); case 2: msg = " formatter device";
break; break;
case 3: printk("sector buffer error"); case 3: msg = " sector buffer";
break; break;
case 4: printk("ECC circuitry error"); case 4: msg = " ECC circuitry";
break; break;
case 5: printk("controlling MPU error"); case 5: msg = " controlling MPU error";
break; break;
default:printk("error (0x%02x?)", tmp);
} }
if (tmp & 0x80) if (tmp & 0x80)
printk("; slave: failed"); printk("; slave:");
printk("\n");
#else
printk("failed\n");
#endif #endif
printk("%s error [%02x]\n", msg, tmp);
} }
} }
hwgroup->poll_timeout = 0; /* done polling */ hwgroup->poll_timeout = 0; /* done polling */
...@@ -705,7 +704,7 @@ static inline u32 read_24 (ide_drive_t *drive) ...@@ -705,7 +704,7 @@ static inline u32 read_24 (ide_drive_t *drive)
/* /*
* Clean up after success/failure of an explicit drive cmd * Clean up after success/failure of an explicit drive cmd
*/ */
void ide_end_drive_cmd(ide_drive_t *drive, byte stat, byte err) void ide_end_drive_cmd(struct ata_device *drive, byte stat, byte err)
{ {
unsigned long flags; unsigned long flags;
struct request *rq; struct request *rq;
...@@ -714,27 +713,16 @@ void ide_end_drive_cmd(ide_drive_t *drive, byte stat, byte err) ...@@ -714,27 +713,16 @@ void ide_end_drive_cmd(ide_drive_t *drive, byte stat, byte err)
rq = HWGROUP(drive)->rq; rq = HWGROUP(drive)->rq;
if (rq->flags & REQ_DRIVE_CMD) { if (rq->flags & REQ_DRIVE_CMD) {
byte *args = (byte *) rq->buffer; u8 *args = rq->buffer;
rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT); rq->errors = !OK_STAT(stat, READY_STAT, BAD_STAT);
if (args) {
args[0] = stat;
args[1] = err;
args[2] = IN_BYTE(IDE_NSECTOR_REG);
}
} else if (rq->flags & REQ_DRIVE_TASK) {
byte *args = (byte *) rq->buffer;
rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
if (args) { if (args) {
args[0] = stat; args[0] = stat;
args[1] = err; args[1] = err;
args[2] = IN_BYTE(IDE_NSECTOR_REG); args[2] = IN_BYTE(IDE_NSECTOR_REG);
args[3] = IN_BYTE(IDE_SECTOR_REG);
args[4] = IN_BYTE(IDE_LCYL_REG);
args[5] = IN_BYTE(IDE_HCYL_REG);
args[6] = IN_BYTE(IDE_SELECT_REG);
} }
} else if (rq->flags & REQ_DRIVE_TASKFILE) { } else if (rq->flags & REQ_DRIVE_ACB) {
struct ata_taskfile *args = rq->special; struct ata_taskfile *args = rq->special;
rq->errors = !OK_STAT(stat, READY_STAT, BAD_STAT); rq->errors = !OK_STAT(stat, READY_STAT, BAD_STAT);
if (args) { if (args) {
args->taskfile.feature = err; args->taskfile.feature = err;
...@@ -783,16 +771,23 @@ byte ide_dump_status (ide_drive_t *drive, const char *msg, byte stat) ...@@ -783,16 +771,23 @@ byte ide_dump_status (ide_drive_t *drive, const char *msg, byte stat)
if (stat & BUSY_STAT) if (stat & BUSY_STAT)
printk("Busy "); printk("Busy ");
else { else {
if (stat & READY_STAT) printk("DriveReady "); if (stat & READY_STAT)
if (stat & WRERR_STAT) printk("DeviceFault "); printk("DriveReady ");
if (stat & SEEK_STAT) printk("SeekComplete "); if (stat & WRERR_STAT)
if (stat & DRQ_STAT) printk("DataRequest "); printk("DeviceFault ");
if (stat & ECC_STAT) printk("CorrectedError "); if (stat & SEEK_STAT)
if (stat & INDEX_STAT) printk("Index "); printk("SeekComplete ");
if (stat & ERR_STAT) printk("Error "); if (stat & DRQ_STAT)
printk("DataRequest ");
if (stat & ECC_STAT)
printk("CorrectedError ");
if (stat & INDEX_STAT)
printk("Index ");
if (stat & ERR_STAT)
printk("Error ");
} }
printk("}"); printk("}");
#endif /* FANCY_STATUS_DUMPS */ #endif
printk("\n"); printk("\n");
if ((stat & (BUSY_STAT|ERR_STAT)) == ERR_STAT) { if ((stat & (BUSY_STAT|ERR_STAT)) == ERR_STAT) {
err = GET_ERR(); err = GET_ERR();
...@@ -839,7 +834,7 @@ byte ide_dump_status (ide_drive_t *drive, const char *msg, byte stat) ...@@ -839,7 +834,7 @@ byte ide_dump_status (ide_drive_t *drive, const char *msg, byte stat)
printk(", sector=%ld", HWGROUP(drive)->rq->sector); printk(", sector=%ld", HWGROUP(drive)->rq->sector);
} }
} }
#endif /* FANCY_STATUS_DUMPS */ #endif
printk("\n"); printk("\n");
} }
__restore_flags (flags); /* local CPU only */ __restore_flags (flags); /* local CPU only */
...@@ -907,7 +902,6 @@ ide_startstop_t ide_error(ide_drive_t *drive, const char *msg, byte stat) ...@@ -907,7 +902,6 @@ ide_startstop_t ide_error(ide_drive_t *drive, const char *msg, byte stat)
OUT_BYTE(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG); /* force an abort */ OUT_BYTE(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG); /* force an abort */
if (rq->errors >= ERROR_MAX) { if (rq->errors >= ERROR_MAX) {
/* ATA-PATTERN */
if (ata_ops(drive) && ata_ops(drive)->end_request) if (ata_ops(drive) && ata_ops(drive)->end_request)
ata_ops(drive)->end_request(drive, 0); ata_ops(drive)->end_request(drive, 0);
else else
...@@ -918,7 +912,7 @@ ide_startstop_t ide_error(ide_drive_t *drive, const char *msg, byte stat) ...@@ -918,7 +912,7 @@ ide_startstop_t ide_error(ide_drive_t *drive, const char *msg, byte stat)
return do_reset1(drive, 0); return do_reset1(drive, 0);
} }
if ((rq->errors & ERROR_RECAL) == ERROR_RECAL) if ((rq->errors & ERROR_RECAL) == ERROR_RECAL)
drive->special.b.recalibrate = 1; drive->special_cmd |= ATA_SPECIAL_RECALIBRATE;
++rq->errors; ++rq->errors;
} }
return ide_stopped; return ide_stopped;
...@@ -1020,47 +1014,55 @@ int ide_wait_stat(ide_startstop_t *startstop, ide_drive_t *drive, byte good, byt ...@@ -1020,47 +1014,55 @@ int ide_wait_stat(ide_startstop_t *startstop, ide_drive_t *drive, byte good, byt
*/ */
static ide_startstop_t start_request(ide_drive_t *drive, struct request *rq) static ide_startstop_t start_request(ide_drive_t *drive, struct request *rq)
{ {
ide_startstop_t startstop; sector_t block;
unsigned long block; unsigned int minor = minor(rq->rq_dev);
unsigned int minor = minor(rq->rq_dev), unit = minor >> PARTN_BITS; unsigned int unit = minor >> PARTN_BITS;
struct ata_channel *hwif = drive->channel; struct ata_channel *ch = drive->channel;
BUG_ON(!(rq->flags & REQ_STARTED)); BUG_ON(!(rq->flags & REQ_STARTED));
#ifdef DEBUG #ifdef DEBUG
printk("%s: start_request: current=0x%08lx\n", hwif->name, (unsigned long) rq); printk("%s: start_request: current=0x%08lx\n", ch->name, (unsigned long) rq);
#endif #endif
/* bail early if we've exceeded max_failures */ /* bail early if we've exceeded max_failures */
if (drive->max_failures && (drive->failures > drive->max_failures)) { if (drive->max_failures && (drive->failures > drive->max_failures))
goto kill_rq; goto kill_rq;
}
if (unit >= MAX_DRIVES) { if (unit >= MAX_DRIVES) {
printk("%s: bad device number: %s\n", hwif->name, kdevname(rq->rq_dev)); printk(KERN_ERR "%s: bad device number: %s\n", ch->name, kdevname(rq->rq_dev));
goto kill_rq; goto kill_rq;
} }
block = rq->sector; block = rq->sector;
/* Strange disk manager remap */ /* Strange disk manager remap.
*/
if ((rq->flags & REQ_CMD) && if ((rq->flags & REQ_CMD) &&
(drive->type == ATA_DISK || drive->type == ATA_FLOPPY)) { (drive->type == ATA_DISK || drive->type == ATA_FLOPPY)) {
block += drive->sect0; block += drive->sect0;
} }
/* Yecch - this will shift the entire interval,
possibly killing some innocent following sector */ /* Yecch - this will shift the entire interval, possibly killing some
* innocent following sector.
*/
if (block == 0 && drive->remap_0_to_1 == 1) if (block == 0 && drive->remap_0_to_1 == 1)
block = 1; /* redirect MBR access to EZ-Drive partn table */ block = 1; /* redirect MBR access to EZ-Drive partn table */
#if (DISK_RECOVERY_TIME > 0) #if (DISK_RECOVERY_TIME > 0)
while ((read_timer() - hwif->last_time) < DISK_RECOVERY_TIME); while ((read_timer() - ch->last_time) < DISK_RECOVERY_TIME);
#endif #endif
SELECT_DRIVE(hwif, drive); {
if (ide_wait_stat(&startstop, drive, drive->ready_stat, ide_startstop_t res;
SELECT_DRIVE(ch, drive);
if (ide_wait_stat(&res, drive, drive->ready_stat,
BUSY_STAT|DRQ_STAT, WAIT_READY)) { BUSY_STAT|DRQ_STAT, WAIT_READY)) {
printk(KERN_WARNING "%s: drive not ready for command\n", drive->name); printk(KERN_WARNING "%s: drive not ready for command\n", drive->name);
return startstop;
return res;
}
} }
/* FIXME: We can see nicely here that all commands should be submitted /* FIXME: We can see nicely here that all commands should be submitted
...@@ -1068,14 +1070,13 @@ static ide_startstop_t start_request(ide_drive_t *drive, struct request *rq) ...@@ -1068,14 +1070,13 @@ static ide_startstop_t start_request(ide_drive_t *drive, struct request *rq)
* go as soon as possible! * go as soon as possible!
*/ */
if (!drive->special.all) { if (drive->special_cmd)
if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK | REQ_DRIVE_TASKFILE)) { return ata_special(drive);
/* This issues a special drive command, usually
* initiated by ioctl() from the external hdparm
* program.
*/
if (rq->flags & REQ_DRIVE_TASKFILE) { /* This issues a special drive command, usually initiated by ioctl()
* from the external hdparm program.
*/
if (rq->flags & REQ_DRIVE_ACB) {
struct ata_taskfile *args = rq->special; struct ata_taskfile *args = rq->special;
if (!(args)) if (!(args))
...@@ -1087,36 +1088,15 @@ static ide_startstop_t start_request(ide_drive_t *drive, struct request *rq) ...@@ -1087,36 +1088,15 @@ static ide_startstop_t start_request(ide_drive_t *drive, struct request *rq)
(args->command_type == IDE_DRIVE_TASK_OUT)) && (args->command_type == IDE_DRIVE_TASK_OUT)) &&
args->prehandler && args->handler) args->prehandler && args->handler)
return args->prehandler(drive, rq); return args->prehandler(drive, rq);
return ide_started; return ide_started;
}
} else if (rq->flags & REQ_DRIVE_TASK) { if (rq->flags & REQ_DRIVE_CMD) {
byte *args = rq->buffer; u8 *args = rq->buffer;
byte sel;
if (!(args)) goto args_error; if (!(args))
#ifdef DEBUG goto args_error;
printk("%s: DRIVE_TASK_CMD ", drive->name);
printk("cmd=0x%02x ", args[0]);
printk("fr=0x%02x ", args[1]);
printk("ns=0x%02x ", args[2]);
printk("sc=0x%02x ", args[3]);
printk("lcyl=0x%02x ", args[4]);
printk("hcyl=0x%02x ", args[5]);
printk("sel=0x%02x\n", args[6]);
#endif
OUT_BYTE(args[1], IDE_FEATURE_REG);
OUT_BYTE(args[3], IDE_SECTOR_REG);
OUT_BYTE(args[4], IDE_LCYL_REG);
OUT_BYTE(args[5], IDE_HCYL_REG);
sel = (args[6] & ~0x10);
if (drive->select.b.unit)
sel |= 0x10;
OUT_BYTE(sel, IDE_SELECT_REG);
ide_cmd(drive, args[0], args[2], &drive_cmd_intr);
return ide_started;
} else if (rq->flags & REQ_DRIVE_CMD) {
byte *args = rq->buffer;
if (!(args)) goto args_error;
#ifdef DEBUG #ifdef DEBUG
printk("%s: DRIVE_CMD ", drive->name); printk("%s: DRIVE_CMD ", drive->name);
printk("cmd=0x%02x ", args[0]); printk("cmd=0x%02x ", args[0]);
...@@ -1135,25 +1115,13 @@ static ide_startstop_t start_request(ide_drive_t *drive, struct request *rq) ...@@ -1135,25 +1115,13 @@ static ide_startstop_t start_request(ide_drive_t *drive, struct request *rq)
} }
OUT_BYTE(args[2],IDE_FEATURE_REG); OUT_BYTE(args[2],IDE_FEATURE_REG);
ide_cmd(drive, args[0], args[1], &drive_cmd_intr); ide_cmd(drive, args[0], args[1], &drive_cmd_intr);
return ide_started;
}
args_error: return ide_started;
/*
* NULL is actually a valid way of waiting for all
* current requests to be flushed from the queue.
*/
#ifdef DEBUG
printk("%s: DRIVE_CMD (null)\n", drive->name);
#endif
ide_end_drive_cmd(drive, GET_STAT(), GET_ERR());
return ide_stopped;
} }
/* The normal way of execution is to pass execute the request /* The normal way of execution is to pass and execute the request
* handler. * handler down to the device type driver.
*/ */
if (ata_ops(drive)) { if (ata_ops(drive)) {
if (ata_ops(drive)->do_request) if (ata_ops(drive)->do_request)
return ata_ops(drive)->do_request(drive, rq, block); return ata_ops(drive)->do_request(drive, rq, block);
...@@ -1162,16 +1130,33 @@ static ide_startstop_t start_request(ide_drive_t *drive, struct request *rq) ...@@ -1162,16 +1130,33 @@ static ide_startstop_t start_request(ide_drive_t *drive, struct request *rq)
return ide_stopped; return ide_stopped;
} }
} }
/*
* Error handling:
*/
printk(KERN_WARNING "%s: device type %d not supported\n", printk(KERN_WARNING "%s: device type %d not supported\n",
drive->name, drive->type); drive->name, drive->type);
goto kill_rq;
}
return ata_special(drive);
kill_rq: kill_rq:
if (ata_ops(drive) && ata_ops(drive)->end_request) if (ata_ops(drive) && ata_ops(drive)->end_request)
ata_ops(drive)->end_request(drive, 0); ata_ops(drive)->end_request(drive, 0);
else else
ide_end_request(drive, 0); ide_end_request(drive, 0);
return ide_stopped;
args_error:
/* NULL as arguemnt is used by ioctls as a way of waiting for all
* current requests to be flushed from the queue.
*/
#ifdef DEBUG
printk("%s: DRIVE_CMD (null)\n", drive->name);
#endif
ide_end_drive_cmd(drive, GET_STAT(), GET_ERR());
return ide_stopped; return ide_stopped;
} }
...@@ -1678,7 +1663,7 @@ ide_drive_t *get_info_ptr(kdev_t i_rdev) ...@@ -1678,7 +1663,7 @@ ide_drive_t *get_info_ptr(kdev_t i_rdev)
/* /*
* This function is intended to be used prior to invoking ide_do_drive_cmd(). * This function is intended to be used prior to invoking ide_do_drive_cmd().
*/ */
void ide_init_drive_cmd (struct request *rq) void ide_init_drive_cmd(struct request *rq)
{ {
memset(rq, 0, sizeof(*rq)); memset(rq, 0, sizeof(*rq));
rq->flags = REQ_DRIVE_CMD; rq->flags = REQ_DRIVE_CMD;
...@@ -1742,6 +1727,7 @@ int ide_do_drive_cmd(ide_drive_t *drive, struct request *rq, ide_action_t action ...@@ -1742,6 +1727,7 @@ int ide_do_drive_cmd(ide_drive_t *drive, struct request *rq, ide_action_t action
wait_for_completion(&wait); /* wait for it to be serviced */ wait_for_completion(&wait); /* wait for it to be serviced */
return rq->errors ? -EIO : 0; /* return -EIO if errors */ return rq->errors ? -EIO : 0; /* return -EIO if errors */
} }
return 0; return 0;
} }
...@@ -2386,18 +2372,21 @@ static int set_using_dma (ide_drive_t *drive, int arg) ...@@ -2386,18 +2372,21 @@ static int set_using_dma (ide_drive_t *drive, int arg)
return 0; return 0;
} }
static int set_pio_mode (ide_drive_t *drive, int arg) static int set_pio_mode(ide_drive_t *drive, int arg)
{ {
struct request rq; struct request rq;
if (!drive->channel->tuneproc) if (!drive->channel->tuneproc)
return -ENOSYS; return -ENOSYS;
if (drive->special.b.set_tune)
if (drive->special_cmd & ATA_SPECIAL_TUNE)
return -EBUSY; return -EBUSY;
ide_init_drive_cmd(&rq); ide_init_drive_cmd(&rq);
drive->tune_req = (byte) arg; drive->tune_req = (u8) arg;
drive->special.b.set_tune = 1; drive->special_cmd |= ATA_SPECIAL_TUNE;
ide_do_drive_cmd(drive, &rq, ide_wait); ide_do_drive_cmd(drive, &rq, ide_wait);
return 0; return 0;
} }
...@@ -2433,8 +2422,7 @@ void ide_delay_50ms (void) ...@@ -2433,8 +2422,7 @@ void ide_delay_50ms (void)
#endif /* CONFIG_BLK_DEV_IDECS */ #endif /* CONFIG_BLK_DEV_IDECS */
} }
static int ide_ioctl (struct inode *inode, struct file *file, static int ide_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
unsigned int cmd, unsigned long arg)
{ {
int err = 0, major, minor; int err = 0, major, minor;
ide_drive_t *drive; ide_drive_t *drive;
...@@ -2468,7 +2456,7 @@ static int ide_ioctl (struct inode *inode, struct file *file, ...@@ -2468,7 +2456,7 @@ static int ide_ioctl (struct inode *inode, struct file *file,
} }
} }
ide_init_drive_cmd (&rq); ide_init_drive_cmd(&rq);
switch (cmd) { switch (cmd) {
case HDIO_GETGEO: case HDIO_GETGEO:
{ {
...@@ -2518,13 +2506,12 @@ static int ide_ioctl (struct inode *inode, struct file *file, ...@@ -2518,13 +2506,12 @@ static int ide_ioctl (struct inode *inode, struct file *file,
return -EACCES; return -EACCES;
return ide_revalidate_disk(inode->i_rdev); return ide_revalidate_disk(inode->i_rdev);
case HDIO_OBSOLETE_IDENTITY:
case HDIO_GET_IDENTITY: case HDIO_GET_IDENTITY:
if (minor(inode->i_rdev) & PARTN_MASK) if (minor(inode->i_rdev) & PARTN_MASK)
return -EINVAL; return -EINVAL;
if (drive->id == NULL) if (drive->id == NULL)
return -ENOMSG; return -ENOMSG;
if (copy_to_user((char *)arg, (char *)drive->id, (cmd == HDIO_GET_IDENTITY) ? sizeof(*drive->id) : 142)) if (copy_to_user((char *)arg, (char *)drive->id, sizeof(*drive->id)))
return -EFAULT; return -EFAULT;
return 0; return 0;
...@@ -2538,11 +2525,6 @@ static int ide_ioctl (struct inode *inode, struct file *file, ...@@ -2538,11 +2525,6 @@ static int ide_ioctl (struct inode *inode, struct file *file,
return -EACCES; return -EACCES;
return ide_cmd_ioctl(drive, arg); return ide_cmd_ioctl(drive, arg);
case HDIO_DRIVE_TASK:
if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
return -EACCES;
return ide_task_ioctl(drive, arg);
case HDIO_SET_NICE: case HDIO_SET_NICE:
if (!capable(CAP_SYS_ADMIN)) return -EACCES; if (!capable(CAP_SYS_ADMIN)) return -EACCES;
if (arg != (arg & ((1 << IDE_NICE_DSC_OVERLAP)))) if (arg != (arg & ((1 << IDE_NICE_DSC_OVERLAP))))
......
...@@ -458,9 +458,9 @@ static ide_startstop_t idescsi_issue_pc (ide_drive_t *drive, idescsi_pc_t *pc) ...@@ -458,9 +458,9 @@ static ide_startstop_t idescsi_issue_pc (ide_drive_t *drive, idescsi_pc_t *pc)
} }
/* /*
* idescsi_do_request is our request handling function. * This is our request handling function.
*/ */
static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *rq, unsigned long block) static ide_startstop_t idescsi_do_request(struct ata_device *drive, struct request *rq, sector_t block)
{ {
#if IDESCSI_DEBUG_LOG #if IDESCSI_DEBUG_LOG
printk (KERN_INFO "rq_status: %d, rq_dev: %u, cmd: %d, errors: %d\n",rq->rq_status,(unsigned int) rq->rq_dev,rq->cmd,rq->errors); printk (KERN_INFO "rq_status: %d, rq_dev: %u, cmd: %d, errors: %d\n",rq->rq_status,(unsigned int) rq->rq_dev,rq->cmd,rq->errors);
...@@ -468,20 +468,20 @@ static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *r ...@@ -468,20 +468,20 @@ static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *r
#endif /* IDESCSI_DEBUG_LOG */ #endif /* IDESCSI_DEBUG_LOG */
if (rq->flags & REQ_SPECIAL) { if (rq->flags & REQ_SPECIAL) {
return idescsi_issue_pc (drive, (idescsi_pc_t *) rq->special); return idescsi_issue_pc(drive, (idescsi_pc_t *) rq->special);
} }
blk_dump_rq_flags(rq, "ide-scsi: unsup command"); blk_dump_rq_flags(rq, "ide-scsi: unsup command");
idescsi_end_request(drive, 0); idescsi_end_request(drive, 0);
return ide_stopped; return ide_stopped;
} }
static int idescsi_open (struct inode *inode, struct file *filp, ide_drive_t *drive) static int idescsi_open(struct inode *inode, struct file *filp, struct ata_device *drive)
{ {
MOD_INC_USE_COUNT; MOD_INC_USE_COUNT;
return 0; return 0;
} }
static void idescsi_ide_release (struct inode *inode, struct file *filp, ide_drive_t *drive) static void idescsi_ide_release(struct inode *inode, struct file *filp, struct ata_device *drive)
{ {
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
} }
...@@ -556,9 +556,7 @@ static struct ata_operations idescsi_driver = { ...@@ -556,9 +556,7 @@ static struct ata_operations idescsi_driver = {
release: idescsi_ide_release, release: idescsi_ide_release,
check_media_change: NULL, check_media_change: NULL,
revalidate: idescsi_revalidate, revalidate: idescsi_revalidate,
pre_reset: NULL,
capacity: NULL, capacity: NULL,
special: NULL,
proc: NULL proc: NULL
}; };
......
...@@ -76,17 +76,16 @@ enum rq_flag_bits { ...@@ -76,17 +76,16 @@ enum rq_flag_bits {
__REQ_STARTED, /* drive already may have started this one */ __REQ_STARTED, /* drive already may have started this one */
__REQ_DONTPREP, /* don't call prep for this one */ __REQ_DONTPREP, /* don't call prep for this one */
/* /*
* for IDE * for ATA/ATAPI devices
*/ */
__REQ_DRIVE_CMD, __REQ_DRIVE_CMD,
__REQ_DRIVE_TASK,
__REQ_DRIVE_ACB, __REQ_DRIVE_ACB,
__REQ_PC, /* packet command (special) */ __REQ_PC, /* packet command (special) */
__REQ_BLOCK_PC, /* queued down pc from block layer */ __REQ_BLOCK_PC, /* queued down pc from block layer */
__REQ_SENSE, /* sense retrival */ __REQ_SENSE, /* sense retrival */
__REQ_SPECIAL, /* driver special command */ __REQ_SPECIAL, /* driver special command (currently reset) */
__REQ_NR_BITS, /* stops here */ __REQ_NR_BITS, /* stops here */
}; };
...@@ -99,15 +98,12 @@ enum rq_flag_bits { ...@@ -99,15 +98,12 @@ enum rq_flag_bits {
#define REQ_STARTED (1 << __REQ_STARTED) #define REQ_STARTED (1 << __REQ_STARTED)
#define REQ_DONTPREP (1 << __REQ_DONTPREP) #define REQ_DONTPREP (1 << __REQ_DONTPREP)
#define REQ_DRIVE_CMD (1 << __REQ_DRIVE_CMD) #define REQ_DRIVE_CMD (1 << __REQ_DRIVE_CMD)
#define REQ_DRIVE_TASK (1 << __REQ_DRIVE_TASK)
#define REQ_DRIVE_ACB (1 << __REQ_DRIVE_ACB) #define REQ_DRIVE_ACB (1 << __REQ_DRIVE_ACB)
#define REQ_PC (1 << __REQ_PC) #define REQ_PC (1 << __REQ_PC)
#define REQ_SENSE (1 << __REQ_SENSE)
#define REQ_BLOCK_PC (1 << __REQ_BLOCK_PC) #define REQ_BLOCK_PC (1 << __REQ_BLOCK_PC)
#define REQ_SENSE (1 << __REQ_SENSE)
#define REQ_SPECIAL (1 << __REQ_SPECIAL) #define REQ_SPECIAL (1 << __REQ_SPECIAL)
#define REQ_DRIVE_TASKFILE REQ_DRIVE_ACB
#include <linux/elevator.h> #include <linux/elevator.h>
typedef int (merge_request_fn) (request_queue_t *, struct request *, typedef int (merge_request_fn) (request_queue_t *, struct request *,
......
...@@ -51,11 +51,9 @@ ...@@ -51,11 +51,9 @@
/* /*
* Command Header sizes for IOCTL commands * Command Header sizes for IOCTL commands
* HDIO_DRIVE_CMD and HDIO_DRIVE_TASK
*/ */
#define HDIO_DRIVE_CMD_HDR_SIZE (4 * sizeof(u8)) #define HDIO_DRIVE_CMD_HDR_SIZE (4 * sizeof(u8))
#define HDIO_DRIVE_TASK_HDR_SIZE (8 * sizeof(u8))
#define HDIO_DRIVE_HOB_HDR_SIZE (8 * sizeof(u8)) #define HDIO_DRIVE_HOB_HDR_SIZE (8 * sizeof(u8))
#define IDE_DRIVE_TASK_INVALID -1 #define IDE_DRIVE_TASK_INVALID -1
...@@ -287,7 +285,6 @@ struct hd_big_geometry { ...@@ -287,7 +285,6 @@ struct hd_big_geometry {
#define HDIO_GET_UNMASKINTR 0x0302 /* get current unmask setting */ #define HDIO_GET_UNMASKINTR 0x0302 /* get current unmask setting */
#define HDIO_GET_MULTCOUNT 0x0304 /* get current IDE blockmode setting */ #define HDIO_GET_MULTCOUNT 0x0304 /* get current IDE blockmode setting */
#define HDIO_GET_QDMA 0x0305 /* get use-qdma flag */ #define HDIO_GET_QDMA 0x0305 /* get use-qdma flag */
#define HDIO_OBSOLETE_IDENTITY 0x0307 /* OBSOLETE, DO NOT USE: returns 142 bytes */
#define HDIO_GET_32BIT 0x0309 /* get current io_32bit setting */ #define HDIO_GET_32BIT 0x0309 /* get current io_32bit setting */
#define HDIO_GET_NOWERR 0x030a /* get ignore-write-error flag */ #define HDIO_GET_NOWERR 0x030a /* get ignore-write-error flag */
#define HDIO_GET_DMA 0x030b /* get use-dma flag */ #define HDIO_GET_DMA 0x030b /* get use-dma flag */
...@@ -298,12 +295,8 @@ struct hd_big_geometry { ...@@ -298,12 +295,8 @@ struct hd_big_geometry {
#define HDIO_GET_ADDRESS 0x0310 /* */ #define HDIO_GET_ADDRESS 0x0310 /* */
#define HDIO_GET_BUSSTATE 0x031a /* get the bus state of the hwif */ #define HDIO_GET_BUSSTATE 0x031a /* get the bus state of the hwif */
#define HDIO_TRISTATE_HWIF 0x031b /* execute a channel tristate */
#define HDIO_DRIVE_TASK 0x031e /* execute task and special drive command */
#define HDIO_DRIVE_CMD 0x031f /* execute a special drive command */ #define HDIO_DRIVE_CMD 0x031f /* execute a special drive command */
#define HDIO_DRIVE_CMD_AEB HDIO_DRIVE_TASK
/* hd/ide ctl's that pass (arg) non-ptr values are numbered 0x032n/0x033n */ /* hd/ide ctl's that pass (arg) non-ptr values are numbered 0x032n/0x033n */
#define HDIO_SET_MULTCOUNT 0x0321 /* change IDE blockmode */ #define HDIO_SET_MULTCOUNT 0x0321 /* change IDE blockmode */
#define HDIO_SET_UNMASKINTR 0x0322 /* permit other irqs during I/O */ #define HDIO_SET_UNMASKINTR 0x0322 /* permit other irqs during I/O */
...@@ -521,11 +514,7 @@ struct hd_driveid { ...@@ -521,11 +514,7 @@ struct hd_driveid {
* 7:0 current value * 7:0 current value
*/ */
unsigned short words95_99[5]; /* reserved words 95-99 */ unsigned short words95_99[5]; /* reserved words 95-99 */
#if 0
unsigned short words100_103[4] ;/* reserved words 100-103 */
#else
unsigned long long lba_capacity_2;/* 48-bit total number of sectors */ unsigned long long lba_capacity_2;/* 48-bit total number of sectors */
#endif
unsigned short words104_125[22];/* reserved words 104-125 */ unsigned short words104_125[22];/* reserved words 104-125 */
unsigned short last_lun; /* (word 126) */ unsigned short last_lun; /* (word 126) */
unsigned short word127; /* (word 127) Feature Set unsigned short word127; /* (word 127) Feature Set
...@@ -573,7 +562,7 @@ struct hd_driveid { ...@@ -573,7 +562,7 @@ struct hd_driveid {
* 15:8 Checksum * 15:8 Checksum
* 7:0 Signature * 7:0 Signature
*/ */
}; } __attribute__((packed));
/* /*
* IDE "nice" flags. These are used on a per drive basis to determine * IDE "nice" flags. These are used on a per drive basis to determine
......
...@@ -34,22 +34,25 @@ ...@@ -34,22 +34,25 @@
#define INITIAL_MULT_COUNT 0 /* off=0; on=2,4,8,16,32, etc.. */ #define INITIAL_MULT_COUNT 0 /* off=0; on=2,4,8,16,32, etc.. */
#ifndef SUPPORT_SLOW_DATA_PORTS /* 1 to support slow data ports */ #ifndef SUPPORT_SLOW_DATA_PORTS /* 1 to support slow data ports */
#define SUPPORT_SLOW_DATA_PORTS 1 /* 0 to reduce kernel size */ # define SUPPORT_SLOW_DATA_PORTS 1 /* 0 to reduce kernel size */
#endif #endif
/* Right now this is only needed by a promise controlled.
*/
#ifndef SUPPORT_VLB_SYNC /* 1 to support weird 32-bit chips */ #ifndef SUPPORT_VLB_SYNC /* 1 to support weird 32-bit chips */
#define SUPPORT_VLB_SYNC 1 /* 0 to reduce kernel size */ # define SUPPORT_VLB_SYNC 1 /* 0 to reduce kernel size */
#endif #endif
#ifndef DISK_RECOVERY_TIME /* off=0; on=access_delay_time */ #ifndef DISK_RECOVERY_TIME /* off=0; on=access_delay_time */
#define DISK_RECOVERY_TIME 0 /* for hardware that needs it */ # define DISK_RECOVERY_TIME 0 /* for hardware that needs it */
#endif #endif
#ifndef OK_TO_RESET_CONTROLLER /* 1 needed for good error recovery */ #ifndef OK_TO_RESET_CONTROLLER /* 1 needed for good error recovery */
#define OK_TO_RESET_CONTROLLER 1 /* 0 for use with AH2372A/B interface */ # define OK_TO_RESET_CONTROLLER 1 /* 0 for use with AH2372A/B interface */
#endif #endif
#ifndef FANCY_STATUS_DUMPS /* 1 for human-readable drive errors */ #ifndef FANCY_STATUS_DUMPS /* 1 for human-readable drive errors */
#define FANCY_STATUS_DUMPS 1 /* 0 to reduce kernel size */ # define FANCY_STATUS_DUMPS 1 /* 0 to reduce kernel size */
#endif #endif
#ifndef DISABLE_IRQ_NOSYNC #ifndef DISABLE_IRQ_NOSYNC
#define DISABLE_IRQ_NOSYNC 0 # define DISABLE_IRQ_NOSYNC 0
#endif #endif
/* /*
...@@ -262,17 +265,6 @@ void ide_setup_ports(hw_regs_t *hw, ...@@ -262,17 +265,6 @@ void ide_setup_ports(hw_regs_t *hw,
#define ATA_SCSI 0x21 #define ATA_SCSI 0x21
#define ATA_NO_LUN 0x7f #define ATA_NO_LUN 0x7f
typedef union {
unsigned all : 8; /* all of the bits together */
struct {
unsigned set_geometry : 1; /* respecify drive geometry */
unsigned recalibrate : 1; /* seek to cyl 0 */
unsigned set_multmode : 1; /* set multmode count */
unsigned set_tune : 1; /* tune interface for drive */
unsigned reserved : 4; /* unused */
} b;
} special_t;
struct ide_settings_s; struct ide_settings_s;
/* structure describing an ATA/ATAPI device */ /* structure describing an ATA/ATAPI device */
typedef typedef
...@@ -300,7 +292,17 @@ struct ata_device { ...@@ -300,7 +292,17 @@ struct ata_device {
unsigned long PADAM_service_time; /* service time of last request */ unsigned long PADAM_service_time; /* service time of last request */
unsigned long PADAM_timeout; /* max time to wait for irq */ unsigned long PADAM_timeout; /* max time to wait for irq */
special_t special; /* special action flags */ /* Flags requesting/indicating one of the following special commands
* executed on the request queue.
*/
#define ATA_SPECIAL_GEOMETRY 0x01
#define ATA_SPECIAL_RECALIBRATE 0x02
#define ATA_SPECIAL_MMODE 0x04
#define ATA_SPECIAL_TUNE 0x08
unsigned char special_cmd;
u8 mult_req; /* requested multiple sector setting */
u8 tune_req; /* requested drive tuning setting */
byte using_dma; /* disk is using dma for read/write */ byte using_dma; /* disk is using dma for read/write */
byte retry_pio; /* retrying dma capable host in pio */ byte retry_pio; /* retrying dma capable host in pio */
byte state; /* retry state */ byte state; /* retry state */
...@@ -327,8 +329,6 @@ struct ata_device { ...@@ -327,8 +329,6 @@ struct ata_device {
byte ctl; /* "normal" value for IDE_CONTROL_REG */ byte ctl; /* "normal" value for IDE_CONTROL_REG */
byte ready_stat; /* min status value for drive ready */ byte ready_stat; /* min status value for drive ready */
byte mult_count; /* current multiple sector setting */ byte mult_count; /* current multiple sector setting */
byte mult_req; /* requested multiple sector setting */
byte tune_req; /* requested drive tuning setting */
byte bad_wstat; /* used for ignoring WRERR_STAT */ byte bad_wstat; /* used for ignoring WRERR_STAT */
byte nowerr; /* used for ignoring WRERR_STAT */ byte nowerr; /* used for ignoring WRERR_STAT */
byte sect0; /* offset of first sector for DM6:DDO */ byte sect0; /* offset of first sector for DM6:DDO */
...@@ -338,8 +338,7 @@ struct ata_device { ...@@ -338,8 +338,7 @@ struct ata_device {
byte bios_sect; /* BIOS/fdisk/LILO sectors per track */ byte bios_sect; /* BIOS/fdisk/LILO sectors per track */
unsigned int bios_cyl; /* BIOS/fdisk/LILO number of cyls */ unsigned int bios_cyl; /* BIOS/fdisk/LILO number of cyls */
unsigned int cyl; /* "real" number of cyls */ unsigned int cyl; /* "real" number of cyls */
unsigned long capacity; /* total number of sectors */ u64 capacity; /* total number of sectors */
unsigned long long capacity48; /* total number of sectors */
unsigned int drive_data; /* for use by tuneproc/selectproc as needed */ unsigned int drive_data; /* for use by tuneproc/selectproc as needed */
wait_queue_head_t wqueue; /* used to wait for drive in open() */ wait_queue_head_t wqueue; /* used to wait for drive in open() */
...@@ -465,16 +464,16 @@ struct ata_channel { ...@@ -465,16 +464,16 @@ struct ata_channel {
unsigned noprobe : 1; /* don't probe for this interface */ unsigned noprobe : 1; /* don't probe for this interface */
unsigned present : 1; /* there is a device on this interface */ unsigned present : 1; /* there is a device on this interface */
unsigned serialized : 1; /* serialized operation between channels */ unsigned serialized : 1; /* serialized operation between channels */
unsigned sharing_irq: 1; /* 1 = sharing irq with another hwif */ unsigned sharing_irq : 1; /* 1 = sharing irq with another hwif */
unsigned reset : 1; /* reset after probe */ unsigned reset : 1; /* reset after probe */
unsigned autodma : 1; /* automatically try to enable DMA at boot */ unsigned autodma : 1; /* automatically try to enable DMA at boot */
unsigned udma_four : 1; /* 1=ATA-66 capable, 0=default */ unsigned udma_four : 1; /* 1=ATA-66 capable, 0=default */
unsigned highmem : 1; /* can do full 32-bit dma */ unsigned highmem : 1; /* can do full 32-bit dma */
byte slow; /* flag: slow data port */
unsigned no_io_32bit : 1; /* disallow enabling 32bit I/O */ unsigned no_io_32bit : 1; /* disallow enabling 32bit I/O */
byte io_32bit; /* 0=16-bit, 1=32-bit, 2/3=32bit+sync */
unsigned no_unmask : 1; /* disallow setting unmask bit */ unsigned no_unmask : 1; /* disallow setting unmask bit */
byte io_32bit; /* 0=16-bit, 1=32-bit, 2/3=32bit+sync */
byte unmask; /* flag: okay to unmask other irqs */ byte unmask; /* flag: okay to unmask other irqs */
byte slow; /* flag: slow data port */
#if (DISK_RECOVERY_TIME > 0) #if (DISK_RECOVERY_TIME > 0)
unsigned long last_time; /* time when previous rq was done */ unsigned long last_time; /* time when previous rq was done */
...@@ -616,20 +615,20 @@ read_proc_t proc_ide_read_geometry; ...@@ -616,20 +615,20 @@ read_proc_t proc_ide_read_geometry;
struct ata_operations { struct ata_operations {
struct module *owner; struct module *owner;
int (*cleanup)(ide_drive_t *); int (*cleanup)(struct ata_device *);
int (*standby)(ide_drive_t *); int (*standby)(struct ata_device *);
ide_startstop_t (*do_request)(ide_drive_t *, struct request *, unsigned long); ide_startstop_t (*do_request)(struct ata_device *, struct request *, sector_t);
int (*end_request)(ide_drive_t *drive, int uptodate); int (*end_request)(struct ata_device *, int);
int (*ioctl)(ide_drive_t *, struct inode *, struct file *, unsigned int, unsigned long); int (*ioctl)(struct ata_device *, struct inode *, struct file *, unsigned int, unsigned long);
int (*open)(struct inode *, struct file *, ide_drive_t *); int (*open)(struct inode *, struct file *, struct ata_device *);
void (*release)(struct inode *, struct file *, ide_drive_t *); void (*release)(struct inode *, struct file *, struct ata_device *);
int (*check_media_change)(ide_drive_t *); int (*check_media_change)(struct ata_device *);
void (*revalidate)(ide_drive_t *); void (*revalidate)(struct ata_device *);
void (*pre_reset)(ide_drive_t *); void (*pre_reset)(struct ata_device *);
unsigned long (*capacity)(ide_drive_t *); sector_t (*capacity)(struct ata_device *);
ide_startstop_t (*special)(ide_drive_t *); ide_startstop_t (*special)(struct ata_device *);
ide_proc_entry_t *proc; ide_proc_entry_t *proc;
}; };
...@@ -646,7 +645,7 @@ do { \ ...@@ -646,7 +645,7 @@ do { \
__MOD_DEC_USE_COUNT((ata)->owner); \ __MOD_DEC_USE_COUNT((ata)->owner); \
} while(0) } while(0)
extern unsigned long ata_capacity(ide_drive_t *drive); extern sector_t ata_capacity(struct ata_device *drive);
/* FIXME: Actually implement and use them as soon as possible! to make the /* FIXME: Actually implement and use them as soon as possible! to make the
* ide_scan_devices() go away! */ * ide_scan_devices() go away! */
...@@ -733,7 +732,6 @@ ide_startstop_t restart_request(ide_drive_t *); ...@@ -733,7 +732,6 @@ ide_startstop_t restart_request(ide_drive_t *);
* This function is intended to be used prior to invoking ide_do_drive_cmd(). * This function is intended to be used prior to invoking ide_do_drive_cmd().
*/ */
extern void ide_init_drive_cmd(struct request *rq); extern void ide_init_drive_cmd(struct request *rq);
extern void init_taskfile_request(struct request *rq);
/* /*
* "action" parameter type for ide_do_drive_cmd() below. * "action" parameter type for ide_do_drive_cmd() below.
...@@ -787,10 +785,8 @@ extern ide_startstop_t task_no_data_intr(ide_drive_t *drive); ...@@ -787,10 +785,8 @@ extern ide_startstop_t task_no_data_intr(ide_drive_t *drive);
/* This is setting up all fields in args, which depend upon the command type. /* This is setting up all fields in args, which depend upon the command type.
*/ */
extern void ide_cmd_type_parser(struct ata_taskfile *args); extern void ide_cmd_type_parser(struct ata_taskfile *args);
extern int ide_raw_taskfile(ide_drive_t *drive, struct ata_taskfile *cmd, byte *buf); extern int ide_raw_taskfile(struct ata_device *drive, struct ata_taskfile *cmd, byte *buf);
extern int ide_cmd_ioctl(struct ata_device *drive, unsigned long arg);
extern int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg);
extern int ide_task_ioctl(ide_drive_t *drive, unsigned long arg);
void ide_delay_50ms(void); void ide_delay_50ms(void);
...@@ -864,13 +860,13 @@ extern int ide_register_subdriver(ide_drive_t *drive, struct ata_operations *dri ...@@ -864,13 +860,13 @@ extern int ide_register_subdriver(ide_drive_t *drive, struct ata_operations *dri
extern int ide_unregister_subdriver(ide_drive_t *drive); extern int ide_unregister_subdriver(ide_drive_t *drive);
#ifdef CONFIG_BLK_DEV_IDEPCI #ifdef CONFIG_BLK_DEV_IDEPCI
#define ON_BOARD 1 # define ON_BOARD 1
#define NEVER_BOARD 0 # define NEVER_BOARD 0
#ifdef CONFIG_BLK_DEV_OFFBOARD # ifdef CONFIG_BLK_DEV_OFFBOARD
# define OFF_BOARD ON_BOARD # define OFF_BOARD ON_BOARD
#else # else
# define OFF_BOARD NEVER_BOARD # define OFF_BOARD NEVER_BOARD
#endif # endif
void __init ide_scan_pcibus(int scan_direction); void __init ide_scan_pcibus(int scan_direction);
#endif #endif
...@@ -892,4 +888,4 @@ extern spinlock_t ide_lock; ...@@ -892,4 +888,4 @@ extern spinlock_t ide_lock;
extern int drive_is_ready(ide_drive_t *drive); extern int drive_is_ready(ide_drive_t *drive);
extern void revalidate_drives(void); extern void revalidate_drives(void);
#endif /* _IDE_H */ #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment