Lines Matching +full:settle +full:- +full:delay +full:- +full:usec
1 // SPDX-License-Identifier: GPL-2.0-only
2 /* imm.c -- low level driver for the IOMEGA MatchMaker
18 #include <linux/delay.h>
38 int base_hi; /* Hi Base address for ECP-ISA chipset */
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");
65 return *(imm_struct **)&host->hostdata; in imm_dev()
72 dev->base = dev->dev->port->base; in got_it()
73 if (dev->cur_cmd) in got_it()
74 imm_scsi_pointer(dev->cur_cmd)->phase = 1; in got_it()
76 wake_up(dev->waiting); in got_it()
85 if (dev->wanted) { in imm_wakeup()
86 if (parport_claim(dev->dev) == 0) { in imm_wakeup()
88 dev->wanted = 0; in imm_wakeup()
99 if (parport_claim(dev->dev) == 0) { in imm_pb_claim()
103 dev->wanted = res; in imm_pb_claim()
113 wanted = dev->wanted; in imm_pb_dismiss()
114 dev->wanted = 0; in imm_pb_dismiss()
117 parport_release(dev->dev); in imm_pb_dismiss()
122 parport_release(dev->dev); in imm_pb_release()
137 dev->mode = simple_strtoul(buffer + 5, NULL, 0); in imm_write_info()
141 return -EINVAL; in imm_write_info()
149 seq_printf(m, "Parport : %s\n", dev->dev->port->name); in imm_show_info()
150 seq_printf(m, "Mode : %s\n", IMM_MODE_STRING[dev->mode]); in imm_show_info()
165 if (dev->cur_cmd) { in imm_fail_func()
166 dev->cur_cmd->result = error_code << 16; in imm_fail_func()
167 dev->failed = 1; in imm_fail_func()
181 unsigned short ppb = dev->base; in imm_wait()
189 k--; in imm_wait()
217 /* Counter expired - Time out occurred */ in imm_wait()
226 * The following is supposedly the IEEE 1284-1994 negotiate in imm_negotiate()
237 unsigned short base = tmp->base; in imm_negotiate()
240 switch (tmp->mode) { in imm_negotiate()
288 int i, ppb_hi = dev->base_hi; in ecp_sync()
308 for (i = len >> 1; i; i--) { in imm_byte_out()
315 return 1; /* All went well - we hope! */ in imm_byte_out()
327 for (i = len; i; i--) { in imm_nibble_in()
334 return 1; /* All went well - we hope! */ in imm_nibble_in()
345 for (i = len; i; i--) { in imm_byte_in()
350 return 1; /* All went well - we hope! */ in imm_byte_in()
355 unsigned short ppb = dev->base; in imm_out()
368 switch (dev->mode) { in imm_out()
374 if (dev->mode == IMM_EPP_32 && !(((long) buffer | len) & 0x03)) in imm_out()
376 else if (dev->mode == IMM_EPP_16 && !(((long) buffer | len) & 0x01)) in imm_out()
401 unsigned short ppb = dev->base; in imm_in()
413 switch (dev->mode) { in imm_in()
431 if (dev->mode == IMM_EPP_32 && !(((long) buffer | len) & 0x03)) in imm_in()
433 else if (dev->mode == IMM_EPP_16 && !(((long) buffer | len) & 0x01)) in imm_in()
460 udelay(2); /* 1 usec - infinite */ in imm_cpp()
462 udelay(10); /* 7 usec - infinite */ in imm_cpp()
464 udelay(10); /* 7 usec - infinite */ in imm_cpp()
466 udelay(10); /* 7 usec - infinite */ in imm_cpp()
468 udelay(10); /* 7 usec - infinite */ in imm_cpp()
471 udelay(10); /* 7 usec - infinite */ in imm_cpp()
474 udelay(10); /* 7 usec - infinite */ in imm_cpp()
487 udelay(2); /* 1 usec - infinite */ in imm_cpp()
489 udelay(10); /* 7 usec - infinite */ in imm_cpp()
491 udelay(2); /* 1 usec - infinite */ in imm_cpp()
493 udelay(10); /* 7 usec - infinite */ in imm_cpp()
495 udelay(10); /* 7 usec - infinite */ in imm_cpp()
518 return -1; /* No device present */ in imm_cpp()
523 unsigned short ppb = dev->base; in imm_connect()
528 if ((dev->mode == IMM_EPP_8) || in imm_connect()
529 (dev->mode == IMM_EPP_16) || in imm_connect()
530 (dev->mode == IMM_EPP_32)) in imm_connect()
537 imm_cpp(dev->base, 0x30); /* Disconnect all devices */ in imm_disconnect()
543 unsigned short ppb = dev->base; in imm_select()
553 k--; in imm_select()
578 k--; in imm_select()
591 bool autodetect = dev->mode == IMM_AUTODETECT; in imm_init()
594 int modes = dev->dev->port->modes; in imm_init()
597 * This avoids a nasty if-then-else-if-... tree in imm_init()
599 dev->mode = IMM_NIBBLE; in imm_init()
602 dev->mode = IMM_PS2; in imm_init()
606 return -EIO; in imm_init()
607 imm_reset_pulse(dev->base); in imm_init()
608 mdelay(1); /* Delay to allow devices to settle */ in imm_init()
610 mdelay(1); /* Another delay to allow devices to settle */ in imm_init()
617 imm_struct *dev = imm_dev(cmd->device->host); in imm_send_command()
621 for (k = 0; k < cmd->cmd_len; k += 2) in imm_send_command()
622 if (!imm_out(dev, &cmd->cmnd[k], 2)) in imm_send_command()
638 * -1 Error in imm_completion()
643 imm_struct *dev = imm_dev(cmd->device->host); in imm_completion()
644 unsigned short ppb = dev->base; in imm_completion()
650 v = cmd->cmnd[0]; in imm_completion()
678 if ((r & 0x88) != 0x88 || scsi_pointer->this_residual <= 0) { in imm_completion()
680 return -1; /* ERROR_RETURN */ in imm_completion()
683 if (dev->rd == 0) { in imm_completion()
684 fast = bulk && scsi_pointer->this_residual >= in imm_completion()
686 status = imm_out(dev, scsi_pointer->ptr, fast); in imm_completion()
688 fast = bulk && scsi_pointer->this_residual >= in imm_completion()
690 status = imm_in(dev, scsi_pointer->ptr, fast); in imm_completion()
693 scsi_pointer->ptr += fast; in imm_completion()
694 scsi_pointer->this_residual -= fast; in imm_completion()
698 return -1; /* ERROR_RETURN */ in imm_completion()
700 if (scsi_pointer->buffer && !scsi_pointer->this_residual) { in imm_completion()
702 if (scsi_pointer->buffers_residual--) { in imm_completion()
703 scsi_pointer->buffer = in imm_completion()
704 sg_next(scsi_pointer->buffer); in imm_completion()
705 scsi_pointer->this_residual = in imm_completion()
706 scsi_pointer->buffer->length; in imm_completion()
707 scsi_pointer->ptr = sg_virt(scsi_pointer->buffer); in imm_completion()
713 if (scsi_pointer->this_residual & 0x01) in imm_completion()
714 scsi_pointer->this_residual++; in imm_completion()
730 * the scheduler's task queue to generate a stream of call-backs and
736 struct scsi_cmnd *cmd = dev->cur_cmd; in imm_interrupt()
737 struct Scsi_Host *host = cmd->device->host; in imm_interrupt()
741 schedule_delayed_work(&dev->imm_tq, 1); in imm_interrupt()
746 switch ((cmd->result >> 16) & 0xff) { in imm_interrupt()
750 printk("imm: no device at SCSI ID %i\n", cmd->device->id); in imm_interrupt()
753 printk("imm: BUS BUSY - EPP timeout detected\n"); in imm_interrupt()
775 (cmd->result >> 16) & 0xff); in imm_interrupt()
779 if (imm_scsi_pointer(cmd)->phase > 1) in imm_interrupt()
784 spin_lock_irqsave(host->host_lock, flags); in imm_interrupt()
785 dev->cur_cmd = NULL; in imm_interrupt()
787 spin_unlock_irqrestore(host->host_lock, flags); in imm_interrupt()
794 unsigned short ppb = dev->base; in imm_engine()
801 if (dev->failed) in imm_engine()
804 switch (scsi_pointer->phase) { in imm_engine()
805 case 0: /* Phase 0 - Waiting for parport */ in imm_engine()
806 if (time_after(jiffies, dev->jstart + HZ)) { in imm_engine()
816 case 1: /* Phase 1 - Connected */ in imm_engine()
818 scsi_pointer->phase++; in imm_engine()
821 case 2: /* Phase 2 - We are now talking to the scsi bus */ in imm_engine()
826 scsi_pointer->phase++; in imm_engine()
829 case 3: /* Phase 3 - Ready to accept a command */ in imm_engine()
836 scsi_pointer->phase++; in imm_engine()
839 case 4: /* Phase 4 - Setup scatter/gather buffers */ in imm_engine()
841 scsi_pointer->buffer = scsi_sglist(cmd); in imm_engine()
842 scsi_pointer->this_residual = scsi_pointer->buffer->length; in imm_engine()
843 scsi_pointer->ptr = sg_virt(scsi_pointer->buffer); in imm_engine()
845 scsi_pointer->buffer = NULL; in imm_engine()
846 scsi_pointer->this_residual = 0; in imm_engine()
847 scsi_pointer->ptr = NULL; in imm_engine()
849 scsi_pointer->buffers_residual = scsi_sg_count(cmd) - 1; in imm_engine()
850 scsi_pointer->phase++; in imm_engine()
851 if (scsi_pointer->this_residual & 0x01) in imm_engine()
852 scsi_pointer->this_residual++; in imm_engine()
855 case 5: /* Phase 5 - Pre-Data transfer stage */ in imm_engine()
863 dev->rd = (x & 0x10) ? 1 : 0; in imm_engine()
864 dev->dp = (x & 0x20) ? 0 : 1; in imm_engine()
866 if ((dev->dp) && (dev->rd)) in imm_engine()
869 scsi_pointer->phase++; in imm_engine()
872 case 6: /* Phase 6 - Data transfer stage */ in imm_engine()
878 if (dev->dp) { in imm_engine()
880 if (retv == -1) in imm_engine()
885 scsi_pointer->phase++; in imm_engine()
888 case 7: /* Phase 7 - Post data transfer stage */ in imm_engine()
889 if ((dev->dp) && (dev->rd)) { in imm_engine()
890 if ((dev->mode == IMM_NIBBLE) || (dev->mode == IMM_PS2)) { in imm_engine()
897 scsi_pointer->phase++; in imm_engine()
900 case 8: /* Phase 8 - Read status/message */ in imm_engine()
912 cmd->result = (DID_OK << 16) | (l & STATUS_MASK); in imm_engine()
914 if ((dev->mode == IMM_NIBBLE) || (dev->mode == IMM_PS2)) { in imm_engine()
930 imm_struct *dev = imm_dev(cmd->device->host); in imm_queuecommand_lck()
932 if (dev->cur_cmd) { in imm_queuecommand_lck()
936 dev->failed = 0; in imm_queuecommand_lck()
937 dev->jstart = jiffies; in imm_queuecommand_lck()
938 dev->cur_cmd = cmd; in imm_queuecommand_lck()
939 cmd->result = DID_ERROR << 16; /* default return code */ in imm_queuecommand_lck()
940 imm_scsi_pointer(cmd)->phase = 0; /* bus free */ in imm_queuecommand_lck()
942 schedule_delayed_work(&dev->imm_tq, 0); in imm_queuecommand_lck()
952 * Apparently the disk->capacity attribute is off by 1 sector in DEF_SCSI_QCMD()
973 imm_struct *dev = imm_dev(cmd->device->host); in imm_abort()
979 switch (imm_scsi_pointer(cmd)->phase) { in imm_abort()
982 dev->cur_cmd = NULL; /* Forget the problem */ in imm_abort()
1003 imm_struct *dev = imm_dev(cmd->device->host); in imm_reset()
1005 if (imm_scsi_pointer(cmd)->phase) in imm_reset()
1007 dev->cur_cmd = NULL; /* Forget the problem */ in imm_reset()
1010 imm_reset_pulse(dev->base); in imm_reset()
1011 mdelay(1); /* device settle delay */ in imm_reset()
1013 mdelay(1); /* device settle delay */ in imm_reset()
1023 int loop, old_mode, status, k, ppb = dev->base; in device_check()
1026 old_mode = dev->mode; in device_check()
1030 dev->mode = IMM_EPP_8; in device_check()
1040 loop, IMM_MODE_STRING[dev->mode]); in device_check()
1051 imm_reset_pulse(dev->base); in device_check()
1055 if (dev->mode != old_mode) { in device_check()
1056 dev->mode = old_mode; in device_check()
1060 return -EIO; in device_check()
1067 k--; in device_check()
1076 imm_reset_pulse(dev->base); in device_check()
1080 if (dev->mode != old_mode) { in device_check()
1081 dev->mode = old_mode; in device_check()
1086 return -EIO; in device_check()
1091 ppb, loop, IMM_MODE_STRING[dev->mode]); in device_check()
1093 imm_reset_pulse(dev->base); in device_check()
1100 return -ENODEV; in device_check()
1140 if (dev->dev_no != cnt) in find_parent()
1156 int err = -ENOMEM; in __imm_attach()
1163 return -ENOMEM; in __imm_attach()
1166 dev->base = -1; in __imm_attach()
1167 dev->mode = mode < IMM_UNKNOWN ? mode : IMM_AUTODETECT; in __imm_attach()
1168 INIT_LIST_HEAD(&dev->list); in __imm_attach()
1172 dev->dev_no = temp->dev_no + 1; in __imm_attach()
1178 dev->dev = parport_register_dev_model(pb, "imm", &imm_cb, dev->dev_no); in __imm_attach()
1179 if (!dev->dev) in __imm_attach()
1186 err = -EBUSY; in __imm_attach()
1187 dev->waiting = &waiting; in __imm_attach()
1191 if (dev->wanted) { in __imm_attach()
1194 "time!\n", pb->number); in __imm_attach()
1196 dev->waiting = NULL; in __imm_attach()
1200 dev->waiting = NULL; in __imm_attach()
1202 dev->base = dev->dev->port->base; in __imm_attach()
1203 dev->base_hi = dev->dev->port->base_hi; in __imm_attach()
1204 w_ctr(dev->base, 0x0c); in __imm_attach()
1216 if (dev->mode == IMM_NIBBLE || dev->mode == IMM_PS2) in __imm_attach()
1221 INIT_DELAYED_WORK(&dev->imm_tq, imm_interrupt); in __imm_attach()
1223 err = -ENOMEM; in __imm_attach()
1227 host->no_highmem = true; in __imm_attach()
1228 host->io_port = pb->base; in __imm_attach()
1229 host->n_io_port = ports; in __imm_attach()
1230 host->dma_channel = -1; in __imm_attach()
1231 host->unique_id = pb->number; in __imm_attach()
1232 *(imm_struct **)&host->hostdata = dev; in __imm_attach()
1233 dev->host = host; in __imm_attach()
1235 list_add_tail(&dev->list, &imm_hosts); in __imm_attach()
1237 list_add_tail(&dev->list, &temp->list); in __imm_attach()
1245 list_del_init(&dev->list); in __imm_attach()
1248 parport_unregister_device(dev->dev); in __imm_attach()
1263 if (dev->dev->port == pb) { in imm_detach()
1264 list_del_init(&dev->list); in imm_detach()
1265 scsi_remove_host(dev->host); in imm_detach()
1266 scsi_host_put(dev->host); in imm_detach()
1267 parport_unregister_device(dev->dev); in imm_detach()