patch-2.4.4 linux/drivers/block/ps2esdi.c

Next file: linux/drivers/cdrom/sbpcd.c
Previous file: linux/drivers/block/paride/ppc6lnx.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.3/linux/drivers/block/ps2esdi.c linux/drivers/block/ps2esdi.c
@@ -52,6 +52,7 @@
 #include <asm/io.h>
 #include <asm/segment.h>
 #include <asm/dma.h>
+#include <asm/mca_dma.h>
 #include <asm/uaccess.h>
 
 #define PS2ESDI_IRQ 14
@@ -89,8 +90,6 @@
 static void ps2esdi_initial_reset_int_handler(u_int);
 static void ps2esdi_geometry_int_handler(u_int);
 
-static void ps2esdi_continue_request(void);
-
 static int ps2esdi_open(struct inode *inode, struct file *file);
 
 static int ps2esdi_release(struct inode *inode, struct file *file);
@@ -469,29 +468,26 @@
 	       DEVICE_NAME,
 	       CURRENT_DEV, MINOR(CURRENT->rq_dev),
 	       CURRENT->cmd, CURRENT->sector,
-	       CURRENT->nr_sectors, CURRENT->buffer);
+	       CURRENT->current_nr_sectors, CURRENT->buffer);
 #endif
 
 	/* standard macro that ensures that requests are really on the
 	   list + sanity checks.                     */
 	INIT_REQUEST;
 
-	if (virt_to_bus(CURRENT->buffer + CURRENT->nr_sectors * 512) > 16 * MB) {
+	if (virt_to_bus(CURRENT->buffer + CURRENT->current_nr_sectors * 512) > 16 * MB) {
 		printk("%s: DMA above 16MB not supported\n", DEVICE_NAME);
 		end_request(FAIL);
-		if (!QUEUE_EMPTY)
-			do_ps2esdi_request(q);
-		return;
 	}			/* check for above 16Mb dmas */
-	if ((CURRENT_DEV < ps2esdi_drives) &&
-	    (CURRENT->sector + CURRENT->nr_sectors <=
+	else if ((CURRENT_DEV < ps2esdi_drives) &&
+	    (CURRENT->sector + CURRENT->current_nr_sectors <=
 	     ps2esdi[MINOR(CURRENT->rq_dev)].nr_sects)) {
 #if 0
 		printk("%s:got request. device : %d minor : %d command : %d  sector : %ld count : %ld\n",
 		       DEVICE_NAME,
-		       CURRENT_DEV, MINOR(CURRENT->dev),
+		       CURRENT_DEV, MINOR(CURRENT->rq_dev),
 		       CURRENT->cmd, CURRENT->sector,
-		       CURRENT->nr_sectors);
+		       CURRENT->current_nr_sectors);
 #endif
 
 
@@ -500,21 +496,17 @@
 #if 0
 		printk("%s: blocknumber : %d\n", DEVICE_NAME, block);
 #endif
-		count = CURRENT->nr_sectors;
+		count = CURRENT->current_nr_sectors;
 		switch (CURRENT->cmd) {
 		case READ:
 			ps2esdi_readwrite(READ, CURRENT_DEV, block, count);
-			return;
 			break;
 		case WRITE:
 			ps2esdi_readwrite(WRITE, CURRENT_DEV, block, count);
-			return;
 			break;
 		default:
 			printk("%s: Unknown command\n", DEVICE_NAME);
 			end_request(FAIL);
-			if (!QUEUE_EMPTY)
-				do_ps2esdi_request(q);
 			break;
 		}		/* handle different commands */
 	}
@@ -523,8 +515,6 @@
 		printk("Grrr. error. ps2esdi_drives: %d, %lu %lu\n", ps2esdi_drives,
 		       CURRENT->sector, ps2esdi[MINOR(CURRENT->rq_dev)].nr_sects);
 		end_request(FAIL);
-		if (!QUEUE_EMPTY)
-			do_ps2esdi_request(q);
 	}
 
 }				/* main strategy routine */
@@ -570,8 +560,6 @@
 	u_short cmd_blk[TYPE_1_CMD_BLK_LENGTH];
 
 	/* do some relevant arithmatic */
-	CURRENT->current_nr_sectors =
-	    (count < (2 * MAX_16BIT / SECT_SIZE)) ? count : (2 * MAX_16BIT / SECT_SIZE);
 	track = block / ps2esdi_info[drive].sect;
 	head = track % ps2esdi_info[drive].head;
 	cylinder = track / ps2esdi_info[drive].head;
@@ -590,13 +578,8 @@
 	/* send the command block to the controller */
 	if (ps2esdi_out_cmd_blk(cmd_blk)) {
 		printk("%s: Controller failed\n", DEVICE_NAME);
-		if ((++CURRENT->errors) < MAX_RETRIES)
-			return do_ps2esdi_request(NULL);
-		else {
+		if ((++CURRENT->errors) >= MAX_RETRIES)
 			end_request(FAIL);
-			if (!QUEUE_EMPTY)
-				do_ps2esdi_request(NULL);
-		}
 	}
 	/* check for failure to put out the command block */ 
 	else {
@@ -675,33 +658,23 @@
 /* prepare for dma - do all the necessary setup */
 static void ps2esdi_prep_dma(char *buffer, u_short length, u_char dma_xmode)
 {
-	u_int tc;
-	
-	buffer=(char *)virt_to_bus(buffer);
-
+	unsigned long flags;
 #if 0
-	printk("ps2esdi: b_wait: %p\n", CURRENT->bh->b_wait);
+	printk("ps2esdi: b_wait: %p\n", &CURRENT->bh->b_wait);
 #endif
-	cli();
+	flags = claim_dma_lock();
 
-	outb(dma_arb_level | DMA_MASK_CHAN, PORT_DMA_FN);
+	mca_disable_dma(dma_arb_level);
 
-	outb(dma_arb_level | DMA_WRITE_ADDR, PORT_DMA_FN);
-	outb((u_int) buffer & (u_int) 0xff, PORT_DMA_EX);
-	outb(((u_int) buffer >> 8) & (u_int) 0xff, PORT_DMA_EX);
-	outb(((u_int) buffer >> 16) & (u_int) 0xff, PORT_DMA_EX);
+	mca_set_dma_addr(dma_arb_level, virt_to_bus(buffer));
 
-	outb(dma_arb_level | DMA_WRITE_TC, PORT_DMA_FN);
-	tc = (length * SECT_SIZE / 2) - 1;
-	outb(tc & 0xff, PORT_DMA_EX);
-	outb((tc >> 8) & 0xff, PORT_DMA_EX);
+	mca_set_dma_count(dma_arb_level, length * 512 / 2);
 
-	outb(dma_arb_level | DMA_WRITE_MODE, PORT_DMA_FN);
-	outb(dma_xmode, PORT_DMA_EX);
+	mca_set_dma_mode(dma_arb_level, dma_xmode);
 
-	outb(dma_arb_level | DMA_UNMASK_CHAN, PORT_DMA_FN);
+	mca_enable_dma(dma_arb_level);
 
-	sti();
+	release_dma_lock(flags);
 
 }				/* prepare for dma */
 
@@ -871,20 +844,26 @@
 
 static void ps2esdi_normal_interrupt_handler(u_int int_ret_code)
 {
+	unsigned long flags;
 	u_int status;
+	u_int ending;
 	int i;
 
 	switch (int_ret_code & 0x0f) {
 	case INT_TRANSFER_REQ:
 		ps2esdi_prep_dma(CURRENT->buffer, CURRENT->current_nr_sectors,
-		    (CURRENT->cmd == READ) ? DMA_READ_16 : DMA_WRITE_16);
+		    (CURRENT->cmd == READ)
+		    ? MCA_DMA_MODE_16 | MCA_DMA_MODE_WRITE | MCA_DMA_MODE_XFER
+		    : MCA_DMA_MODE_16 | MCA_DMA_MODE_READ);
 		outb(CTRL_ENABLE_DMA | CTRL_ENABLE_INTR, ESDI_CONTROL);
+		ending = -1;
 		break;
 
 	case INT_ATTN_ERROR:
 		printk("%s: Attention error. interrupt status : %02X\n", DEVICE_NAME,
 		       int_ret_code);
 		outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
+		ending = FAIL;
 		break;
 
 	case INT_CMD_COMPLETE:
@@ -893,13 +872,10 @@
 			printk("%s: timeout reading status word\n", DEVICE_NAME);
 			outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
 			outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
-			if ((++CURRENT->errors) < MAX_RETRIES)
-				do_ps2esdi_request(NULL);
-			else {
-				end_request(FAIL);
-				if (!QUEUE_EMPTY)
-					do_ps2esdi_request(NULL);
-			}
+			if ((++CURRENT->errors) >= MAX_RETRIES)
+				ending = FAIL;
+			else
+				ending = -1;
 			break;
 		}
 		status = inw(ESDI_STT_INT);
@@ -910,15 +886,16 @@
 			outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
 			outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
 #if 0
-			printk("ps2esdi: cmd_complete b_wait: %p\n", CURRENT->bh->b_wait);
+			printk("ps2esdi: cmd_complete b_wait: %p\n", &CURRENT->bh->b_wait);
 #endif
-			ps2esdi_continue_request();
+			ending = SUCCES;
 			break;
 		default:
 			printk("%s: interrupt for unknown command %02X\n",
 			       DEVICE_NAME, status & 0x1f);
 			outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
 			outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
+			ending = -1;
 			break;
 		}
 		break;
@@ -929,7 +906,7 @@
 		dump_cmd_complete_status(int_ret_code);
 		outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
 		outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
-		ps2esdi_continue_request();
+		ending = SUCCES;
 		break;
 	case INT_CMD_WARNING:
 	case INT_CMD_ABORT:
@@ -939,22 +916,17 @@
 		dump_cmd_complete_status(int_ret_code);
 		outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
 		outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
-		if ((++CURRENT->errors) < MAX_RETRIES)
-			do_ps2esdi_request(NULL);
-		else {
-			end_request(FAIL);
-			if (!QUEUE_EMPTY)
-				do_ps2esdi_request(NULL);
-		}
+		if ((++CURRENT->errors) >= MAX_RETRIES)
+			ending = FAIL;
+		else
+			ending = -1;
 		break;
 
 	case INT_CMD_BLK_ERR:
 		dump_cmd_complete_status(int_ret_code);
 		outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
 		outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
-		end_request(FAIL);
-		if (!QUEUE_EMPTY)
-			do_ps2esdi_request(NULL);
+		ending = FAIL;
 		break;
 
 	case INT_CMD_FORMAT:
@@ -962,12 +934,14 @@
 		       ,DEVICE_NAME);
 		outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
 		outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
+		ending = -1;
 		break;
 
 	case INT_RESET:
 		/* BA printk("%s: reset completed.\n", DEVICE_NAME) */ ;
 		outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
 		outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
+		ending = -1;
 		break;
 
 	default:
@@ -975,24 +949,16 @@
 		       DEVICE_NAME, int_ret_code & 0xf);
 		outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
 		outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
+		ending = -1;
 		break;
 	}
-
-}				/* handle interrupts */
-
-
-static void ps2esdi_continue_request(void)
-{
-	if (CURRENT->nr_sectors -= CURRENT->current_nr_sectors) {
-		CURRENT->buffer += CURRENT->current_nr_sectors * SECT_SIZE;
-		CURRENT->sector += CURRENT->current_nr_sectors;
-		do_ps2esdi_request(NULL);
-	} else {
-		end_request(SUCCES);
-		if (!QUEUE_EMPTY)
-			do_ps2esdi_request(NULL);
+	if(ending != -1) {
+		spin_lock_irqsave(io_request_lock, flags);
+		end_request(ending);
+		do_ps2esdi_request(BLK_DEFAULT_QUEUE(MAJOR_NR));
+		spin_unlock_irqrestore(io_request_lock, flags);
 	}
-}
+}				/* handle interrupts */
 
 
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)