X-Git-Url: http://pilppa.org/gitweb/?a=blobdiff_plain;f=drivers%2Fide%2Fide-floppy.c;h=6e891bccd052db8d228ccb961179c3fcc6b534b4;hb=5e37bdc081a980dd0d669e6387bcf15ca9666f81;hp=5ea1b1b86c4efe56a1129152231b3a3daec70baa;hpb=0bf399e69c365a71c230014af90966faea92e0a3;p=linux-2.6-omap-h63xx.git diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 5ea1b1b86c4..6e891bccd05 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -4,11 +4,6 @@ * Copyright (C) 1996-1999 Gadi Oxman * Copyright (C) 2000-2002 Paul Bristow * Copyright (C) 2005 Bartlomiej Zolnierkiewicz - */ - -/* - * The driver currently doesn't have any fancy features, just the bare - * minimum read/write support. * * This driver supports the following IDE floppy drives: * @@ -20,7 +15,7 @@ * Documentation/ide/ChangeLog.ide-floppy.1996-2002 */ -#define IDEFLOPPY_VERSION "0.99.newide" +#define IDEFLOPPY_VERSION "1.00" #include #include @@ -47,77 +42,42 @@ #include #include -/* - * The following are used to debug the driver. - */ +/* define to see debug info */ #define IDEFLOPPY_DEBUG_LOG 0 -#define IDEFLOPPY_DEBUG_INFO 0 /* #define IDEFLOPPY_DEBUG(fmt, args...) printk(KERN_INFO fmt, ## args) */ -#define IDEFLOPPY_DEBUG( fmt, args... ) +#define IDEFLOPPY_DEBUG(fmt, args...) #if IDEFLOPPY_DEBUG_LOG #define debug_log(fmt, args...) \ printk(KERN_INFO "ide-floppy: " fmt, ## args) #else -#define debug_log(fmt, args... ) do {} while(0) +#define debug_log(fmt, args...) do {} while (0) #endif -/* - * Some drives require a longer irq timeout. - */ +/* Some drives require a longer irq timeout. */ #define IDEFLOPPY_WAIT_CMD (5 * WAIT_CMD) /* - * After each failed packet command we issue a request sense command - * and retry the packet command IDEFLOPPY_MAX_PC_RETRIES times. + * After each failed packet command we issue a request sense command and retry + * the packet command IDEFLOPPY_MAX_PC_RETRIES times. */ #define IDEFLOPPY_MAX_PC_RETRIES 3 /* - * With each packet command, we allocate a buffer of - * IDEFLOPPY_PC_BUFFER_SIZE bytes. + * With each packet command, we allocate a buffer of IDEFLOPPY_PC_BUFFER_SIZE + * bytes. */ #define IDEFLOPPY_PC_BUFFER_SIZE 256 /* - * In various places in the driver, we need to allocate storage - * for packet commands and requests, which will remain valid while - * we leave the driver to wait for an interrupt or a timeout event. + * In various places in the driver, we need to allocate storage for packet + * commands and requests, which will remain valid while we leave the driver to + * wait for an interrupt or a timeout event. */ #define IDEFLOPPY_PC_STACK (10 + IDEFLOPPY_MAX_PC_RETRIES) -/* - * Our view of a packet command. - */ -typedef struct idefloppy_packet_command_s { - u8 c[12]; /* Actual packet bytes */ - int retries; /* On each retry, we increment retries */ - int error; /* Error code */ - int request_transfer; /* Bytes to transfer */ - int actually_transferred; /* Bytes actually transferred */ - int buffer_size; /* Size of our data buffer */ - int b_count; /* Missing/Available data on the current buffer */ - struct request *rq; /* The corresponding request */ - u8 *buffer; /* Data buffer */ - u8 *current_position; /* Pointer into the above buffer */ - void (*callback) (ide_drive_t *); /* Called when this packet command is completed */ - u8 pc_buffer[IDEFLOPPY_PC_BUFFER_SIZE]; /* Temporary buffer */ - unsigned long flags; /* Status/Action bit flags: long for set_bit */ -} idefloppy_pc_t; - -/* - * Packet command flag bits. - */ -#define PC_ABORT 0 /* Set when an error is considered normal - We won't retry */ -#define PC_DMA_RECOMMENDED 2 /* 1 when we prefer to use DMA if possible */ -#define PC_DMA_IN_PROGRESS 3 /* 1 while DMA in progress */ -#define PC_DMA_ERROR 4 /* 1 when encountered problem during DMA */ -#define PC_WRITING 5 /* Data direction */ - -#define PC_SUPPRESS_ERROR 6 /* Suppress error reporting */ - /* format capacities descriptor codes */ #define CAPACITY_INVALID 0x00 #define CAPACITY_UNFORMATTED 0x01 @@ -125,9 +85,9 @@ typedef struct idefloppy_packet_command_s { #define CAPACITY_NO_CARTRIDGE 0x03 /* - * Most of our global data which we need to save even as we leave the - * driver due to an interrupt or a timer event is stored in a variable - * of type idefloppy_floppy_t, defined below. + * Most of our global data which we need to save even as we leave the driver + * due to an interrupt or a timer event is stored in a variable of type + * idefloppy_floppy_t, defined below. */ typedef struct ide_floppy_obj { ide_drive_t *drive; @@ -137,28 +97,24 @@ typedef struct ide_floppy_obj { unsigned int openers; /* protected by BKL for now */ /* Current packet command */ - idefloppy_pc_t *pc; + struct ide_atapi_pc *pc; /* Last failed packet command */ - idefloppy_pc_t *failed_pc; + struct ide_atapi_pc *failed_pc; /* Packet command stack */ - idefloppy_pc_t pc_stack[IDEFLOPPY_PC_STACK]; + struct ide_atapi_pc pc_stack[IDEFLOPPY_PC_STACK]; /* Next free packet command storage space */ int pc_stack_index; struct request rq_stack[IDEFLOPPY_PC_STACK]; /* We implement a circular array */ int rq_stack_index; - /* - * Last error information - */ + /* Last error information */ u8 sense_key, asc, ascq; /* delay this long before sending packet command */ u8 ticks; int progress_indication; - /* - * Device information - */ + /* Device information */ /* Current format */ int blocks, block_size, bs_factor; /* Last format capacity descriptor */ @@ -175,65 +131,35 @@ typedef struct ide_floppy_obj { #define IDEFLOPPY_TICKS_DELAY HZ/20 /* default delay for ZIP 100 (50ms) */ -/* - * Floppy flag bits values. - */ -#define IDEFLOPPY_DRQ_INTERRUPT 0 /* DRQ interrupt device */ -#define IDEFLOPPY_MEDIA_CHANGED 1 /* Media may have changed */ -#define IDEFLOPPY_USE_READ12 2 /* Use READ12/WRITE12 or READ10/WRITE10 */ -#define IDEFLOPPY_FORMAT_IN_PROGRESS 3 /* Format in progress */ -#define IDEFLOPPY_CLIK_DRIVE 4 /* Avoid commands not supported in Clik drive */ -#define IDEFLOPPY_ZIP_DRIVE 5 /* Requires BH algorithm for packets */ +/* Floppy flag bits values. */ +enum { + /* DRQ interrupt device */ + IDEFLOPPY_FLAG_DRQ_INTERRUPT = (1 << 0), + /* Media may have changed */ + IDEFLOPPY_FLAG_MEDIA_CHANGED = (1 << 1), + /* Format in progress */ + IDEFLOPPY_FLAG_FORMAT_IN_PROGRESS = (1 << 2), + /* Avoid commands not supported in Clik drive */ + IDEFLOPPY_FLAG_CLIK_DRIVE = (1 << 3), + /* Requires BH algorithm for packets */ + IDEFLOPPY_FLAG_ZIP_DRIVE = (1 << 4), +}; -/* - * Defines for the mode sense command - */ +/* Defines for the MODE SENSE command */ #define MODE_SENSE_CURRENT 0x00 #define MODE_SENSE_CHANGEABLE 0x01 -#define MODE_SENSE_DEFAULT 0x02 +#define MODE_SENSE_DEFAULT 0x02 #define MODE_SENSE_SAVED 0x03 -/* - * IOCTLs used in low-level formatting. - */ - +/* IOCTLs used in low-level formatting. */ #define IDEFLOPPY_IOCTL_FORMAT_SUPPORTED 0x4600 #define IDEFLOPPY_IOCTL_FORMAT_GET_CAPACITY 0x4601 #define IDEFLOPPY_IOCTL_FORMAT_START 0x4602 #define IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS 0x4603 -/* - * Error codes which are returned in rq->errors to the higher part - * of the driver. - */ +/* Error code returned in rq->errors to the higher part of the driver. */ #define IDEFLOPPY_ERROR_GENERAL 101 -/* - * 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 -}; - /* * Pages of the SELECT SENSE / MODE SENSE packet commands. * See SFF-8070i spec. @@ -270,29 +196,10 @@ static void ide_floppy_put(struct ide_floppy_obj *floppy) } /* - * 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--) - (void) HWIF(drive)->INB(IDE_DATA_REG); -} - -static void idefloppy_write_zeros(ide_drive_t *drive, unsigned int bcount) -{ - while (bcount--) - HWIF(drive)->OUTB(0, IDE_DATA_REG); -} - - -/* - * idefloppy_do_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. + * Used to finish servicing a request. For read/write requests, we will call + * ide_end_request to pass to the next buffer. */ -static int idefloppy_do_end_request(ide_drive_t *drive, int uptodate, int nsecs) +static int idefloppy_end_request(ide_drive_t *drive, int uptodate, int nsecs) { idefloppy_floppy_t *floppy = drive->driver_data; struct request *rq = HWGROUP(drive)->rq; @@ -301,9 +208,9 @@ static int idefloppy_do_end_request(ide_drive_t *drive, int uptodate, int nsecs) debug_log("Reached %s\n", __func__); switch (uptodate) { - case 0: error = IDEFLOPPY_ERROR_GENERAL; break; - case 1: error = 0; break; - default: error = uptodate; + case 0: error = IDEFLOPPY_ERROR_GENERAL; break; + case 1: error = 0; break; + default: error = uptodate; } if (error) floppy->failed_pc = NULL; @@ -321,39 +228,8 @@ static int idefloppy_do_end_request(ide_drive_t *drive, int uptodate, int nsecs) return 0; } -static void idefloppy_input_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, unsigned int bcount) -{ - struct request *rq = pc->rq; - struct bio_vec *bvec; - struct req_iterator iter; - unsigned long flags; - char *data; - int count, done = 0; - - rq_for_each_segment(bvec, rq, iter) { - if (!bcount) - break; - - count = min(bvec->bv_len, bcount); - - data = bvec_kmap_irq(bvec, &flags); - drive->hwif->atapi_input_bytes(drive, data, count); - bvec_kunmap_irq(data, &flags); - - bcount -= count; - pc->b_count += count; - done += count; - } - - idefloppy_do_end_request(drive, 1, done >> 9); - - if (bcount) { - printk(KERN_ERR "%s: leftover data in idefloppy_input_buffers, bcount == %d\n", drive->name, bcount); - idefloppy_discard_data(drive, bcount); - } -} - -static void idefloppy_output_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, unsigned int bcount) +static void ide_floppy_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc, + unsigned int bcount, int direction) { struct request *rq = pc->rq; struct req_iterator iter; @@ -369,7 +245,10 @@ static void idefloppy_output_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, un count = min(bvec->bv_len, bcount); data = bvec_kmap_irq(bvec, &flags); - drive->hwif->atapi_output_bytes(drive, data, count); + if (direction) + drive->hwif->atapi_output_bytes(drive, data, count); + else + drive->hwif->atapi_input_bytes(drive, data, count); bvec_kunmap_irq(data, &flags); bcount -= count; @@ -377,29 +256,35 @@ static void idefloppy_output_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, un done += count; } - idefloppy_do_end_request(drive, 1, done >> 9); + idefloppy_end_request(drive, 1, done >> 9); if (bcount) { - printk(KERN_ERR "%s: leftover data in idefloppy_output_buffers, bcount == %d\n", drive->name, bcount); - idefloppy_write_zeros(drive, bcount); + printk(KERN_ERR "%s: leftover data in %s, bcount == %d\n", + drive->name, __func__, bcount); + if (direction) + ide_atapi_write_zeros(drive, bcount); + else + ide_atapi_discard_data(drive, bcount); } } -static void idefloppy_update_buffers (ide_drive_t *drive, idefloppy_pc_t *pc) +static void idefloppy_update_buffers(ide_drive_t *drive, + struct ide_atapi_pc *pc) { struct request *rq = pc->rq; struct bio *bio = rq->bio; while ((bio = rq->bio) != NULL) - idefloppy_do_end_request(drive, 1, 0); + idefloppy_end_request(drive, 1, 0); } /* - * 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. + * Generate 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) +static void idefloppy_queue_pc_head(ide_drive_t *drive, struct ide_atapi_pc *pc, + struct request *rq) { struct ide_floppy_obj *floppy = drive->driver_data; @@ -410,16 +295,16 @@ static void idefloppy_queue_pc_head (ide_drive_t *drive,idefloppy_pc_t *pc,struc (void) ide_do_drive_cmd(drive, rq, ide_preempt); } -static idefloppy_pc_t *idefloppy_next_pc_storage (ide_drive_t *drive) +static struct ide_atapi_pc *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; + floppy->pc_stack_index = 0; return (&floppy->pc_stack[floppy->pc_stack_index++]); } -static struct request *idefloppy_next_rq_storage (ide_drive_t *drive) +static struct request *idefloppy_next_rq_storage(ide_drive_t *drive) { idefloppy_floppy_t *floppy = drive->driver_data; @@ -431,7 +316,7 @@ static struct request *idefloppy_next_rq_storage (ide_drive_t *drive) static void idefloppy_request_sense_callback(ide_drive_t *drive) { idefloppy_floppy_t *floppy = drive->driver_data; - u8 *buf = floppy->pc->buffer; + u8 *buf = floppy->pc->buf; debug_log("Reached %s\n", __func__); @@ -456,76 +341,68 @@ static void idefloppy_request_sense_callback(ide_drive_t *drive) floppy->ascq); - idefloppy_do_end_request(drive, 1, 0); + idefloppy_end_request(drive, 1, 0); } else { printk(KERN_ERR "Error in REQUEST SENSE itself - Aborting" " request!\n"); - idefloppy_do_end_request(drive, 0, 0); + idefloppy_end_request(drive, 0, 0); } } -/* - * General packet command callback function. - */ -static void idefloppy_pc_callback (ide_drive_t *drive) +/* General packet command callback function. */ +static void idefloppy_pc_callback(ide_drive_t *drive) { idefloppy_floppy_t *floppy = drive->driver_data; debug_log("Reached %s\n", __func__); - idefloppy_do_end_request(drive, floppy->pc->error ? 0 : 1, 0); + idefloppy_end_request(drive, floppy->pc->error ? 0 : 1, 0); } -/* - * idefloppy_init_pc initializes a packet command. - */ -static void idefloppy_init_pc (idefloppy_pc_t *pc) +static void idefloppy_init_pc(struct ide_atapi_pc *pc) { memset(pc->c, 0, 12); pc->retries = 0; pc->flags = 0; - pc->request_transfer = 0; - pc->buffer = pc->pc_buffer; - pc->buffer_size = IDEFLOPPY_PC_BUFFER_SIZE; - pc->callback = &idefloppy_pc_callback; + pc->req_xfer = 0; + pc->buf = pc->pc_buf; + pc->buf_size = IDEFLOPPY_PC_BUFFER_SIZE; + pc->idefloppy_callback = &idefloppy_pc_callback; } -static void idefloppy_create_request_sense_cmd (idefloppy_pc_t *pc) +static void idefloppy_create_request_sense_cmd(struct ide_atapi_pc *pc) { idefloppy_init_pc(pc); pc->c[0] = GPCMD_REQUEST_SENSE; pc->c[4] = 255; - pc->request_transfer = 18; - pc->callback = &idefloppy_request_sense_callback; + pc->req_xfer = 18; + pc->idefloppy_callback = &idefloppy_request_sense_callback; } /* - * idefloppy_retry_pc is called when an error was detected during the - * last packet command. We queue a request sense packet command in - * the head of the request list. + * Called when an error was detected during the last packet command. We queue a + * request sense packet command in the head of the request list. */ -static void idefloppy_retry_pc (ide_drive_t *drive) +static void idefloppy_retry_pc(ide_drive_t *drive) { - idefloppy_pc_t *pc; + struct ide_atapi_pc *pc; struct request *rq; - (void)drive->hwif->INB(IDE_ERROR_REG); + (void)ide_read_error(drive); pc = idefloppy_next_pc_storage(drive); rq = idefloppy_next_rq_storage(drive); idefloppy_create_request_sense_cmd(pc); idefloppy_queue_pc_head(drive, pc, rq); } -/* - * idefloppy_pc_intr is the usual interrupt handler which will be called - * during a packet command. - */ -static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive) +/* The usual interrupt handler called during a packet command. */ +static ide_startstop_t idefloppy_pc_intr(ide_drive_t *drive) { idefloppy_floppy_t *floppy = drive->driver_data; ide_hwif_t *hwif = drive->hwif; - idefloppy_pc_t *pc = floppy->pc; + struct ide_atapi_pc *pc = floppy->pc; struct request *rq = pc->rq; + xfer_func_t *xferfunc; unsigned int temp; int dma_error = 0; u16 bcount; @@ -533,30 +410,31 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive) debug_log("Reached %s interrupt handler\n", __func__); - if (test_bit(PC_DMA_IN_PROGRESS, &pc->flags)) { - dma_error = hwif->ide_dma_end(drive); + if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { + dma_error = hwif->dma_ops->dma_end(drive); if (dma_error) { printk(KERN_ERR "%s: DMA %s error\n", drive->name, rq_data_dir(rq) ? "write" : "read"); - set_bit(PC_DMA_ERROR, &pc->flags); + pc->flags |= PC_FLAG_DMA_ERROR; } else { - pc->actually_transferred = pc->request_transfer; + pc->xferred = pc->req_xfer; idefloppy_update_buffers(drive, pc); } debug_log("DMA finished\n"); } /* Clear the interrupt */ - stat = drive->hwif->INB(IDE_STATUS_REG); + stat = ide_read_status(drive); - if ((stat & DRQ_STAT) == 0) { /* No more interrupts */ + /* No more interrupts */ + if ((stat & DRQ_STAT) == 0) { debug_log("Packet command completed, %d bytes transferred\n", - pc->actually_transferred); - clear_bit(PC_DMA_IN_PROGRESS, &pc->flags); + pc->xferred); + pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS; local_irq_enable_in_hardirq(); - if ((stat & ERR_STAT) || test_bit(PC_DMA_ERROR, &pc->flags)) { + if ((stat & ERR_STAT) || (pc->flags & PC_FLAG_DMA_ERROR)) { /* Error detected */ debug_log("%s: I/O error\n", drive->name); rq->errors++; @@ -574,11 +452,12 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive) if (floppy->failed_pc == pc) floppy->failed_pc = NULL; /* Command finished - Call the callback function */ - pc->callback(drive); + pc->idefloppy_callback(drive); return ide_stopped; } - if (test_and_clear_bit(PC_DMA_IN_PROGRESS, &pc->flags)) { + if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { + pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS; printk(KERN_ERR "ide-floppy: The floppy wants to issue " "more interrupts in DMA mode\n"); ide_dma_off(drive); @@ -586,16 +465,16 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive) } /* Get the number of bytes to transfer */ - bcount = (hwif->INB(IDE_BCOUNTH_REG) << 8) | - hwif->INB(IDE_BCOUNTL_REG); + bcount = (hwif->INB(hwif->io_ports[IDE_BCOUNTH_OFFSET]) << 8) | + hwif->INB(hwif->io_ports[IDE_BCOUNTL_OFFSET]); /* on this interrupt */ - ireason = hwif->INB(IDE_IREASON_REG); + ireason = hwif->INB(hwif->io_ports[IDE_IREASON_OFFSET]); if (ireason & CD) { - printk(KERN_ERR "ide-floppy: CoD != 0 in idefloppy_pc_intr\n"); + printk(KERN_ERR "ide-floppy: CoD != 0 in %s\n", __func__); return ide_do_reset(drive); } - if (((ireason & IO) == IO) == test_bit(PC_WRITING, &pc->flags)) { + if (((ireason & IO) == IO) == !!(pc->flags & PC_FLAG_WRITING)) { /* Hopefully, we will never get here */ printk(KERN_ERR "ide-floppy: We wanted to %s, ", (ireason & IO) ? "Write" : "Read"); @@ -603,15 +482,15 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive) (ireason & IO) ? "Read" : "Write"); return ide_do_reset(drive); } - if (!test_bit(PC_WRITING, &pc->flags)) { + if (!(pc->flags & PC_FLAG_WRITING)) { /* Reading - Check that we have enough space */ - temp = pc->actually_transferred + bcount; - if (temp > pc->request_transfer) { - if (temp > pc->buffer_size) { + temp = pc->xferred + bcount; + if (temp > pc->req_xfer) { + if (temp > pc->buf_size) { printk(KERN_ERR "ide-floppy: The floppy wants " "to send us more data than expected " "- discarding data\n"); - idefloppy_discard_data(drive, bcount); + ide_atapi_discard_data(drive, bcount); ide_set_handler(drive, &idefloppy_pc_intr, @@ -623,26 +502,23 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive) " expected - allowing transfer\n"); } } - if (test_bit(PC_WRITING, &pc->flags)) { - if (pc->buffer != NULL) - /* Write the current buffer */ - hwif->atapi_output_bytes(drive, pc->current_position, - bcount); - else - idefloppy_output_buffers(drive, pc, bcount); - } else { - if (pc->buffer != NULL) - /* Read the current buffer */ - hwif->atapi_input_bytes(drive, pc->current_position, - bcount); - else - idefloppy_input_buffers(drive, pc, bcount); - } + if (pc->flags & PC_FLAG_WRITING) + xferfunc = hwif->atapi_output_bytes; + else + xferfunc = hwif->atapi_input_bytes; + + if (pc->buf) + xferfunc(drive, pc->cur_pos, bcount); + else + ide_floppy_io_buffers(drive, pc, bcount, + !!(pc->flags & PC_FLAG_WRITING)); + /* Update the current position */ - pc->actually_transferred += bcount; - pc->current_position += bcount; + pc->xferred += bcount; + pc->cur_pos += bcount; - ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL); /* And set the interrupt handler again */ + /* And set the interrupt handler again */ + ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL); return ide_started; } @@ -651,8 +527,9 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive) * It fails at high speeds on the Iomega ZIP drive, so there's a slower version * for that drive below. The algorithm is chosen based on drive type */ -static ide_startstop_t idefloppy_transfer_pc (ide_drive_t *drive) +static ide_startstop_t idefloppy_transfer_pc(ide_drive_t *drive) { + ide_hwif_t *hwif = drive->hwif; ide_startstop_t startstop; idefloppy_floppy_t *floppy = drive->driver_data; u8 ireason; @@ -662,7 +539,7 @@ static ide_startstop_t idefloppy_transfer_pc (ide_drive_t *drive) "initiated yet DRQ isn't asserted\n"); return startstop; } - ireason = drive->hwif->INB(IDE_IREASON_REG); + ireason = hwif->INB(hwif->io_ports[IDE_IREASON_OFFSET]); if ((ireason & CD) == 0 || (ireason & IO)) { printk(KERN_ERR "ide-floppy: (IO,CoD) != (0,1) while " "issuing a packet command\n"); @@ -678,18 +555,16 @@ static ide_startstop_t idefloppy_transfer_pc (ide_drive_t *drive) /* - * What we have here is a classic case of a top half / bottom half - * interrupt service routine. In interrupt mode, the device sends - * an interrupt to signal it's ready to receive a packet. However, - * we need to delay about 2-3 ticks before issuing the packet or we - * gets in trouble. + * What we have here is a classic case of a top half / bottom half interrupt + * service routine. In interrupt mode, the device sends an interrupt to signal + * that it is ready to receive a packet. However, we need to delay about 2-3 + * ticks before issuing the packet or we gets in trouble. * - * So, follow carefully. transfer_pc1 is called as an interrupt (or - * directly). In either case, when the device says it's ready for a - * packet, we schedule the packet transfer to occur about 2-3 ticks - * later in transfer_pc2. + * So, follow carefully. transfer_pc1 is called as an interrupt (or directly). + * In either case, when the device says it's ready for a packet, we schedule + * the packet transfer to occur about 2-3 ticks later in transfer_pc2. */ -static int idefloppy_transfer_pc2 (ide_drive_t *drive) +static int idefloppy_transfer_pc2(ide_drive_t *drive) { idefloppy_floppy_t *floppy = drive->driver_data; @@ -699,8 +574,9 @@ static int idefloppy_transfer_pc2 (ide_drive_t *drive) return IDEFLOPPY_WAIT_CMD; } -static ide_startstop_t idefloppy_transfer_pc1 (ide_drive_t *drive) +static ide_startstop_t idefloppy_transfer_pc1(ide_drive_t *drive) { + ide_hwif_t *hwif = drive->hwif; idefloppy_floppy_t *floppy = drive->driver_data; ide_startstop_t startstop; u8 ireason; @@ -710,13 +586,13 @@ static ide_startstop_t idefloppy_transfer_pc1 (ide_drive_t *drive) "initiated yet DRQ isn't asserted\n"); return startstop; } - ireason = drive->hwif->INB(IDE_IREASON_REG); + ireason = hwif->INB(hwif->io_ports[IDE_IREASON_OFFSET]); if ((ireason & CD) == 0 || (ireason & IO)) { printk(KERN_ERR "ide-floppy: (IO,CoD) != (0,1) " "while issuing a packet command\n"); return ide_do_reset(drive); } - /* + /* * The following delay solves a problem with ATAPI Zip 100 drives * where the Busy flag was apparently being deasserted before the * unit was ready to receive data. This was happening on a @@ -725,15 +601,13 @@ static ide_startstop_t idefloppy_transfer_pc1 (ide_drive_t *drive) * used until after the packet is moved in about 50 msec. */ - ide_set_handler(drive, - &idefloppy_pc_intr, /* service routine for packet command */ - floppy->ticks, /* wait this long before "failing" */ - &idefloppy_transfer_pc2); /* fail == transfer_pc2 */ + ide_set_handler(drive, &idefloppy_pc_intr, floppy->ticks, + &idefloppy_transfer_pc2); return ide_started; } static void ide_floppy_report_error(idefloppy_floppy_t *floppy, - idefloppy_pc_t *pc) + struct ide_atapi_pc *pc) { /* supress error messages resulting from Medium not present */ if (floppy->sense_key == 0x02 && @@ -748,10 +622,8 @@ static void ide_floppy_report_error(idefloppy_floppy_t *floppy, } -/* - * Issue a packet command - */ -static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *pc) +static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive, + struct ide_atapi_pc *pc) { idefloppy_floppy_t *floppy = drive->driver_data; ide_hwif_t *hwif = drive->hwif; @@ -765,20 +637,14 @@ static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *p /* Set the current packet command */ floppy->pc = pc; - if (pc->retries > IDEFLOPPY_MAX_PC_RETRIES || - test_bit(PC_ABORT, &pc->flags)) { - /* - * We will "abort" retrying a packet command in case - * a legitimate error code was received. - */ - if (!test_bit(PC_ABORT, &pc->flags)) { - if (!test_bit(PC_SUPPRESS_ERROR, &pc->flags)) - ide_floppy_report_error(floppy, pc); - /* Giving up */ - pc->error = IDEFLOPPY_ERROR_GENERAL; - } + if (pc->retries > IDEFLOPPY_MAX_PC_RETRIES) { + if (!(pc->flags & PC_FLAG_SUPPRESS_ERROR)) + ide_floppy_report_error(floppy, pc); + /* Giving up */ + pc->error = IDEFLOPPY_ERROR_GENERAL; + floppy->failed_pc = NULL; - pc->callback(drive); + pc->idefloppy_callback(drive); return ide_stopped; } @@ -786,36 +652,38 @@ static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *p pc->retries++; /* We haven't transferred any data yet */ - pc->actually_transferred = 0; - pc->current_position = pc->buffer; - bcount = min(pc->request_transfer, 63 * 1024); + pc->xferred = 0; + pc->cur_pos = pc->buf; + bcount = min(pc->req_xfer, 63 * 1024); - if (test_and_clear_bit(PC_DMA_ERROR, &pc->flags)) + if (pc->flags & PC_FLAG_DMA_ERROR) { + pc->flags &= ~PC_FLAG_DMA_ERROR; ide_dma_off(drive); - + } dma = 0; - if (test_bit(PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma) - dma = !hwif->dma_setup(drive); + if ((pc->flags & PC_FLAG_DMA_RECOMMENDED) && drive->using_dma) + dma = !hwif->dma_ops->dma_setup(drive); ide_pktcmd_tf_load(drive, IDE_TFLAG_NO_SELECT_MASK | IDE_TFLAG_OUT_DEVICE, bcount, dma); - if (dma) { /* Begin DMA, if necessary */ - set_bit(PC_DMA_IN_PROGRESS, &pc->flags); - hwif->dma_start(drive); + if (dma) { + /* Begin DMA, if necessary */ + pc->flags |= PC_FLAG_DMA_IN_PROGRESS; + hwif->dma_ops->dma_start(drive); } /* Can we transfer the packet when we get the interrupt or wait? */ - if (test_bit(IDEFLOPPY_ZIP_DRIVE, &floppy->flags)) { + if (floppy->flags & IDEFLOPPY_FLAG_ZIP_DRIVE) { /* wait */ pkt_xfer_routine = &idefloppy_transfer_pc1; } else { /* immediate */ pkt_xfer_routine = &idefloppy_transfer_pc; } - - if (test_bit (IDEFLOPPY_DRQ_INTERRUPT, &floppy->flags)) { + + if (floppy->flags & IDEFLOPPY_FLAG_DRQ_INTERRUPT) { /* Issue the packet command */ ide_execute_command(drive, WIN_PACKETCMD, pkt_xfer_routine, @@ -824,20 +692,20 @@ static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *p return ide_started; } else { /* Issue the packet command */ - HWIF(drive)->OUTB(WIN_PACKETCMD, IDE_COMMAND_REG); + hwif->OUTB(WIN_PACKETCMD, hwif->io_ports[IDE_COMMAND_OFFSET]); return (*pkt_xfer_routine) (drive); } } -static void idefloppy_rw_callback (ide_drive_t *drive) +static void idefloppy_rw_callback(ide_drive_t *drive) { debug_log("Reached %s\n", __func__); - idefloppy_do_end_request(drive, 1, 0); + idefloppy_end_request(drive, 1, 0); return; } -static void idefloppy_create_prevent_cmd (idefloppy_pc_t *pc, int prevent) +static void idefloppy_create_prevent_cmd(struct ide_atapi_pc *pc, int prevent) { debug_log("creating prevent removal command, prevent = %d\n", prevent); @@ -846,133 +714,126 @@ static void idefloppy_create_prevent_cmd (idefloppy_pc_t *pc, int prevent) pc->c[4] = prevent; } -static void idefloppy_create_read_capacity_cmd (idefloppy_pc_t *pc) +static void idefloppy_create_read_capacity_cmd(struct ide_atapi_pc *pc) { idefloppy_init_pc(pc); pc->c[0] = GPCMD_READ_FORMAT_CAPACITIES; pc->c[7] = 255; pc->c[8] = 255; - pc->request_transfer = 255; + pc->req_xfer = 255; } -static void idefloppy_create_format_unit_cmd (idefloppy_pc_t *pc, int b, int l, - int flags) +static void idefloppy_create_format_unit_cmd(struct ide_atapi_pc *pc, int b, + int l, int flags) { idefloppy_init_pc(pc); pc->c[0] = GPCMD_FORMAT_UNIT; pc->c[1] = 0x17; - memset(pc->buffer, 0, 12); - pc->buffer[1] = 0xA2; + memset(pc->buf, 0, 12); + pc->buf[1] = 0xA2; /* Default format list header, u8 1: FOV/DCRT/IMM bits set */ if (flags & 1) /* Verify bit on... */ - pc->buffer[1] ^= 0x20; /* ... turn off DCRT bit */ - pc->buffer[3] = 8; + pc->buf[1] ^= 0x20; /* ... turn off DCRT bit */ + pc->buf[3] = 8; - put_unaligned(cpu_to_be32(b), (unsigned int *)(&pc->buffer[4])); - put_unaligned(cpu_to_be32(l), (unsigned int *)(&pc->buffer[8])); - pc->buffer_size=12; - set_bit(PC_WRITING, &pc->flags); + put_unaligned(cpu_to_be32(b), (unsigned int *)(&pc->buf[4])); + put_unaligned(cpu_to_be32(l), (unsigned int *)(&pc->buf[8])); + pc->buf_size = 12; + pc->flags |= PC_FLAG_WRITING; } -/* - * A mode sense command is used to "sense" floppy parameters. - */ -static void idefloppy_create_mode_sense_cmd (idefloppy_pc_t *pc, u8 page_code, u8 type) +/* A mode sense command is used to "sense" floppy parameters. */ +static void idefloppy_create_mode_sense_cmd(struct ide_atapi_pc *pc, + u8 page_code, u8 type) { u16 length = 8; /* sizeof(Mode Parameter Header) = 8 Bytes */ - + idefloppy_init_pc(pc); pc->c[0] = GPCMD_MODE_SENSE_10; pc->c[1] = 0; pc->c[2] = page_code + (type << 6); switch (page_code) { - case IDEFLOPPY_CAPABILITIES_PAGE: - length += 12; - break; - case IDEFLOPPY_FLEXIBLE_DISK_PAGE: - length += 32; - break; - default: - printk(KERN_ERR "ide-floppy: unsupported page code " + case IDEFLOPPY_CAPABILITIES_PAGE: + length += 12; + break; + case IDEFLOPPY_FLEXIBLE_DISK_PAGE: + length += 32; + break; + default: + printk(KERN_ERR "ide-floppy: unsupported page code " "in create_mode_sense_cmd\n"); } put_unaligned(cpu_to_be16(length), (u16 *) &pc->c[7]); - pc->request_transfer = length; + pc->req_xfer = length; } -static void idefloppy_create_start_stop_cmd (idefloppy_pc_t *pc, int start) +static void idefloppy_create_start_stop_cmd(struct ide_atapi_pc *pc, int start) { idefloppy_init_pc(pc); pc->c[0] = GPCMD_START_STOP_UNIT; pc->c[4] = start; } -static void idefloppy_create_test_unit_ready_cmd(idefloppy_pc_t *pc) +static void idefloppy_create_test_unit_ready_cmd(struct ide_atapi_pc *pc) { idefloppy_init_pc(pc); pc->c[0] = GPCMD_TEST_UNIT_READY; } -static void idefloppy_create_rw_cmd (idefloppy_floppy_t *floppy, idefloppy_pc_t *pc, struct request *rq, unsigned long sector) +static void idefloppy_create_rw_cmd(idefloppy_floppy_t *floppy, + struct ide_atapi_pc *pc, struct request *rq, + unsigned long sector) { int block = sector / floppy->bs_factor; int blocks = rq->nr_sectors / floppy->bs_factor; int cmd = rq_data_dir(rq); - debug_log("create_rw1%d_cmd: block == %d, blocks == %d\n", - 2 * test_bit (IDEFLOPPY_USE_READ12, &floppy->flags), + debug_log("create_rw10_cmd: block == %d, blocks == %d\n", block, blocks); idefloppy_init_pc(pc); - if (test_bit(IDEFLOPPY_USE_READ12, &floppy->flags)) { - pc->c[0] = cmd == READ ? GPCMD_READ_12 : GPCMD_WRITE_12; - put_unaligned(cpu_to_be32(blocks), (unsigned int *) &pc->c[6]); - } else { - pc->c[0] = cmd == READ ? GPCMD_READ_10 : GPCMD_WRITE_10; - put_unaligned(cpu_to_be16(blocks), (unsigned short *)&pc->c[7]); - } + pc->c[0] = cmd == READ ? GPCMD_READ_10 : GPCMD_WRITE_10; + put_unaligned(cpu_to_be16(blocks), (unsigned short *)&pc->c[7]); put_unaligned(cpu_to_be32(block), (unsigned int *) &pc->c[2]); - pc->callback = &idefloppy_rw_callback; + + pc->idefloppy_callback = &idefloppy_rw_callback; pc->rq = rq; pc->b_count = cmd == READ ? 0 : rq->bio->bi_size; if (rq->cmd_flags & REQ_RW) - set_bit(PC_WRITING, &pc->flags); - pc->buffer = NULL; - pc->request_transfer = pc->buffer_size = blocks * floppy->block_size; - set_bit(PC_DMA_RECOMMENDED, &pc->flags); + pc->flags |= PC_FLAG_WRITING; + pc->buf = NULL; + pc->req_xfer = pc->buf_size = blocks * floppy->block_size; + pc->flags |= PC_FLAG_DMA_RECOMMENDED; } -static void -idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy, idefloppy_pc_t *pc, struct request *rq) +static void idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy, + struct ide_atapi_pc *pc, struct request *rq) { idefloppy_init_pc(pc); - pc->callback = &idefloppy_rw_callback; + pc->idefloppy_callback = &idefloppy_rw_callback; memcpy(pc->c, rq->cmd, sizeof(pc->c)); pc->rq = rq; pc->b_count = rq->data_len; if (rq->data_len && rq_data_dir(rq) == WRITE) - set_bit(PC_WRITING, &pc->flags); - pc->buffer = rq->data; + pc->flags |= PC_FLAG_WRITING; + pc->buf = rq->data; if (rq->bio) - set_bit(PC_DMA_RECOMMENDED, &pc->flags); - + pc->flags |= PC_FLAG_DMA_RECOMMENDED; /* * possibly problematic, doesn't look like ide-floppy correctly * handled scattered requests if dma fails... */ - pc->request_transfer = pc->buffer_size = rq->data_len; + pc->req_xfer = pc->buf_size = rq->data_len; } -/* - * idefloppy_do_request is our request handling function. - */ -static ide_startstop_t idefloppy_do_request (ide_drive_t *drive, struct request *rq, sector_t block_s) +static ide_startstop_t idefloppy_do_request(ide_drive_t *drive, + struct request *rq, sector_t block_s) { idefloppy_floppy_t *floppy = drive->driver_data; - idefloppy_pc_t *pc; + struct ide_atapi_pc *pc; unsigned long block = (unsigned long)block_s; debug_log("dev: %s, cmd_type: %x, errors: %d\n", @@ -988,28 +849,28 @@ static ide_startstop_t idefloppy_do_request (ide_drive_t *drive, struct request else printk(KERN_ERR "ide-floppy: %s: I/O error\n", drive->name); - idefloppy_do_end_request(drive, 0, 0); + idefloppy_end_request(drive, 0, 0); return ide_stopped; } if (blk_fs_request(rq)) { if (((long)rq->sector % floppy->bs_factor) || (rq->nr_sectors % floppy->bs_factor)) { - printk("%s: unsupported r/w request size\n", - drive->name); - idefloppy_do_end_request(drive, 0, 0); + printk(KERN_ERR "%s: unsupported r/w request size\n", + drive->name); + idefloppy_end_request(drive, 0, 0); return ide_stopped; } pc = idefloppy_next_pc_storage(drive); idefloppy_create_rw_cmd(floppy, pc, rq, block); } else if (blk_special_request(rq)) { - pc = (idefloppy_pc_t *) rq->buffer; + pc = (struct ide_atapi_pc *) rq->buffer; } else if (blk_pc_request(rq)) { pc = idefloppy_next_pc_storage(drive); idefloppy_blockpc_cmd(floppy, pc, rq); } else { blk_dump_rq_flags(rq, "ide-floppy: unsupported command in queue"); - idefloppy_do_end_request(drive, 0, 0); + idefloppy_end_request(drive, 0, 0); return ide_stopped; } @@ -1018,15 +879,15 @@ static ide_startstop_t idefloppy_do_request (ide_drive_t *drive, struct request } /* - * idefloppy_queue_pc_tail adds a special packet command request to the - * tail of the request queue, and waits for it to be serviced. + * Add a special packet command request to the tail of the request queue, + * and wait for it to be serviced. */ -static int idefloppy_queue_pc_tail (ide_drive_t *drive,idefloppy_pc_t *pc) +static int idefloppy_queue_pc_tail(ide_drive_t *drive, struct ide_atapi_pc *pc) { struct ide_floppy_obj *floppy = drive->driver_data; struct request rq; - ide_init_drive_cmd (&rq); + ide_init_drive_cmd(&rq); rq.buffer = (char *) pc; rq.cmd_type = REQ_TYPE_SPECIAL; rq.rq_disk = floppy->disk; @@ -1041,7 +902,7 @@ static int idefloppy_queue_pc_tail (ide_drive_t *drive,idefloppy_pc_t *pc) static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive) { idefloppy_floppy_t *floppy = drive->driver_data; - idefloppy_pc_t pc; + struct ide_atapi_pc pc; u8 *page; int capacity, lba_capacity; u16 transfer_rate, sector_size, cyls, rpm; @@ -1055,16 +916,16 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive) " parameters\n"); return 1; } - floppy->wp = !!(pc.buffer[3] & 0x80); + floppy->wp = !!(pc.buf[3] & 0x80); set_disk_ro(floppy->disk, floppy->wp); - page = &pc.buffer[8]; + page = &pc.buf[8]; - transfer_rate = be16_to_cpu(*(u16 *)&pc.buffer[8 + 2]); - sector_size = be16_to_cpu(*(u16 *)&pc.buffer[8 + 6]); - cyls = be16_to_cpu(*(u16 *)&pc.buffer[8 + 8]); - rpm = be16_to_cpu(*(u16 *)&pc.buffer[8 + 28]); - heads = pc.buffer[8 + 4]; - sectors = pc.buffer[8 + 5]; + transfer_rate = be16_to_cpu(*(u16 *)&pc.buf[8 + 2]); + sector_size = be16_to_cpu(*(u16 *)&pc.buf[8 + 6]); + cyls = be16_to_cpu(*(u16 *)&pc.buf[8 + 8]); + rpm = be16_to_cpu(*(u16 *)&pc.buf[8 + 28]); + heads = pc.buf[8 + 4]; + sectors = pc.buf[8 + 5]; capacity = cyls * heads * sectors * sector_size; @@ -1093,17 +954,17 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive) static int idefloppy_get_sfrp_bit(ide_drive_t *drive) { idefloppy_floppy_t *floppy = drive->driver_data; - idefloppy_pc_t pc; + struct ide_atapi_pc pc; floppy->srfp = 0; idefloppy_create_mode_sense_cmd(&pc, IDEFLOPPY_CAPABILITIES_PAGE, MODE_SENSE_CURRENT); - set_bit(PC_SUPPRESS_ERROR, &pc.flags); + pc.flags |= PC_FLAG_SUPPRESS_ERROR; if (idefloppy_queue_pc_tail(drive, &pc)) return 1; - floppy->srfp = pc.buffer[8 + 2] & 0x40; + floppy->srfp = pc.buf[8 + 2] & 0x40; return (0); } @@ -1114,7 +975,7 @@ static int idefloppy_get_sfrp_bit(ide_drive_t *drive) static int ide_floppy_get_capacity(ide_drive_t *drive) { idefloppy_floppy_t *floppy = drive->driver_data; - idefloppy_pc_t pc; + struct ide_atapi_pc pc; u8 *cap_desc; u8 header_len, desc_cnt; int i, rc = 1, blocks, length; @@ -1130,15 +991,15 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) printk(KERN_ERR "ide-floppy: Can't get floppy parameters\n"); return 1; } - header_len = pc.buffer[3]; - cap_desc = &pc.buffer[4]; + header_len = pc.buf[3]; + cap_desc = &pc.buf[4]; desc_cnt = header_len / 8; /* capacity descriptor of 8 bytes */ for (i = 0; i < desc_cnt; i++) { unsigned int desc_start = 4 + i*8; - blocks = be32_to_cpu(*(u32 *)&pc.buffer[desc_start]); - length = be16_to_cpu(*(u16 *)&pc.buffer[desc_start + 6]); + blocks = be32_to_cpu(*(u32 *)&pc.buf[desc_start]); + length = be16_to_cpu(*(u16 *)&pc.buf[desc_start + 6]); debug_log("Descriptor %d: %dkB, %d blocks, %d sector size\n", i, blocks * length / 1024, blocks, length); @@ -1149,11 +1010,11 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) * the code below is valid only for the 1st descriptor, ie i=0 */ - switch (pc.buffer[desc_start + 4] & 0x03) { + switch (pc.buf[desc_start + 4] & 0x03) { /* Clik! drive returns this instead of CAPACITY_CURRENT */ case CAPACITY_UNFORMATTED: - if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags)) - /* + if (!(floppy->flags & IDEFLOPPY_FLAG_CLIK_DRIVE)) + /* * If it is not a clik drive, break out * (maintains previous driver behaviour) */ @@ -1194,11 +1055,11 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) break; } debug_log("Descriptor 0 Code: %d\n", - pc.buffer[desc_start + 4] & 0x03); + pc.buf[desc_start + 4] & 0x03); } /* Clik! disk does not support get_flexible_disk_page */ - if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags)) + if (!(floppy->flags & IDEFLOPPY_FLAG_CLIK_DRIVE)) (void) ide_floppy_get_flexible_disk_page(drive); set_capacity(floppy->disk, floppy->blocks * floppy->bs_factor); @@ -1226,7 +1087,7 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg) { - idefloppy_pc_t pc; + struct ide_atapi_pc pc; u8 header_len, desc_cnt; int i, blocks, length, u_array_size, u_index; int __user *argp; @@ -1242,7 +1103,7 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg) printk(KERN_ERR "ide-floppy: Can't get floppy parameters\n"); return (-EIO); } - header_len = pc.buffer[3]; + header_len = pc.buf[3]; desc_cnt = header_len / 8; /* capacity descriptor of 8 bytes */ u_index = 0; @@ -1259,8 +1120,8 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg) if (u_index >= u_array_size) break; /* User-supplied buffer too small */ - blocks = be32_to_cpu(*(u32 *)&pc.buffer[desc_start]); - length = be16_to_cpu(*(u16 *)&pc.buffer[desc_start + 6]); + blocks = be32_to_cpu(*(u32 *)&pc.buf[desc_start]); + length = be16_to_cpu(*(u16 *)&pc.buf[desc_start + 6]); if (put_user(blocks, argp)) return(-EFAULT); @@ -1279,40 +1140,38 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg) } /* -** Get ATAPI_FORMAT_UNIT progress indication. -** -** Userland gives a pointer to an int. The int is set to a progress -** indicator 0-65536, with 65536=100%. -** -** If the drive does not support format progress indication, we just check -** the dsc bit, and return either 0 or 65536. -*/ + * Get ATAPI_FORMAT_UNIT progress indication. + * + * Userland gives a pointer to an int. The int is set to a progress + * indicator 0-65536, with 65536=100%. + * + * If the drive does not support format progress indication, we just check + * the dsc bit, and return either 0 or 65536. + */ static int idefloppy_get_format_progress(ide_drive_t *drive, int __user *arg) { idefloppy_floppy_t *floppy = drive->driver_data; - idefloppy_pc_t pc; + struct ide_atapi_pc pc; int progress_indication = 0x10000; if (floppy->srfp) { idefloppy_create_request_sense_cmd(&pc); - if (idefloppy_queue_pc_tail(drive, &pc)) { + if (idefloppy_queue_pc_tail(drive, &pc)) return (-EIO); - } if (floppy->sense_key == 2 && floppy->asc == 4 && - floppy->ascq == 4) { + floppy->ascq == 4) progress_indication = floppy->progress_indication; - } - /* Else assume format_unit has finished, and we're - ** at 0x10000 */ + + /* Else assume format_unit has finished, and we're at 0x10000 */ } else { unsigned long flags; u8 stat; local_irq_save(flags); - stat = drive->hwif->INB(IDE_STATUS_REG); + stat = ide_read_status(drive); local_irq_restore(flags); progress_indication = ((stat & SEEK_STAT) == 0) ? 0 : 0x10000; @@ -1323,10 +1182,7 @@ static int idefloppy_get_format_progress(ide_drive_t *drive, int __user *arg) return (0); } -/* - * Return the current floppy capacity. - */ -static sector_t idefloppy_capacity (ide_drive_t *drive) +static sector_t idefloppy_capacity(ide_drive_t *drive) { idefloppy_floppy_t *floppy = drive->driver_data; unsigned long capacity = floppy->blocks * floppy->bs_factor; @@ -1335,72 +1191,44 @@ static sector_t idefloppy_capacity (ide_drive_t *drive) } /* - * idefloppy_identify_device checks if we can support a drive, - * based on the ATAPI IDENTIFY command results. + * Check whether we can support a drive, based on the ATAPI IDENTIFY command + * results. */ -static int idefloppy_identify_device (ide_drive_t *drive,struct hd_driveid *id) +static int idefloppy_identify_device(ide_drive_t *drive, struct hd_driveid *id) { - struct idefloppy_id_gcw gcw; -#if IDEFLOPPY_DEBUG_INFO - char buffer[80]; -#endif /* IDEFLOPPY_DEBUG_INFO */ + u8 gcw[2]; + u8 device_type, protocol, removable, drq_type, packet_size; *((u16 *) &gcw) = id->config; + device_type = gcw[1] & 0x1F; + removable = (gcw[0] & 0x80) >> 7; + protocol = (gcw[1] & 0xC0) >> 6; + drq_type = (gcw[0] & 0x60) >> 5; + packet_size = gcw[0] & 0x03; + #ifdef CONFIG_PPC /* kludge for Apple PowerBook internal zip */ - if ((gcw.device_type == 5) && - !strstr(id->model, "CD-ROM") && - strstr(id->model, "ZIP")) - gcw.device_type = 0; + if (device_type == 5 && + !strstr(id->model, "CD-ROM") && strstr(id->model, "ZIP")) + device_type = 0; #endif -#if IDEFLOPPY_DEBUG_INFO - printk(KERN_INFO "Dumping ATAPI Identify Device floppy parameters\n"); - switch (gcw.protocol) { - case 0: case 1: sprintf(buffer, "ATA");break; - case 2: sprintf(buffer, "ATAPI");break; - case 3: sprintf(buffer, "Reserved (Unknown to ide-floppy)");break; - } - printk(KERN_INFO "Protocol Type: %s\n", buffer); - switch (gcw.device_type) { - case 0: sprintf(buffer, "Direct-access Device");break; - case 1: sprintf(buffer, "Streaming Tape Device");break; - case 2: case 3: case 4: sprintf (buffer, "Reserved");break; - case 5: sprintf(buffer, "CD-ROM Device");break; - case 6: sprintf(buffer, "Reserved"); - case 7: sprintf(buffer, "Optical memory Device");break; - case 0x1f: sprintf(buffer, "Unknown or no Device type");break; - default: sprintf(buffer, "Reserved"); - } - printk(KERN_INFO "Device Type: %x - %s\n", gcw.device_type, buffer); - printk(KERN_INFO "Removable: %s\n",gcw.removable ? "Yes":"No"); - switch (gcw.drq_type) { - case 0: sprintf(buffer, "Microprocessor DRQ");break; - case 1: sprintf(buffer, "Interrupt DRQ");break; - case 2: sprintf(buffer, "Accelerated DRQ");break; - case 3: sprintf(buffer, "Reserved");break; - } - printk(KERN_INFO "Command Packet DRQ Type: %s\n", buffer); - switch (gcw.packet_size) { - case 0: sprintf(buffer, "12 bytes");break; - case 1: sprintf(buffer, "16 bytes");break; - default: sprintf(buffer, "Reserved");break; - } - printk(KERN_INFO "Command Packet Size: %s\n", buffer); -#endif /* IDEFLOPPY_DEBUG_INFO */ - - if (gcw.protocol != 2) - printk(KERN_ERR "ide-floppy: Protocol is not ATAPI\n"); - else if (gcw.device_type != 0) - printk(KERN_ERR "ide-floppy: Device type is not set to floppy\n"); - else if (!gcw.removable) + if (protocol != 2) + printk(KERN_ERR "ide-floppy: Protocol (0x%02x) is not ATAPI\n", + protocol); + else if (device_type != 0) + printk(KERN_ERR "ide-floppy: Device type (0x%02x) is not set " + "to floppy\n", device_type); + else if (!removable) printk(KERN_ERR "ide-floppy: The removable flag is not set\n"); - else if (gcw.drq_type == 3) { - printk(KERN_ERR "ide-floppy: Sorry, DRQ type %d not supported\n", gcw.drq_type); - } else if (gcw.packet_size != 0) { - printk(KERN_ERR "ide-floppy: Packet size is not 12 bytes long\n"); - } else + else if (drq_type == 3) + printk(KERN_ERR "ide-floppy: Sorry, DRQ type (0x%02x) not " + "supported\n", drq_type); + else if (packet_size != 0) + printk(KERN_ERR "ide-floppy: Packet size (0x%02x) is not 12 " + "bytes\n", packet_size); + else return 1; return 0; } @@ -1410,58 +1238,53 @@ static void idefloppy_add_settings(ide_drive_t *drive) { idefloppy_floppy_t *floppy = drive->driver_data; -/* - * drive setting name read/write data type min max mul_factor div_factor data pointer set function - */ - ide_add_setting(drive, "bios_cyl", SETTING_RW, TYPE_INT, 0, 1023, 1, 1, &drive->bios_cyl, NULL); - ide_add_setting(drive, "bios_head", SETTING_RW, TYPE_BYTE, 0, 255, 1, 1, &drive->bios_head, NULL); - ide_add_setting(drive, "bios_sect", SETTING_RW, TYPE_BYTE, 0, 63, 1, 1, &drive->bios_sect, NULL); - ide_add_setting(drive, "ticks", SETTING_RW, TYPE_BYTE, 0, 255, 1, 1, &floppy->ticks, NULL); + ide_add_setting(drive, "bios_cyl", SETTING_RW, TYPE_INT, 0, 1023, 1, 1, + &drive->bios_cyl, NULL); + ide_add_setting(drive, "bios_head", SETTING_RW, TYPE_BYTE, 0, 255, 1, 1, + &drive->bios_head, NULL); + ide_add_setting(drive, "bios_sect", SETTING_RW, TYPE_BYTE, 0, 63, 1, 1, + &drive->bios_sect, NULL); + ide_add_setting(drive, "ticks", SETTING_RW, TYPE_BYTE, 0, 255, 1, 1, + &floppy->ticks, NULL); } #else static inline void idefloppy_add_settings(ide_drive_t *drive) { ; } #endif -/* - * Driver initialization. - */ -static void idefloppy_setup (ide_drive_t *drive, idefloppy_floppy_t *floppy) +static void idefloppy_setup(ide_drive_t *drive, idefloppy_floppy_t *floppy) { - struct idefloppy_id_gcw gcw; + u8 gcw[2]; *((u16 *) &gcw) = drive->id->config; floppy->pc = floppy->pc_stack; - if (gcw.drq_type == 1) - set_bit(IDEFLOPPY_DRQ_INTERRUPT, &floppy->flags); + + if (((gcw[0] & 0x60) >> 5) == 1) + floppy->flags |= IDEFLOPPY_FLAG_DRQ_INTERRUPT; /* - * We used to check revisions here. At this point however - * I'm giving up. Just assume they are all broken, its easier. + * We used to check revisions here. At this point however I'm giving up. + * Just assume they are all broken, its easier. * - * The actual reason for the workarounds was likely - * a driver bug after all rather than a firmware bug, - * and the workaround below used to hide it. It should - * be fixed as of version 1.9, but to be on the safe side - * we'll leave the limitation below for the 2.2.x tree. + * The actual reason for the workarounds was likely a driver bug after + * all rather than a firmware bug, and the workaround below used to hide + * it. It should be fixed as of version 1.9, but to be on the safe side + * we'll leave the limitation below for the 2.2.x tree. */ - if (!strncmp(drive->id->model, "IOMEGA ZIP 100 ATAPI", 20)) { - set_bit(IDEFLOPPY_ZIP_DRIVE, &floppy->flags); + floppy->flags |= IDEFLOPPY_FLAG_ZIP_DRIVE; /* This value will be visible in the /proc/ide/hdx/settings */ floppy->ticks = IDEFLOPPY_TICKS_DELAY; blk_queue_max_sectors(drive->queue, 64); } /* - * Guess what? The IOMEGA Clik! drive also needs the - * above fix. It makes nasty clicking noises without - * it, so please don't remove this. - */ + * Guess what? The IOMEGA Clik! drive also needs the above fix. It makes + * nasty clicking noises without it, so please don't remove this. + */ if (strncmp(drive->id->model, "IOMEGA Clik!", 11) == 0) { blk_queue_max_sectors(drive->queue, 64); - set_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags); + floppy->flags |= IDEFLOPPY_FLAG_CLIK_DRIVE; } - (void) ide_floppy_get_capacity(drive); idefloppy_add_settings(drive); } @@ -1491,19 +1314,19 @@ static void idefloppy_cleanup_obj(struct kref *kref) } #ifdef CONFIG_IDE_PROC_FS -static int proc_idefloppy_read_capacity - (char *page, char **start, off_t off, int count, int *eof, void *data) +static int proc_idefloppy_read_capacity(char *page, char **start, off_t off, + int count, int *eof, void *data) { ide_drive_t*drive = (ide_drive_t *)data; int len; - len = sprintf(page,"%llu\n", (long long)idefloppy_capacity(drive)); - PROC_IDE_READ_RETURN(page,start,off,count,eof,len); + len = sprintf(page, "%llu\n", (long long)idefloppy_capacity(drive)); + PROC_IDE_READ_RETURN(page, start, off, count, eof, len); } static ide_proc_entry_t idefloppy_proc[] = { - { "capacity", S_IFREG|S_IRUGO, proc_idefloppy_read_capacity, NULL }, - { "geometry", S_IFREG|S_IRUGO, proc_ide_read_geometry, NULL }, + { "capacity", S_IFREG|S_IRUGO, proc_idefloppy_read_capacity, NULL }, + { "geometry", S_IFREG|S_IRUGO, proc_ide_read_geometry, NULL }, { NULL, 0, NULL, NULL } }; #endif /* CONFIG_IDE_PROC_FS */ @@ -1522,7 +1345,7 @@ static ide_driver_t idefloppy_driver = { .media = ide_floppy, .supports_dsc_overlap = 0, .do_request = idefloppy_do_request, - .end_request = idefloppy_do_end_request, + .end_request = idefloppy_end_request, .error = __ide_error, .abort = __ide_abort, #ifdef CONFIG_IDE_PROC_FS @@ -1535,12 +1358,13 @@ static int idefloppy_open(struct inode *inode, struct file *filp) struct gendisk *disk = inode->i_bdev->bd_disk; struct ide_floppy_obj *floppy; ide_drive_t *drive; - idefloppy_pc_t pc; + struct ide_atapi_pc pc; int ret = 0; debug_log("Reached %s\n", __func__); - if (!(floppy = ide_floppy_get(disk))) + floppy = ide_floppy_get(disk); + if (!floppy) return -ENXIO; drive = floppy->drive; @@ -1548,7 +1372,7 @@ static int idefloppy_open(struct inode *inode, struct file *filp) floppy->openers++; if (floppy->openers == 1) { - clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags); + floppy->flags &= ~IDEFLOPPY_FLAG_FORMAT_IN_PROGRESS; /* Just in case */ idefloppy_create_test_unit_ready_cmd(&pc); @@ -1560,10 +1384,10 @@ static int idefloppy_open(struct inode *inode, struct file *filp) if (ide_floppy_get_capacity(drive) && (filp->f_flags & O_NDELAY) == 0 /* - ** Allow O_NDELAY to open a drive without a disk, or with - ** an unreadable disk, so that we can get the format - ** capacity of the drive or begin the format - Sam - */ + * Allow O_NDELAY to open a drive without a disk, or with an + * unreadable disk, so that we can get the format capacity + * of the drive or begin the format - Sam + */ ) { ret = -EIO; goto out_put_floppy; @@ -1573,14 +1397,14 @@ static int idefloppy_open(struct inode *inode, struct file *filp) ret = -EROFS; goto out_put_floppy; } - set_bit(IDEFLOPPY_MEDIA_CHANGED, &floppy->flags); + floppy->flags |= IDEFLOPPY_FLAG_MEDIA_CHANGED; /* IOMEGA Clik! drives do not support lock/unlock commands */ - if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags)) { + if (!(floppy->flags & IDEFLOPPY_FLAG_CLIK_DRIVE)) { idefloppy_create_prevent_cmd(&pc, 1); (void) idefloppy_queue_pc_tail(drive, &pc); } check_disk_change(inode->i_bdev); - } else if (test_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags)) { + } else if (floppy->flags & IDEFLOPPY_FLAG_FORMAT_IN_PROGRESS) { ret = -EBUSY; goto out_put_floppy; } @@ -1597,18 +1421,18 @@ static int idefloppy_release(struct inode *inode, struct file *filp) struct gendisk *disk = inode->i_bdev->bd_disk; struct ide_floppy_obj *floppy = ide_floppy_g(disk); ide_drive_t *drive = floppy->drive; - idefloppy_pc_t pc; + struct ide_atapi_pc pc; debug_log("Reached %s\n", __func__); if (floppy->openers == 1) { /* IOMEGA Clik! drives do not support lock/unlock commands */ - if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags)) { + if (!(floppy->flags & IDEFLOPPY_FLAG_CLIK_DRIVE)) { idefloppy_create_prevent_cmd(&pc, 0); (void) idefloppy_queue_pc_tail(drive, &pc); } - clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags); + floppy->flags &= ~IDEFLOPPY_FLAG_FORMAT_IN_PROGRESS; } floppy->openers--; @@ -1629,15 +1453,15 @@ static int idefloppy_getgeo(struct block_device *bdev, struct hd_geometry *geo) return 0; } -static int ide_floppy_lockdoor(idefloppy_floppy_t *floppy, idefloppy_pc_t *pc, - unsigned long arg, unsigned int cmd) +static int ide_floppy_lockdoor(idefloppy_floppy_t *floppy, + struct ide_atapi_pc *pc, unsigned long arg, unsigned int cmd) { if (floppy->openers > 1) return -EBUSY; /* The IOMEGA Clik! Drive doesn't support this command - * no room for an eject mechanism */ - if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags)) { + if (!(floppy->flags & IDEFLOPPY_FLAG_CLIK_DRIVE)) { int prevent = arg ? 1 : 0; if (cmd == CDROMEJECT) @@ -1659,15 +1483,15 @@ static int ide_floppy_format_unit(idefloppy_floppy_t *floppy, int __user *arg) { int blocks, length, flags, err = 0; - idefloppy_pc_t pc; + struct ide_atapi_pc pc; if (floppy->openers > 1) { /* Don't format if someone is using the disk */ - clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags); + floppy->flags &= ~IDEFLOPPY_FLAG_FORMAT_IN_PROGRESS; return -EBUSY; } - set_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags); + floppy->flags |= IDEFLOPPY_FLAG_FORMAT_IN_PROGRESS; /* * Send ATAPI_FORMAT_UNIT to the drive. @@ -1699,7 +1523,7 @@ static int ide_floppy_format_unit(idefloppy_floppy_t *floppy, out: if (err) - clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags); + floppy->flags &= ~IDEFLOPPY_FLAG_FORMAT_IN_PROGRESS; return err; } @@ -1710,7 +1534,7 @@ static int idefloppy_ioctl(struct inode *inode, struct file *file, struct block_device *bdev = inode->i_bdev; struct ide_floppy_obj *floppy = ide_floppy_g(bdev->bd_disk); ide_drive_t *drive = floppy->drive; - idefloppy_pc_t pc; + struct ide_atapi_pc pc; void __user *argp = (void __user *)arg; int err; @@ -1752,13 +1576,16 @@ static int idefloppy_media_changed(struct gendisk *disk) { struct ide_floppy_obj *floppy = ide_floppy_g(disk); ide_drive_t *drive = floppy->drive; + int ret; /* do not scan partitions twice if this is a removable device */ if (drive->attach) { drive->attach = 0; return 0; } - return test_and_clear_bit(IDEFLOPPY_MEDIA_CHANGED, &floppy->flags); + ret = !!(floppy->flags & IDEFLOPPY_FLAG_MEDIA_CHANGED); + floppy->flags &= ~IDEFLOPPY_FLAG_MEDIA_CHANGED; + return ret; } static int idefloppy_revalidate_disk(struct gendisk *disk) @@ -1769,13 +1596,13 @@ static int idefloppy_revalidate_disk(struct gendisk *disk) } static struct block_device_operations idefloppy_ops = { - .owner = THIS_MODULE, - .open = idefloppy_open, - .release = idefloppy_release, - .ioctl = idefloppy_ioctl, - .getgeo = idefloppy_getgeo, - .media_changed = idefloppy_media_changed, - .revalidate_disk= idefloppy_revalidate_disk + .owner = THIS_MODULE, + .open = idefloppy_open, + .release = idefloppy_release, + .ioctl = idefloppy_ioctl, + .getgeo = idefloppy_getgeo, + .media_changed = idefloppy_media_changed, + .revalidate_disk = idefloppy_revalidate_disk }; static int ide_floppy_probe(ide_drive_t *drive) @@ -1789,16 +1616,20 @@ static int ide_floppy_probe(ide_drive_t *drive) goto failed; if (drive->media != ide_floppy) goto failed; - if (!idefloppy_identify_device (drive, drive->id)) { - printk (KERN_ERR "ide-floppy: %s: not supported by this version of ide-floppy\n", drive->name); + if (!idefloppy_identify_device(drive, drive->id)) { + printk(KERN_ERR "ide-floppy: %s: not supported by this version" + " of ide-floppy\n", drive->name); goto failed; } if (drive->scsi) { - printk("ide-floppy: passing drive %s to ide-scsi emulation.\n", drive->name); + printk(KERN_INFO "ide-floppy: passing drive %s to ide-scsi" + " emulation.\n", drive->name); goto failed; } - if ((floppy = kzalloc(sizeof (idefloppy_floppy_t), GFP_KERNEL)) == NULL) { - printk (KERN_ERR "ide-floppy: %s: Can't allocate a floppy structure\n", drive->name); + floppy = kzalloc(sizeof(idefloppy_floppy_t), GFP_KERNEL); + if (!floppy) { + printk(KERN_ERR "ide-floppy: %s: Can't allocate a floppy" + " structure\n", drive->name); goto failed; } @@ -1820,7 +1651,7 @@ static int ide_floppy_probe(ide_drive_t *drive) drive->driver_data = floppy; - idefloppy_setup (drive, floppy); + idefloppy_setup(drive, floppy); g->minors = 1 << PARTN_BITS; g->driverfs_dev = &drive->gendev; @@ -1836,9 +1667,7 @@ failed: return -ENODEV; } -MODULE_DESCRIPTION("ATAPI FLOPPY Driver"); - -static void __exit idefloppy_exit (void) +static void __exit idefloppy_exit(void) { driver_unregister(&idefloppy_driver.gen_driver); } @@ -1853,3 +1682,5 @@ MODULE_ALIAS("ide:*m-floppy*"); module_init(idefloppy_init); module_exit(idefloppy_exit); MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("ATAPI FLOPPY Driver"); +