Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

scsi: ppa: Add a module parameter for the transfer mode

I have an Iomega Z100P2 zip drive, but it does not work with my StarTech
PEX1P2 AX99100 PCIe parallel port, which evidently does not support 16-bit
or 32-bit EPP. Currently the only way to tell the PPA driver to use 8-bit
EPP is to write 'mode=3' to /proc/scsi/ppa/*, but the driver doesn't
actually distinguish between the three EPP modes and still tries to use
16-bit or 32-bit EPP. And even if writing to that file did make the driver
use 8-bit EPP, it still wouldn't do me any good because by the time that
file exists, the drive has already failed to initialize.

Add a new parameter /sys/module/ppa/mode to set the transfer mode before
initializing the drive. This parameter replaces the use of
CONFIG_SCSI_IZIP_EPP16 in the PPA driver.

At the same time, default to 8-bit EPP. 16-bit and 32-bit EPP are not
necessary for the drive to function, nor are they part of the IEEE 1284
standard, so the driver should not assume that they are available.

Signed-off-by: Alex Henrie <alexhenrie24@gmail.com>
Link: https://lore.kernel.org/r/20230807155856.362864-2-alexhenrie24@gmail.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

Alex Henrie and committed by
Martin K. Petersen
68a4f84a b68442eb

+43 -45
+1 -1
drivers/scsi/Kconfig
··· 836 836 837 837 config SCSI_IZIP_EPP16 838 838 bool "ppa/imm option - Use slow (but safe) EPP-16" 839 - depends on SCSI_PPA || SCSI_IMM 839 + depends on SCSI_IMM 840 840 help 841 841 EPP (Enhanced Parallel Port) is a standard for parallel ports which 842 842 allows them to act as expansion buses that can handle up to 64
+42 -40
drivers/scsi/ppa.c
··· 45 45 46 46 #include "ppa.h" 47 47 48 + static unsigned int mode = PPA_AUTODETECT; 49 + module_param(mode, uint, 0644); 50 + MODULE_PARM_DESC(mode, "Transfer mode (0 = Autodetect, 1 = SPP 4-bit, " 51 + "2 = SPP 8-bit, 3 = EPP 8-bit, 4 = EPP 16-bit, 5 = EPP 32-bit"); 52 + 48 53 static struct scsi_pointer *ppa_scsi_pointer(struct scsi_cmnd *cmd) 49 54 { 50 55 return scsi_cmd_priv(cmd); ··· 162 157 return 0; 163 158 } 164 159 165 - static int device_check(ppa_struct *dev); 160 + static int device_check(ppa_struct *dev, bool autodetect); 166 161 167 162 #if PPA_DEBUG > 0 168 163 #define ppa_fail(x,y) printk("ppa: ppa_fail(%i) from %s at line %d\n",\ ··· 307 302 case PPA_EPP_8: 308 303 epp_reset(ppb); 309 304 w_ctr(ppb, 0x4); 310 - #ifdef CONFIG_SCSI_IZIP_EPP16 311 - if (!(((long) buffer | len) & 0x01)) 312 - outsw(ppb + 4, buffer, len >> 1); 313 - #else 314 - if (!(((long) buffer | len) & 0x03)) 305 + if (dev->mode == PPA_EPP_32 && !(((long) buffer | len) & 0x01)) 315 306 outsl(ppb + 4, buffer, len >> 2); 316 - #endif 307 + else if (dev->mode == PPA_EPP_16 && !(((long) buffer | len) & 0x03)) 308 + outsw(ppb + 4, buffer, len >> 1); 317 309 else 318 310 outsb(ppb + 4, buffer, len); 319 311 w_ctr(ppb, 0xc); ··· 357 355 case PPA_EPP_8: 358 356 epp_reset(ppb); 359 357 w_ctr(ppb, 0x24); 360 - #ifdef CONFIG_SCSI_IZIP_EPP16 361 - if (!(((long) buffer | len) & 0x01)) 362 - insw(ppb + 4, buffer, len >> 1); 363 - #else 364 - if (!(((long) buffer | len) & 0x03)) 358 + if (dev->mode == PPA_EPP_32 && !(((long) buffer | len) & 0x03)) 365 359 insl(ppb + 4, buffer, len >> 2); 366 - #endif 360 + else if (dev->mode == PPA_EPP_16 && !(((long) buffer | len) & 0x01)) 361 + insw(ppb + 4, buffer, len >> 1); 367 362 else 368 363 insb(ppb + 4, buffer, len); 369 364 w_ctr(ppb, 0x2c); ··· 468 469 { 469 470 int retv; 470 471 unsigned short ppb = dev->base; 472 + bool autodetect = dev->mode == PPA_AUTODETECT; 473 + 474 + if (autodetect) { 475 + int modes = dev->dev->port->modes; 476 + int ppb_hi = dev->dev->port->base_hi; 477 + 478 + /* Mode detection works up the chain of speed 479 + * This avoids a nasty if-then-else-if-... tree 480 + */ 481 + dev->mode = PPA_NIBBLE; 482 + 483 + if (modes & PARPORT_MODE_TRISTATE) 484 + dev->mode = PPA_PS2; 485 + 486 + if (modes & PARPORT_MODE_ECP) { 487 + w_ecr(ppb_hi, 0x20); 488 + dev->mode = PPA_PS2; 489 + } 490 + if ((modes & PARPORT_MODE_EPP) && (modes & PARPORT_MODE_ECP)) 491 + w_ecr(ppb_hi, 0x80); 492 + } 471 493 472 494 ppa_disconnect(dev); 473 495 ppa_connect(dev, CONNECT_NORMAL); ··· 512 492 if (retv) 513 493 return -EIO; 514 494 515 - return device_check(dev); 495 + return device_check(dev, autodetect); 516 496 } 517 497 518 498 static inline int ppa_send_command(struct scsi_cmnd *cmd) ··· 903 883 return SUCCESS; 904 884 } 905 885 906 - static int device_check(ppa_struct *dev) 886 + static int device_check(ppa_struct *dev, bool autodetect) 907 887 { 908 888 /* This routine looks for a device and then attempts to use EPP 909 889 to send a command. If all goes as planned then EPP is available. */ ··· 915 895 old_mode = dev->mode; 916 896 for (loop = 0; loop < 8; loop++) { 917 897 /* Attempt to use EPP for Test Unit Ready */ 918 - if ((ppb & 0x0007) == 0x0000) 919 - dev->mode = PPA_EPP_32; 898 + if (autodetect && (ppb & 0x0007) == 0x0000) 899 + dev->mode = PPA_EPP_8; 920 900 921 901 second_pass: 922 902 ppa_connect(dev, CONNECT_EPP_MAYBE); ··· 944 924 udelay(1000); 945 925 ppa_disconnect(dev); 946 926 udelay(1000); 947 - if (dev->mode == PPA_EPP_32) { 927 + if (dev->mode != old_mode) { 948 928 dev->mode = old_mode; 949 929 goto second_pass; 950 930 } ··· 967 947 udelay(1000); 968 948 ppa_disconnect(dev); 969 949 udelay(1000); 970 - if (dev->mode == PPA_EPP_32) { 950 + if (dev->mode != old_mode) { 971 951 dev->mode = old_mode; 972 952 goto second_pass; 973 953 } ··· 1046 1026 DEFINE_WAIT(wait); 1047 1027 ppa_struct *dev, *temp; 1048 1028 int ports; 1049 - int modes, ppb, ppb_hi; 1050 1029 int err = -ENOMEM; 1051 1030 struct pardev_cb ppa_cb; 1052 1031 ··· 1053 1034 if (!dev) 1054 1035 return -ENOMEM; 1055 1036 dev->base = -1; 1056 - dev->mode = PPA_AUTODETECT; 1037 + dev->mode = mode < PPA_UNKNOWN ? mode : PPA_AUTODETECT; 1057 1038 dev->recon_tmo = PPA_RECON_TMO; 1058 1039 init_waitqueue_head(&waiting); 1059 1040 temp = find_parent(); ··· 1088 1069 } 1089 1070 dev->waiting = NULL; 1090 1071 finish_wait(&waiting, &wait); 1091 - ppb = dev->base = dev->dev->port->base; 1092 - ppb_hi = dev->dev->port->base_hi; 1093 - w_ctr(ppb, 0x0c); 1094 - modes = dev->dev->port->modes; 1095 - 1096 - /* Mode detection works up the chain of speed 1097 - * This avoids a nasty if-then-else-if-... tree 1098 - */ 1099 - dev->mode = PPA_NIBBLE; 1100 - 1101 - if (modes & PARPORT_MODE_TRISTATE) 1102 - dev->mode = PPA_PS2; 1103 - 1104 - if (modes & PARPORT_MODE_ECP) { 1105 - w_ecr(ppb_hi, 0x20); 1106 - dev->mode = PPA_PS2; 1107 - } 1108 - if ((modes & PARPORT_MODE_EPP) && (modes & PARPORT_MODE_ECP)) 1109 - w_ecr(ppb_hi, 0x80); 1072 + dev->base = dev->dev->port->base; 1073 + w_ctr(dev->base, 0x0c); 1110 1074 1111 1075 /* Done configuration */ 1112 1076
-4
drivers/scsi/ppa.h
··· 107 107 "PS/2", 108 108 "EPP 8 bit", 109 109 "EPP 16 bit", 110 - #ifdef CONFIG_SCSI_IZIP_EPP16 111 - "EPP 16 bit", 112 - #else 113 110 "EPP 32 bit", 114 - #endif 115 111 "Unknown"}; 116 112 117 113 /* other options */