diff options
| author | Martin Dalecki <dalecki@evision-ventures.com> | 2002-07-14 03:20:46 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.transmeta.com> | 2002-07-14 03:20:46 -0700 |
| commit | 2dbd15029c00ec56983a240a98306e8ea4101baa (patch) | |
| tree | f355166242752dc1f5f770fcb88fe72fbbc2bd67 /include/linux | |
| parent | 5b2a157778e975a6f66720deca07a3aeed07cafc (diff) | |
[PATCH] IDE 98
Synchronize with 2.5.25.
Incorporate IDE-94, as well as 95, 96, 97 and 98-pre as announced by Bartek and
unfortunately still not included in 2.5.25, which makes admittedly things
still fall appart:
Missing changelog for 98-pre by Bartlomiej Zolnierkiewicz (BTW. Handling
Unicode should be essential at least to make proper crediting of many many
peoples possible!) follows here:
- add missing channel->lock unlocking/locking and fix some comments
in ide_timer_expiry()
- allow PCI drivers to disable autodma in ->init_dma()
(bug introduced in IDE 97, affects sl82c105.c only)
noticed by Russell King
- alim15x3.c, if revision is <= 0x20 disable autodma
- remove unneeded checks (drive.dn > 3) from pdc202xx.c and sis5513.c
- use block layer wrappers
And my additions follow:
- Fix TCQ code. Patch based on work by Alexander Atanasov.
- Use the FreeBSD derived request handler return values:
ATA_OP_FINISHED
ATA_OP_CONTINUES
ATA_OP_RELEASED
ATA_OP_READY /* for status ready reporting during poll */
- PMAC compilation fix by Paul Mackerras.
- Simplify the ata_status_poll function significantly.
- Fix logic used to prevent drive IRQ assertion from drive on channels sharing
our interrupt.
NOTE: We will move it later to the time where a request is really finished
soon.
- Don't use ata_busy_poll() use ata_status_poll() instead. This increases code
unification.
NOTE: We should maybe invent some way to prevent the error recovery path to be
taken at all. In esp to prevent ata_error from trying to reissue commands.
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/atapi.h | 281 | ||||
| -rw-r--r-- | include/linux/blkdev.h | 2 | ||||
| -rw-r--r-- | include/linux/ide.h | 70 |
3 files changed, 307 insertions, 46 deletions
diff --git a/include/linux/atapi.h b/include/linux/atapi.h index 029ae2b6633a..0ac305922e3a 100644 --- a/include/linux/atapi.h +++ b/include/linux/atapi.h @@ -12,6 +12,9 @@ * more details. */ +#include <linux/types.h> +#include <asm/byteorder.h> + /* * With each packet command, we allocate a buffer. * This is used for several packet @@ -79,3 +82,281 @@ extern void atapi_write_zeros(struct ata_device *, unsigned int); extern void atapi_read(struct ata_device *, u8 *, unsigned int); extern void atapi_write(struct ata_device *, u8 *, unsigned int); + +/* + * ATAPI Status Register. + */ +typedef union { + u8 all : 8; + struct { +#if defined(__LITTLE_ENDIAN_BITFIELD) + u8 check : 1; /* Error occurred */ + u8 idx : 1; /* Reserved */ + u8 corr : 1; /* Correctable error occurred */ + u8 drq : 1; /* Data is request by the device */ + u8 dsc : 1; /* Media access command finished / Buffer availability */ + u8 reserved5 : 1; /* Reserved */ + u8 drdy : 1; /* Ignored for ATAPI commands (ready to accept ATA command) */ + u8 bsy : 1; /* The device has access to the command block */ +#elif defined(__BIG_ENDIAN_BITFIELD) + u8 bsy : 1; + u8 drdy : 1; + u8 reserved5 : 1; + u8 dsc : 1; + u8 drq : 1; + u8 corr : 1; + u8 idx : 1; + u8 check : 1; +#else +#error "Please fix <asm/byteorder.h>" +#endif + } b; +} atapi_status_reg_t; + +/* + * ATAPI error register. + */ +typedef union { + u8 all : 8; + struct { +#if defined(__LITTLE_ENDIAN_BITFIELD) + u8 ili : 1; /* Illegal Length Indication */ + u8 eom : 1; /* End Of Media Detected */ + u8 abrt : 1; /* Aborted command - As defined by ATA */ + u8 mcr : 1; /* Media Change Requested - As defined by ATA */ + u8 sense_key : 4; /* Sense key of the last failed packet command */ +#elif defined(__BIG_ENDIAN_BITFIELD) + u8 sense_key : 4; + u8 mcr : 1; + u8 abrt : 1; + u8 eom : 1; + u8 ili : 1; +#else +#error "Please fix <asm/byteorder.h>" +#endif + } b; +} atapi_error_reg_t; + +/* Currently unused, but please do not remove. --bkz */ +/* + * ATAPI Feature Register. + */ +typedef union { + u8 all : 8; + struct { +#if defined(__LITTLE_ENDIAN_BITFIELD) + u8 dma : 1; /* Using DMA or PIO */ + u8 reserved321 : 3; /* Reserved */ + u8 reserved654 : 3; /* Reserved (Tag Type) */ + u8 reserved7 : 1; /* Reserved */ +#elif defined(__BIG_ENDIAN_BITFIELD) + u8 reserved7 : 1; + u8 reserved654 : 3; + u8 reserved321 : 3; + u8 dma : 1; +#else +#error "Please fix <asm/byteorder.h>" +#endif + } b; +} atapi_feature_reg_t; + +/* + * ATAPI Byte Count Register. + */ +typedef union { + u16 all : 16; + struct { +#if defined(__LITTLE_ENDIAN_BITFIELD) + u8 low; /* LSB */ + u8 high; /* MSB */ +#elif defined(__BIG_ENDIAN_BITFIELD) + u8 high; + u8 low; +#else +#error "Please fix <asm/byteorder.h>" +#endif + } b; +} atapi_bcount_reg_t; + +/* + * ATAPI Interrupt Reason Register. + */ +typedef union { + u8 all : 8; + struct { +#if defined(__LITTLE_ENDIAN_BITFIELD) + u8 cod : 1; /* Information transferred is command (1) or data (0) */ + u8 io : 1; /* The device requests us to read (1) or write (0) */ + u8 reserved : 6; /* Reserved */ +#elif defined(__BIG_ENDIAN_BITFIELD) + u8 reserved : 6; + u8 io : 1; + u8 cod : 1; +#else +#error "Please fix <asm/byteorder.h>" +#endif + } b; +} atapi_ireason_reg_t; + +/* Currently unused, but please do not remove. --bkz */ +/* + * ATAPI Drive Select Register. + */ +typedef union { + u8 all :8; + struct { +#if defined(__LITTLE_ENDIAN_BITFIELD) + u8 sam_lun :3; /* Logical unit number */ + u8 reserved3 :1; /* Reserved */ + u8 drv :1; /* The responding drive will be drive 0 (0) or drive 1 (1) */ + u8 one5 :1; /* Should be set to 1 */ + u8 reserved6 :1; /* Reserved */ + u8 one7 :1; /* Should be set to 1 */ +#elif defined(__BIG_ENDIAN_BITFIELD) + u8 one7 :1; + u8 reserved6 :1; + u8 one5 :1; + u8 drv :1; + u8 reserved3 :1; + u8 sam_lun :3; +#else +#error "Please fix <asm/byteorder.h>" +#endif + } b; +} atapi_drivesel_reg_t; + +/* Currently unused, but please do not remove. --bkz */ +/* + * ATAPI Device Control Register. + */ +typedef union { + u8 all : 8; + struct { +#if defined(__LITTLE_ENDIAN_BITFIELD) + u8 zero0 : 1; /* Should be set to zero */ + u8 nien : 1; /* Device interrupt is disabled (1) or enabled (0) */ + u8 srst : 1; /* ATA software reset. ATAPI devices should use the new ATAPI srst. */ + u8 one3 : 1; /* Should be set to 1 */ + u8 reserved4567 : 4; /* Reserved */ +#elif defined(__BIG_ENDIAN_BITFIELD) + u8 reserved4567 : 4; + u8 one3 : 1; + u8 srst : 1; + u8 nien : 1; + u8 zero0 : 1; +#else +#error "Please fix <asm/byteorder.h>" +#endif + } b; +} atapi_control_reg_t; + +/* + * The following is used to format the general configuration word + * of the ATAPI IDENTIFY DEVICE command. + */ +struct atapi_id_gcw { +#if defined(__LITTLE_ENDIAN_BITFIELD) + u8 packet_size : 2; /* Packet Size */ + u8 reserved234 : 3; /* Reserved */ + u8 drq_type : 2; /* Command packet DRQ type */ + u8 removable : 1; /* Removable media */ + u8 device_type : 5; /* Device type */ + u8 reserved13 : 1; /* Reserved */ + u8 protocol : 2; /* Protocol type */ +#elif defined(__BIG_ENDIAN_BITFIELD) + u8 protocol : 2; + u8 reserved13 : 1; + u8 device_type : 5; + u8 removable : 1; + u8 drq_type : 2; + u8 reserved234 : 3; + u8 packet_size : 2; +#else +#error "Please fix <asm/byteorder.h>" +#endif +}; + +/* + * INQUIRY packet command - Data Format. + */ +typedef struct { +#if defined(__LITTLE_ENDIAN_BITFIELD) + u8 device_type : 5; /* Peripheral Device Type */ + u8 reserved0_765 : 3; /* Peripheral Qualifier - Reserved */ + u8 reserved1_6t0 : 7; /* Reserved */ + u8 rmb : 1; /* Removable Medium Bit */ + u8 ansi_version : 3; /* ANSI Version */ + u8 ecma_version : 3; /* ECMA Version */ + u8 iso_version : 2; /* ISO Version */ + u8 response_format : 4; /* Response Data Format */ + u8 reserved3_45 : 2; /* Reserved */ + u8 reserved3_6 : 1; /* TrmIOP - Reserved */ + u8 reserved3_7 : 1; /* AENC - Reserved */ +#elif defined(__BIG_ENDIAN_BITFIELD) + u8 reserved0_765 : 3; + u8 device_type : 5; + u8 rmb : 1; + u8 reserved1_6t0 : 7; + u8 iso_version : 2; + u8 ecma_version : 3; + u8 ansi_version : 3; + u8 reserved3_7 : 1; + u8 reserved3_6 : 1; + u8 reserved3_45 : 2; + u8 response_format : 4; +#else +#error "Please fix <asm/byteorder.h>" +#endif + u8 additional_length; /* Additional Length (total_length-4) */ + u8 rsv5, rsv6, rsv7; /* Reserved */ + u8 vendor_id[8]; /* Vendor Identification */ + u8 product_id[16]; /* Product Identification */ + u8 revision_level[4]; /* Revision Level */ + u8 vendor_specific[20]; /* Vendor Specific - Optional */ + u8 reserved56t95[40]; /* Reserved - Optional */ + /* Additional information may be returned */ +} atapi_inquiry_result_t; + +/* + * REQUEST SENSE packet command result - Data Format. + */ +typedef struct atapi_request_sense { +#if defined(__LITTLE_ENDIAN_BITFIELD) + u8 error_code : 7; /* Error Code (0x70 - current or 0x71 - deferred) */ + u8 valid : 1; /* The information field conforms to standard */ + u8 reserved1 : 8; /* Reserved (Segment Number) */ + u8 sense_key : 4; /* Sense Key */ + u8 reserved2_4 : 1; /* Reserved */ + u8 ili : 1; /* Incorrect Length Indicator */ + u8 eom : 1; /* End Of Medium */ + u8 filemark : 1; /* Filemark */ +#elif defined(__BIG_ENDIAN_BITFIELD) + u8 valid : 1; + u8 error_code : 7; + u8 reserved1 : 8; + u8 filemark : 1; + u8 eom : 1; + u8 ili : 1; + u8 reserved2_4 : 1; + u8 sense_key : 4; +#else +#error "Please fix <asm/byteorder.h>" +#endif + u32 information __attribute__ ((packed)); + u8 asl; /* Additional sense length (n-7) */ + u32 command_specific; /* Additional command specific information */ + u8 asc; /* Additional Sense Code */ + u8 ascq; /* Additional Sense Code Qualifier */ + u8 replaceable_unit_code; /* Field Replaceable Unit Code */ +#if defined(__LITTLE_ENDIAN_BITFIELD) + u8 sk_specific1 : 7; /* Sense Key Specific */ + u8 sksv : 1; /* Sense Key Specific information is valid */ +#elif defined(__BIG_ENDIAN_BITFIELD) + u8 sksv : 1; /* Sense Key Specific information is valid */ + u8 sk_specific1 : 7; /* Sense Key Specific */ +#else +#error "Please fix <asm/byteorder.h>" +#endif + u8 sk_specific[2]; /* Sense Key Specific */ + u8 pad[2]; /* Padding to 20 bytes */ +} atapi_request_sense_result_t; diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index ec38ad1d1f7b..297cb0ba10c1 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -283,7 +283,9 @@ extern void generic_make_request(struct bio *bio); extern inline request_queue_t *bdev_get_queue(struct block_device *bdev); extern void blkdev_release_request(struct request *); extern void blk_attempt_remerge(request_queue_t *, struct request *); +extern void __blk_attempt_remerge(request_queue_t *, struct request *); extern struct request *blk_get_request(request_queue_t *, int, int); +extern struct request *__blk_get_request(request_queue_t *, int); extern void blk_put_request(struct request *); extern void blk_plug_device(request_queue_t *); extern int blk_remove_plug(request_queue_t *); diff --git a/include/linux/ide.h b/include/linux/ide.h index 98426a06e782..4076310675f8 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -372,16 +372,17 @@ struct ata_device { * Status returned by various functions. */ typedef enum { - ide_stopped, /* no drive operation was started */ - ide_started, /* a drive operation was started, and a handler was set */ - ide_released /* started and released bus */ + ATA_OP_FINISHED, /* no drive operation was started */ + ATA_OP_CONTINUES, /* a drive operation was started, and a handler was set */ + ATA_OP_RELEASED, /* started and released bus */ + ATA_OP_READY, /* indicate status poll finished fine */ } ide_startstop_t; /* * Interrupt and timeout handler type. */ typedef ide_startstop_t (ata_handler_t)(struct ata_device *, struct request *); -typedef int (ata_expiry_t)(struct ata_device *, struct request *); +typedef ide_startstop_t (ata_expiry_t)(struct ata_device *, struct request *, unsigned long *); enum { ATA_PRIMARY = 0, @@ -406,7 +407,7 @@ struct ata_channel { ide_startstop_t (*handler)(struct ata_device *, struct request *); /* irq handler, if active */ struct timer_list timer; /* failsafe timer */ - int (*expiry)(struct ata_device *, struct request *); /* irq handler, if active */ + ide_startstop_t (*expiry)(struct ata_device *, struct request *, unsigned long *); /* irq handler, if active */ unsigned long poll_timeout; /* timeout value during polled operations */ struct ata_device *drive; /* last serviced drive */ @@ -456,7 +457,7 @@ struct ata_channel { void (*atapi_read)(struct ata_device *, void *, unsigned int); void (*atapi_write)(struct ata_device *, void *, unsigned int); - int (*udma_setup)(struct ata_device *); + int (*udma_setup)(struct ata_device *, int); void (*udma_enable)(struct ata_device *, int, int); void (*udma_start) (struct ata_device *, struct request *); @@ -496,7 +497,9 @@ struct ata_channel { unsigned unmask : 1; /* flag: okay to unmask other irqs */ unsigned slow : 1; /* flag: slow data port */ unsigned io_32bit : 1; /* 0=16-bit, 1=32-bit */ + unsigned no_atapi_autodma : 1; /* flag: use auto DMA only for disks */ unsigned char bus_state; /* power state of the IDE bus */ + int modes_map; /* map of supported transfer modes */ }; /* @@ -602,9 +605,7 @@ extern int noautodma; #define DEVICE_NR(device) (minor(device) >> PARTN_BITS) #include <linux/blk.h> -/* Not locking and locking variant: */ extern int __ata_end_request(struct ata_device *, struct request *, int, unsigned int); -extern int ata_end_request(struct ata_device *drive, struct request *, int); extern void ata_set_handler(struct ata_device *drive, ata_handler_t handler, unsigned long timeout, ata_expiry_t expiry); @@ -626,12 +627,6 @@ int ide_xlate_1024(kdev_t, int, int, const char *); struct ata_device *get_info_ptr(kdev_t i_rdev); /* - * Re-Start an operation for an IDE interface. - * The caller should return immediately after invoking this. - */ -ide_startstop_t restart_request(struct ata_device *); - -/* * "action" parameter type for ide_do_drive_cmd() below. */ typedef enum { @@ -658,31 +653,7 @@ struct ata_taskfile { extern void ata_read(struct ata_device *, void *, unsigned int); extern void ata_write(struct ata_device *, void *, unsigned int); -/* - * Special Flagged Register Validation Caller - */ - -/* - * for now, taskfile requests are special :/ - */ -static inline char *ide_map_rq(struct request *rq, unsigned long *flags) -{ - if (rq->bio) - return bio_kmap_irq(rq->bio, flags) + ide_rq_offset(rq); - else - return rq->buffer + ((rq)->nr_sectors - (rq)->current_nr_sectors) * SECTOR_SIZE; -} - -static inline void ide_unmap_rq(struct request *rq, char *to, - unsigned long *flags) -{ - if (rq->bio) - bio_kunmap_irq(to, flags); -} - -extern ide_startstop_t ata_special_intr(struct ata_device *, struct request *); -extern int ide_raw_taskfile(struct ata_device *, struct ata_taskfile *); - +extern int ide_raw_taskfile(struct ata_device *, struct ata_taskfile *, char *); extern void ide_fix_driveid(struct hd_driveid *id); extern int ide_config_drive_speed(struct ata_device *, byte); extern byte eighty_ninty_three(struct ata_device *); @@ -756,9 +727,12 @@ static inline void udma_start(struct ata_device *drive, struct request *rq) static inline int udma_stop(struct ata_device *drive) { + int ret; + + ret = drive->channel->udma_stop(drive); clear_bit(IDE_DMA, drive->channel->active); - return drive->channel->udma_stop(drive); + return ret; } /* @@ -766,9 +740,12 @@ static inline int udma_stop(struct ata_device *drive) */ static inline ide_startstop_t udma_init(struct ata_device *drive, struct request *rq) { - int ret = drive->channel->udma_init(drive, rq); - if (ret == ide_started) - set_bit(IDE_DMA, drive->channel->active); + int ret; + + set_bit(IDE_DMA, drive->channel->active); + ret = drive->channel->udma_init(drive, rq); + if (ret != ATA_OP_CONTINUES) + clear_bit(IDE_DMA, drive->channel->active); return ret; } @@ -797,7 +774,9 @@ extern int udma_pci_init(struct ata_device *drive, struct request *rq); extern int udma_pci_irq_status(struct ata_device *drive); extern void udma_pci_timeout(struct ata_device *drive); extern void udma_pci_irq_lost(struct ata_device *); -extern int udma_pci_setup(struct ata_device *); +extern int udma_pci_setup(struct ata_device *, int); + +extern int udma_generic_setup(struct ata_device *, int); extern int udma_new_table(struct ata_device *, struct request *); extern void udma_destroy_table(struct ata_channel *); @@ -830,10 +809,9 @@ extern int drive_is_ready(struct ata_device *drive); extern void ata_select(struct ata_device *, unsigned long); extern void ata_mask(struct ata_device *); -extern int ata_busy_poll(struct ata_device *, unsigned long); extern int ata_status(struct ata_device *, u8, u8); extern int ata_status_poll( struct ata_device *, u8, u8, - unsigned long, struct request *rq, ide_startstop_t *); + unsigned long, struct request *rq); extern int ata_irq_enable(struct ata_device *, int); extern void ata_reset(struct ata_channel *); |
