public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* PS/2 Esdi patch #8
@ 2001-05-23 22:54 Hal Duston
  2001-05-24 20:46 ` Paul Gortmaker
  0 siblings, 1 reply; 8+ messages in thread
From: Hal Duston @ 2001-05-23 22:54 UTC (permalink / raw)
  To: linux-kernel; +Cc: alan

[-- Attachment #1: Type: TEXT/PLAIN, Size: 364 bytes --]

Get soft reset at initialization working again.

Remove reset_time code.  (Re-add timeouts some time later.)
Eliminate remaining sleep_on() calls.
Encapsulate access to esdi attention register.
Correct some formatting in config display.
Correct soft reset logic.

Also...
http://www.sound.net/~hald/projects/ps2esdi/ps2esdi-2.4.4-patch4

Hal Duston
hald@sound.net

[-- Attachment #2: Type: TEXT/PLAIN, Size: 10456 bytes --]

Get soft reset at initialization working again.

Remove reset_time code.  (Re-add timeouts some time later.)
Eliminate remaining sleep_on() calls.
Encapsulate access to esdi attention register.
Correct some formatting in config display.
Correct soft reset logic.

--- linux-2.4.5-pre4/drivers/block/ps2esdi.c.3	Mon May 21 00:07:38 2001
+++ linux-2.4.5-pre4/drivers/block/ps2esdi.c.4	Mon May 21 00:16:49 2001
@@ -107,6 +107,8 @@
 
 static void ps2esdi_reset_timer(unsigned long unused);
 
+static int ps2esdi_attention(u_int device, u_int request);
+
 static u_int dma_arb_level;		/* DMA arbitration level */
 
 static DECLARE_WAIT_QUEUE_HEAD(ps2esdi_int);
@@ -460,19 +462,8 @@
 	current_int_handler = ps2esdi_initial_reset_int_handler;
 	reset_ctrl();
 	reset_status = 0;
-	reset_start = jiffies;
-	while (!reset_status) {
-		init_timer(&esdi_timer);
-		esdi_timer.expires = jiffies + HZ;
-		esdi_timer.data = 0;
-		add_timer(&esdi_timer);
-		sleep_on(&ps2esdi_int);
-	}
-	reset_end = jiffies;
+	wait_event(ps2esdi_int, reset_status);
 	LITE_OFF;
-	printk("%s: reset interrupt after %d jiffies,  %u.%02u secs\n",
-	       DEVICE_NAME, reset_end - reset_start, (reset_end - reset_start) / HZ,
-	       (reset_end - reset_start) % HZ);
 
 
 	/* Integrated ESDI Disk and Controller has only one drive! */
@@ -522,8 +513,7 @@
 		cmd_blk[1] = 0;
 		no_int_yet = TRUE;
 		ps2esdi_out_cmd_blk(cmd_blk);
-		if (no_int_yet)
-			sleep_on(&ps2esdi_int);
+		wait_event(ps2esdi_int, !no_int_yet);
 	}
 	return;
 }
@@ -597,32 +587,20 @@
 {
 
 	u_long expire;
-	u_short status;
-
-	/* enable interrupts on the controller */
-	status = inb(ESDI_INTRPT);
-	outb((status & 0xe0) | ATT_EOI, ESDI_ATTN);	/* to be sure we don't have
-							   any interrupt pending... */
-	outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
 
-	/* read the ESDI status port - if the controller is not busy,
-	   simply do a soft reset (fast) - otherwise we'll have to do a
-	   hard (slow) reset.  */
-	if (!(inb(ESDI_STATUS) & STATUS_BUSY)) {
+	if(!ps2esdi_attention(0x07, 0x04)) {
 		/*BA */ printk("%s: soft reset...\n", DEVICE_NAME);
-		outb(CTRL_SOFT_RESET, ESDI_ATTN);
 	}
-	/* soft reset */ 
+	/* soft reset */
 	else {
 		/*BA */
 		printk("%s: hard reset...\n", DEVICE_NAME);
 		outb(CTRL_HARD_RESET, ESDI_CONTROL);
-		expire = jiffies + 2*HZ;
-		while (time_before(jiffies, expire));
-		outb(1, ESDI_CONTROL);
+		expire = jiffies + 2 * HZ;
+		while(time_before(jiffies, expire))
+		{}
+		outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
 	}			/* hard reset */
-
-
 }				/* reset the controller */
 
 /* called by the strategy routine to handle read and write requests */
@@ -695,13 +673,10 @@
 	printk("%s: i(1)=%d\n", DEVICE_NAME, i);
 #endif
 
-	/* if device is still busy - then just time out */
-	if (inb(ESDI_STATUS) & STATUS_BUSY) {
-		printk("%s: ps2esdi_out_cmd timed out (1)\n", DEVICE_NAME);
+	if(ps2esdi_attention((cmd_blk[0] & 0xe0) >> 5, 0x01)) {
+		printk("%s: ps2esdi_out_cmd timed out (%x)\n", DEVICE_NAME, (cmd_blk[0] & 0xe0) >> 5);
 		return ERROR;
-	}			/* timeout ??? */
-	/* Set up the attention register in the controller */
-	outb(((*cmd_blk) & 0xE0) | 1, ESDI_ATTN);
+	}
 
 #if 0
 	printk("%s: sending %d words to controller\n", DEVICE_NAME, (((*cmd_blk) >> 14) + 1) << 1);
@@ -774,25 +749,25 @@
 static void ps2esdi_initial_reset_int_handler(u_int int_ret_code)
 {
 
+	reset_status = int_ret_code;
 	switch (int_ret_code & 0xf) {
 	case INT_RESET:
 		/*BA */
 		printk("%s: initial reset completed.\n", DEVICE_NAME);
-		outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
+		ps2esdi_attention((int_ret_code & 0xe0) >> 5, ATT_EOI);
 		wake_up(&ps2esdi_int);
 		break;
 	case INT_ATTN_ERROR:
-		printk("%s: Attention error. interrupt status : %02X\n", DEVICE_NAME,
+		printk("%s: Attention error during reset. interrupt status : %02X\n", DEVICE_NAME,
 		       int_ret_code);
 		printk("%s: status: %02x\n", DEVICE_NAME, inb(ESDI_STATUS));
 		break;
 	default:
 		printk("%s: initial reset handler received interrupt: %02X\n",
 		       DEVICE_NAME, int_ret_code);
-		outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
+		ps2esdi_attention((int_ret_code & 0xe0) >> 5, ATT_EOI);
 		break;
 	}
-	outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
 }
 
 
@@ -821,10 +796,10 @@
 				printk("%s: Device Configuration Status for drive %u\n",
 				       DEVICE_NAME, drive_num);
 
-				printk("%s: Spares/cyls: %u", DEVICE_NAME, reply[0] >> 8);
+				printk("%s: Spares/cyls: %u\n", DEVICE_NAME, reply[0] >> 8);
 
 				printk
-				    ("Config bits: %s%s%s%s%s\n",
+				    ("%s: Config bits: %s%s%s%s%s\n", DEVICE_NAME,
 				     (reply[0] & CONFIG_IS) ? "Invalid Secondary, " : "",
 				     ((reply[0] & CONFIG_ZD) && !(reply[0] & CONFIG_IS))
 				 ? "Zero Defect, " : "Defects Present, ",
@@ -877,11 +852,11 @@
 			printk("%s: command %02X unknown by geometry handler\n",
 			       DEVICE_NAME, status & 0x1f);
 
-		outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
+		ps2esdi_attention((int_ret_code & 0xe0) >> 5, ATT_EOI);
 		break;
 
 	case INT_ATTN_ERROR:
-		printk("%s: Attention error. interrupt status : %02X\n", DEVICE_NAME,
+		printk("%s: Attention error during geometry. interrupt status : %02X\n", DEVICE_NAME,
 		       int_ret_code);
 		printk("%s: Device not available\n", DEVICE_NAME);
 		--ps2esdi_drives;
@@ -896,19 +871,18 @@
 	case INT_CMD_BLK_ERR:
 		/*BA */ printk("%s: Whaa. Error occurred...\n", DEVICE_NAME);
 		dump_cmd_complete_status(int_ret_code);
-		outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
+		ps2esdi_attention((int_ret_code & 0xe0) >> 5, ATT_EOI);
 		--ps2esdi_drives;
 		break;
 	default:
 		printk("%s: Unknown interrupt reason: %02X\n",
 		       DEVICE_NAME, int_ret_code & 0xf);
-		outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
+		ps2esdi_attention((int_ret_code & 0xe0) >> 5, ATT_EOI);
 		break;
 	}
 
 	wake_up(&ps2esdi_int);
 	no_int_yet = FALSE;
-	outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
 
 }
 
@@ -930,7 +904,7 @@
 		break;
 
 	case INT_ATTN_ERROR:
-		printk("%s: Attention error. interrupt status : %02X\n", DEVICE_NAME,
+		printk("%s: Attention error during normal. interrupt status : %02X\n", DEVICE_NAME,
 		       int_ret_code);
 		outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
 		ending = FAIL;
@@ -940,8 +914,7 @@
 		for (i = ESDI_TIMEOUT; i & !(inb(ESDI_STATUS) & STATUS_STAT_AVAIL); i--);
 		if (!(inb(ESDI_STATUS) & STATUS_STAT_AVAIL)) {
 			printk("%s: timeout reading status word\n", DEVICE_NAME);
-			outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
-			outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
+			ps2esdi_attention((int_ret_code & 0xe0) >> 5, ATT_EOI);
 			if ((++CURRENT->errors) >= MAX_RETRIES)
 				ending = FAIL;
 			else
@@ -953,8 +926,7 @@
 		case (CMD_READ & 0xff):
 		case (CMD_WRITE & 0xff):
 			LITE_OFF;
-			outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
-			outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
+			ps2esdi_attention((int_ret_code & 0xe0) >> 5, ATT_EOI);
 #if 0
 			printk("ps2esdi: cmd_complete b_wait: %p\n", &CURRENT->bh->b_wait);
 #endif
@@ -963,8 +935,7 @@
 		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);
+			ps2esdi_attention((int_ret_code & 0xe0) >> 5, ATT_EOI);
 			ending = -1;
 			break;
 		}
@@ -974,8 +945,7 @@
 	case INT_CMD_ECC_RETRY:
 		LITE_OFF;
 		dump_cmd_complete_status(int_ret_code);
-		outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
-		outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
+		ps2esdi_attention((int_ret_code & 0xe0) >> 5, ATT_EOI);
 		ending = SUCCES;
 		break;
 	case INT_CMD_WARNING:
@@ -984,8 +954,7 @@
 	case INT_DMA_ERR:
 		LITE_OFF;
 		dump_cmd_complete_status(int_ret_code);
-		outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
-		outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
+		ps2esdi_attention((int_ret_code & 0xe0) >> 5, ATT_EOI);
 		if ((++CURRENT->errors) >= MAX_RETRIES)
 			ending = FAIL;
 		else
@@ -994,31 +963,27 @@
 
 	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);
+		ps2esdi_attention((int_ret_code & 0xe0) >> 5, ATT_EOI);
 		ending = FAIL;
 		break;
 
 	case INT_CMD_FORMAT:
 		printk("%s: huh ? Who issued this format command ?\n"
 		       ,DEVICE_NAME);
-		outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
-		outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
+		ps2esdi_attention((int_ret_code & 0xe0) >> 5, ATT_EOI);
 		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);
+		ps2esdi_attention((int_ret_code & 0xe0) >> 5, ATT_EOI);
 		ending = -1;
 		break;
 
 	default:
 		printk("%s: Unknown interrupt reason: %02X\n",
 		       DEVICE_NAME, int_ret_code & 0xf);
-		outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
-		outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
+		ps2esdi_attention((int_ret_code & 0xe0) >> 5, ATT_EOI);
 		ending = -1;
 		break;
 	}
@@ -1125,8 +1090,7 @@
 	int dev = DEVICE_NR(inode->i_rdev);
 
 	if (dev < ps2esdi_drives) {
-		while (!ps2esdi_valid[dev])
-			sleep_on(&ps2esdi_wait_open);
+		wait_event(ps2esdi_wait_open, ps2esdi_valid[dev]);
 
 		access_count[dev]++;
 
@@ -1236,11 +1200,34 @@
 
 	status = inb(ESDI_INTRPT);
 	if ((status & 0xf) == INT_RESET) {
-		outb((status & 0xe0) | ATT_EOI, ESDI_ATTN);
-		outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
-		reset_status = 1;
+		ps2esdi_attention((status & 0xe0) >> 5, ATT_EOI);
+		reset_status = -1;
 	}
 	wake_up(&ps2esdi_int);
 }
 
+static int ps2esdi_attention(u_int device, u_int request)
+{
+	int busy;
+	u_char status;
+
+	outb(CTRL_DISABLE_INTR, ESDI_CONTROL);
+	if(request == ATT_EOI || !(status = inb(ESDI_STATUS) & 0x50)) {
+		outb((device << 5) | request, ESDI_ATTN);
+		busy = 0;
+	}
+	else {
+		if(status & 0x10) {
+			printk("%s: Attention port in use (0x%x)\n",
+				DEVICE_NAME, status);
+		}
+		if(status & 0x40) {
+			printk("%s: Interrupt pending (0x%x)\n",
+				DEVICE_NAME, status);
+		}
+ 		busy = 1;
+	}
+	outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
+	return busy;
+}
 #endif

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2001-05-27  0:01 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2001-05-23 22:54 PS/2 Esdi patch #8 Hal Duston
2001-05-24 20:46 ` Paul Gortmaker
2001-05-25 14:46   ` Jens Axboe
2001-05-26  9:53     ` Paul Gortmaker
2001-05-26 14:49     ` A Duston
2001-05-26 14:58       ` Jens Axboe
2001-05-26 15:33         ` A Duston
2001-05-26 15:40           ` Jens Axboe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox