/*
 * Driver for the SWIM (Super Woz Integrated Machine) IOP
 * floppy controller on the Macintosh IIfx and Quadra 900/950
 *
 * Written by Joshua M. Thompson (funaho@jurai.org)
 * based on the SWIM3 driver (c) 1996 by Paul Mackerras.
 *
 * 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.
 */

/*
 * -------------------
 * Theory of Operation
 * -------------------
 *
 * Since the SWIM IOP is message-driven we implement a simple request queue
 * system.  One outstanding request may be queued at any given time (this is
 * an IOP limitation); only when that request has completed can a new request
 * be sent.
 */

#include <linux/stddef.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/delay.h>
#include <linux/fd.h>
#include <linux/ioctl.h>
#include <linux/blkdev.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/mac_iop.h>
#include <asm/swim_iop.h>

#define DRIVER_VERSION "Version 0.1 (1999-06-12)"

#define MAX_FLOPPIES	4

enum swim_state {
	idle,
	available,
	revalidating,
	transferring,
	ejecting
};

struct floppy_state {
	enum swim_state state;
	int	drive_num;	/* device number */
	int	secpercyl;	/* disk geometry information */
	int	secpertrack;
	int	total_secs;
	int	write_prot;	/* 1 if write-protected, 0 if not, -1 dunno */
	int	ref_count;
	struct timer_list timeout;
	int	ejected;
	struct wait_queue *wait;
	int	wanted;
	int	timeout_pending;
};

struct swim_iop_req {
	int	sent;
	int	complete;
	__u8	command[32];
	struct floppy_state *fs;
	void	(*done)(struct swim_iop_req *);
};

static struct swim_iop_req *current_req;
static int floppy_count;

static struct floppy_state floppy_states[MAX_FLOPPIES];
static DEFINE_SPINLOCK(swim_iop_lock);

#define CURRENT elv_next_request(swim_queue)

static char *drive_names[7] = {
	"not installed",	/* DRV_NONE    */
	"unknown (1)",		/* DRV_UNKNOWN */
	"a 400K drive",		/* DRV_400K    */
	"an 800K drive"		/* DRV_800K    */
	"unknown (4)",		/* ????        */
	"an FDHD",		/* DRV_FDHD    */
	"unknown (6)",		/* ????        */
	"an Apple HD20"		/* DRV_HD20    */
};

int swimiop_init(void);
static void swimiop_init_request(struct swim_iop_req *);
static int swimiop_send_request(struct swim_iop_req *);
static void swimiop_receive(struct iop_msg *, struct pt_regs *);
static void swimiop_status_update(int, struct swim_drvstatus *);
static int swimiop_eject(struct floppy_state *fs);

static int floppy_ioctl(struct inode *inode, struct file *filp,
			unsigned int cmd, unsigned long param);
static int floppy_open(struct inode *inode, struct file *filp);
static int floppy_release(struct inode *inode, struct file *filp);
static int floppy_check_change(struct gendisk *disk);
static int floppy_revalidate(struct gendisk *disk);
static int grab_drive(struct floppy_state *fs, enum swim_state state,
		      int interruptible);
static void release_drive(struct floppy_state *fs);
static void set_timeout(struct floppy_state *fs, int nticks,
			void (*proc)(unsigned long));
static void fd_request_timeout(unsigned long);
static void do_fd_request(request_queue_t * q);
static void start_request(struct floppy_state *fs);

static struct block_device_operations floppy_fops = {
	.open		= floppy_open,
	.release	= floppy_release,
	.ioctl		= floppy_ioctl,
	.media_changed	= floppy_check_change,
	.revalidate_disk= floppy_revalidate,
};

static struct request_queue *swim_queue;
/*
 * SWIM IOP initialization
 */

int swimiop_init(void)
{
	volatile struct swim_iop_req req;
	struct swimcmd_status *cmd = (struct swimcmd_status *) &req.command[0];
	struct swim_drvstatus *ds = &cmd->status;
	struct floppy_state *fs;
	int i;

	current_req = NULL;
	floppy_count = 0;

	if (!iop_ism_present)
		return -ENODEV;

	if (register_blkdev(FLOPPY_MAJOR, "fd"))
		return -EBUSY;

	swim_queue = blk_init_queue(do_fd_request, &swim_iop_lock);
	if (!swim_queue) {
		unregister_blkdev(FLOPPY_MAJOR, "fd");
		return -ENOMEM;
	}

	printk("SWIM-IOP: %s by Joshua M. Thompson (funaho@jurai.org)\n",
		DRIVER_VERSION);

	if (iop_listen(SWIM_IOP, SWIM_CHAN, swimiop_receive, "SWIM") != 0) {
		printk(KERN_ERR "SWIM-IOP: IOP channel already in use; can't initialize.\n");
		unregister_blkdev(FLOPPY_MAJOR, "fd");
		blk_cleanup_queue(swim_queue);
		return -EBUSY;
	}

	printk(KERN_ERR "SWIM_IOP: probing for installed drives.\n");

	for (i = 0 ; i < MAX_FLOPPIES ; i++) {
		memset(&floppy_states[i], 0, sizeof(struct floppy_state));
		fs = &floppy_states[floppy_count];

		swimiop_init_request(&req);
		cmd->code = CMD_STATUS;
		cmd->drive_num = i + 1;
		if (swimiop_send_request(&req) != 0) continue;
		while (!req.complete);
		if (cmd->error != 0) {
			printk(KERN_ERR "SWIM-IOP: probe on drive %d returned error %d\n", i, (uint) cmd->error);
			continue;
		}
		if (ds->installed != 0x01) continue;
		printk("SWIM-IOP: drive %d is %s (%s, %s, %s, %s)\n", i,
			drive_names[ds->info.type],
			ds->info.external? "ext" : "int",
			ds->info.scsi? "scsi" : "floppy",
			ds->info.fixed? "fixed" : "removable",
			ds->info.secondary? "secondary" : "primary");
		swimiop_status_update(floppy_count, ds);
		fs->state = idle;

		init_timer(&fs->timeout);
		floppy_count++;
	}
	printk("SWIM-IOP: detected %d installed drives.\n", floppy_count);

	for (i = 0; i < floppy_count; i++) {
		struct gendisk *disk = alloc_disk(1);
		if (!disk)
			continue;
		disk->major = FLOPPY_MAJOR;
		disk->first_minor = i;
		disk->fops = &floppy_fops;
		sprintf(disk->disk_name, "fd%d", i);
		disk->private_data = &floppy_states[i];
		disk->queue = swim_queue;
		set_capacity(disk, 2880 * 2);
		add_disk(disk);
	}

	return 0;
}

static void swimiop_init_request(struct swim_iop_req *req)
{
	req->sent = 0;
	req->complete = 0;
	req->done = NULL;
}

static int swimiop_send_request(struct swim_iop_req *req)
{
	unsigned long flags;
	int err;

	/* It's doubtful an interrupt routine would try to send */
	/* a SWIM request, but I'd rather play it safe here.    */

	local_irq_save(flags);

	if (current_req != NULL) {
		local_irq_restore(flags);
		return -ENOMEM;
	}

	current_req = req;

	/* Interrupts should be back on for iop_send_message() */

	local_irq_restore(flags);

	err = iop_send_message(SWIM_IOP, SWIM_CHAN, (void *) req,
				sizeof(req->command), (__u8 *) &req->command[0],
				swimiop_receive);

	/* No race condition here; we own current_req at this point */

	if (err) {
		current_req = NULL;
	} else {
		req->sent = 1;
	}
	return err;
}

/*
 * Receive a SWIM message from the IOP.
 *
 * This will be called in two cases:
 *
 * 1. A message has been successfully sent to the IOP.
 * 2. An unsolicited message was received from the IOP.
 */

void swimiop_receive(struct iop_msg *msg, struct pt_regs *regs)
{
	struct swim_iop_req *req;
	struct swimmsg_status *sm;
	struct swim_drvstatus *ds;

	req = current_req;

	switch(msg->status) {
		case IOP_MSGSTATUS_COMPLETE:
			memcpy(&req->command[0], &msg->reply[0], sizeof(req->command));
			req->complete = 1;
			if (req->done) (*req->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);
			iop_complete_message(msg);
			break;
	}
}

static void swimiop_status_update(int drive_num, struct swim_drvstatus *ds)
{
	struct floppy_state *fs = &floppy_states[drive_num];

	fs->write_prot = (ds->write_prot == 0x80);
	if ((ds->disk_in_drive != 0x01) && (ds->disk_in_drive != 0x02)) {
		fs->ejected = 1;
	} else {
		fs->ejected = 0;
	}
	switch(ds->info.type) {
		case DRV_400K:
			fs->secpercyl = 10;
			fs->secpertrack = 10;
			fs->total_secs = 800;
			break;
		case DRV_800K:
			fs->secpercyl = 20;
			fs->secpertrack = 10;
			fs->total_secs = 1600;
			break;
		case DRV_FDHD:
			fs->secpercyl = 36;
			fs->secpertrack = 18;
			fs->total_secs = 2880;
			break;
		default:
			fs->secpercyl = 0;
			fs->secpertrack = 0;
			fs->total_secs = 0;
			break;
	}
}

static int swimiop_eject(struct floppy_state *fs)
{
	int err, n;
	struct swim_iop_req req;
	struct swimcmd_eject *cmd = (struct swimcmd_eject *) &req.command[0];

	err = grab_drive(fs, ejecting, 1);
	if (err) return err;

	swimiop_init_request(&req);
	cmd->code = CMD_EJECT;
	cmd->drive_num = fs->drive_num;
	err = swimiop_send_request(&req);
	if (err) {
		release_drive(fs);
		return err;
	}
	for (n = 2*HZ; n > 0; --n) {
		if (req.complete) break;
		if (signal_pending(current)) {
			err = -EINTR;
			break;
		}
		current->state = TASK_INTERRUPTIBLE;
		schedule_timeout(1);
	}
	release_drive(fs);
	return cmd->error;
}

static struct floppy_struct floppy_type =
	{ 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,NULL };	/*  7 1.44MB 3.5"   */

static int floppy_ioctl(struct inode *inode, struct file *filp,
			unsigned int cmd, unsigned long param)
{
	struct floppy_state *fs = inode->i_bdev->bd_disk->private_data;
	int err;

	if ((cmd & 0x80) && !capable(CAP_SYS_ADMIN))
		return -EPERM;

	switch (cmd) {
	case FDEJECT:
		if (fs->ref_count != 1)
			return -EBUSY;
		err = swimiop_eject(fs);
		return err;
	case FDGETPRM:
	        if (copy_to_user((void *) param, (void *) &floppy_type,
				 sizeof(struct floppy_struct)))
			return -EFAULT;
		return 0;
	}
	return -ENOTTY;
}

static int floppy_open(struct inode *inode, struct file *filp)
{
	struct floppy_state *fs = inode->i_bdev->bd_disk->private_data;

	if (fs->ref_count == -1 || filp->f_flags & O_EXCL)
		return -EBUSY;

	if ((filp->f_flags & O_NDELAY) == 0 && (filp->f_mode & 3)) {
		check_disk_change(inode->i_bdev);
		if (fs->ejected)
			return -ENXIO;
	}

	if ((filp->f_mode & 2) && fs->write_prot)
		return -EROFS;

	if (filp->f_flags & O_EXCL)
		fs->ref_count = -1;
	else
		++fs->ref_count;

	return 0;
}

static int floppy_release(struct inode *inode, struct file *filp)
{
	struct floppy_state *fs = inode->i_bdev->bd_disk->private_data;
	if (fs->ref_count > 0)
		fs->ref_count--;
	return 0;
}

static int floppy_check_change(struct gendisk *disk)
{
	struct floppy_state *fs = disk->private_data;
	return fs->ejected;
}

static int floppy_revalidate(struct gendisk *disk)
{
	struct floppy_state *fs = disk->private_data;
	grab_drive(fs, revalidating, 0);
	/* yadda, yadda */
	release_drive(fs);
	return 0;
}

static void floppy_off(unsigned int nr)
{
}

static int grab_drive(struct floppy_state *fs, enum swim_state state,
		      int interruptible)
{
	unsigned long flags;

	local_irq_save(flags);
	if (fs->state != idle) {
		++fs->wanted;
		while (fs->state != available) {
			if (interruptible && signal_pending(current)) {
				--fs->wanted;
				local_irq_restore(flags);
				return -EINTR;
			}
			interruptible_sleep_on(&fs->wait);
		}
		--fs->wanted;
	}
	fs->state = state;
	local_irq_restore(flags);
	return 0;
}

static void release_drive(struct floppy_state *fs)
{
	unsigned long flags;

	local_irq_save(flags);
	fs->state = idle;
	start_request(fs);
	local_irq_restore(flags);
}

static void set_timeout(struct floppy_state *fs, int nticks,
			void (*proc)(unsigned long))
{
	unsigned long flags;

	local_irq_save(flags);
	if (fs->timeout_pending)
		del_timer(&fs->timeout);
	init_timer(&fs->timeout);
	fs->timeout.expires = jiffies + nticks;
	fs->timeout.function = proc;
	fs->timeout.data = (unsigned long) fs;
	add_timer(&fs->timeout);
	fs->timeout_pending = 1;
	local_irq_restore(flags);
}

static void do_fd_request(request_queue_t * q)
{
	int i;

	for (i = 0 ; i < floppy_count ; i++) {
		start_request(&floppy_states[i]);
	}
}

static void fd_request_complete(struct swim_iop_req *req)
{
	struct floppy_state *fs = req->fs;
	struct swimcmd_rw *cmd = (struct swimcmd_rw *) &req->command[0];

	del_timer(&fs->timeout);
	fs->timeout_pending = 0;
	fs->state = idle;
	if (cmd->error) {
		printk(KERN_ERR "SWIM-IOP: error %d on read/write request.\n", cmd->error);
		end_request(CURRENT, 0);
	} else {
		CURRENT->sector += cmd->num_blocks;
		CURRENT->current_nr_sectors -= cmd->num_blocks;
		if (CURRENT->current_nr_sectors <= 0) {
			end_request(CURRENT, 1);
			return;
		}
	}
	start_request(fs);
}

static void fd_request_timeout(unsigned long data)
{
	struct floppy_state *fs = (struct floppy_state *) data;

	fs->timeout_pending = 0;
	end_request(CURRENT, 0);
	fs->state = idle;
}

static void start_request(struct floppy_state *fs)
{
	volatile struct swim_iop_req req;
	struct swimcmd_rw *cmd = (struct swimcmd_rw *) &req.command[0];

	if (fs->state == idle && fs->wanted) {
		fs->state = available;
		wake_up(&fs->wait);
		return;
	}
	while (CURRENT && fs->state == idle) {
		if (CURRENT->bh && !buffer_locked(CURRENT->bh))
			panic("floppy: block not locked");
#if 0
		printk("do_fd_req: dev=%s cmd=%d sec=%ld nr_sec=%ld buf=%p\n",
		       CURRENT->rq_disk->disk_name, CURRENT->cmd,
		       CURRENT->sector, CURRENT->nr_sectors, CURRENT->buffer);
		printk("           rq_status=%d errors=%d current_nr_sectors=%ld\n",
		       CURRENT->rq_status, CURRENT->errors, CURRENT->current_nr_sectors);
#endif

		if (CURRENT->sector < 0 || CURRENT->sector >= fs->total_secs) {
			end_request(CURRENT, 0);
			continue;
		}
		if (CURRENT->current_nr_sectors == 0) {
			end_request(CURRENT, 1);
			continue;
		}
		if (fs->ejected) {
			end_request(CURRENT, 0);
			continue;
		}

		swimiop_init_request(&req);
		req.fs = fs;
		req.done = fd_request_complete;

		if (CURRENT->cmd == WRITE) {
			if (fs->write_prot) {
				end_request(CURRENT, 0);
				continue;
			}
			cmd->code = CMD_WRITE;
		} else {
			cmd->code = CMD_READ;

		}
		cmd->drive_num = fs->drive_num;
		cmd->buffer = CURRENT->buffer;
		cmd->first_block = CURRENT->sector;
		cmd->num_blocks = CURRENT->current_nr_sectors;

		if (swimiop_send_request(&req)) {
			end_request(CURRENT, 0);
			continue;
		}

		set_timeout(fs, HZ*CURRENT->current_nr_sectors,
				fd_request_timeout);

		fs->state = transferring;
	}
}
