Skip to content

Commit b0597fd

Browse files
alexhenriemartinkpetersen
authored andcommitted
scsi: imm: Add a module parameter for the transfer mode
Fix in the imm driver the same problem that was fixed in the ppa driver by commit 68a4f84 ("scsi: ppa: Add a module parameter for the transfer mode"). Tested and confirmed working with an Iomega Z250P zip drive and a StarTech PEX1P2 AX99100 PCIe parallel port. Signed-off-by: Alex Henrie <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 1345a7d commit b0597fd

File tree

3 files changed

+37
-52
lines changed

3 files changed

+37
-52
lines changed

drivers/scsi/Kconfig

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -834,21 +834,6 @@ config SCSI_IMM
834834
To compile this driver as a module, choose M here: the
835835
module will be called imm.
836836

837-
config SCSI_IZIP_EPP16
838-
bool "ppa/imm option - Use slow (but safe) EPP-16"
839-
depends on SCSI_IMM
840-
help
841-
EPP (Enhanced Parallel Port) is a standard for parallel ports which
842-
allows them to act as expansion buses that can handle up to 64
843-
peripheral devices.
844-
845-
Some parallel port chipsets are slower than their motherboard, and
846-
so we have to control the state of the chipset's FIFO queue every
847-
now and then to avoid data loss. This will be done if you say Y
848-
here.
849-
850-
Generally, saying Y is the safe option and slows things down a bit.
851-
852837
config SCSI_IZIP_SLOW_CTR
853838
bool "ppa/imm option - Assume slow parport control register"
854839
depends on SCSI_PPA || SCSI_IMM

drivers/scsi/imm.c

Lines changed: 37 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,15 @@ typedef struct {
5151
} imm_struct;
5252

5353
static void imm_reset_pulse(unsigned int base);
54-
static int device_check(imm_struct *dev);
54+
static int device_check(imm_struct *dev, bool autodetect);
5555

5656
#include "imm.h"
5757

58+
static unsigned int mode = IMM_AUTODETECT;
59+
module_param(mode, uint, 0644);
60+
MODULE_PARM_DESC(mode, "Transfer mode (0 = Autodetect, 1 = SPP 4-bit, "
61+
"2 = SPP 8-bit, 3 = EPP 8-bit, 4 = EPP 16-bit, 5 = EPP 32-bit");
62+
5863
static inline imm_struct *imm_dev(struct Scsi_Host *host)
5964
{
6065
return *(imm_struct **)&host->hostdata;
@@ -366,13 +371,10 @@ static int imm_out(imm_struct *dev, char *buffer, int len)
366371
case IMM_EPP_8:
367372
epp_reset(ppb);
368373
w_ctr(ppb, 0x4);
369-
#ifdef CONFIG_SCSI_IZIP_EPP16
370-
if (!(((long) buffer | len) & 0x01))
371-
outsw(ppb + 4, buffer, len >> 1);
372-
#else
373-
if (!(((long) buffer | len) & 0x03))
374+
if (dev->mode == IMM_EPP_32 && !(((long) buffer | len) & 0x03))
374375
outsl(ppb + 4, buffer, len >> 2);
375-
#endif
376+
else if (dev->mode == IMM_EPP_16 && !(((long) buffer | len) & 0x01))
377+
outsw(ppb + 4, buffer, len >> 1);
376378
else
377379
outsb(ppb + 4, buffer, len);
378380
w_ctr(ppb, 0xc);
@@ -426,13 +428,10 @@ static int imm_in(imm_struct *dev, char *buffer, int len)
426428
case IMM_EPP_8:
427429
epp_reset(ppb);
428430
w_ctr(ppb, 0x24);
429-
#ifdef CONFIG_SCSI_IZIP_EPP16
430-
if (!(((long) buffer | len) & 0x01))
431-
insw(ppb + 4, buffer, len >> 1);
432-
#else
433-
if (!(((long) buffer | len) & 0x03))
434-
insl(ppb + 4, buffer, len >> 2);
435-
#endif
431+
if (dev->mode == IMM_EPP_32 && !(((long) buffer | len) & 0x03))
432+
insw(ppb + 4, buffer, len >> 2);
433+
else if (dev->mode == IMM_EPP_16 && !(((long) buffer | len) & 0x01))
434+
insl(ppb + 4, buffer, len >> 1);
436435
else
437436
insb(ppb + 4, buffer, len);
438437
w_ctr(ppb, 0x2c);
@@ -589,13 +588,28 @@ static int imm_select(imm_struct *dev, int target)
589588

590589
static int imm_init(imm_struct *dev)
591590
{
591+
bool autodetect = dev->mode == IMM_AUTODETECT;
592+
593+
if (autodetect) {
594+
int modes = dev->dev->port->modes;
595+
596+
/* Mode detection works up the chain of speed
597+
* This avoids a nasty if-then-else-if-... tree
598+
*/
599+
dev->mode = IMM_NIBBLE;
600+
601+
if (modes & PARPORT_MODE_TRISTATE)
602+
dev->mode = IMM_PS2;
603+
}
604+
592605
if (imm_connect(dev, 0) != 1)
593606
return -EIO;
594607
imm_reset_pulse(dev->base);
595608
mdelay(1); /* Delay to allow devices to settle */
596609
imm_disconnect(dev);
597610
mdelay(1); /* Another delay to allow devices to settle */
598-
return device_check(dev);
611+
612+
return device_check(dev, autodetect);
599613
}
600614

601615
static inline int imm_send_command(struct scsi_cmnd *cmd)
@@ -1000,7 +1014,7 @@ static int imm_reset(struct scsi_cmnd *cmd)
10001014
return SUCCESS;
10011015
}
10021016

1003-
static int device_check(imm_struct *dev)
1017+
static int device_check(imm_struct *dev, bool autodetect)
10041018
{
10051019
/* This routine looks for a device and then attempts to use EPP
10061020
to send a command. If all goes as planned then EPP is available. */
@@ -1012,8 +1026,8 @@ static int device_check(imm_struct *dev)
10121026
old_mode = dev->mode;
10131027
for (loop = 0; loop < 8; loop++) {
10141028
/* Attempt to use EPP for Test Unit Ready */
1015-
if ((ppb & 0x0007) == 0x0000)
1016-
dev->mode = IMM_EPP_32;
1029+
if (autodetect && (ppb & 0x0007) == 0x0000)
1030+
dev->mode = IMM_EPP_8;
10171031

10181032
second_pass:
10191033
imm_connect(dev, CONNECT_EPP_MAYBE);
@@ -1038,7 +1052,7 @@ static int device_check(imm_struct *dev)
10381052
udelay(1000);
10391053
imm_disconnect(dev);
10401054
udelay(1000);
1041-
if (dev->mode == IMM_EPP_32) {
1055+
if (dev->mode != old_mode) {
10421056
dev->mode = old_mode;
10431057
goto second_pass;
10441058
}
@@ -1063,7 +1077,7 @@ static int device_check(imm_struct *dev)
10631077
udelay(1000);
10641078
imm_disconnect(dev);
10651079
udelay(1000);
1066-
if (dev->mode == IMM_EPP_32) {
1080+
if (dev->mode != old_mode) {
10671081
dev->mode = old_mode;
10681082
goto second_pass;
10691083
}
@@ -1150,7 +1164,6 @@ static int __imm_attach(struct parport *pb)
11501164
DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waiting);
11511165
DEFINE_WAIT(wait);
11521166
int ports;
1153-
int modes, ppb;
11541167
int err = -ENOMEM;
11551168
struct pardev_cb imm_cb;
11561169

@@ -1162,7 +1175,7 @@ static int __imm_attach(struct parport *pb)
11621175

11631176

11641177
dev->base = -1;
1165-
dev->mode = IMM_AUTODETECT;
1178+
dev->mode = mode < IMM_UNKNOWN ? mode : IMM_AUTODETECT;
11661179
INIT_LIST_HEAD(&dev->list);
11671180

11681181
temp = find_parent();
@@ -1197,18 +1210,9 @@ static int __imm_attach(struct parport *pb)
11971210
}
11981211
dev->waiting = NULL;
11991212
finish_wait(&waiting, &wait);
1200-
ppb = dev->base = dev->dev->port->base;
1213+
dev->base = dev->dev->port->base;
12011214
dev->base_hi = dev->dev->port->base_hi;
1202-
w_ctr(ppb, 0x0c);
1203-
modes = dev->dev->port->modes;
1204-
1205-
/* Mode detection works up the chain of speed
1206-
* This avoids a nasty if-then-else-if-... tree
1207-
*/
1208-
dev->mode = IMM_NIBBLE;
1209-
1210-
if (modes & PARPORT_MODE_TRISTATE)
1211-
dev->mode = IMM_PS2;
1215+
w_ctr(dev->base, 0x0c);
12121216

12131217
/* Done configuration */
12141218

drivers/scsi/imm.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,11 +100,7 @@ static char *IMM_MODE_STRING[] =
100100
[IMM_PS2] = "PS/2",
101101
[IMM_EPP_8] = "EPP 8 bit",
102102
[IMM_EPP_16] = "EPP 16 bit",
103-
#ifdef CONFIG_SCSI_IZIP_EPP16
104-
[IMM_EPP_32] = "EPP 16 bit",
105-
#else
106103
[IMM_EPP_32] = "EPP 32 bit",
107-
#endif
108104
[IMM_UNKNOWN] = "Unknown",
109105
};
110106

0 commit comments

Comments
 (0)