IDE patch for 2.0.34-pre15+

Gadi Oxman (gadio@netvision.net.il)
Fri, 22 May 1998 08:19:47 +0400 (IDT)


Hi,

I have appended a 2.0.x IDE patch which contains:

- ide-tape support for HP COLORADO 2.5 and 4GB ATAPI tape drives.
- autodetection and DMA support for the Promise/33 controller.
- ide-scsi support for HP CD-Writer+ 7200.
- fixes "acknowledge media change" on removable ATA drives.
- fixes misdetection of NEC 2X cdrom drive as floppy.
- issues ATAPI reset and re-probes in the "hdx: no response" case.
- some ide-floppy changes - activates the "max_sectors_per_request"
work-around only for IOMEGA ZIP 21.D, avoid issuing a START command
if possible (causes irq timeouts on some LS-120 drives), etc.
- adds a "hdx=ide-scsi" command line parameter, so that we would be
able to support one cdrom drive with ide-cd, and one with ide-scsi.

Gadi

diff -u --recursive --new-file v2.0.34pre15/linux/Documentation/ide.txt linux/Documentation/ide.txt
--- v2.0.34pre15/linux/Documentation/ide.txt Mon Aug 4 22:45:55 1997
+++ linux/Documentation/ide.txt Thu May 21 23:50:00 1998
@@ -258,6 +258,7 @@
older/odd IDE drives.
"hdx=slow" : insert a huge pause after each access to the data
port. Should be used only as a last resort.
+ "hdx=ide-scsi" : use the ide-scsi driver for hdx

"idebus=xx" : inform IDE driver of VESA/PCI bus speed in Mhz,
where "xx" is between 20 and 66 inclusive,
diff -u --recursive --new-file v2.0.34pre15/linux/drivers/block/ide-floppy.c linux/drivers/block/ide-floppy.c
--- v2.0.34pre15/linux/drivers/block/ide-floppy.c Mon Aug 4 22:45:55 1997
+++ linux/drivers/block/ide-floppy.c Thu May 21 22:25:32 1998
@@ -1,5 +1,5 @@
/*
- * linux/drivers/block/ide-floppy.c Version 0.7 - ALPHA Aug 4, 1997
+ * linux/drivers/block/ide-floppy.c Version 0.71 - ALPHA May 21, 1998
*
* Copyright (C) 1996, 1997 Gadi Oxman <gadio@netvision.net.il>
*/
@@ -23,6 +23,11 @@
* Fix potential null dereferencing with DEBUG_LOG.
* Ver 0.6 Jul 3 97 Limit max sectors per read/write command to 64.
* Ver 0.7 Aug 4 97 Increase irq timeout from 10 to 100 seconds.
+ * Ver 0.71 May 21 98 Disallow opening a write protected media for writing
+ * Limit max sectors only on IOMEGA ZIP 21.D
+ * Issue START cmd only if TEST_UNIT_READY fails
+ * Add CDROMEJECT ioctl
+ * Clean up error messages a bit
*/

#include <linux/config.h>
@@ -41,6 +46,7 @@
#include <linux/hdreg.h>
#include <linux/genhd.h>
#include <linux/malloc.h>
+#include <linux/cdrom.h>

#include <asm/byteorder.h>
#include <asm/irq.h>
@@ -80,10 +86,7 @@
*/
#define IDEFLOPPY_PC_STACK (10 + IDEFLOPPY_MAX_PC_RETRIES)

-/*
- * Some drives fail read/write requests with 64 or more sectors.
- */
-#define IDEFLOPPY_MAX_SECTORS 64
+#define IDEFLOPPY_MAX_SECTORS 256

/*
* Some drives require a longer irq timeout.
@@ -203,6 +206,8 @@
int blocks, block_size, bs_factor; /* Current format */
idefloppy_capacity_descriptor_t capacity; /* Last format capacity */
idefloppy_flexible_disk_page_t flexible_disk_page; /* Copy of the flexible disk page */
+ int wp;
+ int max_sectors;

unsigned int flags; /* Status/Action flags */
} idefloppy_floppy_t;
@@ -950,10 +955,16 @@
pc->c[4] = start;
}

+static void idefloppy_create_test_unit_ready_cmd (idefloppy_pc_t *pc)
+{
+ idefloppy_init_pc (pc);
+ pc->c[0] = IDEFLOPPY_TEST_UNIT_READY_CMD;
+}
+
static void idefloppy_create_rw_cmd (idefloppy_floppy_t *floppy, idefloppy_pc_t *pc, struct request *rq, unsigned long sector)
{
int block = sector / floppy->bs_factor;
- int blocks = IDEFLOPPY_MIN(rq->nr_sectors / floppy->bs_factor, IDEFLOPPY_MAX_SECTORS);
+ int blocks = IDEFLOPPY_MIN(rq->nr_sectors, floppy->max_sectors) / floppy->bs_factor;

#if IDEFLOPPY_DEBUG_LOG
printk ("create_rw1%d_cmd: block == %d, blocks == %d\n",
@@ -1057,6 +1068,7 @@
return 1;
}
header = (idefloppy_mode_parameter_header_t *) pc.buffer;
+ floppy->wp = header->wp;
page = (idefloppy_flexible_disk_page_t *) (header + 1);

page->transfer_rate = ntohs (page->transfer_rate);
@@ -1075,8 +1087,10 @@
drive->bios_sect = page->sectors;
lba_capacity = floppy->blocks * floppy->block_size;
if (capacity != lba_capacity) {
- printk (KERN_NOTICE "%s: The drive reports both %d and %d bytes as its capacity\n",
- drive->name, capacity, lba_capacity);
+ if (!lba_capacity)
+ printk(KERN_NOTICE "%s: no media in the drive\n");
+ else printk (KERN_NOTICE "%s: The drive reports both %d and %d bytes as its capacity\n",
+ drive->name, capacity, lba_capacity);
capacity = IDEFLOPPY_MIN(capacity, lba_capacity);
floppy->blocks = floppy->block_size ? capacity / floppy->block_size : 0;
}
@@ -1143,6 +1157,17 @@
int idefloppy_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
+ idefloppy_pc_t pc;
+
+ if (cmd == CDROMEJECT) {
+ if (drive->usage > 1)
+ return -EBUSY;
+ idefloppy_create_prevent_cmd (&pc, 0);
+ (void) idefloppy_queue_pc_tail (drive, &pc);
+ idefloppy_create_start_stop_cmd (&pc, 2);
+ (void) idefloppy_queue_pc_tail (drive, &pc);
+ return 0;
+ }
return -EIO;
}

@@ -1160,13 +1185,21 @@

MOD_INC_USE_COUNT;
if (drive->usage == 1) {
- idefloppy_create_start_stop_cmd (&pc, 1);
- (void) idefloppy_queue_pc_tail (drive, &pc);
+ idefloppy_create_test_unit_ready_cmd(&pc);
+ if (idefloppy_queue_pc_tail(drive, &pc)) {
+ idefloppy_create_start_stop_cmd (&pc, 1);
+ (void) idefloppy_queue_pc_tail (drive, &pc);
+ }
if (idefloppy_get_capacity (drive)) {
drive->usage--;
MOD_DEC_USE_COUNT;
return -EIO;
}
+ if (floppy->wp && (filp->f_mode & 2)) {
+ drive->usage--;
+ MOD_DEC_USE_COUNT;
+ return -EROFS;
+ }
set_bit (IDEFLOPPY_MEDIA_CHANGED, &floppy->flags);
idefloppy_create_prevent_cmd (&pc, 1);
(void) idefloppy_queue_pc_tail (drive, &pc);
@@ -1328,46 +1361,6 @@
}

/*
- * idefloppy_get_capabilities asks the floppy about its various
- * parameters.
- */
-static void idefloppy_get_capabilities (ide_drive_t *drive)
-{
- idefloppy_pc_t pc;
- idefloppy_mode_parameter_header_t *header;
- idefloppy_capabilities_page_t *capabilities;
-
- idefloppy_create_mode_sense_cmd (&pc, IDEFLOPPY_CAPABILITIES_PAGE, MODE_SENSE_CURRENT);
- if (idefloppy_queue_pc_tail (drive,&pc)) {
- printk (KERN_ERR "ide-floppy: Can't get drive capabilities\n");
- return;
- }
- header = (idefloppy_mode_parameter_header_t *) pc.buffer;
- capabilities = (idefloppy_capabilities_page_t *) (header + 1);
-
- if (!capabilities->sflp)
- printk (KERN_INFO "%s: Warning - system floppy device bit is not set\n", drive->name);
-
-#if IDEFLOPPY_DEBUG_INFO
- printk (KERN_INFO "Dumping the results of the MODE SENSE packet command\n");
- printk (KERN_INFO "Mode Parameter Header:\n");
- printk (KERN_INFO "Mode Data Length - %d\n",header->mode_data_length);
- printk (KERN_INFO "Medium Type - %d\n",header->medium_type);
- printk (KERN_INFO "WP - %d\n",header->wp);
-
- printk (KERN_INFO "Capabilities Page:\n");
- printk (KERN_INFO "Page code - %d\n",capabilities->page_code);
- printk (KERN_INFO "Page length - %d\n",capabilities->page_length);
- printk (KERN_INFO "PS - %d\n",capabilities->ps);
- printk (KERN_INFO "System Floppy Type device - %s\n",capabilities->sflp ? "Yes":"No");
- printk (KERN_INFO "Supports Reporting progress of Format - %s\n",capabilities->srfp ? "Yes":"No");
- printk (KERN_INFO "Non CD Optical device - %s\n",capabilities->ncd ? "Yes":"No");
- printk (KERN_INFO "Multiple LUN support - %s\n",capabilities->sml ? "Yes":"No");
- printk (KERN_INFO "Total LUN supported - %s\n",capabilities->tlun ? "Yes":"No");
-#endif /* IDEFLOPPY_DEBUG_INFO */
-}
-
-/*
* Driver initialization.
*/
void idefloppy_setup (ide_drive_t *drive)
@@ -1382,7 +1375,10 @@
floppy->pc = floppy->pc_stack;
if (gcw.drq_type == 1)
set_bit (IDEFLOPPY_DRQ_INTERRUPT, &floppy->flags);
-
- idefloppy_get_capabilities (drive);
+ if (strcmp(drive->id->model, "IOMEGA ZIP 100 ATAPI") == 0 &&
+ strcmp(drive->id->fw_rev, "21.D") == 0)
+ floppy->max_sectors = 64;
+ else
+ floppy->max_sectors = IDEFLOPPY_MAX_SECTORS;
(void) idefloppy_get_capacity (drive);
}
diff -u --recursive --new-file v2.0.34pre15/linux/drivers/block/ide-tape.c linux/drivers/block/ide-tape.c
--- v2.0.34pre15/linux/drivers/block/ide-tape.c Thu Nov 14 10:34:52 1996
+++ linux/drivers/block/ide-tape.c Thu May 21 22:30:20 1998
@@ -1,5 +1,5 @@
/*
- * linux/drivers/block/ide-tape.c Version 1.9 - ALPHA Nov 5, 1996
+ * linux/drivers/block/ide-tape.c Version 1.91 May 21, 1998
*
* Copyright (C) 1995, 1996 Gadi Oxman <gadio@netvision.net.il>
*
@@ -195,15 +195,8 @@
* MTTELL was sometimes returning incorrect results.
* Return the real block size in the MTIOCGET ioctl.
* Some error recovery bug fixes.
- *
- * We are currently in an *alpha* stage. The driver is not complete and not
- * much tested. I would strongly suggest to:
- *
- * 1. Connect the tape to a separate interface and irq.
- * 2. Be truly prepared for a kernel crash and the resulting data loss.
- * 3. Don't rely too much on the resulting backups.
- *
- * Other than that, enjoy !
+ * Ver 1.91 May 21 98 Add support for INTERRUPT DRQ devices.
+ * Add "speed == 0" work-around for HP COLORADO 5GB
*
* Here are some words from the first releases of hd.c, which are quoted
* in ide.c and apply here as well:
@@ -1157,11 +1150,6 @@
printk ("ide-tape: The removable flag is not set\n");support=0;
}

- if (gcw.drq_type != 2) {
- printk ("ide-tape: Sorry, DRQ types other than Accelerated DRQ\n");
- printk ("ide-tape: are still not supported by the driver\n");support=0;
- }
-
if (gcw.packet_size != 0) {
printk ("ide-tape: Packet size is not 12 bytes long\n");
if (gcw.packet_size == 1)
@@ -1233,6 +1221,8 @@
{
idetape_tape_t *tape=&(drive->tape);
unsigned int allocation_length;
+ struct idetape_id_gcw gcw;
+
#if IDETAPE_ANTICIPATE_READ_WRITE_DSC
ide_hwif_t *hwif = HWIF(drive);
unsigned long t1, tmid, tn;
@@ -1260,7 +1250,10 @@
tape->chrdev_direction=idetape_direction_none;
tape->reset_issued=0;
tape->pc=&(tape->pc_stack [0]);
-
+
+ *((unsigned short *) &gcw) = drive->id->config;
+ tape->drq_interrupt = (gcw.drq_type == 1) ? 1 : 0;
+
#if IDETAPE_PIPELINE
tape->max_number_of_stages=IDETAPE_MIN_PIPELINE_STAGES;
#else
@@ -1397,6 +1390,15 @@
capabilities->speed=idetape_swap_short (capabilities->speed);
capabilities->buffer_size=idetape_swap_short (capabilities->buffer_size);

+ if (!capabilities->speed) {
+ printk("ide-tape: %s: overriding capabilities->speed (assuming 650KB/sec)\n", drive->name);
+ capabilities->speed = 650;
+ }
+ if (!capabilities->max_speed) {
+ printk("ide-tape: %s: overriding capabilities->max_speed (assuming 650KB/sec)\n", drive->name);
+ capabilities->max_speed = 650;
+ }
+
tape->capabilities=*capabilities; /* Save us a copy */
tape->tape_block_size=capabilities->blk512 ? 512:1024;

@@ -1441,6 +1443,26 @@
#endif /* IDETAPE_DEBUG_LOG */
}

+static void idetape_transfer_pc (ide_drive_t *drive)
+{
+ idetape_tape_t *tape=&(drive->tape);
+ idetape_packet_command_t *pc = tape->pc;
+ idetape_ireason_reg_t ireason;
+
+ if (ide_wait_stat (drive,DRQ_STAT,BUSY_STAT,WAIT_READY)) {
+ printk (KERN_ERR "ide-tape: Strange, packet command initiated yet DRQ isn't asserted\n");
+ return;
+ }
+ ireason.all=IN_BYTE (IDE_IREASON_REG);
+ if (!ireason.b.cod || ireason.b.io) {
+ printk (KERN_ERR "ide-tape: (IO,CoD) != (0,1) while issuing a packet command\n");
+ ide_do_reset (drive);
+ return;
+ }
+ ide_set_handler (drive, &idetape_pc_intr, WAIT_CMD); /* Set the interrupt routine */
+ ide_output_data (drive,pc->c,12/4); /* Send the actual packet */
+}
+
/*
* Packet Command Interface
*
@@ -1489,7 +1511,6 @@
{
idetape_tape_t *tape;
idetape_bcount_reg_t bcount;
- idetape_ireason_reg_t ireason;
int dma_ok=0;

tape=&(drive->tape);
@@ -1562,37 +1583,21 @@
OUT_BYTE (bcount.b.high,IDETAPE_BCOUNTH_REG);
OUT_BYTE (bcount.b.low,IDETAPE_BCOUNTL_REG);
OUT_BYTE (drive->select.all,IDETAPE_DRIVESEL_REG);
-
- ide_set_handler (drive,handler,WAIT_CMD); /* Set the interrupt routine */
- OUT_BYTE (WIN_PACKETCMD,IDETAPE_ATACOMMAND_REG); /* Issue the packet command */
- if (ide_wait_stat (drive,DRQ_STAT,BUSY_STAT,WAIT_READY)) { /* Wait for DRQ to be ready - Assuming Accelerated DRQ */
- /*
- * We currently only support tape drives which report
- * accelerated DRQ assertion. For this case, specs
- * allow up to 50us. We really shouldn't get here.
- *
- * ??? Still needs to think what to do if we reach
- * here anyway.
- */
-
- printk ("ide-tape: Strange, packet command initiated yet DRQ isn't asserted\n");
- return;
- }
-
- ireason.all=IN_BYTE (IDETAPE_IREASON_REG);
- if (!ireason.b.cod || ireason.b.io) {
- printk ("ide-tape: (IO,CoD) != (0,1) while issuing a packet command\n");
- ide_do_reset (drive);
- return;
- }
-
- ide_output_data (drive,pc->c,12/4); /* Send the actual packet */
+
#ifdef CONFIG_BLK_DEV_TRITON
if ((pc->dma_in_progress=dma_ok)) { /* Begin DMA, if necessary */
pc->dma_error=0;
(void) (HWIF(drive)->dmaproc(ide_dma_begin, drive));
}
#endif /* CONFIG_BLK_DEV_TRITON */
+
+ if (tape->drq_interrupt) {
+ ide_set_handler (drive, &idetape_transfer_pc, WAIT_CMD);
+ OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* Issue the packet command */
+ } else {
+ OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG);
+ idetape_transfer_pc (drive);
+ }
}

/*
diff -u --recursive --new-file v2.0.34pre15/linux/drivers/block/ide-tape.h linux/drivers/block/ide-tape.h
--- v2.0.34pre15/linux/drivers/block/ide-tape.h Wed Nov 6 15:48:32 1996
+++ linux/drivers/block/ide-tape.h Thu May 21 22:26:03 1998
@@ -511,6 +511,8 @@
idetape_pipeline_stage_t *last_stage; /* New requests will be added to the pipeline here */
int error_in_pipeline_stage; /* Set when an error was detected in one of the pipeline stages */

+ int drq_interrupt;
+
} idetape_tape_t;

/*
diff -u --recursive --new-file v2.0.34pre15/linux/drivers/block/ide.c linux/drivers/block/ide.c
--- v2.0.34pre15/linux/drivers/block/ide.c Thu May 21 21:53:22 1998
+++ linux/drivers/block/ide.c Fri May 22 08:05:49 1998
@@ -273,6 +273,10 @@
* add work-around for BMI drives
* remove "LBA" from boot messages
* Version 5.53.1 add UDMA "CRC retry" support
+ * Version 5.53.2 add Promise/33 auto-detection and DMA support
+ * fix MC_ERR handling
+ * fix mis-detection of NEC cdrom as floppy
+ * issue ATAPI reset and re-probe after "no response"
*
* Some additional driver compile-time options are in ide.h
*
@@ -1059,6 +1063,8 @@
rq->errors = ERROR_MAX;
else if (err & TRK0_ERR) /* help it find track zero */
rq->errors |= ERROR_RECAL;
+ else if (err & MC_ERR)
+ drive->special.b.mc = 1;
}
if ((stat & DRQ_STAT) && rq->cmd != WRITE)
try_to_flush_leftover_data(drive);
@@ -2447,11 +2453,11 @@
return;
}
#endif /* CONFIG_BLK_DEV_PROMISE */
- switch (type) {
+ if (!drive->ide_scsi) switch (type) {
case 0:
if (!strstr(id->model, "oppy") && !strstr(id->model, "poyp") && !strstr(id->model, "ZIP"))
printk("cdrom or floppy?, assuming ");
- if (drive->media != ide_cdrom) {
+ if (drive->media != ide_cdrom && !strstr(id->model, "CD-ROM")) {
#ifdef CONFIG_BLK_DEV_IDEFLOPPY
printk("FLOPPY drive\n");
drive->media = ide_floppy;
@@ -2728,6 +2734,7 @@
{
int rc;
ide_hwif_t *hwif = HWIF(drive);
+ unsigned long timeout;
#ifdef CONFIG_BLK_DEV_IDEATAPI
if (drive->present) { /* avoid waiting for inappropriate probes */
if ((drive->media != ide_disk) && (cmd == WIN_IDENTIFY))
@@ -2752,6 +2759,17 @@
{
if ((rc = try_to_identify(drive,cmd))) /* send cmd and wait */
rc = try_to_identify(drive,cmd); /* failed: try again */
+ if (rc == 1 && cmd == WIN_PIDENTIFY && drive->autotune != 2) {
+ printk("%s: no response (status = 0x%02x), resetting drive\n", drive->name, GET_STAT());
+ delay_50ms();
+ OUT_BYTE (drive->select.all, IDE_SELECT_REG);
+ delay_50ms();
+ OUT_BYTE(WIN_SRST, IDE_COMMAND_REG);
+ timeout = jiffies;
+ while ((GET_STAT() & BUSY_STAT) && jiffies < timeout + WAIT_WORSTCASE)
+ delay_50ms();
+ rc = try_to_identify(drive, cmd);
+ }
if (rc == 1)
printk("%s: no response (status = 0x%02x)\n", drive->name, GET_STAT());
(void) GET_STAT(); /* ensure drive irq is clear */
@@ -3085,7 +3103,7 @@
if (s[0] == 'h' && s[1] == 'd' && s[2] >= 'a' && s[2] <= max_drive) {
const char *hd_words[] = {"none", "noprobe", "nowerr", "cdrom",
"serialize", "autotune", "noautotune",
- "slow", NULL};
+ "slow", "ide-scsi", NULL};
unit = s[2] - 'a';
hw = unit / MAX_DRIVES;
unit = unit % MAX_DRIVES;
@@ -3118,6 +3136,9 @@
case -8: /* "slow" */
drive->slow = 1;
goto done;
+ case -9: /* "ide-scsi" */
+ drive->ide_scsi = 1;
+ goto done;
case 3: /* cyl,head,sect */
drive->media = ide_disk;
drive->cyl = drive->bios_cyl = vals[0];
@@ -3516,6 +3537,42 @@
#endif /* defined(CONFIG_BLK_DEV_RZ1000) || defined(CONFIG_BLK_DEV_TRITON) */
#endif /* CONFIG_PCI */

+static void ide_probe_promise_20246(void)
+{
+ byte fn, bus;
+ unsigned short io[6], count = 0;
+ unsigned int reg, tmp, i;
+ ide_hwif_t *hwif;
+
+ memset(io, 0, 6 * sizeof(unsigned short));
+ if (pcibios_find_device(PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20246, 0, &bus, &fn))
+ return;
+ printk("ide: Promise Technology IDE Ultra-DMA 33 on PCI bus %d function %d\n", bus, fn);
+ for (reg = PCI_BASE_ADDRESS_0; reg <= PCI_BASE_ADDRESS_5; reg += 4) {
+ pcibios_read_config_dword(bus, fn, reg, &tmp);
+ if (tmp & PCI_BASE_ADDRESS_SPACE_IO)
+ io[count++] = tmp & PCI_BASE_ADDRESS_IO_MASK;
+ }
+ for (i = 2; i < 4; i++) {
+ hwif = ide_hwifs + i;
+ if (hwif->chipset == ide_generic) {
+ printk("ide%d: overridden with command line parameter\n", i);
+ return;
+ }
+ tmp = (i - 2) * 2;
+ if (!io[tmp] || !io[tmp + 1]) {
+ printk("ide%d: invalid port address %x, %x -- aborting\n", i, io[tmp], io[tmp + 1]);
+ return;
+ }
+ hwif->io_base = io[tmp];
+ hwif->ctl_port = io[tmp + 1] + 2;
+ hwif->noprobe = 0;
+ }
+#ifdef CONFIG_BLK_DEV_TRITON
+ ide_init_promise (bus, fn, &ide_hwifs[2], &ide_hwifs[3], io[4]);
+#endif /* CONFIG_BLK_DEV_TRITON */
+}
+
/*
* ide_init_pci() finds/initializes "known" PCI IDE interfaces
*
@@ -3545,6 +3602,7 @@
ide_probe_pci (PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_1, &ide_init_triton, 0);
ide_probe_pci (PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB, &ide_init_triton, 0);
#endif /* CONFIG_BLK_DEV_TRITON */
+ ide_probe_promise_20246();
}
#endif /* CONFIG_PCI */
#ifdef CONFIG_BLK_DEV_CMD640
diff -u --recursive --new-file v2.0.34pre15/linux/drivers/block/ide.h linux/drivers/block/ide.h
--- v2.0.34pre15/linux/drivers/block/ide.h Thu May 21 21:53:22 1998
+++ linux/drivers/block/ide.h Fri May 22 07:43:51 1998
@@ -381,6 +381,7 @@
#ifdef CONFIG_BLK_DEV_IDESCSI
void *scsi; /* for ide-scsi.c */
#endif /* CONFIG_BLK_DEV_IDESCSI */
+ byte ide_scsi; /* use ide-scsi driver */
} ide_drive_t;

/*
@@ -428,7 +429,7 @@
typedef enum { ide_unknown, ide_generic, ide_triton,
ide_cmd640, ide_dtc2278, ide_ali14xx,
ide_qd6580, ide_umc8672, ide_ht6560b,
- ide_promise }
+ ide_promise, ide_promise_udma }
hwif_chipset_t;

typedef struct hwif_s {
@@ -742,4 +743,5 @@

#ifdef CONFIG_BLK_DEV_TRITON
void ide_init_triton (byte, byte);
+void ide_init_promise (byte bus, byte fn, ide_hwif_t *hwif0, ide_hwif_t *hwif1, unsigned short dma);
#endif /* CONFIG_BLK_DEV_TRITON */
diff -u --recursive --new-file v2.0.34pre15/linux/drivers/block/triton.c linux/drivers/block/triton.c
--- v2.0.34pre15/linux/drivers/block/triton.c Thu May 21 21:53:22 1998
+++ linux/drivers/block/triton.c Thu May 21 22:49:04 1998
@@ -374,7 +374,7 @@
* safely use __get_free_page() here instead
* of __get_dma_pages() -- no ISA limitations.
*/
- dmatable = __get_free_page(GFP_KERNEL);
+ dmatable = __get_free_pages(GFP_KERNEL, 1, 0);
}
if (dmatable) {
hwif->dmatable = (unsigned long *) dmatable;
@@ -503,3 +503,24 @@
quit: if (rc) printk("ide: pcibios access failed - %s\n", pcibios_strerror(rc));
}

+void ide_init_promise (byte bus, byte fn, ide_hwif_t *hwif0, ide_hwif_t *hwif1, unsigned short dma)
+{
+ int rc;
+ unsigned short pcicmd;
+ unsigned int bmiba = 0;
+
+ printk("ide: Enabling DMA for Promise Technology IDE Ultra-DMA 33 on PCI bus %d function %d, port 0x%04x\n", bus, fn, dma);
+ if ((rc = pcibios_read_config_word(bus, fn, 0x04, &pcicmd)) || (pcicmd & 1) == 0 || (pcicmd & 4) == 0)
+ goto abort;
+ if ((rc = pcibios_read_config_dword(bus, fn, 0x20, &bmiba)))
+ goto abort;
+ bmiba &= 0xfff0; /* extract port base address */
+ if (bmiba != dma || !bmiba)
+ goto abort;
+ hwif0->chipset = ide_promise_udma;
+ hwif1->chipset = ide_promise_udma;
+ init_triton_dma(hwif0, bmiba);
+ init_triton_dma(hwif1, bmiba + 0x08);
+abort:
+ printk("ide: Promise/33 not configured correctly (BIOS)\n");
+}
diff -u --recursive --new-file v2.0.34pre15/linux/drivers/scsi/ide-scsi.c linux/drivers/scsi/ide-scsi.c
--- v2.0.34pre15/linux/drivers/scsi/ide-scsi.c Thu May 21 21:53:33 1998
+++ linux/drivers/scsi/ide-scsi.c Thu May 21 22:51:42 1998
@@ -1,5 +1,5 @@
/*
- * linux/drivers/scsi/ide-scsi.c Version 0.31 - ALPHA Apr 3, 1998
+ * linux/drivers/scsi/ide-scsi.c Version 0.32 May 21, 1998
*
* Copyright (C) 1996, 1997 Gadi Oxman <gadio@netvision.net.il>
*/
@@ -19,6 +19,8 @@
* Ver 0.3 Jul 24 97 Add support for ATAPI PD/CD drives.
* Ver 0.31 Apr 3 98 Remove buggy MODE_SENSE6/MODE_SELECT6 translation.
* Add variable irq timeout support.
+ * Ver 0.32 May 21 98 Perform maximal data transfer when the drive wants
+ * to send us more data than would fit in our buffer.
*/

#include <linux/module.h>
@@ -276,7 +278,18 @@
if ( temp > pc->request_transfer) {
if (temp > pc->buffer_size) {
printk (KERN_ERR "ide-scsi: The scsi wants to send us more data than expected - discarding data\n");
- idescsi_discard_data (drive,bcount);
+ temp = pc->buffer_size - pc->actually_transferred;
+ if (temp) {
+ clear_bit(PC_WRITING, &pc->flags);
+ if (pc->sg)
+ idescsi_input_buffers(drive, pc, temp);
+ else
+ atapi_input_bytes(drive, pc->current_position, temp);
+ printk(KERN_ERR "ide-scsi: transferred %d of %d bytes\n", temp, bcount);
+ }
+ pc->actually_transferred += temp;
+ pc->current_position += temp;
+ idescsi_discard_data (drive,bcount - temp);
ide_set_handler (drive, &idescsi_pc_intr, get_timeout(pc));
return;
}

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu