Commit e9356da8 authored by Martin Dalecki's avatar Martin Dalecki Committed by Trond Myklebust

[PATCH] 2.5.26 IDE 99

Most noticable in the patch:

1. we handle IRQ sharing now better then ever

2. survives quite a lot of testing by few people. Forexample
cat /dev/hdb > /dev/null, where /dev/hdb contains a CD-ROM
with a big cratch on the surface making sure it's broken :-).
it's BTW. amanzing how wide the cratch had to be until errors
ocurred.

3. Doesn't play with rq_rdev and friends

Fri Jul 12 05:04:32 CEST 2002 ide-clean-99

- Push nIEN disabling down at the place where we are finished with a particular
   request.

- First round of command line parser cleanups by Gerald Champagne.

- Unfold the drive eviction functions in do_request(). This allowed us to
   realize that we don't have to re-get the major/minor numbers of the device we
   are action on from the raw device field of the currently running request. One
   significant place less in kernel where major/minor data gets manipulated.

- Move the big IDE_BUSY loop out of do_request to do_ide_request().  This makes
   us realize that we don't have to clear the IDE_BUSY bit just before
   reentering do_request to look for more requests still pending on the queue
   and set it immediately again.

   This is fixing a tinny race on the code path from IRQ or timer function,
   where we had a tinny window between the clearing of the IDE_BUSY bit and
   reentering the request queue for completely unrelated requests to come in to
   our way.

- Don't return any value in do_reset1(). It's always ATA_OP_CONTINUES. Split it
   up in to two functions one for disks (well in fact channels) and one for
   ATAPI devices. It turns out that they can be moved to the places where they
   are used to clarify the code flow. The only function remaining is
   do_reset_channel() now.

- Duplicate code from ide_do_drive_code explicitely in ide_raw_taskfile().
   Simplify ide_raw_taskfile() thereafter. Realize that ide_do_drive_cmd()
   is now only used by ATAPI devices. Move it therefore to atapi.c.

- Do busy polling for ATAPI reset operations. This is much safer then the
   previous timer games played there. It simply doesn't make sense to give the
   bus up during such a subtile operation. We don't have to disable IRQs here as
   well, since we are already under the protection of the do_request mechanisms.
   (Well hopefully...)

- Remove no longer used reset_poll() function. poll_timeout and friends are now
   used only in pdc4030 code. Those function where not called from IRQ context
   but they where set as handlers and not as expiry functions.

- Return ATA_OP_CONTINUES instead of ATA_OP_FINISHED in ata_error(), to signal
   that we are willing to retry the operation until the maximal number of retry
   attempts is exceeded. Returning ATA_OP_FINISHED without prior end_request()
   hangs the system.

- Apply trivia from DJ patch set.

- Apply small configuration fix to ide-pci.c from Muli Ben-Yehuda.

- Feed add_blkdev_randomness with information we already have in struct
   ata_channel *ch->major, instead of using the major(macro) on the request in
   question.

- Make ide_raw_taskfile use the same request submission mechanism as
   tcq_invalidate_queue(). Something similar would be ideal for ioctl() code as
   well.

- Implement actual device reset. Realize that the recalibration procedure is
   doomed by the standard. Don't try to recover by recalibrating devices
   therefore -just our retry mechanism should work in those cases. And suddenly
   the error handling code is IRQ safe.

- Reinvent the ATA reset operation, since it is apparently needed. We still
   have to do the whole transfer timing reconfiguration there.

- Move drive_is_ready(), which is in reality an attempt to check for IRQ
   requesters without clearing the IRQ line, over to the place where it belongs:
   device.c, which is the direct device access abstraction place.  Rename it to
   ata_status_irq() to prevent global name space pollution.

- Updates to the pdc202xxx host chip controller setup code by Bart³omiej
   ¯o³nierkiewicz:

   Forward port 2.4 patch by Hank Yang from Promise:

	- Add PDC20271 support
	- Disable LBA48 support on PDC20262
	- Fix ATAPI UDMA port value
	- Add new quirk drive
	- Adjust timings for all drives when using ATA133
	- Update pdc202xx_reset() waiting time

- Mark TCQ as dangerous and add some bits about it to the help.

- Add some missing exports.

- Some small ide-scsi.c host allocation fixes by sullivan.
parent 3ec59360
...@@ -708,7 +708,14 @@ CONFIG_BLK_DEV_IDE_TCQ ...@@ -708,7 +708,14 @@ CONFIG_BLK_DEV_IDE_TCQ
Digital drives in the Expert series (by nature of really being IBM Digital drives in the Expert series (by nature of really being IBM
drives). drives).
If you have such a drive, say Y here. However, please, note that there are host chip controllers which will
not cooperate properly if TCQ is enabled. This may cause serious
data loss!
Since enabling TCQ doesn't appear to have any noticeable performance
impact on Linux: [feel free to correct me if you wish too please]
Generally say N here.
CONFIG_BLK_DEV_IDE_TCQ_DEPTH CONFIG_BLK_DEV_IDE_TCQ_DEPTH
Maximum size of commands to enable per-drive. Any value between 1 Maximum size of commands to enable per-drive. Any value between 1
......
...@@ -34,7 +34,7 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then ...@@ -34,7 +34,7 @@ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then
dep_bool ' Use PCI DMA by default when available' CONFIG_IDEDMA_PCI_AUTO $CONFIG_BLK_DEV_IDEDMA_PCI dep_bool ' Use PCI DMA by default when available' CONFIG_IDEDMA_PCI_AUTO $CONFIG_BLK_DEV_IDEDMA_PCI
dep_bool ' Enable DMA only for disks ' CONFIG_IDEDMA_ONLYDISK $CONFIG_IDEDMA_PCI_AUTO dep_bool ' Enable DMA only for disks ' CONFIG_IDEDMA_ONLYDISK $CONFIG_IDEDMA_PCI_AUTO
define_bool CONFIG_BLK_DEV_IDEDMA $CONFIG_BLK_DEV_IDEDMA_PCI define_bool CONFIG_BLK_DEV_IDEDMA $CONFIG_BLK_DEV_IDEDMA_PCI
dep_bool ' ATA tagged command queueing (EXPERIMENTAL)' CONFIG_BLK_DEV_IDE_TCQ $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_EXPERIMENTAL dep_bool ' ATA tagged command queueing (DANGEROUS)' CONFIG_BLK_DEV_IDE_TCQ $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_EXPERIMENTAL
dep_bool ' TCQ on by default' CONFIG_BLK_DEV_IDE_TCQ_DEFAULT $CONFIG_BLK_DEV_IDE_TCQ dep_bool ' TCQ on by default' CONFIG_BLK_DEV_IDE_TCQ_DEFAULT $CONFIG_BLK_DEV_IDE_TCQ
if [ "$CONFIG_BLK_DEV_IDE_TCQ" != "n" ]; then if [ "$CONFIG_BLK_DEV_IDE_TCQ" != "n" ]; then
int ' Default queue depth' CONFIG_BLK_DEV_IDE_TCQ_DEPTH 32 int ' Default queue depth' CONFIG_BLK_DEV_IDE_TCQ_DEPTH 32
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <linux/blkdev.h> #include <linux/blkdev.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/completion.h>
#include <linux/cdrom.h> #include <linux/cdrom.h>
#include <linux/hdreg.h> #include <linux/hdreg.h>
#include <linux/ide.h> #include <linux/ide.h>
...@@ -115,6 +116,66 @@ void atapi_write(struct ata_device *drive, u8 *buf, unsigned int n) ...@@ -115,6 +116,66 @@ void atapi_write(struct ata_device *drive, u8 *buf, unsigned int n)
outsw(IDE_DATA_REG, buf + (n & ~0x03), 1); outsw(IDE_DATA_REG, buf + (n & ~0x03), 1);
} }
/*
* 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_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(struct ata_device *drive, struct request *rq, ide_action_t action)
{
unsigned long flags;
struct ata_channel *ch = drive->channel;
unsigned int major = ch->major;
request_queue_t *q = &drive->queue;
struct list_head *queue_head = &q->queue_head;
DECLARE_COMPLETION(wait);
#ifdef CONFIG_BLK_DEV_PDC4030
if (ch->chipset == ide_pdc4030 && rq->buffer)
return -ENOSYS; /* special drive cmds not supported */
#endif
rq->errors = 0;
rq->rq_status = RQ_ACTIVE;
rq->rq_dev = mk_kdev(major, (drive->select.b.unit) << PARTN_BITS);
if (action == ide_wait)
rq->waiting = &wait;
spin_lock_irqsave(ch->lock, flags);
if (action == ide_preempt)
drive->rq = NULL;
else if (!blk_queue_empty(&drive->queue))
queue_head = queue_head->prev; /* ide_end and ide_wait */
__elv_add_request(q, rq, queue_head);
do_ide_request(q);
spin_unlock_irqrestore(ch->lock, flags);
if (action == ide_wait) {
wait_for_completion(&wait); /* wait for it to be serviced */
return rq->errors ? -EIO : 0; /* return -EIO if errors */
}
return 0;
}
EXPORT_SYMBOL(ide_do_drive_cmd);
EXPORT_SYMBOL(atapi_discard_data); EXPORT_SYMBOL(atapi_discard_data);
EXPORT_SYMBOL(atapi_write_zeros); EXPORT_SYMBOL(atapi_write_zeros);
EXPORT_SYMBOL(atapi_init_pc); EXPORT_SYMBOL(atapi_init_pc);
......
...@@ -79,6 +79,8 @@ void ata_mask(struct ata_device *drive) ...@@ -79,6 +79,8 @@ void ata_mask(struct ata_device *drive)
ch->maskproc(drive); ch->maskproc(drive);
} }
EXPORT_SYMBOL(ata_mask);
/* /*
* Check the state of the status register. * Check the state of the status register.
*/ */
...@@ -93,6 +95,39 @@ int ata_status(struct ata_device *drive, u8 good, u8 bad) ...@@ -93,6 +95,39 @@ int ata_status(struct ata_device *drive, u8 good, u8 bad)
EXPORT_SYMBOL(ata_status); EXPORT_SYMBOL(ata_status);
/*
* This is used to check for the drive status on the IRQ handling code path.
*/
int ata_status_irq(struct ata_device *drive)
{
if (test_bit(IDE_DMA, drive->channel->active))
return udma_irq_status(drive);
/* Need to guarantee 400ns since last command was issued?
*/
#ifdef CONFIG_IDEPCI_SHARE_IRQ
/*
* We do a passive status test under shared PCI interrupts on cards
* that truly share the ATA side interrupt, but may also share an
* interrupt with another pci card/device.
*/
if (drive->channel->io_ports[IDE_CONTROL_OFFSET])
drive->status = IN_BYTE(drive->channel->io_ports[IDE_CONTROL_OFFSET]);
else
#endif
ata_status(drive, 0, 0); /* Note: this may clear a pending IRQ! */
if (drive->status & BUSY_STAT)
return 0; /* drive busy: definitely not interrupting */
else
return 1; /* drive ready: *might* be interrupting */
}
EXPORT_SYMBOL(ata_status_irq);
/* /*
* Busy-wait for the drive status to be not "busy". Check then the status for * Busy-wait for the drive status to be not "busy". Check then the status for
* all of the "good" bits and none of the "bad" bits, and if all is okay it * all of the "good" bits and none of the "bad" bits, and if all is okay it
...@@ -210,6 +245,8 @@ void ata_out_regfile(struct ata_device *drive, struct hd_drive_task_hdr *rf) ...@@ -210,6 +245,8 @@ void ata_out_regfile(struct ata_device *drive, struct hd_drive_task_hdr *rf)
OUT_BYTE(rf->high_cylinder, ch->io_ports[IDE_HCYL_OFFSET]); OUT_BYTE(rf->high_cylinder, ch->io_ports[IDE_HCYL_OFFSET]);
} }
EXPORT_SYMBOL(ata_out_regfile);
/* /*
* Input a complete register file. * Input a complete register file.
*/ */
...@@ -223,5 +260,4 @@ void ata_in_regfile(struct ata_device *drive, struct hd_drive_task_hdr *rf) ...@@ -223,5 +260,4 @@ void ata_in_regfile(struct ata_device *drive, struct hd_drive_task_hdr *rf)
rf->high_cylinder = IN_BYTE(ch->io_ports[IDE_HCYL_OFFSET]); rf->high_cylinder = IN_BYTE(ch->io_ports[IDE_HCYL_OFFSET]);
} }
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -106,9 +106,9 @@ static int gayle_ack_intr_a1200(struct ata_channel *hwif) ...@@ -106,9 +106,9 @@ static int gayle_ack_intr_a1200(struct ata_channel *hwif)
return 1; return 1;
} }
/* /*
* Probe for a Gayle IDE interface (and optionally for an IDE doubler) * Probe for a Gayle IDE interface (and optionally for an IDE doubler)
*/ */
void __init gayle_init(void) void __init gayle_init(void)
{ {
...@@ -122,7 +122,7 @@ void __init gayle_init(void) ...@@ -122,7 +122,7 @@ void __init gayle_init(void)
for (i = 0; i < GAYLE_NUM_PROBE_HWIFS; i++) { for (i = 0; i < GAYLE_NUM_PROBE_HWIFS; i++) {
ide_ioreg_t base, ctrlport, irqport; ide_ioreg_t base, ctrlport, irqport;
ide_ack_intr_t *ack_intr; int (*ack_intr)(struct ata_channel *);
hw_regs_t hw; hw_regs_t hw;
int index; int index;
unsigned long phys_base, res_start, res_n; unsigned long phys_base, res_start, res_n;
......
...@@ -132,16 +132,16 @@ unsigned long last_req; ...@@ -132,16 +132,16 @@ unsigned long last_req;
unsigned long read_timer(void) unsigned long read_timer(void)
{ {
extern spinlock_t i8253_lock;
unsigned long t, flags; unsigned long t, flags;
int i; int i;
save_flags(flags); spin_lock_irqsave(&i8253_lock, flags);
cli();
t = jiffies * 11932; t = jiffies * 11932;
outb_p(0, 0x43); outb_p(0, 0x43);
i = inb_p(0x40); i = inb_p(0x40);
i |= inb(0x40) << 8; i |= inb(0x40) << 8;
restore_flags(flags); spin_unlock_irqrestore(&i8253_lock, flags);
return(t - i); return(t - i);
} }
#endif #endif
...@@ -817,8 +817,19 @@ static void __init hd_geninit(void) ...@@ -817,8 +817,19 @@ static void __init hd_geninit(void)
NR_HD = 0; NR_HD = 0;
return; return;
} }
request_region(HD_DATA, 8, "hd"); if (!request_region(HD_DATA, 8, "hd")) {
request_region(HD_CMD, 1, "hd(cmd)"); printk(KERN_WARNING "hd: port 0x%x busy\n", HD_DATA);
NR_HD = 0;
free_irq(HD_IRQ, NULL);
return;
}
if (!request_region(HD_CMD, 1, "hd(cmd)")) {
printk(KERN_WARNING "hd: port 0x%x busy\n", HD_CMD);
NR_HD = 0;
free_irq(HD_IRQ, NULL);
release_region(HD_DATA, 8);
return;
}
hd_gendisk.nr_real = NR_HD; hd_gendisk.nr_real = NR_HD;
......
...@@ -556,7 +556,7 @@ static void cdrom_end_request(struct ata_device *drive, struct request *rq, int ...@@ -556,7 +556,7 @@ static void cdrom_end_request(struct ata_device *drive, struct request *rq, int
if ((rq->flags & REQ_CMD) && !rq->current_nr_sectors) if ((rq->flags & REQ_CMD) && !rq->current_nr_sectors)
uptodate = 1; uptodate = 1;
__ata_end_request(drive, rq, uptodate, 0); ata_end_request(drive, rq, uptodate, 0);
} }
...@@ -912,7 +912,7 @@ static ide_startstop_t cdrom_read_intr(struct ata_device *drive, struct request ...@@ -912,7 +912,7 @@ static ide_startstop_t cdrom_read_intr(struct ata_device *drive, struct request
if (dma) { if (dma) {
if (!dma_error) { if (!dma_error) {
__ata_end_request(drive, rq, 1, rq->nr_sectors); ata_end_request(drive, rq, 1, rq->nr_sectors);
return ATA_OP_FINISHED; return ATA_OP_FINISHED;
} else } else
...@@ -1497,7 +1497,7 @@ static ide_startstop_t cdrom_write_intr(struct ata_device *drive, struct request ...@@ -1497,7 +1497,7 @@ static ide_startstop_t cdrom_write_intr(struct ata_device *drive, struct request
if (dma_error) if (dma_error)
return ata_error(drive, rq, "dma error"); return ata_error(drive, rq, "dma error");
__ata_end_request(drive, rq, 1, rq->nr_sectors); ata_end_request(drive, rq, 1, rq->nr_sectors);
return ATA_OP_FINISHED; return ATA_OP_FINISHED;
} }
...@@ -1936,7 +1936,7 @@ static int cdrom_read_toc(struct ata_device *drive, struct request_sense *sense) ...@@ -1936,7 +1936,7 @@ static int cdrom_read_toc(struct ata_device *drive, struct request_sense *sense)
If we get an error for the regular case, we assume If we get an error for the regular case, we assume
a CDI without additional audio tracks. In this case a CDI without additional audio tracks. In this case
the readable TOC is empty (CDI tracks are not included) the readable TOC is empty (CDI tracks are not included)
and only holds the Leadout entry. Heiko Eißfeldt */ and only holds the Leadout entry. Heiko EiÃ^ßfeldt */
ntracks = 0; ntracks = 0;
stat = cdrom_read_tocentry(drive, CDROM_LEADOUT, 1, 0, stat = cdrom_read_tocentry(drive, CDROM_LEADOUT, 1, 0,
(char *)&toc->hdr, (char *)&toc->hdr,
...@@ -2840,11 +2840,11 @@ static int ide_cdrom_setup(struct ata_device *drive) ...@@ -2840,11 +2840,11 @@ static int ide_cdrom_setup(struct ata_device *drive)
} }
/* Forwarding functions to generic routines. */ /* Forwarding functions to generic routines. */
static int ide_cdrom_ioctl (struct ata_device *drive, static int ide_cdrom_ioctl(struct ata_device *drive,
struct inode *inode, struct file *file, struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
return cdrom_ioctl (inode, file, cmd, arg); return cdrom_ioctl(inode, file, cmd, arg);
} }
static int ide_cdrom_open (struct inode *ip, struct file *fp, struct ata_device *drive) static int ide_cdrom_open (struct inode *ip, struct file *fp, struct ata_device *drive)
......
...@@ -140,7 +140,7 @@ static ide_startstop_t task_in_intr(struct ata_device *drive, struct request *rq ...@@ -140,7 +140,7 @@ static ide_startstop_t task_in_intr(struct ata_device *drive, struct request *rq
--rq->current_nr_sectors; --rq->current_nr_sectors;
if (rq->current_nr_sectors <= 0) { if (rq->current_nr_sectors <= 0) {
if (!__ata_end_request(drive, rq, 1, 0)) { if (!ata_end_request(drive, rq, 1, 0)) {
// printk("Request Ended stat: %02x\n", drive->status); // printk("Request Ended stat: %02x\n", drive->status);
return ATA_OP_FINISHED; return ATA_OP_FINISHED;
...@@ -166,7 +166,7 @@ static ide_startstop_t task_out_intr(struct ata_device *drive, struct request *r ...@@ -166,7 +166,7 @@ static ide_startstop_t task_out_intr(struct ata_device *drive, struct request *r
if (!ata_status(drive, DRIVE_READY, drive->bad_wstat)) if (!ata_status(drive, DRIVE_READY, drive->bad_wstat))
return ata_error(drive, rq, __FUNCTION__); return ata_error(drive, rq, __FUNCTION__);
if (!rq->current_nr_sectors && !__ata_end_request(drive, rq, 1, 0)) { if (!rq->current_nr_sectors && !ata_end_request(drive, rq, 1, 0)) {
ret = ATA_OP_FINISHED; ret = ATA_OP_FINISHED;
} else { } else {
if ((rq->nr_sectors == 1) != (drive->status & DRQ_STAT)) { if ((rq->nr_sectors == 1) != (drive->status & DRQ_STAT)) {
...@@ -235,7 +235,7 @@ static ide_startstop_t task_mulin_intr(struct ata_device *drive, struct request ...@@ -235,7 +235,7 @@ static ide_startstop_t task_mulin_intr(struct ata_device *drive, struct request
/* FIXME: this seems buggy */ /* FIXME: this seems buggy */
if (rq->current_nr_sectors <= 0) { if (rq->current_nr_sectors <= 0) {
if (!__ata_end_request(drive, rq, 1, 0)) if (!ata_end_request(drive, rq, 1, 0))
return ATA_OP_FINISHED; return ATA_OP_FINISHED;
} }
msect -= nsect; msect -= nsect;
...@@ -269,7 +269,7 @@ static ide_startstop_t task_mulout_intr(struct ata_device *drive, struct request ...@@ -269,7 +269,7 @@ static ide_startstop_t task_mulout_intr(struct ata_device *drive, struct request
return ata_error(drive, rq, __FUNCTION__); return ata_error(drive, rq, __FUNCTION__);
} }
if (!rq->nr_sectors) { if (!rq->nr_sectors) {
__ata_end_request(drive, rq, 1, rq->hard_nr_sectors); ata_end_request(drive, rq, 1, rq->hard_nr_sectors);
rq->bio = NULL; rq->bio = NULL;
ret = ATA_OP_FINISHED; ret = ATA_OP_FINISHED;
} else if (!ok) { } else if (!ok) {
...@@ -349,7 +349,7 @@ static ide_startstop_t idedisk_do_request(struct ata_device *drive, struct reque ...@@ -349,7 +349,7 @@ static ide_startstop_t idedisk_do_request(struct ata_device *drive, struct reque
/* FIXME: this check doesn't make sense */ /* FIXME: this check doesn't make sense */
if (!(rq->flags & REQ_CMD)) { if (!(rq->flags & REQ_CMD)) {
blk_dump_rq_flags(rq, "idedisk_do_request - bad command"); blk_dump_rq_flags(rq, "idedisk_do_request - bad command");
__ata_end_request(drive, rq, 0, 0); ata_end_request(drive, rq, 0, 0);
return ATA_OP_FINISHED; return ATA_OP_FINISHED;
} }
...@@ -514,8 +514,8 @@ static ide_startstop_t idedisk_do_request(struct ata_device *drive, struct reque ...@@ -514,8 +514,8 @@ static ide_startstop_t idedisk_do_request(struct ata_device *drive, struct reque
printk("sectors=%ld, ", rq->nr_sectors); printk("sectors=%ld, ", rq->nr_sectors);
printk("buffer=%p\n", rq->buffer); printk("buffer=%p\n", rq->buffer);
#endif #endif
ar->cmd = cmd; ar->cmd = cmd;
rq->special = ar; rq->special = ar;
} }
/* (ks/hs): Moved to start, do not use for multiple out commands. /* (ks/hs): Moved to start, do not use for multiple out commands.
...@@ -548,10 +548,9 @@ static ide_startstop_t idedisk_do_request(struct ata_device *drive, struct reque ...@@ -548,10 +548,9 @@ static ide_startstop_t idedisk_do_request(struct ata_device *drive, struct reque
return ATA_OP_CONTINUES; return ATA_OP_CONTINUES;
} }
/* FIXME: Warning check for race between handler and prehandler /* FIXME: Warning check for race between handlers for writing
* for writing first block of data. however since we are well * first block of data. However since we are well inside the
* inside the boundaries of the seek, we should be okay. * boundaries of the seek, we should be okay.
* FIXME: should be fixed --bzolnier
*/ */
if (ar->command_type == IDE_DRIVE_TASK_RAW_WRITE) { if (ar->command_type == IDE_DRIVE_TASK_RAW_WRITE) {
ide_startstop_t ret; ide_startstop_t ret;
...@@ -596,13 +595,15 @@ static ide_startstop_t idedisk_do_request(struct ata_device *drive, struct reque ...@@ -596,13 +595,15 @@ static ide_startstop_t idedisk_do_request(struct ata_device *drive, struct reque
* *
* FIXME: Replace hard-coded 100, what about * FIXME: Replace hard-coded 100, what about
* error handling? * error handling?
*
* FIXME: Whatabout the IRE clearing and not clearing case?!
*/ */
for (i = 0; i < 100; ++i) { for (i = 0; i < 100; ++i) {
if (drive_is_ready(drive)) if (ata_status_irq(drive))
break; break;
} }
if (!drive_is_ready(drive)) { if (!ata_status_irq(drive)) {
/* We are compleatly missing an error /* We are compleatly missing an error
* return path here. * return path here.
* FIXME: We have only one? -alat * FIXME: We have only one? -alat
...@@ -1290,7 +1291,9 @@ static int idedisk_cleanup(struct ata_device *drive) ...@@ -1290,7 +1291,9 @@ static int idedisk_cleanup(struct ata_device *drive)
return ret; return ret;
} }
static int idedisk_ioctl(struct ata_device *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) static int idedisk_ioctl(struct ata_device *drive,
struct inode *inode, struct file *__fp,
unsigned int cmd, unsigned long arg)
{ {
struct hd_driveid *id = drive->id; struct hd_driveid *id = drive->id;
......
...@@ -96,6 +96,7 @@ ...@@ -96,6 +96,7 @@
#include <linux/cdrom.h> #include <linux/cdrom.h>
#include <linux/ide.h> #include <linux/ide.h>
#include <linux/atapi.h> #include <linux/atapi.h>
#include <linux/buffer_head.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include <asm/irq.h> #include <asm/irq.h>
...@@ -367,7 +368,7 @@ static int idefloppy_end_request(struct ata_device *drive, struct request *rq, i ...@@ -367,7 +368,7 @@ static int idefloppy_end_request(struct ata_device *drive, struct request *rq, i
return 0; return 0;
if (!(rq->flags & REQ_SPECIAL)) { if (!(rq->flags & REQ_SPECIAL)) {
__ata_end_request(drive, rq, uptodate, 0); ata_end_request(drive, rq, uptodate, 0);
return 0; return 0;
} }
...@@ -731,7 +732,6 @@ static ide_startstop_t idefloppy_transfer_pc2(struct ata_device *drive, struct r ...@@ -731,7 +732,6 @@ static ide_startstop_t idefloppy_transfer_pc2(struct ata_device *drive, struct r
static ide_startstop_t idefloppy_transfer_pc1(struct ata_device *drive, struct request *rq) static ide_startstop_t idefloppy_transfer_pc1(struct ata_device *drive, struct request *rq)
{ {
idefloppy_floppy_t *floppy = drive->driver_data; idefloppy_floppy_t *floppy = drive->driver_data;
ide_startstop_t startstop;
atapi_ireason_reg_t ireason; atapi_ireason_reg_t ireason;
int ret; int ret;
......
...@@ -50,7 +50,7 @@ static void print_fixed (volatile unsigned char *p); ...@@ -50,7 +50,7 @@ static void print_fixed (volatile unsigned char *p);
static void print_funcid (int func); static void print_funcid (int func);
static int check_ide_device (unsigned long base); static int check_ide_device (unsigned long base);
static void ide_interrupt_ack (void *dev); static int ide_interrupt_ack(struct ata_channel *);
static void m8xx_ide_tuneproc(struct ata_device *drive, byte pio); static void m8xx_ide_tuneproc(struct ata_device *drive, byte pio);
typedef struct ide_ioport_desc { typedef struct ide_ioport_desc {
...@@ -326,7 +326,7 @@ m8xx_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, ...@@ -326,7 +326,7 @@ m8xx_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port,
/* register routine to tune PIO mode */ /* register routine to tune PIO mode */
ide_hwifs[data_port].tuneproc = m8xx_ide_tuneproc; ide_hwifs[data_port].tuneproc = m8xx_ide_tuneproc;
hw->ack_intr = (ide_ack_intr_t *) ide_interrupt_ack; hw->ack_intr = ide_interrupt_ack;
/* Enable Harddisk Interrupt, /* Enable Harddisk Interrupt,
* and make it edge sensitive * and make it edge sensitive
*/ */
...@@ -401,7 +401,7 @@ void m8xx_ide_init_hwif_ports (hw_regs_t *hw, ...@@ -401,7 +401,7 @@ void m8xx_ide_init_hwif_ports (hw_regs_t *hw,
ioport_dsc[data_port].reg_off[i], ioport_dsc[data_port].reg_off[i],
i, base + ioport_dsc[data_port].reg_off[i]); i, base + ioport_dsc[data_port].reg_off[i]);
#endif #endif
*p++ = base + ioport_dsc[data_port].reg_off[i]; *p++ = base + ioport_dsc[data_port].reg_off[i];
} }
if (irq) { if (irq) {
...@@ -412,16 +412,16 @@ void m8xx_ide_init_hwif_ports (hw_regs_t *hw, ...@@ -412,16 +412,16 @@ void m8xx_ide_init_hwif_ports (hw_regs_t *hw,
/* register routine to tune PIO mode */ /* register routine to tune PIO mode */
ide_hwifs[data_port].tuneproc = m8xx_ide_tuneproc; ide_hwifs[data_port].tuneproc = m8xx_ide_tuneproc;
hw->ack_intr = (ide_ack_intr_t *) ide_interrupt_ack; hw->ack_intr = ide_interrupt_ack;
/* Enable Harddisk Interrupt, /* Enable Harddisk Interrupt,
* and make it edge sensitive * and make it edge sensitive
*/ */
/* (11-18) Set edge detect for irq, no wakeup from low power mode */ /* (11-18) Set edge detect for irq, no wakeup from low power mode */
((immap_t *) IMAP_ADDR)->im_siu_conf.sc_siel |= ((immap_t *) IMAP_ADDR)->im_siu_conf.sc_siel |=
(0x80000000 >> ioport_dsc[data_port].irq); (0x80000000 >> ioport_dsc[data_port].irq);
} /* m8xx_ide_init_hwif_ports() for CONFIG_IDE_8xx_DIRECT */ } /* m8xx_ide_init_hwif_ports() for CONFIG_IDE_8xx_DIRECT */
#endif /* CONFIG_IDE_8xx_DIRECT */ #endif
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */
...@@ -493,11 +493,10 @@ m8xx_ide_tuneproc(struct ata_device *drive, byte pio) ...@@ -493,11 +493,10 @@ m8xx_ide_tuneproc(struct ata_device *drive, byte pio)
printk("%s[%d] %s: not implemented yet!\n", printk("%s[%d] %s: not implemented yet!\n",
__FILE__,__LINE__,__FUNCTION__); __FILE__,__LINE__,__FUNCTION__);
#endif /* defined(CONFIG_IDE_8xx_PCCARD) || defined(CONFIG_IDE_8xx_PCMCIA */ #endif
} }
static void static int ide_interrupt_ack(struct ata_channel *ch)
ide_interrupt_ack (void *dev)
{ {
#ifdef CONFIG_IDE_8xx_PCCARD #ifdef CONFIG_IDE_8xx_PCCARD
u_int pscr, pipr; u_int pscr, pipr;
...@@ -529,17 +528,17 @@ ide_interrupt_ack (void *dev) ...@@ -529,17 +528,17 @@ ide_interrupt_ack (void *dev)
/* clear the interrupt sources */ /* clear the interrupt sources */
((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr = pscr; ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr = pscr;
#else /* ! CONFIG_IDE_8xx_PCCARD */ #else
/* /*
* Only CONFIG_IDE_8xx_PCCARD is using the interrupt of the * Only CONFIG_IDE_8xx_PCCARD is using the interrupt of the
* MPC8xx's PCMCIA controller, so there is nothing to be done here * MPC8xx's PCMCIA controller, so there is nothing to be done here
* for CONFIG_IDE_8xx_DIRECT and CONFIG_IDE_EXT_DIRECT. * for CONFIG_IDE_8xx_DIRECT and CONFIG_IDE_EXT_DIRECT.
* The interrupt is handled somewhere else. -- Steven * The interrupt is handled somewhere else. -- Steven
*/ */
#endif /* CONFIG_IDE_8xx_PCCARD */ #endif
}
return 0;
}
/* /*
* CIS Tupel codes * CIS Tupel codes
...@@ -655,7 +654,7 @@ static int check_ide_device (unsigned long base) ...@@ -655,7 +654,7 @@ static int check_ide_device (unsigned long base)
q+= 2; q+= 2;
} }
} }
#endif /* DEBUG_PCMCIA */ #endif
switch (code) { switch (code) {
case CISTPL_VERS_1: case CISTPL_VERS_1:
ident = p + 4; ident = p + 4;
......
...@@ -158,6 +158,80 @@ static int __init setup_pci_baseregs(struct pci_dev *dev, const char *name) ...@@ -158,6 +158,80 @@ static int __init setup_pci_baseregs(struct pci_dev *dev, const char *name)
return 0; return 0;
} }
#ifdef CONFIG_BLK_DEV_IDEDMA
/*
* Setup DMA transfers on the channel.
*/
static void __init setup_channel_dma(struct pci_dev *dev,
struct ata_pci_device* d,
int autodma,
struct ata_channel *ch)
{
unsigned long dma_base;
if (d->flags & ATA_F_NOADMA)
autodma = 0;
if (autodma)
ch->autodma = 1;
if (!((d->flags & ATA_F_DMA) || ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE && (dev->class & 0x80))))
return;
/*
* Fetch the DMA Bus-Master-I/O-Base-Address (BMIBA) from PCI space:
*/
dma_base = pci_resource_start(dev, 4);
if (dma_base) {
/* PDC20246, PDC20262, HPT343, & HPT366 */
if ((ch->unit == ATA_PRIMARY) && d->extra) {
request_region(dma_base + 16, d->extra, dev->name);
ch->dma_extra = d->extra;
}
/* If we are on the second channel, the dma base address will
* be one entry away from the primary interface.
*/
if (ch->unit == ATA_SECONDARY)
dma_base += 8;
if (d->flags & ATA_F_SIMPLEX) {
outb(inb(dma_base + 2) & 0x60, dma_base + 2);
if (inb(dma_base + 2) & 0x80)
printk(KERN_INFO "%s: simplex device: DMA forced\n", dev->name);
} else {
/* If the device claims "simplex" DMA, this means only
* one of the two interfaces can be trusted with DMA at
* any point in time. So we should enable DMA only on
* one of the two interfaces.
*/
if ((inb(dma_base + 2) & 0x80)) {
if ((!ch->drives[0].present && !ch->drives[1].present) ||
ch->unit == ATA_SECONDARY) {
printk(KERN_INFO "%s: simplex device: DMA disabled\n", dev->name);
dma_base = 0;
}
}
}
} else {
printk(KERN_INFO "%s: %s Bus-Master DMA was disabled by BIOS\n",
ch->name, dev->name);
return;
}
/* The function below will check itself whatever there is something to
* be done or not. We don't have therefore to care whatever it was
* already enabled by the primary channel run.
*/
pci_set_master(dev);
if (d->init_dma)
d->init_dma(ch, dma_base);
else
ata_init_dma(ch, dma_base);
}
#endif
/* /*
* Setup a particular port on an ATA host controller. * Setup a particular port on an ATA host controller.
* *
...@@ -171,7 +245,6 @@ static int __init setup_host_channel(struct pci_dev *dev, ...@@ -171,7 +245,6 @@ static int __init setup_host_channel(struct pci_dev *dev,
int autodma) int autodma)
{ {
unsigned long base = 0; unsigned long base = 0;
unsigned long dma_base;
unsigned long ctl = 0; unsigned long ctl = 0;
ide_pci_enablebit_t *e = &(d->enablebits[port]); ide_pci_enablebit_t *e = &(d->enablebits[port]);
struct ata_channel *ch; struct ata_channel *ch;
...@@ -260,69 +333,13 @@ static int __init setup_host_channel(struct pci_dev *dev, ...@@ -260,69 +333,13 @@ static int __init setup_host_channel(struct pci_dev *dev,
if (ch->udma_four) if (ch->udma_four)
printk("%s: warning: ATA-66/100 forced bit set!\n", dev->name); printk("%s: warning: ATA-66/100 forced bit set!\n", dev->name);
#ifdef CONFIG_BLK_DEV_IDEDMA #ifdef CONFIG_BLK_DEV_IDEDMA
/* /*
* Setup DMA transfers on the channel. * Setup DMA transfers on the channel.
*/ */
if (!((d->flags & ATA_F_DMA) || ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE && (dev->class & 0x80)))) setup_channel_dma(dev, d, autodma, ch);
goto no_dma;
/*
* Fetch the DMA Bus-Master-I/O-Base-Address (BMIBA) from PCI space:
*/
dma_base = pci_resource_start(dev, 4);
if (dma_base) {
/* PDC20246, PDC20262, HPT343, & HPT366 */
if ((ch->unit == ATA_PRIMARY) && d->extra) {
request_region(dma_base + 16, d->extra, dev->name);
ch->dma_extra = d->extra;
}
/* If we are on the second channel, the dma base address will
* be one entry away from the primary interface.
*/
if (ch->unit == ATA_SECONDARY)
dma_base += 8;
if (d->flags & ATA_F_SIMPLEX) {
outb(inb(dma_base + 2) & 0x60, dma_base + 2);
if (inb(dma_base + 2) & 0x80)
printk(KERN_INFO "%s: simplex device: DMA forced\n", dev->name);
} else {
/* If the device claims "simplex" DMA, this means only
* one of the two interfaces can be trusted with DMA at
* any point in time. So we should enable DMA only on
* one of the two interfaces.
*/
if ((inb(dma_base + 2) & 0x80)) {
if ((!ch->drives[0].present && !ch->drives[1].present) ||
ch->unit == ATA_SECONDARY) {
printk(KERN_INFO "%s: simplex device: DMA disabled\n", dev->name);
dma_base = 0;
}
}
}
} else {
printk(KERN_INFO "%s: %s Bus-Master DMA was disabled by BIOS\n",
ch->name, dev->name);
goto no_dma;
}
/* The function below will check itself whatever there is something to
* be done or not. We don't have therefore to care whatever it was
* already enabled by the primary channel run.
*/
pci_set_master(dev);
if (autodma)
ch->autodma = 1;
if (d->init_dma)
d->init_dma(ch, dma_base);
else
ata_init_dma(ch, dma_base);
#endif #endif
no_dma: no_dma:
/* Call chipset-specific routine for each enabled channel. */ /* Call chipset-specific routine for each enabled channel. */
if (d->init_channel) if (d->init_channel)
......
...@@ -421,6 +421,7 @@ ...@@ -421,6 +421,7 @@
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/ide.h> #include <linux/ide.h>
#include <linux/atapi.h> #include <linux/atapi.h>
#include <linux/buffer_head.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include <asm/irq.h> #include <asm/irq.h>
...@@ -2445,7 +2446,7 @@ static ide_startstop_t idetape_do_request(struct ata_device *drive, struct reque ...@@ -2445,7 +2446,7 @@ static ide_startstop_t idetape_do_request(struct ata_device *drive, struct reque
* We do not support buffer cache originated requests. * We do not support buffer cache originated requests.
*/ */
printk (KERN_NOTICE "ide-tape: %s: Unsupported command in request queue (%ld)\n", drive->name, rq->flags); printk (KERN_NOTICE "ide-tape: %s: Unsupported command in request queue (%ld)\n", drive->name, rq->flags);
__ata_end_request(drive, rq, 0, 0); /* Let the common code handle it */ ata_end_request(drive, rq, 0, 0); /* Let the common code handle it */
return ATA_OP_FINISHED; return ATA_OP_FINISHED;
} }
......
...@@ -33,18 +33,9 @@ ...@@ -33,18 +33,9 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/bitops.h> #include <asm/bitops.h>
#define DEBUG_TASKFILE 0 /* unset when fixed */
#if DEBUG_TASKFILE
#define DTF(x...) printk(##x)
#else
#define DTF(x...)
#endif
/* /*
* Data transfer functions for polled IO. * Data transfer functions for polled IO.
*/ */
static void ata_read_32(struct ata_device *drive, void *buffer, unsigned int wcount) static void ata_read_32(struct ata_device *drive, void *buffer, unsigned int wcount)
{ {
insl(IDE_DATA_REG, buffer, wcount); insl(IDE_DATA_REG, buffer, wcount);
...@@ -143,103 +134,10 @@ void ata_write(struct ata_device *drive, void *buffer, unsigned int wcount) ...@@ -143,103 +134,10 @@ void ata_write(struct ata_device *drive, void *buffer, unsigned int wcount)
} }
} }
/*
* Needed for PCI irq sharing
*/
int drive_is_ready(struct ata_device *drive)
{
if (test_bit(IDE_DMA, drive->channel->active))
return udma_irq_status(drive);
/*
* Need to guarantee 400ns since last command was issued?
*/
/* FIXME: promote this to the general status read method perhaps.
*/
#ifdef CONFIG_IDEPCI_SHARE_IRQ
/*
* We do a passive status test under shared PCI interrupts on
* cards that truly share the ATA side interrupt, but may also share
* an interrupt with another pci card/device. We make no assumptions
* about possible isa-pnp and pci-pnp issues yet.
*/
if (drive->channel->io_ports[IDE_CONTROL_OFFSET])
drive->status = GET_ALTSTAT();
else
#endif
ata_status(drive, 0, 0); /* Note: this may clear a pending IRQ! */
if (drive->status & BUSY_STAT)
return 0; /* drive busy: definitely not interrupting */
return 1; /* drive ready: *might* be interrupting */
}
/*
* 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_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(struct ata_device *drive, struct request *rq, ide_action_t action)
{
unsigned long flags;
struct ata_channel *ch = drive->channel;
unsigned int major = ch->major;
request_queue_t *q = &drive->queue;
struct list_head *queue_head = &q->queue_head;
DECLARE_COMPLETION(wait);
#ifdef CONFIG_BLK_DEV_PDC4030
if (ch->chipset == ide_pdc4030 && rq->buffer)
return -ENOSYS; /* special drive cmds not supported */
#endif
rq->errors = 0;
rq->rq_status = RQ_ACTIVE;
rq->rq_dev = mk_kdev(major,(drive->select.b.unit)<<PARTN_BITS);
if (action == ide_wait)
rq->waiting = &wait;
spin_lock_irqsave(ch->lock, flags);
if (action == ide_preempt)
drive->rq = NULL;
else if (!blk_queue_empty(&drive->queue))
queue_head = queue_head->prev; /* ide_end and ide_wait */
__elv_add_request(q, rq, queue_head);
do_ide_request(q);
spin_unlock_irqrestore(ch->lock, flags);
if (action == ide_wait) {
wait_for_completion(&wait); /* wait for it to be serviced */
return rq->errors ? -EIO : 0; /* return -EIO if errors */
}
return 0;
}
/* /*
* Invoked on completion of a special REQ_SPECIAL command. * Invoked on completion of a special REQ_SPECIAL command.
*/ */
static ide_startstop_t special_intr(struct ata_device *drive, struct static ide_startstop_t special_intr(struct ata_device *drive, struct request *rq) {
request *rq) {
unsigned long flags; unsigned long flags;
struct ata_channel *ch =drive->channel; struct ata_channel *ch =drive->channel;
struct ata_taskfile *ar = rq->special; struct ata_taskfile *ar = rq->special;
...@@ -290,21 +188,52 @@ static ide_startstop_t special_intr(struct ata_device *drive, struct ...@@ -290,21 +188,52 @@ static ide_startstop_t special_intr(struct ata_device *drive, struct
int ide_raw_taskfile(struct ata_device *drive, struct ata_taskfile *ar, char *buf) int ide_raw_taskfile(struct ata_device *drive, struct ata_taskfile *ar, char *buf)
{ {
struct request req; struct request *rq;
unsigned long flags;
struct ata_channel *ch = drive->channel;
request_queue_t *q = &drive->queue;
struct list_head *queue_head = &q->queue_head;
DECLARE_COMPLETION(wait);
#ifdef CONFIG_BLK_DEV_PDC4030
if (ch->chipset == ide_pdc4030 && buf)
return -ENOSYS; /* special drive cmds not supported */
#endif
rq = __blk_get_request(&drive->queue, READ);
if (!rq)
rq = __blk_get_request(&drive->queue, WRITE);
/*
* FIXME: Make sure there is a free slot on the list!
*/
BUG_ON(!rq);
rq->flags = REQ_SPECIAL;
rq->buffer = buf;
rq->special = ar;
rq->errors = 0;
rq->rq_status = RQ_ACTIVE;
rq->waiting = &wait;
ar->command_type = IDE_DRIVE_TASK_NO_DATA;
ar->XXX_handler = special_intr; ar->XXX_handler = special_intr;
ar->command_type = IDE_DRIVE_TASK_NO_DATA;
spin_lock_irqsave(ch->lock, flags);
if (!blk_queue_empty(&drive->queue))
queue_head = queue_head->prev;
__elv_add_request(q, rq, queue_head);
q->request_fn(q);
spin_unlock_irqrestore(ch->lock, flags);
memset(&req, 0, sizeof(req)); wait_for_completion(&wait); /* wait for it to be serviced */
req.flags = REQ_SPECIAL;
req.buffer = buf;
req.special = ar;
return ide_do_drive_cmd(drive, &req, ide_wait); return rq->errors ? -EIO : 0; /* return -EIO if errors */
} }
EXPORT_SYMBOL(drive_is_ready);
EXPORT_SYMBOL(ide_do_drive_cmd);
EXPORT_SYMBOL(ata_read); EXPORT_SYMBOL(ata_read);
EXPORT_SYMBOL(ata_write); EXPORT_SYMBOL(ata_write);
EXPORT_SYMBOL(ide_raw_taskfile); EXPORT_SYMBOL(ide_raw_taskfile);
This diff is collapsed.
...@@ -140,12 +140,9 @@ struct ata_channel ide_hwifs[MAX_HWIFS]; /* master data repository */ ...@@ -140,12 +140,9 @@ struct ata_channel ide_hwifs[MAX_HWIFS]; /* master data repository */
* Setup hw_regs_t structure described by parameters. You may set up the hw * Setup hw_regs_t structure described by parameters. You may set up the hw
* structure yourself OR use this routine to do it for you. * structure yourself OR use this routine to do it for you.
*/ */
void ide_setup_ports(hw_regs_t *hw, void ide_setup_ports(hw_regs_t *hw, ide_ioreg_t base, int *offsets,
ide_ioreg_t base, ide_ioreg_t ctrl, ide_ioreg_t intr,
int *offsets, int (*ack_intr)(struct ata_channel *),
ide_ioreg_t ctrl,
ide_ioreg_t intr,
ide_ack_intr_t *ack_intr,
int irq) int irq)
{ {
int i; int i;
...@@ -637,17 +634,6 @@ int ide_register_hw(hw_regs_t *hw) ...@@ -637,17 +634,6 @@ int ide_register_hw(hw_regs_t *hw)
* FIXME: rewrite the following crap: * FIXME: rewrite the following crap:
*/ */
/*
* stridx() returns the offset of c within s,
* or -1 if c is '\0' or not found within s.
*/
static int __init stridx (const char *s, char c)
{
char *i = strchr(s, c);
return (i && c) ? i - s : -1;
}
/* /*
* Parsing for ide_setup(): * Parsing for ide_setup():
* *
...@@ -657,14 +643,14 @@ static int __init stridx (const char *s, char c) ...@@ -657,14 +643,14 @@ static int __init stridx (const char *s, char c)
* 3. if the remainder is a series of no more than max_vals numbers * 3. if the remainder is a series of no more than max_vals numbers
* separated by commas, the numbers are saved in vals[] and a * separated by commas, the numbers are saved in vals[] and a
* count of how many were saved is returned. Base10 is assumed, * count of how many were saved is returned. Base10 is assumed,
* and base16 is allowed when prefixed with "0x". * and base16 is allowed when prefixed with "0x". The number of
* values read will be placed in vals[0], and the values read will
* placed in vals[1] to vals[max_vals].
* 4. otherwise, zero is returned. * 4. otherwise, zero is returned.
*/ */
static int __init match_parm (char *s, const char *keywords[], int vals[], int max_vals) static int __init match_parm (char *s, const char *keywords[], int vals[], int max_vals)
{ {
static const char decimal[] = "0123456789"; int i;
static const char hex[] = "0123456789abcdef";
int i, n;
if (*s++ == '=') { if (*s++ == '=') {
/* /*
...@@ -683,23 +669,10 @@ static int __init match_parm (char *s, const char *keywords[], int vals[], int m ...@@ -683,23 +669,10 @@ static int __init match_parm (char *s, const char *keywords[], int vals[], int m
* or base16 when prefixed with "0x". * or base16 when prefixed with "0x".
* Return a count of how many were found. * Return a count of how many were found.
*/ */
for (n = 0; (i = stridx(decimal, *s)) >= 0;) { get_options(s, max_vals+1, vals);
vals[n] = i; return vals[0];
while ((i = stridx(decimal, *++s)) >= 0)
vals[n] = (vals[n] * 10) + i;
if (*s == 'x' && !vals[n]) {
while ((i = stridx(hex, *++s)) >= 0)
vals[n] = (vals[n] * 0x10) + i;
}
if (++n == max_vals)
break;
if (*s == ',' || *s == ';')
++s;
}
if (!*s)
return n;
} }
return 0; /* zero = nothing matched */ return 0;
} }
/* /*
...@@ -744,7 +717,7 @@ static void __init init_global_data(void) ...@@ -744,7 +717,7 @@ static void __init init_global_data(void)
*/ */
int __init ide_setup(char *s) int __init ide_setup(char *s)
{ {
int i, vals[3]; int i, vals[4];
struct ata_channel *ch; struct ata_channel *ch;
struct ata_device *drive; struct ata_device *drive;
unsigned int hw, unit; unsigned int hw, unit;
...@@ -755,7 +728,6 @@ int __init ide_setup(char *s) ...@@ -755,7 +728,6 @@ int __init ide_setup(char *s)
return 0; return 0;
if (strncmp(s,"ide",3) && if (strncmp(s,"ide",3) &&
strncmp(s,"idebus",6) &&
strncmp(s,"hd",2)) /* hdx= & hdxlun= */ strncmp(s,"hd",2)) /* hdx= & hdxlun= */
return 0; return 0;
...@@ -801,24 +773,24 @@ int __init ide_setup(char *s) ...@@ -801,24 +773,24 @@ int __init ide_setup(char *s)
unit = unit % MAX_DRIVES; unit = unit % MAX_DRIVES;
ch = &ide_hwifs[hw]; ch = &ide_hwifs[hw];
drive = &ch->drives[unit]; drive = &ch->drives[unit];
if (!strncmp(s + 4, "ide-", 4)) { if (!strncmp(s+3, "=ide-", 5)) {
strncpy(drive->driver_req, s + 4, 9); strncpy(drive->driver_req, s + 4, 9);
goto done; goto done;
} }
/* /*
* Look for last lun option: "hdxlun=" * Look for last lun option: "hdxlun="
*/ */
if (!strncmp(&s[3], "lun", 3)) { if (!strncmp(s+3, "lun=", 4)) {
if (match_parm(&s[6], NULL, vals, 1) != 1) if (*get_options(s+7, 2, vals) || vals[0]!=1)
goto bad_option; goto bad_option;
if (vals[0] >= 0 && vals[0] <= 7) { if (vals[1] >= 0 && vals[1] <= 7) {
drive->last_lun = vals[0]; drive->last_lun = vals[1];
drive->forced_lun = 1; drive->forced_lun = 1;
} else } else
printk(" -- BAD LAST LUN! Expected value from 0 to 7"); printk(" -- BAD LAST LUN! Expected value from 0 to 7");
goto done; goto done;
} }
switch (match_parm(&s[3], hd_words, vals, 3)) { switch (match_parm(s+3, hd_words, vals, 3)) {
case -1: /* "none" */ case -1: /* "none" */
drive->nobios = 1; /* drop into "noprobe" */ drive->nobios = 1; /* drop into "noprobe" */
case -2: /* "noprobe" */ case -2: /* "noprobe" */
...@@ -864,9 +836,9 @@ int __init ide_setup(char *s) ...@@ -864,9 +836,9 @@ int __init ide_setup(char *s)
#endif #endif
case 3: /* cyl,head,sect */ case 3: /* cyl,head,sect */
drive->type = ATA_DISK; drive->type = ATA_DISK;
drive->cyl = drive->bios_cyl = vals[0]; drive->cyl = drive->bios_cyl = vals[1];
drive->head = drive->bios_head = vals[1]; drive->head = drive->bios_head = vals[2];
drive->sect = drive->bios_sect = vals[2]; drive->sect = drive->bios_sect = vals[3];
drive->present = 1; drive->present = 1;
drive->forced_geom = 1; drive->forced_geom = 1;
ch->noprobe = 0; ch->noprobe = 0;
...@@ -879,10 +851,10 @@ int __init ide_setup(char *s) ...@@ -879,10 +851,10 @@ int __init ide_setup(char *s)
/* /*
* Look for bus speed option: "idebus=" * Look for bus speed option: "idebus="
*/ */
if (!strncmp(s, "idebus", 6)) { if (!strncmp(s, "idebus=", 7)) {
if (match_parm(&s[6], NULL, vals, 1) != 1) if (*get_options(s+7, 2, vals) || vals[0] != 1)
goto bad_option; goto bad_option;
idebus_parameter = vals[0]; idebus_parameter = vals[1];
goto done; goto done;
} }
...@@ -892,33 +864,72 @@ int __init ide_setup(char *s) ...@@ -892,33 +864,72 @@ int __init ide_setup(char *s)
if (!strncmp(s, "ide", 3) && s[3] >= '0' && s[3] <= max_ch) { if (!strncmp(s, "ide", 3) && s[3] >= '0' && s[3] <= max_ch) {
/* /*
* Be VERY CAREFUL changing this: note hardcoded indexes below * Be VERY CAREFUL changing this: note hardcoded indexes below
* -8,-9,-10. -11 : are reserved for future idex calls to ease the hardcoding.
*/ */
const char *ide_options[] = {
"noprobe", "serialize", "autotune", "noautotune", "reset", "dma", "ata66", NULL };
const char *ide_words[] = { const char *ide_words[] = {
"noprobe", "serialize", "autotune", "noautotune", "reset", "dma", "ata66",
"minus8", "minus9", "minus10", "minus11",
"qd65xx", "ht6560b", "cmd640_vlb", "dtc2278", "umc8672", "ali14xx", "dc4030", NULL }; "qd65xx", "ht6560b", "cmd640_vlb", "dtc2278", "umc8672", "ali14xx", "dc4030", NULL };
hw = s[3] - '0'; hw = s[3] - '0';
ch = &ide_hwifs[hw]; ch = &ide_hwifs[hw];
switch (match_parm(s+4, ide_options, vals, 1)) {
case -7: /* ata66 */
#ifdef CONFIG_PCI
ch->udma_four = 1;
goto done;
#else
ch->udma_four = 0;
goto bad_channel;
#endif
case -6: /* dma */
ch->autodma = 1;
goto done;
case -5: /* reset */
ch->reset = 1;
goto done;
case -4: /* noautotune */
ch->drives[0].autotune = 2;
ch->drives[1].autotune = 2;
goto done;
case -3: /* autotune */
ch->drives[0].autotune = 1;
ch->drives[1].autotune = 1;
goto done;
case -2: /* "serialize" */
do_serialize:
{
struct ata_channel *mate;
mate = &ide_hwifs[hw ^ 1];
ch->serialized = 1;
mate->serialized = 1;
}
goto done;
case -1: /* "noprobe" */
ch->noprobe = 1;
goto done;
}
i = match_parm(&s[4], ide_words, vals, 3); i = match_parm(&s[4], ide_words, vals, 3);
/* /*
* Cryptic check to ensure chipset not already set for a channel: * Cryptic check to ensure chipset not already set for a channel:
*/ */
if (i > 0 || i <= -11) { /* is parameter a chipset name? */ if (i) { /* is parameter a chipset name? */
if (ch->chipset != ide_unknown) if (ide_hwifs[hw].chipset != ide_unknown)
goto bad_option; /* chipset already specified */ goto bad_option; /* chipset already specified */
if (i <= -11 && i != -18 && hw != 0) if (i != -7 && hw != 0)
goto bad_channel; /* chipset drivers are for "ide0=" only */ goto bad_channel; /* chipset drivers are for "ide0=" only */
if (i <= -11 && i != -18 && ide_hwifs[hw+1].chipset != ide_unknown) if (i != -7 && ide_hwifs[1].chipset != ide_unknown)
goto bad_option; /* chipset for 2nd port already specified */ goto bad_option; /* chipset for 2nd port already specified */
printk("\n"); printk("\n");
} }
switch (i) { switch (i) {
#ifdef CONFIG_BLK_DEV_PDC4030 #ifdef CONFIG_BLK_DEV_PDC4030
case -18: /* "dc4030" */ case -7: /* "dc4030" */
{ {
extern void init_pdc4030(void); extern void init_pdc4030(void);
init_pdc4030(); init_pdc4030();
...@@ -926,7 +937,7 @@ int __init ide_setup(char *s) ...@@ -926,7 +937,7 @@ int __init ide_setup(char *s)
} }
#endif #endif
#ifdef CONFIG_BLK_DEV_ALI14XX #ifdef CONFIG_BLK_DEV_ALI14XX
case -17: /* "ali14xx" */ case -6: /* "ali14xx" */
{ {
extern void init_ali14xx (void); extern void init_ali14xx (void);
init_ali14xx(); init_ali14xx();
...@@ -934,7 +945,7 @@ int __init ide_setup(char *s) ...@@ -934,7 +945,7 @@ int __init ide_setup(char *s)
} }
#endif #endif
#ifdef CONFIG_BLK_DEV_UMC8672 #ifdef CONFIG_BLK_DEV_UMC8672
case -16: /* "umc8672" */ case -5: /* "umc8672" */
{ {
extern void init_umc8672 (void); extern void init_umc8672 (void);
init_umc8672(); init_umc8672();
...@@ -942,7 +953,7 @@ int __init ide_setup(char *s) ...@@ -942,7 +953,7 @@ int __init ide_setup(char *s)
} }
#endif #endif
#ifdef CONFIG_BLK_DEV_DTC2278 #ifdef CONFIG_BLK_DEV_DTC2278
case -15: /* "dtc2278" */ case -4: /* "dtc2278" */
{ {
extern void init_dtc2278 (void); extern void init_dtc2278 (void);
init_dtc2278(); init_dtc2278();
...@@ -950,7 +961,7 @@ int __init ide_setup(char *s) ...@@ -950,7 +961,7 @@ int __init ide_setup(char *s)
} }
#endif #endif
#ifdef CONFIG_BLK_DEV_CMD640 #ifdef CONFIG_BLK_DEV_CMD640
case -14: /* "cmd640_vlb" */ case -3: /* "cmd640_vlb" */
{ {
extern int cmd640_vlb; /* flag for cmd640.c */ extern int cmd640_vlb; /* flag for cmd640.c */
cmd640_vlb = 1; cmd640_vlb = 1;
...@@ -958,7 +969,7 @@ int __init ide_setup(char *s) ...@@ -958,7 +969,7 @@ int __init ide_setup(char *s)
} }
#endif #endif
#ifdef CONFIG_BLK_DEV_HT6560B #ifdef CONFIG_BLK_DEV_HT6560B
case -13: /* "ht6560b" */ case -2: /* "ht6560b" */
{ {
extern void init_ht6560b (void); extern void init_ht6560b (void);
init_ht6560b(); init_ht6560b();
...@@ -966,64 +977,22 @@ int __init ide_setup(char *s) ...@@ -966,64 +977,22 @@ int __init ide_setup(char *s)
} }
#endif #endif
#if CONFIG_BLK_DEV_QD65XX #if CONFIG_BLK_DEV_QD65XX
case -12: /* "qd65xx" */ case -1: /* "qd65xx" */
{ {
extern void init_qd65xx (void); extern void init_qd65xx (void);
init_qd65xx(); init_qd65xx();
goto done; goto done;
} }
#endif #endif
case -11: /* minus11 */
case -10: /* minus10 */
case -9: /* minus9 */
case -8: /* minus8 */
goto bad_option;
case -7: /* ata66 */
#ifdef CONFIG_PCI
ch->udma_four = 1;
goto done;
#else
ch->udma_four = 0;
goto bad_channel;
#endif
case -6: /* dma */
ch->autodma = 1;
goto done;
case -5: /* reset */
ch->reset = 1;
goto done;
case -4: /* noautotune */
ch->drives[0].autotune = 2;
ch->drives[1].autotune = 2;
goto done;
case -3: /* autotune */
ch->drives[0].autotune = 1;
ch->drives[1].autotune = 1;
goto done;
case -2: /* "serialize" */
do_serialize:
{
struct ata_channel *mate;
mate = &ide_hwifs[hw ^ 1];
ch->serialized = 1;
mate->serialized = 1;
}
goto done;
case -1: /* "noprobe" */
ch->noprobe = 1;
goto done;
case 1: /* base */ case 1: /* base */
vals[1] = vals[0] + 0x206; /* default ctl */ vals[2] = vals[1] + 0x206; /* default ctl */
case 2: /* base,ctl */ case 2: /* base,ctl */
vals[2] = 0; /* default irq = probe for it */ vals[3] = 0; /* default irq = probe for it */
case 3: /* base,ctl,irq */ case 3: /* base,ctl,irq */
ch->hw.irq = vals[2]; ch->hw.irq = vals[3];
ide_init_hwif_ports(&ch->hw, (ide_ioreg_t) vals[0], (ide_ioreg_t) vals[1], &ch->irq); ide_init_hwif_ports(&ch->hw, (ide_ioreg_t) vals[1], (ide_ioreg_t) vals[2], &ch->irq);
memcpy(ch->io_ports, ch->hw.io_ports, sizeof(ch->io_ports)); memcpy(ch->io_ports, ch->hw.io_ports, sizeof(ch->io_ports));
ch->irq = vals[2]; ch->irq = vals[3];
ch->noprobe = 0; ch->noprobe = 0;
ch->chipset = ide_generic; ch->chipset = ide_generic;
goto done; goto done;
......
...@@ -46,7 +46,7 @@ ide_startstop_t ide_dma_intr(struct ata_device *drive, struct request *rq) ...@@ -46,7 +46,7 @@ ide_startstop_t ide_dma_intr(struct ata_device *drive, struct request *rq)
if (ata_status(drive, DRIVE_READY, drive->bad_wstat | DRQ_STAT)) { if (ata_status(drive, DRIVE_READY, drive->bad_wstat | DRQ_STAT)) {
if (!dma_stat) { if (!dma_stat) {
__ata_end_request(drive, rq, 1, rq->nr_sectors); ata_end_request(drive, rq, 1, rq->nr_sectors);
return ATA_OP_FINISHED; return ATA_OP_FINISHED;
} }
...@@ -510,7 +510,7 @@ int udma_pci_irq_status(struct ata_device *drive) ...@@ -510,7 +510,7 @@ int udma_pci_irq_status(struct ata_device *drive)
void udma_pci_timeout(struct ata_device *drive) void udma_pci_timeout(struct ata_device *drive)
{ {
printk(KERN_ERR "ATA: UDMA timeout occured %s!\n", drive->name); printk(KERN_ERR "%s: UDMA timeout!\n", drive->name);
} }
void udma_pci_irq_lost(struct ata_device *drive) void udma_pci_irq_lost(struct ata_device *drive)
......
This diff is collapsed.
...@@ -415,7 +415,7 @@ static ide_startstop_t promise_read_intr(struct ata_device *drive, struct reques ...@@ -415,7 +415,7 @@ static ide_startstop_t promise_read_intr(struct ata_device *drive, struct reques
rq->nr_sectors -= nsect; rq->nr_sectors -= nsect;
total_remaining = rq->nr_sectors; total_remaining = rq->nr_sectors;
if ((rq->current_nr_sectors -= nsect) <= 0) if ((rq->current_nr_sectors -= nsect) <= 0)
__ata_end_request(drive, rq, 1, 0); ata_end_request(drive, rq, 1, 0);
/* /*
* Now the data has been read in, do the following: * Now the data has been read in, do the following:
...@@ -477,7 +477,7 @@ static ide_startstop_t promise_complete_pollfunc(struct ata_device *drive, struc ...@@ -477,7 +477,7 @@ static ide_startstop_t promise_complete_pollfunc(struct ata_device *drive, struc
#ifdef DEBUG_WRITE #ifdef DEBUG_WRITE
printk(KERN_DEBUG "%s: Write complete - end_request\n", drive->name); printk(KERN_DEBUG "%s: Write complete - end_request\n", drive->name);
#endif #endif
__ata_end_request(drive, rq, 1, rq->nr_sectors); ata_end_request(drive, rq, 1, rq->nr_sectors);
return ATA_OP_FINISHED; return ATA_OP_FINISHED;
} }
...@@ -629,7 +629,7 @@ ide_startstop_t do_pdc4030_io(struct ata_device *drive, struct ata_taskfile *arg ...@@ -629,7 +629,7 @@ ide_startstop_t do_pdc4030_io(struct ata_device *drive, struct ata_taskfile *arg
/* Check that it's a regular command. If not, bomb out early. */ /* Check that it's a regular command. If not, bomb out early. */
if (!(rq->flags & REQ_CMD)) { if (!(rq->flags & REQ_CMD)) {
blk_dump_rq_flags(rq, "pdc4030 bad flags"); blk_dump_rq_flags(rq, "pdc4030 bad flags");
__ata_end_request(drive, rq, 0, 0); ata_end_request(drive, rq, 0, 0);
return ATA_OP_FINISHED; return ATA_OP_FINISHED;
} }
...@@ -709,7 +709,7 @@ ide_startstop_t do_pdc4030_io(struct ata_device *drive, struct ata_taskfile *arg ...@@ -709,7 +709,7 @@ ide_startstop_t do_pdc4030_io(struct ata_device *drive, struct ata_taskfile *arg
default: default:
printk(KERN_ERR "pdc4030: command not READ or WRITE! Huh?\n"); printk(KERN_ERR "pdc4030: command not READ or WRITE! Huh?\n");
__ata_end_request(drive, rq, 0, 0); ata_end_request(drive, rq, 0, 0);
return ATA_OP_FINISHED; return ATA_OP_FINISHED;
} }
} }
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
Authors: Arjan van de Ven <arjanv@redhat.com> Authors: Arjan van de Ven <arjanv@redhat.com>
Based on work done by Sren Schmidt for FreeBSD Based on work done by Søren Schmidt for FreeBSD
*/ */
......
...@@ -97,11 +97,15 @@ int ide_xlate_1024(kdev_t i_rdev, int xparm, int ptheads, const char *msg) ...@@ -97,11 +97,15 @@ int ide_xlate_1024(kdev_t i_rdev, int xparm, int ptheads, const char *msg)
} }
} }
/* There used to be code here that assigned drive->id->CHS /* There used to be code here that assigned drive->id->CHS to
to drive->CHS and that to drive->bios_CHS. However, some disks have * drive->CHS and that to drive->bios_CHS. However, some disks have
id->C/H/S = 4092/16/63 but are larger than 2.1 GB. In such cases * id->C/H/S = 4092/16/63 but are larger than 2.1 GB. In such cases
that code was wrong. Moreover, there seems to be no reason to do * that code was wrong. Moreover, there seems to be no reason to do
any of these things. */ * any of these things.
*
* Please note that recent RedHat changes to the disk utils are bogous
* and will report spurious errors.
*/
/* translate? */ /* translate? */
if (drive->forced_geom) if (drive->forced_geom)
...@@ -169,8 +173,8 @@ int ide_xlate_1024(kdev_t i_rdev, int xparm, int ptheads, const char *msg) ...@@ -169,8 +173,8 @@ int ide_xlate_1024(kdev_t i_rdev, int xparm, int ptheads, const char *msg)
} }
/* /*
* hd_driveid data come as little endian, it needs to be converted on big * Drive ID data come as little endian, it needs to be converted on big endian
* endian machines. * machines.
*/ */
void ata_fix_driveid(struct hd_driveid *id) void ata_fix_driveid(struct hd_driveid *id)
{ {
...@@ -319,11 +323,8 @@ int ide_config_drive_speed(struct ata_device *drive, byte speed) ...@@ -319,11 +323,8 @@ int ide_config_drive_speed(struct ata_device *drive, byte speed)
outb(inb(ch->dma_base + 2) & ~(1 << (5 + unit)), ch->dma_base + 2); outb(inb(ch->dma_base + 2) & ~(1 << (5 + unit)), ch->dma_base + 2);
#endif #endif
/* Don't use ide_wait_cmd here - it will attempt to set_geometry and /*
* recalibrate, but for some reason these don't work at this point * Select the drive, and issue the SETFEATURES command.
* (lost interrupt).
*
* Select the drive, and issue the SETFEATURES command
*/ */
disable_irq(ch->irq); /* disable_irq_nosync ?? */ disable_irq(ch->irq); /* disable_irq_nosync ?? */
udelay(1); udelay(1);
...@@ -339,7 +340,6 @@ int ide_config_drive_speed(struct ata_device *drive, byte speed) ...@@ -339,7 +340,6 @@ int ide_config_drive_speed(struct ata_device *drive, byte speed)
udelay(1); udelay(1);
ret = ata_status_poll(drive, 0, BUSY_STAT, WAIT_CMD, NULL); ret = ata_status_poll(drive, 0, BUSY_STAT, WAIT_CMD, NULL);
ata_mask(drive); ata_mask(drive);
enable_irq(ch->irq); enable_irq(ch->irq);
if (ret != ATA_OP_READY) { if (ret != ATA_OP_READY) {
...@@ -1127,6 +1127,7 @@ static void channel_init(struct ata_channel *ch) ...@@ -1127,6 +1127,7 @@ static void channel_init(struct ata_channel *ch)
gd->sizes = kmalloc(ATA_MINORS * sizeof(int), GFP_KERNEL); gd->sizes = kmalloc(ATA_MINORS * sizeof(int), GFP_KERNEL);
if (!gd->sizes) if (!gd->sizes)
goto err_kmalloc_gd_sizes; goto err_kmalloc_gd_sizes;
memset(gd->sizes, 0, ATA_MINORS*sizeof(gd->sizes[0]));
gd->part = kmalloc(ATA_MINORS * sizeof(struct hd_struct), GFP_KERNEL); gd->part = kmalloc(ATA_MINORS * sizeof(struct hd_struct), GFP_KERNEL);
if (!gd->part) if (!gd->part)
......
...@@ -134,7 +134,6 @@ static void tcq_invalidate_queue(struct ata_device *drive) ...@@ -134,7 +134,6 @@ static void tcq_invalidate_queue(struct ata_device *drive)
ar->XXX_handler = tcq_nop_handler; ar->XXX_handler = tcq_nop_handler;
ar->command_type = IDE_DRIVE_TASK_NO_DATA; ar->command_type = IDE_DRIVE_TASK_NO_DATA;
rq->rq_dev = mk_kdev(drive->channel->major, (drive->select.b.unit)<<PARTN_BITS);
_elv_add_request(q, rq, 0, 0); _elv_add_request(q, rq, 0, 0);
out: out:
...@@ -359,7 +358,7 @@ static ide_startstop_t dmaq_complete(struct ata_device *drive, struct request *r ...@@ -359,7 +358,7 @@ static ide_startstop_t dmaq_complete(struct ata_device *drive, struct request *r
TCQ_PRINTK("%s: ending %p, tag %d\n", __FUNCTION__, rq, rq->tag); TCQ_PRINTK("%s: ending %p, tag %d\n", __FUNCTION__, rq, rq->tag);
__ata_end_request(drive, rq, !dma_stat, rq->nr_sectors); ata_end_request(drive, rq, !dma_stat, rq->nr_sectors);
/* /*
* we completed this command, check if we can service a new command * we completed this command, check if we can service a new command
......
...@@ -129,7 +129,7 @@ void __init init_umc8672(void) /* called from ide.c */ ...@@ -129,7 +129,7 @@ void __init init_umc8672(void) /* called from ide.c */
__save_flags(flags); /* local CPU only */ __save_flags(flags); /* local CPU only */
__cli(); /* local CPU only */ __cli(); /* local CPU only */
if (check_region(0x108, 2)) { if (!request_region(0x108, 2, "umc8672")) {
__restore_flags(flags); __restore_flags(flags);
printk("\numc8672: PORTS 0x108-0x109 ALREADY IN USE\n"); printk("\numc8672: PORTS 0x108-0x109 ALREADY IN USE\n");
return; return;
...@@ -138,6 +138,7 @@ void __init init_umc8672(void) /* called from ide.c */ ...@@ -138,6 +138,7 @@ void __init init_umc8672(void) /* called from ide.c */
if (in_umc (0xd5) != 0xa0) if (in_umc (0xd5) != 0xa0)
{ {
__restore_flags(flags); /* local CPU only */ __restore_flags(flags); /* local CPU only */
release_region(0x108, 2);
printk ("umc8672: not found\n"); printk ("umc8672: not found\n");
return; return;
} }
...@@ -146,7 +147,6 @@ void __init init_umc8672(void) /* called from ide.c */ ...@@ -146,7 +147,6 @@ void __init init_umc8672(void) /* called from ide.c */
umc_set_speeds (current_speeds); umc_set_speeds (current_speeds);
__restore_flags(flags); /* local CPU only */ __restore_flags(flags); /* local CPU only */
request_region(0x108, 2, "umc8672");
ide_hwifs[0].chipset = ide_umc8672; ide_hwifs[0].chipset = ide_umc8672;
ide_hwifs[1].chipset = ide_umc8672; ide_hwifs[1].chipset = ide_umc8672;
ide_hwifs[0].tuneproc = &tune_umc; ide_hwifs[0].tuneproc = &tune_umc;
......
...@@ -244,7 +244,7 @@ static int idescsi_end_request(struct ata_device *drive, struct request *rq, int ...@@ -244,7 +244,7 @@ static int idescsi_end_request(struct ata_device *drive, struct request *rq, int
u8 *scsi_buf; u8 *scsi_buf;
if (!(rq->flags & REQ_PC)) { if (!(rq->flags & REQ_PC)) {
__ata_end_request(drive, rq, uptodate, 0); ata_end_request(drive, rq, uptodate, 0);
return 0; return 0;
} }
...@@ -491,14 +491,13 @@ static void idescsi_release(struct inode *inode, struct file *filp, struct ata_d ...@@ -491,14 +491,13 @@ static void idescsi_release(struct inode *inode, struct file *filp, struct ata_d
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
} }
static Scsi_Host_Template template;
static int idescsi_cleanup (struct ata_device *drive) static int idescsi_cleanup (struct ata_device *drive)
{ {
struct Scsi_Host *host = drive->driver_data;
if (ide_unregister_subdriver (drive)) { if (ide_unregister_subdriver (drive)) {
return 1; return 1;
} }
scsi_unregister(host); scsi_unregister_host(&template);
return 0; return 0;
} }
...@@ -801,7 +800,6 @@ static int __init init_idescsi_module(void) ...@@ -801,7 +800,6 @@ static int __init init_idescsi_module(void)
static void __exit exit_idescsi_module(void) static void __exit exit_idescsi_module(void)
{ {
unregister_ata_driver(&ata_ops); unregister_ata_driver(&ata_ops);
scsi_unregister_host(&template);
} }
module_init(init_idescsi_module); module_init(init_idescsi_module);
......
...@@ -74,15 +74,6 @@ struct atapi_packet_command { ...@@ -74,15 +74,6 @@ struct atapi_packet_command {
} s; } s;
}; };
extern void atapi_init_pc(struct atapi_packet_command *pc);
extern void atapi_discard_data(struct ata_device *, unsigned int);
extern void atapi_write_zeros(struct ata_device *, unsigned int);
extern void atapi_read(struct ata_device *, u8 *, unsigned int);
extern void atapi_write(struct ata_device *, u8 *, unsigned int);
/* /*
* ATAPI Status Register. * ATAPI Status Register.
*/ */
...@@ -360,3 +351,20 @@ typedef struct atapi_request_sense { ...@@ -360,3 +351,20 @@ typedef struct atapi_request_sense {
u8 sk_specific[2]; /* Sense Key Specific */ u8 sk_specific[2]; /* Sense Key Specific */
u8 pad[2]; /* Padding to 20 bytes */ u8 pad[2]; /* Padding to 20 bytes */
} atapi_request_sense_result_t; } atapi_request_sense_result_t;
extern void atapi_init_pc(struct atapi_packet_command *pc);
extern void atapi_discard_data(struct ata_device *, unsigned int);
extern void atapi_write_zeros(struct ata_device *, unsigned int);
extern void atapi_read(struct ata_device *, u8 *, unsigned int);
extern void atapi_write(struct ata_device *, u8 *, unsigned int);
typedef enum {
ide_wait, /* insert rq at end of list, and wait for it */
ide_preempt, /* insert rq in front of current request */
ide_end /* insert rq at end of list, but don't wait for it */
} ide_action_t;
extern int ide_do_drive_cmd(struct ata_device *, struct request *, ide_action_t);
#ifndef _IDE_H #ifndef _IDE_H
#define _IDE_H #define _IDE_H
/* /*
* Copyright (C) 1994-2002 Linus Torvalds & authors * Copyright (C) 1994-2002 Linus Torvalds & authors
*/ */
...@@ -57,15 +58,14 @@ typedef unsigned char byte; /* used everywhere */ ...@@ -57,15 +58,14 @@ typedef unsigned char byte; /* used everywhere */
*/ */
#define ERROR_MAX 8 /* Max read/write errors per sector */ #define ERROR_MAX 8 /* Max read/write errors per sector */
#define ERROR_RESET 3 /* Reset controller every 4th retry */ #define ERROR_RESET 3 /* Reset controller every 4th retry */
#define ERROR_RECAL 1 /* Recalibrate every 2nd retry */
/* /*
* state flags * State flags.
*/ */
#define DMA_PIO_RETRY 1 /* retrying in PIO */ #define DMA_PIO_RETRY 1 /* retrying in PIO */
/* /*
* Definitions for accessing IDE controller registers * Definitions for accessing IDE controller registers.
*/ */
enum { enum {
...@@ -192,23 +192,21 @@ typedef enum { ...@@ -192,23 +192,21 @@ typedef enum {
* Structure to hold all information about the location of this port * Structure to hold all information about the location of this port
*/ */
typedef struct hw_regs_s { typedef struct hw_regs_s {
ide_ioreg_t io_ports[IDE_NR_PORTS]; /* task file registers */ ide_ioreg_t io_ports[IDE_NR_PORTS]; /* task file registers */
int irq; /* our irq number */ int irq; /* our irq number */
int dma; /* our dma entry */ int dma; /* our dma entry */
ide_ack_intr_t *ack_intr; /* acknowledge interrupt */ int (*ack_intr)(struct ata_channel *); /* acknowledge interrupt */
hwif_chipset_t chipset; hwif_chipset_t chipset;
} hw_regs_t; } hw_regs_t;
/* /*
* Set up hw_regs_t structure before calling ide_register_hw (optional) * Set up hw_regs_t structure before calling ide_register_hw (optional)
*/ */
void ide_setup_ports(hw_regs_t *hw, extern void ide_setup_ports(hw_regs_t *hw,
ide_ioreg_t base, ide_ioreg_t base, int *offsets,
int *offsets, ide_ioreg_t ctrl, ide_ioreg_t intr,
ide_ioreg_t ctrl, int (*ack_intr)(struct ata_channel *),
ide_ioreg_t intr, int irq);
ide_ack_intr_t *ack_intr,
int irq);
#include <asm/ide.h> #include <asm/ide.h>
...@@ -282,14 +280,10 @@ struct ata_device { ...@@ -282,14 +280,10 @@ struct ata_device {
unsigned int usage; /* current "open()" count for drive */ unsigned int usage; /* current "open()" count for drive */
char type; /* distingiush different devices: disk, cdrom, tape, floppy, ... */ char type; /* distingiush different devices: disk, cdrom, tape, floppy, ... */
/* NOTE: If we had proper separation between channel and host chip, we request_queue_t queue; /* per device request queue */
* could move this to the channel and many sync problems would
* magically just go away.
*/
request_queue_t queue; /* per device request queue */
struct request *rq; /* current request */ struct request *rq; /* current request */
unsigned long sleep; /* sleep until this time */ unsigned long sleep; /* sleep until this time */
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 */
...@@ -341,6 +335,7 @@ struct ata_device { ...@@ -341,6 +335,7 @@ struct ata_device {
void *driver_data; /* extra driver data */ void *driver_data; /* extra driver data */
devfs_handle_t de; /* directory for device */ devfs_handle_t de; /* directory for device */
char driver_req[10]; /* requests specific driver */ char driver_req[10]; /* requests specific driver */
int last_lun; /* last logical unit */ int last_lun; /* last logical unit */
...@@ -392,6 +387,7 @@ enum { ...@@ -392,6 +387,7 @@ enum {
enum { enum {
IDE_BUSY, /* awaiting an interrupt */ IDE_BUSY, /* awaiting an interrupt */
IDE_SLEEP, IDE_SLEEP,
IDE_PIO, /* PIO in progress */
IDE_DMA /* DMA in progress */ IDE_DMA /* DMA in progress */
}; };
...@@ -404,11 +400,15 @@ struct ata_channel { ...@@ -404,11 +400,15 @@ struct ata_channel {
*/ */
spinlock_t *lock; spinlock_t *lock;
unsigned long *active; /* active processing request */ unsigned long *active; /* active processing request */
ide_startstop_t (*handler)(struct ata_device *, struct request *); /* irq handler, if active */ ide_startstop_t (*handler)(struct ata_device *, struct request *); /* irq handler, if active */
/* FIXME: Only still used in PDC4030. Localize this code there by
* replacing with busy waits.
*/
struct timer_list timer; /* failsafe timer */ struct timer_list timer; /* failsafe timer */
ide_startstop_t (*expiry)(struct ata_device *, struct request *, unsigned long *); /* irq handler, if active */ ide_startstop_t (*expiry)(struct ata_device *, struct request *, unsigned long *); /* irq handler, if active */
unsigned long poll_timeout; /* timeout value during polled operations */ unsigned long poll_timeout; /* timeout value during polled operations */
struct ata_device *drive; /* last serviced drive */ struct ata_device *drive; /* last serviced drive */
...@@ -508,8 +508,6 @@ struct ata_channel { ...@@ -508,8 +508,6 @@ struct ata_channel {
extern int ide_register_hw(hw_regs_t *hw); extern int ide_register_hw(hw_regs_t *hw);
extern void ide_unregister(struct ata_channel *); extern void ide_unregister(struct ata_channel *);
struct ata_taskfile;
#define IDE_MAX_TAG 32 #define IDE_MAX_TAG 32
#ifdef CONFIG_BLK_DEV_IDE_TCQ #ifdef CONFIG_BLK_DEV_IDE_TCQ
...@@ -605,8 +603,7 @@ extern int noautodma; ...@@ -605,8 +603,7 @@ extern int noautodma;
#define DEVICE_NR(device) (minor(device) >> PARTN_BITS) #define DEVICE_NR(device) (minor(device) >> PARTN_BITS)
#include <linux/blk.h> #include <linux/blk.h>
extern int __ata_end_request(struct ata_device *, struct request *, int, unsigned int); extern int ata_end_request(struct ata_device *, struct request *, int, unsigned int);
extern void ata_set_handler(struct ata_device *drive, ata_handler_t handler, extern void ata_set_handler(struct ata_device *drive, ata_handler_t handler,
unsigned long timeout, ata_expiry_t expiry); unsigned long timeout, ata_expiry_t expiry);
...@@ -626,22 +623,11 @@ int ide_xlate_1024(kdev_t, int, int, const char *); ...@@ -626,22 +623,11 @@ int ide_xlate_1024(kdev_t, int, int, const char *);
*/ */
struct ata_device *get_info_ptr(kdev_t i_rdev); struct ata_device *get_info_ptr(kdev_t i_rdev);
/*
* "action" parameter type for ide_do_drive_cmd() below.
*/
typedef enum {
ide_wait, /* insert rq at end of list, and wait for it */
ide_preempt, /* insert rq in front of current request */
ide_end /* insert rq at end of list, but don't wait for it */
} ide_action_t;
/* /*
* temporarily mapping a (possible) highmem bio for PIO transfer * temporarily mapping a (possible) highmem bio for PIO transfer
*/ */
#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)
extern int ide_do_drive_cmd(struct ata_device *, struct request *, ide_action_t);
struct ata_taskfile { struct ata_taskfile {
struct hd_drive_task_hdr taskfile; struct hd_drive_task_hdr taskfile;
struct hd_drive_task_hdr hobfile; struct hd_drive_task_hdr hobfile;
...@@ -654,7 +640,6 @@ extern void ata_read(struct ata_device *, void *, unsigned int); ...@@ -654,7 +640,6 @@ extern void ata_read(struct ata_device *, void *, unsigned int);
extern void ata_write(struct ata_device *, void *, unsigned int); extern void ata_write(struct ata_device *, void *, unsigned int);
extern int ide_raw_taskfile(struct ata_device *, struct ata_taskfile *, char *); extern int ide_raw_taskfile(struct ata_device *, struct ata_taskfile *, char *);
extern void ide_fix_driveid(struct hd_driveid *id);
extern int ide_config_drive_speed(struct ata_device *, byte); extern int ide_config_drive_speed(struct ata_device *, byte);
extern byte eighty_ninty_three(struct ata_device *); extern byte eighty_ninty_three(struct ata_device *);
...@@ -803,13 +788,12 @@ extern spinlock_t ide_lock; ...@@ -803,13 +788,12 @@ extern spinlock_t ide_lock;
#define DRIVE_LOCK(drive) ((drive)->queue.queue_lock) #define DRIVE_LOCK(drive) ((drive)->queue.queue_lock)
extern int drive_is_ready(struct ata_device *drive);
/* Low level device access functions. */ /* Low level device access functions. */
extern void ata_select(struct ata_device *, unsigned long); extern void ata_select(struct ata_device *, unsigned long);
extern void ata_mask(struct ata_device *); extern void ata_mask(struct ata_device *);
extern int ata_status(struct ata_device *, u8, u8); extern int ata_status(struct ata_device *, u8, u8);
extern int ata_status_irq(struct ata_device *drive);
extern int ata_status_poll( struct ata_device *, u8, u8, extern int ata_status_poll( struct ata_device *, u8, u8,
unsigned long, struct request *rq); unsigned long, struct request *rq);
......
...@@ -610,6 +610,7 @@ ...@@ -610,6 +610,7 @@
#define PCI_DEVICE_ID_PROMISE_20268 0x4d68 #define PCI_DEVICE_ID_PROMISE_20268 0x4d68
#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_20271 0x6269
#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_20276 0x5275
#define PCI_DEVICE_ID_PROMISE_5300 0x5300 #define PCI_DEVICE_ID_PROMISE_5300 0x5300
......
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