lkml.org 
[lkml]   [1998]   [May]   [22]   [last100]   RSS Feed
Views: [more markup]  [less markup]  [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
DateFri, 22 May 1998 08:19:47 +0400 (IDT)
FromGadi Oxman <>
SubjectIDE patch for 2.0.34-pre15+
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

\
 
 \ /
  Last update: 2005-03-22 13:42    [from the cache]
©2003-2008