29 #include <linux/module.h>
30 #include <linux/kernel.h>
31 #include <linux/types.h>
33 #include <linux/string.h>
47 #define VERSION_STRING "Version 1.0.0-ac"
51 #define SCSI_FIFO 0x02
52 #define COMMAND_REG 0x03
53 #define STATUS_REG 0x04
54 #define DEST_BUS_ID 0x04
58 #define SYNC_OFFSET 0x07
59 #define CONF_REG_1 0x08
60 #define CONF_REG_2 0x0B
61 #define CONF_REG_3 0x0C
62 #define CONF_REG_4 0x0D
64 #define PIO_FIFO_1 0x10
65 #define PIO_FIFO_2 0x11
66 #define PIO_FIFO_3 0x12
67 #define PIO_FIFO_4 0x13
68 #define PIO_FIFO_CNT 0x14
69 #define PIO_INT_REG 0x15
70 #define CONF_REG_5 0x16
71 #define FEATURE_EN 0x1D
131 #define PHASE_DATA_OUT 0x00
132 #define PHASE_DATA_IN 0x01
133 #define PHASE_COMMAND 0x02
134 #define PHASE_STATUS 0x03
135 #define PHASE_RESERVED_1 0x04
136 #define PHASE_RESERVED_2 0x05
137 #define PHASE_MESSAGE_OUT 0x06
138 #define PHASE_MESSAGE_IN 0x07
142 #define FLUSH_FIFO 0x01
143 #define RESET_CHIP 0x02
144 #define RESET_SCSI_BUS 0x03
145 #define DISABLE_SEL_RESEL 0x45
146 #define RESEL_SEQ 0x40
147 #define SEL_WITHOUT_ATN_SEQ 0x41
148 #define SEL_WITH_ATN_SEQ 0x42
149 #define SEL_WITH_ATN_AND_STOP_SEQ 0x43
150 #define ENABLE_SEL_RESEL 0x44
151 #define SEL_WITH_ATN3_SEQ 0x46
152 #define RESEL3_SEQ 0x47
154 #define SND_STAT 0x21
155 #define SND_DATA 0x22
156 #define DISCONNECT_SEQ 0x23
157 #define TERMINATE_SEQ 0x24
158 #define TARGET_COMM_COMPLETE_SEQ 0x25
160 #define RECV_MSG_SEQ 0x28
161 #define RECV_CMD 0x29
162 #define RECV_DATA 0x2A
163 #define RECV_CMD_SEQ 0x2B
164 #define TARGET_ABORT_PIO 0x04
165 #define TRANSFER_INFORMATION 0x10
166 #define INIT_COMM_COMPLETE_SEQ 0x11
167 #define MSG_ACCEPTED 0x12
168 #define TRANSFER_PAD 0x18
170 #define RESET_ATN 0x1B
173 #define PIO_MODE 0x80
175 #define IO_RANGE 0x20
176 #define ID "sym53c416"
179 #define READ_TIMEOUT 150
180 #define WRITE_TIMEOUT 150
184 #define sym53c416_base sym53c416
185 #define sym53c416_base_1 sym53c416_1
186 #define sym53c416_base_2 sym53c416_2
187 #define sym53c416_base_3 sym53c416_3
189 static unsigned int sym53c416_base[2];
190 static unsigned int sym53c416_base_1[2];
191 static unsigned int sym53c416_base_2[2];
192 static unsigned int sym53c416_base_3[2];
198 #define SG_ADDRESS(buffer) ((char *) sg_virt((buffer)))
225 static int host_index = 0;
226 static char info[120];
228 static int fastpio = 1;
230 static int probeaddrs[] = {0x200, 0x220, 0x240, 0};
232 static void sym53c416_set_transfer_counter(
int base,
unsigned int len)
243 static __inline__ unsigned int sym53c416_read(
int base,
unsigned char *
buffer,
unsigned int len)
245 unsigned int orig_len = len;
246 unsigned long flags = 0;
247 unsigned int bytes_left;
253 while(len && timeout)
256 if(fastpio && bytes_left > 3)
259 buffer += bytes_left & 0xFC;
260 len -= bytes_left & 0xFC;
262 else if(bytes_left > 0)
265 for(; bytes_left > 0; bytes_left--)
271 spin_unlock_irqrestore(&sym53c416_lock, flags);
280 spin_unlock_irqrestore(&sym53c416_lock, flags);
281 return orig_len - len;
285 static __inline__ unsigned int sym53c416_write(
int base,
unsigned char *buffer,
unsigned int len)
287 unsigned int orig_len = len;
288 unsigned long flags = 0;
289 unsigned int bufferfree;
295 while(len && timeout)
300 if(fastpio && bufferfree > 3)
303 buffer += bufferfree & 0xFC;
304 len -= bufferfree & 0xFC;
306 else if(bufferfree > 0)
309 for(; bufferfree > 0; bufferfree--)
315 spin_unlock_irqrestore(&sym53c416_lock, flags);
323 spin_unlock_irqrestore(&sym53c416_lock, flags);
324 return orig_len - len;
332 unsigned long flags = 0;
333 unsigned char status_reg, pio_int_reg, int_reg;
335 unsigned int tot_trans = 0;
341 spin_unlock_irqrestore(dev->
host_lock, flags);
347 current_command->
SCp.phase =
idle;
350 current_command->
scsi_done(current_command);
351 spin_unlock_irqrestore(dev->
host_lock, flags);
357 current_command->
SCp.phase =
idle;
360 current_command->
scsi_done(current_command);
361 spin_unlock_irqrestore(dev->
host_lock, flags);
367 current_command->
SCp.phase =
idle;
370 current_command->
scsi_done(current_command);
371 spin_unlock_irqrestore(dev->
host_lock, flags);
377 current_command->
SCp.phase =
idle;
380 current_command->
scsi_done(current_command);
381 spin_unlock_irqrestore(dev->
host_lock, flags);
384 if(pio_int_reg & (
CE |
OUE))
387 current_command->
SCp.phase =
idle;
390 current_command->
scsi_done(current_command);
391 spin_unlock_irqrestore(dev->
host_lock, flags);
399 current_command->
result = (current_command->
SCp.Status & 0xFF) | ((current_command->
SCp.Message & 0xFF) << 8) | (
DID_OK << 16);
400 current_command->
SCp.phase =
idle;
402 current_command->
scsi_done(current_command);
403 spin_unlock_irqrestore(dev->
host_lock, flags);
408 switch(status_reg &
PHBITS)
416 sym53c416_set_transfer_counter(base,
417 scsi_bufflen(current_command));
421 sg, scsi_sg_count(current_command), i) {
422 tot_trans += sym53c416_write(base,
426 if(tot_trans < current_command->underflow)
438 sym53c416_set_transfer_counter(base,
439 scsi_bufflen(current_command));
444 sg, scsi_sg_count(current_command), i) {
445 tot_trans += sym53c416_read(base,
449 if(tot_trans < current_command->underflow)
458 printk(
KERN_ERR "sym53c416: Unknown interrupt in command phase.\n");
500 static void sym53c416_init(
int base,
int scsi_id)
515 static int sym53c416_probeirq(
int base,
int scsi_id)
525 sym53c416_init(base, scsi_id);
539 sym53c416_init(base, scsi_id);
553 if(ints[0] < 1 || ints[0] > 2)
559 for(i = 0; i < host_index && i >= 0; i++)
560 if(hosts[i].base == ints[1])
564 hosts[host_index].
base = ints[1];
565 hosts[host_index].
irq = (ints[0] == 2)? ints[2] : 0;
570 static int sym53c416_test(
int base)
589 { ISAPNP_DEVICE_SINGLE_END }
594 static void sym53c416_probe(
void)
596 int *base = probeaddrs;
600 for(; *base; base++) {
602 if (sym53c416_test(*base)) {
623 if(sym53c416_base[0])
625 ints[1] = sym53c416_base[0];
626 ints[2] = sym53c416_base[1];
629 if(sym53c416_base_1[0])
631 ints[1] = sym53c416_base_1[0];
632 ints[2] = sym53c416_base_1[1];
635 if(sym53c416_base_2[0])
637 ints[1] = sym53c416_base_2[0];
638 ints[2] = sym53c416_base_2[1];
641 if(sym53c416_base_3[0])
643 ints[1] = sym53c416_base_3[0];
644 ints[2] = sym53c416_base_3[1];
650 for (i=0; id_table[
i].vendor != 0; i++) {
652 id_table[i].
function, idev))!=
NULL)
670 i[1] = pnp_port_start(idev, 0);
673 printk(
KERN_INFO "sym53c416: ISAPnP card found and configured at 0x%X, IRQ %d.\n",
681 for(count = 0, i = 0; i < host_index; i++) {
684 if (!sym53c416_test(hosts[i].base)) {
686 goto fail_release_region;
691 hosts[
i].
irq = sym53c416_probeirq(hosts[i].base, hosts[i].scsi_id);
693 goto fail_release_region;
697 goto fail_release_region;
699 if (
request_irq(hosts[i].irq, sym53c416_intr_handle, 0,
ID, shpnt))
708 sym53c416_init(hosts[i].base, hosts[i].scsi_id);
710 spin_unlock_irqrestore(&sym53c416_lock, flags);
725 int irq = SChost->
irq;
729 for(i = 0; i < host_index; i++)
730 if(hosts[i].base == base)
732 sprintf(
info,
"Symbios Logic 53c416 (rev. %d) at 0x%03x, irq %d, SCSI-ID %d, %s pio", rev, base, irq, scsi_id, (fastpio)?
"fast" :
"slow");
739 unsigned long flags = 0;
743 base = SCpnt->
device->host->io_port;
744 current_command = SCpnt;
747 current_command->
SCp.Status = 0;
748 current_command->
SCp.Message = 0;
754 for(i = 0; i < SCpnt->
cmd_len; i++)
759 spin_unlock_irqrestore(&sym53c416_lock, flags);
765 static
int sym53c416_host_reset(
Scsi_Cmnd *SCpnt)
775 base = SCpnt->device->host->io_port;
777 for(i = 0; i < host_index && scsi_id == -1; i++)
778 if(hosts[i].base == base)
783 sym53c416_init(base, scsi_id);
785 spin_unlock_irqrestore(&sym53c416_lock, flags);
798 static int sym53c416_bios_param(
struct scsi_device *sdev,
807 if((ip[2] = size >> 11) > 1024)
811 ip[2] = size / (255 * 63);
830 .proc_name =
"sym53c416",
831 .name =
"Symbios Logic 53c416",
834 .queuecommand = sym53c416_queuecommand,
835 .eh_host_reset_handler =sym53c416_host_reset,
836 .release = sym53c416_release,
837 .bios_param = sym53c416_bios_param,
842 .unchecked_isa_dma = 1,