Patch attached, note it contains other stuff, the get_command change is
the one to note...
--- /opt/kernel/linux-2.5.3-pre2/drivers/ide/ide-disk.c Mon Jan 21 00:43:13 2002
+++ drivers/ide/ide-disk.c Mon Jan 21 03:37:20 2002
@@ -139,18 +142,33 @@
}
#endif /* CONFIG_BLK_DEV_PDC4030 */
+ /*
+ * get a new command (push ar further down to avoid grabbing lock here
+ */
+ spin_lock_irqsave(drive->queue.queue_lock, flags);
+ ar = ata_ar_get(drive);
+ spin_unlock_irqrestore(drive->queue.queue_lock, flags);
+
+ BUG_ON(!ar);
+ ar->ar_rq = rq;
+
if ((drive->id->cfs_enable_2 & 0x0400) && (drive->addressing)) /* 48-bit LBA */
- return lba_48_rw_disk(drive, rq, (unsigned long long) block);
+ return lba_48_rw_disk(drive, ar, block);
if (drive->select.b.lba) /* 28-bit LBA */
- return lba_28_rw_disk(drive, rq, (unsigned long) block);
+ return lba_28_rw_disk(drive, ar, block);
/* 28-bit CHS : DIE DIE DIE piece of legacy crap!!! */
- return chs_rw_disk(drive, rq, (unsigned long) block);
+ return chs_rw_disk(drive, ar, block);
}
-static task_ioreg_t get_command (ide_drive_t *drive, int cmd)
+static task_ioreg_t get_command (ide_drive_t *drive, struct request *rq)
{
int lba48bit = (drive->id->cfs_enable_2 & 0x0400) ? 1 : 0;
+ int multi_count = drive->mult_count;
+ int cmd = rq_data_dir(rq);
+
+ if (rq->nr_sectors % multi_count)
+ multi_count = 0;
#if 1
lba48bit = drive->addressing;
@@ -172,14 +190,15 @@
return WIN_NOP;
}
-static ide_startstop_t chs_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block)
+static ide_startstop_t chs_rw_disk (ide_drive_t *drive, ata_request_t *ar, sector_t block)
{
struct hd_drive_task_hdr taskfile;
struct hd_drive_hob_hdr hobfile;
- ide_task_t args;
+ ide_task_t *args = &ar->ar_task;
int sectors;
+ struct request *rq = ar->ar_rq;
- task_ioreg_t command = get_command(drive, rq_data_dir(rq));
+ task_ioreg_t command = get_command(drive, rq);
unsigned int track = (block / drive->sect);
unsigned int sect = (block % drive->sect) + 1;
@@ -192,7 +211,7 @@
sectors = rq->nr_sectors;
if (sectors == 256)
sectors = 0;
- if (command == WIN_MULTWRITE_EXT || command == WIN_MULTWRITE) {
+ if (command == WIN_MULTWRITE) {
sectors = drive->mult_count;
if (sectors > rq->current_nr_sectors)
sectors = rq->current_nr_sectors;
@@ -215,33 +234,33 @@
printk("buffer=0x%08lx\n", (unsigned long) rq->buffer);
#endif
- memcpy(args.tfRegister, &taskfile, sizeof(struct hd_drive_task_hdr));
- memcpy(args.hobRegister, &hobfile, sizeof(struct hd_drive_hob_hdr));
- args.command_type = ide_cmd_type_parser(&args);
- args.prehandler = ide_pre_handler_parser(&taskfile, &hobfile);
- args.handler = ide_handler_parser(&taskfile, &hobfile);
- args.posthandler = NULL;
- args.rq = (struct request *) rq;
- args.block = block;
- rq->special = NULL;
- rq->special = (ide_task_t *)&args;
+ memcpy(args->tfRegister, &taskfile, sizeof(struct hd_drive_task_hdr));
+ memcpy(args->hobRegister, &hobfile, sizeof(struct hd_drive_hob_hdr));
+ args->command_type = ide_cmd_type_parser(args);
+ args->prehandler = ide_pre_handler_parser(&taskfile, &hobfile);
+ args->handler = ide_handler_parser(&taskfile, &hobfile);
+ args->posthandler = NULL;
+ args->ar = ar;
+ args->block = block;
+ rq->special = ar;
- return do_rw_taskfile(drive, &args);
+ return do_rw_taskfile(drive, args);
}
-static ide_startstop_t lba_28_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block)
+static ide_startstop_t lba_28_rw_disk (ide_drive_t *drive, ata_request_t *ar, sector_t block)
{
struct hd_drive_task_hdr taskfile;
struct hd_drive_hob_hdr hobfile;
- ide_task_t args;
+ ide_task_t *args = &ar->ar_task;
int sectors;
+ struct request *rq = ar->ar_rq;
- task_ioreg_t command = get_command(drive, rq_data_dir(rq));
+ task_ioreg_t command = get_command(drive, rq);
sectors = rq->nr_sectors;
if (sectors == 256)
sectors = 0;
- if (command == WIN_MULTWRITE_EXT || command == WIN_MULTWRITE) {
+ if (command == WIN_MULTWRITE) {
sectors = drive->mult_count;
if (sectors > rq->current_nr_sectors)
sectors = rq->current_nr_sectors;
@@ -267,18 +286,17 @@
printk("buffer=0x%08lx\n", (unsigned long) rq->buffer);
#endif
- memcpy(args.tfRegister, &taskfile, sizeof(struct hd_drive_task_hdr));
- memcpy(args.hobRegister, &hobfile, sizeof(struct hd_drive_hob_hdr));
- args.command_type = ide_cmd_type_parser(&args);
- args.prehandler = ide_pre_handler_parser(&taskfile, &hobfile);
- args.handler = ide_handler_parser(&taskfile, &hobfile);
- args.posthandler = NULL;
- args.rq = (struct request *) rq;
- args.block = block;
- rq->special = NULL;
- rq->special = (ide_task_t *)&args;
+ memcpy(args->tfRegister, &taskfile, sizeof(struct hd_drive_task_hdr));
+ memcpy(args->hobRegister, &hobfile, sizeof(struct hd_drive_hob_hdr));
+ args->command_type = ide_cmd_type_parser(args);
+ args->prehandler = ide_pre_handler_parser(&taskfile, &hobfile);
+ args->handler = ide_handler_parser(&taskfile, &hobfile);
+ args->posthandler = NULL;
+ args->ar = ar;
+ args->block = block;
+ rq->special = ar;
- return do_rw_taskfile(drive, &args);
+ return do_rw_taskfile(drive, args);
}
/*
@@ -287,22 +305,23 @@
* 1073741822 == 549756 MB or 48bit addressing fake drive
*/
-static ide_startstop_t lba_48_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long long block)
+static ide_startstop_t lba_48_rw_disk (ide_drive_t *drive, ata_request_t *ar, sector_t block)
{
struct hd_drive_task_hdr taskfile;
struct hd_drive_hob_hdr hobfile;
- ide_task_t args;
+ ide_task_t *args = &ar->ar_task;
int sectors;
+ struct request *rq = ar->ar_rq;
- task_ioreg_t command = get_command(drive, rq_data_dir(rq));
+ task_ioreg_t command = get_command(drive, rq);
memset(&taskfile, 0, sizeof(task_struct_t));
memset(&hobfile, 0, sizeof(hob_struct_t));
sectors = rq->nr_sectors;
- if (sectors == 256)
+ if (sectors == 65536)
sectors = 0;
- if (command == WIN_MULTWRITE_EXT || command == WIN_MULTWRITE) {
+ if (command == WIN_MULTWRITE_EXT) {
sectors = drive->mult_count;
if (sectors > rq->current_nr_sectors)
sectors = rq->current_nr_sectors;
@@ -311,11 +330,6 @@
taskfile.sector_count = sectors;
hobfile.sector_count = sectors >> 8;
- if (rq->nr_sectors == 65536) {
- taskfile.sector_count = 0x00;
- hobfile.sector_count = 0x00;
- }
-
taskfile.sector_number = block; /* low lba */
taskfile.low_cylinder = (block>>=8); /* mid lba */
taskfile.high_cylinder = (block>>=8); /* hi lba */
@@ -336,18 +350,17 @@
printk("buffer=0x%08lx\n", (unsigned long) rq->buffer);
#endif
- memcpy(args.tfRegister, &taskfile, sizeof(struct hd_drive_task_hdr));
- memcpy(args.hobRegister, &hobfile, sizeof(struct hd_drive_hob_hdr));
- args.command_type = ide_cmd_type_parser(&args);
- args.prehandler = ide_pre_handler_parser(&taskfile, &hobfile);
- args.handler = ide_handler_parser(&taskfile, &hobfile);
- args.posthandler = NULL;
- args.rq = (struct request *) rq;
- args.block = block;
- rq->special = NULL;
- rq->special = (ide_task_t *)&args;
+ memcpy(args->tfRegister, &taskfile, sizeof(struct hd_drive_task_hdr));
+ memcpy(args->hobRegister, &hobfile, sizeof(struct hd_drive_hob_hdr));
+ args->command_type = ide_cmd_type_parser(args);
+ args->prehandler = ide_pre_handler_parser(&taskfile, &hobfile);
+ args->handler = ide_handler_parser(&taskfile, &hobfile);
+ args->posthandler = NULL;
+ args->ar = ar;
+ args->block = block;
+ rq->special = ar;
- return do_rw_taskfile(drive, &args);
+ return do_rw_taskfile(drive, args);
}
static int idedisk_open (struct inode *inode, struct file *filp, ide_drive_t *drive)
-- Jens Axboe- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/