* 2.6.4-rc-bk3: hdparm -X locks up IDE
@ 2004-03-11 14:14 Denis Vlasenko
2004-03-11 14:52 ` Bartlomiej Zolnierkiewicz
0 siblings, 1 reply; 11+ messages in thread
From: Denis Vlasenko @ 2004-03-11 14:14 UTC (permalink / raw)
To: Jens Axboe; +Cc: linux-kernel
I discovered that hdparm -X <mode> /dev/hda can lock up IDE
interface if there is some activity.
I walked up from via driver's handler for it:
via_set_speed(): directly programs IDE controller timings.
via_set_drive -> via_set_speed
via82cxxx_tune_drive -> via_set_drive
via82cxxx_ide_dma_check -> via_set_drive
init_hwif_via82cxxx:
hwif->tuneproc = &via82cxxx_tune_drive;
hwif->speedproc = &via_set_drive;
...
hwif->ide_dma_check = &via82cxxx_ide_dma_check;
I think via_set_drive is eventually gets called
by hdparm -X, not other two functions.
ide_set_xfer_rate -> HWIF(drive)->speedproc
pre_reset -> check_dma_crc -> ide_set_xfer_rate
set_xfer_rate -> ide_set_xfer_rate
void ide_add_generic_settings(drive):
...
ide_add_setting(drive, "current_speed", SETTING_RW,
-1, -1, TYPE_BYTE, 0, 70, 1, 1, &drive->current_speed,
set_xfer_rate);
^^^^^^^^^^^^^
Seems like there is no locking protecting mode change.
--
vda
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: 2.6.4-rc-bk3: hdparm -X locks up IDE 2004-03-11 14:14 2.6.4-rc-bk3: hdparm -X locks up IDE Denis Vlasenko @ 2004-03-11 14:52 ` Bartlomiej Zolnierkiewicz 2004-03-11 14:48 ` Jens Axboe 0 siblings, 1 reply; 11+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2004-03-11 14:52 UTC (permalink / raw) To: Denis Vlasenko, Jens Axboe; +Cc: linux-kernel On Thursday 11 of March 2004 15:14, Denis Vlasenko wrote: > I discovered that hdparm -X <mode> /dev/hda can lock up IDE > interface if there is some activity. Known bug and is on TODO but fixing it ain't easy. Thanks for a report anyway. Regards, Bartlomiej ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: 2.6.4-rc-bk3: hdparm -X locks up IDE 2004-03-11 14:52 ` Bartlomiej Zolnierkiewicz @ 2004-03-11 14:48 ` Jens Axboe 2004-03-11 15:07 ` Bartlomiej Zolnierkiewicz 0 siblings, 1 reply; 11+ messages in thread From: Jens Axboe @ 2004-03-11 14:48 UTC (permalink / raw) To: Bartlomiej Zolnierkiewicz; +Cc: Denis Vlasenko, linux-kernel On Thu, Mar 11 2004, Bartlomiej Zolnierkiewicz wrote: > On Thursday 11 of March 2004 15:14, Denis Vlasenko wrote: > > I discovered that hdparm -X <mode> /dev/hda can lock up IDE > > interface if there is some activity. > > Known bug and is on TODO but fixing it ain't easy. > Thanks for a report anyway. Wouldn't it be possible to do the stuff that needs serializing from the end_request() part and get automatic synchronization with normal requests? -- Jens Axboe ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: 2.6.4-rc-bk3: hdparm -X locks up IDE 2004-03-11 14:48 ` Jens Axboe @ 2004-03-11 15:07 ` Bartlomiej Zolnierkiewicz 2004-03-11 15:02 ` Jens Axboe 2004-03-11 17:59 ` Jeff Garzik 0 siblings, 2 replies; 11+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2004-03-11 15:07 UTC (permalink / raw) To: Jens Axboe; +Cc: Denis Vlasenko, linux-kernel On Thursday 11 of March 2004 15:48, Jens Axboe wrote: > On Thu, Mar 11 2004, Bartlomiej Zolnierkiewicz wrote: > > On Thursday 11 of March 2004 15:14, Denis Vlasenko wrote: > > > I discovered that hdparm -X <mode> /dev/hda can lock up IDE > > > interface if there is some activity. > > > > Known bug and is on TODO but fixing it ain't easy. > > Thanks for a report anyway. > > Wouldn't it be possible to do the stuff that needs serializing from the > end_request() part and get automatic synchronization with normal > requests? That's the way to do it (REQ_SPECIAL) but unfortunately on some chipsets we need to synchronize both channels (whereas we don't need to serialize normal operations). Regards, Bartlomiej ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: 2.6.4-rc-bk3: hdparm -X locks up IDE 2004-03-11 15:07 ` Bartlomiej Zolnierkiewicz @ 2004-03-11 15:02 ` Jens Axboe 2004-03-11 17:59 ` Jeff Garzik 1 sibling, 0 replies; 11+ messages in thread From: Jens Axboe @ 2004-03-11 15:02 UTC (permalink / raw) To: Bartlomiej Zolnierkiewicz; +Cc: Denis Vlasenko, linux-kernel On Thu, Mar 11 2004, Bartlomiej Zolnierkiewicz wrote: > On Thursday 11 of March 2004 15:48, Jens Axboe wrote: > > On Thu, Mar 11 2004, Bartlomiej Zolnierkiewicz wrote: > > > On Thursday 11 of March 2004 15:14, Denis Vlasenko wrote: > > > > I discovered that hdparm -X <mode> /dev/hda can lock up IDE > > > > interface if there is some activity. > > > > > > Known bug and is on TODO but fixing it ain't easy. > > > Thanks for a report anyway. > > > > Wouldn't it be possible to do the stuff that needs serializing from the > > end_request() part and get automatic synchronization with normal > > requests? > > That's the way to do it (REQ_SPECIAL) but unfortunately on some chipsets > we need to synchronize both channels (whereas we don't need to serialize > normal operations). Ugh yes, that gets nasty... Good luck with that :) -- Jens Axboe ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: 2.6.4-rc-bk3: hdparm -X locks up IDE 2004-03-11 15:07 ` Bartlomiej Zolnierkiewicz 2004-03-11 15:02 ` Jens Axboe @ 2004-03-11 17:59 ` Jeff Garzik 2004-03-12 0:21 ` [PATCH] hdparm_X.patch (was: Re: 2.6.4-rc-bk3: hdparm -X locks up IDE) Denis Vlasenko 1 sibling, 1 reply; 11+ messages in thread From: Jeff Garzik @ 2004-03-11 17:59 UTC (permalink / raw) To: Bartlomiej Zolnierkiewicz; +Cc: Jens Axboe, Denis Vlasenko, linux-kernel Bartlomiej Zolnierkiewicz wrote: > On Thursday 11 of March 2004 15:48, Jens Axboe wrote: > >>On Thu, Mar 11 2004, Bartlomiej Zolnierkiewicz wrote: >> >>>On Thursday 11 of March 2004 15:14, Denis Vlasenko wrote: >>> >>>>I discovered that hdparm -X <mode> /dev/hda can lock up IDE >>>>interface if there is some activity. >>> >>>Known bug and is on TODO but fixing it ain't easy. >>>Thanks for a report anyway. >> >>Wouldn't it be possible to do the stuff that needs serializing from the >>end_request() part and get automatic synchronization with normal >>requests? > > > That's the way to do it (REQ_SPECIAL) but unfortunately on some chipsets > we need to synchronize both channels (whereas we don't need to serialize > normal operations). blk_stop_queue() on all queues attached to the hardware? You need to synchronize anyway for the rare hardware that reports itself as "simplex" -- one DMA engine for both channels. Jeff ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH] hdparm_X.patch (was: Re: 2.6.4-rc-bk3: hdparm -X locks up IDE) 2004-03-11 17:59 ` Jeff Garzik @ 2004-03-12 0:21 ` Denis Vlasenko 2004-03-12 1:02 ` Bartlomiej Zolnierkiewicz 0 siblings, 1 reply; 11+ messages in thread From: Denis Vlasenko @ 2004-03-12 0:21 UTC (permalink / raw) To: Jeff Garzik, Bartlomiej Zolnierkiewicz; +Cc: Jens Axboe, linux-kernel [-- Attachment #1: Type: text/plain, Size: 1907 bytes --] On Thursday 11 March 2004 19:59, Jeff Garzik wrote: > Bartlomiej Zolnierkiewicz wrote: > > On Thursday 11 of March 2004 15:48, Jens Axboe wrote: > >>On Thu, Mar 11 2004, Bartlomiej Zolnierkiewicz wrote: > >>>On Thursday 11 of March 2004 15:14, Denis Vlasenko wrote: > >>>>I discovered that hdparm -X <mode> /dev/hda can lock up IDE > >>>>interface if there is some activity. > >>> > >>>Known bug and is on TODO but fixing it ain't easy. > >>>Thanks for a report anyway. > >> > >>Wouldn't it be possible to do the stuff that needs serializing from the > >>end_request() part and get automatic synchronization with normal > >>requests? > > > > That's the way to do it (REQ_SPECIAL) but unfortunately on some chipsets > > we need to synchronize both channels (whereas we don't need to serialize > > normal operations). > > blk_stop_queue() on all queues attached to the hardware? > > You need to synchronize anyway for the rare hardware that reports itself > as "simplex" -- one DMA engine for both channels. This patch survived cyclic switching of all DMA modes from mwdma0 to udma4 and continuous write load of type while(1) { dd if=/dev/zero of=file bs=1M count=<RAM size>; sync; } for five minutes. It does not handle crippled/simplex chipset, it is a TODO. Things commented by C++ style comments (//) aren't meant to stay. I think original code was a bit buggy: set_transfer() returned 0 for modes < XFER_SW_DMA_0, ie, for all PIO modes. Later, if (set_transfer(drive, &tfargs)) { xfer_rate = args[1]; if (ide_ata66_check(drive, &tfargs)) goto abort; } err = ide_wait_cmd(drive, args[0], args[1], args[2], args[3], argbuf); if (!err && xfer_rate) { ide_set_xfer_rate(drive, xfer_rate); ide_driveid_update(drive); } This will never execute ide_set_xfer_rate() for PIO modes -- vda [-- Attachment #2: hdparm_X.patch --] [-- Type: text/x-diff, Size: 4538 bytes --] diff -urN linux-2.6.4.orig/drivers/ide/ide-io.c linux-2.6.4/drivers/ide/ide-io.c --- linux-2.6.4.orig/drivers/ide/ide-io.c Thu Mar 11 21:25:17 2004 +++ linux-2.6.4/drivers/ide/ide-io.c Fri Mar 12 02:03:49 2004 @@ -1387,10 +1387,32 @@ err = 0; if (must_wait) { + int xfer_rate = -1; + /* Are we going to do hdparm -X n ? */ + if(rq->buffer + && rq->buffer[0] == (char)WIN_SETFEATURES + // original code checked for !0 below. Is that right? + && (int)rq->buffer[1] != 0 + && rq->buffer[2] == (char)SETFEATURES_XFER + // original code checked for 0 below. It is always true, can we nuke it? + && rq->buffer[3] == 0 + // original code did it but I think it's wrong: + //&& (drive->id->dma_ultra || drive->id->dma_mword + // || drive->id->dma_1word) + ) { + xfer_rate = rq->buffer[1]; /* -X n */ + } + wait_for_completion(&wait); if (rq->errors) err = -EIO; + if(!err && xfer_rate != -1) { + /* asking chipset to change DMA/PIO timings */ + ide_set_xfer_rate(drive, xfer_rate); + ide_driveid_update(drive); + mdelay(2000); // give it a name like WAIT_XFER_RATE + } blk_put_request(rq); } diff -urN linux-2.6.4.orig/drivers/ide/ide-iops.c linux-2.6.4/drivers/ide/ide-iops.c --- linux-2.6.4.orig/drivers/ide/ide-iops.c Wed Feb 18 05:57:24 2004 +++ linux-2.6.4/drivers/ide/ide-iops.c Fri Mar 12 02:04:19 2004 @@ -660,52 +660,34 @@ EXPORT_SYMBOL(eighty_ninty_three); -int ide_ata66_check (ide_drive_t *drive, ide_task_t *args) +/* + * Is drive/channel capable of handling this? + * Currently checks only for ioctl(HDIO_DRIVE_CMD, SETFEATURES_XFER) + * (hdparm -X n) + */ +int unsupported_by_drive (ide_drive_t *drive, ide_task_t *args) { - if ((args->tfRegister[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) && - (args->tfRegister[IDE_SECTOR_OFFSET] > XFER_UDMA_2) && - (args->tfRegister[IDE_FEATURE_OFFSET] == SETFEATURES_XFER)) { + if (args->tfRegister[IDE_COMMAND_OFFSET] != WIN_SETFEATURES) return 0; + if (args->tfRegister[IDE_FEATURE_OFFSET] != SETFEATURES_XFER) return 0; + if (args->tfRegister[IDE_SECTOR_OFFSET] <= XFER_UDMA_2) return 0; + #ifndef CONFIG_IDEDMA_IVB - if ((drive->id->hw_config & 0x6000) == 0) { + if ( (drive->id->hw_config & 0x6000) == 0) { #else /* !CONFIG_IDEDMA_IVB */ - if (((drive->id->hw_config & 0x2000) == 0) || - ((drive->id->hw_config & 0x4000) == 0)) { + if ( ((drive->id->hw_config & 0x2000) == 0) || + ((drive->id->hw_config & 0x4000) == 0) ) { #endif /* CONFIG_IDEDMA_IVB */ - printk("%s: Speed warnings UDMA 3/4/5 is not " - "functional.\n", drive->name); - return 1; - } - if (!HWIF(drive)->udma_four) { - printk("%s: Speed warnings UDMA 3/4/5 is not " - "functional.\n", - HWIF(drive)->name); - return 1; - } + printk("%s is not capable of UDMA 3/4/5\n", drive->name); + return 1; } - return 0; -} - -EXPORT_SYMBOL(ide_ata66_check); - -/* - * Backside of HDIO_DRIVE_CMD call of SETFEATURES_XFER. - * 1 : Safe to update drive->id DMA registers. - * 0 : OOPs not allowed. - */ -int set_transfer (ide_drive_t *drive, ide_task_t *args) -{ - if ((args->tfRegister[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) && - (args->tfRegister[IDE_SECTOR_OFFSET] >= XFER_SW_DMA_0) && - (args->tfRegister[IDE_FEATURE_OFFSET] == SETFEATURES_XFER) && - (drive->id->dma_ultra || - drive->id->dma_mword || - drive->id->dma_1word)) + if (!HWIF(drive)->udma_four) { + printk("%s is not capable of UDMA 3/4/5\n", HWIF(drive)->name); return 1; - + } return 0; } -EXPORT_SYMBOL(set_transfer); +EXPORT_SYMBOL(unsupported_by_drive); u8 ide_auto_reduce_xfer (ide_drive_t *drive) { diff -urN linux-2.6.4.orig/drivers/ide/ide-taskfile.c linux-2.6.4/drivers/ide/ide-taskfile.c --- linux-2.6.4.orig/drivers/ide/ide-taskfile.c Thu Mar 11 21:25:18 2004 +++ linux-2.6.4/drivers/ide/ide-taskfile.c Fri Mar 12 02:03:55 2004 @@ -1592,7 +1592,6 @@ { int err = 0; u8 args[4], *argbuf = args; - u8 xfer_rate = 0; int argsize = 4; ide_task_t tfargs; @@ -1621,19 +1620,13 @@ return -ENOMEM; memcpy(argbuf, args, 4); } - if (set_transfer(drive, &tfargs)) { - xfer_rate = args[1]; - if (ide_ata66_check(drive, &tfargs)) - goto abort; + + if (unsupported_by_drive(drive, &tfargs)) { + goto abort; } err = ide_wait_cmd(drive, args[0], args[1], args[2], args[3], argbuf); - if (!err && xfer_rate) { - /* active-retuning-calls future */ - ide_set_xfer_rate(drive, xfer_rate); - ide_driveid_update(drive); - } abort: if (copy_to_user((void *)arg, argbuf, argsize)) err = -EFAULT; ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] hdparm_X.patch (was: Re: 2.6.4-rc-bk3: hdparm -X locks up IDE) 2004-03-12 0:21 ` [PATCH] hdparm_X.patch (was: Re: 2.6.4-rc-bk3: hdparm -X locks up IDE) Denis Vlasenko @ 2004-03-12 1:02 ` Bartlomiej Zolnierkiewicz 2004-03-12 7:24 ` Denis Vlasenko 0 siblings, 1 reply; 11+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2004-03-12 1:02 UTC (permalink / raw) To: Denis Vlasenko, Jeff Garzik; +Cc: Jens Axboe, linux-kernel On Friday 12 of March 2004 01:21, Denis Vlasenko wrote: > On Thursday 11 March 2004 19:59, Jeff Garzik wrote: > > Bartlomiej Zolnierkiewicz wrote: > > > On Thursday 11 of March 2004 15:48, Jens Axboe wrote: > > >>On Thu, Mar 11 2004, Bartlomiej Zolnierkiewicz wrote: > > >>>On Thursday 11 of March 2004 15:14, Denis Vlasenko wrote: > > >>>>I discovered that hdparm -X <mode> /dev/hda can lock up IDE > > >>>>interface if there is some activity. > > >>> > > >>>Known bug and is on TODO but fixing it ain't easy. > > >>>Thanks for a report anyway. > > >> > > >>Wouldn't it be possible to do the stuff that needs serializing from the > > >>end_request() part and get automatic synchronization with normal > > >>requests? > > > > > > That's the way to do it (REQ_SPECIAL) but unfortunately on some > > > chipsets we need to synchronize both channels (whereas we don't need to > > > serialize normal operations). > > > > blk_stop_queue() on all queues attached to the hardware? > > > > You need to synchronize anyway for the rare hardware that reports itself > > as "simplex" -- one DMA engine for both channels. > > This patch survived cyclic switching of all DMA modes from mwdma0 to udma4 > and continuous write load of type > while(1) { dd if=/dev/zero of=file bs=1M count=<RAM size>; sync; } > for five minutes. > > It does not handle crippled/simplex chipset, it is a TODO. > > Things commented by C++ style comments (//) aren't meant to stay. > > I think original code was a bit buggy: > set_transfer() returned 0 for modes < XFER_SW_DMA_0, ie, > for all PIO modes. Later, > if (set_transfer(drive, &tfargs)) { > xfer_rate = args[1]; > if (ide_ata66_check(drive, &tfargs)) > goto abort; > } > err = ide_wait_cmd(drive, args[0], args[1], args[2], args[3], > argbuf); if (!err && xfer_rate) { > ide_set_xfer_rate(drive, xfer_rate); > ide_driveid_update(drive); > } > This will never execute ide_set_xfer_rate() for PIO modes It will also never execute ide_set_xfer_rate() for DMA on PIO only drive. I must check if "no PIO" thing is a bug or a design decision. Thanks, Bartlomiej ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] hdparm_X.patch (was: Re: 2.6.4-rc-bk3: hdparm -X locks up IDE) 2004-03-12 1:02 ` Bartlomiej Zolnierkiewicz @ 2004-03-12 7:24 ` Denis Vlasenko 2004-03-12 9:39 ` Denis Vlasenko 0 siblings, 1 reply; 11+ messages in thread From: Denis Vlasenko @ 2004-03-12 7:24 UTC (permalink / raw) To: Bartlomiej Zolnierkiewicz, Jeff Garzik; +Cc: Jens Axboe, linux-kernel > > This patch survived cyclic switching of all DMA modes from mwdma0 to > > udma4 and continuous write load of type > > while(1) { dd if=/dev/zero of=file bs=1M count=<RAM size>; sync; } > > for five minutes. > > > > It does not handle crippled/simplex chipset, it is a TODO. > > > > Things commented by C++ style comments (//) aren't meant to stay. > > > > I think original code was a bit buggy: > > set_transfer() returned 0 for modes < XFER_SW_DMA_0, ie, > > for all PIO modes. Later, > > if (set_transfer(drive, &tfargs)) { > > xfer_rate = args[1]; > > if (ide_ata66_check(drive, &tfargs)) > > goto abort; > > } > > err = ide_wait_cmd(drive, args[0], args[1], args[2], args[3], > > argbuf); if (!err && xfer_rate) { > > ide_set_xfer_rate(drive, xfer_rate); > > ide_driveid_update(drive); > > } > > This will never execute ide_set_xfer_rate() for PIO modes > > It will also never execute ide_set_xfer_rate() for DMA on PIO only drive. > I must check if "no PIO" thing is a bug or a design decision. I think IDE driver will never ask for DMA on PIO only drive Bartlomiej, do you have comments on my patch? So far, I myself spotted some minor problems: I forgot to remove now-extraneous if() from ide.c: static int set_xfer_rate (ide_drive_t *drive, int arg) { int err = ide_wait_cmd(drive, WIN_SETFEATURES, (u8) arg, SETFEATURES_XFER, 0, NULL); if (!err && arg) { ide_set_xfer_rate(drive, (u8) arg); ide_driveid_update(drive); } return err; } And second, in ide_do_drive_cmd(), mdelay(2000) after WIN_SETFEATURES is a bit rude. -- vda ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] hdparm_X.patch (was: Re: 2.6.4-rc-bk3: hdparm -X locks up IDE) 2004-03-12 7:24 ` Denis Vlasenko @ 2004-03-12 9:39 ` Denis Vlasenko 2004-03-12 14:34 ` Bartlomiej Zolnierkiewicz 0 siblings, 1 reply; 11+ messages in thread From: Denis Vlasenko @ 2004-03-12 9:39 UTC (permalink / raw) To: Bartlomiej Zolnierkiewicz, Jeff Garzik; +Cc: Jens Axboe, linux-kernel [-- Attachment #1: Type: text/plain, Size: 678 bytes --] > I forgot to remove now-extraneous if() from ide.c: > > static int set_xfer_rate (ide_drive_t *drive, int arg) > { > int err = ide_wait_cmd(drive, > WIN_SETFEATURES, (u8) arg, > SETFEATURES_XFER, 0, NULL); > > if (!err && arg) { > ide_set_xfer_rate(drive, (u8) arg); > ide_driveid_update(drive); > } > return err; > } > > And second, in ide_do_drive_cmd(), mdelay(2000) > after WIN_SETFEATURES is a bit rude. ...and wrongly placed. I just realized that ide_driveid_update(drive) actually talks with the drive! New patch is attached. -- vda [-- Attachment #2: hdparm_X-2.patch --] [-- Type: text/x-diff, Size: 4191 bytes --] diff -urN linux-2.6.4.orig/drivers/ide/ide-io.c linux-2.6.4/drivers/ide/ide-io.c --- linux-2.6.4.orig/drivers/ide/ide-io.c Fri Mar 12 11:15:00 2004 +++ linux-2.6.4/drivers/ide/ide-io.c Fri Mar 12 11:33:30 2004 @@ -1387,10 +1387,25 @@ err = 0; if (must_wait) { + int xfer_rate = -1; + /* Are we going to do hdparm -X n ? */ + if(rq->buffer + && rq->buffer[0] == (char)WIN_SETFEATURES + && rq->buffer[2] == (char)SETFEATURES_XFER + ) { + xfer_rate = rq->buffer[1]; /* -X n */ + } + wait_for_completion(&wait); if (rq->errors) err = -EIO; + if(!err && xfer_rate != -1) { + ide_delay_50ms(); /* be gentle */ + /* ask chipset to change DMA/PIO timings */ + ide_set_xfer_rate(drive, xfer_rate); + ide_driveid_update(drive); + } blk_put_request(rq); } diff -urN linux-2.6.4.orig/drivers/ide/ide-iops.c linux-2.6.4/drivers/ide/ide-iops.c --- linux-2.6.4.orig/drivers/ide/ide-iops.c Fri Mar 12 11:07:07 2004 +++ linux-2.6.4/drivers/ide/ide-iops.c Fri Mar 12 11:26:55 2004 @@ -660,52 +660,34 @@ EXPORT_SYMBOL(eighty_ninty_three); -int ide_ata66_check (ide_drive_t *drive, ide_task_t *args) +/* + * Is drive/channel capable of handling this? + * Currently checks only for ioctl(HDIO_DRIVE_CMD, SETFEATURES_XFER) + * (hdparm -X n) + */ +int unsupported_by_drive (ide_drive_t *drive, ide_task_t *args) { - if ((args->tfRegister[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) && - (args->tfRegister[IDE_SECTOR_OFFSET] > XFER_UDMA_2) && - (args->tfRegister[IDE_FEATURE_OFFSET] == SETFEATURES_XFER)) { + if (args->tfRegister[IDE_COMMAND_OFFSET] != WIN_SETFEATURES) return 0; + if (args->tfRegister[IDE_FEATURE_OFFSET] != SETFEATURES_XFER) return 0; + if (args->tfRegister[IDE_SECTOR_OFFSET] <= XFER_UDMA_2) return 0; + #ifndef CONFIG_IDEDMA_IVB - if ((drive->id->hw_config & 0x6000) == 0) { + if ( (drive->id->hw_config & 0x6000) == 0) { #else /* !CONFIG_IDEDMA_IVB */ - if (((drive->id->hw_config & 0x2000) == 0) || - ((drive->id->hw_config & 0x4000) == 0)) { + if ( ((drive->id->hw_config & 0x2000) == 0) || + ((drive->id->hw_config & 0x4000) == 0) ) { #endif /* CONFIG_IDEDMA_IVB */ - printk("%s: Speed warnings UDMA 3/4/5 is not " - "functional.\n", drive->name); - return 1; - } - if (!HWIF(drive)->udma_four) { - printk("%s: Speed warnings UDMA 3/4/5 is not " - "functional.\n", - HWIF(drive)->name); - return 1; - } + printk("%s is not capable of UDMA 3/4/5\n", drive->name); + return 1; } - return 0; -} - -EXPORT_SYMBOL(ide_ata66_check); - -/* - * Backside of HDIO_DRIVE_CMD call of SETFEATURES_XFER. - * 1 : Safe to update drive->id DMA registers. - * 0 : OOPs not allowed. - */ -int set_transfer (ide_drive_t *drive, ide_task_t *args) -{ - if ((args->tfRegister[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) && - (args->tfRegister[IDE_SECTOR_OFFSET] >= XFER_SW_DMA_0) && - (args->tfRegister[IDE_FEATURE_OFFSET] == SETFEATURES_XFER) && - (drive->id->dma_ultra || - drive->id->dma_mword || - drive->id->dma_1word)) + if (!HWIF(drive)->udma_four) { + printk("%s is not capable of UDMA 3/4/5\n", HWIF(drive)->name); return 1; - + } return 0; } -EXPORT_SYMBOL(set_transfer); +EXPORT_SYMBOL(unsupported_by_drive); u8 ide_auto_reduce_xfer (ide_drive_t *drive) { diff -urN linux-2.6.4.orig/drivers/ide/ide-taskfile.c linux-2.6.4/drivers/ide/ide-taskfile.c --- linux-2.6.4.orig/drivers/ide/ide-taskfile.c Fri Mar 12 11:15:00 2004 +++ linux-2.6.4/drivers/ide/ide-taskfile.c Fri Mar 12 11:26:55 2004 @@ -1592,7 +1592,6 @@ { int err = 0; u8 args[4], *argbuf = args; - u8 xfer_rate = 0; int argsize = 4; ide_task_t tfargs; @@ -1621,19 +1620,13 @@ return -ENOMEM; memcpy(argbuf, args, 4); } - if (set_transfer(drive, &tfargs)) { - xfer_rate = args[1]; - if (ide_ata66_check(drive, &tfargs)) - goto abort; + + if (unsupported_by_drive(drive, &tfargs)) { + goto abort; } err = ide_wait_cmd(drive, args[0], args[1], args[2], args[3], argbuf); - if (!err && xfer_rate) { - /* active-retuning-calls future */ - ide_set_xfer_rate(drive, xfer_rate); - ide_driveid_update(drive); - } abort: if (copy_to_user((void *)arg, argbuf, argsize)) err = -EFAULT; ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] hdparm_X.patch (was: Re: 2.6.4-rc-bk3: hdparm -X locks up IDE) 2004-03-12 9:39 ` Denis Vlasenko @ 2004-03-12 14:34 ` Bartlomiej Zolnierkiewicz 0 siblings, 0 replies; 11+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2004-03-12 14:34 UTC (permalink / raw) To: Denis Vlasenko, Jeff Garzik; +Cc: Jens Axboe, linux-kernel On Friday 12 of March 2004 10:39, Denis Vlasenko wrote: > > I forgot to remove now-extraneous if() from ide.c: > > > > static int set_xfer_rate (ide_drive_t *drive, int arg) > > { > > int err = ide_wait_cmd(drive, > > WIN_SETFEATURES, (u8) arg, > > SETFEATURES_XFER, 0, NULL); > > > > if (!err && arg) { > > ide_set_xfer_rate(drive, (u8) arg); > > ide_driveid_update(drive); > > } > > return err; > > } > > > > And second, in ide_do_drive_cmd(), mdelay(2000) > > after WIN_SETFEATURES is a bit rude. > > ...and wrongly placed. I just realized that ide_driveid_update(drive) > actually talks with the drive! > > New patch is attached. diff -urN linux-2.6.4.orig/drivers/ide/ide-io.c linux-2.6.4/drivers/ide/ide-io.c --- linux-2.6.4.orig/drivers/ide/ide-io.c Fri Mar 12 11:15:00 2004 +++ linux-2.6.4/drivers/ide/ide-io.c Fri Mar 12 11:33:30 2004 @@ -1387,10 +1387,25 @@ err = 0; if (must_wait) { + int xfer_rate = -1; + /* Are we going to do hdparm -X n ? */ HDIO_DRIVE_CMD is an ordinary ioctl, not some hdparm specific thing. + if(rq->buffer + && rq->buffer[0] == (char)WIN_SETFEATURES + && rq->buffer[2] == (char)SETFEATURES_XFER + ) { + xfer_rate = rq->buffer[1]; /* -X n */ + } + wait_for_completion(&wait); if (rq->errors) err = -EIO; + if(!err && xfer_rate != -1) { + ide_delay_50ms(); /* be gentle */ Why? + /* ask chipset to change DMA/PIO timings */ + ide_set_xfer_rate(drive, xfer_rate); + ide_driveid_update(drive); + } blk_put_request(rq); } diff -urN linux-2.6.4.orig/drivers/ide/ide-iops.c linux-2.6.4/drivers/ide/ide-iops.c --- linux-2.6.4.orig/drivers/ide/ide-iops.c Fri Mar 12 11:07:07 2004 +++ linux-2.6.4/drivers/ide/ide-iops.c Fri Mar 12 11:26:55 2004 @@ -660,52 +660,34 @@ EXPORT_SYMBOL(eighty_ninty_three); -int ide_ata66_check (ide_drive_t *drive, ide_task_t *args) +/* + * Is drive/channel capable of handling this? + * Currently checks only for ioctl(HDIO_DRIVE_CMD, SETFEATURES_XFER) + * (hdparm -X n) + */ +int unsupported_by_drive (ide_drive_t *drive, ide_task_t *args) { - if ((args->tfRegister[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) && - (args->tfRegister[IDE_SECTOR_OFFSET] > XFER_UDMA_2) && - (args->tfRegister[IDE_FEATURE_OFFSET] == SETFEATURES_XFER)) { + if (args->tfRegister[IDE_COMMAND_OFFSET] != WIN_SETFEATURES) return 0; + if (args->tfRegister[IDE_FEATURE_OFFSET] != SETFEATURES_XFER) return 0; + if (args->tfRegister[IDE_SECTOR_OFFSET] <= XFER_UDMA_2) return 0; + #ifndef CONFIG_IDEDMA_IVB - if ((drive->id->hw_config & 0x6000) == 0) { + if ( (drive->id->hw_config & 0x6000) == 0) { #else /* !CONFIG_IDEDMA_IVB */ - if (((drive->id->hw_config & 0x2000) == 0) || - ((drive->id->hw_config & 0x4000) == 0)) { + if ( ((drive->id->hw_config & 0x2000) == 0) || + ((drive->id->hw_config & 0x4000) == 0) ) { #endif /* CONFIG_IDEDMA_IVB */ - printk("%s: Speed warnings UDMA 3/4/5 is not " - "functional.\n", drive->name); - return 1; - } - if (!HWIF(drive)->udma_four) { - printk("%s: Speed warnings UDMA 3/4/5 is not " - "functional.\n", - HWIF(drive)->name); - return 1; - } + printk("%s is not capable of UDMA 3/4/5\n", drive->name); + return 1; } - return 0; -} - -EXPORT_SYMBOL(ide_ata66_check); -/* - * Backside of HDIO_DRIVE_CMD call of SETFEATURES_XFER. - * 1 : Safe to update drive->id DMA registers. - * 0 : OOPs not allowed. - */ -int set_transfer (ide_drive_t *drive, ide_task_t *args) -{ - if ((args->tfRegister[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) && - (args->tfRegister[IDE_SECTOR_OFFSET] >= XFER_SW_DMA_0) && - (args->tfRegister[IDE_FEATURE_OFFSET] == SETFEATURES_XFER) && - (drive->id->dma_ultra || - drive->id->dma_mword || - drive->id->dma_1word)) + if (!HWIF(drive)->udma_four) { + printk("%s is not capable of UDMA 3/4/5\n", HWIF(drive)->name); return 1; - + } return 0; } -EXPORT_SYMBOL(set_transfer); +EXPORT_SYMBOL(unsupported_by_drive); This ide_ata66_check() -> unsupported_by_driver() change is totally unnecessary. Please also leave set_transfer() in place, "no PIO" issue can be addressed later. Regards, Bartlomiej ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2004-03-12 14:27 UTC | newest] Thread overview: 11+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2004-03-11 14:14 2.6.4-rc-bk3: hdparm -X locks up IDE Denis Vlasenko 2004-03-11 14:52 ` Bartlomiej Zolnierkiewicz 2004-03-11 14:48 ` Jens Axboe 2004-03-11 15:07 ` Bartlomiej Zolnierkiewicz 2004-03-11 15:02 ` Jens Axboe 2004-03-11 17:59 ` Jeff Garzik 2004-03-12 0:21 ` [PATCH] hdparm_X.patch (was: Re: 2.6.4-rc-bk3: hdparm -X locks up IDE) Denis Vlasenko 2004-03-12 1:02 ` Bartlomiej Zolnierkiewicz 2004-03-12 7:24 ` Denis Vlasenko 2004-03-12 9:39 ` Denis Vlasenko 2004-03-12 14:34 ` Bartlomiej Zolnierkiewicz
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox