📄 ide-floppy.c
字号:
typedef union { unsigned all :8; struct {#if defined(__LITTLE_ENDIAN_BITFIELD) unsigned ili :1; /* Illegal Length Indication */ unsigned eom :1; /* End Of Media Detected */ unsigned abrt :1; /* Aborted command - As defined by ATA */ unsigned mcr :1; /* Media Change Requested - As defined by ATA */ unsigned sense_key :4; /* Sense key of the last failed packet command */#elif defined(__BIG_ENDIAN_BITFIELD) unsigned sense_key :4; /* Sense key of the last failed packet command */ unsigned mcr :1; /* Media Change Requested - As defined by ATA */ unsigned abrt :1; /* Aborted command - As defined by ATA */ unsigned eom :1; /* End Of Media Detected */ unsigned ili :1; /* Illegal Length Indication */#else#error "Bitfield endianness not defined! Check your byteorder.h"#endif } b;} idefloppy_error_reg_t;/* * ATAPI Feature Register */typedef union { unsigned all :8; struct {#if defined(__LITTLE_ENDIAN_BITFIELD) unsigned dma :1; /* Using DMA or PIO */ unsigned reserved321 :3; /* Reserved */ unsigned reserved654 :3; /* Reserved (Tag Type) */ unsigned reserved7 :1; /* Reserved */#elif defined(__BIG_ENDIAN_BITFIELD) unsigned reserved7 :1; /* Reserved */ unsigned reserved654 :3; /* Reserved (Tag Type) */ unsigned reserved321 :3; /* Reserved */ unsigned dma :1; /* Using DMA or PIO */#else#error "Bitfield endianness not defined! Check your byteorder.h"#endif } b;} idefloppy_feature_reg_t;/* * ATAPI Byte Count Register. */typedef union { unsigned all :16; struct {#if defined(__LITTLE_ENDIAN_BITFIELD) unsigned low :8; /* LSB */ unsigned high :8; /* MSB */#elif defined(__BIG_ENDIAN_BITFIELD) unsigned high :8; /* MSB */ unsigned low :8; /* LSB */#else#error "Bitfield endianness not defined! Check your byteorder.h"#endif } b;} idefloppy_bcount_reg_t;/* * ATAPI Interrupt Reason Register. */typedef union { unsigned all :8; struct {#if defined(__LITTLE_ENDIAN_BITFIELD) unsigned cod :1; /* Information transferred is command (1) or data (0) */ unsigned io :1; /* The device requests us to read (1) or write (0) */ unsigned reserved :6; /* Reserved */#elif defined(__BIG_ENDIAN_BITFIELD) unsigned reserved :6; /* Reserved */ unsigned io :1; /* The device requests us to read (1) or write (0) */ unsigned cod :1; /* Information transferred is command (1) or data (0) */#else#error "Bitfield endianness not defined! Check your byteorder.h"#endif } b;} idefloppy_ireason_reg_t;/* * ATAPI floppy Drive Select Register */typedef union { unsigned all :8; struct {#if defined(__LITTLE_ENDIAN_BITFIELD) unsigned sam_lun :3; /* Logical unit number */ unsigned reserved3 :1; /* Reserved */ unsigned drv :1; /* The responding drive will be drive 0 (0) or drive 1 (1) */ unsigned one5 :1; /* Should be set to 1 */ unsigned reserved6 :1; /* Reserved */ unsigned one7 :1; /* Should be set to 1 */#elif defined(__BIG_ENDIAN_BITFIELD) unsigned one7 :1; /* Should be set to 1 */ unsigned reserved6 :1; /* Reserved */ unsigned one5 :1; /* Should be set to 1 */ unsigned drv :1; /* The responding drive will be drive 0 (0) or drive 1 (1) */ unsigned reserved3 :1; /* Reserved */ unsigned sam_lun :3; /* Logical unit number */#else#error "Bitfield endianness not defined! Check your byteorder.h"#endif } b;} idefloppy_drivesel_reg_t;/* * ATAPI Device Control Register */typedef union { unsigned all :8; struct {#if defined(__LITTLE_ENDIAN_BITFIELD) unsigned zero0 :1; /* Should be set to zero */ unsigned nien :1; /* Device interrupt is disabled (1) or enabled (0) */ unsigned srst :1; /* ATA software reset. ATAPI devices should use the new ATAPI srst. */ unsigned one3 :1; /* Should be set to 1 */ unsigned reserved4567 :4; /* Reserved */#elif defined(__BIG_ENDIAN_BITFIELD) unsigned reserved4567 :4; /* Reserved */ unsigned one3 :1; /* Should be set to 1 */ unsigned srst :1; /* ATA software reset. ATAPI devices should use the new ATAPI srst. */ unsigned nien :1; /* Device interrupt is disabled (1) or enabled (0) */ unsigned zero0 :1; /* Should be set to zero */#else#error "Bitfield endianness not defined! Check your byteorder.h"#endif } b;} idefloppy_control_reg_t;/* * The following is used to format the general configuration word of * the ATAPI IDENTIFY DEVICE command. */struct idefloppy_id_gcw { #if defined(__LITTLE_ENDIAN_BITFIELD) unsigned packet_size :2; /* Packet Size */ unsigned reserved234 :3; /* Reserved */ unsigned drq_type :2; /* Command packet DRQ type */ unsigned removable :1; /* Removable media */ unsigned device_type :5; /* Device type */ unsigned reserved13 :1; /* Reserved */ unsigned protocol :2; /* Protocol type */#elif defined(__BIG_ENDIAN_BITFIELD) unsigned protocol :2; /* Protocol type */ unsigned reserved13 :1; /* Reserved */ unsigned device_type :5; /* Device type */ unsigned removable :1; /* Removable media */ unsigned drq_type :2; /* Command packet DRQ type */ unsigned reserved234 :3; /* Reserved */ unsigned packet_size :2; /* Packet Size */#else#error "Bitfield endianness not defined! Check your byteorder.h"#endif};/* * INQUIRY packet command - Data Format */typedef struct {#if defined(__LITTLE_ENDIAN_BITFIELD) unsigned device_type :5; /* Peripheral Device Type */ unsigned reserved0_765 :3; /* Peripheral Qualifier - Reserved */ unsigned reserved1_6t0 :7; /* Reserved */ unsigned rmb :1; /* Removable Medium Bit */ unsigned ansi_version :3; /* ANSI Version */ unsigned ecma_version :3; /* ECMA Version */ unsigned iso_version :2; /* ISO Version */ unsigned response_format :4; /* Response Data Format */ unsigned reserved3_45 :2; /* Reserved */ unsigned reserved3_6 :1; /* TrmIOP - Reserved */ unsigned reserved3_7 :1; /* AENC - Reserved */#elif defined(__BIG_ENDIAN_BITFIELD) unsigned reserved0_765 :3; /* Peripheral Qualifier - Reserved */ unsigned device_type :5; /* Peripheral Device Type */ unsigned rmb :1; /* Removable Medium Bit */ unsigned reserved1_6t0 :7; /* Reserved */ unsigned iso_version :2; /* ISO Version */ unsigned ecma_version :3; /* ECMA Version */ unsigned ansi_version :3; /* ANSI Version */ unsigned reserved3_7 :1; /* AENC - Reserved */ unsigned reserved3_6 :1; /* TrmIOP - Reserved */ unsigned reserved3_45 :2; /* Reserved */ unsigned response_format :4; /* Response Data Format */#else#error "Bitfield endianness not defined! Check your 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 */} idefloppy_inquiry_result_t;/* * REQUEST SENSE packet command result - Data Format. */typedef struct {#if defined(__LITTLE_ENDIAN_BITFIELD) unsigned error_code :7; /* Current error (0x70) */ unsigned valid :1; /* The information field conforms to SFF-8070i */ u8 reserved1 :8; /* Reserved */ unsigned sense_key :4; /* Sense Key */ unsigned reserved2_4 :1; /* Reserved */ unsigned ili :1; /* Incorrect Length Indicator */ unsigned reserved2_67 :2;#elif defined(__BIG_ENDIAN_BITFIELD) unsigned valid :1; /* The information field conforms to SFF-8070i */ unsigned error_code :7; /* Current error (0x70) */ u8 reserved1 :8; /* Reserved */ unsigned reserved2_67 :2; unsigned ili :1; /* Incorrect Length Indicator */ unsigned reserved2_4 :1; /* Reserved */ unsigned sense_key :4; /* Sense Key */#else#error "Bitfield endianness not defined! Check your 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 */ u8 sksv[3]; u8 pad[2]; /* Padding to 20 bytes */} idefloppy_request_sense_result_t;/* * Pages of the SELECT SENSE / MODE SENSE packet commands. */#define IDEFLOPPY_CAPABILITIES_PAGE 0x1b#define IDEFLOPPY_FLEXIBLE_DISK_PAGE 0x05/* * Mode Parameter Header for the MODE SENSE packet command */typedef struct { u16 mode_data_length; /* Length of the following data transfer */ u8 medium_type; /* Medium Type */#if defined(__LITTLE_ENDIAN_BITFIELD) unsigned reserved3 :7; unsigned wp :1; /* Write protect */#elif defined(__BIG_ENDIAN_BITFIELD) unsigned wp :1; /* Write protect */ unsigned reserved3 :7;#else#error "Bitfield endianness not defined! Check your byteorder.h"#endif u8 reserved[4];} idefloppy_mode_parameter_header_t;#define IDEFLOPPY_MIN(a,b) ((a)<(b) ? (a):(b))#define IDEFLOPPY_MAX(a,b) ((a)>(b) ? (a):(b))/* * Too bad. The drive wants to send us data which we are not ready to accept. * Just throw it away. */static void idefloppy_discard_data (ide_drive_t *drive, unsigned int bcount){ while (bcount--) IN_BYTE (IDE_DATA_REG);}#if IDEFLOPPY_DEBUG_BUGSstatic void idefloppy_write_zeros (ide_drive_t *drive, unsigned int bcount){ while (bcount--) OUT_BYTE (0, IDE_DATA_REG);}#endif /* IDEFLOPPY_DEBUG_BUGS *//* * idefloppy_end_request is used to finish servicing a request. * * For read/write requests, we will call ide_end_request to pass to the * next buffer. */static void idefloppy_end_request (byte uptodate, ide_hwgroup_t *hwgroup){ ide_drive_t *drive = hwgroup->drive; idefloppy_floppy_t *floppy = drive->driver_data; struct request *rq = hwgroup->rq; int error;#if IDEFLOPPY_DEBUG_LOG printk (KERN_INFO "Reached idefloppy_end_request\n");#endif /* IDEFLOPPY_DEBUG_LOG */ switch (uptodate) { case 0: error = IDEFLOPPY_ERROR_GENERAL; break; case 1: error = 0; break; default: error = uptodate; } if (error) floppy->failed_pc = NULL; /* Why does this happen? */ if (!rq) return; if (!IDEFLOPPY_RQ_CMD (rq->cmd)) { ide_end_request (uptodate, hwgroup); return; } rq->errors = error; ide_end_drive_cmd (drive, 0, 0);}static void idefloppy_input_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, unsigned int bcount){ struct request *rq = pc->rq; struct buffer_head *bh = rq->bh; int count; while (bcount) { if (pc->b_count == bh->b_size) { rq->sector += rq->current_nr_sectors; rq->nr_sectors -= rq->current_nr_sectors; idefloppy_end_request (1, HWGROUP(drive)); if ((bh = rq->bh) != NULL) pc->b_count = 0; } if (bh == NULL) { printk (KERN_ERR "%s: bh == NULL in idefloppy_input_buffers, bcount == %d\n", drive->name, bcount); idefloppy_discard_data (drive, bcount); return; } count = IDEFLOPPY_MIN (bh->b_size - pc->b_count, bcount); atapi_input_bytes (drive, bh->b_data + pc->b_count, count); bcount -= count; pc->b_count += count; }}static void idefloppy_output_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, unsigned int bcount){ struct request *rq = pc->rq; struct buffer_head *bh = rq->bh; int count; while (bcount) { if (!pc->b_count) { rq->sector += rq->current_nr_sectors; rq->nr_sectors -= rq->current_nr_sectors; idefloppy_end_request (1, HWGROUP(drive)); if ((bh = rq->bh) != NULL) { pc->b_data = bh->b_data; pc->b_count = bh->b_size; } } if (bh == NULL) { printk (KERN_ERR "%s: bh == NULL in idefloppy_output_buffers, bcount == %d\n", drive->name, bcount); idefloppy_write_zeros (drive, bcount); return; } count = IDEFLOPPY_MIN (pc->b_count, bcount); atapi_output_bytes (drive, pc->b_data, count); bcount -= count; pc->b_data += count; pc->b_count -= count; }}#ifdef CONFIG_BLK_DEV_IDEDMAstatic void idefloppy_update_buffers (ide_drive_t *drive, idefloppy_pc_t *pc){ struct request *rq = pc->rq; struct buffer_head *bh = rq->bh; while ((bh = rq->bh) != NULL) idefloppy_end_request (1, HWGROUP(drive));}#endif /* CONFIG_BLK_DEV_IDEDMA *//* * idefloppy_queue_pc_head generates a new packet command request in front * of the request queue, before the current request, so that it will be * processed immediately, on the next pass through the driver. */static void idefloppy_queue_pc_head (ide_drive_t *drive,idefloppy_pc_t *pc,struct request *rq){ ide_init_drive_cmd (rq); rq->buffer = (char *) pc; rq->cmd = IDEFLOPPY_PC_RQ; (void) ide_do_drive_cmd (drive, rq, ide_preempt);}static idefloppy_pc_t *idefloppy_next_pc_storage (ide_drive_t *drive){ idefloppy_floppy_t *floppy = drive->driver_data; if (floppy->pc_stack_index==IDEFLOPPY_PC_STACK) floppy->pc_stack_index=0; return (&floppy->pc_stack[floppy->pc_stack_index++]);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -