Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /* imm.c   --  low level driver for the IOMEGA MatchMaker
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  * parallel port SCSI host adapter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  * 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * (The IMM is the embedded controller in the ZIP Plus drive.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  * 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  * My unofficial company acronym list is 21 pages long:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  *      FLA:    Four letter acronym with built in facility for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  *              future expansion to five letters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <linux/parport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <linux/workqueue.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include <scsi/scsi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include <scsi/scsi_cmnd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include <scsi/scsi_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include <scsi/scsi_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) /* The following #define is to avoid a clash with hosts.c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #define IMM_PROBE_SPP   0x0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #define IMM_PROBE_PS2   0x0002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #define IMM_PROBE_ECR   0x0010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #define IMM_PROBE_EPP17 0x0100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #define IMM_PROBE_EPP19 0x0200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) typedef struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) 	struct pardevice *dev;	/* Parport device entry         */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) 	int base;		/* Actual port address          */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) 	int base_hi;		/* Hi Base address for ECP-ISA chipset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) 	int mode;		/* Transfer mode                */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) 	struct scsi_cmnd *cur_cmd;	/* Current queued command       */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) 	struct delayed_work imm_tq;	/* Polling interrupt stuff       */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) 	unsigned long jstart;	/* Jiffies at start             */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 	unsigned failed:1;	/* Failure flag                 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) 	unsigned dp:1;		/* Data phase present           */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) 	unsigned rd:1;		/* Read data in data phase      */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) 	unsigned wanted:1;	/* Parport sharing busy flag    */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) 	unsigned int dev_no;	/* Device number		*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) 	wait_queue_head_t *waiting;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 	struct Scsi_Host *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 	struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) } imm_struct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) static void imm_reset_pulse(unsigned int base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) static int device_check(imm_struct *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) #include "imm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) static inline imm_struct *imm_dev(struct Scsi_Host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 	return *(imm_struct **)&host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) static DEFINE_SPINLOCK(arbitration_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) static void got_it(imm_struct *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 	dev->base = dev->dev->port->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 	if (dev->cur_cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 		dev->cur_cmd->SCp.phase = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 		wake_up(dev->waiting);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) static void imm_wakeup(void *ref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 	imm_struct *dev = (imm_struct *) ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 	spin_lock_irqsave(&arbitration_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 	if (dev->wanted) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 		if (parport_claim(dev->dev) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 			got_it(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 			dev->wanted = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 	spin_unlock_irqrestore(&arbitration_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) static int imm_pb_claim(imm_struct *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 	int res = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 	spin_lock_irqsave(&arbitration_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 	if (parport_claim(dev->dev) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 		got_it(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 		res = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 	dev->wanted = res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 	spin_unlock_irqrestore(&arbitration_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 	return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) static void imm_pb_dismiss(imm_struct *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 	int wanted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 	spin_lock_irqsave(&arbitration_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 	wanted = dev->wanted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 	dev->wanted = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 	spin_unlock_irqrestore(&arbitration_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 	if (!wanted)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 		parport_release(dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) static inline void imm_pb_release(imm_struct *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 	parport_release(dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) /* This is to give the imm driver a way to modify the timings (and other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121)  * parameters) by writing to the /proc/scsi/imm/0 file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122)  * Very simple method really... (Too simple, no error checking :( )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123)  * Reason: Kernel hackers HATE having to unload and reload modules for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124)  * testing...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125)  * Also gives a method to use a script to obtain optimum timings (TODO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) static int imm_write_info(struct Scsi_Host *host, char *buffer, int length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 	imm_struct *dev = imm_dev(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	if ((length > 5) && (strncmp(buffer, "mode=", 5) == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 		dev->mode = simple_strtoul(buffer + 5, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 		return length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 	printk("imm /proc: invalid variable\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) static int imm_show_info(struct seq_file *m, struct Scsi_Host *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 	imm_struct *dev = imm_dev(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	seq_printf(m, "Version : %s\n", IMM_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	seq_printf(m, "Parport : %s\n", dev->dev->port->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 	seq_printf(m, "Mode    : %s\n", IMM_MODE_STRING[dev->mode]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) #if IMM_DEBUG > 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) #define imm_fail(x,y) printk("imm: imm_fail(%i) from %s at line %d\n",\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 	   y, __func__, __LINE__); imm_fail_func(x,y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) imm_fail_func(imm_struct *dev, int error_code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) imm_fail(imm_struct *dev, int error_code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 	/* If we fail a device then we trash status / message bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	if (dev->cur_cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 		dev->cur_cmd->result = error_code << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 		dev->failed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167)  * Wait for the high bit to be set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168)  * 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169)  * In principle, this could be tied to an interrupt, but the adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170)  * doesn't appear to be designed to support interrupts.  We spin on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171)  * the 0x80 ready bit. 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) static unsigned char imm_wait(imm_struct *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 	int k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 	unsigned short ppb = dev->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 	unsigned char r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 	w_ctr(ppb, 0x0c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 	k = IMM_SPIN_TMO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 		r = r_str(ppb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 		k--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 		udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 	while (!(r & 0x80) && (k));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 	 * STR register (LPT base+1) to SCSI mapping:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 	 * STR      imm     imm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	 * ===================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 	 * 0x80     S_REQ   S_REQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	 * 0x40     !S_BSY  (????)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 	 * 0x20     !S_CD   !S_CD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 	 * 0x10     !S_IO   !S_IO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	 * 0x08     (????)  !S_BSY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	 * imm      imm     meaning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	 * ==================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	 * 0xf0     0xb8    Bit mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	 * 0xc0     0x88    ZIP wants more data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	 * 0xd0     0x98    ZIP wants to send more data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 	 * 0xe0     0xa8    ZIP is expecting SCSI command data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	 * 0xf0     0xb8    end of transfer, ZIP is sending status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	w_ctr(ppb, 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 	if (k)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 		return (r & 0xb8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	/* Counter expired - Time out occurred */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	imm_fail(dev, DID_TIME_OUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 	printk("imm timeout in imm_wait\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	return 0;		/* command timed out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) static int imm_negotiate(imm_struct * tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	 * The following is supposedly the IEEE 1284-1994 negotiate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	 * sequence. I have yet to obtain a copy of the above standard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 	 * so this is a bit of a guess...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 	 * A fair chunk of this is based on the Linux parport implementation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 	 * of IEEE 1284.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 	 * Return 0 if data available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	 *        1 if no data available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 	unsigned short base = tmp->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 	unsigned char a, mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	switch (tmp->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 	case IMM_NIBBLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 		mode = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	case IMM_PS2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 		mode = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	w_ctr(base, 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 	udelay(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 	w_dtr(base, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 	udelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 	w_ctr(base, 0x06);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 	udelay(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 	a = (r_str(base) & 0x20) ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 	udelay(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	w_ctr(base, 0x07);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 	udelay(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	w_ctr(base, 0x06);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	if (a) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 		printk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 		    ("IMM: IEEE1284 negotiate indicates no data available.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 		imm_fail(tmp, DID_ERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 	return a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) /* 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267)  * Clear EPP timeout bit. 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) static inline void epp_reset(unsigned short ppb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 	i = r_str(ppb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	w_str(ppb, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 	w_str(ppb, i & 0xfe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) /* 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279)  * Wait for empty ECP fifo (if we are in ECP fifo mode only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) static inline void ecp_sync(imm_struct *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 	int i, ppb_hi = dev->base_hi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 	if (ppb_hi == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 	if ((r_ecr(ppb_hi) & 0xe0) == 0x60) {	/* mode 011 == ECP fifo mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 		for (i = 0; i < 100; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 			if (r_ecr(ppb_hi) & 0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 				return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 			udelay(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 		printk("imm: ECP sync failed as data still present in FIFO.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) static int imm_byte_out(unsigned short base, const char *buffer, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 	w_ctr(base, 0x4);	/* apparently a sane mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 	for (i = len >> 1; i; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 		w_dtr(base, *buffer++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 		w_ctr(base, 0x5);	/* Drop STROBE low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 		w_dtr(base, *buffer++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 		w_ctr(base, 0x0);	/* STROBE high + INIT low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 	w_ctr(base, 0x4);	/* apparently a sane mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 	return 1;		/* All went well - we hope! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) static int imm_nibble_in(unsigned short base, char *buffer, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 	unsigned char l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 	 * The following is based on documented timing signals
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 	w_ctr(base, 0x4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 	for (i = len; i; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 		w_ctr(base, 0x6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 		l = (r_str(base) & 0xf0) >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 		w_ctr(base, 0x5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 		*buffer++ = (r_str(base) & 0xf0) | l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 		w_ctr(base, 0x4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	return 1;		/* All went well - we hope! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) static int imm_byte_in(unsigned short base, char *buffer, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 	 * The following is based on documented timing signals
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 	w_ctr(base, 0x4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 	for (i = len; i; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 		w_ctr(base, 0x26);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 		*buffer++ = r_dtr(base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 		w_ctr(base, 0x25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 	return 1;		/* All went well - we hope! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) static int imm_out(imm_struct *dev, char *buffer, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	unsigned short ppb = dev->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 	int r = imm_wait(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 	 * Make sure that:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 	 * a) the SCSI bus is BUSY (device still listening)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 	 * b) the device is listening
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 	if ((r & 0x18) != 0x08) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 		imm_fail(dev, DID_ERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 		printk("IMM: returned SCSI status %2x\n", r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 	switch (dev->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 	case IMM_EPP_32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 	case IMM_EPP_16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 	case IMM_EPP_8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 		epp_reset(ppb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 		w_ctr(ppb, 0x4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) #ifdef CONFIG_SCSI_IZIP_EPP16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 		if (!(((long) buffer | len) & 0x01))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 			outsw(ppb + 4, buffer, len >> 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 		if (!(((long) buffer | len) & 0x03))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 			outsl(ppb + 4, buffer, len >> 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 			outsb(ppb + 4, buffer, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 		w_ctr(ppb, 0xc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 		r = !(r_str(ppb) & 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 		w_ctr(ppb, 0xc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 		ecp_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 	case IMM_NIBBLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 	case IMM_PS2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 		/* 8 bit output, with a loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 		r = imm_byte_out(ppb, buffer, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 		printk("IMM: bug in imm_out()\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 		r = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 	return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) static int imm_in(imm_struct *dev, char *buffer, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 	unsigned short ppb = dev->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 	int r = imm_wait(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 	 * Make sure that:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 	 * a) the SCSI bus is BUSY (device still listening)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 	 * b) the device is sending data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 	if ((r & 0x18) != 0x18) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 		imm_fail(dev, DID_ERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 	switch (dev->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	case IMM_NIBBLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 		/* 4 bit input, with a loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 		r = imm_nibble_in(ppb, buffer, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 		w_ctr(ppb, 0xc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 	case IMM_PS2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 		/* 8 bit input, with a loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 		r = imm_byte_in(ppb, buffer, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 		w_ctr(ppb, 0xc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 	case IMM_EPP_32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 	case IMM_EPP_16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 	case IMM_EPP_8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 		epp_reset(ppb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 		w_ctr(ppb, 0x24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) #ifdef CONFIG_SCSI_IZIP_EPP16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 		if (!(((long) buffer | len) & 0x01))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 			insw(ppb + 4, buffer, len >> 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 		if (!(((long) buffer | len) & 0x03))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 			insl(ppb + 4, buffer, len >> 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 			insb(ppb + 4, buffer, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 		w_ctr(ppb, 0x2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 		r = !(r_str(ppb) & 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 		w_ctr(ppb, 0x2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 		ecp_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 		printk("IMM: bug in imm_ins()\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 		r = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 	return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) static int imm_cpp(unsigned short ppb, unsigned char b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 	 * Comments on udelay values refer to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 	 * Command Packet Protocol (CPP) timing diagram.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 	unsigned char s1, s2, s3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 	w_ctr(ppb, 0x0c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 	udelay(2);		/* 1 usec - infinite */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 	w_dtr(ppb, 0xaa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 	udelay(10);		/* 7 usec - infinite */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 	w_dtr(ppb, 0x55);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 	udelay(10);		/* 7 usec - infinite */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 	w_dtr(ppb, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 	udelay(10);		/* 7 usec - infinite */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 	w_dtr(ppb, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 	udelay(10);		/* 7 usec - infinite */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 	s1 = r_str(ppb) & 0xb8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 	w_dtr(ppb, 0x87);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 	udelay(10);		/* 7 usec - infinite */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 	s2 = r_str(ppb) & 0xb8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 	w_dtr(ppb, 0x78);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 	udelay(10);		/* 7 usec - infinite */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 	s3 = r_str(ppb) & 0x38;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 	 * Values for b are:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 	 * 0000 00aa    Assign address aa to current device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 	 * 0010 00aa    Select device aa in EPP Winbond mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 	 * 0010 10aa    Select device aa in EPP mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 	 * 0011 xxxx    Deselect all devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 	 * 0110 00aa    Test device aa
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 	 * 1101 00aa    Select device aa in ECP mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 	 * 1110 00aa    Select device aa in Compatible mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 	w_dtr(ppb, b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 	udelay(2);		/* 1 usec - infinite */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 	w_ctr(ppb, 0x0c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 	udelay(10);		/* 7 usec - infinite */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 	w_ctr(ppb, 0x0d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 	udelay(2);		/* 1 usec - infinite */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 	w_ctr(ppb, 0x0c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	udelay(10);		/* 7 usec - infinite */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 	w_dtr(ppb, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 	udelay(10);		/* 7 usec - infinite */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 	 * The following table is electrical pin values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 	 * (BSY is inverted at the CTR register)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 	 *       BSY  ACK  POut SEL  Fault
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 	 * S1    0    X    1    1    1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 	 * S2    1    X    0    1    1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	 * S3    L    X    1    1    S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 	 * L => Last device in chain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 	 * S => Selected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 	 * Observered values for S1,S2,S3 are:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 	 * Disconnect => f8/58/78
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 	 * Connect    => f8/58/70
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 	if ((s1 == 0xb8) && (s2 == 0x18) && (s3 == 0x30))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 		return 1;	/* Connected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 	if ((s1 == 0xb8) && (s2 == 0x18) && (s3 == 0x38))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 		return 0;	/* Disconnected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 	return -1;		/* No device present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) static inline int imm_connect(imm_struct *dev, int flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 	unsigned short ppb = dev->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 	imm_cpp(ppb, 0xe0);	/* Select device 0 in compatible mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 	imm_cpp(ppb, 0x30);	/* Disconnect all devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 	if ((dev->mode == IMM_EPP_8) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 	    (dev->mode == IMM_EPP_16) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 	    (dev->mode == IMM_EPP_32))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 		return imm_cpp(ppb, 0x28);	/* Select device 0 in EPP mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 	return imm_cpp(ppb, 0xe0);	/* Select device 0 in compatible mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) static void imm_disconnect(imm_struct *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 	imm_cpp(dev->base, 0x30);	/* Disconnect all devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) static int imm_select(imm_struct *dev, int target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 	int k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 	unsigned short ppb = dev->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 	 * Firstly we want to make sure there is nothing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 	 * holding onto the SCSI bus.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	w_ctr(ppb, 0xc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 	k = IMM_SELECT_TMO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 		k--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 	} while ((r_str(ppb) & 0x08) && (k));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	if (!k)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	 * Now assert the SCSI ID (HOST and TARGET) on the data bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	w_ctr(ppb, 0x4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 	w_dtr(ppb, 0x80 | (1 << target));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 	 * Deassert SELIN first followed by STROBE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	w_ctr(ppb, 0xc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 	w_ctr(ppb, 0xd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 	 * ACK should drop low while SELIN is deasserted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 	 * FAULT should drop low when the SCSI device latches the bus.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 	k = IMM_SELECT_TMO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 		k--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 	while (!(r_str(ppb) & 0x08) && (k));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	 * Place the interface back into a sane state (status mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 	w_ctr(ppb, 0xc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	return (k) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) static int imm_init(imm_struct *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 	if (imm_connect(dev, 0) != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 	imm_reset_pulse(dev->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 	mdelay(1);	/* Delay to allow devices to settle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 	imm_disconnect(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 	mdelay(1);	/* Another delay to allow devices to settle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 	return device_check(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) static inline int imm_send_command(struct scsi_cmnd *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 	imm_struct *dev = imm_dev(cmd->device->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 	int k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 	/* NOTE: IMM uses byte pairs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 	for (k = 0; k < cmd->cmd_len; k += 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 		if (!imm_out(dev, &cmd->cmnd[k], 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614)  * The bulk flag enables some optimisations in the data transfer loops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615)  * it should be true for any command that transfers data in integral
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616)  * numbers of sectors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617)  * 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618)  * The driver appears to remain stable if we speed up the parallel port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619)  * i/o in this function, but not elsewhere.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) static int imm_completion(struct scsi_cmnd *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	/* Return codes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 	 * -1     Error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 	 *  0     Told to schedule
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	 *  1     Finished data transfer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 	imm_struct *dev = imm_dev(cmd->device->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 	unsigned short ppb = dev->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 	unsigned long start_jiffies = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 	unsigned char r, v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 	int fast, bulk, status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 	v = cmd->cmnd[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 	bulk = ((v == READ_6) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 		(v == READ_10) || (v == WRITE_6) || (v == WRITE_10));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 	 * We only get here if the drive is ready to comunicate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 	 * hence no need for a full imm_wait.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 	w_ctr(ppb, 0x0c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 	r = (r_str(ppb) & 0xb8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 	 * while (device is not ready to send status byte)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 	 *     loop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 	while (r != (unsigned char) 0xb8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 		 * If we have been running for more than a full timer tick
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 		 * then take a rest.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 		if (time_after(jiffies, start_jiffies + 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 		 * FAIL if:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 		 * a) Drive status is screwy (!ready && !present)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 		 * b) Drive is requesting/sending more data than expected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 		if (((r & 0x88) != 0x88) || (cmd->SCp.this_residual <= 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 			imm_fail(dev, DID_ERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 			return -1;	/* ERROR_RETURN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 		/* determine if we should use burst I/O */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 		if (dev->rd == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 			fast = (bulk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 				&& (cmd->SCp.this_residual >=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 				    IMM_BURST_SIZE)) ? IMM_BURST_SIZE : 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 			status = imm_out(dev, cmd->SCp.ptr, fast);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 			fast = (bulk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 				&& (cmd->SCp.this_residual >=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 				    IMM_BURST_SIZE)) ? IMM_BURST_SIZE : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 			status = imm_in(dev, cmd->SCp.ptr, fast);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 		cmd->SCp.ptr += fast;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 		cmd->SCp.this_residual -= fast;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 		if (!status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 			imm_fail(dev, DID_BUS_BUSY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 			return -1;	/* ERROR_RETURN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 		if (cmd->SCp.buffer && !cmd->SCp.this_residual) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 			/* if scatter/gather, advance to the next segment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 			if (cmd->SCp.buffers_residual--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 				cmd->SCp.buffer = sg_next(cmd->SCp.buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 				cmd->SCp.this_residual =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 				    cmd->SCp.buffer->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 				cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 				 * Make sure that we transfer even number of bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 				 * otherwise it makes imm_byte_out() messy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 				if (cmd->SCp.this_residual & 0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 					cmd->SCp.this_residual++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 		/* Now check to see if the drive is ready to comunicate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 		w_ctr(ppb, 0x0c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 		r = (r_str(ppb) & 0xb8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 		/* If not, drop back down to the scheduler and wait a timer tick */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 		if (!(r & 0x80))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 	return 1;		/* FINISH_RETURN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715)  * Since the IMM itself doesn't generate interrupts, we use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716)  * the scheduler's task queue to generate a stream of call-backs and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717)  * complete the request when the drive is ready.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) static void imm_interrupt(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 	imm_struct *dev = container_of(work, imm_struct, imm_tq.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 	struct scsi_cmnd *cmd = dev->cur_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 	struct Scsi_Host *host = cmd->device->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 	if (imm_engine(dev, cmd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 		schedule_delayed_work(&dev->imm_tq, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 	/* Command must of completed hence it is safe to let go... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) #if IMM_DEBUG > 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 	switch ((cmd->result >> 16) & 0xff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 	case DID_OK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 	case DID_NO_CONNECT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 		printk("imm: no device at SCSI ID %i\n", cmd->device->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 	case DID_BUS_BUSY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 		printk("imm: BUS BUSY - EPP timeout detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 	case DID_TIME_OUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 		printk("imm: unknown timeout\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 	case DID_ABORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 		printk("imm: told to abort\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 	case DID_PARITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 		printk("imm: parity error (???)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 	case DID_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 		printk("imm: internal driver error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 	case DID_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 		printk("imm: told to reset device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 	case DID_BAD_INTR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 		printk("imm: bad interrupt (???)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 		printk("imm: bad return code (%02x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 		       (cmd->result >> 16) & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	if (cmd->SCp.phase > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 		imm_disconnect(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 	imm_pb_dismiss(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 	spin_lock_irqsave(host->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 	dev->cur_cmd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 	cmd->scsi_done(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 	spin_unlock_irqrestore(host->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) static int imm_engine(imm_struct *dev, struct scsi_cmnd *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 	unsigned short ppb = dev->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 	unsigned char l = 0, h = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 	int retv, x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 	/* First check for any errors that may have occurred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 	 * Here we check for internal errors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	if (dev->failed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 	switch (cmd->SCp.phase) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 	case 0:		/* Phase 0 - Waiting for parport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 		if (time_after(jiffies, dev->jstart + HZ)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 			 * We waited more than a second
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 			 * for parport to call us
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 			imm_fail(dev, DID_BUS_BUSY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 		return 1;	/* wait until imm_wakeup claims parport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 	case 1:		/* Phase 1 - Connected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 		imm_connect(dev, CONNECT_EPP_MAYBE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 		cmd->SCp.phase++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 	case 2:		/* Phase 2 - We are now talking to the scsi bus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 		if (!imm_select(dev, scmd_id(cmd))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 			imm_fail(dev, DID_NO_CONNECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 		cmd->SCp.phase++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 	case 3:		/* Phase 3 - Ready to accept a command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 		w_ctr(ppb, 0x0c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 		if (!(r_str(ppb) & 0x80))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 			return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 		if (!imm_send_command(cmd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 		cmd->SCp.phase++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	case 4:		/* Phase 4 - Setup scatter/gather buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 		if (scsi_bufflen(cmd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 			cmd->SCp.buffer = scsi_sglist(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 			cmd->SCp.this_residual = cmd->SCp.buffer->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 			cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 			cmd->SCp.buffer = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 			cmd->SCp.this_residual = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 			cmd->SCp.ptr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 		cmd->SCp.buffers_residual = scsi_sg_count(cmd) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 		cmd->SCp.phase++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 		if (cmd->SCp.this_residual & 0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 			cmd->SCp.this_residual++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 	case 5:		/* Phase 5 - Pre-Data transfer stage */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 		/* Spin lock for BUSY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 		w_ctr(ppb, 0x0c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 		if (!(r_str(ppb) & 0x80))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 			return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 		/* Require negotiation for read requests */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 		x = (r_str(ppb) & 0xb8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 		dev->rd = (x & 0x10) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 		dev->dp = (x & 0x20) ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 		if ((dev->dp) && (dev->rd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 			if (imm_negotiate(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 		cmd->SCp.phase++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 	case 6:		/* Phase 6 - Data transfer stage */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 		/* Spin lock for BUSY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 		w_ctr(ppb, 0x0c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 		if (!(r_str(ppb) & 0x80))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 			return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 		if (dev->dp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 			retv = imm_completion(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 			if (retv == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 			if (retv == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 				return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 		cmd->SCp.phase++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 	case 7:		/* Phase 7 - Post data transfer stage */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 		if ((dev->dp) && (dev->rd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 			if ((dev->mode == IMM_NIBBLE) || (dev->mode == IMM_PS2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 				w_ctr(ppb, 0x4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 				w_ctr(ppb, 0xc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 				w_ctr(ppb, 0xe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 				w_ctr(ppb, 0x4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 		cmd->SCp.phase++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 	case 8:		/* Phase 8 - Read status/message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 		/* Check for data overrun */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 		if (imm_wait(dev) != (unsigned char) 0xb8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 			imm_fail(dev, DID_ERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 		if (imm_negotiate(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 		if (imm_in(dev, &l, 1)) {	/* read status byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 			/* Check for optional message byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 			if (imm_wait(dev) == (unsigned char) 0xb8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 				imm_in(dev, &h, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 			cmd->result = (DID_OK << 16) | (l & STATUS_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 		if ((dev->mode == IMM_NIBBLE) || (dev->mode == IMM_PS2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 			w_ctr(ppb, 0x4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 			w_ctr(ppb, 0xc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 			w_ctr(ppb, 0xe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 			w_ctr(ppb, 0x4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 		return 0;	/* Finished */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 		printk("imm: Invalid scsi phase\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) static int imm_queuecommand_lck(struct scsi_cmnd *cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 		void (*done)(struct scsi_cmnd *))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 	imm_struct *dev = imm_dev(cmd->device->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 	if (dev->cur_cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 		printk("IMM: bug in imm_queuecommand\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	dev->failed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 	dev->jstart = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 	dev->cur_cmd = cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 	cmd->scsi_done = done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 	cmd->result = DID_ERROR << 16;	/* default return code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 	cmd->SCp.phase = 0;	/* bus free */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 	schedule_delayed_work(&dev->imm_tq, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 	imm_pb_claim(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) static DEF_SCSI_QCMD(imm_queuecommand)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939)  * Apparently the disk->capacity attribute is off by 1 sector 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940)  * for all disk drives.  We add the one here, but it should really
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941)  * be done in sd.c.  Even if it gets fixed there, this will still
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942)  * work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) static int imm_biosparam(struct scsi_device *sdev, struct block_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 			 sector_t capacity, int ip[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	ip[0] = 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 	ip[1] = 0x20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	ip[2] = ((unsigned long) capacity + 1) / (ip[0] * ip[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	if (ip[2] > 1024) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 		ip[0] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 		ip[1] = 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 		ip[2] = ((unsigned long) capacity + 1) / (ip[0] * ip[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) static int imm_abort(struct scsi_cmnd *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 	imm_struct *dev = imm_dev(cmd->device->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 	 * There is no method for aborting commands since Iomega
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	 * have tied the SCSI_MESSAGE line high in the interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	switch (cmd->SCp.phase) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 	case 0:		/* Do not have access to parport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 	case 1:		/* Have not connected to interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 		dev->cur_cmd = NULL;	/* Forget the problem */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 		return SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 	default:		/* SCSI command sent, can not abort */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 		return FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) static void imm_reset_pulse(unsigned int base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	w_ctr(base, 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	w_dtr(base, 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	w_ctr(base, 0x0c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	w_ctr(base, 0x0d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	udelay(50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	w_ctr(base, 0x0c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	w_ctr(base, 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) static int imm_reset(struct scsi_cmnd *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	imm_struct *dev = imm_dev(cmd->device->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 	if (cmd->SCp.phase)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 		imm_disconnect(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	dev->cur_cmd = NULL;	/* Forget the problem */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	imm_connect(dev, CONNECT_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	imm_reset_pulse(dev->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 	mdelay(1);		/* device settle delay */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 	imm_disconnect(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 	mdelay(1);		/* device settle delay */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 	return SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) static int device_check(imm_struct *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	/* This routine looks for a device and then attempts to use EPP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	   to send a command. If all goes as planned then EPP is available. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	static char cmd[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	int loop, old_mode, status, k, ppb = dev->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	unsigned char l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	old_mode = dev->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 	for (loop = 0; loop < 8; loop++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 		/* Attempt to use EPP for Test Unit Ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 		if ((ppb & 0x0007) == 0x0000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 			dev->mode = IMM_EPP_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 	      second_pass:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 		imm_connect(dev, CONNECT_EPP_MAYBE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 		/* Select SCSI device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 		if (!imm_select(dev, loop)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 			imm_disconnect(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 		printk("imm: Found device at ID %i, Attempting to use %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 		       loop, IMM_MODE_STRING[dev->mode]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 		/* Send SCSI command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 		status = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 		w_ctr(ppb, 0x0c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 		for (l = 0; (l < 3) && (status); l++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 			status = imm_out(dev, &cmd[l << 1], 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 		if (!status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 			imm_disconnect(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 			imm_connect(dev, CONNECT_EPP_MAYBE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 			imm_reset_pulse(dev->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 			udelay(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 			imm_disconnect(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 			udelay(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 			if (dev->mode == IMM_EPP_32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 				dev->mode = old_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 				goto second_pass;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 			printk("imm: Unable to establish communication\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 			return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 		w_ctr(ppb, 0x0c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 		k = 1000000;	/* 1 Second */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 		do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 			l = r_str(ppb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 			k--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 			udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 		} while (!(l & 0x80) && (k));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 		l &= 0xb8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 		if (l != 0xb8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 			imm_disconnect(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 			imm_connect(dev, CONNECT_EPP_MAYBE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 			imm_reset_pulse(dev->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 			udelay(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 			imm_disconnect(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 			udelay(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 			if (dev->mode == IMM_EPP_32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 				dev->mode = old_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 				goto second_pass;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 			printk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 			    ("imm: Unable to establish communication\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 			return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 		imm_disconnect(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 		printk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 		    ("imm: Communication established at 0x%x with ID %i using %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 		     ppb, loop, IMM_MODE_STRING[dev->mode]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 		imm_connect(dev, CONNECT_EPP_MAYBE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 		imm_reset_pulse(dev->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 		udelay(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 		imm_disconnect(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 		udelay(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 	printk("imm: No devices found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 	return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)  * imm cannot deal with highmem, so this causes all IO pages for this host
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)  * to reside in low memory (hence mapped)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) static int imm_adjust_queue(struct scsi_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 	blk_queue_bounce_limit(device->request_queue, BLK_BOUNCE_HIGH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) static struct scsi_host_template imm_template = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 	.module			= THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 	.proc_name		= "imm",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 	.show_info		= imm_show_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	.write_info		= imm_write_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	.name			= "Iomega VPI2 (imm) interface",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 	.queuecommand		= imm_queuecommand,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 	.eh_abort_handler	= imm_abort,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 	.eh_host_reset_handler	= imm_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 	.bios_param		= imm_biosparam,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 	.this_id		= 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 	.sg_tablesize		= SG_ALL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 	.can_queue		= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 	.slave_alloc		= imm_adjust_queue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) /***************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)  *                   Parallel port probing routines                        *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118)  ***************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) static LIST_HEAD(imm_hosts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)  * Finds the first available device number that can be alloted to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124)  * new imm device and returns the address of the previous node so that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)  * we can add to the tail and have a list in the ascending order.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) static inline imm_struct *find_parent(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 	imm_struct *dev, *par = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 	unsigned int cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 	if (list_empty(&imm_hosts))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 	list_for_each_entry(dev, &imm_hosts, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 		if (dev->dev_no != cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 			return par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 		cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 		par = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 	return par;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) static int __imm_attach(struct parport *pb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 	struct Scsi_Host *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 	imm_struct *dev, *temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 	DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waiting);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 	DEFINE_WAIT(wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	int ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 	int modes, ppb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 	int err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 	struct pardev_cb imm_cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 	init_waitqueue_head(&waiting);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 	dev = kzalloc(sizeof(imm_struct), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 	if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 	dev->base = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 	dev->mode = IMM_AUTODETECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 	INIT_LIST_HEAD(&dev->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 	temp = find_parent();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 	if (temp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 		dev->dev_no = temp->dev_no + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 	memset(&imm_cb, 0, sizeof(imm_cb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 	imm_cb.private = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 	imm_cb.wakeup = imm_wakeup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 	dev->dev = parport_register_dev_model(pb, "imm", &imm_cb, dev->dev_no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 	if (!dev->dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 	/* Claim the bus so it remembers what we do to the control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 	 * registers. [ CTR and ECP ]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 	err = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 	dev->waiting = &waiting;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 	prepare_to_wait(&waiting, &wait, TASK_UNINTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 	if (imm_pb_claim(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 		schedule_timeout(3 * HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 	if (dev->wanted) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 		printk(KERN_ERR "imm%d: failed to claim parport because "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 			"a pardevice is owning the port for too long "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 			"time!\n", pb->number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 		imm_pb_dismiss(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 		dev->waiting = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 		finish_wait(&waiting, &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 		goto out1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 	dev->waiting = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 	finish_wait(&waiting, &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 	ppb = dev->base = dev->dev->port->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 	dev->base_hi = dev->dev->port->base_hi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 	w_ctr(ppb, 0x0c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 	modes = dev->dev->port->modes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 	/* Mode detection works up the chain of speed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 	 * This avoids a nasty if-then-else-if-... tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 	dev->mode = IMM_NIBBLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 	if (modes & PARPORT_MODE_TRISTATE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 		dev->mode = IMM_PS2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 	/* Done configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 	err = imm_init(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 	imm_pb_release(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 		goto out1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 	/* now the glue ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 	if (dev->mode == IMM_NIBBLE || dev->mode == IMM_PS2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 		ports = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 		ports = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 	INIT_DELAYED_WORK(&dev->imm_tq, imm_interrupt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 	err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 	host = scsi_host_alloc(&imm_template, sizeof(imm_struct *));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 	if (!host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 		goto out1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 	host->io_port = pb->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 	host->n_io_port = ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 	host->dma_channel = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 	host->unique_id = pb->number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 	*(imm_struct **)&host->hostdata = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 	dev->host = host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 	if (!temp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 		list_add_tail(&dev->list, &imm_hosts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 		list_add_tail(&dev->list, &temp->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 	err = scsi_add_host(host, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 		goto out2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 	scsi_scan_host(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) out2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 	list_del_init(&dev->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 	scsi_host_put(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) out1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 	parport_unregister_device(dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 	kfree(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) static void imm_attach(struct parport *pb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 	__imm_attach(pb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) static void imm_detach(struct parport *pb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 	imm_struct *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 	list_for_each_entry(dev, &imm_hosts, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 		if (dev->dev->port == pb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 			list_del_init(&dev->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 			scsi_remove_host(dev->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 			scsi_host_put(dev->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 			parport_unregister_device(dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 			kfree(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) static struct parport_driver imm_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 	.name		= "imm",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 	.match_port	= imm_attach,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 	.detach		= imm_detach,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 	.devmodel	= true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) static int __init imm_driver_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 	printk("imm: Version %s\n", IMM_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 	return parport_register_driver(&imm_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) static void __exit imm_driver_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 	parport_unregister_driver(&imm_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) module_init(imm_driver_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) module_exit(imm_driver_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) MODULE_LICENSE("GPL");