From b14c72127fbe8f97e49de7437520175673f7306a Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:30 +0200 Subject: ide: drop dsc_handle argument from ide_pc_intr() * Add 'int dsc' argument to ->pc_callback method. * Call ide_tape_handle_dsc() internally in ide_tape_callback() if dsc argument is set and update ide_pc_intr() accordingly. There should be no functional changes caused by this patch. Cc: Borislav Petkov Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index a9d82d6e6bd..93fd2bc17bf 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -485,7 +485,7 @@ struct ide_drive_s { struct completion gendev_rel_comp; /* to deal with device release() */ /* callback for packet commands */ - void (*pc_callback)(struct ide_drive_s *); + void (*pc_callback)(struct ide_drive_s *, int); unsigned long atapi_flags; }; @@ -1174,7 +1174,7 @@ int ide_set_media_lock(ide_drive_t *, struct gendisk *, int); ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc, ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry, void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *), - void (*retry_pc)(ide_drive_t *), void (*dsc_handle)(ide_drive_t *), + void (*retry_pc)(ide_drive_t *), int (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned int, int)); ide_startstop_t ide_transfer_pc(ide_drive_t *, struct ide_atapi_pc *, -- cgit v1.2.3 From 2b9efba48283f34083df6bc53f6752fba4e4d409 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:31 +0200 Subject: ide: add pointer to the current packet command to ide_drive_t * Add pointer to the current packet command (struct ide_atapi_pc *pc) to ide_drive_t and use it instead of the pointer in struct ide_*_obj. * Use drive->pc in ide_{issue,transfer}_pc() and ide_pc_intr() instead of 'pc' argument. There should be no functional changes caused by this patch. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 93fd2bc17bf..98d29df1ee0 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -322,6 +322,7 @@ typedef enum { ide_started, /* a drive operation was started, handler was set */ } ide_startstop_t; +struct ide_atapi_pc; struct ide_devset; struct ide_driver_s; @@ -484,6 +485,9 @@ struct ide_drive_s { struct device gendev; struct completion gendev_rel_comp; /* to deal with device release() */ + /* current packet command */ + struct ide_atapi_pc *pc; + /* callback for packet commands */ void (*pc_callback)(struct ide_drive_s *, int); @@ -1171,15 +1175,15 @@ int ide_do_test_unit_ready(ide_drive_t *, struct gendisk *); int ide_do_start_stop(ide_drive_t *, struct gendisk *, int); int ide_set_media_lock(ide_drive_t *, struct gendisk *, int); -ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc, +ide_startstop_t ide_pc_intr(ide_drive_t *drive, ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry, void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *), void (*retry_pc)(ide_drive_t *), int (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned int, int)); -ide_startstop_t ide_transfer_pc(ide_drive_t *, struct ide_atapi_pc *, +ide_startstop_t ide_transfer_pc(ide_drive_t *, ide_handler_t *, unsigned int, ide_expiry_t *); -ide_startstop_t ide_issue_pc(ide_drive_t *, struct ide_atapi_pc *, +ide_startstop_t ide_issue_pc(ide_drive_t *, ide_handler_t *, unsigned int, ide_expiry_t *); ide_startstop_t do_rw_taskfile(ide_drive_t *, ide_task_t *); -- cgit v1.2.3 From 844b9468523c8c2c45b90df4efcabcbe4926b5ab Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:31 +0200 Subject: ide: drop 'timeout' and 'expiry' arguments from ide_pc_intr() * Move idescsi_expiry() to ide-atapi.c. * Move get_timeout() to . * Drop 'timeout' and 'expiry' arguments from ide_pc_intr(). While at it: * idescsi_expiry() -> ide_scsi_expiry() * get_timeout() -> ide_scsi_get_timeout() There should be no functional changes caused by this patch. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 98d29df1ee0..3bf2bf0a56d 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1175,8 +1175,14 @@ int ide_do_test_unit_ready(ide_drive_t *, struct gendisk *); int ide_do_start_stop(ide_drive_t *, struct gendisk *, int); int ide_set_media_lock(ide_drive_t *, struct gendisk *, int); -ide_startstop_t ide_pc_intr(ide_drive_t *drive, - ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry, +static inline unsigned long ide_scsi_get_timeout(struct ide_atapi_pc *pc) +{ + return max_t(unsigned long, WAIT_CMD, pc->timeout - jiffies); +} + +int ide_scsi_expiry(ide_drive_t *); + +ide_startstop_t ide_pc_intr(ide_drive_t *drive, ide_handler_t *handler, void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *), void (*retry_pc)(ide_drive_t *), int (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned int, -- cgit v1.2.3 From 67c56364df843fb9e3ed1af014b8fbe4b22ff25d Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:31 +0200 Subject: ide: add request_sense_{pc,rq} to ide_drive_t Add 'struct ide_atapi_pc request_sense_pc' and 'request request_sense_rq' to ide_drive_t and use them instead of fields in struct ide_{floppy,tape}_obj. There should be no functional changes caused by this patch. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 134 ++++++++++++++++++++++++++-------------------------- 1 file changed, 68 insertions(+), 66 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 3bf2bf0a56d..908b4fc9772 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -322,7 +322,71 @@ typedef enum { ide_started, /* a drive operation was started, handler was set */ } ide_startstop_t; -struct ide_atapi_pc; +/* ATAPI packet command flags */ +enum { + /* set when an error is considered normal - no retry (ide-tape) */ + PC_FLAG_ABORT = (1 << 0), + PC_FLAG_SUPPRESS_ERROR = (1 << 1), + PC_FLAG_WAIT_FOR_DSC = (1 << 2), + PC_FLAG_DMA_OK = (1 << 3), + PC_FLAG_DMA_IN_PROGRESS = (1 << 4), + PC_FLAG_DMA_ERROR = (1 << 5), + PC_FLAG_WRITING = (1 << 6), + /* command timed out */ + PC_FLAG_TIMEDOUT = (1 << 7), +}; + +/* + * With each packet command, we allocate a buffer of IDE_PC_BUFFER_SIZE bytes. + * This is used for several packet commands (not for READ/WRITE commands). + */ +#define IDE_PC_BUFFER_SIZE 256 + +struct ide_atapi_pc { + /* actual packet bytes */ + u8 c[12]; + /* incremented on each retry */ + int retries; + int error; + + /* bytes to transfer */ + int req_xfer; + /* bytes actually transferred */ + int xferred; + + /* data buffer */ + u8 *buf; + /* current buffer position */ + u8 *cur_pos; + int buf_size; + /* missing/available data on the current buffer */ + int b_count; + + /* the corresponding request */ + struct request *rq; + + unsigned long flags; + + /* + * those are more or less driver-specific and some of them are subject + * to change/removal later. + */ + u8 pc_buf[IDE_PC_BUFFER_SIZE]; + + /* idetape only */ + struct idetape_bh *bh; + char *b_data; + + /* idescsi only for now */ + struct scatterlist *sg; + unsigned int sg_cnt; + + struct scsi_cmnd *scsi_cmd; + void (*done) (struct scsi_cmnd *); + + unsigned long timeout; +}; + struct ide_devset; struct ide_driver_s; @@ -492,6 +556,9 @@ struct ide_drive_s { void (*pc_callback)(struct ide_drive_s *, int); unsigned long atapi_flags; + + struct ide_atapi_pc request_sense_pc; + struct request request_sense_rq; }; typedef struct ide_drive_s ide_drive_t; @@ -768,71 +835,6 @@ ide_decl_devset(pio_mode); ide_decl_devset(unmaskirq); ide_decl_devset(using_dma); -/* ATAPI packet command flags */ -enum { - /* set when an error is considered normal - no retry (ide-tape) */ - PC_FLAG_ABORT = (1 << 0), - PC_FLAG_SUPPRESS_ERROR = (1 << 1), - PC_FLAG_WAIT_FOR_DSC = (1 << 2), - PC_FLAG_DMA_OK = (1 << 3), - PC_FLAG_DMA_IN_PROGRESS = (1 << 4), - PC_FLAG_DMA_ERROR = (1 << 5), - PC_FLAG_WRITING = (1 << 6), - /* command timed out */ - PC_FLAG_TIMEDOUT = (1 << 7), -}; - -/* - * With each packet command, we allocate a buffer of IDE_PC_BUFFER_SIZE bytes. - * This is used for several packet commands (not for READ/WRITE commands). - */ -#define IDE_PC_BUFFER_SIZE 256 - -struct ide_atapi_pc { - /* actual packet bytes */ - u8 c[12]; - /* incremented on each retry */ - int retries; - int error; - - /* bytes to transfer */ - int req_xfer; - /* bytes actually transferred */ - int xferred; - - /* data buffer */ - u8 *buf; - /* current buffer position */ - u8 *cur_pos; - int buf_size; - /* missing/available data on the current buffer */ - int b_count; - - /* the corresponding request */ - struct request *rq; - - unsigned long flags; - - /* - * those are more or less driver-specific and some of them are subject - * to change/removal later. - */ - u8 pc_buf[IDE_PC_BUFFER_SIZE]; - - /* idetape only */ - struct idetape_bh *bh; - char *b_data; - - /* idescsi only for now */ - struct scatterlist *sg; - unsigned int sg_cnt; - - struct scsi_cmnd *scsi_cmd; - void (*done) (struct scsi_cmnd *); - - unsigned long timeout; -}; - #ifdef CONFIG_IDE_PROC_FS /* * /proc/ide interface -- cgit v1.2.3 From 6b0da28b2d0f4f4e2c55689fc062db569075ff60 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:32 +0200 Subject: ide: add ide_retry_pc() helper * Add ide_create_request_sense_cmd() and ide_retry_pc() helpers and convert ide-{atapi,floppy,tape}.c to use them. * Remove no longer used ide*_create_request_sense_cmd(), ide*_retry_pc() and 'retry_pc' argument from ide_pc_intr(). * Make ide_queue_pc_head() static. There should be no functional changes caused by this patch. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 908b4fc9772..d88cced0d02 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1169,13 +1169,13 @@ enum { REQ_IDETAPE_WRITE = (1 << 3), }; -void ide_queue_pc_head(ide_drive_t *, struct gendisk *, struct ide_atapi_pc *, - struct request *); int ide_queue_pc_tail(ide_drive_t *, struct gendisk *, struct ide_atapi_pc *); int ide_do_test_unit_ready(ide_drive_t *, struct gendisk *); int ide_do_start_stop(ide_drive_t *, struct gendisk *, int); int ide_set_media_lock(ide_drive_t *, struct gendisk *, int); +void ide_create_request_sense_cmd(ide_drive_t *, struct ide_atapi_pc *); +void ide_retry_pc(ide_drive_t *, struct gendisk *); static inline unsigned long ide_scsi_get_timeout(struct ide_atapi_pc *pc) { @@ -1186,7 +1186,6 @@ int ide_scsi_expiry(ide_drive_t *); ide_startstop_t ide_pc_intr(ide_drive_t *drive, ide_handler_t *handler, void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *), - void (*retry_pc)(ide_drive_t *), int (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned int, int)); ide_startstop_t ide_transfer_pc(ide_drive_t *, -- cgit v1.2.3 From 85e39035ca381846b031690f4d1ac1f0660da0a2 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:32 +0200 Subject: ide: add ->pc_{update,io}_buffers methods Add ->pc_{update,io}_buffers methods to ide_drive_t and use them instead of {update,io}_buffers ide_pc_intr() arguments. There should be no functional changes caused by this patch. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index d88cced0d02..f7fc53d1a81 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -555,6 +555,10 @@ struct ide_drive_s { /* callback for packet commands */ void (*pc_callback)(struct ide_drive_s *, int); + void (*pc_update_buffers)(struct ide_drive_s *, struct ide_atapi_pc *); + int (*pc_io_buffers)(struct ide_drive_s *, struct ide_atapi_pc *, + unsigned int, int); + unsigned long atapi_flags; struct ide_atapi_pc request_sense_pc; @@ -1184,10 +1188,7 @@ static inline unsigned long ide_scsi_get_timeout(struct ide_atapi_pc *pc) int ide_scsi_expiry(ide_drive_t *); -ide_startstop_t ide_pc_intr(ide_drive_t *drive, ide_handler_t *handler, - void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *), - int (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned int, - int)); +ide_startstop_t ide_pc_intr(ide_drive_t *drive, ide_handler_t *handler); ide_startstop_t ide_transfer_pc(ide_drive_t *, ide_handler_t *, unsigned int, ide_expiry_t *); ide_startstop_t ide_issue_pc(ide_drive_t *, -- cgit v1.2.3 From aa5d2de7b080873f6d9ac3aede423c9713bf0caa Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:32 +0200 Subject: ide: make ide_pc_intr() static * Always use ide_pc_intr as a handler in ide_pc_intr(). * Remove no longer used ide*_pc_intr() and 'handler' argument from ide_{transfer_pc,pc_intr}(). * Make ide_pc_intr() static. There should be no functional changes caused by this patch. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index f7fc53d1a81..449a1094700 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1188,9 +1188,7 @@ static inline unsigned long ide_scsi_get_timeout(struct ide_atapi_pc *pc) int ide_scsi_expiry(ide_drive_t *); -ide_startstop_t ide_pc_intr(ide_drive_t *drive, ide_handler_t *handler); -ide_startstop_t ide_transfer_pc(ide_drive_t *, - ide_handler_t *, unsigned int, ide_expiry_t *); +ide_startstop_t ide_transfer_pc(ide_drive_t *, unsigned int, ide_expiry_t *); ide_startstop_t ide_issue_pc(ide_drive_t *, ide_handler_t *, unsigned int, ide_expiry_t *); -- cgit v1.2.3 From baf08f0be6d986521bb2fbdc7af51fc4847da734 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:32 +0200 Subject: ide: make ide_transfer_pc() static * Move ->ticks field from struct ide_floppy_obj to ide_drive_t. * Move idefloppy_transfer_pc() to ide-atapi.c and make ide_transfer_pc() use it. * Always use ide_transfer_pc as a handler in ide_issue_pc(). * Remove no longer used idefloppy_start_pc_transfer(), ide*_transfer_pc() and 'handler' argument from ide_issue_pc(). * Make ide_transfer_pc() static. While at it: * idefloppy_transfer_pc() -> ide_delayed_transfer_pc() * IDEFLOPPY_TICKS_DELAY -> IDEFLOPPY_PC_DELAY * ->ticks -> ->pc_delay There should be no functional changes caused by this patch. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 449a1094700..85cb96c1fd6 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -531,6 +531,9 @@ struct ide_drive_s { u8 bios_head; /* BIOS/fdisk/LILO number of heads */ u8 bios_sect; /* BIOS/fdisk/LILO sectors per track */ + /* delay this long before sending packet command */ + u8 pc_delay; + unsigned int bios_cyl; /* BIOS/fdisk/LILO number of cyls */ unsigned int cyl; /* "real" number of cyls */ unsigned int drive_data; /* used by set_pio_mode/selectproc */ @@ -1188,9 +1191,7 @@ static inline unsigned long ide_scsi_get_timeout(struct ide_atapi_pc *pc) int ide_scsi_expiry(ide_drive_t *); -ide_startstop_t ide_transfer_pc(ide_drive_t *, unsigned int, ide_expiry_t *); -ide_startstop_t ide_issue_pc(ide_drive_t *, - ide_handler_t *, unsigned int, ide_expiry_t *); +ide_startstop_t ide_issue_pc(ide_drive_t *, unsigned int, ide_expiry_t *); ide_startstop_t do_rw_taskfile(ide_drive_t *, ide_task_t *); -- cgit v1.2.3 From 5aeddf907f149cae7e19b7c23ccea3823d00698c Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Mon, 13 Oct 2008 21:39:34 +0200 Subject: ide: unify conversion macros Introduce to_ide_drv() and ide_drv_g() macros and replace the respective definitions of similar ones in each driver. There should be no functionality change resulting from this patch. Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 85cb96c1fd6..350ef47ed61 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -570,7 +570,13 @@ struct ide_drive_s { typedef struct ide_drive_s ide_drive_t; -#define to_ide_device(dev)container_of(dev, ide_drive_t, gendev) +#define to_ide_device(dev) container_of(dev, ide_drive_t, gendev) + +#define to_ide_drv(obj, cont_type) \ + container_of(obj, struct cont_type, kref) + +#define ide_drv_g(disk, cont_type) \ + container_of((disk)->private_data, struct cont_type, driver) struct ide_task_s; struct ide_port_info; -- cgit v1.2.3 From b22b2ca4ff0730b14d14bcc36bd1b84873557512 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Mon, 13 Oct 2008 21:39:34 +0200 Subject: ide: add drive->debug_mask switch Add a debugging on/off switch for controlling driver debugging messages dynamically. Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 350ef47ed61..fcd98e1d186 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -545,6 +545,9 @@ struct ide_drive_s { int lun; /* logical unit */ int crc_count; /* crc counter to reduce drive speed */ + + unsigned long debug_mask; /* debugging levels switch */ + #ifdef CONFIG_BLK_DEV_IDEACPI struct ide_acpi_drive_link *acpidata; #endif -- cgit v1.2.3 From e1c7c4641aae8d278fca62b3b5cffad3a8dcb0a4 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Mon, 13 Oct 2008 21:39:35 +0200 Subject: ide: add a driver-wide debugging macro Add __ide_debug_log() debugging macro which is controlled by drive->debug_mask. The macro has to have the macro DRV_NAME defined in each driver before use. Also, add different debugging levels depending on the functionality debugged. Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index fcd98e1d186..02c4c642e6a 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -927,6 +927,26 @@ static inline void ide_proc_unregister_driver(ide_drive_t *drive, ide_driver_t * #define PROC_IDE_READ_RETURN(page,start,off,count,eof,len) return 0; #endif +enum { + /* enter/exit functions */ + IDE_DBG_FUNC = (1 << 0), + /* sense key/asc handling */ + IDE_DBG_SENSE = (1 << 1), + /* packet commands handling */ + IDE_DBG_PC = (1 << 2), + /* request handling */ + IDE_DBG_RQ = (1 << 3), + /* driver probing/setup */ + IDE_DBG_PROBE = (1 << 4), +}; + +/* DRV_NAME has to be defined in the driver before using the macro below */ +#define __ide_debug_log(lvl, fmt, args...) \ +{ \ + if (unlikely(drive->debug_mask & lvl)) \ + printk(KERN_INFO DRV_NAME ": " fmt, ## args); \ +} + /* * Power Management step value (rq->pm->pm_step). * -- cgit v1.2.3 From 35c137531245118962eb40a550661afe317bec03 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:36 +0200 Subject: ide-disk: set_addressing() fixes * Return -EIO if arg > 0 and LBA48 is unsupported. * No need to reset ->addressing. * Make ->addressing a single bit flag. Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 02c4c642e6a..90d53c99fe9 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -509,7 +509,7 @@ struct ide_drive_s { unsigned sleeping : 1; /* 1=sleeping & sleep field valid */ unsigned post_reset : 1; unsigned udma33_warned : 1; - unsigned addressing : 2; /* 0=28-bit, 1=48-bit, 2=48-bit doing 28-bit */ + unsigned addressing : 1; /* 0=28-bit, 1=48-bit */ unsigned wcache : 1; /* status of write cache */ unsigned nowerr : 1; /* used for ignoring ATA_DF */ -- cgit v1.2.3 From 97100fc816badbbc162644cfde7ad39ae9211fb4 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:36 +0200 Subject: ide: add device flags Add 'unsigned long dev_flags' to ide_drive_t and convert bitfields to IDE_DFLAG_* flags. While at it: - IDE_DFLAG_ADDRESSING -> IDE_DFLAG_LBA48 - fixup some comments - remove needless g->flags zeroing from ide*_probe() There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 100 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 73 insertions(+), 27 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 90d53c99fe9..b538d2e6dcb 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -459,6 +459,55 @@ enum { IDE_AFLAG_NO_AUTOCLOSE = (1 << 29), }; +/* device flags */ +enum { + /* restore settings after device reset */ + IDE_DFLAG_KEEP_SETTINGS = (1 << 0), + /* device is using DMA for read/write */ + IDE_DFLAG_USING_DMA = (1 << 1), + /* okay to unmask other IRQs */ + IDE_DFLAG_UNMASK = (1 << 2), + /* don't attempt flushes */ + IDE_DFLAG_NOFLUSH = (1 << 3), + /* DSC overlap */ + IDE_DFLAG_DSC_OVERLAP = (1 << 4), + /* give potential excess bandwidth */ + IDE_DFLAG_NICE1 = (1 << 5), + /* device is physically present */ + IDE_DFLAG_PRESENT = (1 << 6), + /* device ejected hint */ + IDE_DFLAG_DEAD = (1 << 7), + /* id read from device (synthetic if not set) */ + IDE_DFLAG_ID_READ = (1 << 8), + IDE_DFLAG_NOPROBE = (1 << 9), + /* need to do check_media_change() */ + IDE_DFLAG_REMOVABLE = (1 << 10), + /* needed for removable devices */ + IDE_DFLAG_ATTACH = (1 << 11), + IDE_DFLAG_FORCED_GEOM = (1 << 12), + /* disallow setting unmask bit */ + IDE_DFLAG_NO_UNMASK = (1 << 13), + /* disallow enabling 32-bit I/O */ + IDE_DFLAG_NO_IO_32BIT = (1 << 14), + /* for removable only: door lock/unlock works */ + IDE_DFLAG_DOORLOCKING = (1 << 15), + /* disallow DMA */ + IDE_DFLAG_NODMA = (1 << 16), + /* powermanagment told us not to do anything, so sleep nicely */ + IDE_DFLAG_BLOCKED = (1 << 17), + /* ide-scsi emulation */ + IDE_DFLAG_SCSI = (1 << 18), + /* sleeping & sleep field valid */ + IDE_DFLAG_SLEEPING = (1 << 19), + IDE_DFLAG_POST_RESET = (1 << 20), + IDE_DFLAG_UDMA33_WARNED = (1 << 21), + IDE_DFLAG_LBA48 = (1 << 22), + /* status of write cache */ + IDE_DFLAG_WCACHE = (1 << 23), + /* used for ignoring ATA_DF */ + IDE_DFLAG_NOWERR = (1 << 24), +}; + struct ide_drive_s { char name[4]; /* drive name, such as "hda" */ char driver_req[10]; /* requests specific driver */ @@ -475,6 +524,8 @@ struct ide_drive_s { #endif struct hwif_s *hwif; /* actually (ide_hwif_t *) */ + unsigned long dev_flags; + unsigned long sleep; /* sleep until this time */ unsigned long service_start; /* time we started last request */ unsigned long service_time; /* service time of last request */ @@ -487,32 +538,6 @@ struct ide_drive_s { u8 state; /* retry state */ u8 waiting_for_dma; /* dma currently in progress */ - unsigned keep_settings : 1; /* restore settings after drive reset */ - unsigned using_dma : 1; /* disk is using dma for read/write */ - unsigned unmask : 1; /* okay to unmask other irqs */ - unsigned noflush : 1; /* don't attempt flushes */ - unsigned dsc_overlap : 1; /* DSC overlap */ - unsigned nice1 : 1; /* give potential excess bandwidth */ - unsigned present : 1; /* drive is physically present */ - unsigned dead : 1; /* device ejected hint */ - unsigned id_read : 1; /* 1=id read from disk 0 = synthetic */ - unsigned noprobe : 1; /* from: hdx=noprobe */ - unsigned removable : 1; /* 1 if need to do check_media_change */ - unsigned attach : 1; /* needed for removable devices */ - unsigned forced_geom : 1; /* 1 if hdx=c,h,s was given at boot */ - unsigned no_unmask : 1; /* disallow setting unmask bit */ - unsigned no_io_32bit : 1; /* disallow enabling 32bit I/O */ - unsigned doorlocking : 1; /* for removable only: door lock/unlock works */ - unsigned nodma : 1; /* disallow DMA */ - unsigned blocked : 1; /* 1=powermanagment told us not to do anything, so sleep nicely */ - unsigned scsi : 1; /* 0=default, 1=ide-scsi emulation */ - unsigned sleeping : 1; /* 1=sleeping & sleep field valid */ - unsigned post_reset : 1; - unsigned udma33_warned : 1; - unsigned addressing : 1; /* 0=28-bit, 1=48-bit */ - unsigned wcache : 1; /* status of write cache */ - unsigned nowerr : 1; /* used for ignoring ATA_DF */ - u8 quirk_list; /* considered quirky, set for a specific host */ u8 init_speed; /* transfer rate set at boot */ u8 current_speed; /* current transfer rate set */ @@ -826,6 +851,22 @@ static int set_##name(ide_drive_t *drive, int arg) \ return 0; \ } +#define ide_devset_get_flag(name, flag) \ +static int get_##name(ide_drive_t *drive) \ +{ \ + return !!(drive->dev_flags & flag); \ +} + +#define ide_devset_set_flag(name, flag) \ +static int set_##name(ide_drive_t *drive, int arg) \ +{ \ + if (arg) \ + drive->dev_flags |= flag; \ + else \ + drive->dev_flags &= ~flag; \ + return 0; \ +} + #define __IDE_DEVSET(_name, _flags, _get, _set) \ const struct ide_devset ide_devset_##_name = \ __DEVSET(_flags, _get, _set) @@ -861,6 +902,11 @@ ide_devset_get(_name, _field); \ ide_devset_set(_name, _field); \ IDE_DEVSET(_name, DS_SYNC, get_##_name, set_##_name) +#define ide_devset_rw_flag(_name, _field) \ +ide_devset_get_flag(_name, _field); \ +ide_devset_set_flag(_name, _field); \ +IDE_DEVSET(_name, DS_SYNC, get_##_name, set_##_name) + struct ide_proc_devset { const char *name; const struct ide_devset *setting; @@ -1587,6 +1633,6 @@ static inline ide_drive_t *ide_get_pair_dev(ide_drive_t *drive) { ide_drive_t *peer = &drive->hwif->drives[(drive->dn ^ 1) & 1]; - return peer->present ? peer : NULL; + return (peer->dev_flags & IDE_DFLAG_PRESENT) ? peer : NULL; } #endif /* _IDE_H */ -- cgit v1.2.3 From c39220483ebe6871fb129d4b2236cd95290c41fc Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:37 +0200 Subject: ide: DMA_PIO_RETRY -> IDE_DFLAG_DMA_PIO_RETRY Add IDE_DFLAG_DMA_PIO_RETRY and use it instead of ide_drive_t.state + DMA_PIO_RETRY. There should be no functional changes cause by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index b538d2e6dcb..230bd9dd851 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -48,12 +48,6 @@ typedef unsigned char byte; /* used everywhere */ #define ERROR_RESET 3 /* Reset controller every 4th retry */ #define ERROR_RECAL 1 /* Recalibrate every 2nd retry */ -/* - * state flags - */ - -#define DMA_PIO_RETRY 1 /* retrying in PIO */ - #define HWIF(drive) ((ide_hwif_t *)((drive)->hwif)) #define HWGROUP(drive) ((ide_hwgroup_t *)(HWIF(drive)->hwgroup)) @@ -506,6 +500,8 @@ enum { IDE_DFLAG_WCACHE = (1 << 23), /* used for ignoring ATA_DF */ IDE_DFLAG_NOWERR = (1 << 24), + /* retrying in PIO */ + IDE_DFLAG_DMA_PIO_RETRY = (1 << 25), }; struct ide_drive_s { @@ -535,7 +531,6 @@ struct ide_drive_s { select_t select; /* basic drive/head select reg value */ u8 retry_pio; /* retrying dma capable host in pio */ - u8 state; /* retry state */ u8 waiting_for_dma; /* dma currently in progress */ u8 quirk_list; /* considered quirky, set for a specific host */ -- cgit v1.2.3 From 0ae4b3199ab1b6d511c6e0948e92049c272a346a Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:37 +0200 Subject: ide: remove superfluous ->media field from ide_driver_t Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 230bd9dd851..7fd1ec13551 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1029,7 +1029,6 @@ enum { */ struct ide_driver_s { const char *version; - u8 media; ide_startstop_t (*do_request)(ide_drive_t *, struct request *, sector_t); int (*end_request)(ide_drive_t *, int, int); ide_startstop_t (*error)(ide_drive_t *, struct request *rq, u8, u8); -- cgit v1.2.3 From e4634d4ef04fe6d7b114b612e5b71a84187ce76a Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:37 +0200 Subject: ide: remove superfluous ->dma field from ide_hwif_t Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 7fd1ec13551..fdec0108dba 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -756,8 +756,6 @@ typedef struct hwif_s { void *hwif_data; /* extra hwif data */ - unsigned dma; - #ifdef CONFIG_BLK_DEV_IDEACPI struct ide_acpi_hwif_link *acpidata; #endif -- cgit v1.2.3 From d1d76714e2f0c520b6c2a84ab5b050d0b3244949 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:38 +0200 Subject: ide: fix HDIO_DRIVE_TASK[FILE] ioctls for CHS commands on LBA devices Add IDE_DFLAG_LBA device flag and use it instead of ->select.b.lba. Since ->tf_load uses ->select.all for ATA Device/Head register this fixes HDIO_DRIVE_TASK[FILE] ioctls for CHS commands on LBA devices. Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index fdec0108dba..cf7ec3a9d17 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -502,6 +502,7 @@ enum { IDE_DFLAG_NOWERR = (1 << 24), /* retrying in PIO */ IDE_DFLAG_DMA_PIO_RETRY = (1 << 25), + IDE_DFLAG_LBA = (1 << 26), }; struct ide_drive_s { -- cgit v1.2.3 From 0d346ba0730d84f04022f9f984d3f606f69cef37 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:38 +0200 Subject: ide: sanitize ide*_pm_* enums * Move ide*_pm_* enums from ide-io.c to . * idedisk_pm_* -> ide_pm_* * ide_pm_state_* -> ide_pm_* * No need to set ide_pm_* enums to the fixed values. * Uppercase ide_pm_* enums. * Fix/update comments. Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index cf7ec3a9d17..02984f1f041 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -988,36 +988,34 @@ enum { } /* - * Power Management step value (rq->pm->pm_step). + * Power Management state machine (rq->pm->pm_step). * - * The step value starts at 0 (ide_pm_state_start_suspend) for a - * suspend operation or 1000 (ide_pm_state_start_resume) for a - * resume operation. - * - * For each step, the core calls the subdriver start_power_step() first. + * For each step, the core calls ide_start_power_step() first. * This can return: * - ide_stopped : In this case, the core calls us back again unless * step have been set to ide_power_state_completed. * - ide_started : In this case, the channel is left busy until an * async event (interrupt) occurs. - * Typically, start_power_step() will issue a taskfile request with + * Typically, ide_start_power_step() will issue a taskfile request with * do_rw_taskfile(). * - * Upon reception of the interrupt, the core will call complete_power_step() + * Upon reception of the interrupt, the core will call ide_complete_power_step() * with the error code if any. This routine should update the step value * and return. It should not start a new request. The core will call - * start_power_step for the new step value, unless step have been set to - * ide_power_state_completed. - * - * Subdrivers are expected to define their own additional power - * steps from 1..999 for suspend and from 1001..1999 for resume, - * other values are reserved for future use. + * ide_start_power_step() for the new step value, unless step have been + * set to IDE_PM_COMPLETED. */ - enum { - ide_pm_state_completed = -1, - ide_pm_state_start_suspend = 0, - ide_pm_state_start_resume = 1000, + IDE_PM_START_SUSPEND, + IDE_PM_FLUSH_CACHE = IDE_PM_START_SUSPEND, + IDE_PM_STANDBY, + + IDE_PM_START_RESUME, + IDE_PM_RESTORE_PIO = IDE_PM_START_RESUME, + IDE_PM_IDLE, + IDE_PM_RESTORE_DMA, + + IDE_PM_COMPLETED, }; /* -- cgit v1.2.3 From 7f612f272ad8abe82411f368bfacf793b466e1b3 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:40 +0200 Subject: ide: remove [ata_]select_t * Use 'drive->dn & 1' in ide_init_disk(). * remove [ata_]select_t. While at it: * Use ATA_DEVICE_OBS define in ide_port_init_devices_data(). Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 32 +------------------------------- 1 file changed, 1 insertion(+), 31 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 02984f1f041..3e418b996ef 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -278,36 +278,6 @@ typedef union { } b; } special_t; -/* - * ATA-IDE Select Register, aka Device-Head - * - * head : always zeros here - * unit : drive select number: 0/1 - * bit5 : always 1 - * lba : using LBA instead of CHS - * bit7 : always 1 - */ -typedef union { - unsigned all : 8; - struct { -#if defined(__LITTLE_ENDIAN_BITFIELD) - unsigned head : 4; - unsigned unit : 1; - unsigned bit5 : 1; - unsigned lba : 1; - unsigned bit7 : 1; -#elif defined(__BIG_ENDIAN_BITFIELD) - unsigned bit7 : 1; - unsigned lba : 1; - unsigned bit5 : 1; - unsigned unit : 1; - unsigned head : 4; -#else -#error "Please fix " -#endif - } b; -} select_t, ata_select_t; - /* * Status returned from various ide_ functions */ @@ -529,8 +499,8 @@ struct ide_drive_s { unsigned long timeout; /* max time to wait for irq */ special_t special; /* special action flags */ - select_t select; /* basic drive/head select reg value */ + u8 select; /* basic drive/head select reg value */ u8 retry_pio; /* retrying dma capable host in pio */ u8 waiting_for_dma; /* dma currently in progress */ -- cgit v1.2.3 From 6982daf71ca9a0b0c36043315e1968b3cb709b7c Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:40 +0200 Subject: ide: convert 'pio_mode' device setting to use DS_SYNC flag * Convert 'pio_mode' device setting to use DS_SYNC flag. * Remove unused special_t.b.{set_tune,serviced} and ide_drive_t.tune_req. Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 3e418b996ef..a5e1888b1da 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -262,8 +262,6 @@ static inline int __ide_default_irq(unsigned long base) * set_geometry : respecify drive geometry * recalibrate : seek to cyl 0 * set_multmode : set multmode count - * set_tune : tune interface for drive - * serviced : service command * reserved : unused */ typedef union { @@ -272,9 +270,7 @@ typedef union { unsigned set_geometry : 1; unsigned recalibrate : 1; unsigned set_multmode : 1; - unsigned set_tune : 1; - unsigned serviced : 1; - unsigned reserved : 3; + unsigned reserved : 5; } b; } special_t; @@ -514,7 +510,6 @@ struct ide_drive_s { u8 ready_stat; /* min status value for drive ready */ u8 mult_count; /* current multiple sector setting */ u8 mult_req; /* requested multiple sector setting */ - u8 tune_req; /* requested drive tuning setting */ u8 io_32bit; /* 0=16-bit, 1=32-bit, 2/3=32bit+sync */ u8 bad_wstat; /* used for ignoring ATA_DF */ u8 head; /* "real" number of heads */ -- cgit v1.2.3 From d6ff9f64e68d23feab44efa07cc6aee01f3ef32b Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:41 +0200 Subject: ide: merge all TASKFILE_NO_DATA data phase handlers into taskfile_no_intr() * Add 'struct task_s' to ide_hwif_t and init it to the current command in do_rw_taskfile(). * Merge all TASKFILE_NO_DATA data phase handlers into taskfile_no_intr(). Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 211 ++++++++++++++++++++++++++-------------------------- 1 file changed, 106 insertions(+), 105 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index a5e1888b1da..14d489c2e5a 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -282,6 +282,110 @@ typedef enum { ide_started, /* a drive operation was started, handler was set */ } ide_startstop_t; +enum { + IDE_TFLAG_LBA48 = (1 << 0), + IDE_TFLAG_FLAGGED = (1 << 2), + IDE_TFLAG_OUT_DATA = (1 << 3), + IDE_TFLAG_OUT_HOB_FEATURE = (1 << 4), + IDE_TFLAG_OUT_HOB_NSECT = (1 << 5), + IDE_TFLAG_OUT_HOB_LBAL = (1 << 6), + IDE_TFLAG_OUT_HOB_LBAM = (1 << 7), + IDE_TFLAG_OUT_HOB_LBAH = (1 << 8), + IDE_TFLAG_OUT_HOB = IDE_TFLAG_OUT_HOB_FEATURE | + IDE_TFLAG_OUT_HOB_NSECT | + IDE_TFLAG_OUT_HOB_LBAL | + IDE_TFLAG_OUT_HOB_LBAM | + IDE_TFLAG_OUT_HOB_LBAH, + IDE_TFLAG_OUT_FEATURE = (1 << 9), + IDE_TFLAG_OUT_NSECT = (1 << 10), + IDE_TFLAG_OUT_LBAL = (1 << 11), + IDE_TFLAG_OUT_LBAM = (1 << 12), + IDE_TFLAG_OUT_LBAH = (1 << 13), + IDE_TFLAG_OUT_TF = IDE_TFLAG_OUT_FEATURE | + IDE_TFLAG_OUT_NSECT | + IDE_TFLAG_OUT_LBAL | + IDE_TFLAG_OUT_LBAM | + IDE_TFLAG_OUT_LBAH, + IDE_TFLAG_OUT_DEVICE = (1 << 14), + IDE_TFLAG_WRITE = (1 << 15), + IDE_TFLAG_FLAGGED_SET_IN_FLAGS = (1 << 16), + IDE_TFLAG_IN_DATA = (1 << 17), + IDE_TFLAG_CUSTOM_HANDLER = (1 << 18), + IDE_TFLAG_DMA_PIO_FALLBACK = (1 << 19), + IDE_TFLAG_IN_HOB_FEATURE = (1 << 20), + IDE_TFLAG_IN_HOB_NSECT = (1 << 21), + IDE_TFLAG_IN_HOB_LBAL = (1 << 22), + IDE_TFLAG_IN_HOB_LBAM = (1 << 23), + IDE_TFLAG_IN_HOB_LBAH = (1 << 24), + IDE_TFLAG_IN_HOB_LBA = IDE_TFLAG_IN_HOB_LBAL | + IDE_TFLAG_IN_HOB_LBAM | + IDE_TFLAG_IN_HOB_LBAH, + IDE_TFLAG_IN_HOB = IDE_TFLAG_IN_HOB_FEATURE | + IDE_TFLAG_IN_HOB_NSECT | + IDE_TFLAG_IN_HOB_LBA, + IDE_TFLAG_IN_FEATURE = (1 << 1), + IDE_TFLAG_IN_NSECT = (1 << 25), + IDE_TFLAG_IN_LBAL = (1 << 26), + IDE_TFLAG_IN_LBAM = (1 << 27), + IDE_TFLAG_IN_LBAH = (1 << 28), + IDE_TFLAG_IN_LBA = IDE_TFLAG_IN_LBAL | + IDE_TFLAG_IN_LBAM | + IDE_TFLAG_IN_LBAH, + IDE_TFLAG_IN_TF = IDE_TFLAG_IN_NSECT | + IDE_TFLAG_IN_LBA, + IDE_TFLAG_IN_DEVICE = (1 << 29), + IDE_TFLAG_HOB = IDE_TFLAG_OUT_HOB | + IDE_TFLAG_IN_HOB, + IDE_TFLAG_TF = IDE_TFLAG_OUT_TF | + IDE_TFLAG_IN_TF, + IDE_TFLAG_DEVICE = IDE_TFLAG_OUT_DEVICE | + IDE_TFLAG_IN_DEVICE, + /* force 16-bit I/O operations */ + IDE_TFLAG_IO_16BIT = (1 << 30), + /* ide_task_t was allocated using kmalloc() */ + IDE_TFLAG_DYN = (1 << 31), +}; + +struct ide_taskfile { + u8 hob_data; /* 0: high data byte (for TASKFILE IOCTL) */ + + u8 hob_feature; /* 1-5: additional data to support LBA48 */ + u8 hob_nsect; + u8 hob_lbal; + u8 hob_lbam; + u8 hob_lbah; + + u8 data; /* 6: low data byte (for TASKFILE IOCTL) */ + + union { /*  7: */ + u8 error; /* read: error */ + u8 feature; /* write: feature */ + }; + + u8 nsect; /* 8: number of sectors */ + u8 lbal; /* 9: LBA low */ + u8 lbam; /* 10: LBA mid */ + u8 lbah; /* 11: LBA high */ + + u8 device; /* 12: device select */ + + union { /* 13: */ + u8 status; /*  read: status  */ + u8 command; /* write: command */ + }; +}; + +typedef struct ide_task_s { + union { + struct ide_taskfile tf; + u8 tf_array[14]; + }; + u32 tf_flags; + int data_phase; + struct request *rq; /* copy of request */ + void *special; /* valid_t generally */ +} ide_task_t; + /* ATAPI packet command flags */ enum { /* set when an error is considered normal - no retry (ide-tape) */ @@ -567,7 +671,6 @@ typedef struct ide_drive_s ide_drive_t; #define ide_drv_g(disk, cont_type) \ container_of((disk)->private_data, struct cont_type, driver) -struct ide_task_s; struct ide_port_info; struct ide_tp_ops { @@ -694,6 +797,8 @@ typedef struct hwif_s { /* data phase of the active command (currently only valid for PIO/DMA) */ int data_phase; + struct ide_task_s task; /* current command */ + unsigned int nsect; unsigned int nleft; struct scatterlist *cursg; @@ -1059,110 +1164,6 @@ extern void ide_do_drive_cmd(ide_drive_t *, struct request *); extern void ide_end_drive_cmd(ide_drive_t *, u8, u8); -enum { - IDE_TFLAG_LBA48 = (1 << 0), - IDE_TFLAG_FLAGGED = (1 << 2), - IDE_TFLAG_OUT_DATA = (1 << 3), - IDE_TFLAG_OUT_HOB_FEATURE = (1 << 4), - IDE_TFLAG_OUT_HOB_NSECT = (1 << 5), - IDE_TFLAG_OUT_HOB_LBAL = (1 << 6), - IDE_TFLAG_OUT_HOB_LBAM = (1 << 7), - IDE_TFLAG_OUT_HOB_LBAH = (1 << 8), - IDE_TFLAG_OUT_HOB = IDE_TFLAG_OUT_HOB_FEATURE | - IDE_TFLAG_OUT_HOB_NSECT | - IDE_TFLAG_OUT_HOB_LBAL | - IDE_TFLAG_OUT_HOB_LBAM | - IDE_TFLAG_OUT_HOB_LBAH, - IDE_TFLAG_OUT_FEATURE = (1 << 9), - IDE_TFLAG_OUT_NSECT = (1 << 10), - IDE_TFLAG_OUT_LBAL = (1 << 11), - IDE_TFLAG_OUT_LBAM = (1 << 12), - IDE_TFLAG_OUT_LBAH = (1 << 13), - IDE_TFLAG_OUT_TF = IDE_TFLAG_OUT_FEATURE | - IDE_TFLAG_OUT_NSECT | - IDE_TFLAG_OUT_LBAL | - IDE_TFLAG_OUT_LBAM | - IDE_TFLAG_OUT_LBAH, - IDE_TFLAG_OUT_DEVICE = (1 << 14), - IDE_TFLAG_WRITE = (1 << 15), - IDE_TFLAG_FLAGGED_SET_IN_FLAGS = (1 << 16), - IDE_TFLAG_IN_DATA = (1 << 17), - IDE_TFLAG_CUSTOM_HANDLER = (1 << 18), - IDE_TFLAG_DMA_PIO_FALLBACK = (1 << 19), - IDE_TFLAG_IN_HOB_FEATURE = (1 << 20), - IDE_TFLAG_IN_HOB_NSECT = (1 << 21), - IDE_TFLAG_IN_HOB_LBAL = (1 << 22), - IDE_TFLAG_IN_HOB_LBAM = (1 << 23), - IDE_TFLAG_IN_HOB_LBAH = (1 << 24), - IDE_TFLAG_IN_HOB_LBA = IDE_TFLAG_IN_HOB_LBAL | - IDE_TFLAG_IN_HOB_LBAM | - IDE_TFLAG_IN_HOB_LBAH, - IDE_TFLAG_IN_HOB = IDE_TFLAG_IN_HOB_FEATURE | - IDE_TFLAG_IN_HOB_NSECT | - IDE_TFLAG_IN_HOB_LBA, - IDE_TFLAG_IN_FEATURE = (1 << 1), - IDE_TFLAG_IN_NSECT = (1 << 25), - IDE_TFLAG_IN_LBAL = (1 << 26), - IDE_TFLAG_IN_LBAM = (1 << 27), - IDE_TFLAG_IN_LBAH = (1 << 28), - IDE_TFLAG_IN_LBA = IDE_TFLAG_IN_LBAL | - IDE_TFLAG_IN_LBAM | - IDE_TFLAG_IN_LBAH, - IDE_TFLAG_IN_TF = IDE_TFLAG_IN_NSECT | - IDE_TFLAG_IN_LBA, - IDE_TFLAG_IN_DEVICE = (1 << 29), - IDE_TFLAG_HOB = IDE_TFLAG_OUT_HOB | - IDE_TFLAG_IN_HOB, - IDE_TFLAG_TF = IDE_TFLAG_OUT_TF | - IDE_TFLAG_IN_TF, - IDE_TFLAG_DEVICE = IDE_TFLAG_OUT_DEVICE | - IDE_TFLAG_IN_DEVICE, - /* force 16-bit I/O operations */ - IDE_TFLAG_IO_16BIT = (1 << 30), - /* ide_task_t was allocated using kmalloc() */ - IDE_TFLAG_DYN = (1 << 31), -}; - -struct ide_taskfile { - u8 hob_data; /* 0: high data byte (for TASKFILE IOCTL) */ - - u8 hob_feature; /* 1-5: additional data to support LBA48 */ - u8 hob_nsect; - u8 hob_lbal; - u8 hob_lbam; - u8 hob_lbah; - - u8 data; /* 6: low data byte (for TASKFILE IOCTL) */ - - union { /*  7: */ - u8 error; /* read: error */ - u8 feature; /* write: feature */ - }; - - u8 nsect; /* 8: number of sectors */ - u8 lbal; /* 9: LBA low */ - u8 lbam; /* 10: LBA mid */ - u8 lbah; /* 11: LBA high */ - - u8 device; /* 12: device select */ - - union { /* 13: */ - u8 status; /*  read: status  */ - u8 command; /* write: command */ - }; -}; - -typedef struct ide_task_s { - union { - struct ide_taskfile tf; - u8 tf_array[14]; - }; - u32 tf_flags; - int data_phase; - struct request *rq; /* copy of request */ - void *special; /* valid_t generally */ -} ide_task_t; - void ide_tf_dump(const char *, struct ide_taskfile *); void ide_exec_command(ide_hwif_t *, u8); -- cgit v1.2.3 From bfa7d8e55f0c5ae22ef57eb22942c74fdde7b9bd Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:42 +0200 Subject: ide: ->ide_dma_clear_irq() -> ->clear_irq() * Rename ->ide_dma_clear_irq method to ->clear_irq and move it from ide_hwif_t to struct ide_port_ops. * Move ->waiting_for_dma check inside ->clear_irq method. * Move ->dma_base check inside ->clear_irq method. piix.c: * Add ich_port_ops and remove init_hwif_ich() wrapper. There should be no functional changes caused by this patch. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 14d489c2e5a..37a4344f384 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -704,6 +704,7 @@ extern const struct ide_tp_ops default_tp_ops; * @resetproc: routine to reset controller after a disk reset * @maskproc: special host masking for drive selection * @quirkproc: check host's drive quirk list + * @clear_irq: clear IRQ * * @mdma_filter: filter MDMA modes * @udma_filter: filter UDMA modes @@ -720,6 +721,7 @@ struct ide_port_ops { void (*resetproc)(ide_drive_t *); void (*maskproc)(ide_drive_t *, int); void (*quirkproc)(ide_drive_t *); + void (*clear_irq)(ide_drive_t *); u8 (*mdma_filter)(ide_drive_t *); u8 (*udma_filter)(ide_drive_t *); @@ -782,8 +784,6 @@ typedef struct hwif_s { const struct ide_port_ops *port_ops; const struct ide_dma_ops *dma_ops; - void (*ide_dma_clear_irq)(ide_drive_t *drive); - /* dma physical region descriptor table (cpu view) */ unsigned int *dmatable_cpu; /* dma physical region descriptor table (dma view) */ -- cgit v1.2.3 From a36223b0dc14606b5c80aacbbe6288133693a841 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:43 +0200 Subject: ide: remove ide_host_alloc_all() * Remove no longer used ide_host_alloc_all(). * Add MAX_HOST_PORTS define and use it instead of MAX_HWIFS as the maximum number of host ports possible. Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 37a4344f384..86fa030e802 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -832,8 +832,10 @@ typedef struct hwif_s { #endif } ____cacheline_internodealigned_in_smp ide_hwif_t; +#define MAX_HOST_PORTS 4 + struct ide_host { - ide_hwif_t *ports[MAX_HWIFS]; + ide_hwif_t *ports[MAX_HOST_PORTS]; unsigned int n_ports; struct device *dev[2]; unsigned int (*init_chipset)(struct pci_dev *); @@ -1479,7 +1481,6 @@ void ide_undecoded_slave(ide_drive_t *); void ide_port_apply_params(ide_hwif_t *); -struct ide_host *ide_host_alloc_all(const struct ide_port_info *, hw_regs_t **); struct ide_host *ide_host_alloc(const struct ide_port_info *, hw_regs_t **); void ide_host_free(struct ide_host *); int ide_host_register(struct ide_host *, const struct ide_port_info *, -- cgit v1.2.3 From f87904898e91923a91b925078ac933f05076c7fd Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:45 +0200 Subject: ide-disk: move all ioctl handling to ide-disk_ioctl.c While at it: - idedisk_ioctl() -> ide_disk_ioctl() Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 86fa030e802..7ce245e6c6a 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -946,8 +946,11 @@ IDE_DEVSET(_name, 0, get_##_func, set_##_func) #define ide_devset_w(_name, _func) \ IDE_DEVSET(_name, 0, NULL, set_##_func) -#define ide_devset_rw_sync(_name, _func) \ -IDE_DEVSET(_name, DS_SYNC, get_##_func, set_##_func) +#define ide_ext_devset_rw(_name, _func) \ +__IDE_DEVSET(_name, 0, get_##_func, set_##_func) + +#define ide_ext_devset_rw_sync(_name, _func) \ +__IDE_DEVSET(_name, DS_SYNC, get_##_func, set_##_func) #define ide_decl_devset(_name) \ extern const struct ide_devset ide_devset_##_name -- cgit v1.2.3 From 653bcf5292a9ac4ffc07315198f0ef995e0646a8 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:46 +0200 Subject: ide: __ide_dma_end() -> ide_dma_end() While at it: - use EXPORT_SYMBOL_GPL() to match the rest of SFF DMA functions Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 7ce245e6c6a..22f7451f7b4 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1435,7 +1435,7 @@ void ide_dma_host_set(ide_drive_t *, int); extern int ide_dma_setup(ide_drive_t *); void ide_dma_exec_cmd(ide_drive_t *, u8); extern void ide_dma_start(ide_drive_t *); -extern int __ide_dma_end(ide_drive_t *); +int ide_dma_end(ide_drive_t *); int ide_dma_test_irq(ide_drive_t *); extern void ide_dma_lost_irq(ide_drive_t *); extern void ide_dma_timeout(ide_drive_t *); -- cgit v1.2.3 From de23ec9ca82357e6d337a2263befb1a65cf19c83 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:46 +0200 Subject: ide: make ide_dma_lost_irq() available also for CONFIG_BLK_DEV_IDEDMA_SFF=n Make ide_dma_lost_irq() available also for CONFIG_BLK_DEV_IDEDMA_SFF=n and convert {ics,au1xxx-}ide.c to use it. While at it: - use EXPORT_SYMBOL_GPL() to match the rest of SFF DMA functions Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 22f7451f7b4..ae4a25d2b06 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1437,11 +1437,12 @@ void ide_dma_exec_cmd(ide_drive_t *, u8); extern void ide_dma_start(ide_drive_t *); int ide_dma_end(ide_drive_t *); int ide_dma_test_irq(ide_drive_t *); -extern void ide_dma_lost_irq(ide_drive_t *); extern void ide_dma_timeout(ide_drive_t *); extern const struct ide_dma_ops sff_dma_ops; #endif /* CONFIG_BLK_DEV_IDEDMA_SFF */ +void ide_dma_lost_irq(ide_drive_t *); + #else static inline int ide_id_dma_bug(ide_drive_t *drive) { return 0; } static inline u8 ide_find_dma_mode(ide_drive_t *drive, u8 speed) { return 0; } -- cgit v1.2.3 From ffa15a6915b7f6f6f69b4a66e1100a9c68d11250 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:46 +0200 Subject: ide: make ide_dma_timeout() available also for CONFIG_BLK_DEV_IDEDMA_SFF=n Make ide_dma_timeout() available also for CONFIG_BLK_DEV_IDEDMA_SFF=n and convert {ics,au1xxx-}ide.c to use it. While at it: - dump ATA Status register content on error - use EXPORT_SYMBOL_GPL() to match the rest of SFF DMA functions Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index ae4a25d2b06..39aaff8ff45 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1437,11 +1437,11 @@ void ide_dma_exec_cmd(ide_drive_t *, u8); extern void ide_dma_start(ide_drive_t *); int ide_dma_end(ide_drive_t *); int ide_dma_test_irq(ide_drive_t *); -extern void ide_dma_timeout(ide_drive_t *); extern const struct ide_dma_ops sff_dma_ops; #endif /* CONFIG_BLK_DEV_IDEDMA_SFF */ void ide_dma_lost_irq(ide_drive_t *); +void ide_dma_timeout(ide_drive_t *); #else static inline int ide_id_dma_bug(ide_drive_t *drive) { return 0; } -- cgit v1.2.3 From 2bbd57cad3d72334c9fcc4e229a5a5b04dc6aebc Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:47 +0200 Subject: ide: switch to DMA-mapping API part #2 Follow-up to commit 5c05ff68b9a9b40a9be949497e0aa980185565cf ("ide: switch to DMA-mapping API"): * pci_{alloc,free}_consistent() -> dma_{alloc,free}_coherent() in ide_{allocate,release}_dma_engine(). * Add ->prd_max_nents and ->prd_ent_size fields to ide_hwif_t (+ set default values in ide_allocate_dma_engine()). * Make ide_{allocate,release}_dma_engine() available also for CONFIG_BLK_DEV_IDEDMA_SFF=n. Then convert au1xxx-ide.c, scc_pata.c and sgiioc4.c to use them. * Add missing ->init_dma method to scc_pata. This patch also fixes: - ->dmatable_cpu leak for au1xxx-ide - too early realease of ->dmatable_cpu for scc_pata - wrong amount of ->dmatable_cpu memory being freed for sgiioc4 While at it: - remove superfluous ->dma_base check from ide_unregister() - return -ENOMEM on error in ide_release_dma_engine() - beautify error message in ide_release_dma_engine() Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 39aaff8ff45..8121aa9240c 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -788,6 +788,12 @@ typedef struct hwif_s { unsigned int *dmatable_cpu; /* dma physical region descriptor table (dma view) */ dma_addr_t dmatable_dma; + + /* maximum number of PRD table entries */ + int prd_max_nents; + /* PRD entry size in bytes */ + int prd_ent_size; + /* Scatter-gather list used to build the above */ struct scatterlist *sg_table; int sg_max_nents; /* Maximum number of entries in it */ @@ -1423,14 +1429,14 @@ int ide_set_dma(ide_drive_t *); void ide_check_dma_crc(ide_drive_t *); ide_startstop_t ide_dma_intr(ide_drive_t *); +int ide_allocate_dma_engine(ide_hwif_t *); +void ide_release_dma_engine(ide_hwif_t *); + int ide_build_sglist(ide_drive_t *, struct request *); void ide_destroy_dmatable(ide_drive_t *); #ifdef CONFIG_BLK_DEV_IDEDMA_SFF extern int ide_build_dmatable(ide_drive_t *, struct request *); -int ide_allocate_dma_engine(ide_hwif_t *); -void ide_release_dma_engine(ide_hwif_t *); - void ide_dma_host_set(ide_drive_t *, int); extern int ide_dma_setup(ide_drive_t *); void ide_dma_exec_cmd(ide_drive_t *, u8); @@ -1453,11 +1459,8 @@ static inline void ide_dma_on(ide_drive_t *drive) { ; } static inline void ide_dma_verbose(ide_drive_t *drive) { ; } static inline int ide_set_dma(ide_drive_t *drive) { return 1; } static inline void ide_check_dma_crc(ide_drive_t *drive) { ; } -#endif /* CONFIG_BLK_DEV_IDEDMA */ - -#ifndef CONFIG_BLK_DEV_IDEDMA_SFF static inline void ide_release_dma_engine(ide_hwif_t *hwif) { ; } -#endif +#endif /* CONFIG_BLK_DEV_IDEDMA */ #ifdef CONFIG_BLK_DEV_IDEACPI extern int ide_acpi_exec_tfs(ide_drive_t *drive); -- cgit v1.2.3 From 2dbe7e919eb696c86790797f8a814bef19a0d50a Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:47 +0200 Subject: ide: move SFF DMA code to ide-dma-sff.c Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 8121aa9240c..5a39dab2cc9 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1412,6 +1412,7 @@ struct drive_list_entry { int ide_in_drive_list(u16 *, const struct drive_list_entry *); #ifdef CONFIG_BLK_DEV_IDEDMA +int ide_dma_good_drive(ide_drive_t *); int __ide_dma_bad_drive(ide_drive_t *); int ide_id_dma_bug(ide_drive_t *); @@ -1436,6 +1437,7 @@ int ide_build_sglist(ide_drive_t *, struct request *); void ide_destroy_dmatable(ide_drive_t *); #ifdef CONFIG_BLK_DEV_IDEDMA_SFF +int config_drive_for_dma(ide_drive_t *); extern int ide_build_dmatable(ide_drive_t *, struct request *); void ide_dma_host_set(ide_drive_t *, int); extern int ide_dma_setup(ide_drive_t *); @@ -1444,6 +1446,8 @@ extern void ide_dma_start(ide_drive_t *); int ide_dma_end(ide_drive_t *); int ide_dma_test_irq(ide_drive_t *); extern const struct ide_dma_ops sff_dma_ops; +#else +static inline int config_drive_for_dma(ide_drive_t *drive) { return 0; } #endif /* CONFIG_BLK_DEV_IDEDMA_SFF */ void ide_dma_lost_irq(ide_drive_t *); -- cgit v1.2.3 From 0a9b6f8864362e31e348b12922a92b48b1b8cc94 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Mon, 13 Oct 2008 21:39:49 +0200 Subject: ide: add ide_drive_t.dma flag This flag is to accomodate ide-cd functionality into ide atapi. There should be no functionality change resulting from this patch. Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 5a39dab2cc9..8247b286838 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -603,6 +603,7 @@ struct ide_drive_s { u8 select; /* basic drive/head select reg value */ u8 retry_pio; /* retrying dma capable host in pio */ u8 waiting_for_dma; /* dma currently in progress */ + u8 dma; /* atapi dma flag */ u8 quirk_list; /* considered quirky, set for a specific host */ u8 init_speed; /* transfer rate set at boot */ -- cgit v1.2.3 From 4abdc6ee7c47a1a6e12f95717e461baeebee5df7 Mon Sep 17 00:00:00 2001 From: Elias Oltmanns Date: Mon, 13 Oct 2008 21:39:50 +0200 Subject: ide: Implement disk shock protection support (v4) On user request (through sysfs), the IDLE IMMEDIATE command with UNLOAD FEATURE as specified in ATA-7 is issued to the device and processing of the request queue is stopped thereafter until the specified timeout expires or user space asks to resume normal operation. This is supposed to prevent the heads of a hard drive from accidentally crashing onto the platter when a heavy shock is anticipated (like a falling laptop expected to hit the floor). Port resets are deferred whenever a device on that port is in the parked state. v3: Elias Oltmanns wrote: [...] > >> 1. Make sure that no negative value is being passed to > >> jiffies_to_msecs() in ide_park_show(). > >> 2. Drop the superfluous variable hwif in ide_special_rq(). > >> 3. Skip initialisation of task and tf in ide_special_rq() if we are not > >> handling a (un)park request. > > > > Well, #3 should have been done differently because we donn't want to > > check for REQ_(UN)?PARK_HEADS more often than is necessary. > > While preparing the backport to 2.6.27, it has just occurred to me that > we need to clear the IDE_DFLAG_PARKED flag in ide_disk_pre_reset() > because this flag must not be set after *any* sort of access to the > device. v4: Fix a memory leak due to a missing blk_put_request() in issue_park_cmd(). Additionally, we should plug the queue when enqueueing the unpark request because there is no guarantee that the park timeout has not expired by then. Even though the chance for that to happen is very slim, the request might end up hanging in the queue until the next I/O operation is queued up. While at it, clean up the code a little: - make issue_park_cmd() a function of type void since nobody cares for the return value anyway; - use blk_start_queueing() instead of __blk_run_queue() since we don't have to worry about recursion; - remove a superfluous pointer deference in task_no_data_intr(). Signed-off-by: Elias Oltmanns Cc: Jeff Garzik , Cc: Randy Dunlap Cc: Tejun Heo Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 8247b286838..c47e371554c 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -156,6 +156,8 @@ enum { */ #define REQ_DRIVE_RESET 0x20 #define REQ_DEVSET_EXEC 0x21 +#define REQ_PARK_HEADS 0x22 +#define REQ_UNPARK_HEADS 0x23 /* * Check for an interrupt and acknowledge the interrupt status @@ -573,6 +575,10 @@ enum { /* retrying in PIO */ IDE_DFLAG_DMA_PIO_RETRY = (1 << 25), IDE_DFLAG_LBA = (1 << 26), + /* don't unload heads */ + IDE_DFLAG_NO_UNLOAD = (1 << 27), + /* heads unloaded, please don't reset port */ + IDE_DFLAG_PARKED = (1 << 28) }; struct ide_drive_s { @@ -1207,6 +1213,13 @@ int ide_check_atapi_device(ide_drive_t *, const char *); void ide_init_pc(struct ide_atapi_pc *); +/* Disk head parking */ +extern wait_queue_head_t ide_park_wq; +ssize_t ide_park_show(struct device *dev, struct device_attribute *attr, + char *buf); +ssize_t ide_park_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t len); + /* * Special requests for ide-tape block device strategy routine. * -- cgit v1.2.3