IDE Power Management, try 2
PATCH 1/1 IDE Power Management, try 2
Ok, Here's the new one.
However, I'm not completely happy with it yet. Bart, as you suggested, I moved the state value to drive in order to keep a normal taskfile struct in rq->special. But that has a drawback: The request beeing re-fetched from the queue on each step, it goes through start_request for each of them. So I needed a way to know when is the "first pass" so I could initialize drive->pm_step properly. I don't want to initialize it prior to queuing the request as it would be racy. In fact, that pm_step is really a property of the request itself.
I had to add yet another rq->flags bit for that, and I think that sucks
Also, currently, I'm not passing the "state" argument of the PM callback to the PM request. That argument would be needed if we ever wanted to distinguish between S1,S2,S3,S4.... For example, that could be used to skip the STANDBY pass on suspend-to-disk to avoid the disk spinning down and back up (suspend-to-disk is slow enough already ;)
So I'm considering going back to putting some custom pm state structure in rq->special, but having this structure hold a taskfile structure as it's first entry so it is transparent to the taskfile interrupt handlers. It's not the prettiest thing, but unless we add more fields to struct request (which would be an option too since those PM requests could be used by _any_ block driver to implement proper power management).
Jens, Bart, what do you think ? Should I add pm_step & pm_state to struct request ? Do the "extended taskfile structure" thing ? Or just keep things like they are in this new patch and forget about carrying the PM state value ?
I also added another rq->flags bit for requests forced at the head of the queue with ide_preempt. This is typically for sense requests done by ide-cd (though I also spotted a user in the tcq stuff). I need that to make sure that if such a request ever happens to be pushed in front of the current PM request (with the drive->blocked flag already set), we don't enter an endless loop, fetching that new request and dropping it right away because we only accept PM requests from the queue once the drive is suspended.
Regards,
Ben.
===== drivers/ide/ide-cd.c 1.49 vs edited =====
drivers/ide/ide-cd.c +44 -0
@@ -3253,6 +3253,44 @@static int ide_cdrom_attach (ide_drive_t *drive); +/* Power Management state machine. +* +* We don't do much for CDs right now +*/ + + +static void ide_cdrom_complete_power_step (ide_drive_t *drive,struct request *rq,u8 stat,u8 error) +{ +} + +static ide_startstop_t ide_cdrom_start_power_step (ide_drive_t *drive,struct request *rq) +{ +ide_task_t *args = rq->special; + +memset (args,0 ,sizeof (ide_task_t)); + +switch (drive->pm_step) { +case ide_pm_state_start_suspend: +break ; + +case ide_pm_state_start_resume:/* Resume step 1 (restore DMA) */ +/* Right now, all we do is call ide_dma_check for the HWIF, +* we could be smarter and check for current xfer_speed +* in struct drive etc... +* Also, this step could be implemented as a generic helper +* as most subdrivers will use it +*/ +if (!drive->id || !(drive->id->capability &1 )) +break ; +if (HWIF (drive)->ide_dma_check ==NULL ) +break ; +HWIF (drive)->ide_dma_check (drive); +break ; + } + drive->pm_step = ide_pm_state_completed; +return ide_stopped; +} +static ide_driver_t ide_cdrom_driver = { .owner =THIS_MODULE , .name ="ide-cdrom" ,
@@ -3269,6 +3307,12 @@ .capacity = ide_cdrom_capacity, .attach = ide_cdrom_attach, .drives = LIST_HEAD_INIT(ide_cdrom_driver.drives), + .start_power_step = ide_cdrom_start_power_step, + .complete_power_step = ide_cdrom_complete_power_step, + .gen_driver = { + .suspend = generic_ide_suspend, + .resume = generic_ide_resume, + } };static int idecd_open (struct inode * inode,struct file * file)
===== drivers/ide/ide-disk.c 1.45 vs edited =====
drivers/ide/ide-disk.c +61 -45
145 lines not on this page · raw message
===== drivers/ide/ide-io.c 1.11 vs edited =====
drivers/ide/ide-io.c +111 -4
176 lines not on this page · raw message
===== drivers/ide/ide-iops.c 1.17 vs edited =====
drivers/ide/ide-iops.c +27 -0
@@ -1318,5 +1318,32 @@return do_reset1 (drive,0 ); } +/* +* This function waits for the hwif to report a non-busy status +* see comments in probe_hwif() +*/ +int ide_wait_not_busy (ide_hwif_t *hwif,unsigned long timeout) +{ +u8 stat =0 ; + +while (timeout--) { +/* Turn this into a schedule() sleep once I'm sure +* about locking issues (2.5 work ?) +*/ +mdelay (1 ); + stat = hwif->INB (hwif->io_ports[IDE_STATUS_OFFSET ]); +if ((stat &BUSY_STAT ) ==0 ) +break ; +/* Assume a value of 0xff means nothing is connected to +* the interface and it doesn't implement the pull-down +* resistor on D7 +*/ +if (stat ==0xff ) +break ; + } +return ((stat &BUSY_STAT ) ==0 ) ?0 : -EBUSY ; +} + +EXPORT_SYMBOL (ide_do_reset);
===== drivers/ide/ide-probe.c 1.49 vs edited =====
drivers/ide/ide-probe.c +3 -33
@@ -723,35 +723,6 @@//EXPORT_SYMBOL(hwif_register); -/* Enable code below on all archs later, for now, I want it on PPC -*/ -#ifdef CONFIG_PPC -/* -* This function waits for the hwif to report a non-busy status -* see comments in probe_hwif() -*/ -static int wait_not_busy (ide_hwif_t *hwif,unsigned long timeout) -{ -u8 stat =0 ; - -while (timeout--) { -/* Turn this into a schedule() sleep once I'm sure -* about locking issues (2.5 work ?) -*/ -mdelay (1 ); - stat = hwif->INB (hwif->io_ports[IDE_STATUS_OFFSET ]); -if ((stat &BUSY_STAT ) ==0 ) -break ; -/* Assume a value of 0xff means nothing is connected to -* the interface and it doesn't implement the pull-down -* resistor on D7 -*/ -if (stat ==0xff ) -break ; - } -return ((stat &BUSY_STAT ) ==0 ) ?0 : -EBUSY ; -} -static int wait_hwif_ready (ide_hwif_t *hwif) {int rc;
@@ -766,7 +737,7 @@* I know of at least one disk who takes 31 seconds, I use 35 * here to be safe */ - rc =wait_not_busy (hwif,35000 ); + rc =ide_wait_not_busy (hwif,35000 );if (rc)return rc;
@@ -774,20 +745,19 @@SELECT_DRIVE (&hwif->drives[0 ]); hwif->OUTB (8 , hwif->io_ports[IDE_CONTROL_OFFSET ]);mdelay (2 ); - rc =wait_not_busy (hwif,10000 ); + rc =ide_wait_not_busy (hwif,10000 );if (rc)return rc;SELECT_DRIVE (&hwif->drives[1 ]); hwif->OUTB (8 , hwif->io_ports[IDE_CONTROL_OFFSET ]);mdelay (2 ); - rc =wait_not_busy (hwif,10000 ); + rc =ide_wait_not_busy (hwif,10000 );/* Exit function with master reselected (let's be sane) */ SELECT_DRIVE (&hwif->drives[0 ]);return rc; } -#endif /* CONFIG_PPC */ /* * This routine only knows how to look for drive units 0 and 1
===== drivers/ide/ide.c 1.70 vs edited =====
drivers/ide/ide.c +38 -0
@@ -1441,6 +1441,44 @@EXPORT_SYMBOL (ata_attach); +int generic_ide_suspend (struct device *dev,u32 state,u32 level) +{ +ide_drive_t *drive = dev->driver_data; +struct request rq; +ide_task_t args; + +if (level == dev->power_state || level !=SUSPEND_SAVE_STATE ) +return 0 ; + +memset (&rq,0 ,sizeof (rq)); +memset (&args,0 ,sizeof (args)); + rq.flags =REQ_PM_SUSPEND ; + rq.special = &args; + +return ide_do_drive_cmd (drive, &rq, ide_wait); +} + +EXPORT_SYMBOL (generic_ide_suspend); + +int generic_ide_resume (struct device *dev,u32 level) +{ +ide_drive_t *drive = dev->driver_data; +struct request rq; +ide_task_t args; + +if (level == dev->power_state || level !=RESUME_RESTORE_STATE ) +return 0 ; + +memset (&rq,0 ,sizeof (rq)); +memset (&args,0 ,sizeof (args)); + rq.flags =REQ_PM_RESUME ; + rq.special = &args; + +return ide_do_drive_cmd (drive, &rq, ide_head_wait); +} + +EXPORT_SYMBOL (generic_ide_resume); +int generic_ide_ioctl (struct block_device *bdev,unsigned int cmd,unsigned long arg) {
===== include/linux/blkdev.h 1.106 vs edited =====
include/linux/blkdev.h +11 -0
@@ -130,6 +130,10 @@ __REQ_DRIVE_CMD, __REQ_DRIVE_TASK, __REQ_DRIVE_TASKFILE, + __REQ_PM_SUSPEND,/* Suspend request */ + __REQ_PM_RESUME,/* Resume request */ + __REQ_PM_STARTED,/* Flag set when PM state machine has started */ + __REQ_PREEMPT,/* Flag set for "ide_preempt" requests */ __REQ_NR_BITS, /* stops here */ };
@@ -151,6 +155,13 @@#define REQ_DRIVE_CMD (1 << __REQ_DRIVE_CMD)#define REQ_DRIVE_TASK (1 << __REQ_DRIVE_TASK)#define REQ_DRIVE_TASKFILE (1 << __REQ_DRIVE_TASKFILE) +#define REQ_PM_SUSPEND (1 << __REQ_PM_SUSPEND) +#define REQ_PM_RESUME (1 << __REQ_PM_RESUME) +#define REQ_PM_STARTED (1 << __REQ_PM_STARTED) +#define REQ_PREEMPT (1 << __REQ_PREEMPT) + +#define blk_request_is_pm (rq) \ + ((rq->flags & (REQ_PM_SUSPEND | REQ_PM_RESUME)) != 0)#include <linux/elevator.h>
===== include/linux/ide.h 1.54 vs edited =====
include/linux/ide.h +43 -0
85 lines not on this page · raw message
Quoted 3 lines · Benjamin Herrenschmidt
Ok, Here's the new one.
However, I'm not completely happy with it yet. Bart, as you suggested, I
Yeah, I am not happy too.
Quoted 9 lines
moved the state value to drive in order to keep a normal taskfile struct in
rq->special. But that has a drawback: The request beeing re-fetched from the queue on each step, it goes throughstart_requestfor each of them. So I needed a way to know when is the "first pass" so I could initializedrive->pm_stepproperly. I don't want to initialize it prior to queuing the request as it would be racy. In fact, thatpm_stepis really a property of the request itself.I had to add yet another
rq->flagsbit for that, and I think that sucks
You don't have if you use additional, default pm_state (on == 0). This sucks too, but a bit less.
Quoted 14 lines
Also, currently, I'm not passing the "state" argument of the PM callback to the PM request. That argument would be needed if we ever wanted to distinguish between S1,S2,S3,S4.... For example, that could be used to skip the STANDBY pass on suspend-to-disk to avoid the disk spinning down and back up (suspend-to-disk is slow enough already ;)
So I'm considering going back to putting some custom pm state structure in
rq->special, but having this structure hold a taskfile structure as it's first entry so it is transparent to the taskfile interrupt handlers. It's not the prettiest thing, but unless we add more fields to struct request (which would be an option too since those PM requests could be used by _any_ block driver to implement proper power management).
Quoted 4 lines
Jens, Bart, what do you think ? Should I add
pm_step&pm_stateto struct request ? Do the "extended taskfile structure" thing ? Or just keep things like they are in this new patch and forget about carrying the PM state value ?
I think extending struct request is the way to go, pm_step & pm_state or even pointer to rq_pm_struct.
Quoted 8 lines
I also added another
rq->flagsbit for requests forced at the head of the queue withide_preempt. This is typically for sense requests done by ide-cd (though I also spotted a user in the tcq stuff). I need that to make sure that if such a request ever happens to be pushed in front of the current PM request (with thedrive->blockedflag already set), we don't enter an endless loop, fetching that new request and dropping it right away because we only accept PM requests from the queue once the drive is suspended.
Jens, I think generic version of ide_do_drive_cmd() would be useful for other block devices, what do you think?
Regards,
--
Bartlomiej
Quoted 5 lines
Quoted 2 lines
I had to add yet another
rq->flagsbit for that, and I think that sucksYou don't have if you use additional, default
pm_state(on == 0). This sucks too, but a bit less.
Can you elaborate ? I'm not sure I understand what you meant
Quoted 2 lines
I think extending struct request is the way to go,
pm_step&pm_stateor even pointer torq_pm_struct.
Ok. I'll wait for Jens ack and go that way if he agrees.
Ben.
Quoted 6 lines · Benjamin Herrenschmidt
Quoted 4 lines
Quoted 1 line
I had to add yet another
rq->flagsbit for that, and I think that sucksYou don't have if you use additional, default
pm_state(on == 0). This sucks too, but a bit less.Can you elaborate ? I'm not sure I understand what you meant
Forget it, my brain finally got a clue ;) Though I don't like the solution. Adding pm_step & pm_state to struct request or a ptr to rq_pm_struct seem the way to go to me, though I'm not sure which of these 2 solution is the best, struct request is already a can of worms imho... ;) If we ever need more PM fields in there, then the pointer may be the best solution, but right know, I can't think of any reason to add more stuffs
Quoted 6 lines
Quoted 2 lines
I think extending struct request is the way to go,
pm_step&pm_stateor even pointer torq_pm_struct.Ok. I'll wait for Jens ack and go that way if he agrees.
Ben.
Signature · 1 line
Benjamin Herrenschmidt <[email protected]>
Quoted 7 lines · Bartlomiej Zolnierkiewicz
Quoted 4 lines
Jens, Bart, what do you think ? Should I add
pm_step&pm_stateto struct request ? Do the "extended taskfile structure" thing ? Or just keep things like they are in this new patch and forget about carrying the PM state value ?I think extending struct request is the way to go,
pm_step&pm_stateor even pointer torq_pm_struct.
Agree
Quoted 11 lines
Quoted 8 lines
I also added another
rq->flagsbit for requests forced at the head of the queue withide_preempt. This is typically for sense requests done by ide-cd (though I also spotted a user in the tcq stuff). I need that to make sure that if such a request ever happens to be pushed in front of the current PM request (with thedrive->blockedflag already set), we don't enter an endless loop, fetching that new request and dropping it right away because we only accept PM requests from the queue once the drive is suspended.Jens, I think generic version of
ide_do_drive_cmd()would be useful for other block devices, what do you think?
Yes very much so, scsi_ioctl also basically implements part of this functionality.
Signature · 1 line
Jens Axboe
You mean more like a "task management call".
Quoted 61 lines · Bartlomiej Zolnierkiewicz
Quoted 3 lines · Benjamin Herrenschmidt
Ok, Here's the new one.
However, I'm not completely happy with it yet. Bart, as you suggested, I
Yeah, I am not happy too.
Quoted 9 lines
moved the state value to drive in order to keep a normal taskfile struct in
rq->special. But that has a drawback: The request beeing re-fetched from the queue on each step, it goes throughstart_requestfor each of them. So I needed a way to know when is the "first pass" so I could initializedrive->pm_stepproperly. I don't want to initialize it prior to queuing the request as it would be racy. In fact, thatpm_stepis really a property of the request itself.I had to add yet another
rq->flagsbit for that, and I think that sucksYou don't have if you use additional, default
pm_state(on == 0). This sucks too, but a bit less.Quoted 14 lines
Also, currently, I'm not passing the "state" argument of the PM callback to the PM request. That argument would be needed if we ever wanted to distinguish between S1,S2,S3,S4.... For example, that could be used to skip the STANDBY pass on suspend-to-disk to avoid the disk spinning down and back up (suspend-to-disk is slow enough already ;)
So I'm considering going back to putting some custom pm state structure in
rq->special, but having this structure hold a taskfile structure as it's first entry so it is transparent to the taskfile interrupt handlers. It's not the prettiest thing, but unless we add more fields to struct request (which would be an option too since those PM requests could be used by _any_ block driver to implement proper power management).Quoted 4 lines
Jens, Bart, what do you think ? Should I add
pm_step&pm_stateto struct request ? Do the "extended taskfile structure" thing ? Or just keep things like they are in this new patch and forget about carrying the PM state value ?I think extending struct request is the way to go,
pm_step&pm_stateor even pointer torq_pm_struct.Quoted 8 lines
I also added another
rq->flagsbit for requests forced at the head of the queue withide_preempt. This is typically for sense requests done by ide-cd (though I also spotted a user in the tcq stuff). I need that to make sure that if such a request ever happens to be pushed in front of the current PM request (with thedrive->blockedflag already set), we don't enter an endless loop, fetching that new request and dropping it right away because we only accept PM requests from the queue once the drive is suspended.Jens, I think generic version of
ide_do_drive_cmd()would be useful for other block devices, what do you think?Regards,
--
Bartlomiej
Quoted 6 lines
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Andre Hedrick
LAD Storage Consulting Group
Quoted 2 lines · Bartlomiej Zolnierkiewicz
Jens, I think generic version of
ide_do_drive_cmd()would be useful for other block devices, what do you think?
Something ala this? Completely untested, and I only did scsi_ioctl.c and ide-io.c. iirc, scsi uses somthing similar that could be adapted too.
===== drivers/block/ll_rw_blk.c 1.173 vs edited =====
drivers/block/ll_rw_blk.c +49 -0
@@ -1405,6 +1405,55 @@spin_unlock_irqrestore (q->queue_lock, flags); } +/** +* blk_do_request - insert and issue request into block queue +* @bdev: target block device +* @rq: request to be inserted +* @action: where to insert request +* +* Description: +* Insert a request into the block queue at the end or head of the list, +* possibly waiting for its completion. +*/ +int blk_do_request (struct gendisk *disk,struct request *rq,int action) +{ +request_queue_t *q = disk->queue; +DECLARE_COMPLETION (wait); +int err =0 ; + +if (!q) +return -ENODEV ; + + rq->errors =0 ; + rq->rq_disk = disk; + rq->flags |=REQ_NOMERGE ; + +if (action &BLK_RQ_WAIT ) { +/* +* we need an extra reference to the request if we want to +* look at it after io completion +*/ + rq->ref_count++; + rq->waiting = &wait; + } + +elv_add_request (q, rq, action &BLK_RQ_END ,1 ); + +generic_unplug_device (q); + +if (action &BLK_RQ_WAIT ) { +wait_for_completion (&wait); + +if (rq->errors) + err = -EIO ; + +blk_put_request (rq); + } + +return err; +} + +void drive_stat_acct (struct request *rq,int nr_sectors,int new_io) {int rw =rq_data_dir (rq);
===== drivers/block/scsi_ioctl.c 1.29 vs edited =====
drivers/block/scsi_ioctl.c +7 -27
@@ -45,20 +45,11 @@#define SCSI_SENSE_BUFFERSIZE 64#endif -static int blk_do_rq (request_queue_t *q,struct block_device *bdev, -struct request *rq) +#include <scsi/sg.h> + +static int sg_issue_request (struct block_device *bdev,struct request *rq) {char sense[SCSI_SENSE_BUFFERSIZE ]; -DECLARE_COMPLETION (wait); -int err =0 ; - - rq->rq_disk = bdev->bd_disk; - -/* -* we need an extra reference to the request, so we can look at -* it after io completion -*/ - rq->ref_count++;if (!rq->sense) {memset (sense,0 ,sizeof (sense));
@@ -66,20 +57,9 @@ rq->sense_len =0 ; } - rq->flags |=REQ_NOMERGE ; - rq->waiting = &wait; -elv_add_request (q, rq,1 ,1 ); -generic_unplug_device (q); -wait_for_completion (&wait); - -if (rq->errors) - err = -EIO ; - -return err; +return blk_do_request (bdev->bd_disk, rq,BLK_RQ_WAIT |BLK_RQ_END ); } -#include <scsi/sg.h> -static int sg_get_version (int *p) {static int sg_version_num =30527 ;
@@ -248,7 +228,7 @@* (if he doesn't check that is his problem). * N.B. a non-zero SCSI status is _not_ necessarily an error. */ -blk_do_rq (q, bdev, rq); +sg_issue_request (bdev, rq);if (bio)bio_unmap_user (bio, reading);
@@ -376,7 +356,7 @@ rq->data_len = bytes; rq->flags |=REQ_BLOCK_PC ; -blk_do_rq (q, bdev, rq); +sg_issue_request (bdev, rq); err = rq->errors &0xff ;/* only 8 bit SCSI status */ if (err) {if (rq->sense_len && rq->sense) {
@@ -458,7 +438,7 @@ rq->cmd[0 ] =GPCMD_START_STOP_UNIT ; rq->cmd[4 ] =0x02 + (close !=0 ); rq->cmd_len =6 ; - err =blk_do_rq (q, bdev, rq); + err =sg_issue_request (bdev, rq);blk_put_request (rq);break ;default :
===== drivers/ide/ide-io.c 1.11 vs edited =====
drivers/ide/ide-io.c +8 -32
@@ -1278,10 +1278,9 @@int ide_do_drive_cmd (ide_drive_t *drive,struct request *rq,ide_action_t action) { -unsigned long flags;ide_hwgroup_t *hwgroup =HWGROUP (drive);DECLARE_COMPLETION (wait); -int insert_end =1 , err; +int blk_flags =0 ;#ifdef CONFIG_BLK_DEV_PDC4030 /*
@@ -1292,39 +1291,16 @@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 ; - rq->rq_disk = drive->disk; +if (action == ide_wait || action == ide_end) + blk_flags |=BLK_RQ_END ; +if (action == ide_wait) + blk_flags |=BLK_RQ_WAIT ; -/* -* we need to hold an extra reference to request for safe inspection -* after completion -*/ -if (action == ide_wait) { - rq->ref_count++; - rq->waiting = &wait; - } - -spin_lock_irqsave (&ide_lock, flags); -if (action == ide_preempt) { +if (action == ide_preempt) hwgroup->rq =NULL ; - insert_end =0 ; - } -__elv_add_request (&drive->queue, rq, insert_end,0 ); -ide_do_request (hwgroup,IDE_NO_IRQ ); -spin_unlock_irqrestore (&ide_lock, flags); - - err =0 ; -if (action == ide_wait) { -wait_for_completion (&wait); -if (rq->errors) - err = -EIO ; - -blk_put_request (rq); - } - -return err; + +return blk_do_request (drive->disk, rq, blk_flags); }EXPORT_SYMBOL (ide_do_drive_cmd);
===== include/linux/blkdev.h 1.108 vs edited =====
include/linux/blkdev.h +7 -0
@@ -329,6 +329,12 @@#define BLKPREP_KILL 1/* fatal error, kill */ #define BLKPREP_DEFER 2/* leave on queue */ +/* +* blk_do_request actions +*/ +#define BLK_RQ_WAIT 1 +#define BLK_RQ_END 2 +extern unsigned long blk_max_low_pfn, blk_max_pfn;/*
@@ -372,6 +378,7 @@extern struct request *blk_get_request (request_queue_t *,int ,int );extern void blk_put_request (struct request *);extern void blk_insert_request (request_queue_t *,struct request *,int ,void *); +extern int blk_do_request (struct gendisk *,struct request *,int );extern void blk_plug_device (request_queue_t *);extern int blk_remove_plug (request_queue_t *);extern void blk_recount_segments (request_queue_t *,struct bio *);
Signature · 1 line
Jens Axboe
Quoted 6 lines · Jens Axboe
Quoted 2 lines · Bartlomiej Zolnierkiewicz
Jens, I think generic version of
ide_do_drive_cmd()would be useful for other block devices, what do you think?Something ala this? Completely untested, and I only did
scsi_ioctl.candide-io.c. iirc, scsi uses somthing similar that could be adapted too.
Hrm... you didn't keep some functionalities I added with the PM patch here... like marking of preempt requests so I can fetch them even when drive is blocked, and ide_head_wait...
Ben
Quoted 5 lines · Benjamin Herrenschmidt
Quoted 4 lines · Jens Axboe
Quoted 2 lines · Bartlomiej Zolnierkiewicz
Jens, I think generic version of
ide_do_drive_cmd()would be useful for other block devices, what do you think?
Quoted 8 lines
Quoted 2 lines
Something ala this? Completely untested, and I only did
scsi_ioctl.candide-io.c. iirc, scsi uses somthing similar that could be adapted too.Hrm... you didn't keep some functionalities I added with the PM patch here... like marking of preempt requests so I can fetch them even when drive is blocked, and
ide_head_wait...Ben
I've looked for users of ide_preempt in drivers/ide/ and I think that REQ_PREEMPT can later die if we fix drivers to correctly mark sense requests with REQ_SENSE...
--
Bartlomiej
Quoted 3 lines · Bartlomiej Zolnierkiewicz
I've looked for users of
ide_preemptindrivers/ide/and I think thatREQ_PREEMPTcan later die if we fix drivers to correctly mark sense requests withREQ_SENSE...
Ok, I was not sure about REQ_SENSE exact meaning (I suppose the same as REQ_PREEMPT for sense requests sent by the SCSI error handling ? :)
There's also a user in the TCQ stuff
Ben.
Quoted 15 lines · Bartlomiej Zolnierkiewicz
Quoted 12 lines · Benjamin Herrenschmidt
Quoted 6 lines · Jens Axboe
Quoted 2 lines · Bartlomiej Zolnierkiewicz
Jens, I think generic version of
ide_do_drive_cmd()would be useful for other block devices, what do you think?Something ala this? Completely untested, and I only did
scsi_ioctl.candide-io.c. iirc, scsi uses somthing similar that could be adapted too.Hrm... you didn't keep some functionalities I added with the PM patch here... like marking of preempt requests so I can fetch them even when drive is blocked, and
ide_head_wait...
Quoted 5 lines
Quoted 1 line
Ben
I've looked for users of
ide_preemptindrivers/ide/and I think thatREQ_PREEMPTcan later die if we fix drivers to correctly mark sense requests withREQ_SENSE...
Indeed, besides preempt is not really something you can do completely in the block layer safely. So I'd rather kill that logic.
Signature · 1 line
Jens Axboe