^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");