Re: [PATCH 0/4] Mac IOP driver fixes

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Jun 02, 2020 at 09:32:29AM +1000, Finn Thain wrote:
I'm hoping that the SWIM IOP can be used in bypass mode, so it could be 
used with the swim.c driver. I haven't been able to make that work yet.

Putting the IOP in bypass mode would have a couple issues. The obvious
one is that it will break ADB (and because the shift register attached
to the ADB transceiver is part of the IOP chip itself, there's not an
easy fix for that), but there's also some strangeness in the way the
SWIM chip is attached to the IOP chip that looks like it might break
a few things. In particular, it looks like they only enabled using the
SWIM chip in ISM mode and not IWM mode. The notes I have imply that
the normal Mac floppy driver didn't work on a IIfx even in bypass mode.
In particular, note the direct use of a GPIO line on VIA1 in swim_select
in drivers/block/swim.c.  That won't work on an IOP based system as that
input line to SWIM doesn't appear to be hooked up to anything that can
be accessed directly.

Here's the way it's put in _Guide to the Macintosh Family Hardware_
(Second Edition), on page 155:

"An IOP provides the state-control line SEL to the floppy disk drives.
Among other functions, this line selects which of the two heads is to
be used in a double-sided floppy disk drive."

The bit in VIA1 register A that is normally the "vHeadSel" line is
explicitly listed as "Reserved" on the IIfx.

It's definitely possible to access and drive the SWIM chip in bypass
mode, but that doesn't mean it's as transparent as for the SCC driver.
Apparently this external input line is not strictly required when the
SWIM chip is running in ISM mode. However, our driver appears to force
the chip into ISM mode and yet still depends on this input line.

You may want to send the patch to the mailing list anyway. Or maybe send 
it to the linux-mac68k bug tracker on sourceforge.

I've pasted it in here so there is a record of it. The fixes are to
properly handle multiple drives (my IIfx has two floppy drives installed)
and to initialize and handle the auto-polling of drive status properly.

	Brad Boyer
	flar@xxxxxxxxxxxxx

--- swim_iop.c-cvs	Fri Jul 19 22:49:23 2002
+++ swim_iop.c	Sat Jul 27 00:51:30 2002
@@ -5,12 +5,15 @@
  * Written by Joshua M. Thompson (funaho@xxxxxxxxx)
  * based on the SWIM3 driver (c) 1996 by Paul Mackerras.
  *
+ * Misc fixes by Brad A. Boyer (flar@xxxxxxxxxxxxx)
+ *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version
  * 2 of the License, or (at your option) any later version.
  *
  * 1999-06-12 (jmt) - Initial implementation.
+ * 2002-07-26 (bab) - Fixed drive number storage and enabled status updates
  */
 
 /*
@@ -148,6 +151,7 @@
 int swimiop_init(void)
 {
 	volatile struct swim_iop_req req;
+	struct swimcmd_startpoll *poll = (struct swimcmd_startpoll *) &req.command[0];
 	struct swimcmd_status *cmd = (struct swimcmd_status *) &req.command[0];
 	struct swim_drvstatus *ds = &cmd->status;
 	struct floppy_state *fs;
@@ -175,6 +179,19 @@
 		return -EBUSY;
 	}
 
+	printk(KERN_ERR "SWIM_IOP: setting up automatic notification.\n");
+
+	swimiop_init_request(&req);
+	poll->code = CMD_START_POLL;
+	if (swimiop_send_request(&req) != 0) {
+		printk(KERN_ERR "SWIM_IOP: failed to request autonotify.\n");
+	} else {
+		while (!req.complete);
+		if (cmd->error != 0) {
+			printk(KERN_ERR "SWIM_IOP: notify setup failed.\n");
+		}
+	}
+
 	printk(KERN_ERR "SWIM_IOP: probing for installed drives.\n");
 
 	for (i = 0 ; i < MAX_FLOPPIES ; i++) {
@@ -199,6 +216,7 @@
 			ds->info.secondary? "secondary" : "primary");
 		swimiop_status_update(floppy_count, ds);
 		fs->state = idle;
+		fs->drive_num = i + 1;
 
 		init_timer(&fs->timeout);
 		floppy_count++;
@@ -214,6 +232,7 @@
 {
 	req->sent = 0;
 	req->complete = 0;
+	req->fs = NULL;
 	req->done = NULL;
 }
 
@@ -254,6 +273,26 @@
 }
 
 /*
+ * Find the correct status slot for given hardware drive number
+ *
+ * This is only used for unsolicited messages
+ *
+ */
+
+int swimiop_find_slot(int drive_num)
+{
+	struct floppy_state *fs;
+	int i;
+
+	for (i = 0 ; i < MAX_FLOPPIES ; i++) {
+		fs = &floppy_states[i];
+		if(fs->drive_num == drive_num)
+			return i;
+	}
+	return -1;
+}
+
+/*
  * Receive a SWIM message from the IOP.
  *
  * This will be called in two cases:
@@ -267,20 +306,32 @@
 	struct swim_iop_req *req;
 	struct swimmsg_status *sm;
 	struct swim_drvstatus *ds;
+	void	(*done)(struct swim_iop_req *);
+	int drive_slot;
 
 	req = current_req;
 
 	switch(msg->status) {
 		case IOP_MSGSTATUS_COMPLETE:
+			done = req->done;
 			memcpy(&req->command[0], &msg->reply[0], sizeof(req->command));
 			req->complete = 1;
-			if (req->done) (*req->done)(req);
+			if (done) done(req);
 			current_req = NULL;
 			break;
 		case IOP_MSGSTATUS_UNSOL:
 			sm = (struct swimmsg_status *) &msg->message[0];
 			ds = &sm->status;
-			swimiop_status_update(sm->drive_num, ds);
+			drive_slot = swimiop_find_slot(sm->drive_num);
+			if(drive_slot >= 0) {
+				printk(KERN_ERR "SWIM_IOP: unit %d changed.\n",
+					drive_slot);
+				swimiop_status_update(drive_slot, ds);
+			} else {
+				printk("SWIM-IOP: Bad message from drive %d\n",
+				       sm->drive_num);
+			}
+			memcpy(&msg->reply[0], &msg->message[0], IOP_MSG_LEN);
 			iop_complete_message(msg);
 			break;
 	}
@@ -347,7 +398,7 @@
 		schedule_timeout(1);
 	}
 	release_drive(fs);
-	return cmd->error;
+	return cmd->error ? -ENXIO : 0;
 }
 
 static ssize_t floppy_read(struct file *filp, char *buf,




[Index of Archives]     [Video for Linux]     [Yosemite News]     [Linux S/390]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux