Commit 6a0b3e79 authored by Martin Dalecki's avatar Martin Dalecki Committed by Linus Torvalds

[PATCH] 2.5.8-pre3 IDE 32

- Don't provide symbolic links in /proc/ide - they are redundant data.

- Try to use a more reasonable default capacity value in ata_capacity().

- Fix ata_put() ata_get() usage in ide_check_media_change().

- Small readability fixes to the option parsing code.

- Apply Vojtech Pavliks /proc PIIX output fix.

- Replace all occurrences of ide_wait_taskfile() with ide_raw_taskfile().  One
   duplicated code path fewer.
parent 78cb05eb
......@@ -386,23 +386,22 @@ static int idedisk_open (struct inode *inode, struct file *filp, ide_drive_t *dr
{
MOD_INC_USE_COUNT;
if (drive->removable && drive->usage == 1) {
struct hd_drive_task_hdr taskfile;
struct hd_drive_hob_hdr hobfile;
memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
struct ata_taskfile args;
check_disk_change(inode->i_rdev);
taskfile.command = WIN_DOORLOCK;
memset(&args, 0, sizeof(args));
args.taskfile.command = WIN_DOORLOCK;
ide_cmd_type_parser(&args);
/*
* Ignore the return code from door_lock,
* since the open() has already succeeded,
* and the door_lock is irrelevant at this point.
* Ignore the return code from door_lock, since the open() has
* already succeeded, and the door_lock is irrelevant at this
* point.
*/
if (drive->doorlocking &&
ide_wait_taskfile(drive, &taskfile, &hobfile, NULL))
if (drive->doorlocking && ide_raw_taskfile(drive, &args, NULL))
drive->doorlocking = 0;
}
return 0;
......@@ -410,33 +409,33 @@ static int idedisk_open (struct inode *inode, struct file *filp, ide_drive_t *dr
static int idedisk_flushcache(ide_drive_t *drive)
{
struct hd_drive_task_hdr taskfile;
struct hd_drive_hob_hdr hobfile;
struct ata_taskfile args;
memset(&args, 0, sizeof(args));
memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
if (drive->id->cfs_enable_2 & 0x2400)
taskfile.command = WIN_FLUSH_CACHE_EXT;
args.taskfile.command = WIN_FLUSH_CACHE_EXT;
else
taskfile.command = WIN_FLUSH_CACHE;
args.taskfile.command = WIN_FLUSH_CACHE;
return ide_wait_taskfile(drive, &taskfile, &hobfile, NULL);
ide_cmd_type_parser(&args);
return ide_raw_taskfile(drive, &args, NULL);
}
static void idedisk_release (struct inode *inode, struct file *filp, ide_drive_t *drive)
{
if (drive->removable && !drive->usage) {
struct hd_drive_task_hdr taskfile;
struct hd_drive_hob_hdr hobfile;
memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
struct ata_taskfile args;
invalidate_bdev(inode->i_bdev, 0);
taskfile.command = WIN_DOORUNLOCK;
memset(&args, 0, sizeof(args));
args.taskfile.command = WIN_DOORUNLOCK;
ide_cmd_type_parser(&args);
if (drive->doorlocking &&
ide_wait_taskfile(drive, &taskfile, &hobfile, NULL))
ide_raw_taskfile(drive, &args, NULL))
drive->doorlocking = 0;
}
if ((drive->id->cfs_enable_2 & 0x3000) && drive->wcache)
......@@ -601,7 +600,7 @@ static inline int idedisk_supports_host_protected_area(ide_drive_t *drive)
return flag;
}
#endif /* CONFIG_IDEDISK_STROKE */
#endif
/*
* Compute drive->capacity, the full capacity of the drive
......@@ -767,45 +766,50 @@ static void idedisk_pre_reset (ide_drive_t *drive)
static int smart_enable(ide_drive_t *drive)
{
struct hd_drive_task_hdr taskfile;
struct hd_drive_hob_hdr hobfile;
memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
taskfile.feature = SMART_ENABLE;
taskfile.low_cylinder = SMART_LCYL_PASS;
taskfile.high_cylinder = SMART_HCYL_PASS;
taskfile.command = WIN_SMART;
return ide_wait_taskfile(drive, &taskfile, &hobfile, NULL);
struct ata_taskfile args;
memset(&args, 0, sizeof(args));
args.taskfile.feature = SMART_ENABLE;
args.taskfile.low_cylinder = SMART_LCYL_PASS;
args.taskfile.high_cylinder = SMART_HCYL_PASS;
args.taskfile.command = WIN_SMART;
ide_cmd_type_parser(&args);
return ide_raw_taskfile(drive, &args, NULL);
}
static int get_smart_values(ide_drive_t *drive, byte *buf)
static int get_smart_values(ide_drive_t *drive, u8 *buf)
{
struct hd_drive_task_hdr taskfile;
struct hd_drive_hob_hdr hobfile;
memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
taskfile.feature = SMART_READ_VALUES;
taskfile.sector_count = 0x01;
taskfile.low_cylinder = SMART_LCYL_PASS;
taskfile.high_cylinder = SMART_HCYL_PASS;
taskfile.command = WIN_SMART;
struct ata_taskfile args;
memset(&args, 0, sizeof(args));
args.taskfile.feature = SMART_READ_VALUES;
args.taskfile.sector_count = 0x01;
args.taskfile.low_cylinder = SMART_LCYL_PASS;
args.taskfile.high_cylinder = SMART_HCYL_PASS;
args.taskfile.command = WIN_SMART;
ide_cmd_type_parser(&args);
smart_enable(drive);
return ide_wait_taskfile(drive, &taskfile, &hobfile, buf);
return ide_raw_taskfile(drive, &args, buf);
}
static int get_smart_thresholds(ide_drive_t *drive, byte *buf)
static int get_smart_thresholds(ide_drive_t *drive, u8 *buf)
{
struct hd_drive_task_hdr taskfile;
struct hd_drive_hob_hdr hobfile;
memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
taskfile.feature = SMART_READ_THRESHOLDS;
taskfile.sector_count = 0x01;
taskfile.low_cylinder = SMART_LCYL_PASS;
taskfile.high_cylinder = SMART_HCYL_PASS;
taskfile.command = WIN_SMART;
struct ata_taskfile args;
memset(&args, 0, sizeof(args));
args.taskfile.feature = SMART_READ_THRESHOLDS;
args.taskfile.sector_count = 0x01;
args.taskfile.low_cylinder = SMART_LCYL_PASS;
args.taskfile.high_cylinder = SMART_HCYL_PASS;
args.taskfile.command = WIN_SMART;
ide_cmd_type_parser(&args);
smart_enable(drive);
return ide_wait_taskfile(drive, &taskfile, &hobfile, buf);
return ide_raw_taskfile(drive, &args, buf);
}
static int proc_idedisk_read_cache
......@@ -947,7 +951,7 @@ static int set_multcount(ide_drive_t *drive, int arg)
ide_init_drive_cmd (&rq);
drive->mult_req = arg;
drive->special.b.set_multmode = 1;
(void) ide_do_drive_cmd (drive, &rq, ide_wait);
ide_do_drive_cmd (drive, &rq, ide_wait);
return (drive->mult_count == arg) ? 0 : -EIO;
}
......@@ -963,44 +967,46 @@ static int set_nowerr(ide_drive_t *drive, int arg)
static int write_cache(ide_drive_t *drive, int arg)
{
struct hd_drive_task_hdr taskfile;
struct hd_drive_hob_hdr hobfile;
memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
taskfile.feature = (arg) ? SETFEATURES_EN_WCACHE : SETFEATURES_DIS_WCACHE;
taskfile.command = WIN_SETFEATURES;
struct ata_taskfile args;
if (!(drive->id->cfs_enable_2 & 0x3000))
return 1;
ide_wait_taskfile(drive, &taskfile, &hobfile, NULL);
memset(&args, 0, sizeof(args));
args.taskfile.feature = (arg) ? SETFEATURES_EN_WCACHE : SETFEATURES_DIS_WCACHE;
args.taskfile.command = WIN_SETFEATURES;
ide_cmd_type_parser(&args);
ide_raw_taskfile(drive, &args, NULL);
drive->wcache = arg;
return 0;
}
static int idedisk_standby(ide_drive_t *drive)
{
struct hd_drive_task_hdr taskfile;
struct hd_drive_hob_hdr hobfile;
memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
taskfile.command = WIN_STANDBYNOW1;
return ide_wait_taskfile(drive, &taskfile, &hobfile, NULL);
struct ata_taskfile args;
memset(&args, 0, sizeof(args));
args.taskfile.command = WIN_STANDBYNOW1;
ide_cmd_type_parser(&args);
return ide_raw_taskfile(drive, &args, NULL);
}
static int set_acoustic(ide_drive_t *drive, int arg)
{
struct hd_drive_task_hdr taskfile;
struct hd_drive_hob_hdr hobfile;
memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
struct ata_taskfile args;
taskfile.feature = (arg)?SETFEATURES_EN_AAM:SETFEATURES_DIS_AAM;
taskfile.sector_count = arg;
memset(&args, 0, sizeof(args));
args.taskfile.feature = (arg)?SETFEATURES_EN_AAM:SETFEATURES_DIS_AAM;
args.taskfile.sector_count = arg;
args.taskfile.command = WIN_SETFEATURES;
ide_cmd_type_parser(&args);
ide_raw_taskfile(drive, &args, NULL);
taskfile.command = WIN_SETFEATURES;
ide_wait_taskfile(drive, &taskfile, &hobfile, NULL);
drive->acoustic = arg;
return 0;
}
......
/*
* linux/drivers/ide/ide-proc.c Version 1.03 January 2, 1998
*
* Copyright (C) 1997-1998 Mark Lord
*/
/*
*
* This is the /proc/ide/ filesystem implementation.
*
* The major reason this exists is to provide sufficient access
......@@ -176,26 +172,26 @@ static int proc_ide_read_channel
PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
}
static int proc_ide_get_identify(ide_drive_t *drive, byte *buf)
static int get_identify(ide_drive_t *drive, u8 *buf)
{
struct hd_drive_task_hdr taskfile;
struct hd_drive_hob_hdr hobfile;
memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
struct ata_taskfile args;
taskfile.sector_count = 0x01;
taskfile.command = (drive->type == ATA_DISK) ? WIN_IDENTIFY : WIN_PIDENTIFY ;
memset(&args, 0, sizeof(args));
args.taskfile.sector_count = 0x01;
args.taskfile.command = (drive->type == ATA_DISK) ? WIN_IDENTIFY : WIN_PIDENTIFY ;
ide_cmd_type_parser(&args);
return ide_wait_taskfile(drive, &taskfile, &hobfile, buf);
return ide_raw_taskfile(drive, &args, buf);
}
static int proc_ide_read_identify
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
ide_drive_t *drive = data;
int len = 0, i = 0;
ide_drive_t *drive = data;
int len = 0;
int i = 0;
if (drive && !proc_ide_get_identify(drive, page)) {
if (drive && !get_identify(drive, page)) {
unsigned short *val = (unsigned short *) page;
char *out = ((char *)val) + (SECTOR_WORDS * 4);
page = out;
......@@ -204,8 +200,7 @@ static int proc_ide_read_identify
val += 1;
} while (i < (SECTOR_WORDS * 2));
len = out - page;
}
else
} else
len = sprintf(page, "\n");
PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
}
......@@ -422,6 +417,8 @@ void ide_remove_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t *p)
}
}
/* FIXME: we should iterate over the hwifs here as everywhere else.
*/
static void create_proc_ide_drives(struct ata_channel *hwif)
{
int d;
......@@ -447,8 +444,6 @@ static void create_proc_ide_drives(struct ata_channel *hwif)
}
}
sprintf(name,"ide%d/%s", (drive->name[2]-'a')/2, drive->name);
ent = proc_symlink(drive->name, proc_ide_root, name);
if (!ent) return;
}
}
......
......@@ -891,39 +891,6 @@ void init_taskfile_request(struct request *rq)
rq->flags = REQ_DRIVE_TASKFILE;
}
/*
* This is kept for internal use only !!!
* This is an internal call and nobody in user-space has a
* reason to call this taskfile.
*
* ide_raw_taskfile is the one that user-space executes.
*/
int ide_wait_taskfile(ide_drive_t *drive, struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile, byte *buf)
{
struct request rq;
struct ata_request ar;
struct ata_taskfile *args = &ar.ar_task;
ata_ar_init(drive, &ar);
memcpy(&args->taskfile, taskfile, sizeof(*taskfile));
if (hobfile)
memcpy(&args->hobfile, hobfile, sizeof(*hobfile));
init_taskfile_request(&rq);
/* This is kept for internal use only !!! */
ide_cmd_type_parser(args);
if (args->command_type != IDE_DRIVE_TASK_NO_DATA)
rq.current_nr_sectors = rq.nr_sectors = (hobfile->sector_count << 8) | taskfile->sector_count;
rq.buffer = buf;
rq.special = &ar;
return ide_do_drive_cmd(drive, &rq, ide_wait);
}
int ide_raw_taskfile(ide_drive_t *drive, struct ata_taskfile *args, byte *buf)
{
struct request rq;
......@@ -932,6 +899,7 @@ int ide_raw_taskfile(ide_drive_t *drive, struct ata_taskfile *args, byte *buf)
ata_ar_init(drive, &ar);
init_taskfile_request(&rq);
rq.buffer = buf;
memcpy(&ar.ar_task, args, sizeof(*args));
if (args->command_type != IDE_DRIVE_TASK_NO_DATA)
......@@ -1022,7 +990,7 @@ int ide_cmd_ioctl(ide_drive_t *drive, struct inode *inode, struct file *file, un
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, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
int err = 0;
u8 args[7];
......@@ -1051,15 +1019,14 @@ EXPORT_SYMBOL(atapi_input_bytes);
EXPORT_SYMBOL(atapi_output_bytes);
EXPORT_SYMBOL(taskfile_input_data);
EXPORT_SYMBOL(taskfile_output_data);
EXPORT_SYMBOL(ata_taskfile);
EXPORT_SYMBOL(ata_taskfile);
EXPORT_SYMBOL(recal_intr);
EXPORT_SYMBOL(set_geometry_intr);
EXPORT_SYMBOL(set_multmode_intr);
EXPORT_SYMBOL(task_no_data_intr);
EXPORT_SYMBOL(ide_wait_taskfile);
EXPORT_SYMBOL(ide_raw_taskfile);
EXPORT_SYMBOL(ide_cmd_type_parser);
EXPORT_SYMBOL(ide_cmd_ioctl);
EXPORT_SYMBOL(ide_task_ioctl);
......@@ -396,11 +396,9 @@ ide_startstop_t ide_dmaq_intr(ide_drive_t *drive)
*/
static int ide_tcq_configure(ide_drive_t *drive)
{
struct hd_drive_task_hdr taskfile;
struct ata_taskfile args;
int tcq_supp = 1 << 1 | 1 << 14;
memset(&taskfile, 0, sizeof(taskfile));
/*
* bit 14 and 1 must be set in word 83 of the device id to indicate
* support for dma queued protocol
......@@ -410,9 +408,12 @@ static int ide_tcq_configure(ide_drive_t *drive)
return 1;
}
taskfile.feature = SETFEATURES_EN_WCACHE;
taskfile.command = WIN_SETFEATURES;
if (ide_wait_taskfile(drive, &taskfile, NULL, NULL)) {
memset(&args, 0, sizeof(args));
args.taskfile.feature = SETFEATURES_EN_WCACHE;
args.taskfile.command = WIN_SETFEATURES;
ide_cmd_type_parser(&args);
if (ide_raw_taskfile(drive, &args, NULL)) {
printk("%s: failed to enable write cache\n", drive->name);
return 1;
}
......@@ -421,9 +422,12 @@ static int ide_tcq_configure(ide_drive_t *drive)
* disable RELease interrupt, it's quicker to poll this after
* having sent the command opcode
*/
taskfile.feature = SETFEATURES_DIS_RI;
taskfile.command = WIN_SETFEATURES;
if (ide_wait_taskfile(drive, &taskfile, NULL, NULL)) {
memset(&args, 0, sizeof(args));
args.taskfile.feature = SETFEATURES_DIS_RI;
args.taskfile.command = WIN_SETFEATURES;
ide_cmd_type_parser(&args);
if (ide_raw_taskfile(drive, &args, NULL)) {
printk("%s: disabling release interrupt fail\n", drive->name);
return 1;
}
......@@ -432,9 +436,12 @@ static int ide_tcq_configure(ide_drive_t *drive)
/*
* enable SERVICE interrupt
*/
taskfile.feature = SETFEATURES_EN_SI;
taskfile.command = WIN_SETFEATURES;
if (ide_wait_taskfile(drive, &taskfile, NULL, NULL)) {
memset(&args, 0, sizeof(args));
args.taskfile.feature = SETFEATURES_EN_SI;
args.taskfile.command = WIN_SETFEATURES;
ide_cmd_type_parser(&args);
if (ide_raw_taskfile(drive, &args, NULL)) {
printk("%s: enabling service interrupt fail\n", drive->name);
return 1;
}
......
This diff is collapsed.
......@@ -199,7 +199,7 @@ static int piix_get_info(char *buffer, char **addr, off_t offset, int count)
if (~piix_config->flags & PIIX_VICTORY) {
if ((piix_config->flags & PIIX_UDMA) >= PIIX_UDMA_66 && (u & (1 << i))) umul = 2;
if ((piix_config->flags & PIIX_UDMA) >= PIIX_UDMA_100 && (u & ((1 << i) + 12))) umul = 1;
if ((piix_config->flags & PIIX_UDMA) >= PIIX_UDMA_100 && (u & (1 << (i + 12)))) umul = 1;
udma[i] = (4 - ((e >> (i << 2)) & 3)) * umul;
} else udma[i] = (8 - ((e >> (i << 2)) & 7)) * 2;
......
......@@ -858,16 +858,14 @@ extern ide_startstop_t set_geometry_intr(ide_drive_t *drive);
extern ide_startstop_t set_multmode_intr(ide_drive_t *drive);
extern ide_startstop_t task_no_data_intr(ide_drive_t *drive);
int ide_wait_taskfile (ide_drive_t *drive, struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile, byte *buf);
int ide_raw_taskfile (ide_drive_t *drive, struct ata_taskfile *cmd, byte *buf);
/* This is setting up all fields in args, which depend upon the command type.
*/
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);
int ide_cmd_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, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
extern int ide_cmd_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, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
void ide_delay_50ms (void);
......
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