summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/atapi.h281
-rw-r--r--include/linux/blkdev.h2
-rw-r--r--include/linux/ide.h70
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 *);