#include <linux/seq_file.h>
#include <linux/device.h>
#include <linux/kmod.h>
-#include <linux/scatterlist.h>
#include <asm/byteorder.h>
#include <asm/irq.h>
return ide_stopped;
}
+EXPORT_SYMBOL(ide_error);
+
/**
* ide_abort - abort pending IDE operatins
* @drive: drive the error occurred on
* This differs fundamentally from ide_error because in
* this case the command is doing just fine when we
* blow it away.
- *
- * FIXME: need to fix locking corner cases
*/
ide_startstop_t ide_abort(ide_drive_t *drive, const char *msg)
{
ide_hwif_t *hwif;
struct request *rq;
- unsigned long flags;
- spin_lock_irqsave(&ide_lock, flags);
- if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL) {
- spin_unlock_irqrestore(&ide_lock, flags);
+ if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL)
return ide_stopped;
- }
+
hwif = HWIF(drive);
/* retry only "normal" I/O: */
if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK)) {
rq->errors = 1;
- spin_unlock_irqrestore(&ide_lock, flags);
ide_end_drive_cmd(drive, BUSY_STAT, 0);
return ide_stopped;
}
if (rq->flags & REQ_DRIVE_TASKFILE) {
rq->errors = 1;
- spin_unlock_irqrestore(&ide_lock, flags);
ide_end_drive_cmd(drive, BUSY_STAT, 0);
return ide_stopped;
}
rq->errors |= ERROR_RESET;
- spin_unlock_irqrestore(&ide_lock, flags);
DRIVER(drive)->end_request(drive, 0, 0);
return ide_stopped;
}
+EXPORT_SYMBOL(ide_abort);
+
/**
* ide_cmd - issue a simple drive command
* @drive: drive the command is for
* The drive must be selected beforehand.
*/
-static void ide_cmd (ide_drive_t *drive, u8 cmd, u8 nsect,
- ide_handler_t *handler)
+void ide_cmd (ide_drive_t *drive, u8 cmd, u8 nsect, ide_handler_t *handler)
{
ide_hwif_t *hwif = HWIF(drive);
if (IDE_CONTROL_REG)
ide_execute_command(drive, cmd, handler, WAIT_CMD, NULL);
}
+EXPORT_SYMBOL(ide_cmd);
+
/**
* drive_cmd_intr - drive command completion interrupt
* @drive: drive the completion interrupt occurred on
* the request
*/
-static ide_startstop_t drive_cmd_intr (ide_drive_t *drive)
+ide_startstop_t drive_cmd_intr (ide_drive_t *drive)
{
struct request *rq = HWGROUP(drive)->rq;
ide_hwif_t *hwif = HWIF(drive);
return ide_stopped;
}
+EXPORT_SYMBOL(drive_cmd_intr);
+
/**
* do_special - issue some special commands
* @drive: drive the command is for
* back.
*/
-static ide_startstop_t do_special (ide_drive_t *drive)
+ide_startstop_t do_special (ide_drive_t *drive)
{
special_t *s = &drive->special;
return DRIVER(drive)->special(drive);
}
-void ide_map_sg(ide_drive_t *drive, struct request *rq)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct scatterlist *sg = hwif->sg_table;
-
- if (hwif->sg_mapped) /* needed by ide-scsi */
- return;
-
- if ((rq->flags & REQ_DRIVE_TASKFILE) == 0) {
- hwif->sg_nents = blk_rq_map_sg(drive->queue, rq, sg);
- } else {
- sg_init_one(sg, rq->buffer, rq->nr_sectors * SECTOR_SIZE);
- hwif->sg_nents = 1;
- }
-}
-
-EXPORT_SYMBOL_GPL(ide_map_sg);
-
-void ide_init_sg_cmd(ide_drive_t *drive, struct request *rq)
-{
- ide_hwif_t *hwif = drive->hwif;
-
- hwif->nsect = hwif->nleft = rq->nr_sectors;
- hwif->cursg = hwif->cursg_ofs = 0;
-}
-
-EXPORT_SYMBOL_GPL(ide_init_sg_cmd);
+EXPORT_SYMBOL(do_special);
/**
* execute_drive_command - issue special drive command
* all commands to finish. Don't do this as that is due to change
*/
-static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
- struct request *rq)
+ide_startstop_t execute_drive_cmd (ide_drive_t *drive, struct request *rq)
{
ide_hwif_t *hwif = HWIF(drive);
if (rq->flags & REQ_DRIVE_TASKFILE) {
hwif->data_phase = args->data_phase;
- switch (hwif->data_phase) {
- case TASKFILE_MULTI_OUT:
- case TASKFILE_OUT:
- case TASKFILE_MULTI_IN:
- case TASKFILE_IN:
- ide_init_sg_cmd(drive, rq);
- ide_map_sg(drive, rq);
- default:
- break;
- }
-
if (args->tf_out_flags.all != 0)
return flagged_taskfile(drive, args);
return do_rw_taskfile(drive, args);
return ide_stopped;
}
+EXPORT_SYMBOL(execute_drive_cmd);
+
/**
* start_request - start of I/O and command issuing for IDE
*
* FIXME: this function needs a rename
*/
-static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
+ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
{
ide_startstop_t startstop;
sector_t block;
return ide_stopped;
}
+EXPORT_SYMBOL(start_request);
+
/**
* ide_stall_queue - pause an IDE device
* @drive: drive to stall
* the driver. This makes the driver much more friendlier to shared IRQs
* than previous designs, while remaining 100% (?) SMP safe and capable.
*/
-static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)
+/* --BenH: made non-static as ide-pmac.c uses it to kick the hwgroup back
+ * into life on wakeup from machine sleep.
+ */
+void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)
{
ide_drive_t *drive;
ide_hwif_t *hwif;
}
}
+EXPORT_SYMBOL(ide_do_request);
+
/*
* Passes the stuff to ide_do_request
*/
HWGROUP(drive)->rq = NULL;
rq->errors = 0;
-
- if (!rq->bio)
- goto out;
-
rq->sector = rq->bio->bi_sector;
rq->current_nr_sectors = bio_iovec(rq->bio)->bv_len >> 9;
rq->hard_cur_sectors = rq->current_nr_sectors;
- rq->buffer = bio_data(rq->bio);
-out:
+ if (rq->bio)
+ rq->buffer = NULL;
+
return ret;
}
spin_unlock_irqrestore(&ide_lock, flags);
}
+EXPORT_SYMBOL(ide_timer_expiry);
+
/**
* unexpected_intr - handle an unexpected IDE interrupt
* @irq: interrupt line
return IRQ_NONE;
}
- if (hwif->polling) {
- /* We took an interrupt during a polled drive retune.
- This should go away eventually when that code uses
- the polling logic like do_reset1 */
- spin_unlock_irqrestore(&ide_lock, flags);
- return IRQ_HANDLED;
- }
if ((handler = hwgroup->handler) == NULL ||
hwgroup->poll_timeout != 0) {
/*
return IRQ_HANDLED;
}
+EXPORT_SYMBOL(ide_intr);
+
/**
* ide_init_drive_cmd - initialize a drive command request
* @rq: request object
int where = ELEVATOR_INSERT_BACK, err;
int must_wait = (action == ide_wait || action == ide_head_wait);
+#ifdef CONFIG_BLK_DEV_PDC4030
+ /*
+ * FIXME: there should be a drive or hwif->special
+ * handler that points here by default, not hacks
+ * in the ide-io.c code
+ *
+ * FIXME2: That code breaks power management if used with
+ * this chipset, that really doesn't belong here !
+ */
+ if (HWIF(drive)->chipset == ide_pdc4030 && rq->buffer != NULL)
+ return -ENOSYS; /* special drive cmds not supported */
+#endif
rq->errors = 0;
rq->rq_status = RQ_ACTIVE;