113546Sjulian// SPDX-License-Identifier: GPL-2.0-only 2113658Sdeischen/* imm.c -- low level driver for the IOMEGA MatchMaker 3113658Sdeischen * parallel port SCSI host adapter. 435509Sjb * 513546Sjulian * (The IMM is the embedded controller in the ZIP Plus drive.) 613546Sjulian * 713546Sjulian * My unofficial company acronym list is 21 pages long: 813546Sjulian * FLA: Four letter acronym with built in facility for 913546Sjulian * future expansion to five letters. 1013546Sjulian */ 1113546Sjulian 1213546Sjulian#include <linux/init.h> 1313546Sjulian#include <linux/kernel.h> 1413546Sjulian#include <linux/module.h> 1513546Sjulian#include <linux/blkdev.h> 1613546Sjulian#include <linux/parport.h> 1713546Sjulian#include <linux/workqueue.h> 1813546Sjulian#include <linux/delay.h> 1913546Sjulian#include <linux/slab.h> 2013546Sjulian#include <asm/io.h> 2113546Sjulian 2213546Sjulian#include <scsi/scsi.h> 2313546Sjulian#include <scsi/scsi_cmnd.h> 2413546Sjulian#include <scsi/scsi_device.h> 2544963Sjb#include <scsi/scsi_host.h> 2613546Sjulian 2713546Sjulian/* The following #define is to avoid a clash with hosts.c */ 2813546Sjulian#define IMM_PROBE_SPP 0x0001 2913546Sjulian#define IMM_PROBE_PS2 0x0002 3013546Sjulian#define IMM_PROBE_ECR 0x0010 3113546Sjulian#define IMM_PROBE_EPP17 0x0100 3213546Sjulian#define IMM_PROBE_EPP19 0x0200 3313546Sjulian 3413546Sjulian 35113658Sdeischentypedef struct { 36113662Sdeischen struct pardevice *dev; /* Parport device entry */ 37113658Sdeischen int base; /* Actual port address */ 38113658Sdeischen int base_hi; /* Hi Base address for ECP-ISA chipset */ 39113658Sdeischen int mode; /* Transfer mode */ 40132120Sdavidxu struct scsi_cmnd *cur_cmd; /* Current queued command */ 41113658Sdeischen struct delayed_work imm_tq; /* Polling interrupt stuff */ 42113658Sdeischen unsigned long jstart; /* Jiffies at start */ 43113658Sdeischen unsigned failed:1; /* Failure flag */ 44116977Sdavidxu unsigned dp:1; /* Data phase present */ 45113658Sdeischen unsigned rd:1; /* Read data in data phase */ 46113658Sdeischen unsigned wanted:1; /* Parport sharing busy flag */ 47113870Sdeischen unsigned int dev_no; /* Device number */ 48113658Sdeischen wait_queue_head_t *waiting; 4913546Sjulian struct Scsi_Host *host; 5013546Sjulian struct list_head list; 51113658Sdeischen} imm_struct; 52113658Sdeischen 5313546Sjulianstatic void imm_reset_pulse(unsigned int base); 54113658Sdeischenstatic int device_check(imm_struct *dev, bool autodetect); 55113658Sdeischen 56103388Smini#include "imm.h" 57113658Sdeischen 58150499Sbrianstatic unsigned int mode = IMM_AUTODETECT; 59150499Sbrianmodule_param(mode, uint, 0644); 60150499SbrianMODULE_PARM_DESC(mode, "Transfer mode (0 = Autodetect, 1 = SPP 4-bit, " 6113546Sjulian "2 = SPP 8-bit, 3 = EPP 8-bit, 4 = EPP 16-bit, 5 = EPP 32-bit"); 62139023Sdeischen 6367097Sdeischenstatic inline imm_struct *imm_dev(struct Scsi_Host *host) 6467097Sdeischen{ 6567097Sdeischen return *(imm_struct **)&host->hostdata; 6667097Sdeischen} 6767097Sdeischen 6867097Sdeischenstatic DEFINE_SPINLOCK(arbitration_lock); 69113658Sdeischen 70113658Sdeischenstatic void got_it(imm_struct *dev) 71113658Sdeischen{ 72113658Sdeischen dev->base = dev->dev->port->base; 73113658Sdeischen if (dev->cur_cmd) 74113658Sdeischen imm_scsi_pointer(dev->cur_cmd)->phase = 1; 75118676Sdavidxu else 76118676Sdavidxu wake_up(dev->waiting); 77118676Sdavidxu} 78118676Sdavidxu 79118676Sdavidxustatic void imm_wakeup(void *ref) 80118676Sdavidxu{ 81133563Sdeischen imm_struct *dev = (imm_struct *) ref; 82133563Sdeischen unsigned long flags; 83118676Sdavidxu 84113658Sdeischen spin_lock_irqsave(&arbitration_lock, flags); 85118510Sdeischen if (dev->wanted) { 8613546Sjulian if (parport_claim(dev->dev) == 0) { 87113658Sdeischen got_it(dev); 8848046Sjb dev->wanted = 0; 89113658Sdeischen } 90113658Sdeischen } 91113658Sdeischen spin_unlock_irqrestore(&arbitration_lock, flags); 92113658Sdeischen} 93113658Sdeischen 94113658Sdeischenstatic int imm_pb_claim(imm_struct *dev) 95113658Sdeischen{ 96113658Sdeischen unsigned long flags; 97113658Sdeischen int res = 1; 98113658Sdeischen spin_lock_irqsave(&arbitration_lock, flags); 99113658Sdeischen if (parport_claim(dev->dev) == 0) { 100132120Sdavidxu got_it(dev); 101132120Sdavidxu res = 0; 102132120Sdavidxu } 103132120Sdavidxu dev->wanted = res; 104113658Sdeischen spin_unlock_irqrestore(&arbitration_lock, flags); 105114187Sdeischen return res; 106113658Sdeischen} 107120896Sdavidxu 108120896Sdavidxustatic void imm_pb_dismiss(imm_struct *dev) 109120896Sdavidxu{ 110120896Sdavidxu unsigned long flags; 111120896Sdavidxu int wanted; 112120896Sdavidxu spin_lock_irqsave(&arbitration_lock, flags); 113120896Sdavidxu wanted = dev->wanted; 114120896Sdavidxu dev->wanted = 0; 115120896Sdavidxu spin_unlock_irqrestore(&arbitration_lock, flags); 116120896Sdavidxu if (!wanted) 117120896Sdavidxu parport_release(dev->dev); 118120896Sdavidxu} 119113658Sdeischen 120113658Sdeischenstatic inline void imm_pb_release(imm_struct *dev) 121113658Sdeischen{ 122113658Sdeischen parport_release(dev->dev); 123113658Sdeischen} 124113658Sdeischen 125113658Sdeischen/* This is to give the imm driver a way to modify the timings (and other 126113658Sdeischen * parameters) by writing to the /proc/scsi/imm/0 file. 127113658Sdeischen * Very simple method really... (Too simple, no error checking :( ) 128113661Sdeischen * Reason: Kernel hackers HATE having to unload and reload modules for 129113658Sdeischen * testing... 130113658Sdeischen * Also gives a method to use a script to obtain optimum timings (TODO) 131113658Sdeischen */ 132113658Sdeischenstatic int imm_write_info(struct Scsi_Host *host, char *buffer, int length) 133113658Sdeischen{ 134113658Sdeischen imm_struct *dev = imm_dev(host); 135113658Sdeischen 136113658Sdeischen if ((length > 5) && (strncmp(buffer, "mode=", 5) == 0)) { 137113658Sdeischen dev->mode = simple_strtoul(buffer + 5, NULL, 0); 138115278Sdeischen return length; 139113658Sdeischen } 140117706Sdavidxu printk("imm /proc: invalid variable\n"); 141117706Sdavidxu return -EINVAL; 142117706Sdavidxu} 143117706Sdavidxu 144115278Sdeischenstatic int imm_show_info(struct seq_file *m, struct Scsi_Host *host) 145136846Sdavidxu{ 146136846Sdavidxu imm_struct *dev = imm_dev(host); 147136846Sdavidxu 148115173Sdeischen seq_printf(m, "Version : %s\n", IMM_VERSION); 149115173Sdeischen seq_printf(m, "Parport : %s\n", dev->dev->port->name); 150115173Sdeischen seq_printf(m, "Mode : %s\n", IMM_MODE_STRING[dev->mode]); 151113658Sdeischen return 0; 152113658Sdeischen} 153113658Sdeischen 154117706Sdavidxu#if IMM_DEBUG > 0 155118510Sdeischen#define imm_fail(x,y) printk("imm: imm_fail(%i) from %s at line %d\n",\ 156118510Sdeischen y, __func__, __LINE__); imm_fail_func(x,y); 157113658Sdeischenstatic inline void 158117706Sdavidxuimm_fail_func(imm_struct *dev, int error_code) 159113661Sdeischen#else 160118676Sdavidxustatic inline void 161113870Sdeischenimm_fail(imm_struct *dev, int error_code) 162113658Sdeischen#endif 163113786Sdeischen{ 164118676Sdavidxu /* If we fail a device then we trash status / message bytes */ 165113658Sdeischen if (dev->cur_cmd) { 166114187Sdeischen dev->cur_cmd->result = error_code << 16; 167117907Sdeischen dev->failed = 1; 168113658Sdeischen } 169115278Sdeischen} 170116977Sdavidxu 171139023Sdeischen/* 172113658Sdeischen * Wait for the high bit to be set. 173115278Sdeischen * 174136846Sdavidxu * In principle, this could be tied to an interrupt, but the adapter 175118676Sdavidxu * doesn't appear to be designed to support interrupts. We spin on 176118676Sdavidxu * the 0x80 ready bit. 177118676Sdavidxu */ 178113658Sdeischenstatic unsigned char imm_wait(imm_struct *dev) 179117715Sdeischen{ 180117715Sdeischen int k; 181117715Sdeischen unsigned short ppb = dev->base; 182117715Sdeischen unsigned char r; 183117715Sdeischen 184117715Sdeischen w_ctr(ppb, 0x0c); 185118510Sdeischen 186118510Sdeischen k = IMM_SPIN_TMO; 187117715Sdeischen do { 188117715Sdeischen r = r_str(ppb); 189117715Sdeischen k--; 190117715Sdeischen udelay(1); 191118510Sdeischen } 192118510Sdeischen while (!(r & 0x80) && (k)); 193117715Sdeischen 194117715Sdeischen /* 195113658Sdeischen * STR register (LPT base+1) to SCSI mapping: 196113658Sdeischen * 197113658Sdeischen * STR imm imm 198113658Sdeischen * =================================== 199116977Sdavidxu * 0x80 S_REQ S_REQ 200116977Sdavidxu * 0x40 !S_BSY (????) 201116977Sdavidxu * 0x20 !S_CD !S_CD 202116977Sdavidxu * 0x10 !S_IO !S_IO 203116977Sdavidxu * 0x08 (????) !S_BSY 204116977Sdavidxu * 205116977Sdavidxu * imm imm meaning 206123668Sdavidxu * ================================== 207123668Sdavidxu * 0xf0 0xb8 Bit mask 208113658Sdeischen * 0xc0 0x88 ZIP wants more data 20913546Sjulian * 0xd0 0x98 ZIP wants to send more data 210113658Sdeischen * 0xe0 0xa8 ZIP is expecting SCSI command data 21113546Sjulian * 0xf0 0xb8 end of transfer, ZIP is sending status 212116977Sdavidxu */ 213115278Sdeischen w_ctr(ppb, 0x04); 214115278Sdeischen if (k) 215115278Sdeischen return (r & 0xb8); 21671581Sdeischen 217150499Sbrian /* Counter expired - Time out occurred */ 218150499Sbrian imm_fail(dev, DID_TIME_OUT); 219118747Sdavidxu printk("imm timeout in imm_wait\n"); 220118747Sdavidxu return 0; /* command timed out */ 221118747Sdavidxu} 222118747Sdavidxu 223118747Sdavidxustatic int imm_negotiate(imm_struct * tmp) 22467097Sdeischen{ 225118747Sdavidxu /* 226118747Sdavidxu * The following is supposedly the IEEE 1284-1994 negotiate 227118747Sdavidxu * sequence. I have yet to obtain a copy of the above standard 228118747Sdavidxu * so this is a bit of a guess... 229132120Sdavidxu * 23013546Sjulian * A fair chunk of this is based on the Linux parport implementation 231106191Smini * of IEEE 1284. 232113658Sdeischen * 233113658Sdeischen * Return 0 if data available 234106191Smini * 1 if no data available 235115278Sdeischen */ 236115278Sdeischen 237106191Smini unsigned short base = tmp->base; 238113658Sdeischen unsigned char a, mode; 239113658Sdeischen 240113658Sdeischen switch (tmp->mode) { 241106191Smini case IMM_NIBBLE: 242113658Sdeischen mode = 0x00; 243113658Sdeischen break; 244113658Sdeischen case IMM_PS2: 245113658Sdeischen mode = 0x01; 246113658Sdeischen break; 247113658Sdeischen default: 248136846Sdavidxu return 0; 249106191Smini } 250106191Smini 251106191Smini w_ctr(base, 0x04); 252113658Sdeischen udelay(5); 253113658Sdeischen w_dtr(base, mode); 254115278Sdeischen udelay(100); 255116977Sdavidxu w_ctr(base, 0x06); 256113658Sdeischen udelay(5); 257150499Sbrian a = (r_str(base) & 0x20) ? 0 : 1; 258150499Sbrian udelay(5); 259113658Sdeischen w_ctr(base, 0x07); 260113658Sdeischen udelay(5); 261113658Sdeischen w_ctr(base, 0x06); 262120074Sdavidxu 263113658Sdeischen if (a) { 264113658Sdeischen printk 265113658Sdeischen ("IMM: IEEE1284 negotiate indicates no data available.\n"); 266113658Sdeischen imm_fail(tmp, DID_ERROR); 267115278Sdeischen } 268113658Sdeischen return a; 269120074Sdavidxu} 270113658Sdeischen 271113658Sdeischen/* 272113658Sdeischen * Clear EPP timeout bit. 273113658Sdeischen */ 274113658Sdeischenstatic inline void epp_reset(unsigned short ppb) 275113658Sdeischen{ 276120074Sdavidxu int i; 277113658Sdeischen 278113658Sdeischen i = r_str(ppb); 279113658Sdeischen w_str(ppb, i); 280113658Sdeischen w_str(ppb, i & 0xfe); 281115278Sdeischen} 282113658Sdeischen 283120074Sdavidxu/* 284113658Sdeischen * Wait for empty ECP fifo (if we are in ECP fifo mode only) 285113658Sdeischen */ 286113658Sdeischenstatic inline void ecp_sync(imm_struct *dev) 287113658Sdeischen{ 288113658Sdeischen int i, ppb_hi = dev->base_hi; 289113658Sdeischen 290136846Sdavidxu if (ppb_hi == 0) 291113658Sdeischen return; 292113658Sdeischen 293113658Sdeischen if ((r_ecr(ppb_hi) & 0xe0) == 0x60) { /* mode 011 == ECP fifo mode */ 294113658Sdeischen for (i = 0; i < 100; i++) { 295113658Sdeischen if (r_ecr(ppb_hi) & 0x01) 296113661Sdeischen return; 297136846Sdavidxu udelay(5); 298113658Sdeischen } 299113661Sdeischen printk("imm: ECP sync failed as data still present in FIFO.\n"); 300113661Sdeischen } 301113658Sdeischen} 302113658Sdeischen 303113658Sdeischenstatic int imm_byte_out(unsigned short base, const char *buffer, int len) 304113658Sdeischen{ 305113658Sdeischen int i; 306113658Sdeischen 307113658Sdeischen w_ctr(base, 0x4); /* apparently a sane mode */ 308113658Sdeischen for (i = len >> 1; i; i--) { 309113658Sdeischen w_dtr(base, *buffer++); 310113658Sdeischen w_ctr(base, 0x5); /* Drop STROBE low */ 311113658Sdeischen w_dtr(base, *buffer++); 312113658Sdeischen w_ctr(base, 0x0); /* STROBE high + INIT low */ 313106191Smini } 314113658Sdeischen w_ctr(base, 0x4); /* apparently a sane mode */ 315113658Sdeischen return 1; /* All went well - we hope! */ 316106191Smini} 317113658Sdeischen 318113658Sdeischenstatic int imm_nibble_in(unsigned short base, char *buffer, int len) 319113658Sdeischen{ 320150499Sbrian unsigned char l; 321150499Sbrian int i; 322150499Sbrian 323113658Sdeischen /* 324113658Sdeischen * The following is based on documented timing signals 325113658Sdeischen */ 326113658Sdeischen w_ctr(base, 0x4); 327113658Sdeischen for (i = len; i; i--) { 328113658Sdeischen w_ctr(base, 0x6); 329113658Sdeischen l = (r_str(base) & 0xf0) >> 4; 330113658Sdeischen w_ctr(base, 0x5); 331113658Sdeischen *buffer++ = (r_str(base) & 0xf0) | l; 332113658Sdeischen w_ctr(base, 0x4); 333113658Sdeischen } 334116977Sdavidxu return 1; /* All went well - we hope! */ 335122075Sdeischen} 336122075Sdeischen 337122075Sdeischenstatic int imm_byte_in(unsigned short base, char *buffer, int len) 338122075Sdeischen{ 339122075Sdeischen int i; 340122075Sdeischen 341122075Sdeischen /* 342122075Sdeischen * The following is based on documented timing signals 343122075Sdeischen */ 344122075Sdeischen w_ctr(base, 0x4); 345122075Sdeischen for (i = len; i; i--) { 346122075Sdeischen w_ctr(base, 0x26); 347122075Sdeischen *buffer++ = r_dtr(base); 348122075Sdeischen w_ctr(base, 0x25); 349118747Sdavidxu } 350118747Sdavidxu return 1; /* All went well - we hope! */ 351117345Sdavidxu} 352118747Sdavidxu 353118747Sdavidxustatic int imm_out(imm_struct *dev, char *buffer, int len) 354128041Sdeischen{ 355128041Sdeischen unsigned short ppb = dev->base; 356128041Sdeischen int r = imm_wait(dev); 357139023Sdeischen 358139023Sdeischen /* 359139023Sdeischen * Make sure that: 360118747Sdavidxu * a) the SCSI bus is BUSY (device still listening) 361118747Sdavidxu * b) the device is listening 362118747Sdavidxu */ 363118747Sdavidxu if ((r & 0x18) != 0x08) { 364118747Sdavidxu imm_fail(dev, DID_ERROR); 365132120Sdavidxu printk("IMM: returned SCSI status %2x\n", r); 366116977Sdavidxu return 0; 367113658Sdeischen } 368113658Sdeischen switch (dev->mode) { 369113658Sdeischen case IMM_EPP_32: 370113658Sdeischen case IMM_EPP_16: 371113658Sdeischen case IMM_EPP_8: 372113658Sdeischen epp_reset(ppb); 373113658Sdeischen w_ctr(ppb, 0x4); 374113658Sdeischen if (dev->mode == IMM_EPP_32 && !(((long) buffer | len) & 0x03)) 375113658Sdeischen outsl(ppb + 4, buffer, len >> 2); 376113658Sdeischen else if (dev->mode == IMM_EPP_16 && !(((long) buffer | len) & 0x01)) 377113658Sdeischen outsw(ppb + 4, buffer, len >> 1); 378113658Sdeischen else 379113658Sdeischen outsb(ppb + 4, buffer, len); 380113658Sdeischen w_ctr(ppb, 0xc); 381113658Sdeischen r = !(r_str(ppb) & 0x01); 382113661Sdeischen w_ctr(ppb, 0xc); 383113658Sdeischen ecp_sync(dev); 384113658Sdeischen break; 385113658Sdeischen 386113658Sdeischen case IMM_NIBBLE: 387113658Sdeischen case IMM_PS2: 388113658Sdeischen /* 8 bit output, with a loop */ 389113658Sdeischen r = imm_byte_out(ppb, buffer, len); 390113658Sdeischen break; 391113658Sdeischen 392136846Sdavidxu default: 393113658Sdeischen printk("IMM: bug in imm_out()\n"); 394113658Sdeischen r = 0; 395113661Sdeischen } 396113658Sdeischen return r; 397113658Sdeischen} 398113658Sdeischen 399113658Sdeischenstatic int imm_in(imm_struct *dev, char *buffer, int len) 400113658Sdeischen{ 401113658Sdeischen unsigned short ppb = dev->base; 402113658Sdeischen int r = imm_wait(dev); 403113658Sdeischen 404113786Sdeischen /* 405113658Sdeischen * Make sure that: 406113658Sdeischen * a) the SCSI bus is BUSY (device still listening) 407118747Sdavidxu * b) the device is sending data 408118747Sdavidxu */ 409113658Sdeischen if ((r & 0x18) != 0x18) { 410119063Sdavidxu imm_fail(dev, DID_ERROR); 411119063Sdavidxu return 0; 412119063Sdavidxu } 413106191Smini switch (dev->mode) { 414113658Sdeischen case IMM_NIBBLE: 415113658Sdeischen /* 4 bit input, with a loop */ 416113658Sdeischen r = imm_nibble_in(ppb, buffer, len); 417113786Sdeischen w_ctr(ppb, 0xc); 418117706Sdavidxu break; 419133563Sdeischen 420133269Sdeischen case IMM_PS2: 421133269Sdeischen /* 8 bit input, with a loop */ 422133269Sdeischen r = imm_byte_in(ppb, buffer, len); 423133269Sdeischen w_ctr(ppb, 0xc); 424133269Sdeischen break; 425133269Sdeischen 426133269Sdeischen case IMM_EPP_32: 427133269Sdeischen case IMM_EPP_16: 428133269Sdeischen case IMM_EPP_8: 429133269Sdeischen epp_reset(ppb); 430133269Sdeischen w_ctr(ppb, 0x24); 431133269Sdeischen if (dev->mode == IMM_EPP_32 && !(((long) buffer | len) & 0x03)) 432133269Sdeischen insw(ppb + 4, buffer, len >> 2); 433117706Sdavidxu else if (dev->mode == IMM_EPP_16 && !(((long) buffer | len) & 0x01)) 434118747Sdavidxu insl(ppb + 4, buffer, len >> 1); 435118747Sdavidxu else 436118747Sdavidxu insb(ppb + 4, buffer, len); 437118747Sdavidxu w_ctr(ppb, 0x2c); 438118747Sdavidxu r = !(r_str(ppb) & 0x01); 439118747Sdavidxu w_ctr(ppb, 0x2c); 440118747Sdavidxu ecp_sync(dev); 441118510Sdeischen break; 442113786Sdeischen 443114187Sdeischen default: 444116977Sdavidxu printk("IMM: bug in imm_ins()\n"); 445113786Sdeischen r = 0; 446113786Sdeischen break; 447132120Sdavidxu } 448132120Sdavidxu return r; 449132120Sdavidxu} 450117706Sdavidxu 451135714Sssouhlalstatic int imm_cpp(unsigned short ppb, unsigned char b) 452133563Sdeischen{ 453133269Sdeischen /* 454133269Sdeischen * Comments on udelay values refer to the 455133269Sdeischen * Command Packet Protocol (CPP) timing diagram. 456133269Sdeischen */ 457133269Sdeischen 458133269Sdeischen unsigned char s1, s2, s3; 459135714Sssouhlal w_ctr(ppb, 0x0c); 460135714Sssouhlal udelay(2); /* 1 usec - infinite */ 461133269Sdeischen w_dtr(ppb, 0xaa); 462133269Sdeischen udelay(10); /* 7 usec - infinite */ 463113658Sdeischen w_dtr(ppb, 0x55); 464113786Sdeischen udelay(10); /* 7 usec - infinite */ 465113658Sdeischen w_dtr(ppb, 0x00); 466113658Sdeischen udelay(10); /* 7 usec - infinite */ 467113658Sdeischen w_dtr(ppb, 0xff); 468113658Sdeischen udelay(10); /* 7 usec - infinite */ 469113658Sdeischen s1 = r_str(ppb) & 0xb8; 470113658Sdeischen w_dtr(ppb, 0x87); 471113658Sdeischen udelay(10); /* 7 usec - infinite */ 472113658Sdeischen s2 = r_str(ppb) & 0xb8; 473113658Sdeischen w_dtr(ppb, 0x78); 474113658Sdeischen udelay(10); /* 7 usec - infinite */ 475113658Sdeischen s3 = r_str(ppb) & 0x38; 476113658Sdeischen /* 477113658Sdeischen * Values for b are: 478113658Sdeischen * 0000 00aa Assign address aa to current device 479113658Sdeischen * 0010 00aa Select device aa in EPP Winbond mode 480113658Sdeischen * 0010 10aa Select device aa in EPP mode 481113658Sdeischen * 0011 xxxx Deselect all devices 482113658Sdeischen * 0110 00aa Test device aa 483113658Sdeischen * 1101 00aa Select device aa in ECP mode 484113786Sdeischen * 1110 00aa Select device aa in Compatible mode 485113658Sdeischen */ 486118510Sdeischen w_dtr(ppb, b); 487113786Sdeischen udelay(2); /* 1 usec - infinite */ 488113658Sdeischen w_ctr(ppb, 0x0c); 489113658Sdeischen udelay(10); /* 7 usec - infinite */ 490113658Sdeischen w_ctr(ppb, 0x0d); 491113658Sdeischen udelay(2); /* 1 usec - infinite */ 492113658Sdeischen w_ctr(ppb, 0x0c); 493115278Sdeischen udelay(10); /* 7 usec - infinite */ 494113658Sdeischen w_dtr(ppb, 0xff); 495113658Sdeischen udelay(10); /* 7 usec - infinite */ 496113658Sdeischen 497113658Sdeischen /* 498118510Sdeischen * The following table is electrical pin values. 499118510Sdeischen * (BSY is inverted at the CTR register) 500118510Sdeischen * 501113786Sdeischen * BSY ACK POut SEL Fault 502118510Sdeischen * S1 0 X 1 1 1 503113658Sdeischen * S2 1 X 0 1 1 504113658Sdeischen * S3 L X 1 1 S 505113658Sdeischen * 506113658Sdeischen * L => Last device in chain 507113658Sdeischen * S => Selected 508113658Sdeischen * 509113658Sdeischen * Observered values for S1,S2,S3 are: 510113658Sdeischen * Disconnect => f8/58/78 511115080Sdeischen * Connect => f8/58/70 512113658Sdeischen */ 513113658Sdeischen if ((s1 == 0xb8) && (s2 == 0x18) && (s3 == 0x30)) 514113658Sdeischen return 1; /* Connected */ 515113658Sdeischen if ((s1 == 0xb8) && (s2 == 0x18) && (s3 == 0x38)) 516113658Sdeischen return 0; /* Disconnected */ 517113658Sdeischen 518115080Sdeischen return -1; /* No device present */ 519118510Sdeischen} 520115080Sdeischen 521113658Sdeischenstatic inline int imm_connect(imm_struct *dev, int flag) 522113658Sdeischen{ 523115080Sdeischen unsigned short ppb = dev->base; 524115080Sdeischen 525115080Sdeischen imm_cpp(ppb, 0xe0); /* Select device 0 in compatible mode */ 526113658Sdeischen imm_cpp(ppb, 0x30); /* Disconnect all devices */ 527115080Sdeischen 528113658Sdeischen if ((dev->mode == IMM_EPP_8) || 529113658Sdeischen (dev->mode == IMM_EPP_16) || 530113658Sdeischen (dev->mode == IMM_EPP_32)) 531113658Sdeischen return imm_cpp(ppb, 0x28); /* Select device 0 in EPP mode */ 532113658Sdeischen return imm_cpp(ppb, 0xe0); /* Select device 0 in compatible mode */ 533113658Sdeischen} 534113658Sdeischen 535113658Sdeischenstatic void imm_disconnect(imm_struct *dev) 536113658Sdeischen{ 537113658Sdeischen imm_cpp(dev->base, 0x30); /* Disconnect all devices */ 538113658Sdeischen} 539113658Sdeischen 540113658Sdeischenstatic int imm_select(imm_struct *dev, int target) 541115080Sdeischen{ 542117907Sdeischen int k; 543115080Sdeischen unsigned short ppb = dev->base; 544117907Sdeischen 545115278Sdeischen /* 546113658Sdeischen * Firstly we want to make sure there is nothing 547106191Smini * holding onto the SCSI bus. 548113658Sdeischen */ 549113658Sdeischen w_ctr(ppb, 0xc); 550113658Sdeischen 551113658Sdeischen k = IMM_SELECT_TMO; 552113658Sdeischen do { 553117907Sdeischen k--; 554113658Sdeischen } while ((r_str(ppb) & 0x08) && (k)); 555113658Sdeischen 556113658Sdeischen if (!k) 557113658Sdeischen return 0; 558115080Sdeischen 559115080Sdeischen /* 560117907Sdeischen * Now assert the SCSI ID (HOST and TARGET) on the data bus 561115080Sdeischen */ 562117907Sdeischen w_ctr(ppb, 0x4); 563117907Sdeischen w_dtr(ppb, 0x80 | (1 << target)); 564113658Sdeischen udelay(1); 565113658Sdeischen 566113658Sdeischen /* 567113658Sdeischen * Deassert SELIN first followed by STROBE 568113658Sdeischen */ 569113658Sdeischen w_ctr(ppb, 0xc); 570113658Sdeischen w_ctr(ppb, 0xd); 571118510Sdeischen 572113658Sdeischen /* 573113658Sdeischen * ACK should drop low while SELIN is deasserted. 574113658Sdeischen * FAULT should drop low when the SCSI device latches the bus. 575113658Sdeischen */ 576113658Sdeischen k = IMM_SELECT_TMO; 577113658Sdeischen do { 578113658Sdeischen k--; 579113658Sdeischen } 580118510Sdeischen while (!(r_str(ppb) & 0x08) && (k)); 581113658Sdeischen 582113658Sdeischen /* 583113658Sdeischen * Place the interface back into a sane state (status mode) 584113658Sdeischen */ 585113942Sdeischen w_ctr(ppb, 0xc); 586113942Sdeischen return (k) ? 1 : 0; 587113942Sdeischen} 588118510Sdeischen 589113942Sdeischenstatic int imm_init(imm_struct *dev) 590113942Sdeischen{ 591113658Sdeischen bool autodetect = dev->mode == IMM_AUTODETECT; 592113658Sdeischen 593113658Sdeischen if (autodetect) { 594113658Sdeischen int modes = dev->dev->port->modes; 595113658Sdeischen 596113658Sdeischen /* Mode detection works up the chain of speed 597113658Sdeischen * This avoids a nasty if-then-else-if-... tree 598113658Sdeischen */ 599113658Sdeischen dev->mode = IMM_NIBBLE; 600113658Sdeischen 601113658Sdeischen if (modes & PARPORT_MODE_TRISTATE) 602113658Sdeischen dev->mode = IMM_PS2; 603113658Sdeischen } 604115080Sdeischen 605115080Sdeischen if (imm_connect(dev, 0) != 1) 606115080Sdeischen return -EIO; 607115080Sdeischen imm_reset_pulse(dev->base); 608115080Sdeischen mdelay(1); /* Delay to allow devices to settle */ 609115080Sdeischen imm_disconnect(dev); 610115080Sdeischen mdelay(1); /* Another delay to allow devices to settle */ 611115080Sdeischen 612115080Sdeischen return device_check(dev, autodetect); 613115080Sdeischen} 614115080Sdeischen 615113658Sdeischenstatic inline int imm_send_command(struct scsi_cmnd *cmd) 616113658Sdeischen{ 617113658Sdeischen imm_struct *dev = imm_dev(cmd->device->host); 618113658Sdeischen int k; 619113658Sdeischen 620113658Sdeischen /* NOTE: IMM uses byte pairs */ 621115080Sdeischen for (k = 0; k < cmd->cmd_len; k += 2) 622113658Sdeischen if (!imm_out(dev, &cmd->cmnd[k], 2)) 623113658Sdeischen return 0; 624115080Sdeischen return 1; 625123048Sdavidxu} 626113658Sdeischen 627113658Sdeischen/* 628139023Sdeischen * The bulk flag enables some optimisations in the data transfer loops, 629113658Sdeischen * it should be true for any command that transfers data in integral 630113658Sdeischen * numbers of sectors. 631113658Sdeischen * 632113658Sdeischen * The driver appears to remain stable if we speed up the parallel port 633115080Sdeischen * i/o in this function, but not elsewhere. 634115080Sdeischen */ 635115080Sdeischenstatic int imm_completion(struct scsi_cmnd *const cmd) 636117706Sdavidxu{ 637118510Sdeischen /* Return codes: 638123048Sdavidxu * -1 Error 639132120Sdavidxu * 0 Told to schedule 640132120Sdavidxu * 1 Finished data transfer 641132120Sdavidxu */ 642132120Sdavidxu struct scsi_pointer *scsi_pointer = imm_scsi_pointer(cmd); 643132120Sdavidxu imm_struct *dev = imm_dev(cmd->device->host); 644132120Sdavidxu unsigned short ppb = dev->base; 645132120Sdavidxu unsigned long start_jiffies = jiffies; 646132120Sdavidxu 647132120Sdavidxu unsigned char r, v; 648132120Sdavidxu int fast, bulk, status; 649132120Sdavidxu 650132120Sdavidxu v = cmd->cmnd[0]; 651132120Sdavidxu bulk = ((v == READ_6) || 652123312Sdavidxu (v == READ_10) || (v == WRITE_6) || (v == WRITE_10)); 653118510Sdeischen 654116977Sdavidxu /* 655123048Sdavidxu * We only get here if the drive is ready to comunicate, 656123048Sdavidxu * hence no need for a full imm_wait. 657123048Sdavidxu */ 658123048Sdavidxu w_ctr(ppb, 0x0c); 659123048Sdavidxu r = (r_str(ppb) & 0xb8); 660123048Sdavidxu 661139023Sdeischen /* 662115080Sdeischen * while (device is not ready to send status byte) 663123048Sdavidxu * loop; 664123048Sdavidxu */ 665123048Sdavidxu while (r != (unsigned char) 0xb8) { 666115080Sdeischen /* 667113658Sdeischen * If we have been running for more than a full timer tick 668113658Sdeischen * then take a rest. 669113658Sdeischen */ 670139023Sdeischen if (time_after(jiffies, start_jiffies + 1)) 671123048Sdavidxu return 0; 672116977Sdavidxu 673123048Sdavidxu /* 674116977Sdavidxu * FAIL if: 675116977Sdavidxu * a) Drive status is screwy (!ready && !present) 676116977Sdavidxu * b) Drive is requesting/sending more data than expected 677139023Sdeischen */ 678116977Sdavidxu if ((r & 0x88) != 0x88 || scsi_pointer->this_residual <= 0) { 679113658Sdeischen imm_fail(dev, DID_ERROR); 680115080Sdeischen return -1; /* ERROR_RETURN */ 681113658Sdeischen } 682113658Sdeischen /* determine if we should use burst I/O */ 683113658Sdeischen if (dev->rd == 0) { 684113658Sdeischen fast = bulk && scsi_pointer->this_residual >= 685113658Sdeischen IMM_BURST_SIZE ? IMM_BURST_SIZE : 2; 686113658Sdeischen status = imm_out(dev, scsi_pointer->ptr, fast); 687113658Sdeischen } else { 688113658Sdeischen fast = bulk && scsi_pointer->this_residual >= 689113658Sdeischen IMM_BURST_SIZE ? IMM_BURST_SIZE : 1; 690117706Sdavidxu status = imm_in(dev, scsi_pointer->ptr, fast); 691113658Sdeischen } 692118510Sdeischen 693113658Sdeischen scsi_pointer->ptr += fast; 694118510Sdeischen scsi_pointer->this_residual -= fast; 695118510Sdeischen 696113658Sdeischen if (!status) { 697117706Sdavidxu imm_fail(dev, DID_BUS_BUSY); 698117706Sdavidxu return -1; /* ERROR_RETURN */ 699113658Sdeischen } 700118510Sdeischen if (scsi_pointer->buffer && !scsi_pointer->this_residual) { 701118510Sdeischen /* if scatter/gather, advance to the next segment */ 702118510Sdeischen if (scsi_pointer->buffers_residual--) { 703123312Sdavidxu scsi_pointer->buffer = 704117706Sdavidxu sg_next(scsi_pointer->buffer); 705118510Sdeischen scsi_pointer->this_residual = 706118510Sdeischen scsi_pointer->buffer->length; 707117706Sdavidxu scsi_pointer->ptr = sg_virt(scsi_pointer->buffer); 708117706Sdavidxu 709117706Sdavidxu /* 710132120Sdavidxu * Make sure that we transfer even number of bytes 711117706Sdavidxu * otherwise it makes imm_byte_out() messy. 712117706Sdavidxu */ 713117706Sdavidxu if (scsi_pointer->this_residual & 0x01) 714117706Sdavidxu scsi_pointer->this_residual++; 715117706Sdavidxu } 716117706Sdavidxu } 717117706Sdavidxu /* Now check to see if the drive is ready to comunicate */ 718118510Sdeischen w_ctr(ppb, 0x0c); 719118850Sdavidxu r = (r_str(ppb) & 0xb8); 720118850Sdavidxu 721118850Sdavidxu /* If not, drop back down to the scheduler and wait a timer tick */ 722118850Sdavidxu if (!(r & 0x80)) 723118850Sdavidxu return 0; 724118850Sdavidxu } 725118850Sdavidxu return 1; /* FINISH_RETURN */ 726118850Sdavidxu} 727106191Smini 728113786Sdeischen/* 729113786Sdeischen * Since the IMM itself doesn't generate interrupts, we use 730113658Sdeischen * the scheduler's task queue to generate a stream of call-backs and 731113786Sdeischen * complete the request when the drive is ready. 732113786Sdeischen */ 733113786Sdeischenstatic void imm_interrupt(struct work_struct *work) 734113786Sdeischen{ 735113786Sdeischen imm_struct *dev = container_of(work, imm_struct, imm_tq.work); 736113786Sdeischen struct scsi_cmnd *cmd = dev->cur_cmd; 737117706Sdavidxu struct Scsi_Host *host = cmd->device->host; 738117706Sdavidxu unsigned long flags; 739113786Sdeischen 740113786Sdeischen if (imm_engine(dev, cmd)) { 741113786Sdeischen schedule_delayed_work(&dev->imm_tq, 1); 742113786Sdeischen return; 743113786Sdeischen } 744113786Sdeischen /* Command must of completed hence it is safe to let go... */ 745113786Sdeischen#if IMM_DEBUG > 0 746120896Sdavidxu switch ((cmd->result >> 16) & 0xff) { 747113786Sdeischen case DID_OK: 748120896Sdavidxu break; 749120896Sdavidxu case DID_NO_CONNECT: 750120896Sdavidxu printk("imm: no device at SCSI ID %i\n", cmd->device->id); 751120896Sdavidxu break; 752120896Sdavidxu case DID_BUS_BUSY: 753113786Sdeischen printk("imm: BUS BUSY - EPP timeout detected\n"); 754113786Sdeischen break; 755113786Sdeischen case DID_TIME_OUT: 756117706Sdavidxu printk("imm: unknown timeout\n"); 757117706Sdavidxu break; 758117706Sdavidxu case DID_ABORT: 759117706Sdavidxu printk("imm: told to abort\n"); 760117706Sdavidxu break; 761113786Sdeischen case DID_PARITY: 762117706Sdavidxu printk("imm: parity error (???)\n"); 763113786Sdeischen break; 764113786Sdeischen case DID_ERROR: 765113786Sdeischen printk("imm: internal driver error\n"); 766120896Sdavidxu break; 767120896Sdavidxu case DID_RESET: 768120896Sdavidxu printk("imm: told to reset device\n"); 769120896Sdavidxu break; 770120896Sdavidxu case DID_BAD_INTR: 771120896Sdavidxu printk("imm: bad interrupt (???)\n"); 772120896Sdavidxu break; 773120896Sdavidxu default: 774120896Sdavidxu printk("imm: bad return code (%02x)\n", 775120896Sdavidxu (cmd->result >> 16) & 0xff); 776120896Sdavidxu } 777120896Sdavidxu#endif 778120896Sdavidxu 779120896Sdavidxu if (imm_scsi_pointer(cmd)->phase > 1) 780120896Sdavidxu imm_disconnect(dev); 781120896Sdavidxu 782120896Sdavidxu imm_pb_dismiss(dev); 783120896Sdavidxu 784120896Sdavidxu spin_lock_irqsave(host->host_lock, flags); 785120896Sdavidxu dev->cur_cmd = NULL; 786120896Sdavidxu scsi_done(cmd); 787120896Sdavidxu spin_unlock_irqrestore(host->host_lock, flags); 788120896Sdavidxu return; 789120896Sdavidxu} 790120896Sdavidxu 791120896Sdavidxustatic int imm_engine(imm_struct *dev, struct scsi_cmnd *const cmd) 792120896Sdavidxu{ 793120896Sdavidxu struct scsi_pointer *scsi_pointer = imm_scsi_pointer(cmd); 794120896Sdavidxu unsigned short ppb = dev->base; 795120896Sdavidxu unsigned char l = 0, h = 0; 796120896Sdavidxu int retv, x; 797120896Sdavidxu 798120896Sdavidxu /* First check for any errors that may have occurred 799120896Sdavidxu * Here we check for internal errors 800117706Sdavidxu */ 801120896Sdavidxu if (dev->failed) 802120896Sdavidxu return 0; 803117706Sdavidxu 804120896Sdavidxu switch (scsi_pointer->phase) { 805120896Sdavidxu case 0: /* Phase 0 - Waiting for parport */ 806120896Sdavidxu if (time_after(jiffies, dev->jstart + HZ)) { 807120896Sdavidxu /* 808120896Sdavidxu * We waited more than a second 809117706Sdavidxu * for parport to call us 810117706Sdavidxu */ 811117706Sdavidxu imm_fail(dev, DID_BUS_BUSY); 812120896Sdavidxu return 0; 813120896Sdavidxu } 814120896Sdavidxu return 1; /* wait until imm_wakeup claims parport */ 815120896Sdavidxu 816120896Sdavidxu case 1: /* Phase 1 - Connected */ 817120896Sdavidxu imm_connect(dev, CONNECT_EPP_MAYBE); 818120896Sdavidxu scsi_pointer->phase++; 819120896Sdavidxu fallthrough; 820120896Sdavidxu 821113786Sdeischen case 2: /* Phase 2 - We are now talking to the scsi bus */ 822113658Sdeischen if (!imm_select(dev, scmd_id(cmd))) { 823113786Sdeischen imm_fail(dev, DID_NO_CONNECT); 824113786Sdeischen return 0; 825113658Sdeischen } 826117706Sdavidxu scsi_pointer->phase++; 827117706Sdavidxu fallthrough; 828113786Sdeischen 829120896Sdavidxu case 3: /* Phase 3 - Ready to accept a command */ 830120896Sdavidxu w_ctr(ppb, 0x0c); 831120896Sdavidxu if (!(r_str(ppb) & 0x80)) 832120896Sdavidxu return 1; 833113786Sdeischen 834117706Sdavidxu if (!imm_send_command(cmd)) 835113786Sdeischen return 0; 836117706Sdavidxu scsi_pointer->phase++; 837117706Sdavidxu fallthrough; 838117706Sdavidxu 839117706Sdavidxu case 4: /* Phase 4 - Setup scatter/gather buffers */ 840117706Sdavidxu if (scsi_bufflen(cmd)) { 841117706Sdavidxu scsi_pointer->buffer = scsi_sglist(cmd); 842117706Sdavidxu scsi_pointer->this_residual = scsi_pointer->buffer->length; 843117706Sdavidxu scsi_pointer->ptr = sg_virt(scsi_pointer->buffer); 844113658Sdeischen } else { 845117706Sdavidxu scsi_pointer->buffer = NULL; 846117706Sdavidxu scsi_pointer->this_residual = 0; 847117706Sdavidxu scsi_pointer->ptr = NULL; 848117706Sdavidxu } 849117706Sdavidxu scsi_pointer->buffers_residual = scsi_sg_count(cmd) - 1; 850117706Sdavidxu scsi_pointer->phase++; 851117706Sdavidxu if (scsi_pointer->this_residual & 0x01) 852117706Sdavidxu scsi_pointer->this_residual++; 853117706Sdavidxu fallthrough; 854117706Sdavidxu 855117907Sdeischen case 5: /* Phase 5 - Pre-Data transfer stage */ 856117907Sdeischen /* Spin lock for BUSY */ 857113658Sdeischen w_ctr(ppb, 0x0c); 858117706Sdavidxu if (!(r_str(ppb) & 0x80)) 859117706Sdavidxu return 1; 860117706Sdavidxu 861117706Sdavidxu /* Require negotiation for read requests */ 862117706Sdavidxu x = (r_str(ppb) & 0xb8); 863106191Smini dev->rd = (x & 0x10) ? 1 : 0; 864117706Sdavidxu dev->dp = (x & 0x20) ? 0 : 1; 865117706Sdavidxu 866117706Sdavidxu if ((dev->dp) && (dev->rd)) 867136286Sdavidxu if (imm_negotiate(dev)) 868136286Sdavidxu return 0; 869136286Sdavidxu scsi_pointer->phase++; 870136286Sdavidxu fallthrough; 871136286Sdavidxu 872136286Sdavidxu case 6: /* Phase 6 - Data transfer stage */ 873136286Sdavidxu /* Spin lock for BUSY */ 874136286Sdavidxu w_ctr(ppb, 0x0c); 875117706Sdavidxu if (!(r_str(ppb) & 0x80)) 876113658Sdeischen return 1; 877107202Smini 878117706Sdavidxu if (dev->dp) { 879117706Sdavidxu retv = imm_completion(cmd); 880117706Sdavidxu if (retv == -1) 881117706Sdavidxu return 0; 882107202Smini if (retv == 0) 883113786Sdeischen return 1; 884117706Sdavidxu } 885118510Sdeischen scsi_pointer->phase++; 886117706Sdavidxu fallthrough; 887117706Sdavidxu 888113658Sdeischen case 7: /* Phase 7 - Post data transfer stage */ 889106191Smini if ((dev->dp) && (dev->rd)) { 890115173Sdeischen if ((dev->mode == IMM_NIBBLE) || (dev->mode == IMM_PS2)) { 891115173Sdeischen w_ctr(ppb, 0x4); 892113658Sdeischen w_ctr(ppb, 0xc); 893113658Sdeischen w_ctr(ppb, 0xe); 894113658Sdeischen w_ctr(ppb, 0x4); 895106191Smini } 896113658Sdeischen } 897113658Sdeischen scsi_pointer->phase++; 898113658Sdeischen fallthrough; 899113658Sdeischen 900113658Sdeischen case 8: /* Phase 8 - Read status/message */ 901113658Sdeischen /* Check for data overrun */ 902115173Sdeischen if (imm_wait(dev) != (unsigned char) 0xb8) { 903106191Smini imm_fail(dev, DID_ERROR); 904113658Sdeischen return 0; 905113658Sdeischen } 906113658Sdeischen if (imm_negotiate(dev)) 907113658Sdeischen return 0; 908118510Sdeischen if (imm_in(dev, &l, 1)) { /* read status byte */ 909113658Sdeischen /* Check for optional message byte */ 910118510Sdeischen if (imm_wait(dev) == (unsigned char) 0xb8) 911113786Sdeischen imm_in(dev, &h, 1); 912113658Sdeischen cmd->result = (DID_OK << 16) | (l & STATUS_MASK); 913113658Sdeischen } 914118510Sdeischen if ((dev->mode == IMM_NIBBLE) || (dev->mode == IMM_PS2)) { 915118510Sdeischen w_ctr(ppb, 0x4); 916113870Sdeischen w_ctr(ppb, 0xc); 917113870Sdeischen w_ctr(ppb, 0xe); 918113786Sdeischen w_ctr(ppb, 0x4); 919123312Sdavidxu } 920113786Sdeischen return 0; /* Finished */ 921118510Sdeischen 922113786Sdeischen default: 923113786Sdeischen printk("imm: Invalid scsi phase\n"); 924113786Sdeischen } 925113786Sdeischen return 0; 926113786Sdeischen} 927118850Sdavidxu 928118850Sdavidxustatic int imm_queuecommand_lck(struct scsi_cmnd *cmd) 929118850Sdavidxu{ 930118850Sdavidxu imm_struct *dev = imm_dev(cmd->device->host); 931118850Sdavidxu 932118850Sdavidxu if (dev->cur_cmd) { 933118817Sdavidxu printk("IMM: bug in imm_queuecommand\n"); 934123312Sdavidxu return 0; 935114187Sdeischen } 936123312Sdavidxu dev->failed = 0; 937123312Sdavidxu dev->jstart = jiffies; 938113658Sdeischen dev->cur_cmd = cmd; 939123312Sdavidxu cmd->result = DID_ERROR << 16; /* default return code */ 940123312Sdavidxu imm_scsi_pointer(cmd)->phase = 0; /* bus free */ 941123312Sdavidxu 942123312Sdavidxu schedule_delayed_work(&dev->imm_tq, 0); 943123312Sdavidxu 944118510Sdeischen imm_pb_claim(dev); 945118510Sdeischen 946118510Sdeischen return 0; 947118510Sdeischen} 948118510Sdeischen 949118510Sdeischenstatic DEF_SCSI_QCMD(imm_queuecommand) 950116977Sdavidxu 951116977Sdavidxu/* 952113658Sdeischen * Apparently the disk->capacity attribute is off by 1 sector 953113658Sdeischen * for all disk drives. We add the one here, but it should really 954113658Sdeischen * be done in sd.c. Even if it gets fixed there, this will still 955113658Sdeischen * work. 956114187Sdeischen */ 957113658Sdeischenstatic int imm_biosparam(struct scsi_device *sdev, struct block_device *dev, 958113658Sdeischen sector_t capacity, int ip[]) 959113658Sdeischen{ 960113658Sdeischen ip[0] = 0x40; 961113658Sdeischen ip[1] = 0x20; 962113658Sdeischen ip[2] = ((unsigned long) capacity + 1) / (ip[0] * ip[1]); 963113658Sdeischen if (ip[2] > 1024) { 964113658Sdeischen ip[0] = 0xff; 965113658Sdeischen ip[1] = 0x3f; 966139023Sdeischen ip[2] = ((unsigned long) capacity + 1) / (ip[0] * ip[1]); 967139023Sdeischen } 968106191Smini return 0; 969106191Smini} 970113658Sdeischen 971113658Sdeischenstatic int imm_abort(struct scsi_cmnd *cmd) 97267097Sdeischen{ 97335509Sjb imm_struct *dev = imm_dev(cmd->device->host); 974113658Sdeischen /* 97535509Sjb * There is no method for aborting commands since Iomega 976113658Sdeischen * have tied the SCSI_MESSAGE line high in the interface 97713546Sjulian */ 978113658Sdeischen 979113658Sdeischen switch (imm_scsi_pointer(cmd)->phase) { 980113658Sdeischen case 0: /* Do not have access to parport */ 981113658Sdeischen case 1: /* Have not connected to interface */ 982113658Sdeischen dev->cur_cmd = NULL; /* Forget the problem */ 983113658Sdeischen return SUCCESS; 984113658Sdeischen default: /* SCSI command sent, can not abort */ 985132120Sdavidxu return FAILED; 986113658Sdeischen } 987113658Sdeischen} 988113658Sdeischen 989113658Sdeischenstatic void imm_reset_pulse(unsigned int base) 990113658Sdeischen{ 991114187Sdeischen w_ctr(base, 0x04); 992113658Sdeischen w_dtr(base, 0x40); 993113658Sdeischen udelay(1); 994113658Sdeischen w_ctr(base, 0x0c); 995118817Sdavidxu w_ctr(base, 0x0d); 996113658Sdeischen udelay(50); 997113658Sdeischen w_ctr(base, 0x0c); 998113658Sdeischen w_ctr(base, 0x04); 999114267Sdavidxu} 1000115080Sdeischen 1001118510Sdeischenstatic int imm_reset(struct scsi_cmnd *cmd) 1002113658Sdeischen{ 1003113658Sdeischen imm_struct *dev = imm_dev(cmd->device->host); 1004103419Smini 1005132120Sdavidxu if (imm_scsi_pointer(cmd)->phase) 1006132120Sdavidxu imm_disconnect(dev); 1007113658Sdeischen dev->cur_cmd = NULL; /* Forget the problem */ 1008132120Sdavidxu 1009118817Sdavidxu imm_connect(dev, CONNECT_NORMAL); 101053812Salfred imm_reset_pulse(dev->base); 1011114688Sdavidxu mdelay(1); /* device settle delay */ 1012113658Sdeischen imm_disconnect(dev); 1013114688Sdavidxu mdelay(1); /* device settle delay */ 1014113658Sdeischen return SUCCESS; 1015113658Sdeischen} 1016113658Sdeischen 1017119577Sdeischenstatic int device_check(imm_struct *dev, bool autodetect) 1018119577Sdeischen{ 1019113658Sdeischen /* This routine looks for a device and then attempts to use EPP 1020113658Sdeischen to send a command. If all goes as planned then EPP is available. */ 1021113658Sdeischen 1022113658Sdeischen static char cmd[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 1023113786Sdeischen int loop, old_mode, status, k, ppb = dev->base; 1024117706Sdavidxu unsigned char l; 1025113786Sdeischen 1026113658Sdeischen old_mode = dev->mode; 102767097Sdeischen for (loop = 0; loop < 8; loop++) { 1028113658Sdeischen /* Attempt to use EPP for Test Unit Ready */ 1029113658Sdeischen if (autodetect && (ppb & 0x0007) == 0x0000) 1030119577Sdeischen dev->mode = IMM_EPP_8; 1031119577Sdeischen 1032113658Sdeischen second_pass: 1033113658Sdeischen imm_connect(dev, CONNECT_EPP_MAYBE); 1034113658Sdeischen /* Select SCSI device */ 1035113658Sdeischen if (!imm_select(dev, loop)) { 1036113658Sdeischen imm_disconnect(dev); 1037113658Sdeischen continue; 1038113658Sdeischen } 1039113658Sdeischen printk("imm: Found device at ID %i, Attempting to use %s\n", 1040113658Sdeischen loop, IMM_MODE_STRING[dev->mode]); 1041119700Sdavidxu 1042113658Sdeischen /* Send SCSI command */ 1043113658Sdeischen status = 1; 1044115278Sdeischen w_ctr(ppb, 0x0c); 1045113658Sdeischen for (l = 0; (l < 3) && (status); l++) 1046113658Sdeischen status = imm_out(dev, &cmd[l << 1], 2); 1047113658Sdeischen 1048113658Sdeischen if (!status) { 1049113658Sdeischen imm_disconnect(dev); 1050113658Sdeischen imm_connect(dev, CONNECT_EPP_MAYBE); 1051113658Sdeischen imm_reset_pulse(dev->base); 1052113658Sdeischen udelay(1000); 1053113658Sdeischen imm_disconnect(dev); 1054113658Sdeischen udelay(1000); 1055113658Sdeischen if (dev->mode != old_mode) { 1056118817Sdavidxu dev->mode = old_mode; 1057113658Sdeischen goto second_pass; 1058113658Sdeischen } 1059113658Sdeischen printk("imm: Unable to establish communication\n"); 1060113658Sdeischen return -EIO; 1061113658Sdeischen } 1062113658Sdeischen w_ctr(ppb, 0x0c); 1063113658Sdeischen 1064113658Sdeischen k = 1000000; /* 1 Second */ 1065113658Sdeischen do { 1066113658Sdeischen l = r_str(ppb); 1067113658Sdeischen k--; 1068113658Sdeischen udelay(1); 1069113658Sdeischen } while (!(l & 0x80) && (k)); 1070113658Sdeischen 1071113658Sdeischen l &= 0xb8; 1072113658Sdeischen 1073113658Sdeischen if (l != 0xb8) { 1074113658Sdeischen imm_disconnect(dev); 1075113658Sdeischen imm_connect(dev, CONNECT_EPP_MAYBE); 1076113658Sdeischen imm_reset_pulse(dev->base); 1077113658Sdeischen udelay(1000); 1078113658Sdeischen imm_disconnect(dev); 1079113658Sdeischen udelay(1000); 1080139023Sdeischen if (dev->mode != old_mode) { 1081120896Sdavidxu dev->mode = old_mode; 1082120896Sdavidxu goto second_pass; 1083120896Sdavidxu } 1084116977Sdavidxu printk 1085118510Sdeischen ("imm: Unable to establish communication\n"); 1086114187Sdeischen return -EIO; 1087116977Sdavidxu } 1088119700Sdavidxu imm_disconnect(dev); 1089113658Sdeischen printk 1090113658Sdeischen ("imm: Communication established at 0x%x with ID %i using %s\n", 1091113658Sdeischen ppb, loop, IMM_MODE_STRING[dev->mode]); 1092115080Sdeischen imm_connect(dev, CONNECT_EPP_MAYBE); 1093115080Sdeischen imm_reset_pulse(dev->base); 1094115080Sdeischen udelay(1000); 1095115080Sdeischen imm_disconnect(dev); 1096115080Sdeischen udelay(1000); 1097118510Sdeischen return 0; 1098114187Sdeischen } 1099115080Sdeischen printk("imm: No devices found\n"); 1100115080Sdeischen return -ENODEV; 1101118510Sdeischen} 1102114187Sdeischen 1103113658Sdeischen/* 1104113658Sdeischen * imm cannot deal with highmem, so this causes all IO pages for this host 1105113658Sdeischen * to reside in low memory (hence mapped) 1106113658Sdeischen */ 1107113658Sdeischenstatic int imm_adjust_queue(struct scsi_device *device) 110867097Sdeischen{ 110948046Sjb blk_queue_bounce_limit(device->request_queue, BLK_BOUNCE_HIGH); 1110113658Sdeischen return 0; 1111116977Sdavidxu} 111267097Sdeischen 1113113658Sdeischenstatic const struct scsi_host_template imm_template = { 1114116977Sdavidxu .module = THIS_MODULE, 1115119063Sdavidxu .proc_name = "imm", 111613546Sjulian .show_info = imm_show_info, 1117116977Sdavidxu .write_info = imm_write_info, 1118116977Sdavidxu .name = "Iomega VPI2 (imm) interface", 1119116977Sdavidxu .queuecommand = imm_queuecommand, 1120139023Sdeischen .eh_abort_handler = imm_abort, 1121119063Sdavidxu .eh_host_reset_handler = imm_reset, 1122116977Sdavidxu .bios_param = imm_biosparam, 1123139023Sdeischen .this_id = 7, 1124118510Sdeischen .sg_tablesize = SG_ALL, 1125118510Sdeischen .can_queue = 1, 1126116977Sdavidxu .slave_alloc = imm_adjust_queue, 1127116977Sdavidxu .cmd_size = sizeof(struct scsi_pointer), 1128116977Sdavidxu}; 1129116977Sdavidxu 1130113658Sdeischen/*************************************************************************** 1131113658Sdeischen * Parallel port probing routines * 1132113658Sdeischen ***************************************************************************/ 1133139023Sdeischen 1134113658Sdeischenstatic LIST_HEAD(imm_hosts); 1135139023Sdeischen 1136113658Sdeischen/* 1137120896Sdavidxu * Finds the first available device number that can be alloted to the 1138113658Sdeischen * new imm device and returns the address of the previous node so that 1139113658Sdeischen * we can add to the tail and have a list in the ascending order. 1140113658Sdeischen */ 1141113658Sdeischen 1142113658Sdeischenstatic inline imm_struct *find_parent(void) 1143113658Sdeischen{ 1144113658Sdeischen imm_struct *dev, *par = NULL; 1145113658Sdeischen unsigned int cnt = 0; 1146113658Sdeischen 1147113658Sdeischen if (list_empty(&imm_hosts)) 1148113658Sdeischen return NULL; 1149113658Sdeischen 1150117907Sdeischen list_for_each_entry(dev, &imm_hosts, list) { 1151115278Sdeischen if (dev->dev_no != cnt) 1152113658Sdeischen return par; 1153113658Sdeischen cnt++; 1154115278Sdeischen par = dev; 1155115278Sdeischen } 1156115278Sdeischen 1157115278Sdeischen return par; 1158115278Sdeischen} 1159117907Sdeischen 1160115278Sdeischenstatic int __imm_attach(struct parport *pb) 1161115278Sdeischen{ 1162115278Sdeischen struct Scsi_Host *host; 1163115278Sdeischen imm_struct *dev, *temp; 1164115278Sdeischen DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waiting); 1165113658Sdeischen DEFINE_WAIT(wait); 1166115278Sdeischen int ports; 1167115278Sdeischen int err = -ENOMEM; 1168115278Sdeischen struct pardev_cb imm_cb; 1169117907Sdeischen 1170115278Sdeischen init_waitqueue_head(&waiting); 1171113658Sdeischen 1172115278Sdeischen dev = kzalloc(sizeof(imm_struct), GFP_KERNEL); 1173117907Sdeischen if (!dev) 1174117907Sdeischen return -ENOMEM; 1175106786Smini 1176115278Sdeischen 117713546Sjulian dev->base = -1; 1178113658Sdeischen dev->mode = mode < IMM_UNKNOWN ? mode : IMM_AUTODETECT; 1179113658Sdeischen INIT_LIST_HEAD(&dev->list); 118013546Sjulian 1181115278Sdeischen temp = find_parent(); 1182113661Sdeischen if (temp) 1183113661Sdeischen dev->dev_no = temp->dev_no + 1; 1184113661Sdeischen 1185113661Sdeischen memset(&imm_cb, 0, sizeof(imm_cb)); 1186113661Sdeischen imm_cb.private = dev; 1187113661Sdeischen imm_cb.wakeup = imm_wakeup; 1188113661Sdeischen 1189113661Sdeischen dev->dev = parport_register_dev_model(pb, "imm", &imm_cb, dev->dev_no); 1190113661Sdeischen if (!dev->dev) 1191113661Sdeischen goto out; 1192113661Sdeischen 1193113661Sdeischen 1194113661Sdeischen /* Claim the bus so it remembers what we do to the control 1195113661Sdeischen * registers. [ CTR and ECP ] 1196113661Sdeischen */ 1197113661Sdeischen err = -EBUSY; 1198113661Sdeischen dev->waiting = &waiting; 1199113661Sdeischen prepare_to_wait(&waiting, &wait, TASK_UNINTERRUPTIBLE); 1200113661Sdeischen if (imm_pb_claim(dev)) 1201113658Sdeischen schedule_timeout(3 * HZ); 1202136846Sdavidxu if (dev->wanted) { 1203119732Sdavidxu printk(KERN_ERR "imm%d: failed to claim parport because " 1204113658Sdeischen "a pardevice is owning the port for too long " 1205115278Sdeischen "time!\n", pb->number); 1206115278Sdeischen imm_pb_dismiss(dev); 1207115278Sdeischen dev->waiting = NULL; 1208115278Sdeischen finish_wait(&waiting, &wait); 1209115278Sdeischen goto out1; 1210117706Sdavidxu } 1211115278Sdeischen dev->waiting = NULL; 1212117706Sdavidxu finish_wait(&waiting, &wait); 1213117706Sdavidxu dev->base = dev->dev->port->base; 1214115278Sdeischen dev->base_hi = dev->dev->port->base_hi; 1215115278Sdeischen w_ctr(dev->base, 0x0c); 1216115278Sdeischen 1217113661Sdeischen /* Done configuration */ 1218113658Sdeischen 121967097Sdeischen err = imm_init(dev); 1220113658Sdeischen 1221113661Sdeischen imm_pb_release(dev); 1222113658Sdeischen 1223118676Sdavidxu if (err) 1224118676Sdavidxu goto out1; 1225118676Sdavidxu 1226118676Sdavidxu /* now the glue ... */ 1227118676Sdavidxu if (dev->mode == IMM_NIBBLE || dev->mode == IMM_PS2) 1228118676Sdavidxu ports = 3; 1229118676Sdavidxu else 1230118676Sdavidxu ports = 8; 1231113661Sdeischen 1232113661Sdeischen INIT_DELAYED_WORK(&dev->imm_tq, imm_interrupt); 1233113786Sdeischen 1234106786Smini err = -ENOMEM; 1235113786Sdeischen host = scsi_host_alloc(&imm_template, sizeof(imm_struct *)); 1236113661Sdeischen if (!host) 1237113661Sdeischen goto out1; 1238113661Sdeischen host->io_port = pb->base; 1239113661Sdeischen host->n_io_port = ports; 1240113661Sdeischen host->dma_channel = -1; 1241113661Sdeischen host->unique_id = pb->number; 1242136846Sdavidxu *(imm_struct **)&host->hostdata = dev; 1243113661Sdeischen dev->host = host; 1244115278Sdeischen if (!temp) 1245118510Sdeischen list_add_tail(&dev->list, &imm_hosts); 1246113661Sdeischen else 1247113661Sdeischen list_add_tail(&dev->list, &temp->list); 1248113661Sdeischen err = scsi_add_host(host, NULL); 1249113661Sdeischen if (err) 1250113661Sdeischen goto out2; 1251113661Sdeischen scsi_scan_host(host); 1252113661Sdeischen return 0; 1253113786Sdeischen 1254113786Sdeischenout2: 1255113786Sdeischen list_del_init(&dev->list); 1256113786Sdeischen scsi_host_put(host); 1257113786Sdeischenout1: 1258113658Sdeischen parport_unregister_device(dev->dev); 1259113786Sdeischenout: 1260113786Sdeischen kfree(dev); 1261113786Sdeischen return err; 1262113786Sdeischen} 1263113786Sdeischen 1264113661Sdeischenstatic void imm_attach(struct parport *pb) 1265113786Sdeischen{ 1266113786Sdeischen __imm_attach(pb); 1267113786Sdeischen} 1268113786Sdeischen 1269113786Sdeischenstatic void imm_detach(struct parport *pb) 1270113786Sdeischen{ 1271113786Sdeischen imm_struct *dev; 1272114187Sdeischen list_for_each_entry(dev, &imm_hosts, list) { 1273113786Sdeischen if (dev->dev->port == pb) { 1274113786Sdeischen list_del_init(&dev->list); 1275113786Sdeischen scsi_remove_host(dev->host); 1276113786Sdeischen scsi_host_put(dev->host); 1277113786Sdeischen parport_unregister_device(dev->dev); 1278113658Sdeischen kfree(dev); 1279113786Sdeischen break; 1280113786Sdeischen } 1281118985Sdavidxu } 1282118985Sdavidxu} 1283118985Sdavidxu 1284118985Sdavidxustatic struct parport_driver imm_driver = { 1285118985Sdavidxu .name = "imm", 1286118985Sdavidxu .match_port = imm_attach, 1287118985Sdavidxu .detach = imm_detach, 1288118985Sdavidxu .devmodel = true, 1289118985Sdavidxu}; 1290113786Sdeischenmodule_parport_driver(imm_driver); 1291115278Sdeischen 1292113786SdeischenMODULE_LICENSE("GPL"); 1293113661Sdeischen