Commit 3e11aea0 authored by Martin Dalecki's avatar Martin Dalecki Committed by Linus Torvalds

[PATCH] 2.5.8-pre3 IDE 33

- Kill unneded parameters to ide_cmd_ioctl() and ide_task_ioctl().

- Apply Petr Vendrovecs fix for 32bit ver 16bit transfers.

- Make CD-ROM usable again by guarding the generic routines against request
   field abuse found there. We will try to convert this driver to the just to be
   finished struct ata_request after the generic changes stabilize a bit.
   The strcut ata_taskfile and struct ata_request merge to be more preciese.
parent 6a0b3e79
...@@ -512,7 +512,7 @@ void cdrom_analyze_sense_data(ide_drive_t *drive, ...@@ -512,7 +512,7 @@ void cdrom_analyze_sense_data(ide_drive_t *drive,
#endif /* not VERBOSE_IDE_CD_ERRORS */ #endif /* not VERBOSE_IDE_CD_ERRORS */
} }
static void cdrom_queue_request_sense(ide_drive_t *drive, static void cdrom_queue_request_sense(ide_drive_t *drive,
struct completion *wait, struct completion *wait,
struct request_sense *sense, struct request_sense *sense,
struct packet_command *failed_command) struct packet_command *failed_command)
...@@ -536,7 +536,7 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, ...@@ -536,7 +536,7 @@ static void cdrom_queue_request_sense(ide_drive_t *drive,
rq->flags = REQ_SENSE; rq->flags = REQ_SENSE;
rq->special = (char *) pc; rq->special = (char *) pc;
rq->waiting = wait; rq->waiting = wait;
(void) ide_do_drive_cmd(drive, rq, ide_preempt); ide_do_drive_cmd(drive, rq, ide_preempt);
} }
...@@ -554,6 +554,7 @@ static void cdrom_end_request(ide_drive_t *drive, int uptodate) ...@@ -554,6 +554,7 @@ static void cdrom_end_request(ide_drive_t *drive, int uptodate)
if ((rq->flags & REQ_CMD) && !rq->current_nr_sectors) if ((rq->flags & REQ_CMD) && !rq->current_nr_sectors)
uptodate = 1; uptodate = 1;
HWGROUP(drive)->rq->special = NULL;
ide_end_request(drive, uptodate); ide_end_request(drive, uptodate);
} }
......
...@@ -546,6 +546,12 @@ int ide_start_dma(struct ata_channel *hwif, ide_drive_t *drive, ide_dma_action_t ...@@ -546,6 +546,12 @@ int ide_start_dma(struct ata_channel *hwif, ide_drive_t *drive, ide_dma_action_t
unsigned long dma_base = hwif->dma_base; unsigned long dma_base = hwif->dma_base;
struct ata_request *ar = IDE_CUR_AR(drive); struct ata_request *ar = IDE_CUR_AR(drive);
/* This can happen with drivers abusing the special request field.
*/
if (!ar)
return 1;
if (rq_data_dir(ar->ar_rq) == READ) if (rq_data_dir(ar->ar_rq) == READ)
reading = 1 << 3; reading = 1 << 3;
......
...@@ -195,6 +195,9 @@ static inline void do_identify (ide_drive_t *drive, byte cmd) ...@@ -195,6 +195,9 @@ static inline void do_identify (ide_drive_t *drive, byte cmd)
#ifndef CONFIG_BLK_DEV_IDE_TCQ #ifndef CONFIG_BLK_DEV_IDE_TCQ
drive->queue_depth = 1; drive->queue_depth = 1;
#else #else
# ifndef CONFIG_BLK_DEV_IDE_TCQ_DEPTH
# define CONFIG_BLK_DEV_IDE_TCQ_DEPTH 1
# endif
drive->queue_depth = drive->id->queue_depth + 1; drive->queue_depth = drive->id->queue_depth + 1;
if (drive->queue_depth > CONFIG_BLK_DEV_IDE_TCQ_DEPTH) if (drive->queue_depth > CONFIG_BLK_DEV_IDE_TCQ_DEPTH)
drive->queue_depth = CONFIG_BLK_DEV_IDE_TCQ_DEPTH; drive->queue_depth = CONFIG_BLK_DEV_IDE_TCQ_DEPTH;
......
...@@ -311,6 +311,7 @@ static ide_startstop_t pre_task_mulout_intr(ide_drive_t *drive, struct request * ...@@ -311,6 +311,7 @@ static ide_startstop_t pre_task_mulout_intr(ide_drive_t *drive, struct request *
static ide_startstop_t task_mulout_intr (ide_drive_t *drive) static ide_startstop_t task_mulout_intr (ide_drive_t *drive)
{ {
byte stat = GET_STAT(); byte stat = GET_STAT();
/* FIXME: this should go possible as well */
byte io_32bit = drive->io_32bit; byte io_32bit = drive->io_32bit;
struct request *rq = &HWGROUP(drive)->wrq; struct request *rq = &HWGROUP(drive)->wrq;
ide_hwgroup_t *hwgroup = HWGROUP(drive); ide_hwgroup_t *hwgroup = HWGROUP(drive);
...@@ -612,6 +613,7 @@ static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, struct request *rq) ...@@ -612,6 +613,7 @@ static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, struct request *rq)
static ide_startstop_t task_out_intr(ide_drive_t *drive) static ide_startstop_t task_out_intr(ide_drive_t *drive)
{ {
byte stat = GET_STAT(); byte stat = GET_STAT();
/* FIXME: this should go possible as well */
byte io_32bit = drive->io_32bit; byte io_32bit = drive->io_32bit;
struct request *rq = HWGROUP(drive)->rq; struct request *rq = HWGROUP(drive)->rq;
char *pBuf = NULL; char *pBuf = NULL;
...@@ -628,7 +630,7 @@ static ide_startstop_t task_out_intr(ide_drive_t *drive) ...@@ -628,7 +630,7 @@ static ide_startstop_t task_out_intr(ide_drive_t *drive)
rq = HWGROUP(drive)->rq; rq = HWGROUP(drive)->rq;
pBuf = ide_map_rq(rq, &flags); pBuf = ide_map_rq(rq, &flags);
DTF("write: %p, rq->current_nr_sectors: %d\n", pBuf, (int) rq->current_nr_sectors); DTF("write: %p, rq->current_nr_sectors: %d\n", pBuf, (int) rq->current_nr_sectors);
drive->io_32bit = 0;
taskfile_output_data(drive, pBuf, SECTOR_WORDS); taskfile_output_data(drive, pBuf, SECTOR_WORDS);
ide_unmap_rq(rq, pBuf, &flags); ide_unmap_rq(rq, pBuf, &flags);
drive->io_32bit = io_32bit; drive->io_32bit = io_32bit;
...@@ -647,6 +649,7 @@ static ide_startstop_t task_mulin_intr(ide_drive_t *drive) ...@@ -647,6 +649,7 @@ static ide_startstop_t task_mulin_intr(ide_drive_t *drive)
{ {
unsigned int msect, nsect; unsigned int msect, nsect;
byte stat = GET_STAT(); byte stat = GET_STAT();
/* FIXME: this should go possible as well */
byte io_32bit = drive->io_32bit; byte io_32bit = drive->io_32bit;
struct request *rq = HWGROUP(drive)->rq; struct request *rq = HWGROUP(drive)->rq;
char *pBuf = NULL; char *pBuf = NULL;
...@@ -913,68 +916,76 @@ int ide_raw_taskfile(ide_drive_t *drive, struct ata_taskfile *args, byte *buf) ...@@ -913,68 +916,76 @@ int ide_raw_taskfile(ide_drive_t *drive, struct ata_taskfile *args, byte *buf)
} }
/* /*
* Issue ATA command and wait for completion. Use for implementing commands in * Implement generic ioctls invoked from userspace to imlpement specific
* kernel. * functionality.
*
* FIXME:
*
* 1. Rewrite hdparm to use the ide_task_ioctl function.
* *
* The caller has to make sure buf is never NULL! * 2. Publish it.
*
* 3. Kill this and HDIO_DRIVE_CMD alltogether.
*/ */
static int ide_wait_cmd(ide_drive_t *drive, u8 cmd, u8 nsect, u8 feature, u8 sectors, u8 *argbuf)
{
struct request rq;
/* FIXME: Do we really have to zero out the buffer?
*/
memset(argbuf, 0, 4 + SECTOR_WORDS * 4 * sectors);
ide_init_drive_cmd(&rq);
rq.buffer = argbuf;
argbuf[0] = cmd;
argbuf[1] = nsect;
argbuf[2] = feature;
argbuf[3] = sectors;
return ide_do_drive_cmd(drive, &rq, ide_wait); int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)
}
int ide_cmd_ioctl(ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{ {
int err = 0; int err = 0;
u8 args[4]; u8 vals[4];
u8 *argbuf = args; u8 *argbuf = vals;
byte xfer_rate = 0; byte xfer_rate = 0;
int argsize = 4; int argsize = 4;
/* FIXME: this should not reside on the stack */ struct ata_taskfile args;
struct ata_taskfile tfargs; struct request rq;
/*
* First phase.
*/
if (NULL == (void *) arg) { if (NULL == (void *) arg) {
struct request rq; struct request rq;
ide_init_drive_cmd(&rq); ide_init_drive_cmd(&rq);
return ide_do_drive_cmd(drive, &rq, ide_wait); return ide_do_drive_cmd(drive, &rq, ide_wait);
} }
if (copy_from_user(args, (void *)arg, 4))
/*
* Second phase.
*/
if (copy_from_user(vals, (void *)arg, 4))
return -EFAULT; return -EFAULT;
tfargs.taskfile.feature = args[2]; args.taskfile.feature = vals[2];
tfargs.taskfile.sector_count = args[3]; args.taskfile.sector_count = vals[3];
tfargs.taskfile.sector_number = args[1]; args.taskfile.sector_number = vals[1];
tfargs.taskfile.low_cylinder = 0x00; args.taskfile.low_cylinder = 0x00;
tfargs.taskfile.high_cylinder = 0x00; args.taskfile.high_cylinder = 0x00;
tfargs.taskfile.device_head = 0x00; args.taskfile.device_head = 0x00;
tfargs.taskfile.command = args[0]; args.taskfile.command = vals[0];
if (args[3]) { if (vals[3]) {
argsize = 4 + (SECTOR_WORDS * 4 * args[3]); argsize = 4 + (SECTOR_WORDS * 4 * vals[3]);
argbuf = kmalloc(argsize, GFP_KERNEL); argbuf = kmalloc(argsize, GFP_KERNEL);
if (argbuf == NULL) if (argbuf == NULL)
return -ENOMEM; return -ENOMEM;
memcpy(argbuf, args, 4); memcpy(argbuf, vals, 4);
} }
if (set_transfer(drive, &tfargs)) {
xfer_rate = args[1]; if (set_transfer(drive, &args)) {
if (ide_ata66_check(drive, &tfargs)) xfer_rate = vals[1];
if (ide_ata66_check(drive, &args))
goto abort; goto abort;
} }
err = ide_wait_cmd(drive, args[0], args[1], args[2], args[3], argbuf); /* Issue ATA command and wait for completion.
*/
/* FIXME: Do we really have to zero out the buffer?
*/
memset(argbuf, 0, 4 + SECTOR_WORDS * 4 * vals[3]);
ide_init_drive_cmd(&rq);
rq.buffer = argbuf;
memcpy(argbuf, vals, 4);
err = ide_do_drive_cmd(drive, &rq, ide_wait);
if (!err && xfer_rate) { if (!err && xfer_rate) {
/* active-retuning-calls future */ /* active-retuning-calls future */
...@@ -987,10 +998,11 @@ int ide_cmd_ioctl(ide_drive_t *drive, struct inode *inode, struct file *file, un ...@@ -987,10 +998,11 @@ int ide_cmd_ioctl(ide_drive_t *drive, struct inode *inode, struct file *file, un
err = -EFAULT; err = -EFAULT;
if (argsize > 4) if (argsize > 4)
kfree(argbuf); kfree(argbuf);
return err; return err;
} }
int ide_task_ioctl(ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) int ide_task_ioctl(ide_drive_t *drive, unsigned long arg)
{ {
int err = 0; int err = 0;
u8 args[7]; u8 args[7];
......
...@@ -2640,12 +2640,12 @@ static int ide_ioctl (struct inode *inode, struct file *file, ...@@ -2640,12 +2640,12 @@ static int ide_ioctl (struct inode *inode, struct file *file,
case HDIO_DRIVE_CMD: case HDIO_DRIVE_CMD:
if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
return -EACCES; return -EACCES;
return ide_cmd_ioctl(drive, inode, file, cmd, arg); return ide_cmd_ioctl(drive, arg);
case HDIO_DRIVE_TASK: case HDIO_DRIVE_TASK:
if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
return -EACCES; return -EACCES;
return ide_task_ioctl(drive, inode, file, cmd, arg); return ide_task_ioctl(drive, arg);
case HDIO_SET_NICE: case HDIO_SET_NICE:
if (!capable(CAP_SYS_ADMIN)) return -EACCES; if (!capable(CAP_SYS_ADMIN)) return -EACCES;
......
...@@ -864,10 +864,10 @@ extern ide_startstop_t task_no_data_intr(ide_drive_t *drive); ...@@ -864,10 +864,10 @@ extern ide_startstop_t task_no_data_intr(ide_drive_t *drive);
extern void ide_cmd_type_parser(struct ata_taskfile *args); extern void ide_cmd_type_parser(struct ata_taskfile *args);
extern int ide_raw_taskfile(ide_drive_t *drive, struct ata_taskfile *cmd, byte *buf); extern int ide_raw_taskfile(ide_drive_t *drive, struct ata_taskfile *cmd, byte *buf);
extern int ide_cmd_ioctl(ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); extern int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg);
extern int ide_task_ioctl(ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); extern int ide_task_ioctl(ide_drive_t *drive, unsigned long arg);
void ide_delay_50ms (void); void ide_delay_50ms(void);
byte ide_auto_reduce_xfer (ide_drive_t *drive); byte ide_auto_reduce_xfer (ide_drive_t *drive);
int ide_driveid_update (ide_drive_t *drive); int ide_driveid_update (ide_drive_t *drive);
......
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