lkml.org 
[lkml]   [2002]   [Dec]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectRe: Patch for ide-tape driver
Alan:

Here is another copy of my multiple-bug-fix patch for the ide-tape driver,
as of 2.5.53. The corresponding patch for 2.4.21 has already been
accepted by Marcelo. Please apply this to the current kernel (or send it
on up the line) when you have a chance.

Thanks.

Alan Stern
--- linux/drivers/ide/ide-tape.c.orig Mon Dec 9 14:42:07 2002
+++ linux/drivers/ide/ide-tape.c Tue Dec 10 15:40:19 2002
@@ -1,5 +1,5 @@
/*
- * linux/drivers/ide/ide-tape.c Version 1.17a Jan, 2001
+ * linux/drivers/ide/ide-tape.c Version 1.17b Oct, 2002
*
* Copyright (C) 1995 - 1999 Gadi Oxman <gadio@netvision.net.il>
*
@@ -291,6 +291,28 @@
* Ver 1.17a Apr 2001 Willem Riede osst@riede.org
* - Get drive's actual block size from mode sense block descriptor
* - Limit size of pipeline
+ * Ver 1.17b Oct 2002 Alan Stern <stern@rowland.harvard.edu>
+ * Changed IDETAPE_MIN_PIPELINE_STAGES to 1 and actually used
+ * it in the code!
+ * Actually removed aborted stages in idetape_abort_pipeline
+ * instead of just changing the command code.
+ * Made the transfer byte count for Request Sense equal to the
+ * actual length of the data transfer.
+ * Changed handling of partial data transfers: they do not
+ * cause DMA errors.
+ * Moved initiation of DMA transfers to the correct place.
+ * Removed reference to unallocated memory.
+ * Made __idetape_discard_read_pipeline return the number of
+ * sectors skipped, not the number of stages.
+ * Replaced errant kfree() calls with __idetape_kfree_stage().
+ * Fixed off-by-one error in testing the pipeline length.
+ * Fixed handling of filemarks in the read pipeline.
+ * Small code optimization for MTBSF and MTBSFM ioctls.
+ * Don't try to unlock the door during device close if is
+ * already unlocked!
+ * Cosmetic fixes to miscellaneous debugging output messages.
+ * Set the minimum /proc/ide/hd?/settings values for "pipeline",
+ * "pipeline_min", and "pipeline_max" to 1.
*
* Here are some words from the first releases of hd.c, which are quoted
* in ide.c and apply here as well:
@@ -400,7 +422,7 @@
* sharing a (fast) ATA-2 disk with any (slow) new ATAPI device.
*/

-#define IDETAPE_VERSION "1.17a"
+#define IDETAPE_VERSION "1.17b"

#include <linux/config.h>
#include <linux/module.h>
@@ -577,9 +599,10 @@
* whenever we sense that the pipeline is empty, until we reach
* the optimum value or until we reach MAX.
*
- * Setting the following parameter to 0 will disable the pipelined mode.
+ * Setting the following parameter to 0 is illegal: the pipelined mode
+ * cannot be disabled (calculate_speeds() divides by tape->max_stages.)
*/
-#define IDETAPE_MIN_PIPELINE_STAGES 200
+#define IDETAPE_MIN_PIPELINE_STAGES 1
#define IDETAPE_MAX_PIPELINE_STAGES 400
#define IDETAPE_INCREASE_STAGES_RATE 20

@@ -601,8 +624,8 @@
* is verified to be stable enough. This will make it much more
* esthetic.
*/
-#define IDETAPE_DEBUG_INFO 1
-#define IDETAPE_DEBUG_LOG 1
+#define IDETAPE_DEBUG_INFO 0
+#define IDETAPE_DEBUG_LOG 0
#define IDETAPE_DEBUG_LOG_VERBOSE 0
#define IDETAPE_DEBUG_BUGS 1

@@ -1610,24 +1633,6 @@
}
}

-static void idetape_abort_pipeline (ide_drive_t *drive)
-{
- idetape_tape_t *tape = drive->driver_data;
- idetape_stage_t *stage = tape->next_stage;
-
-#if IDETAPE_DEBUG_LOG
- if (tape->debug_level >= 4)
- printk(KERN_INFO "ide-tape: %s: idetape_abort_pipeline called\n", tape->name);
-#endif
- while (stage) {
- if (stage->rq.flags == IDETAPE_WRITE_RQ)
- stage->rq.flags = IDETAPE_ABORTED_WRITE_RQ;
- else if (stage->rq.flags == IDETAPE_READ_RQ)
- stage->rq.flags = IDETAPE_ABORTED_READ_RQ;
- stage = stage->next;
- }
-}
-
/*
* idetape_active_next_stage will declare the next stage as "active".
*/
@@ -1672,7 +1677,7 @@
printk (KERN_INFO "ide-tape: Reached idetape_increase_max_pipeline_stages\n");
#endif /* IDETAPE_DEBUG_LOG */

- tape->max_stages += increase;
+ tape->max_stages += max(increase, 1);
tape->max_stages = max(tape->max_stages, tape->min_pipeline);
tape->max_stages = min(tape->max_stages, tape->max_pipeline);
}
@@ -1745,6 +1750,29 @@
}
}

+static void idetape_abort_pipeline (ide_drive_t *drive, idetape_stage_t *last_stage)
+{
+ idetape_tape_t *tape = drive->driver_data;
+ idetape_stage_t *stage = tape->next_stage;
+ idetape_stage_t *nstage;
+
+#if IDETAPE_DEBUG_LOG
+ if (tape->debug_level >= 4)
+ printk(KERN_INFO "ide-tape: %s: idetape_abort_pipeline called\n", tape->name);
+#endif
+ while (stage) {
+ nstage = stage->next;
+ idetape_kfree_stage(tape, stage);
+ --tape->nr_stages;
+ --tape->nr_pending_stages;
+ stage = nstage;
+ }
+ tape->last_stage = last_stage;
+ if (last_stage)
+ last_stage->next = NULL;
+ tape->next_stage = NULL;
+}
+
/*
* idetape_end_request is used to finish servicing a request, and to
* insert a pending pipeline request into the main device queue.
@@ -1756,6 +1784,7 @@
unsigned long flags;
int error;
int remove_stage = 0;
+ idetape_stage_t *active_stage;
#if ONSTREAM_DEBUG
idetape_stage_t *stage;
os_aux_t *aux;
@@ -1780,6 +1809,7 @@

/* The request was a pipelined data transfer request */
if (tape->active_data_request == rq) {
+ active_stage = tape->active_stage;
tape->active_stage = NULL;
tape->active_data_request = NULL;
tape->nr_pending_stages--;
@@ -1799,18 +1829,20 @@
if (tape->first_frame_position == OS_DATA_ENDFRAME1) {
#if ONSTREAM_DEBUG
if (tape->debug_level >= 2)
- printk("ide-tape: %s: skipping over config parition..\n", tape->name);
+ printk("ide-tape: %s: skipping over config partition.\n", tape->name);
#endif
tape->onstream_write_error = OS_PART_ERROR;
- if (tape->waiting)
+ if (tape->waiting) {
+ rq->waiting = NULL;
complete(tape->waiting);
+ }
}
}
remove_stage = 1;
if (error) {
set_bit(IDETAPE_PIPELINE_ERROR, &tape->flags);
if (error == IDETAPE_ERROR_EOD)
- idetape_abort_pipeline(drive);
+ idetape_abort_pipeline(drive, active_stage);
if (tape->onstream && !tape->raw &&
error == IDETAPE_ERROR_GENERAL &&
tape->sense.sense_key == 3) {
@@ -1821,14 +1853,16 @@
tape->nr_pending_stages++;
tape->next_stage = tape->first_stage;
rq->current_nr_sectors = rq->nr_sectors;
- if (tape->waiting)
+ if (tape->waiting) {
+ rq->waiting = NULL;
complete(tape->waiting);
+ }
}
}
} else if (rq->flags == IDETAPE_READ_RQ) {
if (error == IDETAPE_ERROR_EOD) {
set_bit(IDETAPE_PIPELINE_ERROR, &tape->flags);
- idetape_abort_pipeline(drive);
+ idetape_abort_pipeline(drive, active_stage);
}
}
if (tape->next_stage != NULL && !tape->onstream_write_error) {
@@ -1879,7 +1913,7 @@
idetape_init_pc(pc);
pc->c[0] = IDETAPE_REQUEST_SENSE_CMD;
pc->c[4] = 20;
- pc->request_transfer = 18;
+ pc->request_transfer = 20;
pc->callback = &idetape_request_sense_callback;
}

@@ -1980,7 +2014,7 @@
status.all = HWIF(drive)->INB(IDE_STATUS_REG);

if (test_bit(PC_DMA_IN_PROGRESS, &pc->flags)) {
- if (HWIF(drive)->ide_dma_end(drive)) {
+ if (HWIF(drive)->ide_dma_end(drive) || status.b.check) {
/*
* A DMA error is sometimes expected. For example,
* if the tape is crossing a filemark during a
@@ -1992,8 +2026,18 @@
* actually transferred (we can't receive that
* information from the DMA engine on most chipsets).
*/
+
+ /*
+ * On the contrary, a DMA error is never expected;
+ * it usually indicates a hardware error or abort.
+ * If the tape crosses a filemark during a READ
+ * command, it will issue an irq and position itself
+ * after the filemark (not before). Only a partial
+ * data transfer will occur, but no DMA error.
+ * (AS, 19 Apr 2001)
+ */
set_bit(PC_DMA_ERROR, &pc->flags);
- } else if (!status.b.check) {
+ } else {
pc->actually_transferred = pc->request_transfer;
idetape_update_buffers(pc);
}
@@ -2029,7 +2073,7 @@
if (status.b.check || test_bit(PC_DMA_ERROR, &pc->flags)) { /* Error detected */
#if IDETAPE_DEBUG_LOG
if (tape->debug_level >= 1)
- printk(KERN_INFO "ide-tape: %s: I/O error, ",
+ printk(KERN_INFO "ide-tape: %s: I/O error\n",
tape->name);
#endif /* IDETAPE_DEBUG_LOG */
if (pc->c[0] == IDETAPE_REQUEST_SENSE_CMD) {
@@ -2195,6 +2239,10 @@
BUG();
/* Set the interrupt routine */
ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL);
+#ifdef CONFIG_BLK_DEV_IDEDMA
+ if (test_bit(PC_DMA_IN_PROGRESS, &pc->flags)) /* Begin DMA, if necessary */
+ (void) (HWIF(drive)->ide_dma_begin(drive));
+#endif
/* Send the actual packet */
HWIF(drive)->atapi_output_bytes(drive, pc->c, 12);
return ide_started;
@@ -2223,8 +2271,7 @@
/*
* We will "abort" retrying a packet command in case
* a legitimate error code was received (crossing a
- * filemark, or DMA error in the end of media, for
- * example).
+ * filemark, or end of the media, for example).
*/
if (!test_bit(PC_ABORT, &pc->flags)) {
if (!(pc->c[0] == IDETAPE_TEST_UNIT_READY_CMD &&
@@ -2249,7 +2296,7 @@
}
#if IDETAPE_DEBUG_LOG
if (tape->debug_level >= 2)
- printk(KERN_INFO "ide-tape: Retry number - %d\n", pc->retries);
+ printk(KERN_INFO "ide-tape: Retry number - %d, cmd = %02X\n", pc->retries, pc->c[0]);
#endif /* IDETAPE_DEBUG_LOG */

pc->retries++;
@@ -2275,10 +2322,8 @@
OUT_BYTE(bcount.b.high, IDE_BCOUNTH_REG);
OUT_BYTE(bcount.b.low, IDE_BCOUNTL_REG);
OUT_BYTE(drive->select.all, IDE_SELECT_REG);
- if (dma_ok) { /* Begin DMA, if necessary */
+ if (dma_ok) /* Will begin DMA later */
set_bit(PC_DMA_IN_PROGRESS, &pc->flags);
- (void) (HWIF(drive)->ide_dma_begin(drive));
- }
if (test_bit(IDETAPE_DRQ_INTERRUPT, &tape->flags)) {
if (HWGROUP(drive)->handler != NULL) /* paranoia check */
BUG();
@@ -3069,7 +3114,7 @@
tape->waiting = &wait;
spin_unlock(&tape->spinlock);
wait_for_completion(&wait);
- rq->waiting = NULL;
+ /* The stage and its struct request have been deallocated */
tape->waiting = NULL;
spin_lock_irq(&tape->spinlock);
}
@@ -3333,11 +3378,15 @@

if (tape->chrdev_direction != idetape_direction_read)
return 0;
+ cnt = tape->merge_stage_size / tape->tape_block_size;
+ if (test_and_clear_bit(IDETAPE_FILEMARK, &tape->flags))
+ ++cnt; /* Filemarks count as 1 sector */
tape->merge_stage_size = 0;
if (tape->merge_stage != NULL) {
__idetape_kfree_stage(tape->merge_stage);
tape->merge_stage = NULL;
}
+ clear_bit(IDETAPE_PIPELINE_ERROR, &tape->flags);
tape->chrdev_direction = idetape_direction_none;

if (tape->first_stage == NULL)
@@ -3349,9 +3398,14 @@
idetape_wait_for_request(drive, tape->active_data_request);
spin_unlock_irqrestore(&tape->spinlock, flags);

- cnt = tape->nr_stages - tape->nr_pending_stages;
- while (tape->first_stage != NULL)
+ while (tape->first_stage != NULL) {
+ struct request *rq_ptr = &tape->first_stage->rq;
+
+ cnt += rq_ptr->nr_sectors - rq_ptr->current_nr_sectors;
+ if (rq_ptr->errors == IDETAPE_ERROR_FILEMARK)
+ ++cnt;
idetape_remove_stage_head(drive);
+ }
tape->nr_pending_stages = 0;
tape->max_stages = tape->min_pipeline;
return cnt;
@@ -3946,7 +4000,7 @@
*/
bytes_read = idetape_queue_rw_tail(drive, IDETAPE_READ_RQ, 0, tape->merge_stage->bio);
if (bytes_read < 0) {
- kfree(tape->merge_stage);
+ __idetape_kfree_stage(tape->merge_stage);
tape->merge_stage = NULL;
tape->chrdev_direction = idetape_direction_none;
return bytes_read;
@@ -3959,7 +4013,7 @@
rq.sector = tape->first_frame_position;
rq.nr_sectors = rq.current_nr_sectors = blocks;
if (!test_bit(IDETAPE_PIPELINE_ERROR, &tape->flags) &&
- tape->nr_stages <= max_stages) {
+ tape->nr_stages < max_stages) {
new_stage = idetape_kmalloc_stage(tape);
while (new_stage != NULL) {
new_stage->rq = rq;
@@ -4069,6 +4123,12 @@
#endif /* IDETAPE_DEBUG_LOG */

/*
+ * If we are at a filemark, return a read length of 0
+ */
+ if (test_bit(IDETAPE_FILEMARK, &tape->flags))
+ return 0;
+
+ /*
* Wait for the next logical block to be available at the head
* of the pipeline
*/
@@ -4097,14 +4157,7 @@
}
if (rq_ptr->errors == IDETAPE_ERROR_EOD)
return 0;
- if (rq_ptr->errors == IDETAPE_ERROR_FILEMARK) {
- idetape_switch_buffers(tape, tape->first_stage);
- set_bit(IDETAPE_FILEMARK, &tape->flags);
-#if USE_IOTRACE
- IO_trace(IO_IDETAPE_FIFO, tape->pipeline_head, tape->buffer_head, tape->tape_head, tape->minor);
-#endif
- calculate_speeds(drive);
- } else {
+ else {
idetape_switch_buffers(tape, tape->first_stage);
if (rq_ptr->errors == IDETAPE_ERROR_GENERAL) {
#if ONSTREAM_DEBUG
@@ -4112,7 +4165,8 @@
printk(KERN_INFO "ide-tape: error detected, bytes_read %d\n", bytes_read);
#endif
}
- clear_bit(IDETAPE_FILEMARK, &tape->flags);
+ if (rq_ptr->errors == IDETAPE_ERROR_FILEMARK)
+ set_bit(IDETAPE_FILEMARK, &tape->flags);
spin_lock_irqsave(&tape->spinlock, flags);
idetape_remove_stage_head(drive);
spin_unlock_irqrestore(&tape->spinlock, flags);
@@ -4455,6 +4509,14 @@
tape->restart_speed_control_req = 1;
return retval;
}
+
+ if (mt_count == 0)
+ return 0;
+ if (MTBSF == mt_op || MTBSFM == mt_op) {
+ if (!tape->capabilities.sprev)
+ return -EIO;
+ mt_count = - mt_count;
+ }

if (tape->chrdev_direction == idetape_direction_read) {
/*
@@ -4462,28 +4524,36 @@
* filemarks.
*/
tape->merge_stage_size = 0;
- clear_bit(IDETAPE_FILEMARK, &tape->flags);
+ if (test_and_clear_bit(IDETAPE_FILEMARK, &tape->flags))
+ ++count;
while (tape->first_stage != NULL) {
- idetape_wait_first_stage(drive);
- if (tape->first_stage->rq.errors == IDETAPE_ERROR_FILEMARK)
- count++;
if (count == mt_count) {
- switch (mt_op) {
- case MTFSF:
- spin_lock_irqsave(&tape->spinlock, flags);
- idetape_remove_stage_head(drive);
- spin_unlock_irqrestore(&tape->spinlock, flags);
- case MTFSFM:
- return (0);
- default:
- break;
- }
+ if (mt_op == MTFSFM)
+ set_bit(IDETAPE_FILEMARK, &tape->flags);
+ return 0;
}
spin_lock_irqsave(&tape->spinlock, flags);
+ if (tape->first_stage == tape->active_stage) {
+ /*
+ * We have reached the active stage in the read pipeline.
+ * There is no point in allowing the drive to continue
+ * reading any farther, so we stop the pipeline.
+ *
+ * This section should be moved to a separate subroutine,
+ * because a similar function is performed in
+ * __idetape_discard_read_pipeline(), for example.
+ */
+ tape->next_stage = NULL;
+ spin_unlock_irqrestore(&tape->spinlock, flags);
+ idetape_wait_first_stage(drive);
+ tape->next_stage = tape->first_stage->next;
+ } else
+ spin_unlock_irqrestore(&tape->spinlock, flags);
+ if (tape->first_stage->rq.errors == IDETAPE_ERROR_FILEMARK)
+ ++count;
idetape_remove_stage_head(drive);
- spin_unlock_irqrestore(&tape->spinlock, flags);
}
- idetape_discard_read_pipeline(drive, 1);
+ idetape_discard_read_pipeline(drive, 0);
}

/*
@@ -4492,25 +4562,17 @@
*/
switch (mt_op) {
case MTFSF:
+ case MTBSF:
idetape_create_space_cmd(&pc,mt_count-count,IDETAPE_SPACE_OVER_FILEMARK);
return (idetape_queue_pc_tail(drive, &pc));
case MTFSFM:
- if (!tape->capabilities.sprev)
- return (-EIO);
- retval = idetape_space_over_filemarks(drive, MTFSF, mt_count-count);
- if (retval) return (retval);
- return (idetape_space_over_filemarks(drive, MTBSF, 1));
- case MTBSF:
- if (!tape->capabilities.sprev)
- return (-EIO);
- idetape_create_space_cmd(&pc,-(mt_count+count),IDETAPE_SPACE_OVER_FILEMARK);
- return (idetape_queue_pc_tail(drive, &pc));
case MTBSFM:
if (!tape->capabilities.sprev)
return (-EIO);
- retval = idetape_space_over_filemarks(drive, MTBSF, mt_count+count);
+ retval = idetape_space_over_filemarks(drive, MTFSF, mt_count-count);
if (retval) return (retval);
- return (idetape_space_over_filemarks(drive, MTFSF, 1));
+ count = (MTBSFM == mt_op ? 1 : -1);
+ return (idetape_space_over_filemarks(drive, MTFSF, count));
default:
printk(KERN_ERR "ide-tape: MTIO operation %d not supported\n",mt_op);
return (-EIO);
@@ -4861,7 +4923,7 @@
*/
retval = idetape_queue_rw_tail(drive, IDETAPE_WRITE_RQ, 0, tape->merge_stage->bio);
if (retval < 0) {
- kfree(tape->merge_stage);
+ __idetape_kfree_stage(tape->merge_stage);
tape->merge_stage = NULL;
tape->chrdev_direction = idetape_direction_none;
return retval;
@@ -5447,8 +5509,10 @@
printk(KERN_ERR "ide-tape: %s: drive not ready\n", tape->name);
return -EBUSY;
}
- idetape_read_position(drive);
- clear_bit(IDETAPE_PIPELINE_ERROR, &tape->flags);
+ if (tape->onstream)
+ idetape_read_position(drive);
+ if (tape->chrdev_direction != idetape_direction_read)
+ clear_bit(IDETAPE_PIPELINE_ERROR, &tape->flags);

if (tape->chrdev_direction == idetape_direction_none) {
if (idetape_create_prevent_cmd(drive, &pc, 1)) {
@@ -5520,10 +5584,11 @@
if (minor < 128)
(void) idetape_rewind_tape(drive);
if (tape->chrdev_direction == idetape_direction_none) {
- if (tape->door_locked != DOOR_EXPLICITLY_LOCKED) {
- if (idetape_create_prevent_cmd(drive, &pc, 0))
+ if (tape->door_locked == DOOR_LOCKED) {
+ if (idetape_create_prevent_cmd(drive, &pc, 0)) {
if (!idetape_queue_pc_tail(drive, &pc))
tape->door_locked = DOOR_UNLOCKED;
+ }
}
}
clear_bit(IDETAPE_BUSY, &tape->flags);
@@ -5556,34 +5621,34 @@
printk(KERN_INFO "ide-tape: Dumping ATAPI Identify Device tape parameters\n");
printk(KERN_INFO "ide-tape: Protocol Type: ");
switch (gcw.protocol) {
- case 0: case 1: printk(KERN_INFO "ATA\n");break;
- case 2: printk(KERN_INFO "ATAPI\n");break;
- case 3: printk(KERN_INFO "Reserved (Unknown to ide-tape)\n");break;
+ case 0: case 1: printk("ATA\n");break;
+ case 2: printk("ATAPI\n");break;
+ case 3: printk("Reserved (Unknown to ide-tape)\n");break;
}
printk(KERN_INFO "ide-tape: Device Type: %x - ",gcw.device_type);
switch (gcw.device_type) {
- case 0: printk(KERN_INFO "Direct-access Device\n");break;
- case 1: printk(KERN_INFO "Streaming Tape Device\n");break;
- case 2: case 3: case 4: printk(KERN_INFO "Reserved\n");break;
- case 5: printk(KERN_INFO "CD-ROM Device\n");break;
- case 6: printk(KERN_INFO "Reserved\n");
- case 7: printk(KERN_INFO "Optical memory Device\n");break;
- case 0x1f: printk(KERN_INFO "Unknown or no Device type\n");break;
- default: printk(KERN_INFO "Reserved\n");
+ case 0: printk("Direct-access Device\n");break;
+ case 1: printk("Streaming Tape Device\n");break;
+ case 2: case 3: case 4: printk("Reserved\n");break;
+ case 5: printk("CD-ROM Device\n");break;
+ case 6: printk("Reserved\n");
+ case 7: printk("Optical memory Device\n");break;
+ case 0x1f: printk("Unknown or no Device type\n");break;
+ default: printk("Reserved\n");
}
printk(KERN_INFO "ide-tape: Removable: %s",gcw.removable ? "Yes\n":"No\n");
printk(KERN_INFO "ide-tape: Command Packet DRQ Type: ");
switch (gcw.drq_type) {
- case 0: printk(KERN_INFO "Microprocessor DRQ\n");break;
- case 1: printk(KERN_INFO "Interrupt DRQ\n");break;
- case 2: printk(KERN_INFO "Accelerated DRQ\n");break;
- case 3: printk(KERN_INFO "Reserved\n");break;
+ case 0: printk("Microprocessor DRQ\n");break;
+ case 1: printk("Interrupt DRQ\n");break;
+ case 2: printk("Accelerated DRQ\n");break;
+ case 3: printk("Reserved\n");break;
}
printk(KERN_INFO "ide-tape: Command Packet Size: ");
switch (gcw.packet_size) {
- case 0: printk(KERN_INFO "12 bytes\n");break;
- case 1: printk(KERN_INFO "16 bytes\n");break;
- default: printk(KERN_INFO "Reserved\n");break;
+ case 0: printk("12 bytes\n");break;
+ case 1: printk("16 bytes\n");break;
+ default: printk("Reserved\n");break;
}
printk(KERN_INFO "ide-tape: Model: %.40s\n",id->model);
printk(KERN_INFO "ide-tape: Firmware Revision: %.8s\n",id->fw_rev);
@@ -5599,45 +5664,45 @@
printk(KERN_INFO "ide-tape: Single Word DMA supported modes: ");
for (i=0,mask=1;i<8;i++,mask=mask << 1) {
if (id->dma_1word & mask)
- printk(KERN_INFO "%d ",i);
+ printk("%d ",i);
if (id->dma_1word & (mask << 8))
- printk(KERN_INFO "(active) ");
+ printk("(active) ");
}
- printk(KERN_INFO "\n");
+ printk("\n");
printk(KERN_INFO "ide-tape: Multi Word DMA supported modes: ");
for (i=0,mask=1;i<8;i++,mask=mask << 1) {
if (id->dma_mword & mask)
- printk(KERN_INFO "%d ",i);
+ printk("%d ",i);
if (id->dma_mword & (mask << 8))
- printk(KERN_INFO "(active) ");
+ printk("(active) ");
}
- printk(KERN_INFO "\n");
+ printk("\n");
if (id->field_valid & 0x0002) {
printk(KERN_INFO "ide-tape: Enhanced PIO Modes: %s\n",
id->eide_pio_modes & 1 ? "Mode 3":"None");
printk(KERN_INFO "ide-tape: Minimum Multi-word DMA cycle per word: ");
if (id->eide_dma_min == 0)
- printk(KERN_INFO "Not supported\n");
+ printk("Not supported\n");
else
- printk(KERN_INFO "%d ns\n",id->eide_dma_min);
+ printk("%d ns\n",id->eide_dma_min);

printk(KERN_INFO "ide-tape: Manufacturer\'s Recommended Multi-word cycle: ");
if (id->eide_dma_time == 0)
- printk(KERN_INFO "Not supported\n");
+ printk("Not supported\n");
else
- printk(KERN_INFO "%d ns\n",id->eide_dma_time);
+ printk("%d ns\n",id->eide_dma_time);

printk(KERN_INFO "ide-tape: Minimum PIO cycle without IORDY: ");
if (id->eide_pio == 0)
- printk(KERN_INFO "Not supported\n");
+ printk("Not supported\n");
else
- printk(KERN_INFO "%d ns\n",id->eide_pio);
+ printk("%d ns\n",id->eide_pio);

printk(KERN_INFO "ide-tape: Minimum PIO cycle with IORDY: ");
if (id->eide_pio_iordy == 0)
- printk(KERN_INFO "Not supported\n");
+ printk("Not supported\n");
else
- printk(KERN_INFO "%d ns\n",id->eide_pio_iordy);
+ printk("%d ns\n",id->eide_pio_iordy);

} else
printk(KERN_INFO "ide-tape: According to the device, fields 64-70 are not valid.\n");
@@ -5946,9 +6011,9 @@
* drive setting name read/write ioctl ioctl data type min max mul_factor div_factor data pointer set function
*/
ide_add_setting(drive, "buffer", SETTING_READ, -1, -1, TYPE_SHORT, 0, 0xffff, 1, 2, &tape->capabilities.buffer_size, NULL);
- ide_add_setting(drive, "pipeline_min", SETTING_RW, -1, -1, TYPE_INT, 2, 0xffff, tape->stage_size / 1024, 1, &tape->min_pipeline, NULL);
- ide_add_setting(drive, "pipeline", SETTING_RW, -1, -1, TYPE_INT, 2, 0xffff, tape->stage_size / 1024, 1, &tape->max_stages, NULL);
- ide_add_setting(drive, "pipeline_max", SETTING_RW, -1, -1, TYPE_INT, 2, 0xffff, tape->stage_size / 1024, 1, &tape->max_pipeline, NULL);
+ ide_add_setting(drive, "pipeline_min", SETTING_RW, -1, -1, TYPE_INT, 1, 0xffff, tape->stage_size / 1024, 1, &tape->min_pipeline, NULL);
+ ide_add_setting(drive, "pipeline", SETTING_RW, -1, -1, TYPE_INT, 1, 0xffff, tape->stage_size / 1024, 1, &tape->max_stages, NULL);
+ ide_add_setting(drive, "pipeline_max", SETTING_RW, -1, -1, TYPE_INT, 1, 0xffff, tape->stage_size / 1024, 1, &tape->max_pipeline, NULL);
ide_add_setting(drive, "pipeline_used",SETTING_READ, -1, -1, TYPE_INT, 0, 0xffff, tape->stage_size / 1024, 1, &tape->nr_stages, NULL);
ide_add_setting(drive, "pipeline_pending",SETTING_READ,-1, -1, TYPE_INT, 0, 0xffff, tape->stage_size / 1024, 1, &tape->nr_pending_stages, NULL);
ide_add_setting(drive, "speed", SETTING_READ, -1, -1, TYPE_SHORT, 0, 0xffff, 1, 1, &tape->capabilities.speed, NULL);
@@ -6063,8 +6128,11 @@
si_meminfo(&si);
if (tape->max_stages * tape->stage_size > si.totalram * si.mem_unit / 10)
tape->max_stages = si.totalram * si.mem_unit / (10 * tape->stage_size);
- tape->min_pipeline = tape->max_stages;
- tape->max_pipeline = tape->max_stages * 2;
+ tape->max_stages = min(tape->max_stages, IDETAPE_MAX_PIPELINE_STAGES);
+ tape->min_pipeline = min(tape->max_stages, IDETAPE_MIN_PIPELINE_STAGES);
+ tape->max_pipeline = min(tape->max_stages * 2, IDETAPE_MAX_PIPELINE_STAGES);
+ if (tape->max_stages == 0)
+ tape->max_stages = tape->min_pipeline = tape->max_pipeline = 1;

t1 = (tape->stage_size * HZ) / (speed * 1000);
tmid = (tape->capabilities.buffer_size * 32 * HZ) / (speed * 125);
\
 
 \ /
  Last update: 2005-03-22 13:32    [W:0.080 / U:0.320 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site