Commit 869cc357 authored by Martin Dalecki's avatar Martin Dalecki Committed by Linus Torvalds

[PATCH] 2.5.7 IDE 23

- Support for additional Promise controller id's (PDC20276).

- Remove code duplication between do_rw_taskfile and do_taskfile.
   This will evolve into a more reasonable ata_command() function
   finally. The ata_taskfile function has far too many arguments, but
   I favour this over having two different code paths for getting
   actual data to the drive.
parent 4c1da7a7
......@@ -106,50 +106,6 @@ static int lba_capacity_is_ok (struct hd_driveid *id)
return 0; /* lba_capacity value may be bad */
}
static ide_startstop_t chs_do_request(ide_drive_t *drive, struct request *rq, unsigned long block);
static ide_startstop_t lba28_do_request(ide_drive_t *drive, struct request *rq, unsigned long block);
static ide_startstop_t lba48_do_request(ide_drive_t *drive, struct request *rq, unsigned long long block);
/*
* Issue a READ or WRITE command to a disk, using LBA if supported, or CHS
* otherwise, to address sectors. It also takes care of issuing special
* DRIVE_CMDs.
*/
static ide_startstop_t idedisk_do_request(ide_drive_t *drive, struct request *rq, unsigned long block)
{
/*
* Wait until all request have bin finished.
*/
while (drive->blocked) {
yield();
// panic("ide: Request while drive blocked?");
}
if (!(rq->flags & REQ_CMD)) {
blk_dump_rq_flags(rq, "idedisk_do_request - bad command");
ide_end_request(drive, 0);
return ide_stopped;
}
if (IS_PDC4030_DRIVE) {
extern ide_startstop_t promise_rw_disk(ide_drive_t *, struct request *, unsigned long);
return promise_rw_disk(drive, rq, block);
}
/* 48-bit LBA */
if ((drive->id->cfs_enable_2 & 0x0400) && (drive->addressing))
return lba48_do_request(drive, rq, block);
/* 28-bit LBA */
if (drive->select.b.lba)
return lba28_do_request(drive, rq, block);
/* 28-bit CHS */
return chs_do_request(drive, rq, block);
}
static task_ioreg_t get_command(ide_drive_t *drive, int cmd)
{
int lba48bit = (drive->id->cfs_enable_2 & 0x0400) ? 1 : 0;
......@@ -158,20 +114,38 @@ static task_ioreg_t get_command(ide_drive_t *drive, int cmd)
lba48bit = drive->addressing;
#endif
if (cmd == READ) {
if (drive->using_dma)
return (lba48bit) ? WIN_READDMA_EXT : WIN_READDMA;
else if (drive->mult_count)
return (lba48bit) ? WIN_MULTREAD_EXT : WIN_MULTREAD;
else
return (lba48bit) ? WIN_READ_EXT : WIN_READ;
} else if (cmd == WRITE) {
if (drive->using_dma)
return (lba48bit) ? WIN_WRITEDMA_EXT : WIN_WRITEDMA;
else if (drive->mult_count)
return (lba48bit) ? WIN_MULTWRITE_EXT : WIN_MULTWRITE;
else
return (lba48bit) ? WIN_WRITE_EXT : WIN_WRITE;
if (lba48bit) {
if (cmd == READ) {
if (drive->using_dma)
return WIN_READDMA_EXT;
else if (drive->mult_count)
return WIN_MULTREAD_EXT;
else
return WIN_READ_EXT;
} else if (cmd == WRITE) {
if (drive->using_dma)
return WIN_WRITEDMA_EXT;
else if (drive->mult_count)
return WIN_MULTWRITE_EXT;
else
return WIN_WRITE_EXT;
}
} else {
if (cmd == READ) {
if (drive->using_dma)
return WIN_READDMA;
else if (drive->mult_count)
return WIN_MULTREAD;
else
return WIN_READ;
} else if (cmd == WRITE) {
if (drive->using_dma)
return WIN_WRITEDMA;
else if (drive->mult_count)
return WIN_MULTWRITE;
else
return WIN_WRITE;
}
}
return WIN_NOP;
}
......@@ -183,8 +157,6 @@ static ide_startstop_t chs_do_request(ide_drive_t *drive, struct request *rq, un
ide_task_t args;
int sectors;
task_ioreg_t command = get_command(drive, rq_data_dir(rq));
unsigned int track = (block / drive->sect);
unsigned int sect = (block % drive->sect) + 1;
unsigned int head = (track % drive->head);
......@@ -203,7 +175,7 @@ static ide_startstop_t chs_do_request(ide_drive_t *drive, struct request *rq, un
taskfile.high_cylinder = (cyl>>8);
taskfile.device_head = head;
taskfile.device_head |= drive->select.all;
taskfile.command = command;
taskfile.command = get_command(drive, rq_data_dir(rq));
#ifdef DEBUG
printk("%s: %sing: ", drive->name,
......@@ -221,7 +193,12 @@ static ide_startstop_t chs_do_request(ide_drive_t *drive, struct request *rq, un
args.block = block;
rq->special = &args;
return do_rw_taskfile(drive, &args);
return ata_taskfile(drive,
(struct hd_drive_task_hdr *) &args.tfRegister,
(struct hd_drive_hob_hdr *) &args.hobRegister,
args.handler,
args.prehandler,
args.rq);
}
static ide_startstop_t lba28_do_request(ide_drive_t *drive, struct request *rq, unsigned long block)
......@@ -231,8 +208,6 @@ static ide_startstop_t lba28_do_request(ide_drive_t *drive, struct request *rq,
ide_task_t args;
int sectors;
task_ioreg_t command = get_command(drive, rq_data_dir(rq));
sectors = rq->nr_sectors;
if (sectors == 256)
sectors = 0;
......@@ -246,7 +221,7 @@ static ide_startstop_t lba28_do_request(ide_drive_t *drive, struct request *rq,
taskfile.high_cylinder = (block>>=8);
taskfile.device_head = ((block>>8)&0x0f);
taskfile.device_head |= drive->select.all;
taskfile.command = command;
taskfile.command = get_command(drive, rq_data_dir(rq));
#ifdef DEBUG
printk("%s: %sing: ", drive->name,
......@@ -264,7 +239,12 @@ static ide_startstop_t lba28_do_request(ide_drive_t *drive, struct request *rq,
args.block = block;
rq->special = &args;
return do_rw_taskfile(drive, &args);
return ata_taskfile(drive,
(struct hd_drive_task_hdr *) &args.tfRegister,
(struct hd_drive_hob_hdr *) &args.hobRegister,
args.handler,
args.prehandler,
args.rq);
}
/*
......@@ -280,8 +260,6 @@ static ide_startstop_t lba48_do_request(ide_drive_t *drive, struct request *rq,
ide_task_t args;
int sectors;
task_ioreg_t command = get_command(drive, rq_data_dir(rq));
memset(&taskfile, 0, sizeof(task_struct_t));
memset(&hobfile, 0, sizeof(hob_struct_t));
......@@ -306,7 +284,7 @@ static ide_startstop_t lba48_do_request(ide_drive_t *drive, struct request *rq,
taskfile.device_head = drive->select.all;
hobfile.device_head = taskfile.device_head;
hobfile.control = (drive->ctl|0x80);
taskfile.command = command;
taskfile.command = get_command(drive, rq_data_dir(rq));
#ifdef DEBUG
printk("%s: %sing: ", drive->name,
......@@ -324,7 +302,52 @@ static ide_startstop_t lba48_do_request(ide_drive_t *drive, struct request *rq,
args.block = block;
rq->special = &args;
return do_rw_taskfile(drive, &args);
return ata_taskfile(drive,
(struct hd_drive_task_hdr *) &args.tfRegister,
(struct hd_drive_hob_hdr *) &args.hobRegister,
args.handler,
args.prehandler,
args.rq);
}
/*
* Issue a READ or WRITE command to a disk, using LBA if supported, or CHS
* otherwise, to address sectors. It also takes care of issuing special
* DRIVE_CMDs.
*/
static ide_startstop_t idedisk_do_request(ide_drive_t *drive, struct request *rq, unsigned long block)
{
/*
* Wait until all request have bin finished.
*/
while (drive->blocked) {
yield();
// panic("ide: Request while drive blocked?");
}
if (!(rq->flags & REQ_CMD)) {
blk_dump_rq_flags(rq, "idedisk_do_request - bad command");
ide_end_request(drive, 0);
return ide_stopped;
}
if (IS_PDC4030_DRIVE) {
extern ide_startstop_t promise_rw_disk(ide_drive_t *, struct request *, unsigned long);
return promise_rw_disk(drive, rq, block);
}
/* 48-bit LBA */
if ((drive->id->cfs_enable_2 & 0x0400) && (drive->addressing))
return lba48_do_request(drive, rq, block);
/* 28-bit LBA */
if (drive->select.b.lba)
return lba28_do_request(drive, rq, block);
/* 28-bit CHS */
return chs_do_request(drive, rq, block);
}
static int idedisk_open (struct inode *inode, struct file *filp, ide_drive_t *drive)
......@@ -333,10 +356,13 @@ static int idedisk_open (struct inode *inode, struct file *filp, ide_drive_t *dr
if (drive->removable && drive->usage == 1) {
struct hd_drive_task_hdr taskfile;
struct hd_drive_hob_hdr hobfile;
memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
check_disk_change(inode->i_rdev);
taskfile.command = WIN_DOORLOCK;
/*
* Ignore the return code from door_lock,
* since the open() has already succeeded,
......@@ -355,11 +381,10 @@ static int idedisk_flushcache(ide_drive_t *drive)
struct hd_drive_hob_hdr hobfile;
memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
if (drive->id->cfs_enable_2 & 0x2400) {
if (drive->id->cfs_enable_2 & 0x2400)
taskfile.command = WIN_FLUSH_CACHE_EXT;
} else {
else
taskfile.command = WIN_FLUSH_CACHE;
}
return ide_wait_taskfile(drive, &taskfile, &hobfile, NULL);
}
......@@ -643,7 +668,7 @@ static ide_startstop_t idedisk_special (ide_drive_t *drive)
taskfile.command = WIN_SPECIFY;
handler = set_geometry_intr;;
}
do_taskfile(drive, &taskfile, &hobfile, handler);
ata_taskfile(drive, &taskfile, &hobfile, handler, NULL, NULL);
} else if (s->b.recalibrate) {
s->b.recalibrate = 0;
if (!IS_PDC4030_DRIVE) {
......@@ -653,7 +678,7 @@ static ide_startstop_t idedisk_special (ide_drive_t *drive)
memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
taskfile.sector_count = drive->sect;
taskfile.command = WIN_RESTORE;
do_taskfile(drive, &taskfile, &hobfile, recal_intr);
ata_taskfile(drive, &taskfile, &hobfile, recal_intr, NULL, NULL);
}
} else if (s->b.set_multmode) {
s->b.set_multmode = 0;
......@@ -666,7 +691,7 @@ static ide_startstop_t idedisk_special (ide_drive_t *drive)
memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
taskfile.sector_count = drive->mult_req;
taskfile.command = WIN_SETMULT;
do_taskfile(drive, &taskfile, &hobfile, &set_multmode_intr);
ata_taskfile(drive, &taskfile, &hobfile, set_multmode_intr, NULL, NULL);
}
} else if (s->all) {
int special = s->all;
......
......@@ -229,6 +229,7 @@ static ide_pci_device_t pci_chipsets[] __initdata = {
{PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20268R, pci_init_pdc202xx, ata66_pdc202xx, ide_init_pdc202xx, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0, ATA_F_IRQ | ATA_F_DMA },
{PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20269, pci_init_pdc202xx, ata66_pdc202xx, ide_init_pdc202xx, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0, ATA_F_IRQ | ATA_F_DMA },
{PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20275, pci_init_pdc202xx, ata66_pdc202xx, ide_init_pdc202xx, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0, ATA_F_IRQ | ATA_F_DMA },
{PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20276, pci_init_pdc202xx, ata66_pdc202xx, ide_init_pdc202xx, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0, ATA_F_IRQ | ATA_F_DMA },
#endif
#ifdef CONFIG_BLK_DEV_RZ1000
{PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1000, NULL, NULL, ide_init_rz1000, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0, 0 },
......
......@@ -48,7 +48,7 @@ static inline char *ide_map_rq(struct request *rq, unsigned long *flags)
if (rq->bio)
return bio_kmap_irq(rq->bio, flags) + ide_rq_offset(rq);
else
return rq->buffer + task_rq_offset(rq);
return rq->buffer + ((rq)->nr_sectors - (rq)->current_nr_sectors) * SECTOR_SIZE;
}
static inline void ide_unmap_rq(struct request *rq, char *to,
......@@ -341,27 +341,37 @@ static ide_startstop_t task_mulout_intr(ide_drive_t *drive)
pBuf = ide_map_rq(rq, &flags);
DTF("Multiwrite: %p, nsect: %d , rq->current_nr_sectors: %ld\n",
pBuf, nsect, rq->current_nr_sectors);
drive->io_32bit = 0;
taskfile_output_data(drive, pBuf, nsect * SECTOR_WORDS);
ide_unmap_rq(rq, pBuf, &flags);
drive->io_32bit = io_32bit;
rq->errors = 0;
/* Are we sure that this as all been already transfered? */
rq->current_nr_sectors -= nsect;
if (hwgroup->handler == NULL)
ide_set_handler(drive, &task_mulout_intr, WAIT_CMD, NULL);
return ide_started;
}
ide_startstop_t do_rw_taskfile(ide_drive_t *drive, ide_task_t *task)
ide_startstop_t ata_taskfile(ide_drive_t *drive,
struct hd_drive_task_hdr *taskfile,
struct hd_drive_hob_hdr *hobfile,
ide_handler_t *handler,
ide_pre_handler_t *prehandler,
struct request *rq
)
{
task_struct_t *taskfile = (task_struct_t *) task->tfRegister;
hob_struct_t *hobfile = (hob_struct_t *) task->hobRegister;
struct hd_driveid *id = drive->id;
byte HIHI = (drive->addressing) ? 0xE0 : 0xEF;
u8 HIHI = (drive->addressing) ? 0xE0 : 0xEF;
/* (ks/hs): Moved to start, do not use for multiple out commands */
if (task->handler != task_mulout_intr && task->handler != bio_mulout_intr) {
if (handler != task_mulout_intr && handler != bio_mulout_intr) {
if (IDE_CONTROL_REG)
OUT_BYTE(drive->ctl, IDE_CONTROL_REG); /* clear nIEN */
SELECT_MASK(HWIF(drive), drive, 0);
......@@ -386,17 +396,16 @@ ide_startstop_t do_rw_taskfile(ide_drive_t *drive, ide_task_t *task)
OUT_BYTE(taskfile->high_cylinder, IDE_HCYL_REG);
OUT_BYTE((taskfile->device_head & HIHI) | drive->select.all, IDE_SELECT_REG);
if (task->handler != NULL) {
ide_set_handler (drive, task->handler, WAIT_CMD, NULL);
if (handler != NULL) {
ide_set_handler(drive, handler, WAIT_CMD, NULL);
OUT_BYTE(taskfile->command, IDE_COMMAND_REG);
/*
* Warning check for race between handler and prehandler for
* writing first block of data. however since we are well
* inside the boundaries of the seek, we should be okay.
*/
if (task->prehandler != NULL) {
return task->prehandler(drive, task->rq);
}
if (prehandler != NULL)
return prehandler(drive, rq);
} else {
/* for dma commands we down set the handler */
if (drive->using_dma && !(HWIF(drive)->dmaproc(((taskfile->command == WIN_WRITEDMA) || (taskfile->command == WIN_WRITEDMA_EXT)) ? ide_dma_write : ide_dma_read, drive)));
......@@ -405,48 +414,6 @@ ide_startstop_t do_rw_taskfile(ide_drive_t *drive, ide_task_t *task)
return ide_started;
}
void do_taskfile(ide_drive_t *drive, struct hd_drive_task_hdr *taskfile,
struct hd_drive_hob_hdr *hobfile,
ide_handler_t *handler)
{
struct hd_driveid *id = drive->id;
byte HIHI = (drive->addressing) ? 0xE0 : 0xEF;
/* (ks/hs): Moved to start, do not use for multiple out commands */
if (*handler != task_mulout_intr && handler != bio_mulout_intr) {
if (IDE_CONTROL_REG)
OUT_BYTE(drive->ctl, IDE_CONTROL_REG); /* clear nIEN */
SELECT_MASK(HWIF(drive), drive, 0);
}
if ((id->command_set_2 & 0x0400) &&
(id->cfs_enable_2 & 0x0400) &&
(drive->addressing == 1)) {
OUT_BYTE(hobfile->feature, IDE_FEATURE_REG);
OUT_BYTE(hobfile->sector_count, IDE_NSECTOR_REG);
OUT_BYTE(hobfile->sector_number, IDE_SECTOR_REG);
OUT_BYTE(hobfile->low_cylinder, IDE_LCYL_REG);
OUT_BYTE(hobfile->high_cylinder, IDE_HCYL_REG);
}
OUT_BYTE(taskfile->feature, IDE_FEATURE_REG);
OUT_BYTE(taskfile->sector_count, IDE_NSECTOR_REG);
/* refers to number of sectors to transfer */
OUT_BYTE(taskfile->sector_number, IDE_SECTOR_REG);
/* refers to sector offset or start sector */
OUT_BYTE(taskfile->low_cylinder, IDE_LCYL_REG);
OUT_BYTE(taskfile->high_cylinder, IDE_HCYL_REG);
OUT_BYTE((taskfile->device_head & HIHI) | drive->select.all, IDE_SELECT_REG);
if (handler != NULL) {
ide_set_handler (drive, handler, WAIT_CMD, NULL);
OUT_BYTE(taskfile->command, IDE_COMMAND_REG);
} else {
/* for dma commands we down set the handler */
if (drive->using_dma && !(HWIF(drive)->dmaproc(((taskfile->command == WIN_WRITEDMA) || (taskfile->command == WIN_WRITEDMA_EXT)) ? ide_dma_write : ide_dma_read, drive)));
}
}
/*
* This is invoked on completion of a WIN_SETMULT cmd.
*/
......@@ -1162,8 +1129,7 @@ EXPORT_SYMBOL(atapi_input_bytes);
EXPORT_SYMBOL(atapi_output_bytes);
EXPORT_SYMBOL(taskfile_input_data);
EXPORT_SYMBOL(taskfile_output_data);
EXPORT_SYMBOL(do_rw_taskfile);
EXPORT_SYMBOL(do_taskfile);
EXPORT_SYMBOL(ata_taskfile);
EXPORT_SYMBOL(recal_intr);
EXPORT_SYMBOL(set_geometry_intr);
......
......@@ -978,7 +978,7 @@ static ide_startstop_t drive_cmd_intr (ide_drive_t *drive)
* setting a timer to wake up at half second intervals thereafter,
* until timeout is achieved, before timing out.
*/
int ide_wait_stat (ide_startstop_t *startstop, ide_drive_t *drive, byte good, byte bad, unsigned long timeout) {
int ide_wait_stat(ide_startstop_t *startstop, ide_drive_t *drive, byte good, byte bad, unsigned long timeout) {
byte stat;
int i;
unsigned long flags;
......@@ -1019,90 +1019,6 @@ int ide_wait_stat (ide_startstop_t *startstop, ide_drive_t *drive, byte good, by
return 1;
}
/*
* execute_drive_cmd() issues a special drive command,
* usually initiated by ioctl() from the external hdparm program.
*/
static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, struct request *rq)
{
if (rq->flags & REQ_DRIVE_TASKFILE) {
ide_task_t *args = rq->special;
if (!(args))
goto args_error;
do_taskfile(drive,
(struct hd_drive_task_hdr *)&args->tfRegister,
(struct hd_drive_hob_hdr *)&args->hobRegister,
args->handler);
if (((args->command_type == IDE_DRIVE_TASK_RAW_WRITE) ||
(args->command_type == IDE_DRIVE_TASK_OUT)) &&
args->prehandler && args->handler)
return args->prehandler(drive, rq);
return ide_started;
} else if (rq->flags & REQ_DRIVE_TASK) {
byte *args = rq->buffer;
byte sel;
if (!(args)) goto args_error;
#ifdef DEBUG
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
printk("%s: DRIVE_CMD ", drive->name);
printk("cmd=0x%02x ", args[0]);
printk("sc=0x%02x ", args[1]);
printk("fr=0x%02x ", args[2]);
printk("xx=0x%02x\n", args[3]);
#endif
if (args[0] == WIN_SMART) {
OUT_BYTE(0x4f, IDE_LCYL_REG);
OUT_BYTE(0xc2, IDE_HCYL_REG);
OUT_BYTE(args[2],IDE_FEATURE_REG);
OUT_BYTE(args[1],IDE_SECTOR_REG);
ide_cmd(drive, args[0], args[3], &drive_cmd_intr);
return ide_started;
}
OUT_BYTE(args[2],IDE_FEATURE_REG);
ide_cmd(drive, args[0], args[1], &drive_cmd_intr);
return ide_started;
}
args_error:
/*
* 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;
}
/*
* start_request() initiates handling of a new I/O request
*/
......@@ -1150,9 +1066,100 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
printk(KERN_WARNING "%s: drive not ready for command\n", drive->name);
return startstop;
}
/* FIXME: We can see nicely here that all commands should be submitted
* through the request queue and that the special field in drive should
* go as soon as possible!
*/
if (!drive->special.all) {
if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK | REQ_DRIVE_TASKFILE))
return execute_drive_cmd(drive, rq);
if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK | REQ_DRIVE_TASKFILE)) {
/* This issues a special drive command, usually
* initiated by ioctl() from the external hdparm
* program.
*/
if (rq->flags & REQ_DRIVE_TASKFILE) {
ide_task_t *args = rq->special;
if (!(args))
goto args_error;
ata_taskfile(drive,
(struct hd_drive_task_hdr *)&args->tfRegister,
(struct hd_drive_hob_hdr *)&args->hobRegister,
args->handler, NULL, NULL);
if (((args->command_type == IDE_DRIVE_TASK_RAW_WRITE) ||
(args->command_type == IDE_DRIVE_TASK_OUT)) &&
args->prehandler && args->handler)
return args->prehandler(drive, rq);
return ide_started;
} else if (rq->flags & REQ_DRIVE_TASK) {
byte *args = rq->buffer;
byte sel;
if (!(args)) goto args_error;
#ifdef DEBUG
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
printk("%s: DRIVE_CMD ", drive->name);
printk("cmd=0x%02x ", args[0]);
printk("sc=0x%02x ", args[1]);
printk("fr=0x%02x ", args[2]);
printk("xx=0x%02x\n", args[3]);
#endif
if (args[0] == WIN_SMART) {
OUT_BYTE(0x4f, IDE_LCYL_REG);
OUT_BYTE(0xc2, IDE_HCYL_REG);
OUT_BYTE(args[2],IDE_FEATURE_REG);
OUT_BYTE(args[1],IDE_SECTOR_REG);
ide_cmd(drive, args[0], args[3], &drive_cmd_intr);
return ide_started;
}
OUT_BYTE(args[2],IDE_FEATURE_REG);
ide_cmd(drive, args[0], args[1], &drive_cmd_intr);
return ide_started;
}
args_error:
/*
* 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
* handler.
*/
if (ata_ops(drive)) {
if (ata_ops(drive)->do_request)
......@@ -1699,31 +1706,29 @@ void ide_init_drive_cmd (struct request *rq)
}
/*
* This function issues a special IDE device request
* onto the request queue.
* This function issues a special IDE device request onto the request queue.
*
* If action is ide_wait, then the rq is queued at the end of the
* request queue, and the function sleeps until it has been processed.
* This is for use when invoked from an ioctl handler.
* If action is ide_wait, then the rq is queued at the end of the request
* queue, and the function sleeps until it has been processed. This is for use
* when invoked from an ioctl handler.
*
* If action is ide_preempt, then the rq is queued at the head of
* the request queue, displacing the currently-being-processed
* request and this function returns immediately without waiting
* for the new rq to be completed. This is VERY DANGEROUS, and is
* intended for careful use by the ATAPI tape/cdrom driver code.
* If action is ide_preempt, then the rq is queued at the head of the request
* queue, displacing the currently-being-processed request and this function
* returns immediately without waiting for the new rq to be completed. This is
* VERY DANGEROUS, and is intended for careful use by the ATAPI tape/cdrom
* driver code.
*
* If action is ide_next, then the rq is queued immediately after
* the currently-being-processed-request (if any), and the function
* returns without waiting for the new rq to be completed. As above,
* This is VERY DANGEROUS, and is intended for careful use by the
* ATAPI tape/cdrom driver code.
* If action is ide_next, then the rq is queued immediately after the
* currently-being-processed-request (if any), and the function returns without
* waiting for the new rq to be completed. As above, This is VERY DANGEROUS,
* and is intended for careful use by the ATAPI tape/cdrom driver code.
*
* If action is ide_end, then the rq is queued at the end of the
* request queue, and the function returns immediately without waiting
* for the new rq to be completed. This is again intended for careful
* use by the ATAPI tape/cdrom driver code.
* If action is ide_end, then the rq is queued at the end of the request queue,
* and the function returns immediately without waiting for the new rq to be
* completed. This is again intended for careful use by the ATAPI tape/cdrom
* driver code.
*/
int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t action)
int ide_do_drive_cmd(ide_drive_t *drive, struct request *rq, ide_action_t action)
{
unsigned long flags;
ide_hwgroup_t *hwgroup = HWGROUP(drive);
......@@ -2403,7 +2408,7 @@ static int set_pio_mode (ide_drive_t *drive, int arg)
ide_init_drive_cmd(&rq);
drive->tune_req = (byte) arg;
drive->special.b.set_tune = 1;
(void) ide_do_drive_cmd (drive, &rq, ide_wait);
ide_do_drive_cmd(drive, &rq, ide_wait);
return 0;
}
......
......@@ -217,6 +217,9 @@ static char * pdc202xx_info_new (char *buf, struct pci_dev *dev)
case PCI_DEVICE_ID_PROMISE_20275:
p += sprintf(p, "\n PDC20275 Chipset.\n");
break;
case PCI_DEVICE_ID_PROMISE_20276:
p += sprintf(p, "\n PDC20276 Chipset.\n");
break;
case PCI_DEVICE_ID_PROMISE_20269:
p += sprintf(p, "\n PDC20269 TX2 Chipset.\n");
break;
......@@ -236,6 +239,7 @@ static int pdc202xx_get_info (char *buffer, char **addr, off_t offset, int count
char *p = buffer;
switch(bmide_dev->device) {
case PCI_DEVICE_ID_PROMISE_20275:
case PCI_DEVICE_ID_PROMISE_20276:
case PCI_DEVICE_ID_PROMISE_20269:
case PCI_DEVICE_ID_PROMISE_20268:
case PCI_DEVICE_ID_PROMISE_20268R:
......@@ -732,6 +736,7 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra)
switch(dev->device) {
case PCI_DEVICE_ID_PROMISE_20275:
case PCI_DEVICE_ID_PROMISE_20276:
case PCI_DEVICE_ID_PROMISE_20269:
udma_133 = (udma_66) ? 1 : 0;
udma_100 = (udma_66) ? 1 : 0;
......@@ -989,6 +994,7 @@ int pdc202xx_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
switch (dev->device) {
case PCI_DEVICE_ID_PROMISE_20275:
case PCI_DEVICE_ID_PROMISE_20276:
case PCI_DEVICE_ID_PROMISE_20269:
case PCI_DEVICE_ID_PROMISE_20268R:
case PCI_DEVICE_ID_PROMISE_20268:
......@@ -1121,6 +1127,7 @@ unsigned int __init pci_init_pdc202xx(struct pci_dev *dev)
switch (dev->device) {
case PCI_DEVICE_ID_PROMISE_20275:
case PCI_DEVICE_ID_PROMISE_20276:
case PCI_DEVICE_ID_PROMISE_20269:
case PCI_DEVICE_ID_PROMISE_20268R:
case PCI_DEVICE_ID_PROMISE_20268:
......@@ -1215,6 +1222,7 @@ unsigned int __init ata66_pdc202xx (ide_hwif_t *hwif)
switch(hwif->pci_dev->device) {
case PCI_DEVICE_ID_PROMISE_20275:
case PCI_DEVICE_ID_PROMISE_20276:
case PCI_DEVICE_ID_PROMISE_20269:
case PCI_DEVICE_ID_PROMISE_20268:
case PCI_DEVICE_ID_PROMISE_20268R:
......@@ -1233,6 +1241,7 @@ void __init ide_init_pdc202xx (ide_hwif_t *hwif)
switch(hwif->pci_dev->device) {
case PCI_DEVICE_ID_PROMISE_20275:
case PCI_DEVICE_ID_PROMISE_20276:
case PCI_DEVICE_ID_PROMISE_20269:
case PCI_DEVICE_ID_PROMISE_20268:
case PCI_DEVICE_ID_PROMISE_20268R:
......
......@@ -1108,12 +1108,14 @@
1059 Teknor Industrial Computers Inc
105a Promise Technology, Inc.
0d30 20265
1275 20275
4d30 20267
4d33 20246
4d38 20262
4d68 20268
6268 20268R
4d69 20269
5275 20276
5300 DC5300
105b Foxconn International, Inc.
105c Wipro Infotech Limited
......
......@@ -771,35 +771,7 @@ typedef enum {
*/
#define ide_rq_offset(rq) (((rq)->hard_cur_sectors - (rq)->current_nr_sectors) << 9)
#define task_rq_offset(rq) \
(((rq)->nr_sectors - (rq)->current_nr_sectors) * SECTOR_SIZE)
/*
* This function issues a special IDE device request
* onto the request queue.
*
* If action is ide_wait, then the rq is queued at the end of the
* request queue, and the function sleeps until it has been processed.
* This is for use when invoked from an ioctl handler.
*
* If action is ide_preempt, then the rq is queued at the head of
* the request queue, displacing the currently-being-processed
* request and this function returns immediately without waiting
* for the new rq to be completed. This is VERY DANGEROUS, and is
* intended for careful use by the ATAPI tape/cdrom driver code.
*
* If action is ide_next, then the rq is queued immediately after
* the currently-being-processed-request (if any), and the function
* returns without waiting for the new rq to be completed. As above,
* This is VERY DANGEROUS, and is intended for careful use by the
* ATAPI tape/cdrom driver code.
*
* If action is ide_end, then the rq is queued at the end of the
* request queue, and the function returns immediately without waiting
* for the new rq to be completed. This is again intended for careful
* use by the ATAPI tape/cdrom driver code.
*/
int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t action);
extern int ide_do_drive_cmd(ide_drive_t *drive, struct request *rq, ide_action_t action);
/*
* Clean up after success/failure of an explicit drive cmd.
......@@ -827,15 +799,12 @@ void atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecoun
void taskfile_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount);
void taskfile_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount);
/*
* taskfile io for disks for now...
*/
ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task);
/*
* Builds request from ide_ioctl
*/
void do_taskfile (ide_drive_t *drive, struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile, ide_handler_t *handler);
extern ide_startstop_t ata_taskfile(ide_drive_t *drive,
struct hd_drive_task_hdr *taskfile,
struct hd_drive_hob_hdr *hobfile,
ide_handler_t *handler,
ide_pre_handler_t *prehandler,
struct request *rq);
/*
* Special Flagged Register Validation Caller
......@@ -871,7 +840,7 @@ extern int system_bus_speed;
* idedisk_input_data() is a wrapper around ide_input_data() which copes
* with byte-swapping the input data if required.
*/
inline void idedisk_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount);
extern void idedisk_input_data(ide_drive_t *drive, void *buffer, unsigned int wcount);
/*
* ide_stall_queue() can be used by a drive to give excess bandwidth back
......
......@@ -608,6 +608,7 @@
#define PCI_DEVICE_ID_PROMISE_20268R 0x6268
#define PCI_DEVICE_ID_PROMISE_20269 0x4d69
#define PCI_DEVICE_ID_PROMISE_20275 0x1275
#define PCI_DEVICE_ID_PROMISE_20276 0x5275
#define PCI_DEVICE_ID_PROMISE_5300 0x5300
#define PCI_VENDOR_ID_N9 0x105d
......
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