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) ...@@ -106,50 +106,6 @@ static int lba_capacity_is_ok (struct hd_driveid *id)
return 0; /* lba_capacity value may be bad */ 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) static task_ioreg_t get_command(ide_drive_t *drive, int cmd)
{ {
int lba48bit = (drive->id->cfs_enable_2 & 0x0400) ? 1 : 0; 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) ...@@ -158,20 +114,38 @@ static task_ioreg_t get_command(ide_drive_t *drive, int cmd)
lba48bit = drive->addressing; lba48bit = drive->addressing;
#endif #endif
if (cmd == READ) { if (lba48bit) {
if (drive->using_dma) if (cmd == READ) {
return (lba48bit) ? WIN_READDMA_EXT : WIN_READDMA; if (drive->using_dma)
else if (drive->mult_count) return WIN_READDMA_EXT;
return (lba48bit) ? WIN_MULTREAD_EXT : WIN_MULTREAD; else if (drive->mult_count)
else return WIN_MULTREAD_EXT;
return (lba48bit) ? WIN_READ_EXT : WIN_READ; else
} else if (cmd == WRITE) { return WIN_READ_EXT;
if (drive->using_dma) } else if (cmd == WRITE) {
return (lba48bit) ? WIN_WRITEDMA_EXT : WIN_WRITEDMA; if (drive->using_dma)
else if (drive->mult_count) return WIN_WRITEDMA_EXT;
return (lba48bit) ? WIN_MULTWRITE_EXT : WIN_MULTWRITE; else if (drive->mult_count)
else return WIN_MULTWRITE_EXT;
return (lba48bit) ? WIN_WRITE_EXT : WIN_WRITE; 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; return WIN_NOP;
} }
...@@ -183,8 +157,6 @@ static ide_startstop_t chs_do_request(ide_drive_t *drive, struct request *rq, un ...@@ -183,8 +157,6 @@ static ide_startstop_t chs_do_request(ide_drive_t *drive, struct request *rq, un
ide_task_t args; ide_task_t args;
int sectors; int sectors;
task_ioreg_t command = get_command(drive, rq_data_dir(rq));
unsigned int track = (block / drive->sect); unsigned int track = (block / drive->sect);
unsigned int sect = (block % drive->sect) + 1; unsigned int sect = (block % drive->sect) + 1;
unsigned int head = (track % drive->head); 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 ...@@ -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.high_cylinder = (cyl>>8);
taskfile.device_head = head; taskfile.device_head = head;
taskfile.device_head |= drive->select.all; taskfile.device_head |= drive->select.all;
taskfile.command = command; taskfile.command = get_command(drive, rq_data_dir(rq));
#ifdef DEBUG #ifdef DEBUG
printk("%s: %sing: ", drive->name, printk("%s: %sing: ", drive->name,
...@@ -221,7 +193,12 @@ static ide_startstop_t chs_do_request(ide_drive_t *drive, struct request *rq, un ...@@ -221,7 +193,12 @@ static ide_startstop_t chs_do_request(ide_drive_t *drive, struct request *rq, un
args.block = block; args.block = block;
rq->special = &args; 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) 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, ...@@ -231,8 +208,6 @@ static ide_startstop_t lba28_do_request(ide_drive_t *drive, struct request *rq,
ide_task_t args; ide_task_t args;
int sectors; int sectors;
task_ioreg_t command = get_command(drive, rq_data_dir(rq));
sectors = rq->nr_sectors; sectors = rq->nr_sectors;
if (sectors == 256) if (sectors == 256)
sectors = 0; sectors = 0;
...@@ -246,7 +221,7 @@ static ide_startstop_t lba28_do_request(ide_drive_t *drive, struct request *rq, ...@@ -246,7 +221,7 @@ static ide_startstop_t lba28_do_request(ide_drive_t *drive, struct request *rq,
taskfile.high_cylinder = (block>>=8); taskfile.high_cylinder = (block>>=8);
taskfile.device_head = ((block>>8)&0x0f); taskfile.device_head = ((block>>8)&0x0f);
taskfile.device_head |= drive->select.all; taskfile.device_head |= drive->select.all;
taskfile.command = command; taskfile.command = get_command(drive, rq_data_dir(rq));
#ifdef DEBUG #ifdef DEBUG
printk("%s: %sing: ", drive->name, printk("%s: %sing: ", drive->name,
...@@ -264,7 +239,12 @@ static ide_startstop_t lba28_do_request(ide_drive_t *drive, struct request *rq, ...@@ -264,7 +239,12 @@ static ide_startstop_t lba28_do_request(ide_drive_t *drive, struct request *rq,
args.block = block; args.block = block;
rq->special = &args; 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, ...@@ -280,8 +260,6 @@ static ide_startstop_t lba48_do_request(ide_drive_t *drive, struct request *rq,
ide_task_t args; ide_task_t args;
int sectors; int sectors;
task_ioreg_t command = get_command(drive, rq_data_dir(rq));
memset(&taskfile, 0, sizeof(task_struct_t)); memset(&taskfile, 0, sizeof(task_struct_t));
memset(&hobfile, 0, sizeof(hob_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, ...@@ -306,7 +284,7 @@ static ide_startstop_t lba48_do_request(ide_drive_t *drive, struct request *rq,
taskfile.device_head = drive->select.all; taskfile.device_head = drive->select.all;
hobfile.device_head = taskfile.device_head; hobfile.device_head = taskfile.device_head;
hobfile.control = (drive->ctl|0x80); hobfile.control = (drive->ctl|0x80);
taskfile.command = command; taskfile.command = get_command(drive, rq_data_dir(rq));
#ifdef DEBUG #ifdef DEBUG
printk("%s: %sing: ", drive->name, printk("%s: %sing: ", drive->name,
...@@ -324,7 +302,52 @@ static ide_startstop_t lba48_do_request(ide_drive_t *drive, struct request *rq, ...@@ -324,7 +302,52 @@ static ide_startstop_t lba48_do_request(ide_drive_t *drive, struct request *rq,
args.block = block; args.block = block;
rq->special = &args; 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) 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 ...@@ -333,10 +356,13 @@ static int idedisk_open (struct inode *inode, struct file *filp, ide_drive_t *dr
if (drive->removable && drive->usage == 1) { if (drive->removable && drive->usage == 1) {
struct hd_drive_task_hdr taskfile; struct hd_drive_task_hdr taskfile;
struct hd_drive_hob_hdr hobfile; struct hd_drive_hob_hdr hobfile;
memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr)); memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr)); memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
check_disk_change(inode->i_rdev); check_disk_change(inode->i_rdev);
taskfile.command = WIN_DOORLOCK; taskfile.command = WIN_DOORLOCK;
/* /*
* Ignore the return code from door_lock, * Ignore the return code from door_lock,
* since the open() has already succeeded, * since the open() has already succeeded,
...@@ -355,11 +381,10 @@ static int idedisk_flushcache(ide_drive_t *drive) ...@@ -355,11 +381,10 @@ static int idedisk_flushcache(ide_drive_t *drive)
struct hd_drive_hob_hdr hobfile; struct hd_drive_hob_hdr hobfile;
memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr)); memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
memset(&hobfile, 0, sizeof(struct hd_drive_hob_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; taskfile.command = WIN_FLUSH_CACHE_EXT;
} else { else
taskfile.command = WIN_FLUSH_CACHE; taskfile.command = WIN_FLUSH_CACHE;
}
return ide_wait_taskfile(drive, &taskfile, &hobfile, NULL); return ide_wait_taskfile(drive, &taskfile, &hobfile, NULL);
} }
...@@ -643,7 +668,7 @@ static ide_startstop_t idedisk_special (ide_drive_t *drive) ...@@ -643,7 +668,7 @@ static ide_startstop_t idedisk_special (ide_drive_t *drive)
taskfile.command = WIN_SPECIFY; taskfile.command = WIN_SPECIFY;
handler = set_geometry_intr;; handler = set_geometry_intr;;
} }
do_taskfile(drive, &taskfile, &hobfile, handler); ata_taskfile(drive, &taskfile, &hobfile, handler, NULL, NULL);
} else if (s->b.recalibrate) { } else if (s->b.recalibrate) {
s->b.recalibrate = 0; s->b.recalibrate = 0;
if (!IS_PDC4030_DRIVE) { if (!IS_PDC4030_DRIVE) {
...@@ -653,7 +678,7 @@ static ide_startstop_t idedisk_special (ide_drive_t *drive) ...@@ -653,7 +678,7 @@ static ide_startstop_t idedisk_special (ide_drive_t *drive)
memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr)); memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
taskfile.sector_count = drive->sect; taskfile.sector_count = drive->sect;
taskfile.command = WIN_RESTORE; 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) { } else if (s->b.set_multmode) {
s->b.set_multmode = 0; s->b.set_multmode = 0;
...@@ -666,7 +691,7 @@ static ide_startstop_t idedisk_special (ide_drive_t *drive) ...@@ -666,7 +691,7 @@ static ide_startstop_t idedisk_special (ide_drive_t *drive)
memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr)); memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
taskfile.sector_count = drive->mult_req; taskfile.sector_count = drive->mult_req;
taskfile.command = WIN_SETMULT; 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) { } else if (s->all) {
int special = s->all; int special = s->all;
......
...@@ -229,6 +229,7 @@ static ide_pci_device_t pci_chipsets[] __initdata = { ...@@ -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_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_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_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 #endif
#ifdef CONFIG_BLK_DEV_RZ1000 #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 }, {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) ...@@ -48,7 +48,7 @@ static inline char *ide_map_rq(struct request *rq, unsigned long *flags)
if (rq->bio) if (rq->bio)
return bio_kmap_irq(rq->bio, flags) + ide_rq_offset(rq); return bio_kmap_irq(rq->bio, flags) + ide_rq_offset(rq);
else 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, 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) ...@@ -341,27 +341,37 @@ static ide_startstop_t task_mulout_intr(ide_drive_t *drive)
pBuf = ide_map_rq(rq, &flags); pBuf = ide_map_rq(rq, &flags);
DTF("Multiwrite: %p, nsect: %d , rq->current_nr_sectors: %ld\n", DTF("Multiwrite: %p, nsect: %d , rq->current_nr_sectors: %ld\n",
pBuf, nsect, rq->current_nr_sectors); pBuf, nsect, rq->current_nr_sectors);
drive->io_32bit = 0; drive->io_32bit = 0;
taskfile_output_data(drive, pBuf, nsect * SECTOR_WORDS); taskfile_output_data(drive, pBuf, nsect * SECTOR_WORDS);
ide_unmap_rq(rq, pBuf, &flags); ide_unmap_rq(rq, pBuf, &flags);
drive->io_32bit = io_32bit; drive->io_32bit = io_32bit;
rq->errors = 0; rq->errors = 0;
/* Are we sure that this as all been already transfered? */ /* Are we sure that this as all been already transfered? */
rq->current_nr_sectors -= nsect; rq->current_nr_sectors -= nsect;
if (hwgroup->handler == NULL) if (hwgroup->handler == NULL)
ide_set_handler(drive, &task_mulout_intr, WAIT_CMD, NULL); ide_set_handler(drive, &task_mulout_intr, WAIT_CMD, NULL);
return ide_started; 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; 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 */ /* (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) if (IDE_CONTROL_REG)
OUT_BYTE(drive->ctl, IDE_CONTROL_REG); /* clear nIEN */ OUT_BYTE(drive->ctl, IDE_CONTROL_REG); /* clear nIEN */
SELECT_MASK(HWIF(drive), drive, 0); SELECT_MASK(HWIF(drive), drive, 0);
...@@ -386,17 +396,16 @@ ide_startstop_t do_rw_taskfile(ide_drive_t *drive, ide_task_t *task) ...@@ -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->high_cylinder, IDE_HCYL_REG);
OUT_BYTE((taskfile->device_head & HIHI) | drive->select.all, IDE_SELECT_REG); OUT_BYTE((taskfile->device_head & HIHI) | drive->select.all, IDE_SELECT_REG);
if (task->handler != NULL) { if (handler != NULL) {
ide_set_handler (drive, task->handler, WAIT_CMD, NULL); ide_set_handler(drive, handler, WAIT_CMD, NULL);
OUT_BYTE(taskfile->command, IDE_COMMAND_REG); OUT_BYTE(taskfile->command, IDE_COMMAND_REG);
/* /*
* Warning check for race between handler and prehandler for * Warning check for race between handler and prehandler for
* writing first block of data. however since we are well * writing first block of data. however since we are well
* inside the boundaries of the seek, we should be okay. * inside the boundaries of the seek, we should be okay.
*/ */
if (task->prehandler != NULL) { if (prehandler != NULL)
return task->prehandler(drive, task->rq); return prehandler(drive, rq);
}
} else { } else {
/* for dma commands we down set the handler */ /* 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))); 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) ...@@ -405,48 +414,6 @@ ide_startstop_t do_rw_taskfile(ide_drive_t *drive, ide_task_t *task)
return ide_started; 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. * This is invoked on completion of a WIN_SETMULT cmd.
*/ */
...@@ -1162,8 +1129,7 @@ EXPORT_SYMBOL(atapi_input_bytes); ...@@ -1162,8 +1129,7 @@ EXPORT_SYMBOL(atapi_input_bytes);
EXPORT_SYMBOL(atapi_output_bytes); EXPORT_SYMBOL(atapi_output_bytes);
EXPORT_SYMBOL(taskfile_input_data); EXPORT_SYMBOL(taskfile_input_data);
EXPORT_SYMBOL(taskfile_output_data); EXPORT_SYMBOL(taskfile_output_data);
EXPORT_SYMBOL(do_rw_taskfile); EXPORT_SYMBOL(ata_taskfile);
EXPORT_SYMBOL(do_taskfile);
EXPORT_SYMBOL(recal_intr); EXPORT_SYMBOL(recal_intr);
EXPORT_SYMBOL(set_geometry_intr); EXPORT_SYMBOL(set_geometry_intr);
......
...@@ -978,7 +978,7 @@ static ide_startstop_t drive_cmd_intr (ide_drive_t *drive) ...@@ -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, * setting a timer to wake up at half second intervals thereafter,
* until timeout is achieved, before timing out. * 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; byte stat;
int i; int i;
unsigned long flags; unsigned long flags;
...@@ -1019,90 +1019,6 @@ int ide_wait_stat (ide_startstop_t *startstop, ide_drive_t *drive, byte good, by ...@@ -1019,90 +1019,6 @@ int ide_wait_stat (ide_startstop_t *startstop, ide_drive_t *drive, byte good, by
return 1; 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 * 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) ...@@ -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); printk(KERN_WARNING "%s: drive not ready for command\n", drive->name);
return startstop; 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 (!drive->special.all) {
if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK | REQ_DRIVE_TASKFILE)) if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK | REQ_DRIVE_TASKFILE)) {
return execute_drive_cmd(drive, rq); /* 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)) {
if (ata_ops(drive)->do_request) if (ata_ops(drive)->do_request)
...@@ -1699,31 +1706,29 @@ void ide_init_drive_cmd (struct request *rq) ...@@ -1699,31 +1706,29 @@ void ide_init_drive_cmd (struct request *rq)
} }
/* /*
* This function issues a special IDE device request * This function issues a special IDE device request onto the request queue.
* onto the request queue.
* *
* If action is ide_wait, then the rq is queued at the end of the * If action is ide_wait, then the rq is queued at the end of the request
* request queue, and the function sleeps until it has been processed. * queue, and the function sleeps until it has been processed. This is for use
* This is for use when invoked from an ioctl handler. * when invoked from an ioctl handler.
* *
* If action is ide_preempt, then the rq is queued at the head of * If action is ide_preempt, then the rq is queued at the head of the request
* the request queue, displacing the currently-being-processed * queue, displacing the currently-being-processed request and this function
* request and this function returns immediately without waiting * returns immediately without waiting for the new rq to be completed. This is
* for the new rq to be completed. This is VERY DANGEROUS, and is * VERY DANGEROUS, and is intended for careful use by the ATAPI tape/cdrom
* intended for careful use by the ATAPI tape/cdrom driver code. * driver code.
* *
* If action is ide_next, then the rq is queued immediately after * If action is ide_next, then the rq is queued immediately after the
* the currently-being-processed-request (if any), and the function * currently-being-processed-request (if any), and the function returns without
* returns without waiting for the new rq to be completed. As above, * waiting for the new rq to be completed. As above, This is VERY DANGEROUS,
* This is VERY DANGEROUS, and is intended for careful use by the * and is intended for careful use by the ATAPI tape/cdrom driver code.
* ATAPI tape/cdrom driver code.
* *
* If action is ide_end, then the rq is queued at the end of the * If action is ide_end, then the rq is queued at the end of the request queue,
* request queue, and the function returns immediately without waiting * and the function returns immediately without waiting for the new rq to be
* for the new rq to be completed. This is again intended for careful * completed. This is again intended for careful use by the ATAPI tape/cdrom
* use by the ATAPI tape/cdrom driver code. * 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; unsigned long flags;
ide_hwgroup_t *hwgroup = HWGROUP(drive); ide_hwgroup_t *hwgroup = HWGROUP(drive);
...@@ -2403,7 +2408,7 @@ static int set_pio_mode (ide_drive_t *drive, int arg) ...@@ -2403,7 +2408,7 @@ static int set_pio_mode (ide_drive_t *drive, int arg)
ide_init_drive_cmd(&rq); ide_init_drive_cmd(&rq);
drive->tune_req = (byte) arg; drive->tune_req = (byte) arg;
drive->special.b.set_tune = 1; 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; return 0;
} }
......
...@@ -217,6 +217,9 @@ static char * pdc202xx_info_new (char *buf, struct pci_dev *dev) ...@@ -217,6 +217,9 @@ static char * pdc202xx_info_new (char *buf, struct pci_dev *dev)
case PCI_DEVICE_ID_PROMISE_20275: case PCI_DEVICE_ID_PROMISE_20275:
p += sprintf(p, "\n PDC20275 Chipset.\n"); p += sprintf(p, "\n PDC20275 Chipset.\n");
break; break;
case PCI_DEVICE_ID_PROMISE_20276:
p += sprintf(p, "\n PDC20276 Chipset.\n");
break;
case PCI_DEVICE_ID_PROMISE_20269: case PCI_DEVICE_ID_PROMISE_20269:
p += sprintf(p, "\n PDC20269 TX2 Chipset.\n"); p += sprintf(p, "\n PDC20269 TX2 Chipset.\n");
break; break;
...@@ -236,6 +239,7 @@ static int pdc202xx_get_info (char *buffer, char **addr, off_t offset, int count ...@@ -236,6 +239,7 @@ static int pdc202xx_get_info (char *buffer, char **addr, off_t offset, int count
char *p = buffer; char *p = buffer;
switch(bmide_dev->device) { switch(bmide_dev->device) {
case PCI_DEVICE_ID_PROMISE_20275: case PCI_DEVICE_ID_PROMISE_20275:
case PCI_DEVICE_ID_PROMISE_20276:
case PCI_DEVICE_ID_PROMISE_20269: case PCI_DEVICE_ID_PROMISE_20269:
case PCI_DEVICE_ID_PROMISE_20268: case PCI_DEVICE_ID_PROMISE_20268:
case PCI_DEVICE_ID_PROMISE_20268R: case PCI_DEVICE_ID_PROMISE_20268R:
...@@ -732,6 +736,7 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra) ...@@ -732,6 +736,7 @@ static int config_chipset_for_dma (ide_drive_t *drive, byte ultra)
switch(dev->device) { switch(dev->device) {
case PCI_DEVICE_ID_PROMISE_20275: case PCI_DEVICE_ID_PROMISE_20275:
case PCI_DEVICE_ID_PROMISE_20276:
case PCI_DEVICE_ID_PROMISE_20269: case PCI_DEVICE_ID_PROMISE_20269:
udma_133 = (udma_66) ? 1 : 0; udma_133 = (udma_66) ? 1 : 0;
udma_100 = (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) ...@@ -989,6 +994,7 @@ int pdc202xx_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
switch (dev->device) { switch (dev->device) {
case PCI_DEVICE_ID_PROMISE_20275: case PCI_DEVICE_ID_PROMISE_20275:
case PCI_DEVICE_ID_PROMISE_20276:
case PCI_DEVICE_ID_PROMISE_20269: case PCI_DEVICE_ID_PROMISE_20269:
case PCI_DEVICE_ID_PROMISE_20268R: case PCI_DEVICE_ID_PROMISE_20268R:
case PCI_DEVICE_ID_PROMISE_20268: case PCI_DEVICE_ID_PROMISE_20268:
...@@ -1121,6 +1127,7 @@ unsigned int __init pci_init_pdc202xx(struct pci_dev *dev) ...@@ -1121,6 +1127,7 @@ unsigned int __init pci_init_pdc202xx(struct pci_dev *dev)
switch (dev->device) { switch (dev->device) {
case PCI_DEVICE_ID_PROMISE_20275: case PCI_DEVICE_ID_PROMISE_20275:
case PCI_DEVICE_ID_PROMISE_20276:
case PCI_DEVICE_ID_PROMISE_20269: case PCI_DEVICE_ID_PROMISE_20269:
case PCI_DEVICE_ID_PROMISE_20268R: case PCI_DEVICE_ID_PROMISE_20268R:
case PCI_DEVICE_ID_PROMISE_20268: case PCI_DEVICE_ID_PROMISE_20268:
...@@ -1215,6 +1222,7 @@ unsigned int __init ata66_pdc202xx (ide_hwif_t *hwif) ...@@ -1215,6 +1222,7 @@ unsigned int __init ata66_pdc202xx (ide_hwif_t *hwif)
switch(hwif->pci_dev->device) { switch(hwif->pci_dev->device) {
case PCI_DEVICE_ID_PROMISE_20275: case PCI_DEVICE_ID_PROMISE_20275:
case PCI_DEVICE_ID_PROMISE_20276:
case PCI_DEVICE_ID_PROMISE_20269: case PCI_DEVICE_ID_PROMISE_20269:
case PCI_DEVICE_ID_PROMISE_20268: case PCI_DEVICE_ID_PROMISE_20268:
case PCI_DEVICE_ID_PROMISE_20268R: case PCI_DEVICE_ID_PROMISE_20268R:
...@@ -1233,6 +1241,7 @@ void __init ide_init_pdc202xx (ide_hwif_t *hwif) ...@@ -1233,6 +1241,7 @@ void __init ide_init_pdc202xx (ide_hwif_t *hwif)
switch(hwif->pci_dev->device) { switch(hwif->pci_dev->device) {
case PCI_DEVICE_ID_PROMISE_20275: case PCI_DEVICE_ID_PROMISE_20275:
case PCI_DEVICE_ID_PROMISE_20276:
case PCI_DEVICE_ID_PROMISE_20269: case PCI_DEVICE_ID_PROMISE_20269:
case PCI_DEVICE_ID_PROMISE_20268: case PCI_DEVICE_ID_PROMISE_20268:
case PCI_DEVICE_ID_PROMISE_20268R: case PCI_DEVICE_ID_PROMISE_20268R:
......
...@@ -1108,12 +1108,14 @@ ...@@ -1108,12 +1108,14 @@
1059 Teknor Industrial Computers Inc 1059 Teknor Industrial Computers Inc
105a Promise Technology, Inc. 105a Promise Technology, Inc.
0d30 20265 0d30 20265
1275 20275
4d30 20267 4d30 20267
4d33 20246 4d33 20246
4d38 20262 4d38 20262
4d68 20268 4d68 20268
6268 20268R 6268 20268R
4d69 20269 4d69 20269
5275 20276
5300 DC5300 5300 DC5300
105b Foxconn International, Inc. 105b Foxconn International, Inc.
105c Wipro Infotech Limited 105c Wipro Infotech Limited
......
...@@ -771,35 +771,7 @@ typedef enum { ...@@ -771,35 +771,7 @@ typedef enum {
*/ */
#define ide_rq_offset(rq) (((rq)->hard_cur_sectors - (rq)->current_nr_sectors) << 9) #define ide_rq_offset(rq) (((rq)->hard_cur_sectors - (rq)->current_nr_sectors) << 9)
#define task_rq_offset(rq) \ extern int ide_do_drive_cmd(ide_drive_t *drive, struct request *rq, ide_action_t action);
(((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);
/* /*
* Clean up after success/failure of an explicit drive cmd. * 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 ...@@ -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_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount);
void taskfile_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount); void taskfile_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount);
/* extern ide_startstop_t ata_taskfile(ide_drive_t *drive,
* taskfile io for disks for now... struct hd_drive_task_hdr *taskfile,
*/ struct hd_drive_hob_hdr *hobfile,
ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task); ide_handler_t *handler,
ide_pre_handler_t *prehandler,
/* struct request *rq);
* 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);
/* /*
* Special Flagged Register Validation Caller * Special Flagged Register Validation Caller
...@@ -871,7 +840,7 @@ extern int system_bus_speed; ...@@ -871,7 +840,7 @@ extern int system_bus_speed;
* idedisk_input_data() is a wrapper around ide_input_data() which copes * idedisk_input_data() is a wrapper around ide_input_data() which copes
* with byte-swapping the input data if required. * 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 * ide_stall_queue() can be used by a drive to give excess bandwidth back
......
...@@ -608,6 +608,7 @@ ...@@ -608,6 +608,7 @@
#define PCI_DEVICE_ID_PROMISE_20268R 0x6268 #define PCI_DEVICE_ID_PROMISE_20268R 0x6268
#define PCI_DEVICE_ID_PROMISE_20269 0x4d69 #define PCI_DEVICE_ID_PROMISE_20269 0x4d69
#define PCI_DEVICE_ID_PROMISE_20275 0x1275 #define PCI_DEVICE_ID_PROMISE_20275 0x1275
#define PCI_DEVICE_ID_PROMISE_20276 0x5275
#define PCI_DEVICE_ID_PROMISE_5300 0x5300 #define PCI_DEVICE_ID_PROMISE_5300 0x5300
#define PCI_VENDOR_ID_N9 0x105d #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