aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--i386/i386at/gpl/linux/block/cmd640.c738
-rw-r--r--i386/i386at/gpl/linux/block/floppy.c4100
-rw-r--r--i386/i386at/gpl/linux/block/genhd.c610
-rw-r--r--i386/i386at/gpl/linux/block/ide-cd.c2770
-rw-r--r--i386/i386at/gpl/linux/block/ide.c3087
-rw-r--r--i386/i386at/gpl/linux/block/ide.h655
-rw-r--r--i386/i386at/gpl/linux/block/ide_modes.h142
-rw-r--r--i386/i386at/gpl/linux/block/rz1000.c56
-rw-r--r--i386/i386at/gpl/linux/block/triton.c467
-rw-r--r--i386/i386at/gpl/linux/include/asm/bitops.h137
-rw-r--r--i386/i386at/gpl/linux/include/asm/byteorder.h90
-rw-r--r--i386/i386at/gpl/linux/include/asm/delay.h59
-rw-r--r--i386/i386at/gpl/linux/include/asm/dma.h271
-rw-r--r--i386/i386at/gpl/linux/include/asm/errno.h252
-rw-r--r--i386/i386at/gpl/linux/include/asm/fcntl.h64
-rw-r--r--i386/i386at/gpl/linux/include/asm/floppy.h56
-rw-r--r--i386/i386at/gpl/linux/include/asm/io.h213
-rw-r--r--i386/i386at/gpl/linux/include/asm/ioctl.h75
-rw-r--r--i386/i386at/gpl/linux/include/asm/irq.h346
-rw-r--r--i386/i386at/gpl/linux/include/asm/page.h64
-rw-r--r--i386/i386at/gpl/linux/include/asm/param.h20
-rw-r--r--i386/i386at/gpl/linux/include/asm/processor.h146
-rw-r--r--i386/i386at/gpl/linux/include/asm/ptrace.h52
-rw-r--r--i386/i386at/gpl/linux/include/asm/resource.h37
-rw-r--r--i386/i386at/gpl/linux/include/asm/segment.h347
-rw-r--r--i386/i386at/gpl/linux/include/asm/sigcontext.h29
-rw-r--r--i386/i386at/gpl/linux/include/asm/signal.h95
-rw-r--r--i386/i386at/gpl/linux/include/asm/socket.h31
-rw-r--r--i386/i386at/gpl/linux/include/asm/stat.h41
-rw-r--r--i386/i386at/gpl/linux/include/asm/statfs.h21
-rw-r--r--i386/i386at/gpl/linux/include/asm/string.h593
-rw-r--r--i386/i386at/gpl/linux/include/asm/system.h301
-rw-r--r--i386/i386at/gpl/linux/include/asm/termios.h304
-rw-r--r--i386/i386at/gpl/linux/include/asm/types.h109
-rw-r--r--i386/i386at/gpl/linux/include/asm/unistd.h322
-rw-r--r--i386/i386at/gpl/linux/include/linux/autoconf.h221
-rw-r--r--i386/i386at/gpl/linux/include/linux/binfmts.h60
-rw-r--r--i386/i386at/gpl/linux/include/linux/bios32.h61
-rw-r--r--i386/i386at/gpl/linux/include/linux/blk.h408
-rw-r--r--i386/i386at/gpl/linux/include/linux/blkdev.h56
-rw-r--r--i386/i386at/gpl/linux/include/linux/cdrom.h465
-rw-r--r--i386/i386at/gpl/linux/include/linux/config.h41
-rw-r--r--i386/i386at/gpl/linux/include/linux/delay.h14
-rw-r--r--i386/i386at/gpl/linux/include/linux/errno.h16
-rw-r--r--i386/i386at/gpl/linux/include/linux/etherdevice.h55
-rw-r--r--i386/i386at/gpl/linux/include/linux/fcntl.h6
-rw-r--r--i386/i386at/gpl/linux/include/linux/fd.h368
-rw-r--r--i386/i386at/gpl/linux/include/linux/fdreg.h127
-rw-r--r--i386/i386at/gpl/linux/include/linux/fs.h698
-rw-r--r--i386/i386at/gpl/linux/include/linux/genhd.h73
-rw-r--r--i386/i386at/gpl/linux/include/linux/hdreg.h171
-rw-r--r--i386/i386at/gpl/linux/include/linux/head.h19
-rw-r--r--i386/i386at/gpl/linux/include/linux/if.h167
-rw-r--r--i386/i386at/gpl/linux/include/linux/if_arp.h103
-rw-r--r--i386/i386at/gpl/linux/include/linux/if_ether.h96
-rw-r--r--i386/i386at/gpl/linux/include/linux/if_tr.h104
-rw-r--r--i386/i386at/gpl/linux/include/linux/igmp.h117
-rw-r--r--i386/i386at/gpl/linux/include/linux/in.h149
-rw-r--r--i386/i386at/gpl/linux/include/linux/inet.h52
-rw-r--r--i386/i386at/gpl/linux/include/linux/interrupt.h91
-rw-r--r--i386/i386at/gpl/linux/include/linux/ioctl.h7
-rw-r--r--i386/i386at/gpl/linux/include/linux/ioport.h31
-rw-r--r--i386/i386at/gpl/linux/include/linux/ip.h113
-rw-r--r--i386/i386at/gpl/linux/include/linux/ipc.h67
-rw-r--r--i386/i386at/gpl/linux/include/linux/kdev_t.h114
-rw-r--r--i386/i386at/gpl/linux/include/linux/kernel.h94
-rw-r--r--i386/i386at/gpl/linux/include/linux/kernel_stat.h32
-rw-r--r--i386/i386at/gpl/linux/include/linux/limits.h17
-rw-r--r--i386/i386at/gpl/linux/include/linux/linkage.h59
-rw-r--r--i386/i386at/gpl/linux/include/linux/locks.h66
-rw-r--r--i386/i386at/gpl/linux/include/linux/major.h119
-rw-r--r--i386/i386at/gpl/linux/include/linux/malloc.h16
-rw-r--r--i386/i386at/gpl/linux/include/linux/math_emu.h43
-rw-r--r--i386/i386at/gpl/linux/include/linux/mc146818rtc.h109
-rw-r--r--i386/i386at/gpl/linux/include/linux/minix_fs.h135
-rw-r--r--i386/i386at/gpl/linux/include/linux/minix_fs_sb.h25
-rw-r--r--i386/i386at/gpl/linux/include/linux/mm.h297
-rw-r--r--i386/i386at/gpl/linux/include/linux/module.h115
-rw-r--r--i386/i386at/gpl/linux/include/linux/mount.h30
-rw-r--r--i386/i386at/gpl/linux/include/linux/net.h132
-rw-r--r--i386/i386at/gpl/linux/include/linux/netdevice.h332
-rw-r--r--i386/i386at/gpl/linux/include/linux/nfs.h172
-rw-r--r--i386/i386at/gpl/linux/include/linux/notifier.h100
-rw-r--r--i386/i386at/gpl/linux/include/linux/pagemap.h131
-rw-r--r--i386/i386at/gpl/linux/include/linux/param.h6
-rw-r--r--i386/i386at/gpl/linux/include/linux/pci.h618
-rw-r--r--i386/i386at/gpl/linux/include/linux/personality.h51
-rw-r--r--i386/i386at/gpl/linux/include/linux/proc_fs.h269
-rw-r--r--i386/i386at/gpl/linux/include/linux/ptrace.h26
-rw-r--r--i386/i386at/gpl/linux/include/linux/quota.h219
-rw-r--r--i386/i386at/gpl/linux/include/linux/resource.h60
-rw-r--r--i386/i386at/gpl/linux/include/linux/route.h78
-rw-r--r--i386/i386at/gpl/linux/include/linux/sched.h492
-rw-r--r--i386/i386at/gpl/linux/include/linux/scsi.h198
-rw-r--r--i386/i386at/gpl/linux/include/linux/scsicam.h17
-rw-r--r--i386/i386at/gpl/linux/include/linux/sem.h112
-rw-r--r--i386/i386at/gpl/linux/include/linux/signal.h6
-rw-r--r--i386/i386at/gpl/linux/include/linux/skbuff.h474
-rw-r--r--i386/i386at/gpl/linux/include/linux/smp.h54
-rw-r--r--i386/i386at/gpl/linux/include/linux/socket.h126
-rw-r--r--i386/i386at/gpl/linux/include/linux/sockios.h91
-rw-r--r--i386/i386at/gpl/linux/include/linux/stat.h53
-rw-r--r--i386/i386at/gpl/linux/include/linux/stddef.h15
-rw-r--r--i386/i386at/gpl/linux/include/linux/string.h44
-rw-r--r--i386/i386at/gpl/linux/include/linux/tasks.h19
-rw-r--r--i386/i386at/gpl/linux/include/linux/tcp.h71
-rw-r--r--i386/i386at/gpl/linux/include/linux/termios.h7
-rw-r--r--i386/i386at/gpl/linux/include/linux/time.h50
-rw-r--r--i386/i386at/gpl/linux/include/linux/timer.h101
-rw-r--r--i386/i386at/gpl/linux/include/linux/tqueue.h163
-rw-r--r--i386/i386at/gpl/linux/include/linux/trdevice.h40
-rw-r--r--i386/i386at/gpl/linux/include/linux/tty.h340
-rw-r--r--i386/i386at/gpl/linux/include/linux/tty_driver.h189
-rw-r--r--i386/i386at/gpl/linux/include/linux/tty_ldisc.h46
-rw-r--r--i386/i386at/gpl/linux/include/linux/types.h72
-rw-r--r--i386/i386at/gpl/linux/include/linux/uio.h25
-rw-r--r--i386/i386at/gpl/linux/include/linux/unistd.h11
-rw-r--r--i386/i386at/gpl/linux/include/linux/utsname.h35
-rw-r--r--i386/i386at/gpl/linux/include/linux/version.h8
-rw-r--r--i386/i386at/gpl/linux/include/linux/vfs.h6
-rw-r--r--i386/i386at/gpl/linux/include/linux/vm86.h109
-rw-r--r--i386/i386at/gpl/linux/include/linux/wait.h38
-rw-r--r--i386/i386at/gpl/linux/include/net/af_unix.h4
-rw-r--r--i386/i386at/gpl/linux/include/net/arp.h17
-rw-r--r--i386/i386at/gpl/linux/include/net/atalkcall.h2
-rw-r--r--i386/i386at/gpl/linux/include/net/ax25.h246
-rw-r--r--i386/i386at/gpl/linux/include/net/ax25call.h2
-rw-r--r--i386/i386at/gpl/linux/include/net/checksum.h25
-rw-r--r--i386/i386at/gpl/linux/include/net/datalink.h16
-rw-r--r--i386/i386at/gpl/linux/include/net/icmp.h40
-rw-r--r--i386/i386at/gpl/linux/include/net/ip.h154
-rw-r--r--i386/i386at/gpl/linux/include/net/ip_alias.h23
-rw-r--r--i386/i386at/gpl/linux/include/net/ip_forward.h10
-rw-r--r--i386/i386at/gpl/linux/include/net/ipip.h4
-rw-r--r--i386/i386at/gpl/linux/include/net/ipx.h85
-rw-r--r--i386/i386at/gpl/linux/include/net/ipxcall.h2
-rw-r--r--i386/i386at/gpl/linux/include/net/netlink.h26
-rw-r--r--i386/i386at/gpl/linux/include/net/netrom.h139
-rw-r--r--i386/i386at/gpl/linux/include/net/nrcall.h2
-rw-r--r--i386/i386at/gpl/linux/include/net/p8022.h2
-rw-r--r--i386/i386at/gpl/linux/include/net/p8022call.h2
-rw-r--r--i386/i386at/gpl/linux/include/net/protocol.h55
-rw-r--r--i386/i386at/gpl/linux/include/net/psnap.h2
-rw-r--r--i386/i386at/gpl/linux/include/net/psnapcall.h2
-rw-r--r--i386/i386at/gpl/linux/include/net/rarp.h12
-rw-r--r--i386/i386at/gpl/linux/include/net/raw.h34
-rw-r--r--i386/i386at/gpl/linux/include/net/route.h280
-rw-r--r--i386/i386at/gpl/linux/include/net/slhc.h6
-rw-r--r--i386/i386at/gpl/linux/include/net/snmp.h107
-rw-r--r--i386/i386at/gpl/linux/include/net/sock.h486
-rw-r--r--i386/i386at/gpl/linux/include/net/tcp.h329
-rw-r--r--i386/i386at/gpl/linux/include/net/udp.h52
-rw-r--r--i386/i386at/gpl/linux/linux_autoirq.c161
-rw-r--r--i386/i386at/gpl/linux/linux_block.c1625
-rw-r--r--i386/i386at/gpl/linux/linux_dma.c52
-rw-r--r--i386/i386at/gpl/linux/linux_emul.h32
-rw-r--r--i386/i386at/gpl/linux/linux_init.c416
-rw-r--r--i386/i386at/gpl/linux/linux_irq.c246
-rw-r--r--i386/i386at/gpl/linux/linux_kmem.c480
-rw-r--r--i386/i386at/gpl/linux/linux_misc.c303
-rw-r--r--i386/i386at/gpl/linux/linux_net.c520
-rw-r--r--i386/i386at/gpl/linux/linux_port.c79
-rw-r--r--i386/i386at/gpl/linux/linux_printk.c47
-rw-r--r--i386/i386at/gpl/linux/linux_sched.c237
-rw-r--r--i386/i386at/gpl/linux/linux_soft.c74
-rw-r--r--i386/i386at/gpl/linux/linux_timer.c190
-rw-r--r--i386/i386at/gpl/linux/linux_version.c33
-rw-r--r--i386/i386at/gpl/linux/linux_vsprintf.c341
-rw-r--r--i386/i386at/gpl/linux/net/3c501.c860
-rw-r--r--i386/i386at/gpl/linux/net/3c503.c627
-rw-r--r--i386/i386at/gpl/linux/net/3c503.h91
-rw-r--r--i386/i386at/gpl/linux/net/3c505.c1518
-rw-r--r--i386/i386at/gpl/linux/net/3c505.h245
-rw-r--r--i386/i386at/gpl/linux/net/3c507.c923
-rw-r--r--i386/i386at/gpl/linux/net/3c509.c739
-rw-r--r--i386/i386at/gpl/linux/net/3c59x.c1066
-rw-r--r--i386/i386at/gpl/linux/net/8390.c727
-rw-r--r--i386/i386at/gpl/linux/net/8390.h168
-rw-r--r--i386/i386at/gpl/linux/net/Space.c400
-rw-r--r--i386/i386at/gpl/linux/net/ac3200.c385
-rw-r--r--i386/i386at/gpl/linux/net/apricot.c1046
-rw-r--r--i386/i386at/gpl/linux/net/at1700.c677
-rw-r--r--i386/i386at/gpl/linux/net/atp.c787
-rw-r--r--i386/i386at/gpl/linux/net/atp.h264
-rw-r--r--i386/i386at/gpl/linux/net/de4x5.c2788
-rw-r--r--i386/i386at/gpl/linux/net/de4x5.h645
-rw-r--r--i386/i386at/gpl/linux/net/de600.c853
-rw-r--r--i386/i386at/gpl/linux/net/de620.c1045
-rw-r--r--i386/i386at/gpl/linux/net/de620.h117
-rw-r--r--i386/i386at/gpl/linux/net/depca.c1901
-rw-r--r--i386/i386at/gpl/linux/net/depca.h185
-rw-r--r--i386/i386at/gpl/linux/net/dev.c1413
-rw-r--r--i386/i386at/gpl/linux/net/e2100.c456
-rw-r--r--i386/i386at/gpl/linux/net/eepro.c1169
-rw-r--r--i386/i386at/gpl/linux/net/eexpress.c1034
-rw-r--r--i386/i386at/gpl/linux/net/eth16i.c1214
-rw-r--r--i386/i386at/gpl/linux/net/ewrk3.c1933
-rw-r--r--i386/i386at/gpl/linux/net/ewrk3.h322
-rw-r--r--i386/i386at/gpl/linux/net/hp-plus.c483
-rw-r--r--i386/i386at/gpl/linux/net/hp.c451
-rw-r--r--i386/i386at/gpl/linux/net/hp100.c1144
-rw-r--r--i386/i386at/gpl/linux/net/hp100.h374
-rw-r--r--i386/i386at/gpl/linux/net/i82586.h408
-rw-r--r--i386/i386at/gpl/linux/net/iow.h6
-rw-r--r--i386/i386at/gpl/linux/net/lance.c1129
-rw-r--r--i386/i386at/gpl/linux/net/ne.c733
-rw-r--r--i386/i386at/gpl/linux/net/net_init.c380
-rw-r--r--i386/i386at/gpl/linux/net/ni52.c1110
-rw-r--r--i386/i386at/gpl/linux/net/ni52.h284
-rw-r--r--i386/i386at/gpl/linux/net/ni65.c648
-rw-r--r--i386/i386at/gpl/linux/net/ni65.h130
-rw-r--r--i386/i386at/gpl/linux/net/seeq8005.c760
-rw-r--r--i386/i386at/gpl/linux/net/seeq8005.h156
-rw-r--r--i386/i386at/gpl/linux/net/sk_g16.c2111
-rw-r--r--i386/i386at/gpl/linux/net/sk_g16.h171
-rw-r--r--i386/i386at/gpl/linux/net/smc-ultra.c419
-rw-r--r--i386/i386at/gpl/linux/net/tulip.c782
-rw-r--r--i386/i386at/gpl/linux/net/wavelan.c2526
-rw-r--r--i386/i386at/gpl/linux/net/wavelan.h252
-rw-r--r--i386/i386at/gpl/linux/net/wd.c513
-rw-r--r--i386/i386at/gpl/linux/net/znet.c746
-rw-r--r--i386/i386at/gpl/linux/pci/bios32.c466
-rw-r--r--i386/i386at/gpl/linux/pci/pci.c917
-rw-r--r--i386/i386at/gpl/linux/scsi/53c7,8xx.h1584
-rw-r--r--i386/i386at/gpl/linux/scsi/53c78xx.c6381
-rw-r--r--i386/i386at/gpl/linux/scsi/53c8xx_d.h2677
-rw-r--r--i386/i386at/gpl/linux/scsi/53c8xx_u.h97
-rw-r--r--i386/i386at/gpl/linux/scsi/AM53C974.c2249
-rw-r--r--i386/i386at/gpl/linux/scsi/AM53C974.h419
-rw-r--r--i386/i386at/gpl/linux/scsi/BusLogic.c2779
-rw-r--r--i386/i386at/gpl/linux/scsi/BusLogic.h977
-rw-r--r--i386/i386at/gpl/linux/scsi/NCR5380.h363
-rw-r--r--i386/i386at/gpl/linux/scsi/NCR5380.src3035
-rw-r--r--i386/i386at/gpl/linux/scsi/NCR53c406a.c1079
-rw-r--r--i386/i386at/gpl/linux/scsi/NCR53c406a.h83
-rw-r--r--i386/i386at/gpl/linux/scsi/advansys.c9061
-rw-r--r--i386/i386at/gpl/linux/scsi/advansys.h131
-rw-r--r--i386/i386at/gpl/linux/scsi/aha152x.c2985
-rw-r--r--i386/i386at/gpl/linux/scsi/aha152x.h373
-rw-r--r--i386/i386at/gpl/linux/scsi/aha1542.c1323
-rw-r--r--i386/i386at/gpl/linux/scsi/aha1542.h177
-rw-r--r--i386/i386at/gpl/linux/scsi/aha1740.c531
-rw-r--r--i386/i386at/gpl/linux/scsi/aha1740.h193
-rw-r--r--i386/i386at/gpl/linux/scsi/aic7xxx.c4645
-rw-r--r--i386/i386at/gpl/linux/scsi/aic7xxx.h67
-rw-r--r--i386/i386at/gpl/linux/scsi/aic7xxx_proc.src271
-rw-r--r--i386/i386at/gpl/linux/scsi/aic7xxx_reg.h746
-rw-r--r--i386/i386at/gpl/linux/scsi/aic7xxx_seq.h374
-rw-r--r--i386/i386at/gpl/linux/scsi/constants.c649
-rw-r--r--i386/i386at/gpl/linux/scsi/constants.h6
-rw-r--r--i386/i386at/gpl/linux/scsi/eata.c1099
-rw-r--r--i386/i386at/gpl/linux/scsi/eata.h41
-rw-r--r--i386/i386at/gpl/linux/scsi/eata_dma.c1375
-rw-r--r--i386/i386at/gpl/linux/scsi/eata_dma.h119
-rw-r--r--i386/i386at/gpl/linux/scsi/eata_dma_proc.h260
-rw-r--r--i386/i386at/gpl/linux/scsi/eata_dma_proc.src488
-rw-r--r--i386/i386at/gpl/linux/scsi/eata_generic.h397
-rw-r--r--i386/i386at/gpl/linux/scsi/eata_pio.c1051
-rw-r--r--i386/i386at/gpl/linux/scsi/eata_pio.h116
-rw-r--r--i386/i386at/gpl/linux/scsi/eata_pio_proc.src150
-rw-r--r--i386/i386at/gpl/linux/scsi/fdomain.c2016
-rw-r--r--i386/i386at/gpl/linux/scsi/fdomain.h61
-rw-r--r--i386/i386at/gpl/linux/scsi/g_NCR5380.c588
-rw-r--r--i386/i386at/gpl/linux/scsi/g_NCR5380.h166
-rw-r--r--i386/i386at/gpl/linux/scsi/hosts.c440
-rw-r--r--i386/i386at/gpl/linux/scsi/hosts.h409
-rw-r--r--i386/i386at/gpl/linux/scsi/in2000.c731
-rw-r--r--i386/i386at/gpl/linux/scsi/in2000.h122
-rw-r--r--i386/i386at/gpl/linux/scsi/pas16.c553
-rw-r--r--i386/i386at/gpl/linux/scsi/pas16.h193
-rw-r--r--i386/i386at/gpl/linux/scsi/qlogic.c678
-rw-r--r--i386/i386at/gpl/linux/scsi/qlogic.h40
-rw-r--r--i386/i386at/gpl/linux/scsi/scsi.c3206
-rw-r--r--i386/i386at/gpl/linux/scsi/scsi.h618
-rw-r--r--i386/i386at/gpl/linux/scsi/scsi_debug.c710
-rw-r--r--i386/i386at/gpl/linux/scsi/scsi_debug.h30
-rw-r--r--i386/i386at/gpl/linux/scsi/scsi_ioctl.c397
-rw-r--r--i386/i386at/gpl/linux/scsi/scsi_ioctl.h21
-rw-r--r--i386/i386at/gpl/linux/scsi/scsi_proc.c317
-rw-r--r--i386/i386at/gpl/linux/scsi/scsicam.c214
-rw-r--r--i386/i386at/gpl/linux/scsi/sd.c1543
-rw-r--r--i386/i386at/gpl/linux/scsi/sd.h65
-rw-r--r--i386/i386at/gpl/linux/scsi/sd_ioctl.c94
-rw-r--r--i386/i386at/gpl/linux/scsi/seagate.c1744
-rw-r--r--i386/i386at/gpl/linux/scsi/seagate.h139
-rw-r--r--i386/i386at/gpl/linux/scsi/sr.c1191
-rw-r--r--i386/i386at/gpl/linux/scsi/sr.h40
-rw-r--r--i386/i386at/gpl/linux/scsi/sr_ioctl.c489
-rw-r--r--i386/i386at/gpl/linux/scsi/t128.c413
-rw-r--r--i386/i386at/gpl/linux/scsi/t128.h176
-rw-r--r--i386/i386at/gpl/linux/scsi/u14-34f.c1044
-rw-r--r--i386/i386at/gpl/linux/scsi/u14-34f.h38
-rw-r--r--i386/i386at/gpl/linux/scsi/ultrastor.c1160
-rw-r--r--i386/i386at/gpl/linux/scsi/ultrastor.h102
-rw-r--r--i386/i386at/gpl/linux/scsi/wd7000.c1237
-rw-r--r--i386/i386at/gpl/linux/scsi/wd7000.h55
296 files changed, 0 insertions, 146223 deletions
diff --git a/i386/i386at/gpl/linux/block/cmd640.c b/i386/i386at/gpl/linux/block/cmd640.c
deleted file mode 100644
index 99a139dc..00000000
--- a/i386/i386at/gpl/linux/block/cmd640.c
+++ /dev/null
@@ -1,738 +0,0 @@
-/*
- * linux/drivers/block/cmd640.c Version 0.07 Jan 27, 1996
- *
- * Copyright (C) 1995-1996 Linus Torvalds & author (see below)
- */
-
-/*
- * Principal Author/Maintainer: abramov@cecmow.enet.dec.com (Igor Abramov)
- *
- * This file provides support for the advanced features and bugs
- * of IDE interfaces using the CMD Technologies 0640 IDE interface chip.
- *
- * Version 0.01 Initial version, hacked out of ide.c,
- * and #include'd rather than compiled separately.
- * This will get cleaned up in a subsequent release.
- *
- * Version 0.02 Fixes for vlb initialization code, enable
- * read-ahead for versions 'B' and 'C' of chip by
- * default, some code cleanup.
- *
- * Version 0.03 Added reset of secondary interface,
- * and black list for devices which are not compatible
- * with read ahead mode. Separate function for setting
- * readahead is added, possibly it will be called some
- * day from ioctl processing code.
- *
- * Version 0.04 Now configs/compiles separate from ide.c -ml
- *
- * Version 0.05 Major rewrite of interface timing code.
- * Added new function cmd640_set_mode to set PIO mode
- * from ioctl call. New drives added to black list.
- *
- * Version 0.06 More code cleanup. Readahead is enabled only for
- * detected hard drives, not included in readahed
- * black list.
- *
- * Version 0.07 Changed to more conservative drive tuning policy.
- * Unknown drives, which report PIO < 4 are set to
- * (reported_PIO - 1) if it is supported, or to PIO0.
- * List of known drives extended by info provided by
- * CMD at their ftp site.
- *
- * Version 0.08 Added autotune/noautotune support. -ml
- *
- */
-
-#undef REALLY_SLOW_IO /* most systems can safely undef this */
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
-#include <linux/ioport.h>
-#include <linux/blkdev.h>
-#include <linux/hdreg.h>
-#include <asm/io.h>
-#include "ide.h"
-#include "ide_modes.h"
-
-int cmd640_vlb = 0;
-
-/*
- * CMD640 specific registers definition.
- */
-
-#define VID 0x00
-#define DID 0x02
-#define PCMD 0x04
-#define PSTTS 0x06
-#define REVID 0x08
-#define PROGIF 0x09
-#define SUBCL 0x0a
-#define BASCL 0x0b
-#define BaseA0 0x10
-#define BaseA1 0x14
-#define BaseA2 0x18
-#define BaseA3 0x1c
-#define INTLINE 0x3c
-#define INPINE 0x3d
-
-#define CFR 0x50
-#define CFR_DEVREV 0x03
-#define CFR_IDE01INTR 0x04
-#define CFR_DEVID 0x18
-#define CFR_AT_VESA_078h 0x20
-#define CFR_DSA1 0x40
-#define CFR_DSA0 0x80
-
-#define CNTRL 0x51
-#define CNTRL_DIS_RA0 0x40
-#define CNTRL_DIS_RA1 0x80
-#define CNTRL_ENA_2ND 0x08
-
-#define CMDTIM 0x52
-#define ARTTIM0 0x53
-#define DRWTIM0 0x54
-#define ARTTIM1 0x55
-#define DRWTIM1 0x56
-#define ARTTIM23 0x57
-#define DIS_RA2 0x04
-#define DIS_RA3 0x08
-#define DRWTIM23 0x58
-#define BRST 0x59
-
-static ide_tuneproc_t cmd640_tune_drive;
-
-/* Interface to access cmd640x registers */
-static void (*put_cmd640_reg)(int reg_no, int val);
-static byte (*get_cmd640_reg)(int reg_no);
-
-enum { none, vlb, pci1, pci2 };
-static int bus_type = none;
-static int cmd640_chip_version;
-static int cmd640_key;
-static int bus_speed; /* MHz */
-
-/*
- * For some unknown reasons pcibios functions which read and write registers
- * do not always work with cmd640. We use direct IO instead.
- */
-
-/* PCI method 1 access */
-
-static void put_cmd640_reg_pci1(int reg_no, int val)
-{
- unsigned long flags;
-
- save_flags(flags);
- cli();
- outl_p((reg_no & 0xfc) | cmd640_key, 0xcf8);
- outb_p(val, (reg_no & 3) + 0xcfc);
- restore_flags(flags);
-}
-
-static byte get_cmd640_reg_pci1(int reg_no)
-{
- byte b;
- unsigned long flags;
-
- save_flags(flags);
- cli();
- outl_p((reg_no & 0xfc) | cmd640_key, 0xcf8);
- b = inb_p(0xcfc + (reg_no & 3));
- restore_flags(flags);
- return b;
-}
-
-/* PCI method 2 access (from CMD datasheet) */
-
-static void put_cmd640_reg_pci2(int reg_no, int val)
-{
- unsigned long flags;
-
- save_flags(flags);
- cli();
- outb_p(0x10, 0xcf8);
- outb_p(val, cmd640_key + reg_no);
- outb_p(0, 0xcf8);
- restore_flags(flags);
-}
-
-static byte get_cmd640_reg_pci2(int reg_no)
-{
- byte b;
- unsigned long flags;
-
- save_flags(flags);
- cli();
- outb_p(0x10, 0xcf8);
- b = inb_p(cmd640_key + reg_no);
- outb_p(0, 0xcf8);
- restore_flags(flags);
- return b;
-}
-
-/* VLB access */
-
-static void put_cmd640_reg_vlb(int reg_no, int val)
-{
- unsigned long flags;
-
- save_flags(flags);
- cli();
- outb_p(reg_no, cmd640_key + 8);
- outb_p(val, cmd640_key + 0xc);
- restore_flags(flags);
-}
-
-static byte get_cmd640_reg_vlb(int reg_no)
-{
- byte b;
- unsigned long flags;
-
- save_flags(flags);
- cli();
- outb_p(reg_no, cmd640_key + 8);
- b = inb_p(cmd640_key + 0xc);
- restore_flags(flags);
- return b;
-}
-
-/*
- * Probe for CMD640x -- pci method 1
- */
-
-static int probe_for_cmd640_pci1(void)
-{
- long id;
- int k;
-
- for (k = 0x80000000; k <= 0x8000f800; k += 0x800) {
- outl(k, 0xcf8);
- id = inl(0xcfc);
- if (id != 0x06401095)
- continue;
- put_cmd640_reg = put_cmd640_reg_pci1;
- get_cmd640_reg = get_cmd640_reg_pci1;
- cmd640_key = k;
- return 1;
- }
- return 0;
-}
-
-/*
- * Probe for CMD640x -- pci method 2
- */
-
-static int probe_for_cmd640_pci2(void)
-{
- int i;
- int v_id;
- int d_id;
-
- for (i = 0xc000; i <= 0xcf00; i += 0x100) {
- outb(0x10, 0xcf8);
- v_id = inw(i);
- d_id = inw(i + 2);
- outb(0, 0xcf8);
- if (v_id != 0x1095 || d_id != 0x640)
- continue;
- put_cmd640_reg = put_cmd640_reg_pci2;
- get_cmd640_reg = get_cmd640_reg_pci2;
- cmd640_key = i;
- return 1;
- }
- return 0;
-}
-
-/*
- * Probe for CMD640x -- vlb
- */
-
-static int probe_for_cmd640_vlb(void) {
- byte b;
-
- outb(CFR, 0x178);
- b = inb(0x17c);
- if (b == 0xff || b == 0 || (b & CFR_AT_VESA_078h)) {
- outb(CFR, 0x78);
- b = inb(0x7c);
- if (b == 0xff || b == 0 || !(b & CFR_AT_VESA_078h))
- return 0;
- cmd640_key = 0x70;
- } else {
- cmd640_key = 0x170;
- }
- put_cmd640_reg = put_cmd640_reg_vlb;
- get_cmd640_reg = get_cmd640_reg_vlb;
- return 1;
-}
-
-/*
- * Low level reset for controller, actually it has nothing specific for
- * CMD640, but I don't know how to use standard reset routine before
- * we recognized any drives.
- */
-
-static void cmd640_reset_controller(int iface_no)
-{
- int retry_count = 600;
- int base_port = iface_no ? 0x170 : 0x1f0;
-
- outb_p(4, base_port + 7);
- udelay(5);
- outb_p(0, base_port + 7);
-
- do {
- udelay(5);
- retry_count -= 1;
- } while ((inb_p(base_port + 7) & 0x80) && retry_count);
-
- if (retry_count == 0)
- printk("cmd640: failed to reset controller %d\n", iface_no);
-#if 0
- else
- printk("cmd640: controller %d reset [%d]\n",
- iface_no, retry_count);
-#endif
-}
-
-/*
- * Probe for Cmd640x and initialize it if found
- */
-
-int ide_probe_for_cmd640x(void)
-{
- int second_port;
- byte b;
-
- if (probe_for_cmd640_pci1()) {
- bus_type = pci1;
- } else if (probe_for_cmd640_pci2()) {
- bus_type = pci2;
- } else if (cmd640_vlb && probe_for_cmd640_vlb()) {
- /* May be remove cmd640_vlb at all, and probe in any case */
- bus_type = vlb;
- } else {
- return 0;
- }
-
- ide_hwifs[0].serialized = 1; /* ensure this *always* gets set */
-
-#if 0
- /* Dump initial state of chip registers */
- for (b = 0; b != 0xff; b++) {
- printk(" %2x%c", get_cmd640_reg(b),
- ((b&0xf) == 0xf) ? '\n' : ',');
- }
-
-#endif
-
- /*
- * Undocumented magic. (There is no 0x5b port in specs)
- */
-
- put_cmd640_reg(0x5b, 0xbd);
- if (get_cmd640_reg(0x5b) != 0xbd) {
- printk("ide: can't initialize cmd640 -- wrong value in 0x5b\n");
- return 0;
- }
- put_cmd640_reg(0x5b, 0);
-
- /*
- * Documented magic.
- */
-
- cmd640_chip_version = get_cmd640_reg(CFR) & CFR_DEVREV;
- if (cmd640_chip_version == 0) {
- printk ("ide: wrong CMD640 version -- 0\n");
- return 0;
- }
-
- /*
- * Setup the most conservative timings for all drives,
- */
- put_cmd640_reg(ARTTIM0, 0xc0);
- put_cmd640_reg(ARTTIM1, 0xc0);
- put_cmd640_reg(ARTTIM23, 0xcc); /* 0xc0? */
-
- /*
- * Do not initialize secondary controller for vlbus
- */
- second_port = (bus_type != vlb);
-
- /*
- * Set the maximum allowed bus speed (it is safest until we
- * find how to detect bus speed)
- * Normally PCI bus runs at 33MHz, but often works overclocked to 40
- */
- bus_speed = (bus_type == vlb) ? 50 : 40;
-
- /*
- * Setup Control Register
- */
- b = get_cmd640_reg(CNTRL);
-
- if (second_port)
- b |= CNTRL_ENA_2ND;
- else
- b &= ~CNTRL_ENA_2ND;
-
- /*
- * Disable readahead for drives at primary interface
- */
- b |= (CNTRL_DIS_RA0 | CNTRL_DIS_RA1);
-
- put_cmd640_reg(CNTRL, b);
-
- /*
- * Note that we assume that the first interface is at 0x1f0,
- * and that the second interface, if enabled, is at 0x170.
- */
- ide_hwifs[0].chipset = ide_cmd640;
- ide_hwifs[0].tuneproc = &cmd640_tune_drive;
- if (ide_hwifs[0].drives[0].autotune == 0)
- ide_hwifs[0].drives[0].autotune = 1;
- if (ide_hwifs[0].drives[1].autotune == 0)
- ide_hwifs[0].drives[1].autotune = 1;
-
- /*
- * Initialize 2nd IDE port, if required
- */
- if (second_port) {
- ide_hwifs[1].chipset = ide_cmd640;
- ide_hwifs[1].tuneproc = &cmd640_tune_drive;
- if (ide_hwifs[1].drives[0].autotune == 0)
- ide_hwifs[1].drives[0].autotune = 1;
- if (ide_hwifs[1].drives[1].autotune == 0)
- ide_hwifs[1].drives[1].autotune = 1;
- /* We reset timings, and disable read-ahead */
- put_cmd640_reg(ARTTIM23, (DIS_RA2 | DIS_RA3));
- put_cmd640_reg(DRWTIM23, 0);
-
- cmd640_reset_controller(1);
- }
-
- printk("ide: buggy CMD640%c interface at ",
- 'A' - 1 + cmd640_chip_version);
- switch (bus_type) {
- case vlb :
- printk("local bus, port 0x%x", cmd640_key);
- break;
- case pci1:
- printk("pci, (0x%x)", cmd640_key);
- break;
- case pci2:
- printk("pci,(access method 2) (0x%x)", cmd640_key);
- break;
- }
-
- /*
- * Reset interface timings
- */
- put_cmd640_reg(CMDTIM, 0);
-
- printk("\n ... serialized, secondary interface %s\n",
- second_port ? "enabled" : "disabled");
-
- return 1;
-}
-
-int cmd640_off(void) {
- static int a = 0;
- byte b;
-
- if (bus_type == none || a == 1)
- return 0;
- a = 1;
- b = get_cmd640_reg(CNTRL);
- b &= ~CNTRL_ENA_2ND;
- put_cmd640_reg(CNTRL, b);
- return 1;
-}
-
-/*
- * Sets readahead mode for specific drive
- * in the future it could be called from ioctl
- */
-
-static void set_readahead_mode(int mode, int if_num, int dr_num)
-{
- static int masks[2][2] =
- {
- {CNTRL_DIS_RA0, CNTRL_DIS_RA1},
- {DIS_RA2, DIS_RA3}
- };
-
- int port = (if_num == 0) ? CNTRL : ARTTIM23;
- int mask = masks[if_num][dr_num];
- byte b;
-
- b = get_cmd640_reg(port);
- if (mode)
- b &= ~mask; /* Enable readahead for specific drive */
- else
- b |= mask; /* Disable readahed for specific drive */
- put_cmd640_reg(port, b);
-}
-
-static struct readahead_black_list {
- const char* name;
- int mode;
-} drives_ra[] = {
- { "ST3655A", 0 },
- { "SAMSUNG", 0 }, /* Be conservative */
- { NULL, 0 }
-};
-
-static int strmatch(const char* pattern, const char* name) {
- char c1, c2;
-
- while (1) {
- c1 = *pattern++;
- c2 = *name++;
- if (c1 == 0) {
- return 0;
- }
- if (c1 != c2)
- return 1;
- }
-}
-
-static int known_drive_readahead(char* name) {
- int i;
-
- for (i = 0; drives_ra[i].name != NULL; i++) {
- if (strmatch(drives_ra[i].name, name) == 0) {
- return drives_ra[i].mode;
- }
- }
- return -1;
-}
-
-static int arttim[4] = {2, 2, 2, 2}; /* Address setup count (in clocks) */
-static int a_count[4] = {1, 1, 1, 1}; /* Active count (encoded) */
-static int r_count[4] = {1, 1, 1, 1}; /* Recovery count (encoded) */
-
-/*
- * Convert address setup count from number of clocks
- * to representation used by controller
- */
-
-inline static int pack_arttim(int clocks)
-{
- if (clocks <= 2) return 0x40;
- else if (clocks == 3) return 0x80;
- else if (clocks == 4) return 0x00;
- else return 0xc0;
-}
-
-/*
- * Pack active and recovery counts into single byte representation
- * used by controller
- */
-
-inline static int pack_counts(int act_count, int rec_count)
-{
- return ((act_count & 0x0f)<<4) | (rec_count & 0x0f);
-}
-
-inline int max(int a, int b) { return a > b ? a : b; }
-inline int max4(int *p) { return max(p[0], max(p[1], max(p[2], p[3]))); }
-
-/*
- * Set timing parameters
- */
-
-static void cmd640_set_timing(int if_num, int dr_num)
-{
- int b_reg;
- int ac, rc, at;
-
- /*
- * Set address setup count and drive read/write timing registers.
- * Primary interface has individual count/timing registers for
- * each drive. Secondary interface has common set of registers, and
- * we should set timings for the slowest drive.
- */
-
- if (if_num == 0) {
- b_reg = dr_num ? ARTTIM1 : ARTTIM0;
- at = arttim[dr_num];
- ac = a_count[dr_num];
- rc = r_count[dr_num];
- } else {
- b_reg = ARTTIM23;
- at = max(arttim[2], arttim[3]);
- ac = max(a_count[2], a_count[3]);
- rc = max(r_count[2], r_count[3]);
- }
-
- put_cmd640_reg(b_reg, pack_arttim(at));
- put_cmd640_reg(b_reg + 1, pack_counts(ac, rc));
-
- /*
- * Update CMDTIM (IDE Command Block Timing Register)
- */
-
- ac = max4(r_count);
- rc = max4(a_count);
- put_cmd640_reg(CMDTIM, pack_counts(ac, rc));
-}
-
-/*
- * Standard timings for PIO modes
- */
-
-static struct pio_timing {
- int mc_time; /* Minimal cycle time (ns) */
- int av_time; /* Address valid to DIOR-/DIOW- setup (ns) */
- int ds_time; /* DIOR data setup (ns) */
-} pio_timings[6] = {
- { 70, 165, 600 }, /* PIO Mode 0 */
- { 50, 125, 383 }, /* PIO Mode 1 */
- { 30, 100, 240 }, /* PIO Mode 2 */
- { 30, 80, 180 }, /* PIO Mode 3 */
- { 25, 70, 125 }, /* PIO Mode 4 -- should be 120, not 125 */
- { 20, 50, 100 } /* PIO Mode ? (nonstandard) */
-};
-
-static void cmd640_timings_to_clocks(int mc_time, int av_time, int ds_time,
- int clock_time, int drv_idx)
-{
- int a, b;
-
- arttim[drv_idx] = (mc_time + clock_time - 1)/clock_time;
-
- a = (av_time + clock_time - 1)/clock_time;
- if (a < 2)
- a = 2;
- b = (ds_time + clock_time - 1)/clock_time - a;
- if (b < 2)
- b = 2;
- if (b > 0x11) {
- a += b - 0x11;
- b = 0x11;
- }
- if (a > 0x10)
- a = 0x10;
- if (cmd640_chip_version > 1)
- b -= 1;
- if (b > 0x10)
- b = 0x10;
-
- a_count[drv_idx] = a;
- r_count[drv_idx] = b;
-}
-
-static void set_pio_mode(int if_num, int drv_num, int mode_num) {
- int p_base;
- int i;
-
- p_base = if_num ? 0x170 : 0x1f0;
- outb_p(3, p_base + 1);
- outb_p(mode_num | 8, p_base + 2);
- outb_p((drv_num | 0xa) << 4, p_base + 6);
- outb_p(0xef, p_base + 7);
- for (i = 0; (i < 100) && (inb (p_base + 7) & 0x80); i++)
- udelay(10000);
-}
-
-/*
- * Set a specific pio_mode for a drive
- */
-
-static void cmd640_set_mode(ide_drive_t* drive, int pio_mode) {
- int interface_number;
- int drive_number;
- int clock_time; /* ns */
- int mc_time, av_time, ds_time;
-
- interface_number = HWIF(drive)->index;
- drive_number = drive->select.b.unit;
- clock_time = 1000/bus_speed;
-
- mc_time = pio_timings[pio_mode].mc_time;
- av_time = pio_timings[pio_mode].av_time;
- ds_time = pio_timings[pio_mode].ds_time;
-
- cmd640_timings_to_clocks(mc_time, av_time, ds_time, clock_time,
- interface_number*2 + drive_number);
- set_pio_mode(interface_number, drive_number, pio_mode);
- cmd640_set_timing(interface_number, drive_number);
-}
-
-/*
- * Drive PIO mode "autoconfiguration".
- * Ideally, this code should *always* call cmd640_set_mode(), but it doesn't.
- */
-
-static void cmd640_tune_drive(ide_drive_t *drive, byte pio_mode) {
- int interface_number;
- int drive_number;
- int clock_time; /* ns */
- int max_pio;
- int mc_time, av_time, ds_time;
- struct hd_driveid* id;
- int readahead; /* there is a global named read_ahead */
-
- if (pio_mode != 255) {
- cmd640_set_mode(drive, pio_mode);
- return;
- }
-
- interface_number = HWIF(drive)->index;
- drive_number = drive->select.b.unit;
- clock_time = 1000/bus_speed;
- id = drive->id;
- if ((max_pio = ide_scan_pio_blacklist(id->model)) != -1) {
- ds_time = pio_timings[max_pio].ds_time;
- } else {
- max_pio = id->tPIO;
- ds_time = pio_timings[max_pio].ds_time;
- if (id->field_valid & 2) {
- if ((id->capability & 8) && (id->eide_pio_modes & 7)) {
- if (id->eide_pio_modes & 4) max_pio = 5;
- else if (id->eide_pio_modes & 2) max_pio = 4;
- else max_pio = 3;
- ds_time = id->eide_pio_iordy;
- } else {
- ds_time = id->eide_pio;
- }
- if (ds_time == 0)
- ds_time = pio_timings[max_pio].ds_time;
- }
-
- /*
- * Conservative "downgrade"
- */
- if (max_pio < 4 && max_pio != 0) {
- max_pio -= 1;
- ds_time = pio_timings[max_pio].ds_time;
- }
- }
- mc_time = pio_timings[max_pio].mc_time;
- av_time = pio_timings[max_pio].av_time;
- cmd640_timings_to_clocks(mc_time, av_time, ds_time, clock_time,
- interface_number*2 + drive_number);
- set_pio_mode(interface_number, drive_number, max_pio);
- cmd640_set_timing(interface_number, drive_number);
-
- /*
- * Disable (or set) readahead mode
- */
-
- readahead = 0;
- if (cmd640_chip_version > 1) { /* Mmmm.. probably should be > 2 ?? */
- readahead = known_drive_readahead(id->model);
- if (readahead == -1)
- readahead = 1; /* Mmmm.. probably be 0 ?? */
- set_readahead_mode(readahead, interface_number, drive_number);
- }
-
- printk ("Mode and Timing set to PIO%d, Readahead is %s\n",
- max_pio, readahead ? "enabled" : "disabled");
-}
-
diff --git a/i386/i386at/gpl/linux/block/floppy.c b/i386/i386at/gpl/linux/block/floppy.c
deleted file mode 100644
index ee4a8980..00000000
--- a/i386/i386at/gpl/linux/block/floppy.c
+++ /dev/null
@@ -1,4100 +0,0 @@
-/*
- * linux/kernel/floppy.c
- *
- * Copyright (C) 1991, 1992 Linus Torvalds
- * Copyright (C) 1993, 1994 Alain Knaff
- */
-/*
- * 02.12.91 - Changed to static variables to indicate need for reset
- * and recalibrate. This makes some things easier (output_byte reset
- * checking etc), and means less interrupt jumping in case of errors,
- * so the code is hopefully easier to understand.
- */
-
-/*
- * This file is certainly a mess. I've tried my best to get it working,
- * but I don't like programming floppies, and I have only one anyway.
- * Urgel. I should check for more errors, and do more graceful error
- * recovery. Seems there are problems with several drives. I've tried to
- * correct them. No promises.
- */
-
-/*
- * As with hd.c, all routines within this file can (and will) be called
- * by interrupts, so extreme caution is needed. A hardware interrupt
- * handler may not sleep, or a kernel panic will happen. Thus I cannot
- * call "floppy-on" directly, but have to set a special timer interrupt
- * etc.
- */
-
-/*
- * 28.02.92 - made track-buffering routines, based on the routines written
- * by entropy@wintermute.wpi.edu (Lawrence Foard). Linus.
- */
-
-/*
- * Automatic floppy-detection and formatting written by Werner Almesberger
- * (almesber@nessie.cs.id.ethz.ch), who also corrected some problems with
- * the floppy-change signal detection.
- */
-
-/*
- * 1992/7/22 -- Hennus Bergman: Added better error reporting, fixed
- * FDC data overrun bug, added some preliminary stuff for vertical
- * recording support.
- *
- * 1992/9/17: Added DMA allocation & DMA functions. -- hhb.
- *
- * TODO: Errors are still not counted properly.
- */
-
-/* 1992/9/20
- * Modifications for ``Sector Shifting'' by Rob Hooft (hooft@chem.ruu.nl)
- * modelled after the freeware MS/DOS program fdformat/88 V1.8 by
- * Christoph H. Hochst\"atter.
- * I have fixed the shift values to the ones I always use. Maybe a new
- * ioctl() should be created to be able to modify them.
- * There is a bug in the driver that makes it impossible to format a
- * floppy as the first thing after bootup.
- */
-
-/*
- * 1993/4/29 -- Linus -- cleaned up the timer handling in the kernel, and
- * this helped the floppy driver as well. Much cleaner, and still seems to
- * work.
- */
-
-/* 1994/6/24 --bbroad-- added the floppy table entries and made
- * minor modifications to allow 2.88 floppies to be run.
- */
-
-/* 1994/7/13 -- Paul Vojta -- modified the probing code to allow three or more
- * disk types.
- */
-
-/*
- * 1994/8/8 -- Alain Knaff -- Switched to fdpatch driver: Support for bigger
- * format bug fixes, but unfortunately some new bugs too...
- */
-
-/* 1994/9/17 -- Koen Holtman -- added logging of physical floppy write
- * errors to allow safe writing by specialized programs.
- */
-
-/* 1995/4/24 -- Dan Fandrich -- added support for Commodore 1581 3.5" disks
- * by defining bit 1 of the "stretch" parameter to mean put sectors on the
- * opposite side of the disk, leaving the sector IDs alone (i.e. Commodore's
- * drives are "upside-down").
- */
-
-/*
- * 1995/8/26 -- Andreas Busse -- added Mips support.
- */
-
-/*
- * 1995/10/18 -- Ralf Baechle -- Portability cleanup; move machine dependend
- * features to asm/floppy.h.
- */
-
-
-#define FLOPPY_SANITY_CHECK
-#undef FLOPPY_SILENT_DCL_CLEAR
-
-#define REALLY_SLOW_IO
-
-#define DEBUGT 2
-#define DCL_DEBUG /* debug disk change line */
-
-/* do print messages for unexpected interrupts */
-static int print_unex=1;
-#include <linux/utsname.h>
-#include <linux/module.h>
-
-/* the following is the mask of allowed drives. By default units 2 and
- * 3 of both floppy controllers are disabled, because switching on the
- * motor of these drives causes system hangs on some PCI computers. drive
- * 0 is the low bit (0x1), and drive 7 is the high bit (0x80). Bits are on if
- * a drive is allowed. */
-static int FLOPPY_IRQ=6;
-static int FLOPPY_DMA=2;
-static int allowed_drive_mask = 0x33;
-
-
-#include <linux/sched.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/timer.h>
-#include <linux/tqueue.h>
-#define FDPATCHES
-#include <linux/fdreg.h>
-
-
-#include <linux/fd.h>
-
-
-#define OLDFDRAWCMD 0x020d /* send a raw command to the fdc */
-
-struct old_floppy_raw_cmd {
- void *data;
- long length;
-
- unsigned char rate;
- unsigned char flags;
- unsigned char cmd_count;
- unsigned char cmd[9];
- unsigned char reply_count;
- unsigned char reply[7];
- int track;
-};
-
-#include <linux/errno.h>
-#include <linux/malloc.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/fcntl.h>
-#include <linux/delay.h>
-#include <linux/mc146818rtc.h> /* CMOS defines */
-#include <linux/ioport.h>
-
-#include <asm/dma.h>
-#include <asm/floppy.h>
-#include <asm/irq.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/segment.h>
-
-#define MAJOR_NR FLOPPY_MAJOR
-
-#include <linux/blk.h>
-
-
-/* Dma Memory related stuff */
-
-/* Pure 2^n version of get_order */
-static inline int __get_order (int size)
-{
- int order;
-
-#ifdef _ASM_IO_H2
- __asm__ __volatile__("bsr %1,%0"
- : "=r" (order)
- : "r" (size / PAGE_SIZE));
-#else
- for (order = 0; order < NR_MEM_LISTS; ++order)
- if (size <= (PAGE_SIZE << order))
- return order;
-#endif
- return NR_MEM_LISTS;
-}
-
-static unsigned long dma_mem_alloc(int size)
-{
- int order = __get_order(size);
-
- if (order >= NR_MEM_LISTS)
- return(0);
- return __get_dma_pages(GFP_KERNEL,order);
-}
-
-/* End dma memory related stuff */
-
-static unsigned int fake_change = 0;
-static int initialising=1;
-
-static inline int TYPE(kdev_t x) {
- return (MINOR(x)>>2) & 0x1f;
-}
-static inline int DRIVE(kdev_t x) {
- return (MINOR(x)&0x03) | ((MINOR(x)&0x80) >> 5);
-}
-#define ITYPE(x) (((x)>>2) & 0x1f)
-#define TOMINOR(x) ((x & 3) | ((x & 4) << 5))
-#define UNIT(x) ((x) & 0x03) /* drive on fdc */
-#define FDC(x) (((x) & 0x04) >> 2) /* fdc of drive */
-#define REVDRIVE(fdc, unit) ((unit) + ((fdc) << 2))
- /* reverse mapping from unit and fdc to drive */
-#define DP (&drive_params[current_drive])
-#define DRS (&drive_state[current_drive])
-#define DRWE (&write_errors[current_drive])
-#define FDCS (&fdc_state[fdc])
-#define CLEARF(x) (clear_bit(x##_BIT, &DRS->flags))
-#define SETF(x) (set_bit(x##_BIT, &DRS->flags))
-#define TESTF(x) (test_bit(x##_BIT, &DRS->flags))
-
-#define UDP (&drive_params[drive])
-#define UDRS (&drive_state[drive])
-#define UDRWE (&write_errors[drive])
-#define UFDCS (&fdc_state[FDC(drive)])
-#define UCLEARF(x) (clear_bit(x##_BIT, &UDRS->flags))
-#define USETF(x) (set_bit(x##_BIT, &UDRS->flags))
-#define UTESTF(x) (test_bit(x##_BIT, &UDRS->flags))
-
-#define DPRINT(x) printk(DEVICE_NAME "%d: " x,current_drive)
-
-#define DPRINT1(x,x1) printk(DEVICE_NAME "%d: " x,current_drive,(x1))
-
-#define DPRINT2(x,x1,x2) printk(DEVICE_NAME "%d: " x,current_drive,(x1),(x2))
-
-#define DPRINT3(x,x1,x2,x3) printk(DEVICE_NAME "%d: " x,current_drive,(x1),(x2),(x3))
-
-#define PH_HEAD(floppy,head) (((((floppy)->stretch & 2) >>1) ^ head) << 2)
-#define STRETCH(floppy) ((floppy)->stretch & FD_STRETCH)
-
-#define CLEARSTRUCT(x) memset((x), 0, sizeof(*(x)))
-
-/* read/write */
-#define COMMAND raw_cmd->cmd[0]
-#define DR_SELECT raw_cmd->cmd[1]
-#define TRACK raw_cmd->cmd[2]
-#define HEAD raw_cmd->cmd[3]
-#define SECTOR raw_cmd->cmd[4]
-#define SIZECODE raw_cmd->cmd[5]
-#define SECT_PER_TRACK raw_cmd->cmd[6]
-#define GAP raw_cmd->cmd[7]
-#define SIZECODE2 raw_cmd->cmd[8]
-#define NR_RW 9
-
-/* format */
-#define F_SIZECODE raw_cmd->cmd[2]
-#define F_SECT_PER_TRACK raw_cmd->cmd[3]
-#define F_GAP raw_cmd->cmd[4]
-#define F_FILL raw_cmd->cmd[5]
-#define NR_F 6
-
-/*
- * Maximum disk size (in kilobytes). This default is used whenever the
- * current disk size is unknown.
- * [Now it is rather a minimum]
- */
-#define MAX_DISK_SIZE 2 /* 3984*/
-
-#define K_64 0x10000 /* 64KB */
-
-/*
- * globals used by 'result()'
- */
-#define MAX_REPLIES 17
-static unsigned char reply_buffer[MAX_REPLIES];
-static int inr; /* size of reply buffer, when called from interrupt */
-#define ST0 (reply_buffer[0])
-#define ST1 (reply_buffer[1])
-#define ST2 (reply_buffer[2])
-#define ST3 (reply_buffer[0]) /* result of GETSTATUS */
-#define R_TRACK (reply_buffer[3])
-#define R_HEAD (reply_buffer[4])
-#define R_SECTOR (reply_buffer[5])
-#define R_SIZECODE (reply_buffer[6])
-
-#define SEL_DLY (2*HZ/100)
-
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
-/*
- * this struct defines the different floppy drive types.
- */
-static struct {
- struct floppy_drive_params params;
- const char *name; /* name printed while booting */
-} default_drive_params[]= {
-/* NOTE: the time values in jiffies should be in msec!
- CMOS drive type
- | Maximum data rate supported by drive type
- | | Head load time, msec
- | | | Head unload time, msec (not used)
- | | | | Step rate interval, usec
- | | | | | Time needed for spinup time (jiffies)
- | | | | | | Timeout for spinning down (jiffies)
- | | | | | | | Spindown offset (where disk stops)
- | | | | | | | | Select delay
- | | | | | | | | | RPS
- | | | | | | | | | | Max number of tracks
- | | | | | | | | | | | Interrupt timeout
- | | | | | | | | | | | | Max nonintlv. sectors
- | | | | | | | | | | | | | -Max Errors- flags */
-{{0, 500, 16, 16, 8000, 1*HZ, 3*HZ, 0, SEL_DLY, 5, 80, 3*HZ, 20, {3,1,2,0,2}, 0,
- 0, { 7, 4, 8, 2, 1, 5, 3,10}, 3*HZ/2, 0 }, "unknown" },
-
-{{1, 300, 16, 16, 8000, 1*HZ, 3*HZ, 0, SEL_DLY, 5, 40, 3*HZ, 17, {3,1,2,0,2}, 0,
- 0, { 1, 0, 0, 0, 0, 0, 0, 0}, 3*HZ/2, 1 }, "360K PC" }, /*5 1/4 360 KB PC*/
-
-{{2, 500, 16, 16, 6000, 4*HZ/10, 3*HZ, 14, SEL_DLY, 6, 83, 3*HZ, 17, {3,1,2,0,2}, 0,
- 0, { 2, 5, 6,23,10,20,11, 0}, 3*HZ/2, 2 }, "1.2M" }, /*5 1/4 HD AT*/
-
-{{3, 250, 16, 16, 3000, 1*HZ, 3*HZ, 0, SEL_DLY, 5, 83, 3*HZ, 20, {3,1,2,0,2}, 0,
- 0, { 4,22,21,30, 3, 0, 0, 0}, 3*HZ/2, 4 }, "720k" }, /*3 1/2 DD*/
-
-{{4, 500, 16, 16, 4000, 4*HZ/10, 3*HZ, 10, SEL_DLY, 5, 83, 3*HZ, 20, {3,1,2,0,2}, 0,
- 0, { 7, 4,25,22,31,21,29,11}, 3*HZ/2, 7 }, "1.44M" }, /*3 1/2 HD*/
-
-{{5, 1000, 15, 8, 3000, 4*HZ/10, 3*HZ, 10, SEL_DLY, 5, 83, 3*HZ, 40, {3,1,2,0,2}, 0,
- 0, { 7, 8, 4,25,28,22,31,21}, 3*HZ/2, 8 }, "2.88M AMI BIOS" }, /*3 1/2 ED*/
-
-{{6, 1000, 15, 8, 3000, 4*HZ/10, 3*HZ, 10, SEL_DLY, 5, 83, 3*HZ, 40, {3,1,2,0,2}, 0,
- 0, { 7, 8, 4,25,28,22,31,21}, 3*HZ/2, 8 }, "2.88M" } /*3 1/2 ED*/
-/* | --autodetected formats--- | | |
- * read_track | | Name printed when booting
- * | Native format
- * Frequency of disk change checks */
-};
-
-static struct floppy_drive_params drive_params[N_DRIVE];
-static struct floppy_drive_struct drive_state[N_DRIVE];
-static struct floppy_write_errors write_errors[N_DRIVE];
-static struct floppy_raw_cmd *raw_cmd, default_raw_cmd;
-
-/*
- * This struct defines the different floppy types.
- *
- * Bit 0 of 'stretch' tells if the tracks need to be doubled for some
- * types (e.g. 360kB diskette in 1.2MB drive, etc.). Bit 1 of 'stretch'
- * tells if the disk is in Commodore 1581 format, which means side 0 sectors
- * are located on side 1 of the disk but with a side 0 ID, and vice-versa.
- * This is the same as the Sharp MZ-80 5.25" CP/M disk format, except that the
- * 1581's logical side 0 is on physical side 1, whereas the Sharp's logical
- * side 0 is on physical side 0 (but with the misnamed sector IDs).
- * 'stretch' should probably be renamed to something more general, like
- * 'options'. Other parameters should be self-explanatory (see also
- * setfdprm(8)).
- */
-static struct floppy_struct floppy_type[32] = {
- { 0, 0,0, 0,0,0x00,0x00,0x00,0x00,NULL }, /* 0 no testing */
- { 720, 9,2,40,0,0x2A,0x02,0xDF,0x50,"d360" }, /* 1 360KB PC */
- { 2400,15,2,80,0,0x1B,0x00,0xDF,0x54,"h1200" }, /* 2 1.2MB AT */
- { 720, 9,1,80,0,0x2A,0x02,0xDF,0x50,"D360" }, /* 3 360KB SS 3.5" */
- { 1440, 9,2,80,0,0x2A,0x02,0xDF,0x50,"D720" }, /* 4 720KB 3.5" */
- { 720, 9,2,40,1,0x23,0x01,0xDF,0x50,"h360" }, /* 5 360KB AT */
- { 1440, 9,2,80,0,0x23,0x01,0xDF,0x50,"h720" }, /* 6 720KB AT */
- { 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,"H1440" }, /* 7 1.44MB 3.5" */
- { 5760,36,2,80,0,0x1B,0x43,0xAF,0x54,"E2880" }, /* 8 2.88MB 3.5" */
- { 5760,36,2,80,0,0x1B,0x43,0xAF,0x54,"CompaQ"}, /* 9 2.88MB 3.5" */
-
- { 2880,18,2,80,0,0x25,0x00,0xDF,0x02,"h1440" }, /* 10 1.44MB 5.25" */
- { 3360,21,2,80,0,0x1C,0x00,0xCF,0x0C,"H1680" }, /* 11 1.68MB 3.5" */
- { 820,10,2,41,1,0x25,0x01,0xDF,0x2E,"h410" }, /* 12 410KB 5.25" */
- { 1640,10,2,82,0,0x25,0x02,0xDF,0x2E,"H820" }, /* 13 820KB 3.5" */
- { 2952,18,2,82,0,0x25,0x00,0xDF,0x02,"h1476" }, /* 14 1.48MB 5.25" */
- { 3444,21,2,82,0,0x25,0x00,0xDF,0x0C,"H1722" }, /* 15 1.72MB 3.5" */
- { 840,10,2,42,1,0x25,0x01,0xDF,0x2E,"h420" }, /* 16 420KB 5.25" */
- { 1660,10,2,83,0,0x25,0x02,0xDF,0x2E,"H830" }, /* 17 830KB 3.5" */
- { 2988,18,2,83,0,0x25,0x00,0xDF,0x02,"h1494" }, /* 18 1.49MB 5.25" */
- { 3486,21,2,83,0,0x25,0x00,0xDF,0x0C,"H1743" }, /* 19 1.74 MB 3.5" */
-
- { 1760,11,2,80,0,0x1C,0x09,0xCF,0x00,"h880" }, /* 20 880KB 5.25" */
- { 2080,13,2,80,0,0x1C,0x01,0xCF,0x00,"D1040" }, /* 21 1.04MB 3.5" */
- { 2240,14,2,80,0,0x1C,0x19,0xCF,0x00,"D1120" }, /* 22 1.12MB 3.5" */
- { 3200,20,2,80,0,0x1C,0x20,0xCF,0x2C,"h1600" }, /* 23 1.6MB 5.25" */
- { 3520,22,2,80,0,0x1C,0x08,0xCF,0x2e,"H1760" }, /* 24 1.76MB 3.5" */
- { 3840,24,2,80,0,0x1C,0x20,0xCF,0x00,"H1920" }, /* 25 1.92MB 3.5" */
- { 6400,40,2,80,0,0x25,0x5B,0xCF,0x00,"E3200" }, /* 26 3.20MB 3.5" */
- { 7040,44,2,80,0,0x25,0x5B,0xCF,0x00,"E3520" }, /* 27 3.52MB 3.5" */
- { 7680,48,2,80,0,0x25,0x63,0xCF,0x00,"E3840" }, /* 28 3.84MB 3.5" */
-
- { 3680,23,2,80,0,0x1C,0x10,0xCF,0x00,"H1840" }, /* 29 1.84MB 3.5" */
- { 1600,10,2,80,0,0x25,0x02,0xDF,0x2E,"D800" }, /* 30 800KB 3.5" */
- { 3200,20,2,80,0,0x1C,0x00,0xCF,0x2C,"H1600" }, /* 31 1.6MB 3.5" */
-};
-
-#define NUMBER(x) (sizeof(x) / sizeof(*(x)))
-#define SECTSIZE (_FD_SECTSIZE(*floppy))
-
-/* Auto-detection: Disk type used until the next media change occurs. */
-static struct floppy_struct *current_type[N_DRIVE] = {
- NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL
-};
-
-/*
- * User-provided type information. current_type points to
- * the respective entry of this array.
- */
-static struct floppy_struct user_params[N_DRIVE];
-
-static int floppy_sizes[256];
-static int floppy_blocksizes[256] = { 0, };
-
-/*
- * The driver is trying to determine the correct media format
- * while probing is set. rw_interrupt() clears it after a
- * successful access.
- */
-static int probing = 0;
-
-/* Synchronization of FDC access. */
-#define FD_COMMAND_NONE -1
-#define FD_COMMAND_ERROR 2
-#define FD_COMMAND_OKAY 3
-
-static volatile int command_status = FD_COMMAND_NONE, fdc_busy = 0;
-static struct wait_queue *fdc_wait = NULL, *command_done = NULL;
-#ifdef MACH
-extern int issig (void);
-#define NO_SIGNAL (! issig () || ! interruptible)
-#else
-#define NO_SIGNAL (!(current->signal & ~current->blocked) || !interruptible)
-#endif
-#define CALL(x) if ((x) == -EINTR) return -EINTR
-#define ECALL(x) if ((ret = (x))) return ret;
-#define _WAIT(x,i) CALL(ret=wait_til_done((x),i))
-#define WAIT(x) _WAIT((x),interruptible)
-#define IWAIT(x) _WAIT((x),1)
-
-/* Errors during formatting are counted here. */
-static int format_errors;
-
-/* Format request descriptor. */
-static struct format_descr format_req;
-
-/*
- * Rate is 0 for 500kb/s, 1 for 300kbps, 2 for 250kbps
- * Spec1 is 0xSH, where S is stepping rate (F=1ms, E=2ms, D=3ms etc),
- * H is head unload time (1=16ms, 2=32ms, etc)
- */
-
-/*
- * Track buffer
- * Because these are written to by the DMA controller, they must
- * not contain a 64k byte boundary crossing, or data will be
- * corrupted/lost. Alignment of these is enforced in boot/head.S.
- * Note that you must not change the sizes below without updating head.S.
- */
-static char *floppy_track_buffer=0;
-static int max_buffer_sectors=0;
-
-static int *errors;
-typedef void (*done_f)(int);
-static struct cont_t {
- void (*interrupt)(void); /* this is called after the interrupt of the
- * main command */
- void (*redo)(void); /* this is called to retry the operation */
- void (*error)(void); /* this is called to tally an error */
- done_f done; /* this is called to say if the operation has
- * succeeded/failed */
-} *cont=NULL;
-
-static void floppy_ready(void);
-static void floppy_start(void);
-static void process_fd_request(void);
-static void recalibrate_floppy(void);
-static void floppy_shutdown(void);
-
-static int floppy_grab_irq_and_dma(void);
-static void floppy_release_irq_and_dma(void);
-
-/*
- * The "reset" variable should be tested whenever an interrupt is scheduled,
- * after the commands have been sent. This is to ensure that the driver doesn't
- * get wedged when the interrupt doesn't come because of a failed command.
- * reset doesn't need to be tested before sending commands, because
- * output_byte is automatically disabled when reset is set.
- */
-#define CHECK_RESET { if (FDCS->reset){ reset_fdc(); return; } }
-static void reset_fdc(void);
-
-/*
- * These are global variables, as that's the easiest way to give
- * information to interrupts. They are the data used for the current
- * request.
- */
-#define NO_TRACK -1
-#define NEED_1_RECAL -2
-#define NEED_2_RECAL -3
-
-/* */
-static int usage_count = 0;
-
-
-/* buffer related variables */
-static int buffer_track = -1;
-static int buffer_drive = -1;
-static int buffer_min = -1;
-static int buffer_max = -1;
-
-/* fdc related variables, should end up in a struct */
-static struct floppy_fdc_state fdc_state[N_FDC];
-static int fdc; /* current fdc */
-
-static struct floppy_struct * floppy = floppy_type;
-static unsigned char current_drive = 0;
-static long current_count_sectors = 0;
-static unsigned char sector_t; /* sector in track */
-
-#ifdef DEBUGT
-static long unsigned debugtimer;
-#endif
-
-/*
- * Debugging
- * =========
- */
-static inline void set_debugt(void)
-{
-#ifdef DEBUGT
- debugtimer = jiffies;
-#endif
-}
-
-static inline void debugt(const char *message)
-{
-#ifdef DEBUGT
- if (DP->flags & DEBUGT)
- printk("%s dtime=%lu\n", message, jiffies-debugtimer);
-#endif
-}
-
-typedef void (*timeout_fn)(unsigned long);
-static struct timer_list fd_timeout ={ NULL, NULL, 0, 0,
- (timeout_fn) floppy_shutdown };
-
-static const char *timeout_message;
-
-#ifdef FLOPPY_SANITY_CHECK
-static void is_alive(const char *message)
-{
- /* this routine checks whether the floppy driver is "alive" */
- if (fdc_busy && command_status < 2 && !fd_timeout.prev){
- DPRINT1("timeout handler died: %s\n",message);
- }
-}
-#endif
-
-#ifdef FLOPPY_SANITY_CHECK
-
-#define OLOGSIZE 20
-
-static void (*lasthandler)(void) = NULL;
-static int interruptjiffies=0;
-static int resultjiffies=0;
-static int resultsize=0;
-static int lastredo=0;
-
-static struct output_log {
- unsigned char data;
- unsigned char status;
- unsigned long jiffies;
-} output_log[OLOGSIZE];
-
-static int output_log_pos=0;
-#endif
-
-#define CURRENTD -1
-#define MAXTIMEOUT -2
-
-static void reschedule_timeout(int drive, const char *message, int marg)
-{
- if (drive == CURRENTD)
- drive = current_drive;
- del_timer(&fd_timeout);
- if (drive < 0 || drive > N_DRIVE) {
- fd_timeout.expires = jiffies + 20*HZ;
- drive=0;
- } else
- fd_timeout.expires = jiffies + UDP->timeout;
- add_timer(&fd_timeout);
- if (UDP->flags & FD_DEBUG){
- DPRINT("reschedule timeout ");
- printk(message, marg);
- printk("\n");
- }
- timeout_message = message;
-}
-
-static int maximum(int a, int b)
-{
- if(a > b)
- return a;
- else
- return b;
-}
-#define INFBOUND(a,b) (a)=maximum((a),(b));
-
-static int minimum(int a, int b)
-{
- if(a < b)
- return a;
- else
- return b;
-}
-#define SUPBOUND(a,b) (a)=minimum((a),(b));
-
-
-/*
- * Bottom half floppy driver.
- * ==========================
- *
- * This part of the file contains the code talking directly to the hardware,
- * and also the main service loop (seek-configure-spinup-command)
- */
-
-/*
- * disk change.
- * This routine is responsible for maintaining the FD_DISK_CHANGE flag,
- * and the last_checked date.
- *
- * last_checked is the date of the last check which showed 'no disk change'
- * FD_DISK_CHANGE is set under two conditions:
- * 1. The floppy has been changed after some i/o to that floppy already
- * took place.
- * 2. No floppy disk is in the drive. This is done in order to ensure that
- * requests are quickly flushed in case there is no disk in the drive. It
- * follows that FD_DISK_CHANGE can only be cleared if there is a disk in
- * the drive.
- *
- * For 1., maxblock is observed. Maxblock is 0 if no i/o has taken place yet.
- * For 2., FD_DISK_NEWCHANGE is watched. FD_DISK_NEWCHANGE is cleared on
- * each seek. If a disk is present, the disk change line should also be
- * cleared on each seek. Thus, if FD_DISK_NEWCHANGE is clear, but the disk
- * change line is set, this means either that no disk is in the drive, or
- * that it has been removed since the last seek.
- *
- * This means that we really have a third possibility too:
- * The floppy has been changed after the last seek.
- */
-
-static int disk_change(int drive)
-{
- int fdc=FDC(drive);
-#ifdef FLOPPY_SANITY_CHECK
- if (jiffies < UDP->select_delay + UDRS->select_date)
- DPRINT("WARNING disk change called early\n");
- if (!(FDCS->dor & (0x10 << UNIT(drive))) ||
- (FDCS->dor & 3) != UNIT(drive) ||
- fdc != FDC(drive)){
- DPRINT("probing disk change on unselected drive\n");
- DPRINT3("drive=%d fdc=%d dor=%x\n",drive, FDC(drive),
- FDCS->dor);
- }
-#endif
-
-#ifdef DCL_DEBUG
- if (UDP->flags & FD_DEBUG){
- DPRINT1("checking disk change line for drive %d\n",drive);
- DPRINT1("jiffies=%ld\n", jiffies);
- DPRINT1("disk change line=%x\n",fd_inb(FD_DIR)&0x80);
- DPRINT1("flags=%x\n",UDRS->flags);
- }
-#endif
- if (UDP->flags & FD_BROKEN_DCL)
- return UTESTF(FD_DISK_CHANGED);
- if ((fd_inb(FD_DIR) ^ UDP->flags) & 0x80){
- USETF(FD_VERIFY); /* verify write protection */
- if (UDRS->maxblock){
- /* mark it changed */
- USETF(FD_DISK_CHANGED);
-
- /* invalidate its geometry */
- if (UDRS->keep_data >= 0) {
- if ((UDP->flags & FTD_MSG) &&
- current_type[drive] != NULL)
- DPRINT("Disk type is undefined after "
- "disk change\n");
- current_type[drive] = NULL;
- floppy_sizes[TOMINOR(current_drive)] = MAX_DISK_SIZE;
- }
- }
- /*USETF(FD_DISK_NEWCHANGE);*/
- return 1;
- } else {
- UDRS->last_checked=jiffies;
- UCLEARF(FD_DISK_NEWCHANGE);
- }
- return 0;
-}
-
-static inline int is_selected(int dor, int unit)
-{
- return ((dor & (0x10 << unit)) && (dor &3) == unit);
-}
-
-static int set_dor(int fdc, char mask, char data)
-{
- register unsigned char drive, unit, newdor,olddor;
-
- if (FDCS->address == -1)
- return -1;
-
- olddor = FDCS->dor;
- newdor = (olddor & mask) | data;
- if (newdor != olddor){
- unit = olddor & 0x3;
- if (is_selected(olddor, unit) && !is_selected(newdor,unit)){
- drive = REVDRIVE(fdc,unit);
-#ifdef DCL_DEBUG
- if (UDP->flags & FD_DEBUG){
- DPRINT("calling disk change from set_dor\n");
- }
-#endif
- disk_change(drive);
- }
- FDCS->dor = newdor;
- fd_outb(newdor, FD_DOR);
-
- unit = newdor & 0x3;
- if (!is_selected(olddor, unit) && is_selected(newdor,unit)){
- drive = REVDRIVE(fdc,unit);
- UDRS->select_date = jiffies;
- }
- }
- if (newdor & 0xf0)
- floppy_grab_irq_and_dma();
- if (olddor & 0xf0)
- floppy_release_irq_and_dma();
- return olddor;
-}
-
-static void twaddle(void)
-{
- if (DP->select_delay)
- return;
- fd_outb(FDCS->dor & ~(0x10<<UNIT(current_drive)),FD_DOR);
- fd_outb(FDCS->dor, FD_DOR);
- DRS->select_date = jiffies;
-}
-
-/* reset all driver information about the current fdc. This is needed after
- * a reset, and after a raw command. */
-static void reset_fdc_info(int mode)
-{
- int drive;
-
- FDCS->spec1 = FDCS->spec2 = -1;
- FDCS->need_configure = 1;
- FDCS->perp_mode = 1;
- FDCS->rawcmd = 0;
- for (drive = 0; drive < N_DRIVE; drive++)
- if (FDC(drive) == fdc &&
- (mode || UDRS->track != NEED_1_RECAL))
- UDRS->track = NEED_2_RECAL;
-}
-
-/* selects the fdc and drive, and enables the fdc's input/dma. */
-static void set_fdc(int drive)
-{
- if (drive >= 0 && drive < N_DRIVE){
- fdc = FDC(drive);
- current_drive = drive;
- }
- if (fdc != 1 && fdc != 0) {
- printk("bad fdc value\n");
- return;
- }
- set_dor(fdc,~0,8);
- set_dor(1-fdc, ~8, 0);
- if (FDCS->rawcmd == 2)
- reset_fdc_info(1);
- if (fd_inb(FD_STATUS) != STATUS_READY)
- FDCS->reset = 1;
-}
-
-/* locks the driver */
-static int lock_fdc(int drive, int interruptible)
-{
- if (!usage_count){
- printk("trying to lock fdc while usage count=0\n");
- return -1;
- }
- floppy_grab_irq_and_dma();
- cli();
- while (fdc_busy && NO_SIGNAL)
- interruptible_sleep_on(&fdc_wait);
- if (fdc_busy){
- sti();
- return -EINTR;
- }
- fdc_busy = 1;
- sti();
- command_status = FD_COMMAND_NONE;
- reschedule_timeout(drive, "lock fdc", 0);
- set_fdc(drive);
- return 0;
-}
-
-#define LOCK_FDC(drive,interruptible) \
-if (lock_fdc(drive,interruptible)) return -EINTR;
-
-
-/* unlocks the driver */
-static inline void unlock_fdc(void)
-{
- raw_cmd = 0;
- if (!fdc_busy)
- DPRINT("FDC access conflict!\n");
-
- if (DEVICE_INTR)
- DPRINT1("device interrupt still active at FDC release: %p!\n",
- DEVICE_INTR);
- command_status = FD_COMMAND_NONE;
- del_timer(&fd_timeout);
- cont = NULL;
- fdc_busy = 0;
- floppy_release_irq_and_dma();
- wake_up(&fdc_wait);
-}
-
-/* switches the motor off after a given timeout */
-static void motor_off_callback(unsigned long nr)
-{
- unsigned char mask = ~(0x10 << UNIT(nr));
-
- set_dor(FDC(nr), mask, 0);
-}
-
-static struct timer_list motor_off_timer[N_DRIVE] = {
- { NULL, NULL, 0, 0, motor_off_callback },
- { NULL, NULL, 0, 1, motor_off_callback },
- { NULL, NULL, 0, 2, motor_off_callback },
- { NULL, NULL, 0, 3, motor_off_callback },
- { NULL, NULL, 0, 4, motor_off_callback },
- { NULL, NULL, 0, 5, motor_off_callback },
- { NULL, NULL, 0, 6, motor_off_callback },
- { NULL, NULL, 0, 7, motor_off_callback }
-};
-
-/* schedules motor off */
-static void floppy_off(unsigned int drive)
-{
- unsigned long volatile delta;
- register int fdc=FDC(drive);
-
- if (!(FDCS->dor & (0x10 << UNIT(drive))))
- return;
-
- del_timer(motor_off_timer+drive);
-
- /* make spindle stop in a position which minimizes spinup time
- * next time */
- if (UDP->rps){
- delta = jiffies - UDRS->first_read_date + HZ -
- UDP->spindown_offset;
- delta = ((delta * UDP->rps) % HZ) / UDP->rps;
- motor_off_timer[drive].expires = jiffies + UDP->spindown - delta;
- }
- add_timer(motor_off_timer+drive);
-}
-
-/*
- * cycle through all N_DRIVE floppy drives, for disk change testing.
- * stopping at current drive. This is done before any long operation, to
- * be sure to have up to date disk change information.
- */
-static void scandrives(void)
-{
- int i, drive, saved_drive;
-
- if (DP->select_delay)
- return;
-
- saved_drive = current_drive;
- for (i=0; i < N_DRIVE; i++){
- drive = (saved_drive + i + 1) % N_DRIVE;
- if (UDRS->fd_ref == 0 || UDP->select_delay != 0)
- continue; /* skip closed drives */
- set_fdc(drive);
- if (!(set_dor(fdc, ~3, UNIT(drive) | (0x10 << UNIT(drive))) &
- (0x10 << UNIT(drive))))
- /* switch the motor off again, if it was off to
- * begin with */
- set_dor(fdc, ~(0x10 << UNIT(drive)), 0);
- }
- set_fdc(saved_drive);
-}
-
-static struct timer_list fd_timer ={ NULL, NULL, 0, 0, 0 };
-
-/* this function makes sure that the disk stays in the drive during the
- * transfer */
-static void fd_watchdog(void)
-{
-#ifdef DCL_DEBUG
- if (DP->flags & FD_DEBUG){
- DPRINT("calling disk change from watchdog\n");
- }
-#endif
-
- if (disk_change(current_drive)){
- DPRINT("disk removed during i/o\n");
- floppy_shutdown();
- } else {
- del_timer(&fd_timer);
- fd_timer.function = (timeout_fn) fd_watchdog;
- fd_timer.expires = jiffies + HZ / 10;
- add_timer(&fd_timer);
- }
-}
-
-static void main_command_interrupt(void)
-{
- del_timer(&fd_timer);
- cont->interrupt();
-}
-
-/* waits for a delay (spinup or select) to pass */
-static int wait_for_completion(int delay, timeout_fn function)
-{
- if (FDCS->reset){
- reset_fdc(); /* do the reset during sleep to win time
- * if we don't need to sleep, it's a good
- * occasion anyways */
- return 1;
- }
-
- if (jiffies < delay){
- del_timer(&fd_timer);
- fd_timer.function = function;
- fd_timer.expires = delay;
- add_timer(&fd_timer);
- return 1;
- }
- return 0;
-}
-
-static int hlt_disabled=0;
-static void floppy_disable_hlt(void)
-{
- unsigned long flags;
- save_flags(flags);
- cli();
- if (!hlt_disabled){
- hlt_disabled=1;
-#ifdef HAVE_DISABLE_HLT
- disable_hlt();
-#endif
- }
- restore_flags(flags);
-}
-
-static void floppy_enable_hlt(void)
-{
- unsigned long flags;
- save_flags(flags);
- cli();
- if (hlt_disabled){
- hlt_disabled=0;
-#ifdef HAVE_DISABLE_HLT
- enable_hlt();
-#endif
- }
- restore_flags(flags);
-}
-
-
-static void setup_DMA(void)
-{
-#ifdef FLOPPY_SANITY_CHECK
- if (raw_cmd->length == 0){
- int i;
-
- printk("zero dma transfer size:");
- for (i=0; i < raw_cmd->cmd_count; i++)
- printk("%x,", raw_cmd->cmd[i]);
- printk("\n");
- cont->done(0);
- FDCS->reset = 1;
- return;
- }
- if ((long) raw_cmd->kernel_data % 512){
- printk("non aligned address: %p\n", raw_cmd->kernel_data);
- cont->done(0);
- FDCS->reset=1;
- return;
- }
- if (CROSS_64KB(raw_cmd->kernel_data, raw_cmd->length)) {
- printk("DMA crossing 64-K boundary %p-%p\n",
- raw_cmd->kernel_data,
- raw_cmd->kernel_data + raw_cmd->length);
- cont->done(0);
- FDCS->reset=1;
- return;
- }
-#endif
- cli();
- fd_disable_dma();
- fd_clear_dma_ff();
- fd_set_dma_mode((raw_cmd->flags & FD_RAW_READ)?
- DMA_MODE_READ : DMA_MODE_WRITE);
- fd_set_dma_addr(virt_to_bus(raw_cmd->kernel_data));
- fd_set_dma_count(raw_cmd->length);
- fd_enable_dma();
- sti();
- floppy_disable_hlt();
-}
-
-/* sends a command byte to the fdc */
-static int output_byte(char byte)
-{
- int counter;
- unsigned char status = 0;
- unsigned char rstatus;
-
- if (FDCS->reset)
- return -1;
- for (counter = 0; counter < 10000 && !FDCS->reset; counter++) {
- rstatus = fd_inb(FD_STATUS);
- status = rstatus &(STATUS_READY|STATUS_DIR|STATUS_DMA);
- if (!(status & STATUS_READY))
- continue;
- if (status == STATUS_READY){
- fd_outb(byte,FD_DATA);
-
-#ifdef FLOPPY_SANITY_CHECK
- output_log[output_log_pos].data = byte;
- output_log[output_log_pos].status = rstatus;
- output_log[output_log_pos].jiffies = jiffies;
- output_log_pos = (output_log_pos + 1) % OLOGSIZE;
-#endif
- return 0;
- } else
- break;
- }
- FDCS->reset = 1;
- if (!initialising)
- DPRINT2("Unable to send byte %x to FDC. Status=%x\n",
- byte, status);
- return -1;
-}
-#define LAST_OUT(x) if (output_byte(x)){ reset_fdc();return;}
-
-/* gets the response from the fdc */
-static int result(void)
-{
- int i = 0, counter, status = 0;
-
- if (FDCS->reset)
- return -1;
- for (counter = 0; counter < 10000 && !FDCS->reset; counter++) {
- status = fd_inb(FD_STATUS)&
- (STATUS_DIR|STATUS_READY|STATUS_BUSY|STATUS_DMA);
- if (!(status & STATUS_READY))
- continue;
- if (status == STATUS_READY){
-#ifdef FLOPPY_SANITY_CHECK
- resultjiffies = jiffies;
- resultsize = i;
-#endif
- return i;
- }
- if (status & STATUS_DMA)
- break;
- if (status == (STATUS_DIR|STATUS_READY|STATUS_BUSY)) {
- if (i >= MAX_REPLIES) {
- DPRINT("floppy_stat reply overrun\n");
- break;
- }
- reply_buffer[i++] = fd_inb(FD_DATA);
- }
- }
- FDCS->reset = 1;
- if (!initialising)
- DPRINT3("Getstatus times out (%x) on fdc %d [%d]\n",
- status, fdc, i);
- return -1;
-}
-
-/* Set perpendicular mode as required, based on data rate, if supported.
- * 82077 Now tested. 1Mbps data rate only possible with 82077-1.
- */
-static inline void perpendicular_mode(void)
-{
- unsigned char perp_mode;
-
- if (raw_cmd->rate & 0x40){
- switch(raw_cmd->rate & 3){
- case 0:
- perp_mode=2;
- break;
- case 3:
- perp_mode=3;
- break;
- default:
- DPRINT("Invalid data rate for perpendicular mode!\n");
- cont->done(0);
- FDCS->reset = 1; /* convenient way to return to
- * redo without to much hassle (deep
- * stack et al. */
- return;
- }
- } else
- perp_mode = 0;
-
- if (FDCS->perp_mode == perp_mode)
- return;
- if (FDCS->version >= FDC_82077_ORIG && FDCS->has_fifo) {
- output_byte(FD_PERPENDICULAR);
- output_byte(perp_mode);
- FDCS->perp_mode = perp_mode;
- } else if (perp_mode) {
- DPRINT("perpendicular mode not supported by this FDC.\n");
- }
-} /* perpendicular_mode */
-
-#define NOMINAL_DTR 500
-
-/* Issue a "SPECIFY" command to set the step rate time, head unload time,
- * head load time, and DMA disable flag to values needed by floppy.
- *
- * The value "dtr" is the data transfer rate in Kbps. It is needed
- * to account for the data rate-based scaling done by the 82072 and 82077
- * FDC types. This parameter is ignored for other types of FDCs (i.e.
- * 8272a).
- *
- * Note that changing the data transfer rate has a (probably deleterious)
- * effect on the parameters subject to scaling for 82072/82077 FDCs, so
- * fdc_specify is called again after each data transfer rate
- * change.
- *
- * srt: 1000 to 16000 in microseconds
- * hut: 16 to 240 milliseconds
- * hlt: 2 to 254 milliseconds
- *
- * These values are rounded up to the next highest available delay time.
- */
-static void fdc_specify(void)
-{
- unsigned char spec1, spec2;
- int srt, hlt, hut;
- unsigned long dtr = NOMINAL_DTR;
- unsigned long scale_dtr = NOMINAL_DTR;
- int hlt_max_code = 0x7f;
- int hut_max_code = 0xf;
-
- if (FDCS->need_configure && FDCS->has_fifo) {
- if (FDCS->reset)
- return;
- /* Turn on FIFO for 82077-class FDC (improves performance) */
- /* TODO: lock this in via LOCK during initialization */
- output_byte(FD_CONFIGURE);
- output_byte(0);
- output_byte(0x2A); /* FIFO on, polling off, 10 byte threshold */
- output_byte(0); /* precompensation from track 0 upwards */
- if (FDCS->reset){
- FDCS->has_fifo=0;
- return;
- }
- FDCS->need_configure = 0;
- /*DPRINT("FIFO enabled\n");*/
- }
-
- switch (raw_cmd->rate & 0x03) {
- case 3:
- dtr = 1000;
- break;
- case 1:
- dtr = 300;
- break;
- case 2:
- dtr = 250;
- break;
- }
-
- if (FDCS->version >= FDC_82072) {
- scale_dtr = dtr;
- hlt_max_code = 0x00; /* 0==256msec*dtr0/dtr (not linear!) */
- hut_max_code = 0x0; /* 0==256msec*dtr0/dtr (not linear!) */
- }
-
- /* Convert step rate from microseconds to milliseconds and 4 bits */
- srt = 16 - (DP->srt*scale_dtr/1000 + NOMINAL_DTR - 1)/NOMINAL_DTR;
- SUPBOUND(srt, 0xf);
- INFBOUND(srt, 0);
-
- hlt = (DP->hlt*scale_dtr/2 + NOMINAL_DTR - 1)/NOMINAL_DTR;
- if (hlt < 0x01)
- hlt = 0x01;
- else if (hlt > 0x7f)
- hlt = hlt_max_code;
-
- hut = (DP->hut*scale_dtr/16 + NOMINAL_DTR - 1)/NOMINAL_DTR;
- if (hut < 0x1)
- hut = 0x1;
- else if (hut > 0xf)
- hut = hut_max_code;
-
- spec1 = (srt << 4) | hut;
- spec2 = (hlt << 1);
-
- /* If these parameters did not change, just return with success */
- if (FDCS->spec1 != spec1 || FDCS->spec2 != spec2) {
- /* Go ahead and set spec1 and spec2 */
- output_byte(FD_SPECIFY);
- output_byte(FDCS->spec1 = spec1);
- output_byte(FDCS->spec2 = spec2);
- }
-} /* fdc_specify */
-
-/* Set the FDC's data transfer rate on behalf of the specified drive.
- * NOTE: with 82072/82077 FDCs, changing the data rate requires a reissue
- * of the specify command (i.e. using the fdc_specify function).
- */
-static int fdc_dtr(void)
-{
- /* If data rate not already set to desired value, set it. */
- if ((raw_cmd->rate & 3) == FDCS->dtr)
- return 0;
-
- /* Set dtr */
- fd_outb(raw_cmd->rate & 3, FD_DCR);
-
- /* TODO: some FDC/drive combinations (C&T 82C711 with TEAC 1.2MB)
- * need a stabilization period of several milliseconds to be
- * enforced after data rate changes before R/W operations.
- * Pause 5 msec to avoid trouble. (Needs to be 2 jiffies)
- */
- FDCS->dtr = raw_cmd->rate & 3;
- return(wait_for_completion(jiffies+2*HZ/100,
- (timeout_fn) floppy_ready));
-} /* fdc_dtr */
-
-static void tell_sector(void)
-{
- printk(": track %d, head %d, sector %d, size %d",
- R_TRACK, R_HEAD, R_SECTOR, R_SIZECODE);
-} /* tell_sector */
-
-
-/*
- * Ok, this error interpreting routine is called after a
- * DMA read/write has succeeded
- * or failed, so we check the results, and copy any buffers.
- * hhb: Added better error reporting.
- * ak: Made this into a separate routine.
- */
-static int interpret_errors(void)
-{
- char bad;
-
- if (inr!=7) {
- DPRINT("-- FDC reply error");
- FDCS->reset = 1;
- return 1;
- }
-
- /* check IC to find cause of interrupt */
- switch (ST0 & ST0_INTR) {
- case 0x40: /* error occurred during command execution */
- bad = 1;
- if (ST1 & ST1_WP) {
- DPRINT("Drive is write protected\n");
- CLEARF(FD_DISK_WRITABLE);
- cont->done(0);
- bad = 2;
- } else if (ST1 & ST1_ND) {
- SETF(FD_NEED_TWADDLE);
- } else if (ST1 & ST1_OR) {
- if (DP->flags & FTD_MSG)
- DPRINT("Over/Underrun - retrying\n");
- bad = 0;
- }else if (*errors >= DP->max_errors.reporting){
- DPRINT("");
- if (ST0 & ST0_ECE) {
- printk("Recalibrate failed!");
- } else if (ST2 & ST2_CRC) {
- printk("data CRC error");
- tell_sector();
- } else if (ST1 & ST1_CRC) {
- printk("CRC error");
- tell_sector();
- } else if ((ST1 & (ST1_MAM|ST1_ND)) || (ST2 & ST2_MAM)) {
- if (!probing) {
- printk("sector not found");
- tell_sector();
- } else
- printk("probe failed...");
- } else if (ST2 & ST2_WC) { /* seek error */
- printk("wrong cylinder");
- } else if (ST2 & ST2_BC) { /* cylinder marked as bad */
- printk("bad cylinder");
- } else {
- printk("unknown error. ST[0..2] are: 0x%x 0x%x 0x%x", ST0, ST1, ST2);
- tell_sector();
- }
- printk("\n");
-
- }
- if (ST2 & ST2_WC || ST2 & ST2_BC)
- /* wrong cylinder => recal */
- DRS->track = NEED_2_RECAL;
- return bad;
- case 0x80: /* invalid command given */
- DPRINT("Invalid FDC command given!\n");
- cont->done(0);
- return 2;
- case 0xc0:
- DPRINT("Abnormal termination caused by polling\n");
- cont->error();
- return 2;
- default: /* (0) Normal command termination */
- return 0;
- }
-}
-
-/*
- * This routine is called when everything should be correctly set up
- * for the transfer (ie floppy motor is on, the correct floppy is
- * selected, and the head is sitting on the right track).
- */
-static void setup_rw_floppy(void)
-{
- int i,ready_date,r, flags,dflags;
- timeout_fn function;
-
- flags = raw_cmd->flags;
- if (flags & (FD_RAW_READ | FD_RAW_WRITE))
- flags |= FD_RAW_INTR;
-
- if ((flags & FD_RAW_SPIN) && !(flags & FD_RAW_NO_MOTOR)){
- ready_date = DRS->spinup_date + DP->spinup;
- /* If spinup will take a long time, rerun scandrives
- * again just before spinup completion. Beware that
- * after scandrives, we must again wait for selection.
- */
- if (ready_date > jiffies + DP->select_delay){
- ready_date -= DP->select_delay;
- function = (timeout_fn) floppy_start;
- } else
- function = (timeout_fn) setup_rw_floppy;
-
- /* wait until the floppy is spinning fast enough */
- if (wait_for_completion(ready_date,function))
- return;
- }
- dflags = DRS->flags;
-
- if ((flags & FD_RAW_READ) || (flags & FD_RAW_WRITE))
- setup_DMA();
-
- if (flags & FD_RAW_INTR)
- SET_INTR(main_command_interrupt);
-
- r=0;
- for (i=0; i< raw_cmd->cmd_count; i++)
- r|=output_byte(raw_cmd->cmd[i]);
-
-#ifdef DEBUGT
- debugt("rw_command: ");
-#endif
- if (r){
- reset_fdc();
- return;
- }
-
- if (!(flags & FD_RAW_INTR)){
- inr = result();
- cont->interrupt();
- } else if (flags & FD_RAW_NEED_DISK)
- fd_watchdog();
-}
-
-static int blind_seek;
-
-/*
- * This is the routine called after every seek (or recalibrate) interrupt
- * from the floppy controller.
- */
-static void seek_interrupt(void)
-{
-#ifdef DEBUGT
- debugt("seek interrupt:");
-#endif
- if (inr != 2 || (ST0 & 0xF8) != 0x20) {
- DPRINT("seek failed\n");
- DRS->track = NEED_2_RECAL;
- cont->error();
- cont->redo();
- return;
- }
- if (DRS->track >= 0 && DRS->track != ST1 && !blind_seek){
-#ifdef DCL_DEBUG
- if (DP->flags & FD_DEBUG){
- DPRINT("clearing NEWCHANGE flag because of effective seek\n");
- DPRINT1("jiffies=%ld\n", jiffies);
- }
-#endif
- CLEARF(FD_DISK_NEWCHANGE); /* effective seek */
- DRS->select_date = jiffies;
- }
- DRS->track = ST1;
- floppy_ready();
-}
-
-static void check_wp(void)
-{
- if (TESTF(FD_VERIFY)) {
- /* check write protection */
- output_byte(FD_GETSTATUS);
- output_byte(UNIT(current_drive));
- if (result() != 1){
- FDCS->reset = 1;
- return;
- }
- CLEARF(FD_VERIFY);
- CLEARF(FD_NEED_TWADDLE);
-#ifdef DCL_DEBUG
- if (DP->flags & FD_DEBUG){
- DPRINT("checking whether disk is write protected\n");
- DPRINT1("wp=%x\n",ST3 & 0x40);
- }
-#endif
- if (!(ST3 & 0x40))
- SETF(FD_DISK_WRITABLE);
- else
- CLEARF(FD_DISK_WRITABLE);
- }
-}
-
-static void seek_floppy(void)
-{
- int track;
-
- blind_seek=0;
-
-#ifdef DCL_DEBUG
- if (DP->flags & FD_DEBUG){
- DPRINT("calling disk change from seek\n");
- }
-#endif
-
- if (!TESTF(FD_DISK_NEWCHANGE) &&
- disk_change(current_drive) &&
- (raw_cmd->flags & FD_RAW_NEED_DISK)){
- /* the media changed flag should be cleared after the seek.
- * If it isn't, this means that there is really no disk in
- * the drive.
- */
- SETF(FD_DISK_CHANGED);
- cont->done(0);
- cont->redo();
- return;
- }
- if (DRS->track <= NEED_1_RECAL){
- recalibrate_floppy();
- return;
- } else if (TESTF(FD_DISK_NEWCHANGE) &&
- (raw_cmd->flags & FD_RAW_NEED_DISK) &&
- (DRS->track <= NO_TRACK || DRS->track == raw_cmd->track)) {
- /* we seek to clear the media-changed condition. Does anybody
- * know a more elegant way, which works on all drives? */
- if (raw_cmd->track)
- track = raw_cmd->track - 1;
- else {
- if (DP->flags & FD_SILENT_DCL_CLEAR){
- set_dor(fdc, ~(0x10 << UNIT(current_drive)), 0);
- blind_seek = 1;
- raw_cmd->flags |= FD_RAW_NEED_SEEK;
- }
- track = 1;
- }
- } else {
- check_wp();
- if (raw_cmd->track != DRS->track &&
- (raw_cmd->flags & FD_RAW_NEED_SEEK))
- track = raw_cmd->track;
- else {
- setup_rw_floppy();
- return;
- }
- }
-
- SET_INTR(seek_interrupt);
- output_byte(FD_SEEK);
- output_byte(UNIT(current_drive));
- LAST_OUT(track);
-#ifdef DEBUGT
- debugt("seek command:");
-#endif
-}
-
-static void recal_interrupt(void)
-{
-#ifdef DEBUGT
- debugt("recal interrupt:");
-#endif
- if (inr !=2)
- FDCS->reset = 1;
- else if (ST0 & ST0_ECE) {
- switch(DRS->track){
- case NEED_1_RECAL:
-#ifdef DEBUGT
- debugt("recal interrupt need 1 recal:");
-#endif
- /* after a second recalibrate, we still haven't
- * reached track 0. Probably no drive. Raise an
- * error, as failing immediately might upset
- * computers possessed by the Devil :-) */
- cont->error();
- cont->redo();
- return;
- case NEED_2_RECAL:
-#ifdef DEBUGT
- debugt("recal interrupt need 2 recal:");
-#endif
- /* If we already did a recalibrate,
- * and we are not at track 0, this
- * means we have moved. (The only way
- * not to move at recalibration is to
- * be already at track 0.) Clear the
- * new change flag */
-#ifdef DCL_DEBUG
- if (DP->flags & FD_DEBUG){
- DPRINT("clearing NEWCHANGE flag because of second recalibrate\n");
- }
-#endif
-
- CLEARF(FD_DISK_NEWCHANGE);
- DRS->select_date = jiffies;
- /* fall through */
- default:
-#ifdef DEBUGT
- debugt("recal interrupt default:");
-#endif
- /* Recalibrate moves the head by at
- * most 80 steps. If after one
- * recalibrate we don't have reached
- * track 0, this might mean that we
- * started beyond track 80. Try
- * again. */
- DRS->track = NEED_1_RECAL;
- break;
- }
- } else
- DRS->track = ST1;
- floppy_ready();
-}
-
-/*
- * Unexpected interrupt - Print as much debugging info as we can...
- * All bets are off...
- */
-static void unexpected_floppy_interrupt(void)
-{
- int i;
- if (initialising)
- return;
- if (print_unex){
- DPRINT("unexpected interrupt\n");
- if (inr >= 0)
- for (i=0; i<inr; i++)
- printk("%d %x\n", i, reply_buffer[i]);
- }
- while(1){
- output_byte(FD_SENSEI);
- inr=result();
- if (inr != 2)
- break;
- if (print_unex){
- printk("sensei\n");
- for (i=0; i<inr; i++)
- printk("%d %x\n", i, reply_buffer[i]);
- }
- }
- FDCS->reset = 1;
-}
-
-static struct tq_struct floppy_tq =
-{ 0, 0, (void *) (void *) unexpected_floppy_interrupt, 0 };
-
-/* interrupt handler */
-static void floppy_interrupt(int irq, struct pt_regs * regs)
-{
- void (*handler)(void) = DEVICE_INTR;
-
- lasthandler = handler;
- interruptjiffies = jiffies;
-
- floppy_enable_hlt();
- CLEAR_INTR;
- if (fdc >= N_FDC || FDCS->address == -1){
- /* we don't even know which FDC is the culprit */
- printk("DOR0=%x\n", fdc_state[0].dor);
- printk("floppy interrupt on bizarre fdc %d\n",fdc);
- printk("handler=%p\n", handler);
- is_alive("bizarre fdc");
- return;
- }
- inr = result();
- if (!handler){
- unexpected_floppy_interrupt();
- is_alive("unexpected");
- return;
- }
- if (inr == 0){
- do {
- output_byte(FD_SENSEI);
- inr = result();
- } while ((ST0 & 0x83) != UNIT(current_drive) && inr == 2);
- }
- floppy_tq.routine = (void *)(void *) handler;
- queue_task_irq(&floppy_tq, &tq_timer);
- is_alive("normal interrupt end");
-}
-
-static void recalibrate_floppy(void)
-{
-#ifdef DEBUGT
- debugt("recalibrate floppy:");
-#endif
- SET_INTR(recal_interrupt);
- output_byte(FD_RECALIBRATE);
- LAST_OUT(UNIT(current_drive));
-}
-
-/*
- * Must do 4 FD_SENSEIs after reset because of ``drive polling''.
- */
-static void reset_interrupt(void)
-{
-#ifdef DEBUGT
- debugt("reset interrupt:");
-#endif
- /* fdc_specify(); reprogram fdc */
- result(); /* get the status ready for set_fdc */
- if (FDCS->reset) {
- printk("reset set in interrupt, calling %p\n", cont->error);
- cont->error(); /* a reset just after a reset. BAD! */
- }
- cont->redo();
-}
-
-/*
- * reset is done by pulling bit 2 of DOR low for a while (old FDC's),
- * or by setting the self clearing bit 7 of STATUS (newer FDC's)
- */
-static void reset_fdc(void)
-{
- SET_INTR(reset_interrupt);
- FDCS->reset = 0;
- reset_fdc_info(0);
- if (FDCS->version >= FDC_82077)
- fd_outb(0x80 | (FDCS->dtr &3), FD_STATUS);
- else {
- fd_outb(FDCS->dor & ~0x04, FD_DOR);
- udelay(FD_RESET_DELAY);
- outb(FDCS->dor, FD_DOR);
- }
-}
-
-static void empty(void)
-{
-}
-
-void show_floppy(void)
-{
- int i;
-
- printk("\n");
- printk("floppy driver state\n");
- printk("-------------------\n");
- printk("now=%ld last interrupt=%d last called handler=%p\n",
- jiffies, interruptjiffies, lasthandler);
-
-
-#ifdef FLOPPY_SANITY_CHECK
- printk("timeout_message=%s\n", timeout_message);
- printk("last output bytes:\n");
- for (i=0; i < OLOGSIZE; i++)
- printk("%2x %2x %ld\n",
- output_log[(i+output_log_pos) % OLOGSIZE].data,
- output_log[(i+output_log_pos) % OLOGSIZE].status,
- output_log[(i+output_log_pos) % OLOGSIZE].jiffies);
- printk("last result at %d\n", resultjiffies);
- printk("last redo_fd_request at %d\n", lastredo);
- for (i=0; i<resultsize; i++){
- printk("%2x ", reply_buffer[i]);
- }
- printk("\n");
-#endif
-
- printk("status=%x\n", fd_inb(FD_STATUS));
- printk("fdc_busy=%d\n", fdc_busy);
- if (DEVICE_INTR)
- printk("DEVICE_INTR=%p\n", DEVICE_INTR);
- if (floppy_tq.sync)
- printk("floppy_tq.routine=%p\n", floppy_tq.routine);
- if (fd_timer.prev)
- printk("fd_timer.function=%p\n", fd_timer.function);
- if (fd_timeout.prev){
- printk("timer_table=%p\n",fd_timeout.function);
- printk("expires=%ld\n",fd_timeout.expires-jiffies);
- printk("now=%ld\n",jiffies);
- }
- printk("cont=%p\n", cont);
- printk("CURRENT=%p\n", CURRENT);
- printk("command_status=%d\n", command_status);
- printk("\n");
-}
-
-static void floppy_shutdown(void)
-{
- if (!initialising)
- show_floppy();
- CLEAR_INTR;
- floppy_tq.routine = (void *)(void *) empty;
- del_timer(&fd_timer);
- sti();
-
- floppy_enable_hlt();
- fd_disable_dma();
- /* avoid dma going to a random drive after shutdown */
-
- if (!initialising)
- DPRINT("floppy timeout\n");
- FDCS->reset = 1;
- if (cont){
- cont->done(0);
- cont->redo(); /* this will recall reset when needed */
- } else {
- printk("no cont in shutdown!\n");
- process_fd_request();
- }
- is_alive("floppy shutdown");
-}
-/*typedef void (*timeout_fn)(unsigned long);*/
-
-/* start motor, check media-changed condition and write protection */
-static int start_motor(void (*function)(void) )
-{
- int mask, data;
-
- mask = 0xfc;
- data = UNIT(current_drive);
- if (!(raw_cmd->flags & FD_RAW_NO_MOTOR)){
- if (!(FDCS->dor & (0x10 << UNIT(current_drive)))){
- set_debugt();
- /* no read since this drive is running */
- DRS->first_read_date = 0;
- /* note motor start time if motor is not yet running */
- DRS->spinup_date = jiffies;
- data |= (0x10 << UNIT(current_drive));
- }
- } else
- if (FDCS->dor & (0x10 << UNIT(current_drive)))
- mask &= ~(0x10 << UNIT(current_drive));
-
- /* starts motor and selects floppy */
- del_timer(motor_off_timer + current_drive);
- set_dor(fdc, mask, data);
-
- /* wait_for_completion also schedules reset if needed. */
- return(wait_for_completion(DRS->select_date+DP->select_delay,
- (timeout_fn) function));
-}
-
-static void floppy_ready(void)
-{
- CHECK_RESET;
- if (start_motor(floppy_ready)) return;
- if (fdc_dtr()) return;
-
-#ifdef DCL_DEBUG
- if (DP->flags & FD_DEBUG){
- DPRINT("calling disk change from floppy_ready\n");
- }
-#endif
-
- if (!(raw_cmd->flags & FD_RAW_NO_MOTOR) &&
- disk_change(current_drive) &&
- !DP->select_delay)
- twaddle(); /* this clears the dcl on certain drive/controller
- * combinations */
-
- if (raw_cmd->flags & (FD_RAW_NEED_SEEK | FD_RAW_NEED_DISK)){
- perpendicular_mode();
- fdc_specify(); /* must be done here because of hut, hlt ... */
- seek_floppy();
- } else
- setup_rw_floppy();
-}
-
-static void floppy_start(void)
-{
- reschedule_timeout(CURRENTD, "floppy start", 0);
-
- scandrives();
-#ifdef DCL_DEBUG
- if (DP->flags & FD_DEBUG){
- DPRINT("setting NEWCHANGE in floppy_start\n");
- }
-#endif
- SETF(FD_DISK_NEWCHANGE);
- floppy_ready();
-}
-
-/*
- * ========================================================================
- * here ends the bottom half. Exported routines are:
- * floppy_start, floppy_off, floppy_ready, lock_fdc, unlock_fdc, set_fdc,
- * start_motor, reset_fdc, reset_fdc_info, interpret_errors.
- * Initialisation also uses output_byte, result, set_dor, floppy_interrupt
- * and set_dor.
- * ========================================================================
- */
-/*
- * General purpose continuations.
- * ==============================
- */
-
-static void do_wakeup(void)
-{
- reschedule_timeout(MAXTIMEOUT, "do wakeup", 0);
- cont = 0;
- command_status += 2;
- wake_up(&command_done);
-}
-
-static struct cont_t wakeup_cont={
- empty,
- do_wakeup,
- empty,
- (done_f)empty
-};
-
-static int wait_til_done(void (*handler)(void), int interruptible)
-{
- int ret;
-
- floppy_tq.routine = (void *)(void *) handler;
- queue_task(&floppy_tq, &tq_timer);
-
- cli();
- while(command_status < 2 && NO_SIGNAL){
- is_alive("wait_til_done");
- if (interruptible)
- interruptible_sleep_on(&command_done);
- else
- sleep_on(&command_done);
- }
- if (command_status < 2){
- floppy_shutdown();
- sti();
- process_fd_request();
- return -EINTR;
- }
- sti();
-
- if (FDCS->reset)
- command_status = FD_COMMAND_ERROR;
- if (command_status == FD_COMMAND_OKAY)
- ret=0;
- else
- ret=-EIO;
- command_status = FD_COMMAND_NONE;
- return ret;
-}
-
-static void generic_done(int result)
-{
- command_status = result;
- cont = &wakeup_cont;
-}
-
-static void generic_success(void)
-{
- cont->done(1);
-}
-
-static void generic_failure(void)
-{
- cont->done(0);
-}
-
-static void success_and_wakeup(void)
-{
- generic_success();
- cont->redo();
-}
-
-
-/*
- * formatting and rw support.
- * ==========================
- */
-
-static int next_valid_format(void)
-{
- int probed_format;
-
- probed_format = DRS->probed_format;
- while(1){
- if (probed_format >= 8 ||
- !DP->autodetect[probed_format]){
- DRS->probed_format = 0;
- return 1;
- }
- if (floppy_type[DP->autodetect[probed_format]].sect){
- DRS->probed_format = probed_format;
- return 0;
- }
- probed_format++;
- }
-}
-
-static void bad_flp_intr(void)
-{
- if (probing){
- DRS->probed_format++;
- if (!next_valid_format())
- return;
- }
- (*errors)++;
- INFBOUND(DRWE->badness, *errors);
- if (*errors > DP->max_errors.abort)
- cont->done(0);
- if (*errors > DP->max_errors.reset)
- FDCS->reset = 1;
- else if (*errors > DP->max_errors.recal)
- DRS->track = NEED_2_RECAL;
-}
-
-static void set_floppy(kdev_t device)
-{
- if (TYPE(device))
- floppy = TYPE(device) + floppy_type;
- else
- floppy = current_type[ DRIVE(device) ];
-}
-
-/*
- * formatting and support.
- * =======================
- */
-static void format_interrupt(void)
-{
- switch (interpret_errors()){
- case 1:
- cont->error();
- case 2:
- break;
- case 0:
- cont->done(1);
- }
- cont->redo();
-}
-
-#define CODE2SIZE (ssize = ((1 << SIZECODE) + 3) >> 2)
-#define FM_MODE(x,y) ((y) & ~(((x)->rate & 0x80) >>1))
-#define CT(x) ((x) | 0x40)
-static void setup_format_params(int track)
-{
- struct fparm {
- unsigned char track,head,sect,size;
- } *here = (struct fparm *)floppy_track_buffer;
- int il,n;
- int count,head_shift,track_shift;
-
- raw_cmd = &default_raw_cmd;
- raw_cmd->track = track;
-
- raw_cmd->flags = FD_RAW_WRITE | FD_RAW_INTR | FD_RAW_SPIN |
- /*FD_RAW_NEED_DISK |*/ FD_RAW_NEED_SEEK;
- raw_cmd->rate = floppy->rate & 0x43;
- raw_cmd->cmd_count = NR_F;
- COMMAND = FM_MODE(floppy,FD_FORMAT);
- DR_SELECT = UNIT(current_drive) + PH_HEAD(floppy,format_req.head);
- F_SIZECODE = FD_SIZECODE(floppy);
- F_SECT_PER_TRACK = floppy->sect << 2 >> F_SIZECODE;
- F_GAP = floppy->fmt_gap;
- F_FILL = FD_FILL_BYTE;
-
- raw_cmd->kernel_data = floppy_track_buffer;
- raw_cmd->length = 4 * F_SECT_PER_TRACK;
-
- /* allow for about 30ms for data transport per track */
- head_shift = (F_SECT_PER_TRACK + 5) / 6;
-
- /* a ``cylinder'' is two tracks plus a little stepping time */
- track_shift = 2 * head_shift + 3;
-
- /* position of logical sector 1 on this track */
- n = (track_shift * format_req.track + head_shift * format_req.head)
- % F_SECT_PER_TRACK;
-
- /* determine interleave */
- il = 1;
- if (floppy->sect > DP->interleave_sect && F_SIZECODE == 2)
- il++;
-
- /* initialize field */
- for (count = 0; count < F_SECT_PER_TRACK; ++count) {
- here[count].track = format_req.track;
- here[count].head = format_req.head;
- here[count].sect = 0;
- here[count].size = F_SIZECODE;
- }
- /* place logical sectors */
- for (count = 1; count <= F_SECT_PER_TRACK; ++count) {
- here[n].sect = count;
- n = (n+il) % F_SECT_PER_TRACK;
- if (here[n].sect) { /* sector busy, find next free sector */
- ++n;
- if (n>= F_SECT_PER_TRACK) {
- n-=F_SECT_PER_TRACK;
- while (here[n].sect) ++n;
- }
- }
- }
-}
-
-static void redo_format(void)
-{
- buffer_track = -1;
- setup_format_params(format_req.track << STRETCH(floppy));
- floppy_start();
-#ifdef DEBUGT
- debugt("queue format request");
-#endif
-}
-
-static struct cont_t format_cont={
- format_interrupt,
- redo_format,
- bad_flp_intr,
- generic_done };
-
-static int do_format(kdev_t device, struct format_descr *tmp_format_req)
-{
- int ret;
- int drive=DRIVE(device);
-
- LOCK_FDC(drive,1);
- set_floppy(device);
- if (!floppy ||
- floppy->track > DP->tracks ||
- tmp_format_req->track >= floppy->track ||
- tmp_format_req->head >= floppy->head ||
- (floppy->sect << 2) % (1 << FD_SIZECODE(floppy)) ||
- !floppy->fmt_gap) {
- process_fd_request();
- return -EINVAL;
- }
- format_req = *tmp_format_req;
- format_errors = 0;
- cont = &format_cont;
- errors = &format_errors;
- IWAIT(redo_format);
- process_fd_request();
- return ret;
-}
-
-/*
- * Buffer read/write and support
- * =============================
- */
-
-/* new request_done. Can handle physical sectors which are smaller than a
- * logical buffer */
-static void request_done(int uptodate)
-{
- int block;
-
- probing = 0;
- reschedule_timeout(MAXTIMEOUT, "request done %d", uptodate);
-
- if (!CURRENT){
- DPRINT("request list destroyed in floppy request done\n");
- return;
- }
- if (uptodate){
- /* maintain values for invalidation on geometry
- * change */
- block = current_count_sectors + CURRENT->sector;
- INFBOUND(DRS->maxblock, block);
- if (block > floppy->sect)
- DRS->maxtrack = 1;
-
- /* unlock chained buffers */
- while (current_count_sectors && CURRENT &&
- current_count_sectors >= CURRENT->current_nr_sectors){
- current_count_sectors -= CURRENT->current_nr_sectors;
- CURRENT->nr_sectors -= CURRENT->current_nr_sectors;
- CURRENT->sector += CURRENT->current_nr_sectors;
- end_request(1);
- }
- if (current_count_sectors && CURRENT){
- /* "unlock" last subsector */
- CURRENT->buffer += current_count_sectors <<9;
- CURRENT->current_nr_sectors -= current_count_sectors;
- CURRENT->nr_sectors -= current_count_sectors;
- CURRENT->sector += current_count_sectors;
- return;
- }
-
- if (current_count_sectors && !CURRENT)
- DPRINT("request list destroyed in floppy request done\n");
-
- } else {
- if (CURRENT->cmd == WRITE) {
- /* record write error information */
- DRWE->write_errors++;
- if (DRWE->write_errors == 1) {
- DRWE->first_error_sector = CURRENT->sector;
- DRWE->first_error_generation = DRS->generation;
- }
- DRWE->last_error_sector = CURRENT->sector;
- DRWE->last_error_generation = DRS->generation;
- }
- end_request(0);
- }
-}
-
-/* Interrupt handler evaluating the result of the r/w operation */
-static void rw_interrupt(void)
-{
- int nr_sectors, ssize;
-
- if (!DRS->first_read_date)
- DRS->first_read_date = jiffies;
-
- nr_sectors = 0;
- CODE2SIZE;
- nr_sectors = ((R_TRACK-TRACK)*floppy->head+R_HEAD-HEAD) *
- floppy->sect + ((R_SECTOR-SECTOR) << SIZECODE >> 2) -
- (sector_t % floppy->sect) % ssize;
-
-#ifdef FLOPPY_SANITY_CHECK
- if (nr_sectors > current_count_sectors + ssize -
- (current_count_sectors + sector_t) % ssize +
- sector_t % ssize){
- DPRINT2("long rw: %x instead of %lx\n",
- nr_sectors, current_count_sectors);
- printk("rs=%d s=%d\n", R_SECTOR, SECTOR);
- printk("rh=%d h=%d\n", R_HEAD, HEAD);
- printk("rt=%d t=%d\n", R_TRACK, TRACK);
- printk("spt=%d st=%d ss=%d\n", SECT_PER_TRACK,
- sector_t, ssize);
- }
-#endif
- INFBOUND(nr_sectors,0);
- SUPBOUND(current_count_sectors, nr_sectors);
-
- switch (interpret_errors()){
- case 2:
- cont->redo();
- return;
- case 1:
- if (!current_count_sectors){
- cont->error();
- cont->redo();
- return;
- }
- break;
- case 0:
- if (!current_count_sectors){
- cont->redo();
- return;
- }
- current_type[current_drive] = floppy;
- floppy_sizes[TOMINOR(current_drive) ]= floppy->size>>1;
- break;
- }
-
- if (probing) {
- if (DP->flags & FTD_MSG)
- DPRINT2("Auto-detected floppy type %s in fd%d\n",
- floppy->name,current_drive);
- current_type[current_drive] = floppy;
- floppy_sizes[TOMINOR(current_drive)] = floppy->size >> 1;
- probing = 0;
- }
-
- if (CT(COMMAND) != FD_READ ||
- raw_cmd->kernel_data == CURRENT->buffer){
- /* transfer directly from buffer */
- cont->done(1);
- } else if (CT(COMMAND) == FD_READ){
- buffer_track = raw_cmd->track;
- buffer_drive = current_drive;
- INFBOUND(buffer_max, nr_sectors + sector_t);
- }
- cont->redo();
-}
-
-/* Compute maximal contiguous buffer size. */
-static int buffer_chain_size(void)
-{
- struct buffer_head *bh;
- int size;
- char *base;
-
- base = CURRENT->buffer;
- size = CURRENT->current_nr_sectors << 9;
- bh = CURRENT->bh;
-
- if (bh){
- bh = bh->b_reqnext;
- while (bh && bh->b_data == base + size){
- size += bh->b_size;
- bh = bh->b_reqnext;
- }
- }
- return size >> 9;
-}
-
-/* Compute the maximal transfer size */
-static int transfer_size(int ssize, int max_sector, int max_size)
-{
- SUPBOUND(max_sector, sector_t + max_size);
-
- /* alignment */
- max_sector -= (max_sector % floppy->sect) % ssize;
-
- /* transfer size, beginning not aligned */
- current_count_sectors = max_sector - sector_t ;
-
- return max_sector;
-}
-
-/*
- * Move data from/to the track buffer to/from the buffer cache.
- */
-static void copy_buffer(int ssize, int max_sector, int max_sector_2)
-{
- int remaining; /* number of transferred 512-byte sectors */
- struct buffer_head *bh;
- char *buffer, *dma_buffer;
- int size;
-
- max_sector = transfer_size(ssize,
- minimum(max_sector, max_sector_2),
- CURRENT->nr_sectors);
-
- if (current_count_sectors <= 0 && CT(COMMAND) == FD_WRITE &&
- buffer_max > sector_t + CURRENT->nr_sectors)
- current_count_sectors = minimum(buffer_max - sector_t,
- CURRENT->nr_sectors);
-
- remaining = current_count_sectors << 9;
-#ifdef FLOPPY_SANITY_CHECK
- if ((remaining >> 9) > CURRENT->nr_sectors &&
- CT(COMMAND) == FD_WRITE){
- DPRINT("in copy buffer\n");
- printk("current_count_sectors=%ld\n", current_count_sectors);
- printk("remaining=%d\n", remaining >> 9);
- printk("CURRENT->nr_sectors=%ld\n",CURRENT->nr_sectors);
- printk("CURRENT->current_nr_sectors=%ld\n",
- CURRENT->current_nr_sectors);
- printk("max_sector=%d\n", max_sector);
- printk("ssize=%d\n", ssize);
- }
-#endif
-
- buffer_max = maximum(max_sector, buffer_max);
-
- dma_buffer = floppy_track_buffer + ((sector_t - buffer_min) << 9);
-
- bh = CURRENT->bh;
- size = CURRENT->current_nr_sectors << 9;
- buffer = CURRENT->buffer;
-
- while (remaining > 0){
- SUPBOUND(size, remaining);
-#ifdef FLOPPY_SANITY_CHECK
- if (dma_buffer + size >
- floppy_track_buffer + (max_buffer_sectors << 10) ||
- dma_buffer < floppy_track_buffer){
- DPRINT1("buffer overrun in copy buffer %d\n",
- (int) ((floppy_track_buffer - dma_buffer) >>9));
- printk("sector_t=%d buffer_min=%d\n",
- sector_t, buffer_min);
- printk("current_count_sectors=%ld\n",
- current_count_sectors);
- if (CT(COMMAND) == FD_READ)
- printk("read\n");
- if (CT(COMMAND) == FD_READ)
- printk("write\n");
- break;
- }
- if (((unsigned long)buffer) % 512)
- DPRINT1("%p buffer not aligned\n", buffer);
-#endif
- if (CT(COMMAND) == FD_READ) {
- fd_cacheflush(dma_buffer, size);
- memcpy(buffer, dma_buffer, size);
- } else {
- memcpy(dma_buffer, buffer, size);
- fd_cacheflush(dma_buffer, size);
- }
- remaining -= size;
- if (!remaining)
- break;
-
- dma_buffer += size;
- bh = bh->b_reqnext;
-#ifdef FLOPPY_SANITY_CHECK
- if (!bh){
- DPRINT("bh=null in copy buffer after copy\n");
- break;
- }
-#endif
- size = bh->b_size;
- buffer = bh->b_data;
- }
-#ifdef FLOPPY_SANITY_CHECK
- if (remaining){
- if (remaining > 0)
- max_sector -= remaining >> 9;
- DPRINT1("weirdness: remaining %d\n", remaining>>9);
- }
-#endif
-}
-
-/*
- * Formulate a read/write request.
- * this routine decides where to load the data (directly to buffer, or to
- * tmp floppy area), how much data to load (the size of the buffer, the whole
- * track, or a single sector)
- * All floppy_track_buffer handling goes in here. If we ever add track buffer
- * allocation on the fly, it should be done here. No other part should need
- * modification.
- */
-
-static int make_raw_rw_request(void)
-{
- int aligned_sector_t;
- int max_sector, max_size, tracksize, ssize;
-
- set_fdc(DRIVE(CURRENT->rq_dev));
-
- raw_cmd = &default_raw_cmd;
- raw_cmd->flags = FD_RAW_SPIN | FD_RAW_NEED_DISK | FD_RAW_NEED_DISK |
- FD_RAW_NEED_SEEK;
- raw_cmd->cmd_count = NR_RW;
- if (CURRENT->cmd == READ){
- raw_cmd->flags |= FD_RAW_READ;
- COMMAND = FM_MODE(floppy,FD_READ);
- } else if (CURRENT->cmd == WRITE){
- raw_cmd->flags |= FD_RAW_WRITE;
- COMMAND = FM_MODE(floppy,FD_WRITE);
- } else {
- DPRINT("make_raw_rw_request: unknown command\n");
- return 0;
- }
-
- max_sector = floppy->sect * floppy->head;
-
- TRACK = CURRENT->sector / max_sector;
- sector_t = CURRENT->sector % max_sector;
- if (floppy->track && TRACK >= floppy->track)
- return 0;
- HEAD = sector_t / floppy->sect;
-
- if (((floppy->stretch & FD_SWAPSIDES) || TESTF(FD_NEED_TWADDLE)) &&
- sector_t < floppy->sect)
- max_sector = floppy->sect;
-
- /* 2M disks have phantom sectors on the first track */
- if ((floppy->rate & FD_2M) && (!TRACK) && (!HEAD)){
- max_sector = 2 * floppy->sect / 3;
- if (sector_t >= max_sector){
- current_count_sectors = minimum(floppy->sect - sector_t,
- CURRENT->nr_sectors);
- return 1;
- }
- SIZECODE = 2;
- } else
- SIZECODE = FD_SIZECODE(floppy);
- raw_cmd->rate = floppy->rate & 0x43;
- if ((floppy->rate & FD_2M) &&
- (TRACK || HEAD) &&
- raw_cmd->rate == 2)
- raw_cmd->rate = 1;
-
- if (SIZECODE)
- SIZECODE2 = 0xff;
- else
- SIZECODE2 = 0x80;
- raw_cmd->track = TRACK << STRETCH(floppy);
- DR_SELECT = UNIT(current_drive) + PH_HEAD(floppy,HEAD);
- GAP = floppy->gap;
- CODE2SIZE;
- SECT_PER_TRACK = floppy->sect << 2 >> SIZECODE;
- SECTOR = ((sector_t % floppy->sect) << 2 >> SIZECODE) + 1;
- tracksize = floppy->sect - floppy->sect % ssize;
- if (tracksize < floppy->sect){
- SECT_PER_TRACK ++;
- if (tracksize <= sector_t % floppy->sect)
- SECTOR--;
- while (tracksize <= sector_t % floppy->sect){
- while(tracksize + ssize > floppy->sect){
- SIZECODE--;
- ssize >>= 1;
- }
- SECTOR++; SECT_PER_TRACK ++;
- tracksize += ssize;
- }
- max_sector = HEAD * floppy->sect + tracksize;
- } else if (!TRACK && !HEAD && !(floppy->rate & FD_2M) && probing)
- max_sector = floppy->sect;
-
- aligned_sector_t = sector_t - (sector_t % floppy->sect) % ssize;
- max_size = CURRENT->nr_sectors;
- if ((raw_cmd->track == buffer_track) &&
- (current_drive == buffer_drive) &&
- (sector_t >= buffer_min) && (sector_t < buffer_max)) {
- /* data already in track buffer */
- if (CT(COMMAND) == FD_READ) {
- copy_buffer(1, max_sector, buffer_max);
- return 1;
- }
- } else if (aligned_sector_t != sector_t || CURRENT->nr_sectors < ssize){
- if (CT(COMMAND) == FD_WRITE){
- if (sector_t + CURRENT->nr_sectors > ssize &&
- sector_t + CURRENT->nr_sectors < ssize + ssize)
- max_size = ssize + ssize;
- else
- max_size = ssize;
- }
- raw_cmd->flags &= ~FD_RAW_WRITE;
- raw_cmd->flags |= FD_RAW_READ;
- COMMAND = FM_MODE(floppy,FD_READ);
- } else if ((unsigned long)CURRENT->buffer < MAX_DMA_ADDRESS) {
- unsigned long dma_limit;
- int direct, indirect;
-
- indirect= transfer_size(ssize,max_sector,max_buffer_sectors*2) -
- sector_t;
-
- /*
- * Do NOT use minimum() here---MAX_DMA_ADDRESS is 64 bits wide
- * on a 64 bit machine!
- */
- max_size = buffer_chain_size();
- dma_limit = (MAX_DMA_ADDRESS - ((unsigned long) CURRENT->buffer)) >> 9;
- if ((unsigned long) max_size > dma_limit) {
- max_size = dma_limit;
- }
- /* 64 kb boundaries */
- if (CROSS_64KB(CURRENT->buffer, max_size << 9))
- max_size = (K_64 - ((long) CURRENT->buffer) % K_64)>>9;
- direct = transfer_size(ssize,max_sector,max_size) - sector_t;
- /*
- * We try to read tracks, but if we get too many errors, we
- * go back to reading just one sector at a time.
- *
- * This means we should be able to read a sector even if there
- * are other bad sectors on this track.
- */
- if (!direct ||
- (indirect * 2 > direct * 3 &&
- *errors < DP->max_errors.read_track &&
- /*!TESTF(FD_NEED_TWADDLE) &&*/
- ((!probing || (DP->read_track&(1<<DRS->probed_format)))))){
- max_size = CURRENT->nr_sectors;
- } else {
- raw_cmd->kernel_data = CURRENT->buffer;
- raw_cmd->length = current_count_sectors << 9;
- if (raw_cmd->length == 0){
- DPRINT("zero dma transfer attempted from make_raw_request\n");
- DPRINT3("indirect=%d direct=%d sector_t=%d",
- indirect, direct, sector_t);
- return 0;
- }
- return 2;
- }
- }
-
- if (CT(COMMAND) == FD_READ)
- max_size = max_sector; /* unbounded */
-
- /* claim buffer track if needed */
- if (buffer_track != raw_cmd->track || /* bad track */
- buffer_drive !=current_drive || /* bad drive */
- sector_t > buffer_max ||
- sector_t < buffer_min ||
- ((CT(COMMAND) == FD_READ ||
- (aligned_sector_t == sector_t && CURRENT->nr_sectors >= ssize))&&
- max_sector > 2 * max_buffer_sectors + buffer_min &&
- max_size + sector_t > 2 * max_buffer_sectors + buffer_min)
- /* not enough space */){
- buffer_track = -1;
- buffer_drive = current_drive;
- buffer_max = buffer_min = aligned_sector_t;
- }
- raw_cmd->kernel_data = floppy_track_buffer +
- ((aligned_sector_t-buffer_min)<<9);
-
- if (CT(COMMAND) == FD_WRITE){
- /* copy write buffer to track buffer.
- * if we get here, we know that the write
- * is either aligned or the data already in the buffer
- * (buffer will be overwritten) */
-#ifdef FLOPPY_SANITY_CHECK
- if (sector_t != aligned_sector_t && buffer_track == -1)
- DPRINT("internal error offset !=0 on write\n");
-#endif
- buffer_track = raw_cmd->track;
- buffer_drive = current_drive;
- copy_buffer(ssize, max_sector, 2*max_buffer_sectors+buffer_min);
- } else
- transfer_size(ssize, max_sector,
- 2*max_buffer_sectors+buffer_min-aligned_sector_t);
-
- /* round up current_count_sectors to get dma xfer size */
- raw_cmd->length = sector_t+current_count_sectors-aligned_sector_t;
- raw_cmd->length = ((raw_cmd->length -1)|(ssize-1))+1;
- raw_cmd->length <<= 9;
-#ifdef FLOPPY_SANITY_CHECK
- if ((raw_cmd->length < current_count_sectors << 9) ||
- (raw_cmd->kernel_data != CURRENT->buffer &&
- CT(COMMAND) == FD_WRITE &&
- (aligned_sector_t + (raw_cmd->length >> 9) > buffer_max ||
- aligned_sector_t < buffer_min)) ||
- raw_cmd->length % (128 << SIZECODE) ||
- raw_cmd->length <= 0 || current_count_sectors <= 0){
- DPRINT2("fractionary current count b=%lx s=%lx\n",
- raw_cmd->length, current_count_sectors);
- if (raw_cmd->kernel_data != CURRENT->buffer)
- printk("addr=%d, length=%ld\n",
- (int) ((raw_cmd->kernel_data -
- floppy_track_buffer) >> 9),
- current_count_sectors);
- printk("st=%d ast=%d mse=%d msi=%d\n",
- sector_t, aligned_sector_t, max_sector, max_size);
- printk("ssize=%x SIZECODE=%d\n", ssize, SIZECODE);
- printk("command=%x SECTOR=%d HEAD=%d, TRACK=%d\n",
- COMMAND, SECTOR, HEAD, TRACK);
- printk("buffer drive=%d\n", buffer_drive);
- printk("buffer track=%d\n", buffer_track);
- printk("buffer_min=%d\n", buffer_min);
- printk("buffer_max=%d\n", buffer_max);
- return 0;
- }
-
- if (raw_cmd->kernel_data != CURRENT->buffer){
- if (raw_cmd->kernel_data < floppy_track_buffer ||
- current_count_sectors < 0 ||
- raw_cmd->length < 0 ||
- raw_cmd->kernel_data + raw_cmd->length >
- floppy_track_buffer + (max_buffer_sectors << 10)){
- DPRINT("buffer overrun in schedule dma\n");
- printk("sector_t=%d buffer_min=%d current_count=%ld\n",
- sector_t, buffer_min,
- raw_cmd->length >> 9);
- printk("current_count_sectors=%ld\n",
- current_count_sectors);
- if (CT(COMMAND) == FD_READ)
- printk("read\n");
- if (CT(COMMAND) == FD_READ)
- printk("write\n");
- return 0;
- }
- } else if (raw_cmd->length > CURRENT->nr_sectors << 9 ||
- current_count_sectors > CURRENT->nr_sectors){
- DPRINT("buffer overrun in direct transfer\n");
- return 0;
- } else if (raw_cmd->length < current_count_sectors << 9){
- DPRINT("more sectors than bytes\n");
- printk("bytes=%ld\n", raw_cmd->length >> 9);
- printk("sectors=%ld\n", current_count_sectors);
- }
- if (raw_cmd->length == 0){
- DPRINT("zero dma transfer attempted from make_raw_request\n");
- return 0;
- }
-#endif
- return 2;
-}
-
-static void redo_fd_request(void)
-{
-#define REPEAT {request_done(0); continue; }
- kdev_t device;
- int tmp;
-
- lastredo = jiffies;
- if (current_drive < N_DRIVE)
- floppy_off(current_drive);
-
- if (CURRENT && CURRENT->rq_status == RQ_INACTIVE){
- DPRINT("current not active!\n");
- return;
- }
-
- while(1){
- if (!CURRENT) {
- CLEAR_INTR;
- unlock_fdc();
- return;
- }
- if (MAJOR(CURRENT->rq_dev) != MAJOR_NR)
- panic(DEVICE_NAME ": request list destroyed");
- if (CURRENT->bh && !buffer_locked(CURRENT->bh))
- panic(DEVICE_NAME ": block not locked");
-
- device = CURRENT->rq_dev;
- set_fdc(DRIVE(device));
- reschedule_timeout(CURRENTD, "redo fd request", 0);
-
- set_floppy(device);
- raw_cmd = & default_raw_cmd;
- raw_cmd->flags = 0;
- if (start_motor(redo_fd_request)) return;
- if (test_bit(current_drive, &fake_change) ||
- TESTF(FD_DISK_CHANGED)){
- DPRINT("disk absent or changed during operation\n");
- REPEAT;
- }
- if (!floppy) { /* Autodetection */
- if (!probing){
- DRS->probed_format = 0;
- if (next_valid_format()){
- DPRINT("no autodetectable formats\n");
- floppy = NULL;
- REPEAT;
- }
- }
- probing = 1;
- floppy = floppy_type+DP->autodetect[DRS->probed_format];
- } else
- probing = 0;
- errors = & (CURRENT->errors);
- tmp = make_raw_rw_request();
- if (tmp < 2){
- request_done(tmp);
- continue;
- }
-
- if (TESTF(FD_NEED_TWADDLE))
- twaddle();
- floppy_tq.routine = (void *)(void *) floppy_start;
- queue_task(&floppy_tq, &tq_timer);
-#ifdef DEBUGT
- debugt("queue fd request");
-#endif
- return;
- }
-#undef REPEAT
-}
-
-static struct cont_t rw_cont={
- rw_interrupt,
- redo_fd_request,
- bad_flp_intr,
- request_done };
-
-static struct tq_struct request_tq =
-{ 0, 0, (void *) (void *) redo_fd_request, 0 };
-
-static void process_fd_request(void)
-{
- cont = &rw_cont;
- queue_task(&request_tq, &tq_timer);
-}
-
-static void do_fd_request(void)
-{
- if (fdc_busy){
- /* fdc busy, this new request will be treated when the
- current one is done */
- is_alive("do fd request, old request running");
- return;
- }
- lock_fdc(MAXTIMEOUT,0);
- process_fd_request();
- is_alive("do fd request");
-}
-
-static struct cont_t poll_cont={
- success_and_wakeup,
- floppy_ready,
- generic_failure,
- generic_done };
-
-static int poll_drive(int interruptible, int flag)
-{
- int ret;
- /* no auto-sense, just clear dcl */
- raw_cmd = &default_raw_cmd;
- raw_cmd->flags= flag;
- raw_cmd->track=0;
- raw_cmd->cmd_count=0;
- cont = &poll_cont;
-#ifdef DCL_DEBUG
- if (DP->flags & FD_DEBUG){
- DPRINT("setting NEWCHANGE in poll_drive\n");
- }
-#endif
- SETF(FD_DISK_NEWCHANGE);
- WAIT(floppy_ready);
- return ret;
-}
-
-/*
- * User triggered reset
- * ====================
- */
-
-static void reset_intr(void)
-{
- printk("weird, reset interrupt called\n");
-}
-
-static struct cont_t reset_cont={
- reset_intr,
- success_and_wakeup,
- generic_failure,
- generic_done };
-
-static int user_reset_fdc(int drive, int arg, int interruptible)
-{
- int ret;
-
- ret=0;
- LOCK_FDC(drive,interruptible);
- if (arg == FD_RESET_ALWAYS)
- FDCS->reset=1;
- if (FDCS->reset){
- cont = &reset_cont;
- WAIT(reset_fdc);
- }
- process_fd_request();
- return ret;
-}
-
-/*
- * Misc Ioctl's and support
- * ========================
- */
-static int fd_copyout(void *param, const void *address, int size)
-{
- int ret;
-
- ECALL(verify_area(VERIFY_WRITE,param,size));
- fd_cacheflush(address, size); /* is this necessary ??? */
- /* Ralf: Yes; only the l2 cache is completly chipset
- controlled */
- memcpy_tofs(param,(void *) address, size);
- return 0;
-}
-
-static int fd_copyin(void *param, void *address, int size)
-{
- int ret;
-
- ECALL(verify_area(VERIFY_READ,param,size));
- memcpy_fromfs((void *) address, param, size);
- return 0;
-}
-
-#define COPYOUT(x) ECALL(fd_copyout((void *)param, &(x), sizeof(x)))
-#define COPYIN(x) ECALL(fd_copyin((void *)param, &(x), sizeof(x)))
-
-static inline const char *drive_name(int type, int drive)
-{
- struct floppy_struct *floppy;
-
- if (type)
- floppy = floppy_type + type;
- else {
- if (UDP->native_format)
- floppy = floppy_type + UDP->native_format;
- else
- return "(null)";
- }
- if (floppy->name)
- return floppy->name;
- else
- return "(null)";
-}
-
-
-/* raw commands */
-static void raw_cmd_done(int flag)
-{
- int i;
-
- if (!flag) {
- raw_cmd->flags = FD_RAW_FAILURE;
- raw_cmd->flags |= FD_RAW_HARDFAILURE;
- } else {
- raw_cmd->reply_count = inr;
- for (i=0; i< raw_cmd->reply_count; i++)
- raw_cmd->reply[i] = reply_buffer[i];
-
- if (raw_cmd->flags & (FD_RAW_READ | FD_RAW_WRITE))
- raw_cmd->length = get_dma_residue(FLOPPY_DMA);
-
- if ((raw_cmd->flags & FD_RAW_SOFTFAILURE) &&
- (!raw_cmd->reply_count || (raw_cmd->reply[0] & 0xc0)))
- raw_cmd->flags |= FD_RAW_FAILURE;
-
- if (disk_change(current_drive))
- raw_cmd->flags |= FD_RAW_DISK_CHANGE;
- else
- raw_cmd->flags &= ~FD_RAW_DISK_CHANGE;
- if (raw_cmd->flags & FD_RAW_NO_MOTOR_AFTER)
- motor_off_callback(current_drive);
-
- if (raw_cmd->next &&
- (!(raw_cmd->flags & FD_RAW_FAILURE) ||
- !(raw_cmd->flags & FD_RAW_STOP_IF_FAILURE)) &&
- ((raw_cmd->flags & FD_RAW_FAILURE) ||
- !(raw_cmd->flags &FD_RAW_STOP_IF_SUCCESS))) {
- raw_cmd = raw_cmd->next;
- return;
- }
- }
- generic_done(flag);
-}
-
-
-static struct cont_t raw_cmd_cont={
- success_and_wakeup,
- floppy_start,
- generic_failure,
- raw_cmd_done
-};
-
-static inline int raw_cmd_copyout(int cmd, char *param,
- struct floppy_raw_cmd *ptr)
-{
- struct old_floppy_raw_cmd old_raw_cmd;
- int ret;
-
- while(ptr) {
- if (cmd == OLDFDRAWCMD) {
- old_raw_cmd.flags = ptr->flags;
- old_raw_cmd.data = ptr->data;
- old_raw_cmd.length = ptr->length;
- old_raw_cmd.rate = ptr->rate;
- old_raw_cmd.reply_count = ptr->reply_count;
- memcpy(old_raw_cmd.reply, ptr->reply, 7);
- COPYOUT(old_raw_cmd);
- param += sizeof(old_raw_cmd);
- } else {
- COPYOUT(*ptr);
- param += sizeof(struct floppy_raw_cmd);
- }
-
- if ((ptr->flags & FD_RAW_READ) && ptr->buffer_length){
- if (ptr->length>=0 && ptr->length<=ptr->buffer_length)
- ECALL(fd_copyout(ptr->data,
- ptr->kernel_data,
- ptr->buffer_length -
- ptr->length));
- }
- ptr = ptr->next;
- }
- return 0;
-}
-
-
-static void raw_cmd_free(struct floppy_raw_cmd **ptr)
-{
- struct floppy_raw_cmd *next,*this;
-
- this = *ptr;
- *ptr = 0;
- while(this) {
- if (this->buffer_length) {
- free_pages((unsigned long)this->kernel_data,
- __get_order(this->buffer_length));
- this->buffer_length = 0;
- }
- next = this->next;
- kfree(this);
- this = next;
- }
-}
-
-
-static inline int raw_cmd_copyin(int cmd, char *param,
- struct floppy_raw_cmd **rcmd)
-{
- struct floppy_raw_cmd *ptr;
- struct old_floppy_raw_cmd old_raw_cmd;
- int ret;
- int i;
-
- *rcmd = 0;
- while(1) {
- ptr = (struct floppy_raw_cmd *)
- kmalloc(sizeof(struct floppy_raw_cmd), GFP_USER);
- if (!ptr)
- return -ENOMEM;
- *rcmd = ptr;
- if (cmd == OLDFDRAWCMD){
- COPYIN(old_raw_cmd);
- ptr->flags = old_raw_cmd.flags;
- ptr->data = old_raw_cmd.data;
- ptr->length = old_raw_cmd.length;
- ptr->rate = old_raw_cmd.rate;
- ptr->cmd_count = old_raw_cmd.cmd_count;
- ptr->track = old_raw_cmd.track;
- ptr->phys_length = 0;
- ptr->next = 0;
- ptr->buffer_length = 0;
- memcpy(ptr->cmd, old_raw_cmd.cmd, 9);
- param += sizeof(struct old_floppy_raw_cmd);
- if (ptr->cmd_count > 9)
- return -EINVAL;
- } else {
- COPYIN(*ptr);
- ptr->next = 0;
- ptr->buffer_length = 0;
- param += sizeof(struct floppy_raw_cmd);
- if (ptr->cmd_count > 16)
- return -EINVAL;
- }
-
- for (i=0; i< 16; i++)
- ptr->reply[i] = 0;
- ptr->resultcode = 0;
- ptr->kernel_data = 0;
-
- if (ptr->flags & (FD_RAW_READ | FD_RAW_WRITE)) {
- if (ptr->length <= 0)
- return -EINVAL;
- ptr->kernel_data =(char*)dma_mem_alloc(ptr->length);
- if (!ptr->kernel_data)
- return -ENOMEM;
- ptr->buffer_length = ptr->length;
- }
- if ( ptr->flags & FD_RAW_READ )
- ECALL( verify_area( VERIFY_WRITE, ptr->data,
- ptr->length ));
- if (ptr->flags & FD_RAW_WRITE)
- ECALL(fd_copyin(ptr->data, ptr->kernel_data,
- ptr->length));
- rcmd = & (ptr->next);
- if (!(ptr->flags & FD_RAW_MORE))
- return 0;
- ptr->rate &= 0x43;
- }
-}
-
-
-static int raw_cmd_ioctl(int cmd, void *param)
-{
- int drive, ret, ret2;
- struct floppy_raw_cmd *my_raw_cmd;
-
- if (FDCS->rawcmd <= 1)
- FDCS->rawcmd = 1;
- for (drive= 0; drive < N_DRIVE; drive++){
- if (FDC(drive) != fdc)
- continue;
- if (drive == current_drive){
- if (UDRS->fd_ref > 1){
- FDCS->rawcmd = 2;
- break;
- }
- } else if (UDRS->fd_ref){
- FDCS->rawcmd = 2;
- break;
- }
- }
-
- if (FDCS->reset)
- return -EIO;
-
- ret = raw_cmd_copyin(cmd, param, &my_raw_cmd);
- if (ret) {
- raw_cmd_free(&my_raw_cmd);
- return ret;
- }
-
- raw_cmd = my_raw_cmd;
- cont = &raw_cmd_cont;
- ret=wait_til_done(floppy_start,1);
-#ifdef DCL_DEBUG
- if (DP->flags & FD_DEBUG){
- DPRINT("calling disk change from raw_cmd ioctl\n");
- }
-#endif
-
- if (ret != -EINTR && FDCS->reset)
- ret = -EIO;
-
- DRS->track = NO_TRACK;
-
- ret2 = raw_cmd_copyout(cmd, param, my_raw_cmd);
- if (!ret)
- ret = ret2;
- raw_cmd_free(&my_raw_cmd);
- return ret;
-}
-
-static int invalidate_drive(kdev_t rdev)
-{
- /* invalidate the buffer track to force a reread */
- set_bit(DRIVE(rdev), &fake_change);
- process_fd_request();
- check_disk_change(rdev);
- return 0;
-}
-
-
-static inline void clear_write_error(int drive)
-{
- CLEARSTRUCT(UDRWE);
-}
-
-static inline int set_geometry(unsigned int cmd, struct floppy_struct *g,
- int drive, int type, kdev_t device)
-{
- int cnt;
-
- /* sanity checking for parameters.*/
- if (g->sect <= 0 ||
- g->head <= 0 ||
- g->track <= 0 ||
- g->track > UDP->tracks>>STRETCH(g) ||
- /* check if reserved bits are set */
- (g->stretch&~(FD_STRETCH|FD_SWAPSIDES)) != 0)
- return -EINVAL;
- if (type){
- if (!suser())
- return -EPERM;
- LOCK_FDC(drive,1);
- for (cnt = 0; cnt < N_DRIVE; cnt++){
- if (ITYPE(drive_state[cnt].fd_device) == type &&
- drive_state[cnt].fd_ref)
- set_bit(drive, &fake_change);
- }
- floppy_type[type] = *g;
- floppy_type[type].name="user format";
- for (cnt = type << 2; cnt < (type << 2) + 4; cnt++)
- floppy_sizes[cnt]= floppy_sizes[cnt+0x80]=
- floppy_type[type].size>>1;
- process_fd_request();
- for (cnt = 0; cnt < N_DRIVE; cnt++){
- if (ITYPE(drive_state[cnt].fd_device) == type &&
- drive_state[cnt].fd_ref)
- check_disk_change(
- MKDEV(FLOPPY_MAJOR,
- drive_state[cnt].fd_device));
- }
- } else {
- LOCK_FDC(drive,1);
- if (cmd != FDDEFPRM)
- /* notice a disk change immediately, else
- * we loose our settings immediately*/
- CALL(poll_drive(1,0));
- user_params[drive] = *g;
- if (buffer_drive == drive)
- SUPBOUND(buffer_max, user_params[drive].sect);
- current_type[drive] = &user_params[drive];
- floppy_sizes[drive] = user_params[drive].size >> 1;
- if (cmd == FDDEFPRM)
- DRS->keep_data = -1;
- else
- DRS->keep_data = 1;
- /* invalidation. Invalidate only when needed, i.e.
- * when there are already sectors in the buffer cache
- * whose number will change. This is useful, because
- * mtools often changes the geometry of the disk after
- * looking at the boot block */
- if (DRS->maxblock > user_params[drive].sect || DRS->maxtrack)
- invalidate_drive(device);
- else
- process_fd_request();
- }
- return 0;
-}
-
-/* handle obsolete ioctl's */
-static struct translation_entry {
- int newcmd;
- int oldcmd;
- int oldsize; /* size of 0x00xx-style ioctl. Reflects old structures, thus
- * use numeric values. NO SIZEOFS */
-} translation_table[]= {
- {FDCLRPRM, 0, 0},
- {FDSETPRM, 1, 28},
- {FDDEFPRM, 2, 28},
- {FDGETPRM, 3, 28},
- {FDMSGON, 4, 0},
- {FDMSGOFF, 5, 0},
- {FDFMTBEG, 6, 0},
- {FDFMTTRK, 7, 12},
- {FDFMTEND, 8, 0},
- {FDSETEMSGTRESH, 10, 0},
- {FDFLUSH, 11, 0},
- {FDSETMAXERRS, 12, 20},
- {OLDFDRAWCMD, 30, 0},
- {FDGETMAXERRS, 14, 20},
- {FDGETDRVTYP, 16, 16},
- {FDSETDRVPRM, 20, 88},
- {FDGETDRVPRM, 21, 88},
- {FDGETDRVSTAT, 22, 52},
- {FDPOLLDRVSTAT, 23, 52},
- {FDRESET, 24, 0},
- {FDGETFDCSTAT, 25, 40},
- {FDWERRORCLR, 27, 0},
- {FDWERRORGET, 28, 24},
- {FDRAWCMD, 0, 0},
- {FDTWADDLE, 40, 0} };
-
-static inline int normalize_0x02xx_ioctl(int *cmd, int *size)
-{
- int i;
-
- for (i=0; i < ARRAY_SIZE(translation_table); i++) {
- if ((*cmd & 0xffff) == (translation_table[i].newcmd & 0xffff)){
- *size = _IOC_SIZE(*cmd);
- *cmd = translation_table[i].newcmd;
- if (*size > _IOC_SIZE(*cmd)) {
- printk("ioctl not yet supported\n");
- return -EFAULT;
- }
- return 0;
- }
- }
- return -EINVAL;
-}
-
-static inline int xlate_0x00xx_ioctl(int *cmd, int *size)
-{
- int i;
- /* old ioctls' for kernels <= 1.3.33 */
- /* When the next even release will come around, we'll start
- * warning against these.
- * When the next odd release will come around, we'll fail with
- * -EINVAL */
- if(strcmp(system_utsname.version, "1.4.0") >= 0)
- printk("obsolete floppy ioctl %x\n", *cmd);
- if((system_utsname.version[0] == '1' &&
- strcmp(system_utsname.version, "1.5.0") >= 0) ||
- (system_utsname.version[0] >= '2' &&
- strcmp(system_utsname.version, "2.1.0") >= 0))
- return -EINVAL;
- for (i=0; i < ARRAY_SIZE(translation_table); i++) {
- if (*cmd == translation_table[i].oldcmd) {
- *size = translation_table[i].oldsize;
- *cmd = translation_table[i].newcmd;
- return 0;
- }
- }
- return -EINVAL;
-}
-
-static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
- unsigned long param)
-{
-#define IOCTL_MODE_BIT 8
-#define OPEN_WRITE_BIT 16
-#define IOCTL_ALLOWED (filp && (filp->f_mode & IOCTL_MODE_BIT))
-#define OUT(c,x) case c: outparam = (const char *) (x); break
-#define IN(c,x,tag) case c: *(x) = inparam. tag ; return 0
-
- int i,drive,type;
- kdev_t device;
- int ret;
- int size;
- union inparam {
- struct floppy_struct g; /* geometry */
- struct format_descr f;
- struct floppy_max_errors max_errors;
- struct floppy_drive_params dp;
- } inparam; /* parameters coming from user space */
- const char *outparam; /* parameters passed back to user space */
-
- device = inode->i_rdev;
- switch (cmd) {
- RO_IOCTLS(device,param);
- }
- type = TYPE(device);
- drive = DRIVE(device);
-
- /* convert the old style command into a new style command */
- if ((cmd & 0xff00) == 0x0200) {
- ECALL(normalize_0x02xx_ioctl(&cmd, &size));
- } else if ((cmd & 0xff00) == 0x0000) {
- ECALL(xlate_0x00xx_ioctl(&cmd, &size));
- } else
- return -EINVAL;
-
- /* permission checks */
- if (((cmd & 0x80) && !suser()) ||
- ((cmd & 0x40) && !IOCTL_ALLOWED))
- return -EPERM;
-
- /* verify writability of result, and fail early */
- if (_IOC_DIR(cmd) & _IOC_READ)
- ECALL(verify_area(VERIFY_WRITE,(void *) param, size));
-
- /* copyin */
- CLEARSTRUCT(&inparam);
- if (_IOC_DIR(cmd) & _IOC_WRITE)
- ECALL(fd_copyin((void *)param, &inparam, size))
-
- switch (cmd) {
- case FDCLRPRM:
- LOCK_FDC(drive,1);
- current_type[drive] = NULL;
- floppy_sizes[drive] = MAX_DISK_SIZE;
- UDRS->keep_data = 0;
- return invalidate_drive(device);
- case FDSETPRM:
- case FDDEFPRM:
- return set_geometry(cmd, & inparam.g,
- drive, type, device);
- case FDGETPRM:
- if (type)
- outparam = (char *) &floppy_type[type];
- else
- outparam = (char *) current_type[drive];
- if(!outparam)
- return -ENODEV;
- break;
-
- case FDMSGON:
- UDP->flags |= FTD_MSG;
- return 0;
- case FDMSGOFF:
- UDP->flags &= ~FTD_MSG;
- return 0;
-
- case FDFMTBEG:
- LOCK_FDC(drive,1);
- CALL(poll_drive(1, FD_RAW_NEED_DISK));
- ret = UDRS->flags;
- process_fd_request();
- if(ret & FD_VERIFY)
- return -ENODEV;
- if(!(ret & FD_DISK_WRITABLE))
- return -EROFS;
- return 0;
- case FDFMTTRK:
- if (UDRS->fd_ref != 1)
- return -EBUSY;
- return do_format(device, &inparam.f);
- case FDFMTEND:
- case FDFLUSH:
- LOCK_FDC(drive,1);
- return invalidate_drive(device);
-
- case FDSETEMSGTRESH:
- UDP->max_errors.reporting =
- (unsigned short) (param & 0x0f);
- return 0;
- OUT(FDGETMAXERRS, &UDP->max_errors);
- IN(FDSETMAXERRS, &UDP->max_errors, max_errors);
-
- case FDGETDRVTYP:
- outparam = drive_name(type,drive);
- SUPBOUND(size,strlen(outparam)+1);
- break;
-
- IN(FDSETDRVPRM, UDP, dp);
- OUT(FDGETDRVPRM, UDP);
-
- case FDPOLLDRVSTAT:
- LOCK_FDC(drive,1);
- CALL(poll_drive(1, FD_RAW_NEED_DISK));
- process_fd_request();
- /* fall through */
- OUT(FDGETDRVSTAT, UDRS);
-
- case FDRESET:
- return user_reset_fdc(drive, (int)param, 1);
-
- OUT(FDGETFDCSTAT,UFDCS);
-
- case FDWERRORCLR:
- CLEARSTRUCT(UDRWE);
- return 0;
- OUT(FDWERRORGET,UDRWE);
-
- case OLDFDRAWCMD:
- case FDRAWCMD:
- if (type)
- return -EINVAL;
- LOCK_FDC(drive,1);
- set_floppy(device);
- CALL(i = raw_cmd_ioctl(cmd,(void *) param));
- process_fd_request();
- return i;
-
- case FDTWADDLE:
- LOCK_FDC(drive,1);
- twaddle();
- process_fd_request();
- return 0;
-
- default:
- return -EINVAL;
- }
-
- if (_IOC_DIR(cmd) & _IOC_READ)
- return fd_copyout((void *)param, outparam, size);
- else
- return 0;
-#undef IOCTL_ALLOWED
-#undef OUT
-#undef IN
-}
-
-static void config_types(void)
-{
- int first=1;
- int drive;
-
- /* read drive info out of physical cmos */
- drive=0;
- if (!UDP->cmos)
- UDP->cmos= FLOPPY0_TYPE;
- drive=1;
- if (!UDP->cmos && FLOPPY1_TYPE)
- UDP->cmos = FLOPPY1_TYPE;
-
- /* XXX */
- /* additional physical CMOS drive detection should go here */
-
- for (drive=0; drive < N_DRIVE; drive++){
- if (UDP->cmos >= 0 && UDP->cmos <= NUMBER(default_drive_params))
- memcpy((char *) UDP,
- (char *) (&default_drive_params[(int)UDP->cmos].params),
- sizeof(struct floppy_drive_params));
- if (UDP->cmos){
- if (first)
- printk("Floppy drive(s): ");
- else
- printk(", ");
- first=0;
- if (UDP->cmos > 0){
- allowed_drive_mask |= 1 << drive;
- printk("fd%d is %s", drive,
- default_drive_params[(int)UDP->cmos].name);
- } else
- printk("fd%d is unknown type %d",drive,
- UDP->cmos);
- }
- }
- if (!first)
- printk("\n");
-}
-
-static int floppy_read(struct inode * inode, struct file * filp,
- char * buf, int count)
-{
- int drive = DRIVE(inode->i_rdev);
-
- check_disk_change(inode->i_rdev);
- if (UTESTF(FD_DISK_CHANGED))
- return -ENXIO;
- return block_read(inode, filp, buf, count);
-}
-
-static int floppy_write(struct inode * inode, struct file * filp,
- const char * buf, int count)
-{
- int block;
- int ret;
- int drive = DRIVE(inode->i_rdev);
-
- if (!UDRS->maxblock)
- UDRS->maxblock=1;/* make change detectable */
- check_disk_change(inode->i_rdev);
- if (UTESTF(FD_DISK_CHANGED))
- return -ENXIO;
- if (!UTESTF(FD_DISK_WRITABLE))
- return -EROFS;
- block = (filp->f_pos + count) >> 9;
- INFBOUND(UDRS->maxblock, block);
- ret= block_write(inode, filp, buf, count);
- return ret;
-}
-
-static void floppy_release(struct inode * inode, struct file * filp)
-{
- int drive;
-
- drive = DRIVE(inode->i_rdev);
-
- if (!filp || (filp->f_mode & (2 | OPEN_WRITE_BIT)))
- /* if the file is mounted OR (writable now AND writable at
- * open time) Linus: Does this cover all cases? */
- block_fsync(inode,filp);
-
- if (UDRS->fd_ref < 0)
- UDRS->fd_ref=0;
- else if (!UDRS->fd_ref--) {
- DPRINT("floppy_release with fd_ref == 0");
- UDRS->fd_ref = 0;
- }
- floppy_release_irq_and_dma();
-}
-
-/*
- * floppy_open check for aliasing (/dev/fd0 can be the same as
- * /dev/PS0 etc), and disallows simultaneous access to the same
- * drive with different device numbers.
- */
-#define RETERR(x) do{floppy_release(inode,filp); return -(x);}while(0)
-
-static int floppy_open(struct inode * inode, struct file * filp)
-{
- int drive;
- int old_dev;
- int try;
- char *tmp;
-
- if (!filp) {
- DPRINT("Weird, open called with filp=0\n");
- return -EIO;
- }
-
- drive = DRIVE(inode->i_rdev);
- if (drive >= N_DRIVE ||
- !(allowed_drive_mask & (1 << drive)) ||
- fdc_state[FDC(drive)].version == FDC_NONE)
- return -ENXIO;
-
- if (TYPE(inode->i_rdev) >= NUMBER(floppy_type))
- return -ENXIO;
- old_dev = UDRS->fd_device;
- if (UDRS->fd_ref && old_dev != MINOR(inode->i_rdev))
- return -EBUSY;
-
- if (!UDRS->fd_ref && (UDP->flags & FD_BROKEN_DCL)){
- USETF(FD_DISK_CHANGED);
- USETF(FD_VERIFY);
- }
-
- if (UDRS->fd_ref == -1 ||
- (UDRS->fd_ref && (filp->f_flags & O_EXCL)))
- return -EBUSY;
-
- if (floppy_grab_irq_and_dma())
- return -EBUSY;
-
- if (filp->f_flags & O_EXCL)
- UDRS->fd_ref = -1;
- else
- UDRS->fd_ref++;
-
- if (!floppy_track_buffer){
- /* if opening an ED drive, reserve a big buffer,
- * else reserve a small one */
- if ((UDP->cmos == 6) || (UDP->cmos == 5))
- try = 64; /* Only 48 actually useful */
- else
- try = 32; /* Only 24 actually useful */
-
- tmp=(char *)dma_mem_alloc(1024 * try);
- if (!tmp) {
- try >>= 1; /* buffer only one side */
- INFBOUND(try, 16);
- tmp= (char *)dma_mem_alloc(1024*try);
- }
- if (!tmp) {
- DPRINT("Unable to allocate DMA memory\n");
- RETERR(ENXIO);
- }
- if (floppy_track_buffer){
- free_pages((unsigned long)tmp,__get_order(try*1024));
- }else {
- buffer_min = buffer_max = -1;
- floppy_track_buffer = tmp;
- max_buffer_sectors = try;
- }
- }
-
- UDRS->fd_device = MINOR(inode->i_rdev);
- if (old_dev != -1 && old_dev != MINOR(inode->i_rdev)) {
- if (buffer_drive == drive)
- buffer_track = -1;
- invalidate_buffers(MKDEV(FLOPPY_MAJOR,old_dev));
- }
-
- /* Allow ioctls if we have write-permissions even if read-only open */
- if ((filp->f_mode & 2) || (permission(inode,2) == 0))
- filp->f_mode |= IOCTL_MODE_BIT;
- if (filp->f_mode & 2)
- filp->f_mode |= OPEN_WRITE_BIT;
-
- if (UFDCS->rawcmd == 1)
- UFDCS->rawcmd = 2;
-
- if (filp->f_flags & O_NDELAY)
- return 0;
- if (filp->f_mode & 3) {
- UDRS->last_checked = 0;
- check_disk_change(inode->i_rdev);
- if (UTESTF(FD_DISK_CHANGED))
- RETERR(ENXIO);
- }
- if ((filp->f_mode & 2) && !(UTESTF(FD_DISK_WRITABLE)))
- RETERR(EROFS);
- return 0;
-#undef RETERR
-}
-
-/*
- * Check if the disk has been changed or if a change has been faked.
- */
-static int check_floppy_change(kdev_t dev)
-{
- int drive = DRIVE(dev);
-
- if (MAJOR(dev) != MAJOR_NR) {
- DPRINT("floppy_changed: not a floppy\n");
- return 0;
- }
-
- if (UTESTF(FD_DISK_CHANGED) || UTESTF(FD_VERIFY))
- return 1;
-
- if (UDRS->last_checked + UDP->checkfreq < jiffies){
- lock_fdc(drive,0);
- poll_drive(0,0);
- process_fd_request();
- }
-
- if (UTESTF(FD_DISK_CHANGED) ||
- UTESTF(FD_VERIFY) ||
- test_bit(drive, &fake_change) ||
- (!TYPE(dev) && !current_type[drive]))
- return 1;
- return 0;
-}
-
-/* revalidate the floppy disk, i.e. trigger format autodetection by reading
- * the bootblock (block 0). "Autodetection" is also needed to check whether
- * there is a disk in the drive at all... Thus we also do it for fixed
- * geometry formats */
-static int floppy_revalidate(kdev_t dev)
-{
-#define NO_GEOM (!current_type[drive] && !TYPE(dev))
- struct buffer_head * bh;
- int drive=DRIVE(dev);
- int cf;
-
- if (UTESTF(FD_DISK_CHANGED) ||
- UTESTF(FD_VERIFY) ||
- test_bit(drive, &fake_change) ||
- NO_GEOM){
- lock_fdc(drive,0);
- cf = UTESTF(FD_DISK_CHANGED) || UTESTF(FD_VERIFY);
- if (!(cf || test_bit(drive, &fake_change) || NO_GEOM)){
- process_fd_request(); /*already done by another thread*/
- return 0;
- }
- UDRS->maxblock = 0;
- UDRS->maxtrack = 0;
- if (buffer_drive == drive)
- buffer_track = -1;
- clear_bit(drive, &fake_change);
- UCLEARF(FD_DISK_CHANGED);
- if (cf)
- UDRS->generation++;
- if (NO_GEOM){
- /* auto-sensing */
- int size = floppy_blocksizes[MINOR(dev)];
- if (!size)
- size = 1024;
- if (!(bh = getblk(dev,0,size))){
- process_fd_request();
- return 1;
- }
- if (bh && !buffer_uptodate(bh))
- ll_rw_block(READ, 1, &bh);
- process_fd_request();
- wait_on_buffer(bh);
- brelse(bh);
- return 0;
- }
- if (cf)
- poll_drive(0, FD_RAW_NEED_DISK);
- process_fd_request();
- }
- return 0;
-}
-
-static struct file_operations floppy_fops = {
- NULL, /* lseek - default */
- floppy_read, /* read - general block-dev read */
- floppy_write, /* write - general block-dev write */
- NULL, /* readdir - bad */
- NULL, /* select */
- fd_ioctl, /* ioctl */
- NULL, /* mmap */
- floppy_open, /* open */
- floppy_release, /* release */
- block_fsync, /* fsync */
- NULL, /* fasync */
- check_floppy_change, /* media_change */
- floppy_revalidate, /* revalidate */
-};
-
-/*
- * Floppy Driver initialisation
- * =============================
- */
-
-/* Determine the floppy disk controller type */
-/* This routine was written by David C. Niemi */
-static char get_fdc_version(void)
-{
- int r;
-
- output_byte(FD_DUMPREGS); /* 82072 and better know DUMPREGS */
- if (FDCS->reset)
- return FDC_NONE;
- if ((r = result()) <= 0x00)
- return FDC_NONE; /* No FDC present ??? */
- if ((r==1) && (reply_buffer[0] == 0x80)){
- printk("FDC %d is a 8272A\n",fdc);
- return FDC_8272A; /* 8272a/765 don't know DUMPREGS */
- }
- if (r != 10) {
- printk("FDC %d init: DUMPREGS: unexpected return of %d bytes.\n",
- fdc, r);
- return FDC_UNKNOWN;
- }
- output_byte(FD_VERSION);
- r = result();
- if ((r == 1) && (reply_buffer[0] == 0x80)){
- printk("FDC %d is a 82072\n",fdc);
- return FDC_82072; /* 82072 doesn't know VERSION */
- }
- if ((r != 1) || (reply_buffer[0] != 0x90)) {
- printk("FDC %d init: VERSION: unexpected return of %d bytes.\n",
- fdc, r);
- return FDC_UNKNOWN;
- }
- output_byte(FD_UNLOCK);
- r = result();
- if ((r == 1) && (reply_buffer[0] == 0x80)){
- printk("FDC %d is a pre-1991 82077\n", fdc);
- return FDC_82077_ORIG; /* Pre-1991 82077 doesn't know LOCK/UNLOCK */
- }
- if ((r != 1) || (reply_buffer[0] != 0x00)) {
- printk("FDC %d init: UNLOCK: unexpected return of %d bytes.\n",
- fdc, r);
- return FDC_UNKNOWN;
- }
- output_byte(FD_PARTID);
- r = result();
- if (r != 1) {
- printk("FDC %d init: PARTID: unexpected return of %d bytes.\n",
- fdc, r);
- return FDC_UNKNOWN;
- }
- if (reply_buffer[0] == 0x80) {
- printk("FDC %d is a post-1991 82077\n",fdc);
- return FDC_82077; /* Revised 82077AA passes all the tests */
- }
- switch (reply_buffer[0] >> 5) {
- case 0x0:
- output_byte(FD_SAVE);
- r = result();
- if (r != 16) {
- printk("FDC %d init: SAVE: unexpected return of %d bytes.\n", fdc, r);
- return FDC_UNKNOWN;
- }
- if (!(reply_buffer[0] & 0x40)) {
- printk("FDC %d is a 3Volt 82078SL.\n",fdc);
- return FDC_82078;
- }
- /* Either a 82078-1 or a 82078SL running at 5Volt */
- printk("FDC %d is a 82078-1.\n",fdc);
- return FDC_82078_1;
- case 0x1:
- printk("FDC %d is a 44pin 82078\n",fdc);
- return FDC_82078;
- case 0x2:
- printk("FDC %d is a S82078B\n", fdc);
- return FDC_S82078B;
- case 0x3:
- printk("FDC %d is a National Semiconductor PC87306\n", fdc);
- return FDC_87306;
- default:
- printk("FDC %d init: 82077 variant with PARTID=%d.\n",
- fdc, reply_buffer[0] >> 5);
- return FDC_82077_UNKN;
- }
-} /* get_fdc_version */
-
-/* lilo configuration */
-
-/* we make the invert_dcl function global. One day, somebody might
- * want to centralize all thinkpad related options into one lilo option,
- * there are just so many thinkpad related quirks! */
-void floppy_invert_dcl(int *ints,int param)
-{
- int i;
-
- for (i=0; i < ARRAY_SIZE(default_drive_params); i++){
- if (param)
- default_drive_params[i].params.flags |= 0x80;
- else
- default_drive_params[i].params.flags &= ~0x80;
- }
- DPRINT("Configuring drives for inverted dcl\n");
-}
-
-static void daring(int *ints,int param)
-{
- int i;
-
- for (i=0; i < ARRAY_SIZE(default_drive_params); i++){
- if (param){
- default_drive_params[i].params.select_delay = 0;
- default_drive_params[i].params.flags |= FD_SILENT_DCL_CLEAR;
- } else {
- default_drive_params[i].params.select_delay = 2*HZ/100;
- default_drive_params[i].params.flags &= ~FD_SILENT_DCL_CLEAR;
- }
- }
- DPRINT1("Assuming %s floppy hardware\n", param ? "standard" : "broken");
-}
-
-static void allow_drives(int *ints, int param)
-{
- allowed_drive_mask=param;
- DPRINT1("setting allowed_drive_mask to 0x%x\n", param);
-}
-
-static void fdc2_adr(int *ints, int param)
-{
- FDC2 = param;
- if (param)
- DPRINT1("enabling second fdc at address 0x%3x\n", FDC2);
- else
- DPRINT("disabling second fdc\n");
-}
-
-static void unex(int *ints,int param)
-{
- print_unex = param;
- DPRINT1("%sprinting messages for unexpected interrupts\n",
- param ? "" : "not ");
-}
-
-static void set_cmos(int *ints, int dummy)
-{
- int current_drive=0;
-
- if (ints[0] != 2){
- DPRINT("wrong number of parameter for cmos\n");
- return;
- }
- current_drive = ints[1];
- if (current_drive < 0 || current_drive >= 8){
- DPRINT("bad drive for set_cmos\n");
- return;
- }
- if (current_drive >= 4 && !FDC2)
- fdc2_adr(0, 0x370);
- if (ints[2] <= 0 || ints[2] >= NUMBER(default_drive_params)){
- DPRINT1("bad cmos code %d\n", ints[2]);
- return;
- }
- DP->cmos = ints[2];
- DPRINT1("setting cmos code to %d\n", ints[2]);
-}
-
-static struct param_table {
- const char *name;
- void (*fn)(int *ints, int param);
- int def_param;
-} config_params[]={
- { "allowed_drive_mask", allow_drives, 0xff },
- { "all_drives", allow_drives, 0xff },
- { "asus_pci", allow_drives, 0x33 },
-
- { "daring", daring, 1},
-
- { "two_fdc", fdc2_adr, 0x370 },
- { "one_fdc", fdc2_adr, 0 },
-
- { "thinkpad", floppy_invert_dcl, 1 },
-
- { "cmos", set_cmos, 0 },
-
- { "unexpected_interrupts", unex, 1 },
- { "no_unexpected_interrupts", unex, 0 },
- { "L40SX", unex, 0 } };
-
-#define FLOPPY_SETUP
-void floppy_setup(char *str, int *ints)
-{
- int i;
- int param;
- if (str)
- for (i=0; i< ARRAY_SIZE(config_params); i++){
- if (strcmp(str,config_params[i].name) == 0){
- if (ints[0])
- param = ints[1];
- else
- param = config_params[i].def_param;
- config_params[i].fn(ints,param);
- return;
- }
- }
- if (str) {
- DPRINT1("unknown floppy option [%s]\n", str);
-
- DPRINT("allowed options are:");
- for (i=0; i< ARRAY_SIZE(config_params); i++)
- printk(" %s",config_params[i].name);
- printk("\n");
- } else
- DPRINT("botched floppy option\n");
- DPRINT("Read linux/drivers/block/README.fd\n");
-}
-
-int floppy_init(void)
-{
- int i,unit,drive;
- int have_no_fdc= -EIO;
-
- raw_cmd = 0;
-
- sti();
-
- if (register_blkdev(MAJOR_NR,"fd",&floppy_fops)) {
- printk("Unable to get major %d for floppy\n",MAJOR_NR);
- return -EBUSY;
- }
-
- for (i=0; i<256; i++)
- if (ITYPE(i))
- floppy_sizes[i] = floppy_type[ITYPE(i)].size >> 1;
- else
- floppy_sizes[i] = MAX_DISK_SIZE;
-
- blk_size[MAJOR_NR] = floppy_sizes;
- blksize_size[MAJOR_NR] = floppy_blocksizes;
- blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
- reschedule_timeout(MAXTIMEOUT, "floppy init", MAXTIMEOUT);
- config_types();
-
- for (i = 0; i < N_FDC; i++) {
- fdc = i;
- CLEARSTRUCT(FDCS);
- FDCS->dtr = -1;
- FDCS->dor = 0x4;
- }
-
- fdc_state[0].address = FDC1;
-#if N_FDC > 1
- fdc_state[1].address = FDC2;
-#endif
-
- if (floppy_grab_irq_and_dma()){
- unregister_blkdev(MAJOR_NR,"fd");
- return -EBUSY;
- }
-
- /* initialise drive state */
- for (drive = 0; drive < N_DRIVE; drive++) {
- CLEARSTRUCT(UDRS);
- CLEARSTRUCT(UDRWE);
- UDRS->flags = FD_VERIFY | FD_DISK_NEWCHANGE | FD_DISK_CHANGED;
- UDRS->fd_device = -1;
- floppy_track_buffer = NULL;
- max_buffer_sectors = 0;
- }
-
- for (i = 0; i < N_FDC; i++) {
- fdc = i;
- FDCS->driver_version = FD_DRIVER_VERSION;
- for (unit=0; unit<4; unit++)
- FDCS->track[unit] = 0;
- if (FDCS->address == -1)
- continue;
- FDCS->rawcmd = 2;
- if (user_reset_fdc(-1,FD_RESET_ALWAYS,0)){
- FDCS->address = -1;
- continue;
- }
- /* Try to determine the floppy controller type */
- FDCS->version = get_fdc_version();
- if (FDCS->version == FDC_NONE){
- FDCS->address = -1;
- continue;
- }
-
- request_region(FDCS->address, 6, "floppy");
- request_region(FDCS->address+7, 1, "floppy DIR");
- /* address + 6 is reserved, and may be taken by IDE.
- * Unfortunately, Adaptec doesn't know this :-(, */
-
- have_no_fdc = 0;
- /* Not all FDCs seem to be able to handle the version command
- * properly, so force a reset for the standard FDC clones,
- * to avoid interrupt garbage.
- */
- FDCS->has_fifo = FDCS->version >= FDC_82077_ORIG;
- user_reset_fdc(-1,FD_RESET_ALWAYS,0);
- }
- fdc=0;
- del_timer(&fd_timeout);
- current_drive = 0;
- floppy_release_irq_and_dma();
- initialising=0;
- if (have_no_fdc) {
- DPRINT("no floppy controllers found\n");
- unregister_blkdev(MAJOR_NR,"fd");
- } else
- virtual_dma_init();
- return have_no_fdc;
-}
-
-static int floppy_grab_irq_and_dma(void)
-{
- int i;
- cli();
- if (usage_count++){
- sti();
- return 0;
- }
- sti();
- MOD_INC_USE_COUNT;
- for (i=0; i< N_FDC; i++){
- if (FDCS->address != -1){
- fdc = i;
- reset_fdc_info(1);
- fd_outb(FDCS->dor, FD_DOR);
- }
- }
- set_dor(0, ~0, 8); /* avoid immediate interrupt */
-
- if (fd_request_irq()) {
- DPRINT1("Unable to grab IRQ%d for the floppy driver\n",
- FLOPPY_IRQ);
- return -1;
- }
- if (fd_request_dma()) {
- DPRINT1("Unable to grab DMA%d for the floppy driver\n",
- FLOPPY_DMA);
- fd_free_irq();
- return -1;
- }
- for (fdc = 0; fdc < N_FDC; fdc++)
- if (FDCS->address != -1)
- fd_outb(FDCS->dor, FD_DOR);
- fdc = 0;
- fd_enable_irq();
- return 0;
-}
-
-static void floppy_release_irq_and_dma(void)
-{
-#ifdef FLOPPY_SANITY_CHECK
- int drive;
-#endif
- long tmpsize;
- void *tmpaddr;
-
- cli();
- if (--usage_count){
- sti();
- return;
- }
- sti();
- MOD_DEC_USE_COUNT;
- fd_disable_dma();
- fd_free_dma();
- fd_disable_irq();
- fd_free_irq();
-
- set_dor(0, ~0, 8);
-#if N_FDC > 1
- set_dor(1, ~8, 0);
-#endif
- floppy_enable_hlt();
-
- if (floppy_track_buffer && max_buffer_sectors) {
- tmpsize = max_buffer_sectors*1024;
- tmpaddr = (void *)floppy_track_buffer;
- floppy_track_buffer = 0;
- max_buffer_sectors = 0;
- buffer_min = buffer_max = -1;
- free_pages((unsigned long)tmpaddr, __get_order(tmpsize));
- }
-
-#ifdef FLOPPY_SANITY_CHECK
- for (drive=0; drive < N_FDC * 4; drive++)
- if (motor_off_timer[drive].next)
- printk("motor off timer %d still active\n", drive);
-
- if (fd_timeout.next)
- printk("floppy timer still active:%s\n", timeout_message);
- if (fd_timer.next)
- printk("auxiliary floppy timer still active\n");
- if (floppy_tq.sync)
- printk("task queue still active\n");
-#endif
-}
-
-
-#ifdef MODULE
-
-extern char *get_options(char *str, int *ints);
-
-static void mod_setup(char *pattern, void (*setup)(char *, int *))
-{
- int i;
- char c;
- int j;
- int match;
- char buffer[100];
- int ints[11];
- int length = strlen(pattern)+1;
-
- match=0;
- j=1;
-
- for (i=current->mm->env_start; i< current->mm->env_end; i ++){
- c= get_fs_byte(i);
- if (match){
- if (j==99)
- c='\0';
- buffer[j] = c;
- if (!c || c == ' ' || c == '\t'){
- if (j){
- buffer[j] = '\0';
- setup(get_options(buffer,ints),ints);
- }
- j=0;
- } else
- j++;
- if (!c)
- break;
- continue;
- }
- if ((!j && !c) || (j && c == pattern[j-1]))
- j++;
- else
- j=0;
- if (j==length){
- match=1;
- j=0;
- }
- }
-}
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-int init_module(void)
-{
- printk("inserting floppy driver for %s\n", kernel_version);
-
- mod_setup("floppy=", floppy_setup);
-
- return floppy_init();
-}
-
-void cleanup_module(void)
-{
- int fdc;
-
- for (fdc=0; fdc<2; fdc++)
- if (FDCS->address != -1){
- release_region(FDCS->address, 6);
- release_region(FDCS->address+7, 1);
- }
-
- unregister_blkdev(MAJOR_NR, "fd");
-
- blk_dev[MAJOR_NR].request_fn = 0;
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/i386/i386at/gpl/linux/block/genhd.c b/i386/i386at/gpl/linux/block/genhd.c
deleted file mode 100644
index cebc7eaa..00000000
--- a/i386/i386at/gpl/linux/block/genhd.c
+++ /dev/null
@@ -1,610 +0,0 @@
-/*
- * Code extracted from
- * linux/kernel/hd.c
- *
- * Copyright (C) 1991, 1992 Linus Torvalds
- *
- *
- * Thanks to Branko Lankester, lankeste@fwi.uva.nl, who found a bug
- * in the early extended-partition checks and added DM partitions
- *
- * Support for DiskManager v6.0x added by Mark Lord (mlord@bnr.ca)
- * with information provided by OnTrack. This now works for linux fdisk
- * and LILO, as well as loadlin and bootln. Note that disks other than
- * /dev/hda *must* have a "DOS" type 0x51 partition in the first slot (hda1).
- *
- * More flexible handling of extended partitions - aeb, 950831
- *
- * Check partition table on IDE disks for common CHS translations
- */
-
-#include <linux/config.h>
-#include <linux/fs.h>
-#include <linux/genhd.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/string.h>
-
-#include <asm/system.h>
-
-#ifdef __alpha__
-/*
- * On the Alpha, we get unaligned access exceptions on
- * p->nr_sects and p->start_sect, when the partition table
- * is not on a 4-byte boundary, which is frequently the case.
- * This code uses unaligned load instructions to prevent
- * such exceptions.
- */
-#include <asm/unaligned.h>
-#define NR_SECTS(p) ldl_u(&p->nr_sects)
-#define START_SECT(p) ldl_u(&p->start_sect)
-#else /* __alpha__ */
-#define NR_SECTS(p) p->nr_sects
-#define START_SECT(p) p->start_sect
-#endif /* __alpha__ */
-
-#ifdef MACH
-#include <i386/ipl.h>
-#endif
-
-struct gendisk *gendisk_head = NULL;
-
-static int current_minor = 0;
-extern int *blk_size[];
-extern void rd_load(void);
-
-extern int chr_dev_init(void);
-extern int blk_dev_init(void);
-extern int scsi_dev_init(void);
-extern int net_dev_init(void);
-
-static void print_minor_name (struct gendisk *hd, int minor)
-{
- unsigned int unit = minor >> hd->minor_shift;
- unsigned int part = minor & ((1 << hd->minor_shift) - 1);
-
-#ifdef CONFIG_BLK_DEV_IDE
- /*
- * IDE devices use multiple major numbers, but the drives
- * are named as: {hda,hdb}, {hdc,hdd}, {hde,hdf}, {hdg,hdh}..
- * This requires some creative handling here to find the
- * correct name to use, with some help from ide.c
- */
- if (!strcmp(hd->major_name,"ide")) {
- char name[16]; /* more than large enough */
- strcpy(name, hd->real_devices); /* courtesy ide.c */
- name[strlen(name)-1] += unit;
- printk(" %s", name);
- } else
-#endif
- printk(" %s%c", hd->major_name, 'a' + unit);
- if (part)
- printk("%d", part);
- else
- printk(":");
-}
-
-static void add_partition (struct gendisk *hd, int minor, int start, int size)
-{
- hd->part[minor].start_sect = start;
- hd->part[minor].nr_sects = size;
- /* print_minor_name(hd, minor);*/
-}
-
-static inline int is_extended_partition(struct partition *p)
-{
- return (p->sys_ind == DOS_EXTENDED_PARTITION ||
- p->sys_ind == LINUX_EXTENDED_PARTITION);
-}
-
-#ifdef CONFIG_MSDOS_PARTITION
-/*
- * Create devices for each logical partition in an extended partition.
- * The logical partitions form a linked list, with each entry being
- * a partition table with two entries. The first entry
- * is the real data partition (with a start relative to the partition
- * table start). The second is a pointer to the next logical partition
- * (with a start relative to the entire extended partition).
- * We do not create a Linux partition for the partition tables, but
- * only for the actual data partitions.
- */
-
-static void extended_partition(struct gendisk *hd, kdev_t dev)
-{
- struct buffer_head *bh;
- struct partition *p;
- unsigned long first_sector, first_size, this_sector, this_size;
- int mask = (1 << hd->minor_shift) - 1;
- int i;
-
- first_sector = hd->part[MINOR(dev)].start_sect;
- first_size = hd->part[MINOR(dev)].nr_sects;
- this_sector = first_sector;
-
- while (1) {
- if ((current_minor & mask) == 0)
- return;
- if (!(bh = bread(dev,0,1024)))
- return;
- /*
- * This block is from a device that we're about to stomp on.
- * So make sure nobody thinks this block is usable.
- */
- bh->b_state = 0;
-
- if (*(unsigned short *) (bh->b_data+510) != 0xAA55)
- goto done;
-
- p = (struct partition *) (0x1BE + bh->b_data);
-
- this_size = hd->part[MINOR(dev)].nr_sects;
-
- /*
- * Usually, the first entry is the real data partition,
- * the 2nd entry is the next extended partition, or empty,
- * and the 3rd and 4th entries are unused.
- * However, DRDOS sometimes has the extended partition as
- * the first entry (when the data partition is empty),
- * and OS/2 seems to use all four entries.
- */
-
- /*
- * First process the data partition(s)
- */
- for (i=0; i<4; i++, p++) {
- if (!NR_SECTS(p) || is_extended_partition(p))
- continue;
-
- /* Check the 3rd and 4th entries -
- these sometimes contain random garbage */
- if (i >= 2
- && START_SECT(p) + NR_SECTS(p) > this_size
- && (this_sector + START_SECT(p) < first_sector ||
- this_sector + START_SECT(p) + NR_SECTS(p) >
- first_sector + first_size))
- continue;
-
- add_partition(hd, current_minor, this_sector+START_SECT(p), NR_SECTS(p));
- current_minor++;
- if ((current_minor & mask) == 0)
- goto done;
- }
- /*
- * Next, process the (first) extended partition, if present.
- * (So far, there seems to be no reason to make
- * extended_partition() recursive and allow a tree
- * of extended partitions.)
- * It should be a link to the next logical partition.
- * Create a minor for this just long enough to get the next
- * partition table. The minor will be reused for the next
- * data partition.
- */
- p -= 4;
- for (i=0; i<4; i++, p++)
- if(NR_SECTS(p) && is_extended_partition(p))
- break;
- if (i == 4)
- goto done; /* nothing left to do */
-
- hd->part[current_minor].nr_sects = NR_SECTS(p);
- hd->part[current_minor].start_sect = first_sector + START_SECT(p);
- this_sector = first_sector + START_SECT(p);
- dev = MKDEV(hd->major, current_minor);
- brelse(bh);
- }
-done:
- brelse(bh);
-}
-
-static int msdos_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector)
-{
- int i, minor = current_minor;
- struct buffer_head *bh;
- struct partition *p;
- unsigned char *data;
- int mask = (1 << hd->minor_shift) - 1;
-#ifdef CONFIG_BLK_DEV_IDE
- int tested_for_xlate = 0;
-
-read_mbr:
-#endif
- if (!(bh = bread(dev,0,1024))) {
- printk(" unable to read partition table\n");
- return -1;
- }
- data = bh->b_data;
- /* In some cases we modify the geometry */
- /* of the drive (below), so ensure that */
- /* nobody else tries to re-use this data. */
- bh->b_state = 0;
-#ifdef CONFIG_BLK_DEV_IDE
-check_table:
-#endif
- if (*(unsigned short *) (0x1fe + data) != 0xAA55) {
- brelse(bh);
- return 0;
- }
- p = (struct partition *) (0x1be + data);
-
-#ifdef CONFIG_BLK_DEV_IDE
- if (!tested_for_xlate++) { /* Do this only once per disk */
- /*
- * Look for various forms of IDE disk geometry translation
- */
- extern int ide_xlate_1024(kdev_t, int, const char *);
- unsigned int sig = *(unsigned short *)(data + 2);
- if (p->sys_ind == EZD_PARTITION) {
- /*
- * The remainder of the disk must be accessed using
- * a translated geometry that reduces the number of
- * apparent cylinders to less than 1024 if possible.
- *
- * ide_xlate_1024() will take care of the necessary
- * adjustments to fool fdisk/LILO and partition check.
- */
- if (ide_xlate_1024(dev, -1, " [EZD]")) {
- data += 512;
- goto check_table;
- }
- } else if (p->sys_ind == DM6_PARTITION) {
-
- /*
- * Everything on the disk is offset by 63 sectors,
- * including a "new" MBR with its own partition table,
- * and the remainder of the disk must be accessed using
- * a translated geometry that reduces the number of
- * apparent cylinders to less than 1024 if possible.
- *
- * ide_xlate_1024() will take care of the necessary
- * adjustments to fool fdisk/LILO and partition check.
- */
- if (ide_xlate_1024(dev, 1, " [DM6:DDO]")) {
- brelse(bh);
- goto read_mbr; /* start over with new MBR */
- }
- } else if (sig <= 0x1ae && *(unsigned short *)(data + sig) == 0x55AA
- && (1 & *(unsigned char *)(data + sig + 2)) )
- {
- /*
- * DM6 signature in MBR, courtesy of OnTrack
- */
- (void) ide_xlate_1024 (dev, 0, " [DM6:MBR]");
- } else if (p->sys_ind == DM6_AUX1PARTITION || p->sys_ind == DM6_AUX3PARTITION) {
- /*
- * DM6 on other than the first (boot) drive
- */
- (void) ide_xlate_1024(dev, 0, " [DM6:AUX]");
- } else {
- /*
- * Examine the partition table for common translations.
- * This is necessary for drives for situations where
- * the translated geometry is unavailable from the BIOS.
- */
- for (i = 0; i < 4 ; i++) {
- struct partition *q = &p[i];
- if (NR_SECTS(q) && q->sector == 1 && q->end_sector == 63) {
- unsigned int heads = q->end_head + 1;
- if (heads == 32 || heads == 64 || heads == 128) {
-
- (void) ide_xlate_1024(dev, heads, " [PTBL]");
- break;
- }
- }
- }
- }
- }
-#endif /* CONFIG_BLK_DEV_IDE */
-
- current_minor += 4; /* first "extra" minor (for extended partitions) */
- for (i=1 ; i<=4 ; minor++,i++,p++) {
- if (!NR_SECTS(p))
- continue;
- add_partition(hd, minor, first_sector+START_SECT(p), NR_SECTS(p));
- if (is_extended_partition(p)) {
- /* printk(" <");*/
- /*
- * If we are rereading the partition table, we need
- * to set the size of the partition so that we will
- * be able to bread the block containing the extended
- * partition info.
- */
- hd->sizes[minor] = hd->part[minor].nr_sects
- >> (BLOCK_SIZE_BITS - 9);
- extended_partition(hd, MKDEV(hd->major, minor));
- /* printk(" >");*/
- /* prevent someone doing mkfs or mkswap on an
- extended partition, but leave room for LILO */
- if (hd->part[minor].nr_sects > 2)
- hd->part[minor].nr_sects = 2;
- }
- }
- /*
- * Check for old-style Disk Manager partition table
- */
- if (*(unsigned short *) (data+0xfc) == 0x55AA) {
- p = (struct partition *) (0x1be + data);
- for (i = 4 ; i < 16 ; i++, current_minor++) {
- p--;
- if ((current_minor & mask) == 0)
- break;
- if (!(START_SECT(p) && NR_SECTS(p)))
- continue;
- add_partition(hd, current_minor, START_SECT(p), NR_SECTS(p));
- }
- }
- /* printk("\n");*/
- brelse(bh);
- return 1;
-}
-
-#endif /* CONFIG_MSDOS_PARTITION */
-
-#ifdef CONFIG_OSF_PARTITION
-
-static int osf_partition(struct gendisk *hd, unsigned int dev, unsigned long first_sector)
-{
- int i;
- int mask = (1 << hd->minor_shift) - 1;
- struct buffer_head *bh;
- struct disklabel {
- u32 d_magic;
- u16 d_type,d_subtype;
- u8 d_typename[16];
- u8 d_packname[16];
- u32 d_secsize;
- u32 d_nsectors;
- u32 d_ntracks;
- u32 d_ncylinders;
- u32 d_secpercyl;
- u32 d_secprtunit;
- u16 d_sparespertrack;
- u16 d_sparespercyl;
- u32 d_acylinders;
- u16 d_rpm, d_interleave, d_trackskew, d_cylskew;
- u32 d_headswitch, d_trkseek, d_flags;
- u32 d_drivedata[5];
- u32 d_spare[5];
- u32 d_magic2;
- u16 d_checksum;
- u16 d_npartitions;
- u32 d_bbsize, d_sbsize;
- struct d_partition {
- u32 p_size;
- u32 p_offset;
- u32 p_fsize;
- u8 p_fstype;
- u8 p_frag;
- u16 p_cpg;
- } d_partitions[8];
- } * label;
- struct d_partition * partition;
-#define DISKLABELMAGIC (0x82564557UL)
-
- if (!(bh = bread(dev,0,1024))) {
- printk("unable to read partition table\n");
- return -1;
- }
- label = (struct disklabel *) (bh->b_data+64);
- partition = label->d_partitions;
- if (label->d_magic != DISKLABELMAGIC) {
- printk("magic: %08x\n", label->d_magic);
- brelse(bh);
- return 0;
- }
- if (label->d_magic2 != DISKLABELMAGIC) {
- printk("magic2: %08x\n", label->d_magic2);
- brelse(bh);
- return 0;
- }
- for (i = 0 ; i < label->d_npartitions; i++, partition++) {
- if ((current_minor & mask) == 0)
- break;
- if (partition->p_size)
- add_partition(hd, current_minor,
- first_sector+partition->p_offset,
- partition->p_size);
- current_minor++;
- }
- /* printk("\n");*/
- brelse(bh);
- return 1;
-}
-
-#endif /* CONFIG_OSF_PARTITION */
-
-#ifdef CONFIG_SUN_PARTITION
-
-static int sun_partition(struct gendisk *hd, unsigned int dev, unsigned long first_sector)
-{
- int i, csum;
- unsigned short *ush;
- struct buffer_head *bh;
- struct sun_disklabel {
- unsigned char info[128]; /* Informative text string */
- unsigned char spare[292]; /* Boot information etc. */
- unsigned short rspeed; /* Disk rotational speed */
- unsigned short pcylcount; /* Physical cylinder count */
- unsigned short sparecyl; /* extra sects per cylinder */
- unsigned char spare2[4]; /* More magic... */
- unsigned short ilfact; /* Interleave factor */
- unsigned short ncyl; /* Data cylinder count */
- unsigned short nacyl; /* Alt. cylinder count */
- unsigned short ntrks; /* Tracks per cylinder */
- unsigned short nsect; /* Sectors per track */
- unsigned char spare3[4]; /* Even more magic... */
- struct sun_partition {
- unsigned long start_cylinder;
- unsigned long num_sectors;
- } partitions[8];
- unsigned short magic; /* Magic number */
- unsigned short csum; /* Label xor'd checksum */
- } * label;
- struct sun_partition *p;
- unsigned long spc;
-#define SUN_LABEL_MAGIC 0xDABE
-
- if(!(bh = bread(dev, 0, 1024))) {
- printk("Dev %d: unable to read partition table\n", dev);
- return -1;
- }
- label = (struct sun_disklabel *) bh->b_data;
- p = label->partitions;
- if(label->magic != SUN_LABEL_MAGIC) {
- printk("Dev %d Sun disklabel: bad magic %08x\n", dev, label->magic);
- brelse(bh);
- return 0;
- }
- /* Look at the checksum */
- ush = ((unsigned short *) (label+1)) - 1;
- for(csum = 0; ush >= ((unsigned short *) label);)
- csum ^= *ush--;
- if(csum) {
- printk("Dev %d Sun disklabel: Csum bad, label corrupted\n", dev);
- brelse(bh);
- return 0;
- }
- /* All Sun disks have 8 partition entries */
- spc = (label->ntrks * label->nsect);
- for(i=0; i < 8; i++, p++) {
- unsigned long st_sector;
-
- /* We register all partitions, even if zero size, so that
- * the minor numbers end up ok as per SunOS interpretation.
- */
- st_sector = first_sector + (p->start_cylinder * spc);
- add_partition(hd, current_minor, st_sector, p->num_sectors);
- current_minor++;
- }
- /* printk("\n");*/
- brelse(bh);
- return 1;
-}
-
-#endif /* CONFIG_SUN_PARTITION */
-
-static void check_partition(struct gendisk *hd, kdev_t dev)
-{
- static int first_time = 1;
- unsigned long first_sector;
-
- /* if (first_time)
- printk("Partition check:\n");*/
- first_time = 0;
- first_sector = hd->part[MINOR(dev)].start_sect;
-
- /*
- * This is a kludge to allow the partition check to be
- * skipped for specific drives (e.g. IDE cd-rom drives)
- */
- if ((int)first_sector == -1) {
- hd->part[MINOR(dev)].start_sect = 0;
- return;
- }
-
- /* printk(" ");
- print_minor_name(hd, MINOR(dev));*/
-#ifdef CONFIG_MSDOS_PARTITION
- if (msdos_partition(hd, dev, first_sector))
- return;
-#endif
-#ifdef CONFIG_OSF_PARTITION
- if (osf_partition(hd, dev, first_sector))
- return;
-#endif
-#ifdef CONFIG_SUN_PARTITION
- if(sun_partition(hd, dev, first_sector))
- return;
-#endif
- printk(" unknown partition table\n");
-}
-
-/* This function is used to re-read partition tables for removable disks.
- Much of the cleanup from the old partition tables should have already been
- done */
-
-/* This function will re-read the partition tables for a given device,
-and set things back up again. There are some important caveats,
-however. You must ensure that no one is using the device, and no one
-can start using the device while this function is being executed. */
-
-void resetup_one_dev(struct gendisk *dev, int drive)
-{
- int i;
- int first_minor = drive << dev->minor_shift;
- int end_minor = first_minor + dev->max_p;
-
- blk_size[dev->major] = NULL;
- current_minor = 1 + first_minor;
- check_partition(dev, MKDEV(dev->major, first_minor));
-
- /*
- * We need to set the sizes array before we will be able to access
- * any of the partitions on this device.
- */
- if (dev->sizes != NULL) { /* optional safeguard in ll_rw_blk.c */
- for (i = first_minor; i < end_minor; i++)
- dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9);
- blk_size[dev->major] = dev->sizes;
- }
-}
-
-static void setup_dev(struct gendisk *dev)
-{
- int i, drive;
- int end_minor = dev->max_nr * dev->max_p;
-
- blk_size[dev->major] = NULL;
- for (i = 0 ; i < end_minor; i++) {
- dev->part[i].start_sect = 0;
- dev->part[i].nr_sects = 0;
- }
- dev->init(dev);
- for (drive = 0 ; drive < dev->nr_real ; drive++) {
- int first_minor = drive << dev->minor_shift;
- current_minor = 1 + first_minor;
- check_partition(dev, MKDEV(dev->major, first_minor));
- }
- if (dev->sizes != NULL) { /* optional safeguard in ll_rw_blk.c */
- for (i = 0; i < end_minor; i++)
- dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9);
- blk_size[dev->major] = dev->sizes;
- }
-}
-
-void device_setup(void)
-{
- extern void console_map_init(void);
- struct gendisk *p;
- int nr=0;
-#ifdef MACH
- extern int linux_intr_pri;
-
- linux_intr_pri = SPL5;
-#endif
-
-#ifndef MACH
- chr_dev_init();
-#endif
- blk_dev_init();
- sti();
-#ifdef CONFIG_SCSI
- scsi_dev_init();
-#endif
-#ifdef CONFIG_INET
-#ifdef MACH
- linux_intr_pri = SPL6;
-#endif
- net_dev_init();
-#endif
-#ifndef MACH
- console_map_init();
-#endif
-
- for (p = gendisk_head ; p ; p=p->next) {
- setup_dev(p);
- nr += p->nr_real;
- }
-#ifdef CONFIG_BLK_DEV_RAM
- rd_load();
-#endif
-}
diff --git a/i386/i386at/gpl/linux/block/ide-cd.c b/i386/i386at/gpl/linux/block/ide-cd.c
deleted file mode 100644
index 6dc93806..00000000
--- a/i386/i386at/gpl/linux/block/ide-cd.c
+++ /dev/null
@@ -1,2770 +0,0 @@
-/*
- * linux/drivers/block/ide-cd.c
- *
- * 1.00 Oct 31, 1994 -- Initial version.
- * 1.01 Nov 2, 1994 -- Fixed problem with starting request in
- * cdrom_check_status.
- * 1.03 Nov 25, 1994 -- leaving unmask_intr[] as a user-setting (as for disks)
- * (from mlord) -- minor changes to cdrom_setup()
- * -- renamed ide_dev_s to ide_drive_t, enable irq on command
- * 2.00 Nov 27, 1994 -- Generalize packet command interface;
- * add audio ioctls.
- * 2.01 Dec 3, 1994 -- Rework packet command interface to handle devices
- * which send an interrupt when ready for a command.
- * 2.02 Dec 11, 1994 -- Cache the TOC in the driver.
- * Don't use SCMD_PLAYAUDIO_TI; it's not included
- * in the current version of ATAPI.
- * Try to use LBA instead of track or MSF addressing
- * when possible.
- * Don't wait for READY_STAT.
- * 2.03 Jan 10, 1995 -- Rewrite block read routines to handle block sizes
- * other than 2k and to move multiple sectors in a
- * single transaction.
- * 2.04 Apr 21, 1995 -- Add work-around for Creative Labs CD220E drives.
- * Thanks to Nick Saw <cwsaw@pts7.pts.mot.com> for
- * help in figuring this out. Ditto for Acer and
- * Aztech drives, which seem to have the same problem.
- * 2.04b May 30, 1995 -- Fix to match changes in ide.c version 3.16 -ml
- * 2.05 Jun 8, 1995 -- Don't attempt to retry after an illegal request
- * or data protect error.
- * Use HWIF and DEV_HWIF macros as in ide.c.
- * Always try to do a request_sense after
- * a failed command.
- * Include an option to give textual descriptions
- * of ATAPI errors.
- * Fix a bug in handling the sector cache which
- * showed up if the drive returned data in 512 byte
- * blocks (like Pioneer drives). Thanks to
- * Richard Hirst <srh@gpt.co.uk> for diagnosing this.
- * Properly supply the page number field in the
- * MODE_SELECT command.
- * PLAYAUDIO12 is broken on the Aztech; work around it.
- * 2.05x Aug 11, 1995 -- lots of data structure renaming/restructuring in ide.c
- * (my apologies to Scott, but now ide-cd.c is independent)
- * 3.00 Aug 22, 1995 -- Implement CDROMMULTISESSION ioctl.
- * Implement CDROMREADAUDIO ioctl (UNTESTED).
- * Use input_ide_data() and output_ide_data().
- * Add door locking.
- * Fix usage count leak in cdrom_open, which happened
- * when a read-write mount was attempted.
- * Try to load the disk on open.
- * Implement CDROMEJECT_SW ioctl (off by default).
- * Read total cdrom capacity during open.
- * Rearrange logic in cdrom_decode_status. Issue
- * request sense commands for failed packet commands
- * from here instead of from cdrom_queue_packet_command.
- * Fix a race condition in retrieving error information.
- * Suppress printing normal unit attention errors and
- * some drive not ready errors.
- * Implement CDROMVOLREAD ioctl.
- * Implement CDROMREADMODE1/2 ioctls.
- * Fix race condition in setting up interrupt handlers
- * when the `serialize' option is used.
- * 3.01 Sep 2, 1995 -- Fix ordering of reenabling interrupts in
- * cdrom_queue_request.
- * Another try at using ide_[input,output]_data.
- * 3.02 Sep 16, 1995 -- Stick total disk capacity in partition table as well.
- * Make VERBOSE_IDE_CD_ERRORS dump failed command again.
- * Dump out more information for ILLEGAL REQUEST errs.
- * Fix handling of errors occuring before the
- * packet command is transferred.
- * Fix transfers with odd bytelengths.
- * 3.03 Oct 27, 1995 -- Some Creative drives have an id of just `CD'.
- * `DCI-2S10' drives are broken too.
- * 3.04 Nov 20, 1995 -- So are Vertos drives.
- * 3.05 Dec 1, 1995 -- Changes to go with overhaul of ide.c and ide-tape.c
- * 3.06 Dec 16, 1995 -- Add support needed for partitions.
- * More workarounds for Vertos bugs (based on patches
- * from Holger Dietze <dietze@aix520.informatik.uni-leipzig.de>).
- * Try to eliminate byteorder assumptions.
- * Use atapi_cdrom_subchnl struct definition.
- * Add STANDARD_ATAPI compilation option.
- * 3.07 Jan 29, 1996 -- More twiddling for broken drives: Sony 55D,
- * Vertos 300.
- * Add NO_DOOR_LOCKING configuration option.
- * Handle drive_cmd requests w/NULL args (for hdparm -t).
- * Work around sporadic Sony55e audio play problem.
- * 3.07a Feb 11, 1996 -- check drive->id for NULL before dereferencing, to fix
- * problem with "hde=cdrom" with no drive present. -ml
- *
- * NOTE: Direct audio reads will only work on some types of drive.
- * So far, i've received reports of success for Sony and Toshiba drives.
- *
- * ATAPI cd-rom driver. To be used with ide.c.
- *
- * Copyright (C) 1994, 1995, 1996 scott snyder <snyder@fnald0.fnal.gov>
- * May be copied or modified under the terms of the GNU General Public License
- * (../../COPYING).
- */
-
-
-/***************************************************************************/
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/timer.h>
-#include <linux/malloc.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/blkdev.h>
-#include <linux/errno.h>
-#include <linux/hdreg.h>
-#include <linux/cdrom.h>
-#include <asm/irq.h>
-#include <asm/io.h>
-#include <asm/byteorder.h>
-#include <asm/segment.h>
-#ifdef __alpha__
-# include <asm/unaligned.h>
-#endif
-
-#include "ide.h"
-
-
-
-/* Turn this on to have the driver print out the meanings of the
- ATAPI error codes. This will use up additional kernel-space
- memory, though. */
-
-#ifndef VERBOSE_IDE_CD_ERRORS
-#define VERBOSE_IDE_CD_ERRORS 0
-#endif
-
-
-/* Turning this on will remove code to work around various nonstandard
- ATAPI implementations. If you know your drive follows the standard,
- this will give you a slightly smaller kernel. */
-
-#ifndef STANDARD_ATAPI
-#define STANDARD_ATAPI 0
-#endif
-
-
-/* Turning this on will disable the door-locking functionality.
- This is apparently needed for supermount. */
-
-#ifndef NO_DOOR_LOCKING
-#define NO_DOOR_LOCKING 0
-#endif
-
-
-/************************************************************************/
-
-#define SECTOR_SIZE 512
-#define SECTOR_BITS 9
-#define SECTORS_PER_FRAME (CD_FRAMESIZE / SECTOR_SIZE)
-
-#define MIN(a,b) ((a) < (b) ? (a) : (b))
-
-/* special command codes for strategy routine. */
-#define PACKET_COMMAND 4315
-#define REQUEST_SENSE_COMMAND 4316
-#define RESET_DRIVE_COMMAND 4317
-
-/* Some ATAPI command opcodes (just like SCSI).
- (Some other cdrom-specific codes are in cdrom.h.) */
-#define TEST_UNIT_READY 0x00
-#define REQUEST_SENSE 0x03
-#define START_STOP 0x1b
-#define ALLOW_MEDIUM_REMOVAL 0x1e
-#define READ_CAPACITY 0x25
-#define READ_10 0x28
-#define MODE_SENSE_10 0x5a
-#define MODE_SELECT_10 0x55
-#define READ_CD 0xbe
-
-
-/* ATAPI sense keys (mostly copied from scsi.h). */
-
-#define NO_SENSE 0x00
-#define RECOVERED_ERROR 0x01
-#define NOT_READY 0x02
-#define MEDIUM_ERROR 0x03
-#define HARDWARE_ERROR 0x04
-#define ILLEGAL_REQUEST 0x05
-#define UNIT_ATTENTION 0x06
-#define DATA_PROTECT 0x07
-#define ABORTED_COMMAND 0x0b
-#define MISCOMPARE 0x0e
-
-/* We want some additional flags for cd-rom drives.
- To save space in the ide_drive_t struct, use some fields which
- doesn't make sense for cd-roms -- `bios_sect' and `bios_head'. */
-
-/* Configuration flags. These describe the capabilities of the drive.
- They generally do not change after initialization, unless we learn
- more about the drive from stuff failing. */
-struct ide_cd_config_flags {
- __u8 drq_interrupt : 1; /* Device sends an interrupt when ready
- for a packet command. */
- __u8 no_doorlock : 1; /* Drive cannot lock the door. */
-#if ! STANDARD_ATAPI
- __u8 no_playaudio12: 1; /* The PLAYAUDIO12 command is not supported. */
-
- __u8 no_lba_toc : 1; /* Drive cannot return TOC info in LBA format. */
- __u8 playmsf_uses_bcd : 1; /* Drive uses BCD in PLAYAUDIO_MSF. */
- __u8 old_readcd : 1; /* Drive uses old READ CD opcode. */
- __u8 vertos_lossage: 1; /* Drive is a Vertos 300,
- and likes to speak BCD. */
-#endif /* not STANDARD_ATAPI */
- __u8 reserved : 1;
-};
-#define CDROM_CONFIG_FLAGS(drive) ((struct ide_cd_config_flags *)&((drive)->bios_sect))
-
-
-/* State flags. These give information about the current state of the
- drive, and will change during normal operation. */
-struct ide_cd_state_flags {
- __u8 media_changed : 1; /* Driver has noticed a media change. */
- __u8 toc_valid : 1; /* Saved TOC information is current. */
- __u8 door_locked : 1; /* We think that the drive door is locked. */
- __u8 eject_on_close: 1; /* Drive should eject when device is closed. */
- __u8 reserved : 4;
-};
-#define CDROM_STATE_FLAGS(drive) ((struct ide_cd_state_flags *)&((drive)->bios_head))
-
-
-#define SECTOR_BUFFER_SIZE CD_FRAMESIZE
-
-
-
-/****************************************************************************
- * Routines to read and write data from/to the drive, using
- * the routines input_ide_data() and output_ide_data() from ide.c.
- *
- * These routines will round up any request for an odd number of bytes,
- * so if an odd bytecount is specified, be sure that there's at least one
- * extra byte allocated for the buffer.
- */
-
-
-static inline
-void cdrom_in_bytes (ide_drive_t *drive, void *buffer, uint bytecount)
-{
- ++bytecount;
- ide_input_data (drive, buffer, bytecount / 4);
- if ((bytecount & 0x03) >= 2)
- {
- insw (IDE_DATA_REG, ((byte *)buffer) + (bytecount & ~0x03), 1);
- }
-}
-
-
-static inline
-void cdrom_out_bytes (ide_drive_t *drive, void *buffer, uint bytecount)
-{
- ++bytecount;
- ide_output_data (drive, buffer, bytecount / 4);
- if ((bytecount & 0x03) >= 2)
- {
- outsw (IDE_DATA_REG, ((byte *)buffer) + (bytecount & ~0x03), 1);
- }
-}
-
-
-
-/****************************************************************************
- * Descriptions of ATAPI error codes.
- */
-
-#define ARY_LEN(a) ((sizeof(a) / sizeof(a[0])))
-
-#if VERBOSE_IDE_CD_ERRORS
-
-/* From Table 124 of the ATAPI 1.2 spec. */
-
-char *sense_key_texts[16] = {
- "No sense data",
- "Recovered error",
- "Not ready",
- "Medium error",
- "Hardware error",
- "Illegal request",
- "Unit attention",
- "Data protect",
- "(reserved)",
- "(reserved)",
- "(reserved)",
- "Aborted command",
- "(reserved)",
- "(reserved)",
- "Miscompare",
- "(reserved)",
-};
-
-
-/* From Table 125 of the ATAPI 1.2 spec. */
-
-struct {
- short asc_ascq;
- char *text;
-} sense_data_texts[] = {
- { 0x0000, "No additional sense information" },
- { 0x0011, "Audio play operation in progress" },
- { 0x0012, "Audio play operation paused" },
- { 0x0013, "Audio play operation successfully completed" },
- { 0x0014, "Audio play operation stopped due to error" },
- { 0x0015, "No current audio status to return" },
-
- { 0x0200, "No seek complete" },
-
- { 0x0400, "Logical unit not ready - cause not reportable" },
- { 0x0401, "Logical unit not ready - in progress (sic) of becoming ready" },
- { 0x0402, "Logical unit not ready - initializing command required" },
- { 0x0403, "Logical unit not ready - manual intervention required" },
-
- { 0x0600, "No reference position found" },
-
- { 0x0900, "Track following error" },
- { 0x0901, "Tracking servo failure" },
- { 0x0902, "Focus servo failure" },
- { 0x0903, "Spindle servo failure" },
-
- { 0x1100, "Unrecovered read error" },
- { 0x1106, "CIRC unrecovered error" },
-
- { 0x1500, "Random positioning error" },
- { 0x1501, "Mechanical positioning error" },
- { 0x1502, "Positioning error detected by read of medium" },
-
- { 0x1700, "Recovered data with no error correction applied" },
- { 0x1701, "Recovered data with retries" },
- { 0x1702, "Recovered data with positive head offset" },
- { 0x1703, "Recovered data with negative head offset" },
- { 0x1704, "Recovered data with retries and/or CIRC applied" },
- { 0x1705, "Recovered data using previous sector ID" },
-
- { 0x1800, "Recovered data with error correction applied" },
- { 0x1801, "Recovered data with error correction and retries applied" },
- { 0x1802, "Recovered data - the data was auto-reallocated" },
- { 0x1803, "Recovered data with CIRC" },
- { 0x1804, "Recovered data with L-EC" },
- { 0x1805, "Recovered data - recommend reassignment" },
- { 0x1806, "Recovered data - recommend rewrite" },
-
- { 0x1a00, "Parameter list length error" },
-
- { 0x2000, "Invalid command operation code" },
-
- { 0x2100, "Logical block address out of range" },
-
- { 0x2400, "Invalid field in command packet" },
-
- { 0x2600, "Invalid field in parameter list" },
- { 0x2601, "Parameter not supported" },
- { 0x2602, "Parameter value invalid" },
- { 0x2603, "Threshold parameters not supported" },
-
- { 0x2800, "Not ready to ready transition, medium may have changed" },
-
- { 0x2900, "Power on, reset or bus device reset occurred" },
-
- { 0x2a00, "Parameters changed" },
- { 0x2a01, "Mode parameters changed" },
-
- { 0x3000, "Incompatible medium installed" },
- { 0x3001, "Cannot read medium - unknown format" },
- { 0x3002, "Cannot read medium - incompatible format" },
-
- { 0x3700, "Rounded parameter" },
-
- { 0x3900, "Saving parameters not supported" },
-
- { 0x3a00, "Medium not present" },
-
- { 0x3f00, "ATAPI CD-ROM drive operating conditions have changed" },
- { 0x3f01, "Microcode has been changed" },
- { 0x3f02, "Changed operating definition" },
- { 0x3f03, "Inquiry data has changed" },
-
- { 0x4000, "Diagnostic failure on component (ASCQ)" },
-
- { 0x4400, "Internal ATAPI CD-ROM drive failure" },
-
- { 0x4e00, "Overlapped commands attempted" },
-
- { 0x5300, "Media load or eject failed" },
- { 0x5302, "Medium removal prevented" },
-
- { 0x5700, "Unable to recover table of contents" },
-
- { 0x5a00, "Operator request or state change input (unspecified)" },
- { 0x5a01, "Operator medium removal request" },
-
- { 0x5b00, "Threshold condition met" },
-
- { 0x5c00, "Status change" },
-
- { 0x6300, "End of user area encountered on this track" },
-
- { 0x6400, "Illegal mode for this track" },
-
- { 0xbf00, "Loss of streaming" },
-};
-#endif
-
-
-
-/****************************************************************************
- * Generic packet command support and error handling routines.
- */
-
-
-static
-void cdrom_analyze_sense_data (ide_drive_t *drive,
- struct atapi_request_sense *reqbuf,
- struct packet_command *failed_command)
-{
- /* Don't print not ready or unit attention errors for READ_SUBCHANNEL.
- Workman (and probably other programs) uses this command to poll
- the drive, and we don't want to fill the syslog with useless errors. */
- if (failed_command &&
- failed_command->c[0] == SCMD_READ_SUBCHANNEL &&
- (reqbuf->sense_key == NOT_READY || reqbuf->sense_key == UNIT_ATTENTION))
- return;
-
-#if VERBOSE_IDE_CD_ERRORS
- {
- int i;
- char *s;
- char buf[80];
-
- printk ("ATAPI device %s:\n", drive->name);
-
- printk (" Error code: 0x%02x\n", reqbuf->error_code);
-
- if (reqbuf->sense_key >= 0 &&
- reqbuf->sense_key < ARY_LEN (sense_key_texts))
- s = sense_key_texts[reqbuf->sense_key];
- else
- s = "(bad sense key)";
-
- printk (" Sense key: 0x%02x - %s\n", reqbuf->sense_key, s);
-
- if (reqbuf->asc == 0x40) {
- sprintf (buf, "Diagnostic failure on component 0x%02x", reqbuf->ascq);
- s = buf;
- }
-
- else {
- int lo, hi;
- int key = (reqbuf->asc << 8);
- if ( ! (reqbuf->ascq >= 0x80 && reqbuf->ascq <= 0xdd) )
- key |= reqbuf->ascq;
-
- lo = 0;
- hi = ARY_LEN (sense_data_texts);
- s = NULL;
-
- while (hi > lo) {
- int mid = (lo + hi) / 2;
- if (sense_data_texts[mid].asc_ascq == key) {
- s = sense_data_texts[mid].text;
- break;
- }
- else if (sense_data_texts[mid].asc_ascq > key)
- hi = mid;
- else
- lo = mid+1;
- }
- }
-
- if (s == NULL) {
- if (reqbuf->asc > 0x80)
- s = "(vendor-specific error)";
- else
- s = "(reserved error code)";
- }
-
- printk (" Additional sense data: 0x%02x, 0x%02x - %s\n",
- reqbuf->asc, reqbuf->ascq, s);
-
- if (failed_command != NULL) {
- printk (" Failed packet command: ");
- for (i=0; i<sizeof (failed_command->c); i++)
- printk ("%02x ", failed_command->c[i]);
- printk ("\n");
- }
-
- if (reqbuf->sense_key == ILLEGAL_REQUEST &&
- (reqbuf->sense_key_specific[0] & 0x80) != 0)
- {
- printk (" Error in %s byte %d",
- (reqbuf->sense_key_specific[0] & 0x40) != 0
- ? "command packet"
- : "command data",
- (reqbuf->sense_key_specific[1] << 8) +
- reqbuf->sense_key_specific[2]);
-
- if ((reqbuf->sense_key_specific[0] & 0x40) != 0)
- {
- printk (" bit %d", reqbuf->sense_key_specific[0] & 0x07);
- }
-
- printk ("\n");
- }
- }
-
-#else
-
- /* Suppress printing unit attention and `in progress of becoming ready'
- errors when we're not being verbose. */
-
- if (reqbuf->sense_key == UNIT_ATTENTION ||
- (reqbuf->sense_key == NOT_READY && (reqbuf->asc == 4 ||
- reqbuf->asc == 0x3a)))
- return;
-
- printk ("%s: code: 0x%02x key: 0x%02x asc: 0x%02x ascq: 0x%02x\n",
- drive->name,
- reqbuf->error_code, reqbuf->sense_key, reqbuf->asc, reqbuf->ascq);
-#endif
-}
-
-
-/* Fix up a possibly partially-processed request so that we can
- start it over entirely, or even put it back on the request queue. */
-static void restore_request (struct request *rq)
-{
- if (rq->buffer != rq->bh->b_data)
- {
- int n = (rq->buffer - rq->bh->b_data) / SECTOR_SIZE;
- rq->buffer = rq->bh->b_data;
- rq->nr_sectors += n;
- rq->sector -= n;
- }
- rq->current_nr_sectors = rq->bh->b_size >> SECTOR_BITS;
-}
-
-
-static void cdrom_queue_request_sense (ide_drive_t *drive,
- struct semaphore *sem,
- struct atapi_request_sense *reqbuf,
- struct packet_command *failed_command)
-{
- struct request *rq;
- struct packet_command *pc;
- int len;
-
- /* If the request didn't explicitly specify where to put the sense data,
- use the statically allocated structure. */
- if (reqbuf == NULL)
- reqbuf = &drive->cdrom_info.sense_data;
-
- /* Make up a new request to retrieve sense information. */
-
- pc = &HWIF(drive)->request_sense_pc;
- memset (pc, 0, sizeof (*pc));
-
- /* The request_sense structure has an odd number of (16-bit) words,
- which won't work well with 32-bit transfers. However, we don't care
- about the last two bytes, so just truncate the structure down
- to an even length. */
- len = sizeof (*reqbuf) / 4;
- len *= 4;
-
- pc->c[0] = REQUEST_SENSE;
- pc->c[4] = len;
- pc->buffer = (char *)reqbuf;
- pc->buflen = len;
- pc->sense_data = (struct atapi_request_sense *)failed_command;
-
- /* stuff the sense request in front of our current request */
-
- rq = &HWIF(drive)->request_sense_request;
- ide_init_drive_cmd (rq);
- rq->cmd = REQUEST_SENSE_COMMAND;
- rq->buffer = (char *)pc;
- rq->sem = sem;
- (void) ide_do_drive_cmd (drive, rq, ide_preempt);
-}
-
-
-static void cdrom_end_request (int uptodate, ide_drive_t *drive)
-{
- struct request *rq = HWGROUP(drive)->rq;
-
- /* The code in blk.h can screw us up on error recovery if the block
- size is larger than 1k. Fix that up here. */
- if (!uptodate && rq->bh != 0)
- {
- int adj = rq->current_nr_sectors - 1;
- rq->current_nr_sectors -= adj;
- rq->sector += adj;
- }
-
- if (rq->cmd == REQUEST_SENSE_COMMAND && uptodate)
- {
- struct packet_command *pc = (struct packet_command *)rq->buffer;
- cdrom_analyze_sense_data (drive,
- (struct atapi_request_sense *)(pc->buffer - pc->c[4]),
- (struct packet_command *)pc->sense_data);
- }
-
- ide_end_request (uptodate, HWGROUP(drive));
-}
-
-
-/* Mark that we've seen a media change, and invalidate our internal
- buffers. */
-static void cdrom_saw_media_change (ide_drive_t *drive)
-{
- CDROM_STATE_FLAGS (drive)->media_changed = 1;
- CDROM_STATE_FLAGS (drive)->toc_valid = 0;
- drive->cdrom_info.nsectors_buffered = 0;
-}
-
-
-/* Returns 0 if the request should be continued.
- Returns 1 if the request was ended. */
-static int cdrom_decode_status (ide_drive_t *drive, int good_stat, int *stat_ret)
-{
- struct request *rq = HWGROUP(drive)->rq;
- int stat, err, sense_key, cmd;
-
- /* Check for errors. */
- stat = GET_STAT();
- *stat_ret = stat;
-
- if (OK_STAT (stat, good_stat, BAD_R_STAT))
- return 0;
-
- /* Got an error. */
- err = IN_BYTE (IDE_ERROR_REG);
- sense_key = err >> 4;
-
- if (rq == NULL)
- printk ("%s : missing request in cdrom_decode_status\n", drive->name);
- else
- {
- cmd = rq->cmd;
-
- if (cmd == REQUEST_SENSE_COMMAND)
- {
- /* We got an error trying to get sense info from the drive
- (probably while trying to recover from a former error).
- Just give up. */
-
- struct packet_command *pc = (struct packet_command *)rq->buffer;
- pc->stat = 1;
- cdrom_end_request (1, drive);
- ide_error (drive, "request sense failure", stat);
- return 1;
- }
-
- else if (cmd == PACKET_COMMAND)
- {
- /* All other functions, except for READ. */
-
- struct packet_command *pc = (struct packet_command *)rq->buffer;
- struct semaphore *sem = NULL;
-
- /* Check for tray open. */
- if (sense_key == NOT_READY)
- {
- cdrom_saw_media_change (drive);
-
- /* Print an error message to the syslog.
- Exception: don't print anything if this is a read subchannel
- command. This is because workman constantly polls the drive
- with this command, and we don't want to uselessly fill up
- the syslog. */
- if (pc->c[0] != SCMD_READ_SUBCHANNEL)
- printk ("%s : tray open or drive not ready\n", drive->name);
- }
-
- /* Check for media change. */
- else if (sense_key == UNIT_ATTENTION)
- {
- cdrom_saw_media_change (drive);
- printk ("%s: media changed\n", drive->name);
- }
-
- /* Otherwise, print an error. */
- else
- {
- ide_dump_status (drive, "packet command error", stat);
- }
-
- /* Set the error flag and complete the request.
- Then, if we have a CHECK CONDITION status, queue a request
- sense command. We must be careful, though: we don't want
- the thread in cdrom_queue_packet_command to wake up until
- the request sense has completed. We do this by transferring
- the semaphore from the packet command request to the
- request sense request. */
-
- if ((stat & ERR_STAT) != 0)
- {
- sem = rq->sem;
- rq->sem = NULL;
- }
-
- pc->stat = 1;
- cdrom_end_request (1, drive);
-
- if ((stat & ERR_STAT) != 0)
- cdrom_queue_request_sense (drive, sem, pc->sense_data, pc);
- }
-
- else
- {
- /* Handle errors from READ requests. */
-
- /* Check for tray open. */
- if (sense_key == NOT_READY)
- {
- cdrom_saw_media_change (drive);
-
- /* Fail the request. */
- printk ("%s : tray open\n", drive->name);
- cdrom_end_request (0, drive);
- }
-
- /* Check for media change. */
- else if (sense_key == UNIT_ATTENTION)
- {
- cdrom_saw_media_change (drive);
-
- /* Arrange to retry the request.
- But be sure to give up if we've retried too many times. */
- if (++rq->errors > ERROR_MAX)
- {
- cdrom_end_request (0, drive);
- }
- }
- /* No point in retrying after an illegal request or
- data protect error.*/
- else if (sense_key == ILLEGAL_REQUEST || sense_key == DATA_PROTECT)
- {
- ide_dump_status (drive, "command error", stat);
- cdrom_end_request (0, drive);
- }
-
- /* If there were other errors, go to the default handler. */
- else if ((err & ~ABRT_ERR) != 0)
- {
- ide_error (drive, "cdrom_decode_status", stat);
- return 1;
- }
-
- /* Else, abort if we've racked up too many retries. */
- else if ((++rq->errors > ERROR_MAX))
- {
- cdrom_end_request (0, drive);
- }
-
- /* If we got a CHECK_CONDITION status, queue a request sense
- command. */
- if ((stat & ERR_STAT) != 0)
- cdrom_queue_request_sense (drive, NULL, NULL, NULL);
- }
- }
-
- /* Retry, or handle the next request. */
- return 1;
-}
-
-
-/* Set up the device registers for transferring a packet command on DEV,
- expecting to later transfer XFERLEN bytes. HANDLER is the routine
- which actually transfers the command to the drive. If this is a
- drq_interrupt device, this routine will arrange for HANDLER to be
- called when the interrupt from the drive arrives. Otherwise, HANDLER
- will be called immediately after the drive is prepared for the transfer. */
-
-static int cdrom_start_packet_command (ide_drive_t *drive, int xferlen,
- ide_handler_t *handler)
-{
- /* Wait for the controller to be idle. */
- if (ide_wait_stat (drive, 0, BUSY_STAT, WAIT_READY)) return 1;
-
- /* Set up the controller registers. */
- OUT_BYTE (0, IDE_FEATURE_REG);
- OUT_BYTE (0, IDE_NSECTOR_REG);
- OUT_BYTE (0, IDE_SECTOR_REG);
-
- OUT_BYTE (xferlen & 0xff, IDE_LCYL_REG);
- OUT_BYTE (xferlen >> 8 , IDE_HCYL_REG);
- OUT_BYTE (drive->ctl, IDE_CONTROL_REG);
-
- if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt)
- {
- ide_set_handler (drive, handler, WAIT_CMD);
- OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */
- }
- else
- {
- OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */
- (*handler) (drive);
- }
-
- return 0;
-}
-
-
-/* Send a packet command to DRIVE described by CMD_BUF and CMD_LEN.
- The device registers must have already been prepared
- by cdrom_start_packet_command.
- HANDLER is the interrupt handler to call when the command completes
- or there's data ready. */
-static int cdrom_transfer_packet_command (ide_drive_t *drive,
- char *cmd_buf, int cmd_len,
- ide_handler_t *handler)
-{
- if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt)
- {
- /* Here we should have been called after receiving an interrupt
- from the device. DRQ should how be set. */
- int stat_dum;
-
- /* Check for errors. */
- if (cdrom_decode_status (drive, DRQ_STAT, &stat_dum)) return 1;
- }
- else
- {
- /* Otherwise, we must wait for DRQ to get set. */
- if (ide_wait_stat (drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) return 1;
- }
-
- /* Arm the interrupt handler. */
- ide_set_handler (drive, handler, WAIT_CMD);
-
- /* Send the command to the device. */
- cdrom_out_bytes (drive, cmd_buf, cmd_len);
-
- return 0;
-}
-
-
-
-/****************************************************************************
- * Block read functions.
- */
-
-/*
- * Buffer up to SECTORS_TO_TRANSFER sectors from the drive in our sector
- * buffer. Once the first sector is added, any subsequent sectors are
- * assumed to be continuous (until the buffer is cleared). For the first
- * sector added, SECTOR is its sector number. (SECTOR is then ignored until
- * the buffer is cleared.)
- */
-static void cdrom_buffer_sectors (ide_drive_t *drive, unsigned long sector,
- int sectors_to_transfer)
-{
- struct cdrom_info *info = &drive->cdrom_info;
-
- /* Number of sectors to read into the buffer. */
- int sectors_to_buffer = MIN (sectors_to_transfer,
- (SECTOR_BUFFER_SIZE >> SECTOR_BITS) -
- info->nsectors_buffered);
-
- char *dest;
-
- /* If we don't yet have a sector buffer, try to allocate one.
- If we can't get one atomically, it's not fatal -- we'll just throw
- the data away rather than caching it. */
- if (info->sector_buffer == NULL)
- {
- info->sector_buffer = (char *) kmalloc (SECTOR_BUFFER_SIZE, GFP_ATOMIC);
-
- /* If we couldn't get a buffer, don't try to buffer anything... */
- if (info->sector_buffer == NULL)
- sectors_to_buffer = 0;
- }
-
- /* If this is the first sector in the buffer, remember its number. */
- if (info->nsectors_buffered == 0)
- info->sector_buffered = sector;
-
- /* Read the data into the buffer. */
- dest = info->sector_buffer + info->nsectors_buffered * SECTOR_SIZE;
- while (sectors_to_buffer > 0)
- {
- cdrom_in_bytes (drive, dest, SECTOR_SIZE);
- --sectors_to_buffer;
- --sectors_to_transfer;
- ++info->nsectors_buffered;
- dest += SECTOR_SIZE;
- }
-
- /* Throw away any remaining data. */
- while (sectors_to_transfer > 0)
- {
- char dum[SECTOR_SIZE];
- cdrom_in_bytes (drive, dum, sizeof (dum));
- --sectors_to_transfer;
- }
-}
-
-
-/*
- * Check the contents of the interrupt reason register from the cdrom
- * and attempt to recover if there are problems. Returns 0 if everything's
- * ok; nonzero if the request has been terminated.
- */
-static inline
-int cdrom_read_check_ireason (ide_drive_t *drive, int len, int ireason)
-{
- ireason &= 3;
- if (ireason == 2) return 0;
-
- if (ireason == 0)
- {
- /* Whoops... The drive is expecting to receive data from us! */
- printk ("%s: cdrom_read_intr: "
- "Drive wants to transfer data the wrong way!\n",
- drive->name);
-
- /* Throw some data at the drive so it doesn't hang
- and quit this request. */
- while (len > 0)
- {
- int dum = 0;
- cdrom_out_bytes (drive, &dum, sizeof (dum));
- len -= sizeof (dum);
- }
- }
-
- else
- {
- /* Drive wants a command packet, or invalid ireason... */
- printk ("%s: cdrom_read_intr: bad interrupt reason %d\n",
- drive->name, ireason);
- }
-
- cdrom_end_request (0, drive);
- return -1;
-}
-
-
-/*
- * Interrupt routine. Called when a read request has completed.
- */
-static void cdrom_read_intr (ide_drive_t *drive)
-{
- int stat;
- int ireason, len, sectors_to_transfer, nskip;
-
- struct request *rq = HWGROUP(drive)->rq;
-
- /* Check for errors. */
- if (cdrom_decode_status (drive, 0, &stat)) return;
-
- /* Read the interrupt reason and the transfer length. */
- ireason = IN_BYTE (IDE_NSECTOR_REG);
- len = IN_BYTE (IDE_LCYL_REG) + 256 * IN_BYTE (IDE_HCYL_REG);
-
- /* If DRQ is clear, the command has completed. */
- if ((stat & DRQ_STAT) == 0)
- {
- /* If we're not done filling the current buffer, complain.
- Otherwise, complete the command normally. */
- if (rq->current_nr_sectors > 0)
- {
- printk ("%s: cdrom_read_intr: data underrun (%ld blocks)\n",
- drive->name, rq->current_nr_sectors);
- cdrom_end_request (0, drive);
- }
- else
- cdrom_end_request (1, drive);
-
- return;
- }
-
- /* Check that the drive is expecting to do the same thing that we are. */
- if (cdrom_read_check_ireason (drive, len, ireason)) return;
-
- /* Assume that the drive will always provide data in multiples of at least
- SECTOR_SIZE, as it gets hairy to keep track of the transfers otherwise. */
- if ((len % SECTOR_SIZE) != 0)
- {
- printk ("%s: cdrom_read_intr: Bad transfer size %d\n",
- drive->name, len);
- printk (" This drive is not supported by this version of the driver\n");
- cdrom_end_request (0, drive);
- return;
- }
-
- /* The number of sectors we need to read from the drive. */
- sectors_to_transfer = len / SECTOR_SIZE;
-
- /* First, figure out if we need to bit-bucket any of the leading sectors. */
- nskip = MIN ((int)(rq->current_nr_sectors - (rq->bh->b_size >> SECTOR_BITS)),
- sectors_to_transfer);
-
- while (nskip > 0)
- {
- /* We need to throw away a sector. */
- char dum[SECTOR_SIZE];
- cdrom_in_bytes (drive, dum, sizeof (dum));
-
- --rq->current_nr_sectors;
- --nskip;
- --sectors_to_transfer;
- }
-
- /* Now loop while we still have data to read from the drive. */
- while (sectors_to_transfer > 0)
- {
- int this_transfer;
-
- /* If we've filled the present buffer but there's another chained
- buffer after it, move on. */
- if (rq->current_nr_sectors == 0 &&
- rq->nr_sectors > 0)
- cdrom_end_request (1, drive);
-
- /* If the buffers are full, cache the rest of the data in our
- internal buffer. */
- if (rq->current_nr_sectors == 0)
- {
- cdrom_buffer_sectors (drive, rq->sector, sectors_to_transfer);
- sectors_to_transfer = 0;
- }
- else
- {
- /* Transfer data to the buffers.
- Figure out how many sectors we can transfer
- to the current buffer. */
- this_transfer = MIN (sectors_to_transfer,
- rq->current_nr_sectors);
-
- /* Read this_transfer sectors into the current buffer. */
- while (this_transfer > 0)
- {
- cdrom_in_bytes (drive, rq->buffer, SECTOR_SIZE);
- rq->buffer += SECTOR_SIZE;
- --rq->nr_sectors;
- --rq->current_nr_sectors;
- ++rq->sector;
- --this_transfer;
- --sectors_to_transfer;
- }
- }
- }
-
- /* Done moving data!
- Wait for another interrupt. */
- ide_set_handler (drive, &cdrom_read_intr, WAIT_CMD);
-}
-
-
-/*
- * Try to satisfy some of the current read request from our cached data.
- * Returns nonzero if the request has been completed, zero otherwise.
- */
-static int cdrom_read_from_buffer (ide_drive_t *drive)
-{
- struct cdrom_info *info = &drive->cdrom_info;
- struct request *rq = HWGROUP(drive)->rq;
-
- /* Can't do anything if there's no buffer. */
- if (info->sector_buffer == NULL) return 0;
-
- /* Loop while this request needs data and the next block is present
- in our cache. */
- while (rq->nr_sectors > 0 &&
- rq->sector >= info->sector_buffered &&
- rq->sector < info->sector_buffered + info->nsectors_buffered)
- {
- if (rq->current_nr_sectors == 0)
- cdrom_end_request (1, drive);
-
- memcpy (rq->buffer,
- info->sector_buffer +
- (rq->sector - info->sector_buffered) * SECTOR_SIZE,
- SECTOR_SIZE);
- rq->buffer += SECTOR_SIZE;
- --rq->current_nr_sectors;
- --rq->nr_sectors;
- ++rq->sector;
- }
-
- /* If we've satisfied the current request, terminate it successfully. */
- if (rq->nr_sectors == 0)
- {
- cdrom_end_request (1, drive);
- return -1;
- }
-
- /* Move on to the next buffer if needed. */
- if (rq->current_nr_sectors == 0)
- cdrom_end_request (1, drive);
-
- /* If this condition does not hold, then the kluge i use to
- represent the number of sectors to skip at the start of a transfer
- will fail. I think that this will never happen, but let's be
- paranoid and check. */
- if (rq->current_nr_sectors < (rq->bh->b_size >> SECTOR_BITS) &&
- (rq->sector % SECTORS_PER_FRAME) != 0)
- {
- printk ("%s: cdrom_read_from_buffer: buffer botch (%ld)\n",
- drive->name, rq->sector);
- cdrom_end_request (0, drive);
- return -1;
- }
-
- return 0;
-}
-
-
-
-/*
- * Routine to send a read packet command to the drive.
- * This is usually called directly from cdrom_start_read.
- * However, for drq_interrupt devices, it is called from an interrupt
- * when the drive is ready to accept the command.
- */
-static void cdrom_start_read_continuation (ide_drive_t *drive)
-{
- struct packet_command pc;
- struct request *rq = HWGROUP(drive)->rq;
-
- int nsect, sector, nframes, frame, nskip;
-
- /* Number of sectors to transfer. */
- nsect = rq->nr_sectors;
-
- /* Starting sector. */
- sector = rq->sector;
-
- /* If the requested sector doesn't start on a cdrom block boundary,
- we must adjust the start of the transfer so that it does,
- and remember to skip the first few sectors. If the CURRENT_NR_SECTORS
- field is larger than the size of the buffer, it will mean that
- we're to skip a number of sectors equal to the amount by which
- CURRENT_NR_SECTORS is larger than the buffer size. */
- nskip = (sector % SECTORS_PER_FRAME);
- if (nskip > 0)
- {
- /* Sanity check... */
- if (rq->current_nr_sectors != (rq->bh->b_size >> SECTOR_BITS))
- {
- printk ("%s: cdrom_start_read_continuation: buffer botch (%ld)\n",
- drive->name, rq->current_nr_sectors);
- cdrom_end_request (0, drive);
- return;
- }
-
- sector -= nskip;
- nsect += nskip;
- rq->current_nr_sectors += nskip;
- }
-
- /* Convert from sectors to cdrom blocks, rounding up the transfer
- length if needed. */
- nframes = (nsect + SECTORS_PER_FRAME-1) / SECTORS_PER_FRAME;
- frame = sector / SECTORS_PER_FRAME;
-
- /* Largest number of frames was can transfer at once is 64k-1. */
- nframes = MIN (nframes, 65535);
-
- /* Set up the command */
- memset (&pc.c, 0, sizeof (pc.c));
- pc.c[0] = READ_10;
- pc.c[7] = (nframes >> 8);
- pc.c[8] = (nframes & 0xff);
-#ifdef __alpha__
- stl_u (htonl (frame), (unsigned int *) &pc.c[2]);
-#else
- *(int *)(&pc.c[2]) = htonl (frame);
-#endif
-
- /* Send the command to the drive and return. */
- (void) cdrom_transfer_packet_command (drive, pc.c, sizeof (pc.c),
- &cdrom_read_intr);
-}
-
-
-/*
- * Start a read request from the CD-ROM.
- */
-static void cdrom_start_read (ide_drive_t *drive, unsigned int block)
-{
- struct request *rq = HWGROUP(drive)->rq;
- int minor = MINOR (rq->rq_dev);
-
- /* If the request is relative to a partition, fix it up to refer to the
- absolute address. */
- if ((minor & PARTN_MASK) != 0) {
- rq->sector = block;
- minor &= ~PARTN_MASK;
- rq->rq_dev = MKDEV (MAJOR(rq->rq_dev), minor);
- }
-
- /* We may be retrying this request after an error.
- Fix up any weirdness which might be present in the request packet. */
- restore_request (rq);
-
- /* Satisfy whatever we can of this request from our cached sector. */
- if (cdrom_read_from_buffer (drive))
- return;
-
- /* Clear the local sector buffer. */
- drive->cdrom_info.nsectors_buffered = 0;
-
- /* Start sending the read request to the drive. */
- cdrom_start_packet_command (drive, 32768, cdrom_start_read_continuation);
-}
-
-
-
-
-/****************************************************************************
- * Execute all other packet commands.
- */
-
-/* Forward declarations. */
-static int
-cdrom_lockdoor (ide_drive_t *drive, int lockflag,
- struct atapi_request_sense *reqbuf);
-
-
-
-/* Interrupt routine for packet command completion. */
-static void cdrom_pc_intr (ide_drive_t *drive)
-{
- int ireason, len, stat, thislen;
- struct request *rq = HWGROUP(drive)->rq;
- struct packet_command *pc = (struct packet_command *)rq->buffer;
-
- /* Check for errors. */
- if (cdrom_decode_status (drive, 0, &stat)) return;
-
- /* Read the interrupt reason and the transfer length. */
- ireason = IN_BYTE (IDE_NSECTOR_REG);
- len = IN_BYTE (IDE_LCYL_REG) + 256 * IN_BYTE (IDE_HCYL_REG);
-
- /* If DRQ is clear, the command has completed.
- Complain if we still have data left to transfer. */
- if ((stat & DRQ_STAT) == 0)
- {
- /* Some of the trailing request sense fields are optional, and
- some drives don't send them. Sigh. */
- if (pc->c[0] == REQUEST_SENSE && pc->buflen > 0 && pc->buflen <= 5) {
- while (pc->buflen > 0) {
- *pc->buffer++ = 0;
- --pc->buflen;
- }
- }
-
- if (pc->buflen == 0)
- cdrom_end_request (1, drive);
- else
- {
- printk ("%s: cdrom_pc_intr: data underrun %d\n",
- drive->name, pc->buflen);
- pc->stat = 1;
- cdrom_end_request (1, drive);
- }
- return;
- }
-
- /* Figure out how much data to transfer. */
- thislen = pc->buflen;
- if (thislen < 0) thislen = -thislen;
- if (thislen > len) thislen = len;
-
- /* The drive wants to be written to. */
- if ((ireason & 3) == 0)
- {
- /* Check that we want to write. */
- if (pc->buflen > 0)
- {
- printk ("%s: cdrom_pc_intr: Drive wants to transfer data the wrong way!\n",
- drive->name);
- pc->stat = 1;
- thislen = 0;
- }
-
- /* Transfer the data. */
- cdrom_out_bytes (drive, pc->buffer, thislen);
-
- /* If we haven't moved enough data to satisfy the drive,
- add some padding. */
- while (len > thislen)
- {
- int dum = 0;
- cdrom_out_bytes (drive, &dum, sizeof (dum));
- len -= sizeof (dum);
- }
-
- /* Keep count of how much data we've moved. */
- pc->buffer += thislen;
- pc->buflen += thislen;
- }
-
- /* Same drill for reading. */
- else if ((ireason & 3) == 2)
- {
- /* Check that we want to read. */
- if (pc->buflen < 0)
- {
- printk ("%s: cdrom_pc_intr: Drive wants to transfer data the wrong way!\n",
- drive->name);
- pc->stat = 1;
- thislen = 0;
- }
-
- /* Transfer the data. */
- cdrom_in_bytes (drive, pc->buffer, thislen);
-
- /* If we haven't moved enough data to satisfy the drive,
- add some padding. */
- while (len > thislen)
- {
- int dum = 0;
- cdrom_in_bytes (drive, &dum, sizeof (dum));
- len -= sizeof (dum);
- }
-
- /* Keep count of how much data we've moved. */
- pc->buffer += thislen;
- pc->buflen -= thislen;
- }
-
- else
- {
- printk ("%s: cdrom_pc_intr: The drive appears confused (ireason = 0x%2x)\n",
- drive->name, ireason);
- pc->stat = 1;
- }
-
- /* Now we wait for another interrupt. */
- ide_set_handler (drive, &cdrom_pc_intr, WAIT_CMD);
-}
-
-
-static void cdrom_do_pc_continuation (ide_drive_t *drive)
-{
- struct request *rq = HWGROUP(drive)->rq;
- struct packet_command *pc = (struct packet_command *)rq->buffer;
-
- /* Send the command to the drive and return. */
- cdrom_transfer_packet_command (drive, pc->c, sizeof (pc->c), &cdrom_pc_intr);
-}
-
-
-static void cdrom_do_packet_command (ide_drive_t *drive)
-{
- int len;
- struct request *rq = HWGROUP(drive)->rq;
- struct packet_command *pc = (struct packet_command *)rq->buffer;
-
- len = pc->buflen;
- if (len < 0) len = -len;
-
- pc->stat = 0;
-
- /* Start sending the command to the drive. */
- cdrom_start_packet_command (drive, len, cdrom_do_pc_continuation);
-}
-
-#ifndef MACH
-/* Sleep for TIME jiffies.
- Not to be called from an interrupt handler. */
-static
-void cdrom_sleep (int time)
-{
- current->state = TASK_INTERRUPTIBLE;
- current->timeout = jiffies + time;
- schedule ();
-}
-#endif
-
-static
-int cdrom_queue_packet_command (ide_drive_t *drive, struct packet_command *pc)
-{
- struct atapi_request_sense my_reqbuf;
- int retries = 10;
- struct request req;
-
- /* If our caller has not provided a place to stick any sense data,
- use our own area. */
- if (pc->sense_data == NULL)
- pc->sense_data = &my_reqbuf;
- pc->sense_data->sense_key = 0;
-
- /* Start of retry loop. */
- do {
- ide_init_drive_cmd (&req);
- req.cmd = PACKET_COMMAND;
- req.buffer = (char *)pc;
- (void) ide_do_drive_cmd (drive, &req, ide_wait);
-
- if (pc->stat != 0)
- {
- /* The request failed. Retry if it was due to a unit attention status
- (usually means media was changed). */
- struct atapi_request_sense *reqbuf = pc->sense_data;
-
- if (reqbuf->sense_key == UNIT_ATTENTION)
- ;
-
- /* Also retry if the drive is in the process of loading a disk.
- This time, however, wait a little between retries to give
- the drive time. */
- else if (reqbuf->sense_key == NOT_READY && reqbuf->asc == 4)
- {
- cdrom_sleep (HZ);
- }
-
- /* Otherwise, don't retry. */
- else
- retries = 0;
-
- --retries;
- }
-
- /* End of retry loop. */
- } while (pc->stat != 0 && retries >= 0);
-
-
- /* Return an error if the command failed. */
- if (pc->stat != 0)
- return -EIO;
-
- else
- {
- /* The command succeeded. If it was anything other than a request sense,
- eject, or door lock command, and we think that the door is presently
- unlocked, lock it again. (The door was probably unlocked via
- an explicit CDROMEJECT ioctl.) */
- if (CDROM_STATE_FLAGS (drive)->door_locked == 0 &&
- (pc->c[0] != REQUEST_SENSE &&
- pc->c[0] != ALLOW_MEDIUM_REMOVAL &&
- pc->c[0] != START_STOP))
- {
- (void) cdrom_lockdoor (drive, 1, NULL);
- }
- return 0;
- }
-}
-
-
-
-/****************************************************************************
- * drive_cmd handling.
- *
- * Most of the functions accessed via drive_cmd are not valid for ATAPI
- * devices. Only attempt to execute those which actually should be valid.
- */
-
-static
-void cdrom_do_drive_cmd (ide_drive_t *drive)
-{
- struct request *rq = HWGROUP(drive)->rq;
- byte *args = rq->buffer;
-
- if (args)
- {
-#if 0 /* This bit isn't done yet... */
- if (args[0] == WIN_SETFEATURES &&
- (args[2] == 0x66 || args[2] == 0xcc || args[2] == 0x02 ||
- args[2] == 0xdd || args[2] == 0x5d))
- {
- OUT_BYTE (args[2], io_base + IDE_FEATURE_OFFSET);
- <send cmd>
- }
- else
-#endif
- {
- printk ("%s: Unsupported drive command %02x %02x %02x\n",
- drive->name, args[0], args[1], args[2]);
- rq->errors = 1;
- }
- }
-
- cdrom_end_request (1, drive);
-}
-
-
-
-/****************************************************************************
- * cdrom driver request routine.
- */
-
-void ide_do_rw_cdrom (ide_drive_t *drive, unsigned long block)
-{
- struct request *rq = HWGROUP(drive)->rq;
-
- if (rq -> cmd == PACKET_COMMAND || rq -> cmd == REQUEST_SENSE_COMMAND)
- cdrom_do_packet_command (drive);
-
- else if (rq -> cmd == RESET_DRIVE_COMMAND)
- {
- cdrom_end_request (1, drive);
- ide_do_reset (drive);
- return;
- }
-
- else if (rq -> cmd == IDE_DRIVE_CMD)
- cdrom_do_drive_cmd (drive);
-
- else if (rq -> cmd != READ)
- {
- printk ("ide-cd: bad cmd %d\n", rq -> cmd);
- cdrom_end_request (0, drive);
- }
- else
- cdrom_start_read (drive, block);
-}
-
-
-
-/****************************************************************************
- * Ioctl handling.
- *
- * Routines which queue packet commands take as a final argument a pointer
- * to an atapi_request_sense struct. If execution of the command results
- * in an error with a CHECK CONDITION status, this structure will be filled
- * with the results of the subsequent request sense command. The pointer
- * can also be NULL, in which case no sense information is returned.
- */
-
-#if ! STANDARD_ATAPI
-static
-int bin2bcd (int x)
-{
- return (x%10) | ((x/10) << 4);
-}
-
-
-static
-int bcd2bin (int x)
-{
- return (x >> 4) * 10 + (x & 0x0f);
-}
-#endif /* not STANDARD_ATAPI */
-
-
-static inline
-void lba_to_msf (int lba, byte *m, byte *s, byte *f)
-{
- lba += CD_BLOCK_OFFSET;
- lba &= 0xffffff; /* negative lbas use only 24 bits */
- *m = lba / (CD_SECS * CD_FRAMES);
- lba %= (CD_SECS * CD_FRAMES);
- *s = lba / CD_FRAMES;
- *f = lba % CD_FRAMES;
-}
-
-
-static inline
-int msf_to_lba (byte m, byte s, byte f)
-{
- return (((m * CD_SECS) + s) * CD_FRAMES + f) - CD_BLOCK_OFFSET;
-}
-
-
-static int
-cdrom_check_status (ide_drive_t *drive,
- struct atapi_request_sense *reqbuf)
-{
- struct packet_command pc;
-
- memset (&pc, 0, sizeof (pc));
-
- pc.sense_data = reqbuf;
- pc.c[0] = TEST_UNIT_READY;
-
- return cdrom_queue_packet_command (drive, &pc);
-}
-
-
-/* Lock the door if LOCKFLAG is nonzero; unlock it otherwise. */
-static int
-cdrom_lockdoor (ide_drive_t *drive, int lockflag,
- struct atapi_request_sense *reqbuf)
-{
- struct atapi_request_sense my_reqbuf;
- int stat;
- struct packet_command pc;
-
- if (reqbuf == NULL)
- reqbuf = &my_reqbuf;
-
- /* If the drive cannot lock the door, just pretend. */
- if (CDROM_CONFIG_FLAGS (drive)->no_doorlock)
- stat = 0;
- else
- {
- memset (&pc, 0, sizeof (pc));
- pc.sense_data = reqbuf;
-
- pc.c[0] = ALLOW_MEDIUM_REMOVAL;
- pc.c[4] = (lockflag != 0);
- stat = cdrom_queue_packet_command (drive, &pc);
- }
-
- if (stat == 0)
- CDROM_STATE_FLAGS (drive)->door_locked = lockflag;
- else
- {
- /* If we got an illegal field error, the drive
- probably cannot lock the door. */
- if (reqbuf->sense_key == ILLEGAL_REQUEST && reqbuf->asc == 0x24)
- {
- printk ("%s: door locking not supported\n", drive->name);
- CDROM_CONFIG_FLAGS (drive)->no_doorlock = 1;
- stat = 0;
- CDROM_STATE_FLAGS (drive)->door_locked = lockflag;
- }
- }
- return stat;
-}
-
-
-/* Eject the disk if EJECTFLAG is 0.
- If EJECTFLAG is 1, try to reload the disk. */
-static int
-cdrom_eject (ide_drive_t *drive, int ejectflag,
- struct atapi_request_sense *reqbuf)
-{
- struct packet_command pc;
-
- memset (&pc, 0, sizeof (pc));
- pc.sense_data = reqbuf;
-
- pc.c[0] = START_STOP;
- pc.c[4] = 2 + (ejectflag != 0);
- return cdrom_queue_packet_command (drive, &pc);
-}
-
-
-static int
-cdrom_pause (ide_drive_t *drive, int pauseflag,
- struct atapi_request_sense *reqbuf)
-{
- struct packet_command pc;
-
- memset (&pc, 0, sizeof (pc));
- pc.sense_data = reqbuf;
-
- pc.c[0] = SCMD_PAUSE_RESUME;
- pc.c[8] = !pauseflag;
- return cdrom_queue_packet_command (drive, &pc);
-}
-
-
-static int
-cdrom_startstop (ide_drive_t *drive, int startflag,
- struct atapi_request_sense *reqbuf)
-{
- struct packet_command pc;
-
- memset (&pc, 0, sizeof (pc));
- pc.sense_data = reqbuf;
-
- pc.c[0] = START_STOP;
- pc.c[1] = 1;
- pc.c[4] = startflag;
- return cdrom_queue_packet_command (drive, &pc);
-}
-
-
-static int
-cdrom_read_capacity (ide_drive_t *drive, unsigned *capacity,
- struct atapi_request_sense *reqbuf)
-{
- struct {
- unsigned lba;
- unsigned blocklen;
- } capbuf;
-
- int stat;
- struct packet_command pc;
-
- memset (&pc, 0, sizeof (pc));
- pc.sense_data = reqbuf;
-
- pc.c[0] = READ_CAPACITY;
- pc.buffer = (char *)&capbuf;
- pc.buflen = sizeof (capbuf);
-
- stat = cdrom_queue_packet_command (drive, &pc);
- if (stat == 0)
- {
- *capacity = ntohl (capbuf.lba);
- }
-
- return stat;
-}
-
-
-static int
-cdrom_read_tocentry (ide_drive_t *drive, int trackno, int msf_flag,
- int format, char *buf, int buflen,
- struct atapi_request_sense *reqbuf)
-{
- struct packet_command pc;
-
- memset (&pc, 0, sizeof (pc));
- pc.sense_data = reqbuf;
-
- pc.buffer = buf;
- pc.buflen = buflen;
- pc.c[0] = SCMD_READ_TOC;
- pc.c[6] = trackno;
- pc.c[7] = (buflen >> 8);
- pc.c[8] = (buflen & 0xff);
- pc.c[9] = (format << 6);
- if (msf_flag) pc.c[1] = 2;
- return cdrom_queue_packet_command (drive, &pc);
-}
-
-
-/* Try to read the entire TOC for the disk into our internal buffer. */
-static int
-cdrom_read_toc (ide_drive_t *drive,
- struct atapi_request_sense *reqbuf)
-{
- int msf_flag;
- int stat, ntracks, i;
- struct atapi_toc *toc = drive->cdrom_info.toc;
- struct {
- struct atapi_toc_header hdr;
- struct atapi_toc_entry ent;
- } ms_tmp;
-
- if (toc == NULL)
- {
- /* Try to allocate space. */
- toc = (struct atapi_toc *) kmalloc (sizeof (struct atapi_toc),
- GFP_KERNEL);
- drive->cdrom_info.toc = toc;
- }
-
- if (toc == NULL)
- {
- printk ("%s: No cdrom TOC buffer!\n", drive->name);
- return -EIO;
- }
-
- /* Check to see if the existing data is still valid.
- If it is, just return. */
- if (CDROM_STATE_FLAGS (drive)->toc_valid)
- (void) cdrom_check_status (drive, NULL);
-
- if (CDROM_STATE_FLAGS (drive)->toc_valid) return 0;
-
-#if STANDARD_ATAPI
- msf_flag = 0;
-#else /* not STANDARD_ATAPI */
- /* Some drives can't return TOC data in LBA format. */
- msf_flag = (CDROM_CONFIG_FLAGS (drive)->no_lba_toc);
-#endif /* not STANDARD_ATAPI */
-
- /* First read just the header, so we know how long the TOC is. */
- stat = cdrom_read_tocentry (drive, 0, msf_flag, 0, (char *)&toc->hdr,
- sizeof (struct atapi_toc_header) +
- sizeof (struct atapi_toc_entry),
- reqbuf);
- if (stat) return stat;
-
-#if ! STANDARD_ATAPI
- if (CDROM_CONFIG_FLAGS (drive)->vertos_lossage)
- {
- toc->hdr.first_track = bcd2bin (toc->hdr.first_track);
- toc->hdr.last_track = bcd2bin (toc->hdr.last_track);
- /* hopefully the length is not BCD, too ;-| */
- }
-#endif /* not STANDARD_ATAPI */
-
- ntracks = toc->hdr.last_track - toc->hdr.first_track + 1;
- if (ntracks <= 0) return -EIO;
- if (ntracks > MAX_TRACKS) ntracks = MAX_TRACKS;
-
- /* Now read the whole schmeer. */
- stat = cdrom_read_tocentry (drive, 0, msf_flag, 0, (char *)&toc->hdr,
- sizeof (struct atapi_toc_header) +
- (ntracks+1) * sizeof (struct atapi_toc_entry),
- reqbuf);
- if (stat) return stat;
- toc->hdr.toc_length = ntohs (toc->hdr.toc_length);
-
-#if ! STANDARD_ATAPI
- if (CDROM_CONFIG_FLAGS (drive)->vertos_lossage)
- {
- toc->hdr.first_track = bcd2bin (toc->hdr.first_track);
- toc->hdr.last_track = bcd2bin (toc->hdr.last_track);
- /* hopefully the length is not BCD, too ;-| */
- }
-#endif /* not STANDARD_ATAPI */
-
- for (i=0; i<=ntracks; i++)
- {
-#if ! STANDARD_ATAPI
- if (msf_flag)
- {
- if (CDROM_CONFIG_FLAGS (drive)->vertos_lossage)
- {
- toc->ent[i].track = bcd2bin (toc->ent[i].track);
- toc->ent[i].addr.msf.m = bcd2bin (toc->ent[i].addr.msf.m);
- toc->ent[i].addr.msf.s = bcd2bin (toc->ent[i].addr.msf.s);
- toc->ent[i].addr.msf.f = bcd2bin (toc->ent[i].addr.msf.f);
- }
- toc->ent[i].addr.lba = msf_to_lba (toc->ent[i].addr.msf.m,
- toc->ent[i].addr.msf.s,
- toc->ent[i].addr.msf.f);
- }
- else
-#endif /* not STANDARD_ATAPI */
- toc->ent[i].addr.lba = ntohl (toc->ent[i].addr.lba);
- }
-
- /* Read the multisession information. */
- stat = cdrom_read_tocentry (drive, 0, msf_flag, 1,
- (char *)&ms_tmp, sizeof (ms_tmp),
- reqbuf);
- if (stat) return stat;
-#if ! STANDARD_ATAPI
- if (msf_flag)
- toc->last_session_lba = msf_to_lba (ms_tmp.ent.addr.msf.m,
- ms_tmp.ent.addr.msf.s,
- ms_tmp.ent.addr.msf.f);
- else
-#endif /* not STANDARD_ATAPI */
- toc->last_session_lba = ntohl (ms_tmp.ent.addr.lba);
-
- toc->xa_flag = (ms_tmp.hdr.first_track != ms_tmp.hdr.last_track);
-
- /* Now try to get the total cdrom capacity. */
- stat = cdrom_read_capacity (drive, &toc->capacity, reqbuf);
- if (stat) toc->capacity = 0x1fffff;
-
- HWIF(drive)->gd->sizes[drive->select.b.unit << PARTN_BITS]
- = toc->capacity * SECTORS_PER_FRAME;
- drive->part[0].nr_sects = toc->capacity * SECTORS_PER_FRAME;
-
- /* Remember that we've read this stuff. */
- CDROM_STATE_FLAGS (drive)->toc_valid = 1;
-
- return 0;
-}
-
-
-static int
-cdrom_read_subchannel (ide_drive_t *drive,
- char *buf, int buflen,
- struct atapi_request_sense *reqbuf)
-{
- struct packet_command pc;
-
- memset (&pc, 0, sizeof (pc));
- pc.sense_data = reqbuf;
-
- pc.buffer = buf;
- pc.buflen = buflen;
- pc.c[0] = SCMD_READ_SUBCHANNEL;
- pc.c[2] = 0x40; /* request subQ data */
- pc.c[3] = 0x01; /* Format 1: current position */
- pc.c[7] = (buflen >> 8);
- pc.c[8] = (buflen & 0xff);
- return cdrom_queue_packet_command (drive, &pc);
-}
-
-
-/* modeflag: 0 = current, 1 = changeable mask, 2 = default, 3 = saved */
-static int
-cdrom_mode_sense (ide_drive_t *drive, int pageno, int modeflag,
- char *buf, int buflen,
- struct atapi_request_sense *reqbuf)
-{
- struct packet_command pc;
-
- memset (&pc, 0, sizeof (pc));
- pc.sense_data = reqbuf;
-
- pc.buffer = buf;
- pc.buflen = buflen;
- pc.c[0] = MODE_SENSE_10;
- pc.c[2] = pageno | (modeflag << 6);
- pc.c[7] = (buflen >> 8);
- pc.c[8] = (buflen & 0xff);
- return cdrom_queue_packet_command (drive, &pc);
-}
-
-
-static int
-cdrom_mode_select (ide_drive_t *drive, int pageno, char *buf, int buflen,
- struct atapi_request_sense *reqbuf)
-{
- struct packet_command pc;
-
- memset (&pc, 0, sizeof (pc));
- pc.sense_data = reqbuf;
-
- pc.buffer = buf;
- pc.buflen = - buflen;
- pc.c[0] = MODE_SELECT_10;
- pc.c[1] = 0x10;
- pc.c[2] = pageno;
- pc.c[7] = (buflen >> 8);
- pc.c[8] = (buflen & 0xff);
- return cdrom_queue_packet_command (drive, &pc);
-}
-
-
-static int
-cdrom_play_lba_range_play12 (ide_drive_t *drive, int lba_start, int lba_end,
- struct atapi_request_sense *reqbuf)
-{
- struct packet_command pc;
-
- memset (&pc, 0, sizeof (pc));
- pc.sense_data = reqbuf;
-
- pc.c[0] = SCMD_PLAYAUDIO12;
-#ifdef __alpha__
- stq_u(((long) htonl (lba_end - lba_start) << 32) | htonl(lba_start),
- (unsigned long *) &pc.c[2]);
-#else
- *(int *)(&pc.c[2]) = htonl (lba_start);
- *(int *)(&pc.c[6]) = htonl (lba_end - lba_start);
-#endif
-
- return cdrom_queue_packet_command (drive, &pc);
-}
-
-
-#if ! STANDARD_ATAPI
-static int
-cdrom_play_lba_range_msf (ide_drive_t *drive, int lba_start, int lba_end,
- struct atapi_request_sense *reqbuf)
-{
- struct packet_command pc;
-
- memset (&pc, 0, sizeof (pc));
- pc.sense_data = reqbuf;
-
- pc.c[0] = SCMD_PLAYAUDIO_MSF;
- lba_to_msf (lba_start, &pc.c[3], &pc.c[4], &pc.c[5]);
- lba_to_msf (lba_end-1, &pc.c[6], &pc.c[7], &pc.c[8]);
-
- if (CDROM_CONFIG_FLAGS (drive)->playmsf_uses_bcd)
- {
- pc.c[3] = bin2bcd (pc.c[3]);
- pc.c[4] = bin2bcd (pc.c[4]);
- pc.c[5] = bin2bcd (pc.c[5]);
- pc.c[6] = bin2bcd (pc.c[6]);
- pc.c[7] = bin2bcd (pc.c[7]);
- pc.c[8] = bin2bcd (pc.c[8]);
- }
-
- return cdrom_queue_packet_command (drive, &pc);
-}
-#endif /* not STANDARD_ATAPI */
-
-
-static int
-cdrom_play_lba_range_1 (ide_drive_t *drive, int lba_start, int lba_end,
- struct atapi_request_sense *reqbuf)
-{
- /* This is rather annoying.
- My NEC-260 won't recognize group 5 commands such as PLAYAUDIO12;
- the only way to get it to play more than 64k of blocks at once
- seems to be the PLAYAUDIO_MSF command. However, the parameters
- the NEC 260 wants for the PLAYMSF command are incompatible with
- the new version of the spec.
-
- So what i'll try is this. First try for PLAYAUDIO12. If it works,
- great. Otherwise, if the drive reports an illegal command code,
- try PLAYAUDIO_MSF using the NEC 260-style bcd parameters. */
-
-#if ! STANDARD_ATAPI
- if (CDROM_CONFIG_FLAGS (drive)->no_playaudio12)
- return cdrom_play_lba_range_msf (drive, lba_start, lba_end, reqbuf);
- else
-#endif /* not STANDARD_ATAPI */
- {
- int stat;
- struct atapi_request_sense my_reqbuf;
-
- if (reqbuf == NULL)
- reqbuf = &my_reqbuf;
-
- stat = cdrom_play_lba_range_play12 (drive, lba_start, lba_end, reqbuf);
- if (stat == 0) return 0;
-
-#if ! STANDARD_ATAPI
- /* It failed. Try to find out why. */
- if (reqbuf->sense_key == ILLEGAL_REQUEST && reqbuf->asc == 0x20)
- {
- /* The drive didn't recognize the command.
- Retry with the MSF variant. */
- printk ("%s: Drive does not support PLAYAUDIO12; "
- "trying PLAYAUDIO_MSF\n", drive->name);
- CDROM_CONFIG_FLAGS (drive)->no_playaudio12 = 1;
- CDROM_CONFIG_FLAGS (drive)->playmsf_uses_bcd = 1;
- return cdrom_play_lba_range_msf (drive, lba_start, lba_end, reqbuf);
- }
-#endif /* not STANDARD_ATAPI */
-
- /* Failed for some other reason. Give up. */
- return stat;
- }
-}
-
-
-/* Play audio starting at LBA LBA_START and finishing with the
- LBA before LBA_END. */
-static int
-cdrom_play_lba_range (ide_drive_t *drive, int lba_start, int lba_end,
- struct atapi_request_sense *reqbuf)
-{
- int i, stat;
- struct atapi_request_sense my_reqbuf;
-
- if (reqbuf == NULL)
- reqbuf = &my_reqbuf;
-
- /* Some drives, will, for certain audio cds,
- give an error if you ask them to play the entire cd using the
- values which are returned in the TOC. The play will succeed, however,
- if the ending address is adjusted downwards by a few frames. */
- for (i=0; i<75; i++)
- {
- stat = cdrom_play_lba_range_1 (drive, lba_start, lba_end, reqbuf);
-
- if (stat == 0 ||
- !(reqbuf->sense_key == ILLEGAL_REQUEST && reqbuf->asc == 0x24))
- return stat;
-
- --lba_end;
- if (lba_end <= lba_start) break;
- }
-
- return stat;
-}
-
-
-static
-int cdrom_get_toc_entry (ide_drive_t *drive, int track,
- struct atapi_toc_entry **ent,
- struct atapi_request_sense *reqbuf)
-{
- int stat, ntracks;
- struct atapi_toc *toc;
-
- /* Make sure our saved TOC is valid. */
- stat = cdrom_read_toc (drive, reqbuf);
- if (stat) return stat;
-
- toc = drive->cdrom_info.toc;
-
- /* Check validity of requested track number. */
- ntracks = toc->hdr.last_track - toc->hdr.first_track + 1;
- if (track == CDROM_LEADOUT)
- *ent = &toc->ent[ntracks];
- else if (track < toc->hdr.first_track ||
- track > toc->hdr.last_track)
- return -EINVAL;
- else
- *ent = &toc->ent[track - toc->hdr.first_track];
-
- return 0;
-}
-
-
-static int
-cdrom_read_block (ide_drive_t *drive, int format, int lba,
- char *buf, int buflen,
- struct atapi_request_sense *reqbuf)
-{
- struct packet_command pc;
- struct atapi_request_sense my_reqbuf;
- int stat;
-
- if (reqbuf == NULL)
- reqbuf = &my_reqbuf;
-
- memset (&pc, 0, sizeof (pc));
- pc.sense_data = reqbuf;
-
- pc.buffer = buf;
- pc.buflen = buflen;
-
-#if ! STANDARD_ATAPI
- if (CDROM_CONFIG_FLAGS (drive)->old_readcd)
- pc.c[0] = 0xd4;
- else
-#endif /* not STANDARD_ATAPI */
- pc.c[0] = READ_CD;
-
- pc.c[1] = (format << 2);
-#ifdef __alpha__
- stl_u(htonl (lba), (unsigned int *) &pc.c[2]);
-#else
- *(int *)(&pc.c[2]) = htonl (lba);
-#endif
- pc.c[8] = 1; /* one block */
- pc.c[9] = 0x10;
-
- stat = cdrom_queue_packet_command (drive, &pc);
-
-#if ! STANDARD_ATAPI
- /* If the drive doesn't recognize the READ CD opcode, retry the command
- with an older opcode for that command. */
- if (stat && reqbuf->sense_key == ILLEGAL_REQUEST && reqbuf->asc == 0x20 &&
- CDROM_CONFIG_FLAGS (drive)->old_readcd == 0)
- {
- printk ("%s: Drive does not recognize READ_CD; trying opcode 0xd4\n",
- drive->name);
- CDROM_CONFIG_FLAGS (drive)->old_readcd = 1;
- return cdrom_read_block (drive, format, lba, buf, buflen, reqbuf);
- }
-#endif /* not STANDARD_ATAPI */
-
- return stat;
-}
-
-
-int ide_cdrom_ioctl (ide_drive_t *drive, struct inode *inode,
- struct file *file, unsigned int cmd, unsigned long arg)
-{
- switch (cmd)
- {
- case CDROMEJECT:
- {
- int stat;
-
- if (drive->usage > 1)
- return -EBUSY;
-
- stat = cdrom_lockdoor (drive, 0, NULL);
- if (stat) return stat;
-
- return cdrom_eject (drive, 0, NULL);
- }
-
- case CDROMEJECT_SW:
- {
- CDROM_STATE_FLAGS (drive)->eject_on_close = arg;
- return 0;
- }
-
- case CDROMPAUSE:
- return cdrom_pause (drive, 1, NULL);
-
- case CDROMRESUME:
- return cdrom_pause (drive, 0, NULL);
-
- case CDROMSTART:
- return cdrom_startstop (drive, 1, NULL);
-
- case CDROMSTOP:
- {
- int stat;
-
- stat = cdrom_startstop (drive, 0, NULL);
- if (stat) return stat;
- /* pit says the Dolphin needs this. */
- return cdrom_eject (drive, 1, NULL);
- }
-
- case CDROMPLAYMSF:
- {
- struct cdrom_msf msf;
- int stat, lba_start, lba_end;
-
- stat = verify_area (VERIFY_READ, (void *)arg, sizeof (msf));
- if (stat) return stat;
-
- memcpy_fromfs (&msf, (void *) arg, sizeof(msf));
-
- lba_start = msf_to_lba (msf.cdmsf_min0, msf.cdmsf_sec0,
- msf.cdmsf_frame0);
- lba_end = msf_to_lba (msf.cdmsf_min1, msf.cdmsf_sec1,
- msf.cdmsf_frame1) + 1;
-
- if (lba_end <= lba_start) return -EINVAL;
-
- return cdrom_play_lba_range (drive, lba_start, lba_end, NULL);
- }
-
- /* Like just about every other Linux cdrom driver, we ignore the
- index part of the request here. */
- case CDROMPLAYTRKIND:
- {
- int stat, lba_start, lba_end;
- struct cdrom_ti ti;
- struct atapi_toc_entry *first_toc, *last_toc;
-
- stat = verify_area (VERIFY_READ, (void *)arg, sizeof (ti));
- if (stat) return stat;
-
- memcpy_fromfs (&ti, (void *) arg, sizeof(ti));
-
- stat = cdrom_get_toc_entry (drive, ti.cdti_trk0, &first_toc, NULL);
- if (stat) return stat;
- stat = cdrom_get_toc_entry (drive, ti.cdti_trk1, &last_toc, NULL);
- if (stat) return stat;
-
- if (ti.cdti_trk1 != CDROM_LEADOUT) ++last_toc;
- lba_start = first_toc->addr.lba;
- lba_end = last_toc->addr.lba;
-
- if (lba_end <= lba_start) return -EINVAL;
-
- return cdrom_play_lba_range (drive, lba_start, lba_end, NULL);
- }
-
- case CDROMREADTOCHDR:
- {
- int stat;
- struct cdrom_tochdr tochdr;
- struct atapi_toc *toc;
-
- stat = verify_area (VERIFY_WRITE, (void *) arg, sizeof (tochdr));
- if (stat) return stat;
-
- /* Make sure our saved TOC is valid. */
- stat = cdrom_read_toc (drive, NULL);
- if (stat) return stat;
-
- toc = drive->cdrom_info.toc;
- tochdr.cdth_trk0 = toc->hdr.first_track;
- tochdr.cdth_trk1 = toc->hdr.last_track;
-
- memcpy_tofs ((void *) arg, &tochdr, sizeof (tochdr));
-
- return stat;
- }
-
- case CDROMREADTOCENTRY:
- {
- int stat;
- struct cdrom_tocentry tocentry;
- struct atapi_toc_entry *toce;
-
- stat = verify_area (VERIFY_READ, (void *) arg, sizeof (tocentry));
- if (stat) return stat;
- stat = verify_area (VERIFY_WRITE, (void *) arg, sizeof (tocentry));
- if (stat) return stat;
-
- memcpy_fromfs (&tocentry, (void *) arg, sizeof (tocentry));
-
- stat = cdrom_get_toc_entry (drive, tocentry.cdte_track, &toce, NULL);
- if (stat) return stat;
-
- tocentry.cdte_ctrl = toce->control;
- tocentry.cdte_adr = toce->adr;
-
- if (tocentry.cdte_format == CDROM_MSF)
- {
- /* convert to MSF */
- lba_to_msf (toce->addr.lba,
- &tocentry.cdte_addr.msf.minute,
- &tocentry.cdte_addr.msf.second,
- &tocentry.cdte_addr.msf.frame);
- }
- else
- tocentry.cdte_addr.lba = toce->addr.lba;
-
- memcpy_tofs ((void *) arg, &tocentry, sizeof (tocentry));
-
- return stat;
- }
-
- case CDROMSUBCHNL:
- {
- struct atapi_cdrom_subchnl scbuf;
- int stat, abs_lba, rel_lba;
- struct cdrom_subchnl subchnl;
-
- stat = verify_area (VERIFY_WRITE, (void *) arg, sizeof (subchnl));
- if (stat) return stat;
- stat = verify_area (VERIFY_READ, (void *) arg, sizeof (subchnl));
- if (stat) return stat;
-
- memcpy_fromfs (&subchnl, (void *) arg, sizeof (subchnl));
-
- stat = cdrom_read_subchannel (drive, (char *)&scbuf, sizeof (scbuf),
- NULL);
- if (stat) return stat;
-
-#if ! STANDARD_ATAPI
- if (CDROM_CONFIG_FLAGS (drive)->vertos_lossage)
- {
- abs_lba = msf_to_lba (bcd2bin (scbuf.acdsc_absaddr.msf.minute),
- bcd2bin (scbuf.acdsc_absaddr.msf.second),
- bcd2bin (scbuf.acdsc_absaddr.msf.frame));
- rel_lba = msf_to_lba (bcd2bin (scbuf.acdsc_reladdr.msf.minute),
- bcd2bin (scbuf.acdsc_reladdr.msf.second),
- bcd2bin (scbuf.acdsc_reladdr.msf.frame));
- scbuf.acdsc_trk = bcd2bin (scbuf.acdsc_trk);
- }
- else
-#endif /* not STANDARD_ATAPI */
- {
- abs_lba = ntohl (scbuf.acdsc_absaddr.lba);
- rel_lba = ntohl (scbuf.acdsc_reladdr.lba);
- }
-
- if (subchnl.cdsc_format == CDROM_MSF)
- {
- lba_to_msf (abs_lba,
- &subchnl.cdsc_absaddr.msf.minute,
- &subchnl.cdsc_absaddr.msf.second,
- &subchnl.cdsc_absaddr.msf.frame);
- lba_to_msf (rel_lba,
- &subchnl.cdsc_reladdr.msf.minute,
- &subchnl.cdsc_reladdr.msf.second,
- &subchnl.cdsc_reladdr.msf.frame);
- }
- else
- {
- subchnl.cdsc_absaddr.lba = abs_lba;
- subchnl.cdsc_reladdr.lba = rel_lba;
- }
-
- subchnl.cdsc_audiostatus = scbuf.acdsc_audiostatus;
- subchnl.cdsc_ctrl = scbuf.acdsc_ctrl;
- subchnl.cdsc_trk = scbuf.acdsc_trk;
- subchnl.cdsc_ind = scbuf.acdsc_ind;
-
- memcpy_tofs ((void *) arg, &subchnl, sizeof (subchnl));
-
- return stat;
- }
-
- case CDROMVOLCTRL:
- {
- struct cdrom_volctrl volctrl;
- char buffer[24], mask[24];
- int stat;
-
- stat = verify_area (VERIFY_READ, (void *) arg, sizeof (volctrl));
- if (stat) return stat;
- memcpy_fromfs (&volctrl, (void *) arg, sizeof (volctrl));
-
- stat = cdrom_mode_sense (drive, 0x0e, 0, buffer, sizeof (buffer),NULL);
- if (stat) return stat;
- stat = cdrom_mode_sense (drive, 0x0e, 1, mask , sizeof (buffer),NULL);
- if (stat) return stat;
-
- buffer[1] = buffer[2] = 0;
-
- buffer[17] = volctrl.channel0 & mask[17];
- buffer[19] = volctrl.channel1 & mask[19];
- buffer[21] = volctrl.channel2 & mask[21];
- buffer[23] = volctrl.channel3 & mask[23];
-
- return cdrom_mode_select (drive, 0x0e, buffer, sizeof (buffer), NULL);
- }
-
- case CDROMVOLREAD:
- {
- struct cdrom_volctrl volctrl;
- char buffer[24];
- int stat;
-
- stat = verify_area (VERIFY_WRITE, (void *) arg, sizeof (volctrl));
- if (stat) return stat;
-
- stat = cdrom_mode_sense (drive, 0x0e, 0, buffer, sizeof (buffer), NULL);
- if (stat) return stat;
-
- volctrl.channel0 = buffer[17];
- volctrl.channel1 = buffer[19];
- volctrl.channel2 = buffer[21];
- volctrl.channel3 = buffer[23];
-
- memcpy_tofs ((void *) arg, &volctrl, sizeof (volctrl));
-
- return 0;
- }
-
- case CDROMMULTISESSION:
- {
- struct cdrom_multisession ms_info;
- struct atapi_toc *toc;
- int stat;
-
- stat = verify_area (VERIFY_READ, (void *)arg, sizeof (ms_info));
- if (stat) return stat;
- stat = verify_area (VERIFY_WRITE, (void *)arg, sizeof (ms_info));
- if (stat) return stat;
-
- memcpy_fromfs (&ms_info, (void *)arg, sizeof (ms_info));
-
- /* Make sure the TOC information is valid. */
- stat = cdrom_read_toc (drive, NULL);
- if (stat) return stat;
-
- toc = drive->cdrom_info.toc;
-
- if (ms_info.addr_format == CDROM_MSF)
- lba_to_msf (toc->last_session_lba,
- &ms_info.addr.msf.minute,
- &ms_info.addr.msf.second,
- &ms_info.addr.msf.frame);
-
- else if (ms_info.addr_format == CDROM_LBA)
- ms_info.addr.lba = toc->last_session_lba;
-
- else
- return -EINVAL;
-
- ms_info.xa_flag = toc->xa_flag;
-
- memcpy_tofs ((void *)arg, &ms_info, sizeof (ms_info));
-
- return 0;
- }
-
- /* Read 2352 byte blocks from audio tracks. */
- case CDROMREADAUDIO:
- {
- int stat, lba;
- struct atapi_toc *toc;
- struct cdrom_read_audio ra;
- char buf[CD_FRAMESIZE_RAW];
-
- /* Make sure the TOC is up to date. */
- stat = cdrom_read_toc (drive, NULL);
- if (stat) return stat;
-
- toc = drive->cdrom_info.toc;
-
- stat = verify_area (VERIFY_READ, (char *)arg, sizeof (ra));
- if (stat) return stat;
-
- memcpy_fromfs (&ra, (void *)arg, sizeof (ra));
-
- if (ra.nframes < 0 || ra.nframes > toc->capacity)
- return -EINVAL;
- else if (ra.nframes == 0)
- return 0;
-
- stat = verify_area (VERIFY_WRITE, (char *)ra.buf,
- ra.nframes * CD_FRAMESIZE_RAW);
- if (stat) return stat;
-
- if (ra.addr_format == CDROM_MSF)
- lba = msf_to_lba (ra.addr.msf.minute, ra.addr.msf.second,
- ra.addr.msf.frame);
-
- else if (ra.addr_format == CDROM_LBA)
- lba = ra.addr.lba;
-
- else
- return -EINVAL;
-
- if (lba < 0 || lba >= toc->capacity)
- return -EINVAL;
-
- while (ra.nframes > 0)
- {
- stat = cdrom_read_block (drive, 1, lba, buf,
- CD_FRAMESIZE_RAW, NULL);
- if (stat) return stat;
- memcpy_tofs (ra.buf, buf, CD_FRAMESIZE_RAW);
- ra.buf += CD_FRAMESIZE_RAW;
- --ra.nframes;
- ++lba;
- }
-
- return 0;
- }
-
- case CDROMREADMODE1:
- case CDROMREADMODE2:
- {
- struct cdrom_msf msf;
- int blocksize, format, stat, lba;
- struct atapi_toc *toc;
- char buf[CD_FRAMESIZE_RAW0];
-
- if (cmd == CDROMREADMODE1)
- {
- blocksize = CD_FRAMESIZE;
- format = 2;
- }
- else
- {
- blocksize = CD_FRAMESIZE_RAW0;
- format = 3;
- }
-
- stat = verify_area (VERIFY_READ, (char *)arg, sizeof (msf));
- if (stat) return stat;
- stat = verify_area (VERIFY_WRITE, (char *)arg, blocksize);
- if (stat) return stat;
-
- memcpy_fromfs (&msf, (void *)arg, sizeof (msf));
-
- lba = msf_to_lba (msf.cdmsf_min0, msf.cdmsf_sec0, msf.cdmsf_frame0);
-
- /* Make sure the TOC is up to date. */
- stat = cdrom_read_toc (drive, NULL);
- if (stat) return stat;
-
- toc = drive->cdrom_info.toc;
-
- if (lba < 0 || lba >= toc->capacity)
- return -EINVAL;
-
- stat = cdrom_read_block (drive, format, lba, buf, blocksize, NULL);
- if (stat) return stat;
-
- memcpy_tofs ((char *)arg, buf, blocksize);
- return 0;
- }
-
-#if 0 /* Doesn't work reliably yet. */
- case CDROMRESET:
- {
- struct request req;
- ide_init_drive_cmd (&req);
- req.cmd = RESET_DRIVE_COMMAND;
- return ide_do_drive_cmd (drive, &req, ide_wait);
- }
-#endif
-
-
-#ifdef TEST
- case 0x1234:
- {
- int stat;
- struct packet_command pc;
- int len, lena;
-
- memset (&pc, 0, sizeof (pc));
-
- stat = verify_area (VERIFY_READ, (void *) arg, sizeof (pc.c));
- if (stat) return stat;
- memcpy_fromfs (&pc.c, (void *) arg, sizeof (pc.c));
- arg += sizeof (pc.c);
-
- stat = verify_area (VERIFY_READ, (void *) arg, sizeof (len));
- if (stat) return stat;
- memcpy_fromfs (&len, (void *) arg , sizeof (len));
- arg += sizeof (len);
-
- if (len > 0) {
- stat = verify_area (VERIFY_WRITE, (void *) arg, len);
- if (stat) return stat;
- }
-
- lena = len;
- if (lena < 0) lena = 0;
-
- {
- char buf[lena];
- if (len > 0) {
- pc.buflen = len;
- pc.buffer = buf;
- }
-
- stat = cdrom_queue_packet_command (drive, &pc);
-
- if (len > 0)
- memcpy_tofs ((void *)arg, buf, len);
- }
-
- return stat;
- }
-#endif
-
- default:
- return -EPERM;
- }
-
-}
-
-
-
-/****************************************************************************
- * Other driver requests (open, close, check media change).
- */
-
-int ide_cdrom_check_media_change (ide_drive_t *drive)
-{
- int retval;
-
- (void) cdrom_check_status (drive, NULL);
-
- retval = CDROM_STATE_FLAGS (drive)->media_changed;
- CDROM_STATE_FLAGS (drive)->media_changed = 0;
-
- return retval;
-}
-
-
-int ide_cdrom_open (struct inode *ip, struct file *fp, ide_drive_t *drive)
-{
- /* no write access */
- if (fp->f_mode & 2)
- {
- --drive->usage;
- return -EROFS;
- }
-
- /* If this is the first open, check the drive status. */
- if (drive->usage == 1)
- {
- int stat;
- struct atapi_request_sense my_reqbuf;
- my_reqbuf.sense_key = 0;
-
- /* Get the drive status. */
- stat = cdrom_check_status (drive, &my_reqbuf);
-
- /* If the tray is open, try to close it. */
- if (stat && my_reqbuf.sense_key == NOT_READY)
- {
- cdrom_eject (drive, 1, &my_reqbuf);
- stat = cdrom_check_status (drive, &my_reqbuf);
- }
-
- /* Return an error if there are still problems. */
- if (stat && my_reqbuf.sense_key != UNIT_ATTENTION)
- {
- --drive->usage;
- return -ENXIO;
- }
-
- /* Now lock the door. */
- (void) cdrom_lockdoor (drive, 1, &my_reqbuf);
-
- /* And try to read the TOC information now. */
- (void) cdrom_read_toc (drive, &my_reqbuf);
- }
-
- return 0;
-}
-
-
-/*
- * Close down the device. Invalidate all cached blocks.
- */
-
-void ide_cdrom_release (struct inode *inode, struct file *file, ide_drive_t *drive)
-{
- if (drive->usage == 0)
- {
- invalidate_buffers (inode->i_rdev);
-
- /* Unlock the door. */
- (void) cdrom_lockdoor (drive, 0, NULL);
-
- /* Do an eject if we were requested to do so. */
- if (CDROM_STATE_FLAGS (drive)->eject_on_close)
- (void) cdrom_eject (drive, 0, NULL);
- }
-}
-
-
-
-/****************************************************************************
- * Device initialization.
- */
-
-void ide_cdrom_setup (ide_drive_t *drive)
-{
- blksize_size[HWIF(drive)->major][drive->select.b.unit << PARTN_BITS] = CD_FRAMESIZE;
-
- drive->special.all = 0;
- drive->ready_stat = 0;
-
- CDROM_STATE_FLAGS (drive)->media_changed = 0;
- CDROM_STATE_FLAGS (drive)->toc_valid = 0;
- CDROM_STATE_FLAGS (drive)->door_locked = 0;
-
- /* Turn this off by default, since many people don't like it. */
- CDROM_STATE_FLAGS (drive)->eject_on_close= 0;
-
-#if NO_DOOR_LOCKING
- CDROM_CONFIG_FLAGS (drive)->no_doorlock = 1;
-#else
- CDROM_CONFIG_FLAGS (drive)->no_doorlock = 0;
-#endif
-
- if (drive->id != NULL) {
- CDROM_CONFIG_FLAGS (drive)->drq_interrupt =
- ((drive->id->config & 0x0060) == 0x20);
- } else {
- CDROM_CONFIG_FLAGS (drive)->drq_interrupt = 0;
- }
-
-#if ! STANDARD_ATAPI
- CDROM_CONFIG_FLAGS (drive)->no_playaudio12 = 0;
- CDROM_CONFIG_FLAGS (drive)->old_readcd = 0;
- CDROM_CONFIG_FLAGS (drive)->no_lba_toc = 0;
- CDROM_CONFIG_FLAGS (drive)->playmsf_uses_bcd = 0;
- CDROM_CONFIG_FLAGS (drive)->vertos_lossage = 0;
-
- if (drive->id != NULL) {
- /* Accommodate some broken drives... */
- if (strcmp (drive->id->model, "CD220E") == 0 ||
- strcmp (drive->id->model, "CD") == 0) /* Creative Labs */
- CDROM_CONFIG_FLAGS (drive)->no_lba_toc = 1;
-
- else if (strcmp (drive->id->model, "TO-ICSLYAL") == 0 || /* Acer CD525E */
- strcmp (drive->id->model, "OTI-SCYLLA") == 0)
- CDROM_CONFIG_FLAGS (drive)->no_lba_toc = 1;
-
- /* I don't know who makes this.
- Francesco Messineo <sidera@ccii.unipi.it> says this one's broken too. */
- else if (strcmp (drive->id->model, "DCI-2S10") == 0)
- CDROM_CONFIG_FLAGS (drive)->no_lba_toc = 1;
-
- else if (strcmp (drive->id->model, "CDA26803I SE") == 0) /* Aztech */
- {
- CDROM_CONFIG_FLAGS (drive)->no_lba_toc = 1;
-
- /* This drive _also_ does not implement PLAYAUDIO12 correctly. */
- CDROM_CONFIG_FLAGS (drive)->no_playaudio12 = 1;
- }
-
- /* Vertos 300.
- There seem to be at least two different, incompatible versions
- of this drive floating around. Luckily, they appear to return their
- id strings with different byte orderings. */
- else if (strcmp (drive->id->model, "V003S0DS") == 0)
- {
- CDROM_CONFIG_FLAGS (drive)->vertos_lossage = 1;
- CDROM_CONFIG_FLAGS (drive)->playmsf_uses_bcd = 1;
- CDROM_CONFIG_FLAGS (drive)->no_lba_toc = 1;
- }
- else if (strcmp (drive->id->model, "0V300SSD") == 0 ||
- strcmp (drive->id->model, "V003M0DP") == 0)
- CDROM_CONFIG_FLAGS (drive)->no_lba_toc = 1;
-
- /* Vertos 400. */
- else if (strcmp (drive->id->model, "V004E0DT") == 0 ||
- strcmp (drive->id->model, "0V400ETD") == 0)
- CDROM_CONFIG_FLAGS (drive)->no_lba_toc = 1;
-
- else if ( strcmp (drive->id->model, "CD-ROM CDU55D") == 0) /*sony cdu55d */
- CDROM_CONFIG_FLAGS (drive)->no_playaudio12 = 1;
-
- else if (strcmp (drive->id->model, "CD-ROM CDU55E") == 0)
- CDROM_CONFIG_FLAGS (drive)->no_playaudio12 = 1;
- } /* drive-id != NULL */
-#endif /* not STANDARD_ATAPI */
-
- drive->cdrom_info.toc = NULL;
- drive->cdrom_info.sector_buffer = NULL;
- drive->cdrom_info.sector_buffered = 0;
- drive->cdrom_info.nsectors_buffered = 0;
-}
-
-
-
-/*
- * TODO:
- * CDROM_GET_UPC
- * CDROMRESET
- * Lock the door when a read request completes successfully and the
- * door is not already locked. Also try to reorganize to reduce
- * duplicated functionality between read and ioctl paths?
- * Establish interfaces for an IDE port driver, and break out the cdrom
- * code into a loadable module.
- * Support changers.
- * Write some real documentation.
- */
diff --git a/i386/i386at/gpl/linux/block/ide.c b/i386/i386at/gpl/linux/block/ide.c
deleted file mode 100644
index 4b7c5e95..00000000
--- a/i386/i386at/gpl/linux/block/ide.c
+++ /dev/null
@@ -1,3087 +0,0 @@
-/*
- * linux/drivers/block/ide.c Version 5.28 Feb 11, 1996
- *
- * Copyright (C) 1994-1996 Linus Torvalds & authors (see below)
- */
-#define _IDE_C /* needed by <linux/blk.h> */
-
-/*
- * This is the multiple IDE interface driver, as evolved from hd.c.
- * It supports up to four IDE interfaces, on one or more IRQs (usually 14 & 15).
- * There can be up to two drives per interface, as per the ATA-2 spec.
- *
- * Primary i/f: ide0: major=3; (hda) minor=0; (hdb) minor=64
- * Secondary i/f: ide1: major=22; (hdc or hd1a) minor=0; (hdd or hd1b) minor=64
- * Tertiary i/f: ide2: major=33; (hde) minor=0; (hdf) minor=64
- * Quaternary i/f: ide3: major=34; (hdg) minor=0; (hdh) minor=64
- *
- * It is easy to extend ide.c to handle more than four interfaces:
- *
- * Change the MAX_HWIFS constant in ide.h.
- *
- * Define some new major numbers (in major.h), and insert them into
- * the ide_hwif_to_major table in ide.c.
- *
- * Fill in the extra values for the new interfaces into the two tables
- * inside ide.c: default_io_base[] and default_irqs[].
- *
- * Create the new request handlers by cloning "do_ide3_request()"
- * for each new interface, and add them to the switch statement
- * in the ide_init() function in ide.c.
- *
- * Recompile, create the new /dev/ entries, and it will probably work.
- *
- * From hd.c:
- * |
- * | It traverses the request-list, using interrupts to jump between functions.
- * | As nearly all functions can be called within interrupts, we may not sleep.
- * | Special care is recommended. Have Fun!
- * |
- * | modified by Drew Eckhardt to check nr of hd's from the CMOS.
- * |
- * | Thanks to Branko Lankester, lankeste@fwi.uva.nl, who found a bug
- * | in the early extended-partition checks and added DM partitions.
- * |
- * | Early work on error handling by Mika Liljeberg (liljeber@cs.Helsinki.FI).
- * |
- * | IRQ-unmask, drive-id, multiple-mode, support for ">16 heads",
- * | and general streamlining by Mark Lord (mlord@bnr.ca).
- *
- * October, 1994 -- Complete line-by-line overhaul for linux 1.1.x, by:
- *
- * Mark Lord (mlord@bnr.ca) (IDE Perf.Pkg)
- * Delman Lee (delman@mipg.upenn.edu) ("Mr. atdisk2")
- * Petri Mattila (ptjmatti@kruuna.helsinki.fi) (EIDE stuff)
- * Scott Snyder (snyder@fnald0.fnal.gov) (ATAPI IDE cd-rom)
- *
- * Maintained by Mark Lord (mlord@bnr.ca): ide.c, ide.h, triton.c, hd.c, ..
- *
- * This was a rewrite of just about everything from hd.c, though some original
- * code is still sprinkled about. Think of it as a major evolution, with
- * inspiration from lots of linux users, esp. hamish@zot.apana.org.au
- *
- * Version 1.0 ALPHA initial code, primary i/f working okay
- * Version 1.3 BETA dual i/f on shared irq tested & working!
- * Version 1.4 BETA added auto probing for irq(s)
- * Version 1.5 BETA added ALPHA (untested) support for IDE cd-roms,
- * ...
- * Version 3.5 correct the bios_cyl field if it's too small
- * (linux 1.1.76) (to help fdisk with brain-dead BIOSs)
- * Version 3.6 cosmetic corrections to comments and stuff
- * (linux 1.1.77) reorganise probing code to make it understandable
- * added halfway retry to probing for drive identification
- * added "hdx=noprobe" command line option
- * allow setting multmode even when identification fails
- * Version 3.7 move set_geometry=1 from do_identify() to ide_init()
- * increase DRQ_WAIT to eliminate nuisance messages
- * wait for DRQ_STAT instead of DATA_READY during probing
- * (courtesy of Gary Thomas gary@efland.UU.NET)
- * Version 3.8 fixed byte-swapping for confused Mitsumi cdrom drives
- * update of ide-cd.c from Scott, allows blocksize=1024
- * cdrom probe fixes, inspired by jprang@uni-duisburg.de
- * Version 3.9 don't use LBA if lba_capacity looks funny
- * correct the drive capacity calculations
- * fix probing for old Seagates without IDE_ALTSTATUS_REG
- * fix byte-ordering for some NEC cdrom drives
- * Version 3.10 disable multiple mode by default; was causing trouble
- * Version 3.11 fix mis-identification of old WD disks as cdroms
- * Version 3,12 simplify logic for selecting initial mult_count
- * (fixes problems with buggy WD drives)
- * Version 3.13 remove excess "multiple mode disabled" messages
- * Version 3.14 fix ide_error() handling of BUSY_STAT
- * fix byte-swapped cdrom strings (again.. arghh!)
- * ignore INDEX bit when checking the ALTSTATUS reg
- * Version 3.15 add SINGLE_THREADED flag for use with dual-CMD i/f
- * ignore WRERR_STAT for non-write operations
- * added vlb_sync support for DC-2000A & others,
- * (incl. some Promise chips), courtesy of Frank Gockel
- * Version 3.16 convert vlb_32bit and vlb_sync into runtime flags
- * add ioctls to get/set VLB flags (HDIO_[SG]ET_CHIPSET)
- * rename SINGLE_THREADED to SUPPORT_SERIALIZE,
- * add boot flag to "serialize" operation for CMD i/f
- * add optional support for DTC2278 interfaces,
- * courtesy of andy@cercle.cts.com (Dyan Wile).
- * add boot flag to enable "dtc2278" probe
- * add probe to avoid EATA (SCSI) interfaces,
- * courtesy of neuffer@goofy.zdv.uni-mainz.de.
- * Version 4.00 tidy up verify_area() calls - heiko@colossus.escape.de
- * add flag to ignore WRERR_STAT for some drives
- * courtesy of David.H.West@um.cc.umich.edu
- * assembly syntax tweak to vlb_sync
- * removeable drive support from scuba@cs.tu-berlin.de
- * add transparent support for DiskManager-6.0x "Dynamic
- * Disk Overlay" (DDO), most of this is in genhd.c
- * eliminate "multiple mode turned off" message at boot
- * Version 4.10 fix bug in ioctl for "hdparm -c3"
- * fix DM6:DDO support -- now works with LILO, fdisk, ...
- * don't treat some naughty WD drives as removeable
- * Version 4.11 updated DM6 support using info provided by OnTrack
- * Version 5.00 major overhaul, multmode setting fixed, vlb_sync fixed
- * added support for 3rd/4th/alternative IDE ports
- * created ide.h; ide-cd.c now compiles separate from ide.c
- * hopefully fixed infinite "unexpected_intr" from cdroms
- * zillions of other changes and restructuring
- * somehow reduced overall memory usage by several kB
- * probably slowed things down slightly, but worth it
- * Version 5.01 AT LAST!! Finally understood why "unexpected_intr"
- * was happening at various times/places: whenever the
- * ide-interface's ctl_port was used to "mask" the irq,
- * it also would trigger an edge in the process of masking
- * which would result in a self-inflicted interrupt!!
- * (such a stupid way to build a hardware interrupt mask).
- * This is now fixed (after a year of head-scratching).
- * Version 5.02 got rid of need for {enable,disable}_irq_list()
- * Version 5.03 tune-ups, comments, remove "busy wait" from drive resets
- * removed PROBE_FOR_IRQS option -- no longer needed
- * OOOPS! fixed "bad access" bug for 2nd drive on an i/f
- * Version 5.04 changed "ira %d" to "irq %d" in DEBUG message
- * added more comments, cleaned up unexpected_intr()
- * OOOPS! fixed null pointer problem in ide reset code
- * added autodetect for Triton chipset -- no effect yet
- * Version 5.05 OOOPS! fixed bug in revalidate_disk()
- * OOOPS! fixed bug in ide_do_request()
- * added ATAPI reset sequence for cdroms
- * Version 5.10 added Bus-Mastered DMA support for Triton Chipset
- * some (mostly) cosmetic changes
- * Version 5.11 added ht6560b support by malafoss@snakemail.hut.fi
- * reworked PCI scanning code
- * added automatic RZ1000 detection/support
- * added automatic PCI CMD640 detection/support
- * added option for VLB CMD640 support
- * tweaked probe to find cdrom on hdb with disks on hda,hdc
- * Version 5.12 some performance tuning
- * added message to alert user to bad /dev/hd[cd] entries
- * OOOPS! fixed bug in atapi reset
- * driver now forces "serialize" again for all cmd640 chips
- * noticed REALLY_SLOW_IO had no effect, moved it to ide.c
- * made do_drive_cmd() into public ide_do_drive_cmd()
- * Version 5.13 fixed typo ('B'), thanks to houston@boyd.geog.mcgill.ca
- * fixed ht6560b support
- * Version 5.13b (sss) fix problem in calling ide_cdrom_setup()
- * don't bother invalidating nonexistent partitions
- * Version 5.14 fixes to cmd640 support.. maybe it works now(?)
- * added & tested full EZ-DRIVE support -- don't use LILO!
- * don't enable 2nd CMD640 PCI port during init - conflict
- * Version 5.15 bug fix in init_cmd640_vlb()
- * bug fix in interrupt sharing code
- * Version 5.16 ugh.. fix "serialize" support, broken in 5.15
- * remove "Huh?" from cmd640 code
- * added qd6580 interface speed select from Colten Edwards
- * Version 5.17 kludge around bug in BIOS32 on Intel triton motherboards
- * Version 5.18 new CMD640 code, moved to cmd640.c, #include'd for now
- * new UMC8672 code, moved to umc8672.c, #include'd for now
- * disallow turning on DMA when h/w not capable of DMA
- * Version 5.19 fix potential infinite timeout on resets
- * extend reset poll into a general purpose polling scheme
- * add atapi tape drive support from Gadi Oxman
- * simplify exit from _intr routines -- no IDE_DO_REQUEST
- * Version 5.20 leave current rq on blkdev request list during I/O
- * generalized ide_do_drive_cmd() for tape/cdrom driver use
- * Version 5.21 fix nasty cdrom/tape bug (ide_preempt was messed up)
- * Version 5.22 fix ide_xlate_1024() to work with/without drive->id
- * Version 5.23 miscellaneous touch-ups
- * Version 5.24 fix #if's for SUPPORT_CMD640
- * Version 5.25 more touch-ups, fix cdrom resets, ...
- * cmd640.c now configs/compiles separate from ide.c
- * Version 5.26 keep_settings now maintains the using_dma flag
- * fix [EZD] remap message to only output at boot time
- * fix "bad /dev/ entry" message to say hdc, not hdc0
- * fix ide_xlate_1024() to respect user specified CHS
- * use CHS from partn table if it looks translated
- * re-merged flags chipset,vlb_32bit,vlb_sync into io_32bit
- * keep track of interface chipset type, when known
- * add generic PIO mode "tuneproc" mechanism
- * fix cmd640_vlb option
- * fix ht6560b support (was completely broken)
- * umc8672.c now configures/compiles separate from ide.c
- * move dtc2278 support to dtc2278.c
- * move ht6560b support to ht6560b.c
- * move qd6580 support to qd6580.c
- * add ali14xx support in ali14xx.c
- * Version 5.27 add [no]autotune parameters to help cmd640
- * move rz1000 support to rz1000.c
- * Version 5.28 #include "ide_modes.h"
- * fix disallow_unmask: now per-interface "no_unmask" bit
- * force io_32bit to be the same on drive pairs of dtc2278
- * improved IDE tape error handling, and tape DMA support
- * bugfix in ide_do_drive_cmd() for cdroms + serialize
- *
- * Some additional driver compile-time options are in ide.h
- *
- * To do, in likely order of completion:
- * - add Promise DC4030VL support from peterd@pnd-pc.demon.co.uk
- * - modify kernel to obtain BIOS geometry for drives on 2nd/3rd/4th i/f
-*/
-
-#if defined (MACH) && !defined (LINUX_IDE_DEBUG)
-#undef DEBUG
-#endif
-
-#undef REALLY_SLOW_IO /* most systems can safely undef this */
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/major.h>
-#include <linux/blkdev.h>
-#include <linux/errno.h>
-#include <linux/hdreg.h>
-#include <linux/genhd.h>
-#include <linux/malloc.h>
-
-#include <asm/byteorder.h>
-#include <asm/irq.h>
-#include <asm/segment.h>
-#include <asm/io.h>
-
-#ifdef CONFIG_PCI
-#include <linux/bios32.h>
-#include <linux/pci.h>
-#endif /* CONFIG_PCI */
-
-#include "ide.h"
-#include "ide_modes.h"
-
-static ide_hwgroup_t *irq_to_hwgroup [NR_IRQS];
-static const byte ide_hwif_to_major[MAX_HWIFS] = {IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR};
-
-static const unsigned short default_io_base[MAX_HWIFS] = {0x1f0, 0x170, 0x1e8, 0x168};
-static const byte default_irqs[MAX_HWIFS] = {14, 15, 11, 10};
-
-#if (DISK_RECOVERY_TIME > 0)
-/*
- * For really screwy hardware (hey, at least it *can* be used with Linux)
- * we can enforce a minimum delay time between successive operations.
- */
-static unsigned long read_timer(void)
-{
- unsigned long t, flags;
- int i;
-
- save_flags(flags);
- cli();
- t = jiffies * 11932;
- outb_p(0, 0x43);
- i = inb_p(0x40);
- i |= inb(0x40) << 8;
- restore_flags(flags);
- return (t - i);
-}
-
-static void set_recovery_timer (ide_hwif_t *hwif)
-{
- hwif->last_time = read_timer();
-}
-#define SET_RECOVERY_TIMER(drive) set_recovery_timer (drive)
-
-#else
-
-#define SET_RECOVERY_TIMER(drive)
-
-#endif /* DISK_RECOVERY_TIME */
-
-/*
- * init_ide_data() sets reasonable default values into all fields
- * of all instances of the hwifs and drives, but only on the first call.
- * Subsequent calls have no effect (they don't wipe out anything).
- *
- * This routine is normally called at driver initialization time,
- * but may also be called MUCH earlier during kernel "command-line"
- * parameter processing. As such, we cannot depend on any other parts
- * of the kernel (such as memory allocation) to be functioning yet.
- *
- * This is too bad, as otherwise we could dynamically allocate the
- * ide_drive_t structs as needed, rather than always consuming memory
- * for the max possible number (MAX_HWIFS * MAX_DRIVES) of them.
- */
-#define MAGIC_COOKIE 0x12345678
-static void init_ide_data (void)
-{
- byte *p;
- unsigned int h, unit;
- static unsigned long magic_cookie = MAGIC_COOKIE;
-
- if (magic_cookie != MAGIC_COOKIE)
- return; /* already initialized */
- magic_cookie = 0;
-
- for (h = 0; h < NR_IRQS; ++h)
- irq_to_hwgroup[h] = NULL;
-
- /* bulk initialize hwif & drive info with zeros */
- p = ((byte *) ide_hwifs) + sizeof(ide_hwifs);
- do {
- *--p = 0;
- } while (p > (byte *) ide_hwifs);
-
- /* fill in any non-zero initial values */
- for (h = 0; h < MAX_HWIFS; ++h) {
- ide_hwif_t *hwif = &ide_hwifs[h];
-
- hwif->index = h;
- hwif->noprobe = (h > 1);
- hwif->io_base = default_io_base[h];
- hwif->ctl_port = hwif->io_base ? hwif->io_base+0x206 : 0x000;
-#ifdef CONFIG_BLK_DEV_HD
- if (hwif->io_base == HD_DATA)
- hwif->noprobe = 1; /* may be overriden by ide_setup() */
-#endif /* CONFIG_BLK_DEV_HD */
- hwif->major = ide_hwif_to_major[h];
- hwif->name[0] = 'i';
- hwif->name[1] = 'd';
- hwif->name[2] = 'e';
- hwif->name[3] = '0' + h;
-#ifdef CONFIG_BLK_DEV_IDETAPE
- hwif->tape_drive = NULL;
-#endif /* CONFIG_BLK_DEV_IDETAPE */
- for (unit = 0; unit < MAX_DRIVES; ++unit) {
- ide_drive_t *drive = &hwif->drives[unit];
-
- drive->select.all = (unit<<4)|0xa0;
- drive->hwif = hwif;
- drive->ctl = 0x08;
- drive->ready_stat = READY_STAT;
- drive->bad_wstat = BAD_W_STAT;
- drive->special.b.recalibrate = 1;
- drive->special.b.set_geometry = 1;
- drive->name[0] = 'h';
- drive->name[1] = 'd';
- drive->name[2] = 'a' + (h * MAX_DRIVES) + unit;
- }
- }
-}
-
-#if SUPPORT_VLB_SYNC
-/*
- * Some localbus EIDE interfaces require a special access sequence
- * when using 32-bit I/O instructions to transfer data. We call this
- * the "vlb_sync" sequence, which consists of three successive reads
- * of the sector count register location, with interrupts disabled
- * to ensure that the reads all happen together.
- */
-static inline void do_vlb_sync (unsigned short port) {
- (void) inb (port);
- (void) inb (port);
- (void) inb (port);
-}
-#endif /* SUPPORT_VLB_SYNC */
-
-/*
- * This is used for most PIO data transfers *from* the IDE interface
- */
-void ide_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
-{
- unsigned short io_base = HWIF(drive)->io_base;
- unsigned short data_reg = io_base+IDE_DATA_OFFSET;
- byte io_32bit = drive->io_32bit;
-
- if (io_32bit) {
-#if SUPPORT_VLB_SYNC
- if (io_32bit & 2) {
- cli();
- do_vlb_sync(io_base+IDE_NSECTOR_OFFSET);
- insl(data_reg, buffer, wcount);
- if (drive->unmask)
- sti();
- } else
-#endif /* SUPPORT_VLB_SYNC */
- insl(data_reg, buffer, wcount);
- } else
- insw(data_reg, buffer, wcount<<1);
-}
-
-/*
- * This is used for most PIO data transfers *to* the IDE interface
- */
-void ide_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
-{
- unsigned short io_base = HWIF(drive)->io_base;
- unsigned short data_reg = io_base+IDE_DATA_OFFSET;
- byte io_32bit = drive->io_32bit;
-
- if (io_32bit) {
-#if SUPPORT_VLB_SYNC
- if (io_32bit & 2) {
- cli();
- do_vlb_sync(io_base+IDE_NSECTOR_OFFSET);
- outsl(data_reg, buffer, wcount);
- if (drive->unmask)
- sti();
- } else
-#endif /* SUPPORT_VLB_SYNC */
- outsl(data_reg, buffer, wcount);
- } else
- outsw(data_reg, buffer, wcount<<1);
-}
-
-/*
- * This should get invoked any time we exit the driver to
- * wait for an interrupt response from a drive. handler() points
- * at the appropriate code to handle the next interrupt, and a
- * timer is started to prevent us from waiting forever in case
- * something goes wrong (see the timer_expiry() handler later on).
- */
-void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, unsigned int timeout)
-{
- ide_hwgroup_t *hwgroup = HWGROUP(drive);
-#ifdef DEBUG
- if (hwgroup->handler != NULL) {
- printk("%s: ide_set_handler: handler not null; old=%p, new=%p\n",
- drive->name, hwgroup->handler, handler);
- }
-#endif
- hwgroup->handler = handler;
- hwgroup->timer.expires = jiffies + timeout;
- add_timer(&(hwgroup->timer));
-}
-
-/*
- * lba_capacity_is_ok() performs a sanity check on the claimed "lba_capacity"
- * value for this drive (from its reported identification information).
- *
- * Returns: 1 if lba_capacity looks sensible
- * 0 otherwise
- */
-static int lba_capacity_is_ok (struct hd_driveid *id)
-{
- unsigned long lba_sects = id->lba_capacity;
- unsigned long chs_sects = id->cyls * id->heads * id->sectors;
- unsigned long _10_percent = chs_sects / 10;
-
- /* perform a rough sanity check on lba_sects: within 10% is "okay" */
- if ((lba_sects - chs_sects) < _10_percent)
- return 1; /* lba_capacity is good */
-
- /* some drives have the word order reversed */
- lba_sects = (lba_sects << 16) | (lba_sects >> 16);
- if ((lba_sects - chs_sects) < _10_percent) {
- id->lba_capacity = lba_sects; /* fix it */
- return 1; /* lba_capacity is (now) good */
- }
- return 0; /* lba_capacity value is bad */
-}
-
-/*
- * current_capacity() returns the capacity (in sectors) of a drive
- * according to its current geometry/LBA settings.
- */
-static unsigned long current_capacity (ide_drive_t *drive)
-{
- struct hd_driveid *id = drive->id;
- unsigned long capacity;
-
- if (!drive->present)
- return 0;
- if (drive->media != ide_disk)
- return 0x7fffffff; /* cdrom or tape */
- /* Determine capacity, and use LBA if the drive properly supports it */
- if (id != NULL && (id->capability & 2) && lba_capacity_is_ok(id)) {
- drive->select.b.lba = 1;
- capacity = id->lba_capacity;
- } else {
- drive->select.b.lba = 0;
- capacity = drive->cyl * drive->head * drive->sect;
- }
- return (capacity - drive->sect0);
-}
-
-/*
- * ide_geninit() is called exactly *once* for each major, from genhd.c,
- * at the beginning of the initial partition check for the drives.
- */
-static void ide_geninit (struct gendisk *gd)
-{
- unsigned int unit;
- ide_hwif_t *hwif = gd->real_devices;
-
- for (unit = 0; unit < gd->nr_real; ++unit) {
- ide_drive_t *drive = &hwif->drives[unit];
-#ifdef CONFIG_BLK_DEV_IDECD
- if (drive->present && drive->media == ide_cdrom)
- ide_cdrom_setup(drive);
-#endif /* CONFIG_BLK_DEV_IDECD */
-#ifdef CONFIG_BLK_DEV_IDETAPE
- if (drive->present && drive->media == ide_tape)
- idetape_setup(drive);
-#endif /* CONFIG_BLK_DEV_IDETAPE */
- drive->part[0].nr_sects = current_capacity(drive);
- if (!drive->present || drive->media != ide_disk) {
- drive->part[0].start_sect = -1; /* skip partition check */
- }
- }
- /*
- * The partition check in genhd.c needs this string to identify
- * our minor devices by name for display purposes.
- * Note that doing this will prevent us from working correctly
- * if ever called a second time for this major (never happens).
- */
- gd->real_devices = hwif->drives[0].name; /* name of first drive */
-}
-
-/*
- * init_gendisk() (as opposed to ide_geninit) is called for each major device,
- * after probing for drives, to allocate partition tables and other data
- * structures needed for the routines in genhd.c. ide_geninit() gets called
- * somewhat later, during the partition check.
- */
-static void init_gendisk (ide_hwif_t *hwif)
-{
- struct gendisk *gd;
- unsigned int unit, units, minors;
- int *bs;
-
- /* figure out maximum drive number on the interface */
- for (units = MAX_DRIVES; units > 0; --units) {
- if (hwif->drives[units-1].present)
- break;
- }
- minors = units * (1<<PARTN_BITS);
- gd = kmalloc (sizeof(struct gendisk), GFP_KERNEL);
- gd->sizes = kmalloc (minors * sizeof(int), GFP_KERNEL);
- gd->part = kmalloc (minors * sizeof(struct hd_struct), GFP_KERNEL);
- bs = kmalloc (minors*sizeof(int), GFP_KERNEL);
-
- /* cdroms and msdos f/s are examples of non-1024 blocksizes */
- blksize_size[hwif->major] = bs;
- for (unit = 0; unit < minors; ++unit)
- *bs++ = BLOCK_SIZE;
-
- for (unit = 0; unit < units; ++unit)
- hwif->drives[unit].part = &gd->part[unit << PARTN_BITS];
-
- gd->major = hwif->major; /* our major device number */
- gd->major_name = IDE_MAJOR_NAME; /* treated special in genhd.c */
- gd->minor_shift = PARTN_BITS; /* num bits for partitions */
- gd->max_p = 1<<PARTN_BITS; /* 1 + max partitions / drive */
- gd->max_nr = units; /* max num real drives */
- gd->nr_real = units; /* current num real drives */
- gd->init = ide_geninit; /* initialization function */
- gd->real_devices= hwif; /* ptr to internal data */
-
- gd->next = gendisk_head; /* link new major into list */
- hwif->gd = gendisk_head = gd;
-}
-
-static void do_reset1 (ide_drive_t *, int); /* needed below */
-
-#ifdef CONFIG_BLK_DEV_IDEATAPI
-/*
- * atapi_reset_pollfunc() gets invoked to poll the interface for completion every 50ms
- * during an atapi drive reset operation. If the drive has not yet responded,
- * and we have not yet hit our maximum waiting time, then the timer is restarted
- * for another 50ms.
- */
-static void atapi_reset_pollfunc (ide_drive_t *drive)
-{
- ide_hwgroup_t *hwgroup = HWGROUP(drive);
- byte stat;
-
- OUT_BYTE (drive->select.all, IDE_SELECT_REG);
- udelay (10);
-
- if (OK_STAT(stat=GET_STAT(), 0, BUSY_STAT)) {
- printk("%s: ATAPI reset complete\n", drive->name);
- } else {
- if (jiffies < hwgroup->poll_timeout) {
- ide_set_handler (drive, &atapi_reset_pollfunc, HZ/20);
- return; /* continue polling */
- }
- hwgroup->poll_timeout = 0; /* end of polling */
- printk("%s: ATAPI reset timed-out, status=0x%02x\n", drive->name, stat);
- do_reset1 (drive, 1); /* do it the old fashioned way */
- }
- hwgroup->poll_timeout = 0; /* done polling */
-}
-#endif /* CONFIG_BLK_DEV_IDEATAPI */
-
-/*
- * reset_pollfunc() gets invoked to poll the interface for completion every 50ms
- * during an ide reset operation. If the drives have not yet responded,
- * and we have not yet hit our maximum waiting time, then the timer is restarted
- * for another 50ms.
- */
-static void reset_pollfunc (ide_drive_t *drive)
-{
- ide_hwgroup_t *hwgroup = HWGROUP(drive);
- ide_hwif_t *hwif = HWIF(drive);
- byte tmp;
-
- if (!OK_STAT(tmp=GET_STAT(), 0, BUSY_STAT)) {
- if (jiffies < hwgroup->poll_timeout) {
- ide_set_handler (drive, &reset_pollfunc, HZ/20);
- return; /* continue polling */
- }
- printk("%s: reset timed-out, status=0x%02x\n", hwif->name, tmp);
- } else {
- printk("%s: reset: ", hwif->name);
- if ((tmp = GET_ERR()) == 1)
- printk("success\n");
- else {
- printk("master: ");
- switch (tmp & 0x7f) {
- case 1: printk("passed");
- break;
- case 2: printk("formatter device error");
- break;
- case 3: printk("sector buffer error");
- break;
- case 4: printk("ECC circuitry error");
- break;
- case 5: printk("controlling MPU error");
- break;
- default:printk("error (0x%02x?)", tmp);
- }
- if (tmp & 0x80)
- printk("; slave: failed");
- printk("\n");
- }
- }
- hwgroup->poll_timeout = 0; /* done polling */
-}
-
-/*
- * do_reset1() attempts to recover a confused drive by resetting it.
- * Unfortunately, resetting a disk drive actually resets all devices on
- * the same interface, so it can really be thought of as resetting the
- * interface rather than resetting the drive.
- *
- * ATAPI devices have their own reset mechanism which allows them to be
- * individually reset without clobbering other devices on the same interface.
- *
- * Unfortunately, the IDE interface does not generate an interrupt to let
- * us know when the reset operation has finished, so we must poll for this.
- * Equally poor, though, is the fact that this may a very long time to complete,
- * (up to 30 seconds worstcase). So, instead of busy-waiting here for it,
- * we set a timer to poll at 50ms intervals.
- */
-static void do_reset1 (ide_drive_t *drive, int do_not_try_atapi)
-{
- unsigned int unit;
- unsigned long flags;
- ide_hwif_t *hwif = HWIF(drive);
- ide_hwgroup_t *hwgroup = HWGROUP(drive);
-
- save_flags(flags);
- cli(); /* Why ? */
-
-#ifdef CONFIG_BLK_DEV_IDEATAPI
- /* For an ATAPI device, first try an ATAPI SRST. */
- if (drive->media != ide_disk) {
- if (!do_not_try_atapi) {
- if (!drive->keep_settings)
- drive->unmask = 0;
- OUT_BYTE (drive->select.all, IDE_SELECT_REG);
- udelay (20);
- OUT_BYTE (WIN_SRST, IDE_COMMAND_REG);
- hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
- ide_set_handler (drive, &atapi_reset_pollfunc, HZ/20);
- restore_flags (flags);
- return;
- }
- }
-#endif /* CONFIG_BLK_DEV_IDEATAPI */
-
- /*
- * First, reset any device state data we were maintaining
- * for any of the drives on this interface.
- */
- for (unit = 0; unit < MAX_DRIVES; ++unit) {
- ide_drive_t *rdrive = &hwif->drives[unit];
- rdrive->special.all = 0;
- rdrive->special.b.set_geometry = 1;
- rdrive->special.b.recalibrate = 1;
- if (OK_TO_RESET_CONTROLLER)
- rdrive->mult_count = 0;
- if (!rdrive->keep_settings) {
- rdrive->using_dma = 0;
- rdrive->mult_req = 0;
- rdrive->unmask = 0;
- }
- if (rdrive->mult_req != rdrive->mult_count)
- rdrive->special.b.set_multmode = 1;
- }
-
-#if OK_TO_RESET_CONTROLLER
- /*
- * Note that we also set nIEN while resetting the device,
- * to mask unwanted interrupts from the interface during the reset.
- * However, due to the design of PC hardware, this will cause an
- * immediate interrupt due to the edge transition it produces.
- * This single interrupt gives us a "fast poll" for drives that
- * recover from reset very quickly, saving us the first 50ms wait time.
- */
- OUT_BYTE(drive->ctl|6,IDE_CONTROL_REG); /* set SRST and nIEN */
- udelay(5); /* more than enough time */
- OUT_BYTE(drive->ctl|2,IDE_CONTROL_REG); /* clear SRST, leave nIEN */
- hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
- ide_set_handler (drive, &reset_pollfunc, HZ/20);
-#endif /* OK_TO_RESET_CONTROLLER */
-
- restore_flags (flags);
-}
-
-/*
- * ide_do_reset() is the entry point to the drive/interface reset code.
- */
-void ide_do_reset (ide_drive_t *drive)
-{
- do_reset1 (drive, 0);
-#ifdef CONFIG_BLK_DEV_IDETAPE
- if (drive->media == ide_tape)
- drive->tape.reset_issued=1;
-#endif /* CONFIG_BLK_DEV_IDETAPE */
-}
-
-/*
- * Clean up after success/failure of an explicit drive cmd
- */
-void ide_end_drive_cmd (ide_drive_t *drive, byte stat, byte err)
-{
- unsigned long flags;
- struct request *rq = HWGROUP(drive)->rq;
-
- if (rq->cmd == IDE_DRIVE_CMD) {
- byte *args = (byte *) rq->buffer;
- rq->errors = !OK_STAT(stat,READY_STAT,BAD_STAT);
- if (args) {
- args[0] = stat;
- args[1] = err;
- args[2] = IN_BYTE(IDE_NSECTOR_REG);
- }
- }
- save_flags(flags);
- cli();
- blk_dev[MAJOR(rq->rq_dev)].current_request = rq->next;
- HWGROUP(drive)->rq = NULL;
- rq->rq_status = RQ_INACTIVE;
- if (rq->sem != NULL)
- up(rq->sem);
- restore_flags(flags);
-}
-
-/*
- * Error reporting, in human readable form (luxurious, but a memory hog).
- */
-byte ide_dump_status (ide_drive_t *drive, const char *msg, byte stat)
-{
- unsigned long flags;
- byte err = 0;
-
- save_flags (flags);
- sti();
- printk("%s: %s: status=0x%02x", drive->name, msg, stat);
-#if FANCY_STATUS_DUMPS
- if (drive->media == ide_disk) {
- printk(" { ");
- if (stat & BUSY_STAT)
- printk("Busy ");
- else {
- if (stat & READY_STAT) printk("DriveReady ");
- if (stat & WRERR_STAT) printk("DeviceFault ");
- if (stat & SEEK_STAT) printk("SeekComplete ");
- if (stat & DRQ_STAT) printk("DataRequest ");
- if (stat & ECC_STAT) printk("CorrectedError ");
- if (stat & INDEX_STAT) printk("Index ");
- if (stat & ERR_STAT) printk("Error ");
- }
- printk("}");
- }
-#endif /* FANCY_STATUS_DUMPS */
- printk("\n");
- if ((stat & (BUSY_STAT|ERR_STAT)) == ERR_STAT) {
- err = GET_ERR();
- printk("%s: %s: error=0x%02x", drive->name, msg, err);
-#if FANCY_STATUS_DUMPS
- if (drive->media == ide_disk) {
- printk(" { ");
- if (err & BBD_ERR) printk("BadSector ");
- if (err & ECC_ERR) printk("UncorrectableError ");
- if (err & ID_ERR) printk("SectorIdNotFound ");
- if (err & ABRT_ERR) printk("DriveStatusError ");
- if (err & TRK0_ERR) printk("TrackZeroNotFound ");
- if (err & MARK_ERR) printk("AddrMarkNotFound ");
- printk("}");
- if (err & (BBD_ERR|ECC_ERR|ID_ERR|MARK_ERR)) {
- byte cur = IN_BYTE(IDE_SELECT_REG);
- if (cur & 0x40) { /* using LBA? */
- printk(", LBAsect=%ld", (unsigned long)
- ((cur&0xf)<<24)
- |(IN_BYTE(IDE_HCYL_REG)<<16)
- |(IN_BYTE(IDE_LCYL_REG)<<8)
- | IN_BYTE(IDE_SECTOR_REG));
- } else {
- printk(", CHS=%d/%d/%d",
- (IN_BYTE(IDE_HCYL_REG)<<8) +
- IN_BYTE(IDE_LCYL_REG),
- cur & 0xf,
- IN_BYTE(IDE_SECTOR_REG));
- }
- if (HWGROUP(drive)->rq)
- printk(", sector=%ld", HWGROUP(drive)->rq->sector);
- }
- }
-#endif /* FANCY_STATUS_DUMPS */
- printk("\n");
- }
- restore_flags (flags);
- return err;
-}
-
-/*
- * try_to_flush_leftover_data() is invoked in response to a drive
- * unexpectedly having its DRQ_STAT bit set. As an alternative to
- * resetting the drive, this routine tries to clear the condition
- * by read a sector's worth of data from the drive. Of course,
- * this may not help if the drive is *waiting* for data from *us*.
- */
-static void try_to_flush_leftover_data (ide_drive_t *drive)
-{
- int i = (drive->mult_count ? drive->mult_count : 1) * SECTOR_WORDS;
-
- while (i > 0) {
- unsigned long buffer[16];
- unsigned int wcount = (i > 16) ? 16 : i;
- i -= wcount;
- ide_input_data (drive, buffer, wcount);
- }
-}
-
-/*
- * ide_error() takes action based on the error returned by the controller.
- */
-void ide_error (ide_drive_t *drive, const char *msg, byte stat)
-{
- struct request *rq;
- byte err;
-
- err = ide_dump_status(drive, msg, stat);
- if ((rq = HWGROUP(drive)->rq) == NULL || drive == NULL)
- return;
- /* retry only "normal" I/O: */
- if (rq->cmd == IDE_DRIVE_CMD || (rq->cmd != READ && rq->cmd != WRITE && drive->media == ide_disk))
- {
- rq->errors = 1;
- ide_end_drive_cmd(drive, stat, err);
- return;
- }
- if (stat & BUSY_STAT) { /* other bits are useless when BUSY */
- rq->errors |= ERROR_RESET;
- } else {
- if (drive->media == ide_disk && (stat & ERR_STAT)) {
- /* err has different meaning on cdrom and tape */
- if (err & (BBD_ERR | ECC_ERR)) /* retries won't help these */
- rq->errors = ERROR_MAX;
- else if (err & TRK0_ERR) /* help it find track zero */
- rq->errors |= ERROR_RECAL;
- }
- if ((stat & DRQ_STAT) && rq->cmd != WRITE)
- try_to_flush_leftover_data(drive);
- }
- if (GET_STAT() & (BUSY_STAT|DRQ_STAT))
- rq->errors |= ERROR_RESET; /* Mmmm.. timing problem */
-
- if (rq->errors >= ERROR_MAX) {
-#ifdef CONFIG_BLK_DEV_IDETAPE
- if (drive->media == ide_tape) {
- rq->errors = 0;
- idetape_end_request(0, HWGROUP(drive));
- }
- else
-#endif /* CONFIG_BLK_DEV_IDETAPE */
- ide_end_request(0, HWGROUP(drive));
- }
- else {
- if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
- ++rq->errors;
- ide_do_reset(drive);
- return;
- } else if ((rq->errors & ERROR_RECAL) == ERROR_RECAL)
- drive->special.b.recalibrate = 1;
- ++rq->errors;
- }
-}
-
-/*
- * read_intr() is the handler for disk read/multread interrupts
- */
-static void read_intr (ide_drive_t *drive)
-{
- byte stat;
- int i;
- unsigned int msect, nsect;
- struct request *rq;
-
- if (!OK_STAT(stat=GET_STAT(),DATA_READY,BAD_R_STAT)) {
- ide_error(drive, "read_intr", stat);
- return;
- }
- msect = drive->mult_count;
-read_next:
- rq = HWGROUP(drive)->rq;
- if (msect) {
- if ((nsect = rq->current_nr_sectors) > msect)
- nsect = msect;
- msect -= nsect;
- } else
- nsect = 1;
- ide_input_data(drive, rq->buffer, nsect * SECTOR_WORDS);
-#ifdef DEBUG
- printk("%s: read: sectors(%ld-%ld), buffer=0x%08lx, remaining=%ld\n",
- drive->name, rq->sector, rq->sector+nsect-1,
- (unsigned long) rq->buffer+(nsect<<9), rq->nr_sectors-nsect);
-#endif
- rq->sector += nsect;
- rq->buffer += nsect<<9;
- rq->errors = 0;
- i = (rq->nr_sectors -= nsect);
- if ((rq->current_nr_sectors -= nsect) <= 0)
- ide_end_request(1, HWGROUP(drive));
- if (i > 0) {
- if (msect)
- goto read_next;
- ide_set_handler (drive, &read_intr, WAIT_CMD);
- }
-}
-
-/*
- * write_intr() is the handler for disk write interrupts
- */
-static void write_intr (ide_drive_t *drive)
-{
- byte stat;
- int i;
- ide_hwgroup_t *hwgroup = HWGROUP(drive);
- struct request *rq = hwgroup->rq;
-
- if (OK_STAT(stat=GET_STAT(),DRIVE_READY,drive->bad_wstat)) {
-#ifdef DEBUG
- printk("%s: write: sector %ld, buffer=0x%08lx, remaining=%ld\n",
- drive->name, rq->sector, (unsigned long) rq->buffer,
- rq->nr_sectors-1);
-#endif
- if ((rq->nr_sectors == 1) ^ ((stat & DRQ_STAT) != 0)) {
- rq->sector++;
- rq->buffer += 512;
- rq->errors = 0;
- i = --rq->nr_sectors;
- --rq->current_nr_sectors;
- if (rq->current_nr_sectors <= 0)
- ide_end_request(1, hwgroup);
- if (i > 0) {
- ide_output_data (drive, rq->buffer, SECTOR_WORDS);
- ide_set_handler (drive, &write_intr, WAIT_CMD);
- }
- return;
- }
- }
- ide_error(drive, "write_intr", stat);
-}
-
-/*
- * multwrite() transfers a block of one or more sectors of data to a drive
- * as part of a disk multwrite operation.
- */
-static void multwrite (ide_drive_t *drive)
-{
- struct request *rq = &HWGROUP(drive)->wrq;
- unsigned int mcount = drive->mult_count;
-
- do {
- unsigned int nsect = rq->current_nr_sectors;
- if (nsect > mcount)
- nsect = mcount;
- mcount -= nsect;
-
- ide_output_data(drive, rq->buffer, nsect<<7);
-#ifdef DEBUG
- printk("%s: multwrite: sector %ld, buffer=0x%08lx, count=%d, remaining=%ld\n",
- drive->name, rq->sector, (unsigned long) rq->buffer,
- nsect, rq->nr_sectors - nsect);
-#endif
- if ((rq->nr_sectors -= nsect) <= 0)
- break;
- if ((rq->current_nr_sectors -= nsect) == 0) {
- if ((rq->bh = rq->bh->b_reqnext) != NULL) {
- rq->current_nr_sectors = rq->bh->b_size>>9;
- rq->buffer = rq->bh->b_data;
- } else {
- panic("%s: buffer list corrupted\n", drive->name);
- break;
- }
- } else {
- rq->buffer += nsect << 9;
- }
- } while (mcount);
-}
-
-/*
- * multwrite_intr() is the handler for disk multwrite interrupts
- */
-static void multwrite_intr (ide_drive_t *drive)
-{
- byte stat;
- int i;
- ide_hwgroup_t *hwgroup = HWGROUP(drive);
- struct request *rq = &hwgroup->wrq;
-
- if (OK_STAT(stat=GET_STAT(),DRIVE_READY,drive->bad_wstat)) {
- if (stat & DRQ_STAT) {
- if (rq->nr_sectors) {
- multwrite(drive);
- ide_set_handler (drive, &multwrite_intr, WAIT_CMD);
- return;
- }
- } else {
- if (!rq->nr_sectors) { /* all done? */
- rq = hwgroup->rq;
- for (i = rq->nr_sectors; i > 0;){
- i -= rq->current_nr_sectors;
- ide_end_request(1, hwgroup);
- }
- return;
- }
- }
- }
- ide_error(drive, "multwrite_intr", stat);
-}
-
-/*
- * Issue a simple drive command
- * The drive must be selected beforehand.
- */
-static void ide_cmd(ide_drive_t *drive, byte cmd, byte nsect, ide_handler_t *handler)
-{
- ide_set_handler (drive, handler, WAIT_CMD);
- OUT_BYTE(drive->ctl,IDE_CONTROL_REG);
- OUT_BYTE(nsect,IDE_NSECTOR_REG);
- OUT_BYTE(cmd,IDE_COMMAND_REG);
-}
-
-/*
- * set_multmode_intr() is invoked on completion of a WIN_SETMULT cmd.
- */
-static void set_multmode_intr (ide_drive_t *drive)
-{
- byte stat = GET_STAT();
-
- sti();
- if (OK_STAT(stat,READY_STAT,BAD_STAT)) {
- drive->mult_count = drive->mult_req;
- } else {
- drive->mult_req = drive->mult_count = 0;
- drive->special.b.recalibrate = 1;
- (void) ide_dump_status(drive, "set_multmode", stat);
- }
-}
-
-/*
- * set_geometry_intr() is invoked on completion of a WIN_SPECIFY cmd.
- */
-static void set_geometry_intr (ide_drive_t *drive)
-{
- byte stat = GET_STAT();
-
- sti();
- if (!OK_STAT(stat,READY_STAT,BAD_STAT))
- ide_error(drive, "set_geometry_intr", stat);
-}
-
-/*
- * recal_intr() is invoked on completion of a WIN_RESTORE (recalibrate) cmd.
- */
-static void recal_intr (ide_drive_t *drive)
-{
- byte stat = GET_STAT();
-
- sti();
- if (!OK_STAT(stat,READY_STAT,BAD_STAT))
- ide_error(drive, "recal_intr", stat);
-}
-
-/*
- * drive_cmd_intr() is invoked on completion of a special DRIVE_CMD.
- */
-static void drive_cmd_intr (ide_drive_t *drive)
-{
- byte stat = GET_STAT();
-
- sti();
- if (OK_STAT(stat,READY_STAT,BAD_STAT))
- ide_end_drive_cmd (drive, stat, GET_ERR());
- else
- ide_error(drive, "drive_cmd", stat); /* calls ide_end_drive_cmd */
-}
-
-/*
- * do_special() is used to issue WIN_SPECIFY, WIN_RESTORE, and WIN_SETMULT
- * commands to a drive. It used to do much more, but has been scaled back.
- */
-static inline void do_special (ide_drive_t *drive)
-{
- special_t *s = &drive->special;
-next:
-#ifdef DEBUG
- printk("%s: do_special: 0x%02x\n", drive->name, s->all);
-#endif
- if (s->b.set_geometry) {
- s->b.set_geometry = 0;
- if (drive->media == ide_disk) {
- OUT_BYTE(drive->sect,IDE_SECTOR_REG);
- OUT_BYTE(drive->cyl,IDE_LCYL_REG);
- OUT_BYTE(drive->cyl>>8,IDE_HCYL_REG);
- OUT_BYTE(((drive->head-1)|drive->select.all)&0xBF,IDE_SELECT_REG);
- ide_cmd(drive, WIN_SPECIFY, drive->sect, &set_geometry_intr);
- }
- } else if (s->b.recalibrate) {
- s->b.recalibrate = 0;
- if (drive->media == ide_disk) {
- ide_cmd(drive, WIN_RESTORE, drive->sect, &recal_intr);
- }
- } else if (s->b.set_pio) {
- ide_tuneproc_t *tuneproc = HWIF(drive)->tuneproc;
- s->b.set_pio = 0;
- if (tuneproc != NULL)
- tuneproc(drive, drive->pio_req);
- goto next;
- } else if (s->b.set_multmode) {
- s->b.set_multmode = 0;
- if (drive->media == ide_disk) {
- if (drive->id && drive->mult_req > drive->id->max_multsect)
- drive->mult_req = drive->id->max_multsect;
- ide_cmd(drive, WIN_SETMULT, drive->mult_req, &set_multmode_intr);
- } else
- drive->mult_req = 0;
- } else if (s->all) {
- s->all = 0;
- printk("%s: bad special flag: 0x%02x\n", drive->name, s->all);
- }
-}
-
-/*
- * This routine busy-waits for the drive status to be not "busy".
- * It then checks the status for all of the "good" bits and none
- * of the "bad" bits, and if all is okay it returns 0. All other
- * cases return 1 after invoking ide_error() -- caller should just return.
- *
- * This routine should get fixed to not hog the cpu during extra long waits..
- * That could be done by busy-waiting for the first jiffy or two, and then
- * setting a timer to wake up at half second intervals thereafter,
- * until timeout is achieved, before timing out.
- */
-int ide_wait_stat (ide_drive_t *drive, byte good, byte bad, unsigned long timeout)
-{
- byte stat;
- unsigned long flags;
-
-test:
- udelay(1); /* spec allows drive 400ns to change "BUSY" */
- if (OK_STAT((stat = GET_STAT()), good, bad))
- return 0; /* fast exit for most frequent case */
- if (!(stat & BUSY_STAT)) {
- ide_error(drive, "status error", stat);
- return 1;
- }
-
- save_flags(flags);
- sti();
- timeout += jiffies;
- do {
- if (!((stat = GET_STAT()) & BUSY_STAT)) {
- restore_flags(flags);
- goto test;
- }
- } while (jiffies <= timeout);
-
- restore_flags(flags);
- ide_error(drive, "status timeout", GET_STAT());
- return 1;
-}
-
-/*
- * do_rw_disk() issues WIN_{MULT}READ and WIN_{MULT}WRITE commands to a disk,
- * using LBA if supported, or CHS otherwise, to address sectors. It also takes
- * care of issuing special DRIVE_CMDs.
- */
-static inline void do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block)
-{
- unsigned short io_base = HWIF(drive)->io_base;
-
- OUT_BYTE(drive->ctl,IDE_CONTROL_REG);
- OUT_BYTE(rq->nr_sectors,io_base+IDE_NSECTOR_OFFSET);
- if (drive->select.b.lba) {
-#ifdef DEBUG
- printk("%s: %sing: LBAsect=%ld, sectors=%ld, buffer=0x%08lx\n",
- drive->name, (rq->cmd==READ)?"read":"writ",
- block, rq->nr_sectors, (unsigned long) rq->buffer);
-#endif
- OUT_BYTE(block,io_base+IDE_SECTOR_OFFSET);
- OUT_BYTE(block>>=8,io_base+IDE_LCYL_OFFSET);
- OUT_BYTE(block>>=8,io_base+IDE_HCYL_OFFSET);
- OUT_BYTE(((block>>8)&0x0f)|drive->select.all,io_base+IDE_SELECT_OFFSET);
- } else {
- unsigned int sect,head,cyl,track;
- track = block / drive->sect;
- sect = block % drive->sect + 1;
- OUT_BYTE(sect,io_base+IDE_SECTOR_OFFSET);
- head = track % drive->head;
- cyl = track / drive->head;
- OUT_BYTE(cyl,io_base+IDE_LCYL_OFFSET);
- OUT_BYTE(cyl>>8,io_base+IDE_HCYL_OFFSET);
- OUT_BYTE(head|drive->select.all,io_base+IDE_SELECT_OFFSET);
-#ifdef DEBUG
- printk("%s: %sing: CHS=%d/%d/%d, sectors=%ld, buffer=0x%08lx\n",
- drive->name, (rq->cmd==READ)?"read":"writ", cyl,
- head, sect, rq->nr_sectors, (unsigned long) rq->buffer);
-#endif
- }
- if (rq->cmd == READ) {
-#ifdef CONFIG_BLK_DEV_TRITON
- if (drive->using_dma && !(HWIF(drive)->dmaproc(ide_dma_read, drive)))
- return;
-#endif /* CONFIG_BLK_DEV_TRITON */
- ide_set_handler(drive, &read_intr, WAIT_CMD);
- OUT_BYTE(drive->mult_count ? WIN_MULTREAD : WIN_READ, io_base+IDE_COMMAND_OFFSET);
- return;
- }
- if (rq->cmd == WRITE) {
-#ifdef CONFIG_BLK_DEV_TRITON
- if (drive->using_dma && !(HWIF(drive)->dmaproc(ide_dma_write, drive)))
- return;
-#endif /* CONFIG_BLK_DEV_TRITON */
- OUT_BYTE(drive->mult_count ? WIN_MULTWRITE : WIN_WRITE, io_base+IDE_COMMAND_OFFSET);
- if (ide_wait_stat(drive, DATA_READY, drive->bad_wstat, WAIT_DRQ)) {
- printk("%s: no DRQ after issuing %s\n", drive->name,
- drive->mult_count ? "MULTWRITE" : "WRITE");
- return;
- }
- if (!drive->unmask)
- cli();
- if (drive->mult_count) {
- HWGROUP(drive)->wrq = *rq; /* scratchpad */
- ide_set_handler (drive, &multwrite_intr, WAIT_CMD);
- multwrite(drive);
- } else {
- ide_set_handler (drive, &write_intr, WAIT_CMD);
- ide_output_data(drive, rq->buffer, SECTOR_WORDS);
- }
- return;
- }
- if (rq->cmd == IDE_DRIVE_CMD) {
- byte *args = rq->buffer;
- if (args) {
-#ifdef DEBUG
- printk("%s: DRIVE_CMD cmd=0x%02x sc=0x%02x fr=0x%02x\n",
- drive->name, args[0], args[1], args[2]);
-#endif
- OUT_BYTE(args[2],io_base+IDE_FEATURE_OFFSET);
- ide_cmd(drive, args[0], args[1], &drive_cmd_intr);
- return;
- } else {
- /*
- * NULL is actually a valid way of waiting for
- * all current requests to be flushed from the queue.
- */
-#ifdef DEBUG
- printk("%s: DRIVE_CMD (null)\n", drive->name);
-#endif
- ide_end_drive_cmd(drive, GET_STAT(), GET_ERR());
- return;
- }
- }
- printk("%s: bad command: %d\n", drive->name, rq->cmd);
- ide_end_request(0, HWGROUP(drive));
-}
-
-/*
- * do_request() initiates handling of a new I/O request
- */
-static inline void do_request (ide_hwif_t *hwif, struct request *rq)
-{
- unsigned int minor, unit;
- unsigned long block, blockend;
- ide_drive_t *drive;
-
- sti();
-#ifdef DEBUG
- printk("%s: do_request: current=0x%08lx\n", hwif->name, (unsigned long) rq);
-#endif
- minor = MINOR(rq->rq_dev);
- unit = minor >> PARTN_BITS;
- if (MAJOR(rq->rq_dev) != hwif->major || unit >= MAX_DRIVES) {
- printk("%s: bad device number: %s\n",
- hwif->name, kdevname(rq->rq_dev));
- goto kill_rq;
- }
- drive = &hwif->drives[unit];
-#ifdef DEBUG
- if (rq->bh && !buffer_locked(rq->bh)) {
- printk("%s: block not locked\n", drive->name);
- goto kill_rq;
- }
-#endif
- block = rq->sector;
- blockend = block + rq->nr_sectors;
- if ((blockend < block) || (blockend > drive->part[minor&PARTN_MASK].nr_sects)) {
- printk("%s%c: bad access: block=%ld, count=%ld\n", drive->name,
- (minor&PARTN_MASK)?'0'+(minor&PARTN_MASK):' ', block, rq->nr_sectors);
- goto kill_rq;
- }
- block += drive->part[minor&PARTN_MASK].start_sect + drive->sect0;
-#if FAKE_FDISK_FOR_EZDRIVE
- if (block == 0 && drive->remap_0_to_1)
- block = 1; /* redirect MBR access to EZ-Drive partn table */
-#endif /* FAKE_FDISK_FOR_EZDRIVE */
- ((ide_hwgroup_t *)hwif->hwgroup)->drive = drive;
-#ifdef CONFIG_BLK_DEV_HT6560B
- if (hwif->selectproc)
- hwif->selectproc (drive);
-#endif /* CONFIG_BLK_DEV_HT6560B */
-#if (DISK_RECOVERY_TIME > 0)
- while ((read_timer() - hwif->last_time) < DISK_RECOVERY_TIME);
-#endif
-
-#ifdef CONFIG_BLK_DEV_IDETAPE
- POLL_HWIF_TAPE_DRIVE; /* macro from ide-tape.h */
-#endif /* CONFIG_BLK_DEV_IDETAPE */
-
- OUT_BYTE(drive->select.all,IDE_SELECT_REG);
- if (ide_wait_stat(drive, drive->ready_stat, BUSY_STAT|DRQ_STAT, WAIT_READY)) {
- printk("%s: drive not ready for command\n", drive->name);
- return;
- }
-
- if (!drive->special.all) {
-#ifdef CONFIG_BLK_DEV_IDEATAPI
- switch (drive->media) {
- case ide_disk:
- do_rw_disk (drive, rq, block);
- return;
-#ifdef CONFIG_BLK_DEV_IDECD
- case ide_cdrom:
- ide_do_rw_cdrom (drive, block);
- return;
-#endif /* CONFIG_BLK_DEV_IDECD */
-#ifdef CONFIG_BLK_DEV_IDETAPE
- case ide_tape:
- if (rq->cmd == IDE_DRIVE_CMD) {
- byte *args = (byte *) rq->buffer;
- OUT_BYTE(args[2],IDE_FEATURE_REG);
- ide_cmd(drive, args[0], args[1], &drive_cmd_intr);
- return;
- }
- idetape_do_request (drive, rq, block);
- return;
-#endif /* CONFIG_BLK_DEV_IDETAPE */
-
- default:
- printk("%s: media type %d not supported\n",
- drive->name, drive->media);
- goto kill_rq;
- }
-#else
- do_rw_disk (drive, rq, block); /* simpler and faster */
- return;
-#endif /* CONFIG_BLK_DEV_IDEATAPI */;
- }
- do_special(drive);
- return;
-kill_rq:
- ide_end_request(0, hwif->hwgroup);
-}
-
-/*
- * The driver enables interrupts as much as possible. In order to do this,
- * (a) the device-interrupt is always masked before entry, and
- * (b) the timeout-interrupt is always disabled before entry.
- *
- * If we enter here from, say irq14, and then start a new request for irq15,
- * (possible with "serialize" option) then we cannot ensure that we exit
- * before the irq15 hits us. So, we must be careful not to let this bother us.
- *
- * Interrupts are still masked (by default) whenever we are exchanging
- * data/cmds with a drive, because some drives seem to have very poor
- * tolerance for latency during I/O. For devices which don't suffer from
- * this problem (most don't), the unmask flag can be set using the "hdparm"
- * utility, to permit other interrupts during data/cmd transfers.
- */
-void ide_do_request (ide_hwgroup_t *hwgroup)
-{
- cli(); /* paranoia */
- if (hwgroup->handler != NULL) {
- printk("%s: EEeekk!! handler not NULL in ide_do_request()\n", hwgroup->hwif->name);
- return;
- }
- do {
- ide_hwif_t *hwif = hwgroup->hwif;
- struct request *rq;
- if ((rq = hwgroup->rq) == NULL) {
- do {
- rq = blk_dev[hwif->major].current_request;
- if (rq != NULL && rq->rq_status != RQ_INACTIVE)
- goto got_rq;
- } while ((hwif = hwif->next) != hwgroup->hwif);
- return; /* no work left for this hwgroup */
- }
- got_rq:
- do_request(hwgroup->hwif = hwif, hwgroup->rq = rq);
- cli();
- } while (hwgroup->handler == NULL);
-}
-
-/*
- * do_hwgroup_request() invokes ide_do_request() after first masking
- * all possible interrupts for the current hwgroup. This prevents race
- * conditions in the event that an unexpected interrupt occurs while
- * we are in the driver.
- *
- * Note that when an interrupt is used to reenter the driver, the first level
- * handler will already have masked the irq that triggered, but any other ones
- * for the hwgroup will still be unmasked. The driver tries to be careful
- * about such things.
- */
-static void do_hwgroup_request (ide_hwgroup_t *hwgroup)
-{
- if (hwgroup->handler == NULL) {
- ide_hwif_t *hgif = hwgroup->hwif;
- ide_hwif_t *hwif = hgif;
- do {
- disable_irq(hwif->irq);
- } while ((hwif = hwif->next) != hgif);
- ide_do_request (hwgroup);
- do {
- enable_irq(hwif->irq);
- } while ((hwif = hwif->next) != hgif);
- }
-}
-
-static void do_ide0_request (void) /* invoked with cli() */
-{
- do_hwgroup_request (ide_hwifs[0].hwgroup);
-}
-
-static void do_ide1_request (void) /* invoked with cli() */
-{
- do_hwgroup_request (ide_hwifs[1].hwgroup);
-}
-
-static void do_ide2_request (void) /* invoked with cli() */
-{
- do_hwgroup_request (ide_hwifs[2].hwgroup);
-}
-
-static void do_ide3_request (void) /* invoked with cli() */
-{
- do_hwgroup_request (ide_hwifs[3].hwgroup);
-}
-
-static void timer_expiry (unsigned long data)
-{
- ide_hwgroup_t *hwgroup = (ide_hwgroup_t *) data;
- ide_drive_t *drive = hwgroup->drive;
- unsigned long flags;
-
- save_flags(flags);
- cli();
-
- if (hwgroup->poll_timeout != 0) { /* polling in progress? */
- ide_handler_t *handler = hwgroup->handler;
- hwgroup->handler = NULL;
- handler(drive);
- } else if (hwgroup->handler == NULL) { /* not waiting for anything? */
- sti(); /* drive must have responded just as the timer expired */
- printk("%s: marginal timeout\n", drive->name);
- } else {
- hwgroup->handler = NULL; /* abort the operation */
- if (hwgroup->hwif->dmaproc)
- (void) hwgroup->hwif->dmaproc (ide_dma_abort, drive);
- ide_error(drive, "irq timeout", GET_STAT());
- }
- if (hwgroup->handler == NULL)
- do_hwgroup_request (hwgroup);
- restore_flags(flags);
-}
-
-/*
- * There's nothing really useful we can do with an unexpected interrupt,
- * other than reading the status register (to clear it), and logging it.
- * There should be no way that an irq can happen before we're ready for it,
- * so we needn't worry much about losing an "important" interrupt here.
- *
- * On laptops (and "green" PCs), an unexpected interrupt occurs whenever the
- * drive enters "idle", "standby", or "sleep" mode, so if the status looks
- * "good", we just ignore the interrupt completely.
- *
- * This routine assumes cli() is in effect when called.
- *
- * If an unexpected interrupt happens on irq15 while we are handling irq14
- * and if the two interfaces are "serialized" (CMD640B), then it looks like
- * we could screw up by interfering with a new request being set up for irq15.
- *
- * In reality, this is a non-issue. The new command is not sent unless the
- * drive is ready to accept one, in which case we know the drive is not
- * trying to interrupt us. And ide_set_handler() is always invoked before
- * completing the issuance of any new drive command, so we will not be
- * accidently invoked as a result of any valid command completion interrupt.
- *
- */
-static void unexpected_intr (int irq, ide_hwgroup_t *hwgroup)
-{
- byte stat;
- unsigned int unit;
- ide_hwif_t *hwif = hwgroup->hwif;
-
- /*
- * handle the unexpected interrupt
- */
- do {
- if (hwif->irq == irq) {
- for (unit = 0; unit < MAX_DRIVES; ++unit) {
- ide_drive_t *drive = &hwif->drives[unit];
- if (!drive->present)
- continue;
-#ifdef CONFIG_BLK_DEV_HT6560B
- if (hwif->selectproc)
- hwif->selectproc (drive);
-#endif /* CONFIG_BLK_DEV_HT6560B */
- if (!OK_STAT(stat=GET_STAT(), drive->ready_stat, BAD_STAT))
- (void) ide_dump_status(drive, "unexpected_intr", stat);
- if ((stat & DRQ_STAT))
- try_to_flush_leftover_data(drive);
- }
- }
- } while ((hwif = hwif->next) != hwgroup->hwif);
-#ifdef CONFIG_BLK_DEV_HT6560B
- if (hwif->selectproc)
- hwif->selectproc (hwgroup->drive);
-#endif /* CONFIG_BLK_DEV_HT6560B */
-}
-
-/*
- * entry point for all interrupts, caller does cli() for us
- */
-static void ide_intr (int irq, struct pt_regs *regs)
-{
- ide_hwgroup_t *hwgroup = irq_to_hwgroup[irq];
- ide_handler_t *handler;
-
- if (irq == hwgroup->hwif->irq && (handler = hwgroup->handler) != NULL) {
- ide_drive_t *drive = hwgroup->drive;
- hwgroup->handler = NULL;
- del_timer(&(hwgroup->timer));
- if (drive->unmask)
- sti();
- handler(drive);
- cli(); /* this is necessary, as next rq may be different irq */
- if (hwgroup->handler == NULL) {
- SET_RECOVERY_TIMER(HWIF(drive));
- ide_do_request(hwgroup);
- }
- } else {
- unexpected_intr(irq, hwgroup);
- }
- cli();
-}
-
-/*
- * get_info_ptr() returns the (ide_drive_t *) for a given device number.
- * It returns NULL if the given device number does not match any present drives.
- */
-static ide_drive_t *get_info_ptr (kdev_t i_rdev)
-{
- int major = MAJOR(i_rdev);
- unsigned int h;
-
- for (h = 0; h < MAX_HWIFS; ++h) {
- ide_hwif_t *hwif = &ide_hwifs[h];
- if (hwif->present && major == hwif->major) {
- unsigned unit = DEVICE_NR(i_rdev);
- if (unit < MAX_DRIVES) {
- ide_drive_t *drive = &hwif->drives[unit];
- if (drive->present)
- return drive;
- } else if (major == IDE0_MAJOR && unit < 4) {
- printk("ide: probable bad entry for /dev/hd%c\n", 'a'+unit);
- printk("ide: to fix it, run: /usr/src/linux/drivers/block/MAKEDEV.ide\n");
- }
- break;
- }
- }
- return NULL;
-}
-
-/*
- * This function is intended to be used prior to invoking ide_do_drive_cmd().
- */
-void ide_init_drive_cmd (struct request *rq)
-{
- rq->buffer = NULL;
- rq->cmd = IDE_DRIVE_CMD;
- rq->sector = 0;
- rq->nr_sectors = 0;
- rq->current_nr_sectors = 0;
- rq->sem = NULL;
- rq->bh = NULL;
- rq->bhtail = NULL;
- rq->next = NULL;
-
-#if 0 /* these are done each time through ide_do_drive_cmd() */
- rq->errors = 0;
- rq->rq_status = RQ_ACTIVE;
- rq->rq_dev = ????;
-#endif
-}
-
-/*
- * This function issues a special IDE device request
- * onto the request queue.
- *
- * If action is ide_wait, then then rq is queued at the end of
- * the request queue, and the function sleeps until it has been
- * processed. This is for use when invoked from an ioctl handler.
- *
- * If action is ide_preempt, then the rq is queued at the head of
- * the request queue, displacing the currently-being-processed
- * request and this function returns immediately without waiting
- * for the new rq to be completed. This is VERY DANGEROUS, and is
- * intended for careful use by the ATAPI tape/cdrom driver code.
- *
- * If action is ide_next, then the rq is queued immediately after
- * the currently-being-processed-request (if any), and the function
- * returns without waiting for the new rq to be completed. As above,
- * This is VERY DANGEROUS, and is intended for careful use by the
- * ATAPI tape/cdrom driver code.
- *
- * If action is ide_end, then the rq is queued at the end of the
- * request queue, and the function returns immediately without waiting
- * for the new rq to be completed. This is again intended for careful
- * use by the ATAPI tape/cdrom driver code. (Currently used by ide-tape.c,
- * when operating in the pipelined operation mode).
- */
-int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t action)
-{
- unsigned long flags;
- unsigned int major = HWIF(drive)->major;
- struct request *cur_rq;
- struct blk_dev_struct *bdev = &blk_dev[major];
- struct semaphore sem = MUTEX_LOCKED;
-
- rq->errors = 0;
- rq->rq_status = RQ_ACTIVE;
- rq->rq_dev = MKDEV(major,(drive->select.b.unit)<<PARTN_BITS);
- if (action == ide_wait)
- rq->sem = &sem;
-
- save_flags(flags);
- cli();
- cur_rq = bdev->current_request;
-
- if (cur_rq == NULL || action == ide_preempt) {
- rq->next = cur_rq;
- bdev->current_request = rq;
- if (action == ide_preempt) {
- HWGROUP(drive)->rq = NULL;
- } else
- if (HWGROUP(drive)->rq == NULL) { /* is this necessary (?) */
- bdev->request_fn();
- cli();
- }
- } else {
- if (action == ide_wait || action == ide_end) {
- while (cur_rq->next != NULL) /* find end of list */
- cur_rq = cur_rq->next;
- }
- rq->next = cur_rq->next;
- cur_rq->next = rq;
- }
- if (action == ide_wait && rq->rq_status != RQ_INACTIVE)
- down(&sem); /* wait for it to be serviced */
- restore_flags(flags);
- return rq->errors ? -EIO : 0; /* return -EIO if errors */
-}
-
-static int ide_open(struct inode * inode, struct file * filp)
-{
- ide_drive_t *drive;
- unsigned long flags;
-
- if ((drive = get_info_ptr(inode->i_rdev)) == NULL)
- return -ENODEV;
- save_flags(flags);
- cli();
- while (drive->busy)
- sleep_on(&drive->wqueue);
- drive->usage++;
- restore_flags(flags);
-#ifdef CONFIG_BLK_DEV_IDECD
- if (drive->media == ide_cdrom)
- return ide_cdrom_open (inode, filp, drive);
-#endif /* CONFIG_BLK_DEV_IDECD */
-#ifdef CONFIG_BLK_DEV_IDETAPE
- if (drive->media == ide_tape)
- return idetape_blkdev_open (inode, filp, drive);
-#endif /* CONFIG_BLK_DEV_IDETAPE */
- if (drive->removeable) {
- byte door_lock[] = {WIN_DOORLOCK,0,0,0};
- struct request rq;
- check_disk_change(inode->i_rdev);
- ide_init_drive_cmd (&rq);
- rq.buffer = door_lock;
- /*
- * Ignore the return code from door_lock,
- * since the open() has already succeeded,
- * and the door_lock is irrelevant at this point.
- */
- (void) ide_do_drive_cmd(drive, &rq, ide_wait);
- }
- return 0;
-}
-
-/*
- * Releasing a block device means we sync() it, so that it can safely
- * be forgotten about...
- */
-static void ide_release(struct inode * inode, struct file * file)
-{
- ide_drive_t *drive;
-
- if ((drive = get_info_ptr(inode->i_rdev)) != NULL) {
- sync_dev(inode->i_rdev);
- drive->usage--;
-#ifdef CONFIG_BLK_DEV_IDECD
- if (drive->media == ide_cdrom) {
- ide_cdrom_release (inode, file, drive);
- return;
- }
-#endif /* CONFIG_BLK_DEV_IDECD */
-#ifdef CONFIG_BLK_DEV_IDETAPE
- if (drive->media == ide_tape) {
- idetape_blkdev_release (inode, file, drive);
- return;
- }
-#endif /* CONFIG_BLK_DEV_IDETAPE */
- if (drive->removeable) {
- byte door_unlock[] = {WIN_DOORUNLOCK,0,0,0};
- struct request rq;
- invalidate_buffers(inode->i_rdev);
- ide_init_drive_cmd (&rq);
- rq.buffer = door_unlock;
- (void) ide_do_drive_cmd(drive, &rq, ide_wait);
- }
- }
-}
-
-/*
- * This routine is called to flush all partitions and partition tables
- * for a changed disk, and then re-read the new partition table.
- * If we are revalidating a disk because of a media change, then we
- * enter with usage == 0. If we are using an ioctl, we automatically have
- * usage == 1 (we need an open channel to use an ioctl :-), so this
- * is our limit.
- */
-static int revalidate_disk(kdev_t i_rdev)
-{
- ide_drive_t *drive;
- unsigned int p, major, minor;
- long flags;
-
- if ((drive = get_info_ptr(i_rdev)) == NULL)
- return -ENODEV;
-
- major = MAJOR(i_rdev);
- minor = drive->select.b.unit << PARTN_BITS;
- save_flags(flags);
- cli();
- if (drive->busy || (drive->usage > 1)) {
- restore_flags(flags);
- return -EBUSY;
- };
- drive->busy = 1;
- restore_flags(flags);
-
- for (p = 0; p < (1<<PARTN_BITS); ++p) {
- if (drive->part[p].nr_sects > 0) {
- kdev_t devp = MKDEV(major, minor+p);
- sync_dev (devp);
- invalidate_inodes (devp);
- invalidate_buffers (devp);
- }
- drive->part[p].start_sect = 0;
- drive->part[p].nr_sects = 0;
- };
-
- drive->part[0].nr_sects = current_capacity(drive);
- if (drive->media == ide_disk)
- resetup_one_dev(HWIF(drive)->gd, drive->select.b.unit);
-
- drive->busy = 0;
- wake_up(&drive->wqueue);
- return 0;
-}
-
-static int write_fs_long (unsigned long useraddr, long value)
-{
- int err;
-
- if (NULL == (long *)useraddr)
- return -EINVAL;
- if ((err = verify_area(VERIFY_WRITE, (long *)useraddr, sizeof(long))))
- return err;
- put_user((unsigned)value, (long *) useraddr);
- return 0;
-}
-
-static int ide_ioctl (struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- struct hd_geometry *loc = (struct hd_geometry *) arg;
- int err;
- ide_drive_t *drive;
- unsigned long flags;
- struct request rq;
-
- ide_init_drive_cmd (&rq);
- if (!inode || !(inode->i_rdev))
- return -EINVAL;
- if ((drive = get_info_ptr(inode->i_rdev)) == NULL)
- return -ENODEV;
- switch (cmd) {
- case HDIO_GETGEO:
- if (!loc || drive->media != ide_disk) return -EINVAL;
- err = verify_area(VERIFY_WRITE, loc, sizeof(*loc));
- if (err) return err;
- put_user(drive->bios_head, (byte *) &loc->heads);
- put_user(drive->bios_sect, (byte *) &loc->sectors);
- put_user(drive->bios_cyl, (unsigned short *) &loc->cylinders);
- put_user((unsigned)drive->part[MINOR(inode->i_rdev)&PARTN_MASK].start_sect,
- (unsigned long *) &loc->start);
- return 0;
-
- case BLKFLSBUF:
- if(!suser()) return -EACCES;
- fsync_dev(inode->i_rdev);
- invalidate_buffers(inode->i_rdev);
- return 0;
-
- case BLKRASET:
- if(!suser()) return -EACCES;
- if(arg > 0xff) return -EINVAL;
- read_ahead[MAJOR(inode->i_rdev)] = arg;
- return 0;
-
- case BLKRAGET:
- return write_fs_long(arg, read_ahead[MAJOR(inode->i_rdev)]);
-
- case BLKGETSIZE: /* Return device size */
- return write_fs_long(arg, drive->part[MINOR(inode->i_rdev)&PARTN_MASK].nr_sects);
- case BLKRRPART: /* Re-read partition tables */
- return revalidate_disk(inode->i_rdev);
-
- case HDIO_GET_KEEPSETTINGS:
- return write_fs_long(arg, drive->keep_settings);
-
- case HDIO_GET_UNMASKINTR:
- return write_fs_long(arg, drive->unmask);
-
- case HDIO_GET_DMA:
- return write_fs_long(arg, drive->using_dma);
-
- case HDIO_GET_32BIT:
- return write_fs_long(arg, drive->io_32bit);
-
- case HDIO_GET_MULTCOUNT:
- return write_fs_long(arg, drive->mult_count);
-
- case HDIO_GET_IDENTITY:
- if (!arg || (MINOR(inode->i_rdev) & PARTN_MASK))
- return -EINVAL;
- if (drive->id == NULL)
- return -ENOMSG;
- err = verify_area(VERIFY_WRITE, (char *)arg, sizeof(*drive->id));
- if (!err)
- memcpy_tofs((char *)arg, (char *)drive->id, sizeof(*drive->id));
- return err;
-
- case HDIO_GET_NOWERR:
- return write_fs_long(arg, drive->bad_wstat == BAD_R_STAT);
-
- case HDIO_SET_DMA:
-#ifdef CONFIG_BLK_DEV_IDECD
- if (drive->media == ide_cdrom)
- return -EPERM;
-#endif /* CONFIG_BLK_DEV_IDECD */
- if (!drive->id || !(drive->id->capability & 1) || !HWIF(drive)->dmaproc)
- return -EPERM;
- case HDIO_SET_KEEPSETTINGS:
- case HDIO_SET_UNMASKINTR:
- case HDIO_SET_NOWERR:
- if (arg > 1)
- return -EINVAL;
- case HDIO_SET_32BIT:
- if (!suser())
- return -EACCES;
- if ((MINOR(inode->i_rdev) & PARTN_MASK))
- return -EINVAL;
- save_flags(flags);
- cli();
- switch (cmd) {
- case HDIO_SET_DMA:
- if (!(HWIF(drive)->dmaproc)) {
- restore_flags(flags);
- return -EPERM;
- }
- drive->using_dma = arg;
- break;
- case HDIO_SET_KEEPSETTINGS:
- drive->keep_settings = arg;
- break;
- case HDIO_SET_UNMASKINTR:
- if (arg && HWIF(drive)->no_unmask) {
- restore_flags(flags);
- return -EPERM;
- }
- drive->unmask = arg;
- break;
- case HDIO_SET_NOWERR:
- drive->bad_wstat = arg ? BAD_R_STAT : BAD_W_STAT;
- break;
- case HDIO_SET_32BIT:
- if (arg > (1 + (SUPPORT_VLB_SYNC<<1)))
- return -EINVAL;
- drive->io_32bit = arg;
-#ifdef CONFIG_BLK_DEV_DTC2278
- if (HWIF(drive)->chipset == ide_dtc2278)
- HWIF(drive)->drives[!drive->select.b.unit].io_32bit = arg;
-#endif /* CONFIG_BLK_DEV_DTC2278 */
- break;
- }
- restore_flags(flags);
- return 0;
-
- case HDIO_SET_MULTCOUNT:
- if (!suser())
- return -EACCES;
- if (MINOR(inode->i_rdev) & PARTN_MASK)
- return -EINVAL;
- if (drive->id && arg > drive->id->max_multsect)
- return -EINVAL;
- save_flags(flags);
- cli();
- if (drive->special.b.set_multmode) {
- restore_flags(flags);
- return -EBUSY;
- }
- drive->mult_req = arg;
- drive->special.b.set_multmode = 1;
- restore_flags(flags);
- (void) ide_do_drive_cmd (drive, &rq, ide_wait);
- return (drive->mult_count == arg) ? 0 : -EIO;
-
- case HDIO_DRIVE_CMD:
- {
- unsigned long args;
-
- if (NULL == (long *) arg)
- err = ide_do_drive_cmd(drive, &rq, ide_wait);
- else {
- if (!(err = verify_area(VERIFY_READ,(long *)arg,sizeof(long))))
- {
- args = get_user((long *)arg);
- if (!(err = verify_area(VERIFY_WRITE,(long *)arg,sizeof(long)))) {
- rq.buffer = (char *) &args;
- err = ide_do_drive_cmd(drive, &rq, ide_wait);
- put_user(args,(long *)arg);
- }
- }
- }
- return err;
- }
- case HDIO_SET_PIO_MODE:
- if (!suser())
- return -EACCES;
- if (MINOR(inode->i_rdev) & PARTN_MASK)
- return -EINVAL;
- if (!HWIF(drive)->tuneproc)
- return -ENOSYS;
- save_flags(flags);
- cli();
- drive->pio_req = (int) arg;
- drive->special.b.set_pio = 1;
- restore_flags(flags);
- return 0;
-
- RO_IOCTLS(inode->i_rdev, arg);
-
- default:
-#ifdef CONFIG_BLK_DEV_IDECD
- if (drive->media == ide_cdrom)
- return ide_cdrom_ioctl(drive, inode, file, cmd, arg);
-#endif /* CONFIG_BLK_DEV_IDECD */
-#ifdef CONFIG_BLK_DEV_IDETAPE
- if (drive->media == ide_tape)
- return idetape_blkdev_ioctl(drive, inode, file, cmd, arg);
-#endif /* CONFIG_BLK_DEV_IDETAPE */
- return -EPERM;
- }
-}
-
-static int ide_check_media_change (kdev_t i_rdev)
-{
- ide_drive_t *drive;
-
- if ((drive = get_info_ptr(i_rdev)) == NULL)
- return -ENODEV;
-#ifdef CONFIG_BLK_DEV_IDECD
- if (drive->media == ide_cdrom)
- return ide_cdrom_check_media_change (drive);
-#endif /* CONFIG_BLK_DEV_IDECD */
- if (drive->removeable) /* for disks */
- return 1; /* always assume it was changed */
- return 0;
-}
-
-void ide_fixstring (byte *s, const int bytecount, const int byteswap)
-{
- byte *p = s, *end = &s[bytecount & ~1]; /* bytecount must be even */
-
- if (byteswap) {
- /* convert from big-endian to host byte order */
- for (p = end ; p != s;) {
- unsigned short *pp = (unsigned short *) (p -= 2);
- *pp = ntohs(*pp);
- }
- }
-
- /* strip leading blanks */
- while (s != end && *s == ' ')
- ++s;
-
- /* compress internal blanks and strip trailing blanks */
- while (s != end && *s) {
- if (*s++ != ' ' || (s != end && *s && *s != ' '))
- *p++ = *(s-1);
- }
-
- /* wipe out trailing garbage */
- while (p != end)
- *p++ = '\0';
-}
-
-static inline void do_identify (ide_drive_t *drive, byte cmd)
-{
- int bswap;
- struct hd_driveid *id;
- unsigned long capacity, check;
-
- id = drive->id = kmalloc (SECTOR_WORDS*4, GFP_KERNEL);
- ide_input_data(drive, id, SECTOR_WORDS); /* read 512 bytes of id info */
- sti();
-
- /*
- * EATA SCSI controllers do a hardware ATA emulation: ignore them
- */
- if ((id->model[0] == 'P' && id->model[1] == 'M')
- || (id->model[0] == 'S' && id->model[1] == 'K')) {
- printk("%s: EATA SCSI HBA %.10s\n", drive->name, id->model);
- drive->present = 0;
- return;
- }
-
- /*
- * WIN_IDENTIFY returns little-endian info,
- * WIN_PIDENTIFY *usually* returns little-endian info.
- */
- bswap = 1;
- if (cmd == WIN_PIDENTIFY) {
- if ((id->model[0] == 'N' && id->model[1] == 'E') /* NEC */
- || (id->model[0] == 'F' && id->model[1] == 'X') /* Mitsumi */
- || (id->model[0] == 'P' && id->model[1] == 'i'))/* Pioneer */
- bswap = 0; /* Vertos drives may still be weird */
- }
- ide_fixstring (id->model, sizeof(id->model), bswap);
- ide_fixstring (id->fw_rev, sizeof(id->fw_rev), bswap);
- ide_fixstring (id->serial_no, sizeof(id->serial_no), bswap);
-
- /*
- * Check for an ATAPI device
- */
-
- if (cmd == WIN_PIDENTIFY) {
- byte type = (id->config >> 8) & 0x1f;
- printk("%s: %s, ATAPI ", drive->name, id->model);
- switch (type) {
- case 0: /* Early cdrom models used zero */
- case 5:
-#ifdef CONFIG_BLK_DEV_IDECD
- printk ("CDROM drive\n");
- drive->media = ide_cdrom;
- drive->present = 1;
- drive->removeable = 1;
- return;
-#else
- printk ("CDROM ");
- break;
-#endif /* CONFIG_BLK_DEV_IDECD */
- case 1:
-#ifdef CONFIG_BLK_DEV_IDETAPE
- printk ("TAPE drive");
- if (idetape_identify_device (drive,id)) {
- drive->media = ide_tape;
- drive->present = 1;
- drive->removeable = 1;
- if (HWIF(drive)->dmaproc != NULL &&
- !HWIF(drive)->dmaproc(ide_dma_check, drive))
- printk(", DMA");
- printk("\n");
- }
- else {
- drive->present = 0;
- printk ("\nide-tape: the tape is not supported by this version of the driver\n");
- }
- return;
-#else
- printk ("TAPE ");
- break;
-#endif /* CONFIG_BLK_DEV_IDETAPE */
- default:
- drive->present = 0;
- printk("Type %d - Unknown device\n", type);
- return;
- }
- drive->present = 0;
- printk("- not supported by this kernel\n");
- return;
- }
-
- /* check for removeable disks (eg. SYQUEST), ignore 'WD' drives */
- if (id->config & (1<<7)) { /* removeable disk ? */
- if (id->model[0] != 'W' || id->model[1] != 'D')
- drive->removeable = 1;
- }
-
- drive->media = ide_disk;
- /* Extract geometry if we did not already have one for the drive */
- if (!drive->present) {
- drive->present = 1;
- drive->cyl = drive->bios_cyl = id->cyls;
- drive->head = drive->bios_head = id->heads;
- drive->sect = drive->bios_sect = id->sectors;
- }
- /* Handle logical geometry translation by the drive */
- if ((id->field_valid & 1) && id->cur_cyls && id->cur_heads
- && (id->cur_heads <= 16) && id->cur_sectors)
- {
- /*
- * Extract the physical drive geometry for our use.
- * Note that we purposely do *not* update the bios info.
- * This way, programs that use it (like fdisk) will
- * still have the same logical view as the BIOS does,
- * which keeps the partition table from being screwed.
- *
- * An exception to this is the cylinder count,
- * which we reexamine later on to correct for 1024 limitations.
- */
- drive->cyl = id->cur_cyls;
- drive->head = id->cur_heads;
- drive->sect = id->cur_sectors;
-
- /* check for word-swapped "capacity" field in id information */
- capacity = drive->cyl * drive->head * drive->sect;
- check = (id->cur_capacity0 << 16) | id->cur_capacity1;
- if (check == capacity) { /* was it swapped? */
- /* yes, bring it into little-endian order: */
- id->cur_capacity0 = (capacity >> 0) & 0xffff;
- id->cur_capacity1 = (capacity >> 16) & 0xffff;
- }
- }
- /* Use physical geometry if what we have still makes no sense */
- if ((!drive->head || drive->head > 16) && id->heads && id->heads <= 16) {
- drive->cyl = id->cyls;
- drive->head = id->heads;
- drive->sect = id->sectors;
- }
- /* Correct the number of cyls if the bios value is too small */
- if (drive->sect == drive->bios_sect && drive->head == drive->bios_head) {
- if (drive->cyl > drive->bios_cyl)
- drive->bios_cyl = drive->cyl;
- }
-
- (void) current_capacity (drive); /* initialize LBA selection */
-
- printk ("%s: %.40s, %ldMB w/%dKB Cache, %sCHS=%d/%d/%d",
- drive->name, id->model, current_capacity(drive)/2048L, id->buf_size/2,
- drive->select.b.lba ? "LBA, " : "",
- drive->bios_cyl, drive->bios_head, drive->bios_sect);
-
- drive->mult_count = 0;
- if (id->max_multsect) {
- drive->mult_req = INITIAL_MULT_COUNT;
- if (drive->mult_req > id->max_multsect)
- drive->mult_req = id->max_multsect;
- if (drive->mult_req || ((id->multsect_valid & 1) && id->multsect))
- drive->special.b.set_multmode = 1;
- }
- if (HWIF(drive)->dmaproc != NULL) { /* hwif supports DMA? */
- if (!(HWIF(drive)->dmaproc(ide_dma_check, drive)))
- printk(", DMA");
- }
- printk("\n");
-}
-
-/*
- * Delay for *at least* 10ms. As we don't know how much time is left
- * until the next tick occurs, we wait an extra tick to be safe.
- * This is used only during the probing/polling for drives at boot time.
- */
-static void delay_10ms (void)
-{
- unsigned long timer = jiffies + (HZ + 99)/100 + 1;
- while (timer > jiffies);
-}
-
-/*
- * try_to_identify() sends an ATA(PI) IDENTIFY request to a drive
- * and waits for a response. It also monitors irqs while this is
- * happening, in hope of automatically determining which one is
- * being used by the interface.
- *
- * Returns: 0 device was identified
- * 1 device timed-out (no response to identify request)
- * 2 device aborted the command (refused to identify itself)
- */
-static int try_to_identify (ide_drive_t *drive, byte cmd)
-{
- int hd_status, rc;
- unsigned long timeout;
- int irqs = 0;
-
- if (!HWIF(drive)->irq) { /* already got an IRQ? */
- probe_irq_off(probe_irq_on()); /* clear dangling irqs */
- irqs = probe_irq_on(); /* start monitoring irqs */
- OUT_BYTE(drive->ctl,IDE_CONTROL_REG); /* enable device irq */
- }
-
- delay_10ms(); /* take a deep breath */
- if ((IN_BYTE(IDE_ALTSTATUS_REG) ^ IN_BYTE(IDE_STATUS_REG)) & ~INDEX_STAT) {
- printk("%s: probing with STATUS instead of ALTSTATUS\n", drive->name);
- hd_status = IDE_STATUS_REG; /* ancient Seagate drives */
- } else
- hd_status = IDE_ALTSTATUS_REG; /* use non-intrusive polling */
-
- OUT_BYTE(cmd,IDE_COMMAND_REG); /* ask drive for ID */
- timeout = ((cmd == WIN_IDENTIFY) ? WAIT_WORSTCASE : WAIT_PIDENTIFY) / 2;
- timeout += jiffies;
- do {
- if (jiffies > timeout) {
- if (!HWIF(drive)->irq)
- (void) probe_irq_off(irqs);
- return 1; /* drive timed-out */
- }
- delay_10ms(); /* give drive a breather */
- } while (IN_BYTE(hd_status) & BUSY_STAT);
-
- delay_10ms(); /* wait for IRQ and DRQ_STAT */
- if (OK_STAT(GET_STAT(),DRQ_STAT,BAD_R_STAT)) {
- cli(); /* some systems need this */
- do_identify(drive, cmd); /* drive returned ID */
- if (drive->present && drive->media != ide_tape) {
- ide_tuneproc_t *tuneproc = HWIF(drive)->tuneproc;
- if (tuneproc != NULL && drive->autotune == 1)
- tuneproc(drive, 255); /* auto-tune PIO mode */
- }
- rc = 0; /* drive responded with ID */
- } else
- rc = 2; /* drive refused ID */
- if (!HWIF(drive)->irq) {
- irqs = probe_irq_off(irqs); /* get irq number */
- if (irqs > 0)
- HWIF(drive)->irq = irqs;
- else /* Mmmm.. multiple IRQs */
- printk("%s: IRQ probe failed (%d)\n", drive->name, irqs);
- }
- return rc;
-}
-
-/*
- * do_probe() has the difficult job of finding a drive if it exists,
- * without getting hung up if it doesn't exist, without trampling on
- * ethernet cards, and without leaving any IRQs dangling to haunt us later.
- *
- * If a drive is "known" to exist (from CMOS or kernel parameters),
- * but does not respond right away, the probe will "hang in there"
- * for the maximum wait time (about 30 seconds), otherwise it will
- * exit much more quickly.
- *
- * Returns: 0 device was identified
- * 1 device timed-out (no response to identify request)
- * 2 device aborted the command (refused to identify itself)
- * 3 bad status from device (possible for ATAPI drives)
- * 4 probe was not attempted because failure was obvious
- */
-static int do_probe (ide_drive_t *drive, byte cmd)
-{
- int rc;
-#ifdef CONFIG_BLK_DEV_IDEATAPI
- if (drive->present) { /* avoid waiting for inappropriate probes */
- if ((drive->media != ide_disk) && (cmd == WIN_IDENTIFY))
- return 4;
- }
-#endif /* CONFIG_BLK_DEV_IDEATAPI */
-#ifdef DEBUG
- printk("probing for %s: present=%d, media=%d, probetype=%s\n",
- drive->name, drive->present, drive->media,
- (cmd == WIN_IDENTIFY) ? "ATA" : "ATAPI");
-#endif
-#ifdef CONFIG_BLK_DEV_HT6560B
- if (HWIF(drive)->selectproc)
- HWIF(drive)->selectproc (drive);
-#endif /* CONFIG_BLK_DEV_HT6560B */
- OUT_BYTE(drive->select.all,IDE_SELECT_REG); /* select target drive */
- delay_10ms(); /* wait for BUSY_STAT */
- if (IN_BYTE(IDE_SELECT_REG) != drive->select.all && !drive->present) {
- OUT_BYTE(0xa0,IDE_SELECT_REG); /* exit with drive0 selected */
- return 3; /* no i/f present: avoid killing ethernet cards */
- }
-
- if (OK_STAT(GET_STAT(),READY_STAT,BUSY_STAT)
- || drive->present || cmd == WIN_PIDENTIFY)
- {
- if ((rc = try_to_identify(drive,cmd))) /* send cmd and wait */
- rc = try_to_identify(drive,cmd); /* failed: try again */
- if (rc == 1)
- printk("%s: no response (status = 0x%02x)\n", drive->name, GET_STAT());
- (void) GET_STAT(); /* ensure drive irq is clear */
- } else {
- rc = 3; /* not present or maybe ATAPI */
- }
- if (drive->select.b.unit != 0) {
- OUT_BYTE(0xa0,IDE_SELECT_REG); /* exit with drive0 selected */
- delay_10ms();
- (void) GET_STAT(); /* ensure drive irq is clear */
- }
- return rc;
-}
-
-/*
- * probe_for_drive() tests for existance of a given drive using do_probe().
- *
- * Returns: 0 no device was found
- * 1 device was found (note: drive->present might still be 0)
- */
-static inline byte probe_for_drive (ide_drive_t *drive)
-{
- if (drive->noprobe) /* skip probing? */
- return drive->present;
- if (do_probe(drive, WIN_IDENTIFY) >= 2) { /* if !(success||timed-out) */
-#ifdef CONFIG_BLK_DEV_IDEATAPI
- (void) do_probe(drive, WIN_PIDENTIFY); /* look for ATAPI device */
-#endif /* CONFIG_BLK_DEV_IDEATAPI */
- }
- if (!drive->present)
- return 0; /* drive not found */
- if (drive->id == NULL) { /* identification failed? */
- if (drive->media == ide_disk) {
- printk ("%s: non-IDE drive, CHS=%d/%d/%d\n",
- drive->name, drive->cyl, drive->head, drive->sect);
- }
-#ifdef CONFIG_BLK_DEV_IDECD
- else if (drive->media == ide_cdrom) {
- printk("%s: ATAPI cdrom (?)\n", drive->name);
- }
-#endif /* CONFIG_BLK_DEV_IDECD */
- else {
- drive->present = 0; /* nuke it */
- return 1; /* drive was found */
- }
- }
- if (drive->media == ide_disk && !drive->select.b.lba) {
- if (!drive->head || drive->head > 16) {
- printk("%s: INVALID GEOMETRY: %d PHYSICAL HEADS?\n",
- drive->name, drive->head);
- drive->present = 0;
- }
- }
- return 1; /* drive was found */
-}
-
-/*
- * This routine only knows how to look for drive units 0 and 1
- * on an interface, so any setting of MAX_DRIVES > 2 won't work here.
- */
-static void probe_for_drives (ide_hwif_t *hwif)
-{
- unsigned int unit;
-
- if (check_region(hwif->io_base,8) || check_region(hwif->ctl_port,1)) {
- int msgout = 0;
- for (unit = 0; unit < MAX_DRIVES; ++unit) {
- ide_drive_t *drive = &hwif->drives[unit];
- if (drive->present) {
- drive->present = 0;
- printk("%s: ERROR, PORTS ALREADY IN USE\n", drive->name);
- msgout = 1;
- }
- }
- if (!msgout)
- printk("%s: ports already in use, skipping probe\n", hwif->name);
- } else {
- unsigned long flags;
- save_flags(flags);
-
-#if (MAX_DRIVES > 2)
- printk("%s: probing for first 2 of %d possible drives\n", hwif->name, MAX_DRIVES);
-#endif
- sti(); /* needed for jiffies and irq probing */
- /*
- * Second drive should only exist if first drive was found,
- * but a lot of cdrom drives seem to be configured as slave-only
- */
- for (unit = 0; unit < 2; ++unit) { /* note the hardcoded '2' */
- ide_drive_t *drive = &hwif->drives[unit];
- (void) probe_for_drive (drive);
- }
- for (unit = 0; unit < MAX_DRIVES; ++unit) {
- ide_drive_t *drive = &hwif->drives[unit];
- if (drive->present) {
- hwif->present = 1;
- request_region(hwif->io_base, 8, hwif->name);
- request_region(hwif->ctl_port, 1, hwif->name);
- break;
- }
- }
- restore_flags(flags);
- }
-}
-
-/*
- * stridx() returns the offset of c within s,
- * or -1 if c is '\0' or not found within s.
- */
-static int stridx (const char *s, char c)
-{
- char *i = strchr(s, c);
- return (i && c) ? i - s : -1;
-}
-
-/*
- * match_parm() does parsing for ide_setup():
- *
- * 1. the first char of s must be '='.
- * 2. if the remainder matches one of the supplied keywords,
- * the index (1 based) of the keyword is negated and returned.
- * 3. if the remainder is a series of no more than max_vals numbers
- * separated by commas, the numbers are saved in vals[] and a
- * count of how many were saved is returned. Base10 is assumed,
- * and base16 is allowed when prefixed with "0x".
- * 4. otherwise, zero is returned.
- */
-static int match_parm (char *s, const char *keywords[], int vals[], int max_vals)
-{
- static const char *decimal = "0123456789";
- static const char *hex = "0123456789abcdef";
- int i, n;
-
- if (*s++ == '=') {
- /*
- * Try matching against the supplied keywords,
- * and return -(index+1) if we match one
- */
- for (i = 0; *keywords != NULL; ++i) {
- if (!strcmp(s, *keywords++))
- return -(i+1);
- }
- /*
- * Look for a series of no more than "max_vals"
- * numeric values separated by commas, in base10,
- * or base16 when prefixed with "0x".
- * Return a count of how many were found.
- */
- for (n = 0; (i = stridx(decimal, *s)) >= 0;) {
- vals[n] = i;
- while ((i = stridx(decimal, *++s)) >= 0)
- vals[n] = (vals[n] * 10) + i;
- if (*s == 'x' && !vals[n]) {
- while ((i = stridx(hex, *++s)) >= 0)
- vals[n] = (vals[n] * 0x10) + i;
- }
- if (++n == max_vals)
- break;
- if (*s == ',')
- ++s;
- }
- if (!*s)
- return n;
- }
- return 0; /* zero = nothing matched */
-}
-
-/*
- * ide_setup() gets called VERY EARLY during initialization,
- * to handle kernel "command line" strings beginning with "hdx="
- * or "ide". Here is the complete set currently supported:
- *
- * "hdx=" is recognized for all "x" from "a" to "h", such as "hdc".
- * "idex=" is recognized for all "x" from "0" to "3", such as "ide1".
- *
- * "hdx=noprobe" : drive may be present, but do not probe for it
- * "hdx=nowerr" : ignore the WRERR_STAT bit on this drive
- * "hdx=cdrom" : drive is present, and is a cdrom drive
- * "hdx=cyl,head,sect" : disk drive is present, with specified geometry
- * "hdx=autotune" : driver will attempt to tune interface speed
- * to the fastest PIO mode supported,
- * if possible for this drive only.
- * Not fully supported by all chipset types,
- * and quite likely to cause trouble with
- * older/odd IDE drives.
- *
- * "idex=noprobe" : do not attempt to access/use this interface
- * "idex=base" : probe for an interface at the addr specified,
- * where "base" is usually 0x1f0 or 0x170
- * and "ctl" is assumed to be "base"+0x206
- * "idex=base,ctl" : specify both base and ctl
- * "idex=base,ctl,irq" : specify base, ctl, and irq number
- * "idex=autotune" : driver will attempt to tune interface speed
- * to the fastest PIO mode supported,
- * for all drives on this interface.
- * Not fully supported by all chipset types,
- * and quite likely to cause trouble with
- * older/odd IDE drives.
- * "idex=noautotune" : driver will NOT attempt to tune interface speed
- * This is the default for most chipsets,
- * except the cmd640.
- *
- * The following two are valid ONLY on ide0,
- * and the defaults for the base,ctl ports must not be altered.
- *
- * "ide0=serialize" : do not overlap operations on ide0 and ide1.
- * "ide0=dtc2278" : probe/support DTC2278 interface
- * "ide0=ht6560b" : probe/support HT6560B interface
- * "ide0=cmd640_vlb" : *REQUIRED* for VLB cards with the CMD640 chip
- * (not for PCI -- automatically detected)
- * "ide0=qd6580" : probe/support qd6580 interface
- * "ide0=ali14xx" : probe/support ali14xx chipsets (ALI M1439, M1443, M1445)
- * "ide0=umc8672" : probe/support umc8672 chipsets
- */
-void ide_setup (char *s)
-{
- int i, vals[3];
- ide_hwif_t *hwif;
- ide_drive_t *drive;
- unsigned int hw, unit;
- const char max_drive = 'a' + ((MAX_HWIFS * MAX_DRIVES) - 1);
- const char max_hwif = '0' + (MAX_HWIFS - 1);
-
- printk("ide_setup: %s", s);
- init_ide_data ();
-
- /*
- * Look for drive options: "hdx="
- */
- if (s[0] == 'h' && s[1] == 'd' && s[2] >= 'a' && s[2] <= max_drive) {
- const char *hd_words[] = {"noprobe", "nowerr", "cdrom", "serialize",
- "autotune", "noautotune", NULL};
- unit = s[2] - 'a';
- hw = unit / MAX_DRIVES;
- unit = unit % MAX_DRIVES;
- hwif = &ide_hwifs[hw];
- drive = &hwif->drives[unit];
- switch (match_parm(&s[3], hd_words, vals, 3)) {
- case -1: /* "noprobe" */
- drive->noprobe = 1;
- goto done;
- case -2: /* "nowerr" */
- drive->bad_wstat = BAD_R_STAT;
- hwif->noprobe = 0;
- goto done;
- case -3: /* "cdrom" */
- drive->present = 1;
- drive->media = ide_cdrom;
- hwif->noprobe = 0;
- goto done;
- case -4: /* "serialize" */
- printk(" -- USE \"ide%c=serialize\" INSTEAD", '0'+hw);
- goto do_serialize;
- case -5: /* "autotune" */
- drive->autotune = 1;
- goto done;
- case -6: /* "noautotune" */
- drive->autotune = 2;
- goto done;
- case 3: /* cyl,head,sect */
- drive->media = ide_disk;
- drive->cyl = drive->bios_cyl = vals[0];
- drive->head = drive->bios_head = vals[1];
- drive->sect = drive->bios_sect = vals[2];
- drive->present = 1;
- drive->forced_geom = 1;
- hwif->noprobe = 0;
- goto done;
- default:
- goto bad_option;
- }
- }
- /*
- * Look for interface options: "idex="
- */
- if (s[0] == 'i' && s[1] == 'd' && s[2] == 'e' && s[3] >= '0' && s[3] <= max_hwif) {
- /*
- * Be VERY CAREFUL changing this: note hardcoded indexes below
- */
- const char *ide_words[] = {"noprobe", "serialize", "autotune", "noautotune",
- "qd6580", "ht6560b", "cmd640_vlb", "dtc2278", "umc8672", "ali14xx", NULL};
- hw = s[3] - '0';
- hwif = &ide_hwifs[hw];
- i = match_parm(&s[4], ide_words, vals, 3);
-
- /*
- * Cryptic check to ensure chipset not already set for hwif:
- */
- if (i != -1 && i != -2) {
- if (hwif->chipset != ide_unknown)
- goto bad_option;
- if (i < 0 && ide_hwifs[1].chipset != ide_unknown)
- goto bad_option;
- }
- /*
- * Interface keywords work only for ide0:
- */
- if (i <= -6 && hw != 0)
- goto bad_hwif;
-
- switch (i) {
-#ifdef CONFIG_BLK_DEV_ALI14XX
- case -10: /* "ali14xx" */
- {
- extern void init_ali14xx (void);
- init_ali14xx();
- goto done;
- }
-#endif /* CONFIG_BLK_DEV_ALI14XX */
-#ifdef CONFIG_BLK_DEV_UMC8672
- case -9: /* "umc8672" */
- {
- extern void init_umc8672 (void);
- init_umc8672();
- goto done;
- }
-#endif /* CONFIG_BLK_DEV_UMC8672 */
-#ifdef CONFIG_BLK_DEV_DTC2278
- case -8: /* "dtc2278" */
- {
- extern void init_dtc2278 (void);
- init_dtc2278();
- goto done;
- }
-#endif /* CONFIG_BLK_DEV_DTC2278 */
-#ifdef CONFIG_BLK_DEV_CMD640
- case -7: /* "cmd640_vlb" */
- {
- extern int cmd640_vlb; /* flag for cmd640.c */
- cmd640_vlb = 1;
- goto done;
- }
-#endif /* CONFIG_BLK_DEV_CMD640 */
-#ifdef CONFIG_BLK_DEV_HT6560B
- case -6: /* "ht6560b" */
- {
- extern void init_ht6560b (void);
- init_ht6560b();
- goto done;
- }
-#endif /* CONFIG_BLK_DEV_HT6560B */
-#if CONFIG_BLK_DEV_QD6580
- case -5: /* "qd6580" (no secondary i/f) */
- {
- extern void init_qd6580 (void);
- init_qd6580();
- goto done;
- }
-#endif /* CONFIG_BLK_DEV_QD6580 */
- case -4: /* "noautotune" */
- hwif->drives[0].autotune = 2;
- hwif->drives[1].autotune = 2;
- goto done;
- case -3: /* "autotune" */
- hwif->drives[0].autotune = 1;
- hwif->drives[1].autotune = 1;
- goto done;
- case -2: /* "serialize" */
- do_serialize:
- if (hw > 1) goto bad_hwif;
- ide_hwifs[0].serialized = 1;
- goto done;
-
- case -1: /* "noprobe" */
- hwif->noprobe = 1;
- goto done;
-
- case 1: /* base */
- vals[1] = vals[0] + 0x206; /* default ctl */
- case 2: /* base,ctl */
- vals[2] = 0; /* default irq = probe for it */
- case 3: /* base,ctl,irq */
- hwif->io_base = vals[0];
- hwif->ctl_port = vals[1];
- hwif->irq = vals[2];
- hwif->noprobe = 0;
- hwif->chipset = ide_generic;
- goto done;
-
- case 0: goto bad_option;
- default:
- printk(" -- SUPPORT NOT CONFIGURED IN THIS KERNEL\n");
- return;
- }
- }
-bad_option:
- printk(" -- BAD OPTION\n");
- return;
-bad_hwif:
- printk("-- NOT SUPPORTED ON ide%d", hw);
-done:
- printk("\n");
-}
-
-/*
- * This routine is called from the partition-table code in genhd.c
- * to "convert" a drive to a logical geometry with fewer than 1024 cyls.
- *
- * The second parameter, "xparm", determines exactly how the translation
- * will be handled:
- * 0 = convert to CHS with fewer than 1024 cyls
- * using the same method as Ontrack DiskManager.
- * 1 = same as "0", plus offset everything by 63 sectors.
- * -1 = similar to "0", plus redirect sector 0 to sector 1.
- * >1 = convert to a CHS geometry with "xparm" heads.
- *
- * Returns 0 if the translation was not possible, if the device was not
- * an IDE disk drive, or if a geometry was "forced" on the commandline.
- * Returns 1 if the geometry translation was successful.
- */
-int ide_xlate_1024 (kdev_t i_rdev, int xparm, const char *msg)
-{
- ide_drive_t *drive;
- static const byte head_vals[] = {4, 8, 16, 32, 64, 128, 255, 0};
- const byte *heads = head_vals;
- unsigned long tracks;
-
- if ((drive = get_info_ptr(i_rdev)) == NULL || drive->forced_geom)
- return 0;
-
- if (xparm > 1 && xparm <= drive->bios_head && drive->bios_sect == 63)
- return 0; /* we already have a translation */
-
- printk("%s ", msg);
-
- if (drive->id) {
- drive->cyl = drive->id->cyls;
- drive->head = drive->id->heads;
- drive->sect = drive->id->sectors;
- }
- drive->bios_cyl = drive->cyl;
- drive->bios_head = drive->head;
- drive->bios_sect = drive->sect;
- drive->special.b.set_geometry = 1;
-
- tracks = drive->bios_cyl * drive->bios_head * drive->bios_sect / 63;
- drive->bios_sect = 63;
- if (xparm > 1) {
- drive->bios_head = xparm;
- drive->bios_cyl = tracks / drive->bios_head;
- } else {
- while (drive->bios_cyl >= 1024) {
- drive->bios_head = *heads;
- drive->bios_cyl = tracks / drive->bios_head;
- if (0 == *++heads)
- break;
- }
-#if FAKE_FDISK_FOR_EZDRIVE
- if (xparm == -1) {
- drive->remap_0_to_1 = 1;
- msg = "0->1";
- } else
-#endif /* FAKE_FDISK_FOR_EZDRIVE */
- if (xparm == 1) {
- drive->sect0 = 63;
- drive->bios_cyl = (tracks - 1) / drive->bios_head;
- msg = "+63";
- }
- printk("[remap %s] ", msg);
- }
- drive->part[0].nr_sects = current_capacity(drive);
- printk("[%d/%d/%d]", drive->bios_cyl, drive->bios_head, drive->bios_sect);
- return 1;
-}
-
-/*
- * We query CMOS about hard disks : it could be that we have a SCSI/ESDI/etc
- * controller that is BIOS compatible with ST-506, and thus showing up in our
- * BIOS table, but not register compatible, and therefore not present in CMOS.
- *
- * Furthermore, we will assume that our ST-506 drives <if any> are the primary
- * drives in the system -- the ones reflected as drive 1 or 2. The first
- * drive is stored in the high nibble of CMOS byte 0x12, the second in the low
- * nibble. This will be either a 4 bit drive type or 0xf indicating use byte
- * 0x19 for an 8 bit type, drive 1, 0x1a for drive 2 in CMOS. A non-zero value
- * means we have an AT controller hard disk for that drive.
- *
- * Of course, there is no guarantee that either drive is actually on the
- * "primary" IDE interface, but we don't bother trying to sort that out here.
- * If a drive is not actually on the primary interface, then these parameters
- * will be ignored. This results in the user having to supply the logical
- * drive geometry as a boot parameter for each drive not on the primary i/f.
- *
- * The only "perfect" way to handle this would be to modify the setup.[cS] code
- * to do BIOS calls Int13h/Fn08h and Int13h/Fn48h to get all of the drive info
- * for us during initialization. I have the necessary docs -- any takers? -ml
- */
-
-static void probe_cmos_for_drives (ide_hwif_t *hwif)
-{
-#ifdef __i386__
- extern struct drive_info_struct drive_info;
- byte cmos_disks, *BIOS = (byte *) &drive_info;
- int unit;
-
- outb_p(0x12,0x70); /* specify CMOS address 0x12 */
- cmos_disks = inb_p(0x71); /* read the data from 0x12 */
- /* Extract drive geometry from CMOS+BIOS if not already setup */
- for (unit = 0; unit < MAX_DRIVES; ++unit) {
- ide_drive_t *drive = &hwif->drives[unit];
- if ((cmos_disks & (0xf0 >> (unit*4))) && !drive->present) {
- drive->cyl = drive->bios_cyl = *(unsigned short *)BIOS;
- drive->head = drive->bios_head = *(BIOS+2);
- drive->sect = drive->bios_sect = *(BIOS+14);
- drive->ctl = *(BIOS+8);
- drive->present = 1;
- }
- BIOS += 16;
- }
-#endif
-}
-
-/*
- * This routine sets up the irq for an ide interface, and creates a new
- * hwgroup for the irq/hwif if none was previously assigned.
- *
- * The SA_INTERRUPT in sa_flags means ide_intr() is always entered with
- * interrupts completely disabled. This can be bad for interrupt latency,
- * but anything else has led to problems on some machines. We re-enable
- * interrupts as much as we can safely do in most places.
- */
-static int init_irq (ide_hwif_t *hwif)
-{
- unsigned long flags;
- int irq = hwif->irq;
- ide_hwgroup_t *hwgroup = irq_to_hwgroup[irq];
-
- save_flags(flags);
- cli();
-
- /*
- * Grab the irq if we don't already have it from a previous hwif
- */
- if (hwgroup == NULL) {
- if (request_irq(irq, ide_intr, SA_INTERRUPT|SA_SAMPLE_RANDOM, hwif->name)) {
- restore_flags(flags);
- printk(" -- FAILED!");
- return 1;
- }
- }
- /*
- * Check for serialization with ide1.
- * This code depends on us having already taken care of ide1.
- */
- if (hwif->serialized && hwif->name[3] == '0' && ide_hwifs[1].present)
- hwgroup = ide_hwifs[1].hwgroup;
- /*
- * If this is the first interface in a group,
- * then we need to create the hwgroup structure
- */
- if (hwgroup == NULL) {
- hwgroup = kmalloc (sizeof(ide_hwgroup_t), GFP_KERNEL);
- hwgroup->hwif = hwif->next = hwif;
- hwgroup->rq = NULL;
- hwgroup->handler = NULL;
- hwgroup->drive = &hwif->drives[0];
- hwgroup->poll_timeout = 0;
- init_timer(&hwgroup->timer);
- hwgroup->timer.function = &timer_expiry;
- hwgroup->timer.data = (unsigned long) hwgroup;
- } else {
- hwif->next = hwgroup->hwif->next;
- hwgroup->hwif->next = hwif;
- }
- hwif->hwgroup = hwgroup;
- irq_to_hwgroup[irq] = hwgroup;
-
- restore_flags(flags); /* safe now that hwif->hwgroup is set up */
-
- printk("%s at 0x%03x-0x%03x,0x%03x on irq %d", hwif->name,
- hwif->io_base, hwif->io_base+7, hwif->ctl_port, irq);
- if (hwgroup->hwif != hwif)
- printk(" (serialized with %s)", hwgroup->hwif->name);
- printk("\n");
- return 0;
-}
-
-static struct file_operations ide_fops = {
- NULL, /* lseek - default */
- block_read, /* read - general block-dev read */
- block_write, /* write - general block-dev write */
- NULL, /* readdir - bad */
- NULL, /* select */
- ide_ioctl, /* ioctl */
- NULL, /* mmap */
- ide_open, /* open */
- ide_release, /* release */
- block_fsync /* fsync */
- ,NULL, /* fasync */
- ide_check_media_change, /* check_media_change */
- revalidate_disk /* revalidate */
-};
-
-#ifdef CONFIG_PCI
-#if defined(CONFIG_BLK_DEV_RZ1000) || defined(CONFIG_BLK_DEV_TRITON)
-
-typedef void (ide_pci_init_proc_t)(byte, byte);
-
-/*
- * ide_probe_pci() scans PCI for a specific vendor/device function,
- * and invokes the supplied init routine for each instance detected.
- */
-static void ide_probe_pci (unsigned short vendor, unsigned short device, ide_pci_init_proc_t *init, int func_adj)
-{
- unsigned long flags;
- unsigned index;
- byte fn, bus;
-
- save_flags(flags);
- cli();
- for (index = 0; !pcibios_find_device (vendor, device, index, &bus, &fn); ++index) {
- init (bus, fn + func_adj);
- }
- restore_flags(flags);
-}
-
-#endif /* defined(CONFIG_BLK_DEV_RZ1000) || defined(CONFIG_BLK_DEV_TRITON) */
-#endif /* CONFIG_PCI */
-
-/*
- * ide_init_pci() finds/initializes "known" PCI IDE interfaces
- *
- * This routine should ideally be using pcibios_find_class() to find
- * all IDE interfaces, but that function causes some systems to "go weird".
- */
-static void probe_for_hwifs (void)
-{
-#ifdef CONFIG_PCI
- /*
- * Find/initialize PCI IDE interfaces
- */
- if (pcibios_present()) {
-#ifdef CONFIG_BLK_DEV_RZ1000
- ide_pci_init_proc_t init_rz1000;
- ide_probe_pci (PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1000, &init_rz1000, 0);
-#endif /* CONFIG_BLK_DEV_RZ1000 */
-#ifdef CONFIG_BLK_DEV_TRITON
- /*
- * Apparently the BIOS32 services on Intel motherboards are
- * buggy and won't find the PCI_DEVICE_ID_INTEL_82371_1 for us.
- * So instead, we search for PCI_DEVICE_ID_INTEL_82371_0,
- * and then add 1.
- */
- ide_probe_pci (PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371_0, &ide_init_triton, 1);
-#endif /* CONFIG_BLK_DEV_TRITON */
- }
-#endif /* CONFIG_PCI */
-#ifdef CONFIG_BLK_DEV_CMD640
- {
- extern void ide_probe_for_cmd640x (void);
- ide_probe_for_cmd640x();
- }
-#endif
-}
-
-/*
- * This is gets invoked once during initialization, to set *everything* up
- */
-int ide_init (void)
-{
- int h;
-
- init_ide_data ();
- /*
- * Probe for special "known" interface chipsets
- */
- probe_for_hwifs ();
-
- /*
- * Probe for drives in the usual way.. CMOS/BIOS, then poke at ports
- */
- for (h = 0; h < MAX_HWIFS; ++h) {
- ide_hwif_t *hwif = &ide_hwifs[h];
- if (!hwif->noprobe) {
- if (hwif->io_base == HD_DATA)
- probe_cmos_for_drives (hwif);
- probe_for_drives (hwif);
- }
- if (hwif->present) {
- if (!hwif->irq) {
- if (!(hwif->irq = default_irqs[h])) {
- printk("%s: DISABLED, NO IRQ\n", hwif->name);
- hwif->present = 0;
- continue;
- }
- }
-#ifdef CONFIG_BLK_DEV_HD
- if (hwif->irq == HD_IRQ && hwif->io_base != HD_DATA) {
- printk("%s: CANNOT SHARE IRQ WITH OLD HARDDISK DRIVER (hd.c)\n", hwif->name);
- hwif->present = 0;
- }
-#endif /* CONFIG_BLK_DEV_HD */
- }
- }
-
- /*
- * Now we try to set up irqs and major devices for what was found
- */
- for (h = MAX_HWIFS-1; h >= 0; --h) {
- void (*rfn)(void);
- ide_hwif_t *hwif = &ide_hwifs[h];
- if (!hwif->present)
- continue;
- hwif->present = 0; /* we set it back to 1 if all is ok below */
- switch (hwif->major) {
- case IDE0_MAJOR: rfn = &do_ide0_request; break;
- case IDE1_MAJOR: rfn = &do_ide1_request; break;
- case IDE2_MAJOR: rfn = &do_ide2_request; break;
- case IDE3_MAJOR: rfn = &do_ide3_request; break;
- default:
- printk("%s: request_fn NOT DEFINED\n", hwif->name);
- continue;
- }
- if (register_blkdev (hwif->major, hwif->name, &ide_fops)) {
- printk("%s: UNABLE TO GET MAJOR NUMBER %d\n", hwif->name, hwif->major);
- } else if (init_irq (hwif)) {
- printk("%s: UNABLE TO GET IRQ %d\n", hwif->name, hwif->irq);
- (void) unregister_blkdev (hwif->major, hwif->name);
- } else {
- init_gendisk(hwif);
- blk_dev[hwif->major].request_fn = rfn;
- read_ahead[hwif->major] = 8; /* (4kB) */
- hwif->present = 1; /* success */
- }
- }
-
-#ifdef CONFIG_BLK_DEV_IDETAPE
- idetape_register_chrdev(); /* Register character device interface to the ide tape */
-#endif /* CONFIG_BLK_DEV_IDETAPE */
-
- return 0;
-}
diff --git a/i386/i386at/gpl/linux/block/ide.h b/i386/i386at/gpl/linux/block/ide.h
deleted file mode 100644
index b1ebc4c3..00000000
--- a/i386/i386at/gpl/linux/block/ide.h
+++ /dev/null
@@ -1,655 +0,0 @@
-/*
- * linux/drivers/block/ide.h
- *
- * Copyright (C) 1994, 1995 Linus Torvalds & authors
- */
-
-#include <linux/config.h>
-
-/*
- * This is the multiple IDE interface driver, as evolved from hd.c.
- * It supports up to four IDE interfaces, on one or more IRQs (usually 14 & 15).
- * There can be up to two drives per interface, as per the ATA-2 spec.
- *
- * Primary i/f: ide0: major=3; (hda) minor=0; (hdb) minor=64
- * Secondary i/f: ide1: major=22; (hdc or hd1a) minor=0; (hdd or hd1b) minor=64
- * Tertiary i/f: ide2: major=33; (hde) minor=0; (hdf) minor=64
- * Quaternary i/f: ide3: major=34; (hdg) minor=0; (hdh) minor=64
- */
-
-/******************************************************************************
- * IDE driver configuration options (play with these as desired):
- *
- * REALLY_SLOW_IO can be defined in ide.c and ide-cd.c, if necessary
- */
-#undef REALLY_FAST_IO /* define if ide ports are perfect */
-#define INITIAL_MULT_COUNT 0 /* off=0; on=2,4,8,16,32, etc.. */
-
-#ifndef SUPPORT_VLB_SYNC /* 1 to support weird 32-bit chips */
-#define SUPPORT_VLB_SYNC 1 /* 0 to reduce kernel size */
-#endif
-#ifndef DISK_RECOVERY_TIME /* off=0; on=access_delay_time */
-#define DISK_RECOVERY_TIME 0 /* for hardware that needs it */
-#endif
-#ifndef OK_TO_RESET_CONTROLLER /* 1 needed for good error recovery */
-#define OK_TO_RESET_CONTROLLER 1 /* 0 for use with AH2372A/B interface */
-#endif
-#ifndef FAKE_FDISK_FOR_EZDRIVE /* 1 to help linux fdisk with EZDRIVE */
-#define FAKE_FDISK_FOR_EZDRIVE 1 /* 0 to reduce kernel size */
-#endif
-#ifndef FANCY_STATUS_DUMPS /* 1 for human-readable drive errors */
-#define FANCY_STATUS_DUMPS 1 /* 0 to reduce kernel size */
-#endif
-
-#if defined(CONFIG_BLK_DEV_IDECD) || defined(CONFIG_BLK_DEV_IDETAPE)
-#define CONFIG_BLK_DEV_IDEATAPI 1
-#endif
-
-/*
- * IDE_DRIVE_CMD is used to implement many features of the hdparm utility
- */
-#define IDE_DRIVE_CMD 99 /* (magic) undef to reduce kernel size*/
-
-/*
- * "No user-serviceable parts" beyond this point :)
- *****************************************************************************/
-
-typedef unsigned char byte; /* used everywhere */
-
-/*
- * Probably not wise to fiddle with these
- */
-#define ERROR_MAX 8 /* Max read/write errors per sector */
-#define ERROR_RESET 3 /* Reset controller every 4th retry */
-#define ERROR_RECAL 1 /* Recalibrate every 2nd retry */
-
-/*
- * Ensure that various configuration flags have compatible settings
- */
-#ifdef REALLY_SLOW_IO
-#undef REALLY_FAST_IO
-#endif
-
-/*
- * Definitions for accessing IDE controller registers
- */
-
-#define HWIF(drive) ((ide_hwif_t *)drive->hwif)
-#define HWGROUP(drive) ((ide_hwgroup_t *)(HWIF(drive)->hwgroup))
-
-#define IDE_DATA_OFFSET (0)
-#define IDE_ERROR_OFFSET (1)
-#define IDE_NSECTOR_OFFSET (2)
-#define IDE_SECTOR_OFFSET (3)
-#define IDE_LCYL_OFFSET (4)
-#define IDE_HCYL_OFFSET (5)
-#define IDE_SELECT_OFFSET (6)
-#define IDE_STATUS_OFFSET (7)
-#define IDE_FEATURE_OFFSET IDE_ERROR_OFFSET
-#define IDE_COMMAND_OFFSET IDE_STATUS_OFFSET
-
-#define IDE_DATA_REG (HWIF(drive)->io_base+IDE_DATA_OFFSET)
-#define IDE_ERROR_REG (HWIF(drive)->io_base+IDE_ERROR_OFFSET)
-#define IDE_NSECTOR_REG (HWIF(drive)->io_base+IDE_NSECTOR_OFFSET)
-#define IDE_SECTOR_REG (HWIF(drive)->io_base+IDE_SECTOR_OFFSET)
-#define IDE_LCYL_REG (HWIF(drive)->io_base+IDE_LCYL_OFFSET)
-#define IDE_HCYL_REG (HWIF(drive)->io_base+IDE_HCYL_OFFSET)
-#define IDE_SELECT_REG (HWIF(drive)->io_base+IDE_SELECT_OFFSET)
-#define IDE_STATUS_REG (HWIF(drive)->io_base+IDE_STATUS_OFFSET)
-#define IDE_CONTROL_REG (HWIF(drive)->ctl_port)
-#define IDE_FEATURE_REG IDE_ERROR_REG
-#define IDE_COMMAND_REG IDE_STATUS_REG
-#define IDE_ALTSTATUS_REG IDE_CONTROL_REG
-
-#ifdef REALLY_FAST_IO
-#define OUT_BYTE(b,p) outb((b),p)
-#define IN_BYTE(p) (byte)inb(p)
-#else
-#define OUT_BYTE(b,p) outb_p((b),p)
-#define IN_BYTE(p) (byte)inb_p(p)
-#endif /* REALLY_FAST_IO */
-
-#define GET_ERR() IN_BYTE(IDE_ERROR_REG)
-#define GET_STAT() IN_BYTE(IDE_STATUS_REG)
-#define OK_STAT(stat,good,bad) (((stat)&((good)|(bad)))==(good))
-#define BAD_R_STAT (BUSY_STAT | ERR_STAT)
-#define BAD_W_STAT (BAD_R_STAT | WRERR_STAT)
-#define BAD_STAT (BAD_R_STAT | DRQ_STAT)
-#define DRIVE_READY (READY_STAT | SEEK_STAT)
-#define DATA_READY (DRIVE_READY | DRQ_STAT)
-
-/*
- * Some more useful definitions
- */
-#define IDE_MAJOR_NAME "ide" /* the same for all i/f; see also genhd.c */
-#define MAJOR_NAME IDE_MAJOR_NAME
-#define PARTN_BITS 6 /* number of minor dev bits for partitions */
-#define PARTN_MASK ((1<<PARTN_BITS)-1) /* a useful bit mask */
-#define MAX_DRIVES 2 /* per interface; 2 assumed by lots of code */
-#define MAX_HWIFS 4 /* an arbitrary, but realistic limit */
-#define SECTOR_WORDS (512 / 4) /* number of 32bit words per sector */
-
-/*
- * Timeouts for various operations:
- */
-#define WAIT_DRQ (5*HZ/100) /* 50msec - spec allows up to 20ms */
-#define WAIT_READY (3*HZ/100) /* 30msec - should be instantaneous */
-#define WAIT_PIDENTIFY (1*HZ) /* 1sec - should be less than 3ms (?) */
-#define WAIT_WORSTCASE (30*HZ) /* 30sec - worst case when spinning up */
-#define WAIT_CMD (10*HZ) /* 10sec - maximum wait for an IRQ to happen */
-
-#ifdef CONFIG_BLK_DEV_IDETAPE
-#include "ide-tape.h"
-#endif /* CONFIG_BLK_DEV_IDETAPE */
-
-#ifdef CONFIG_BLK_DEV_IDECD
-
-struct atapi_request_sense {
- unsigned char error_code : 7;
- unsigned char valid : 1;
- byte reserved1;
- unsigned char sense_key : 4;
- unsigned char reserved2 : 1;
- unsigned char ili : 1;
- unsigned char reserved3 : 2;
- byte info[4];
- byte sense_len;
- byte command_info[4];
- byte asc;
- byte ascq;
- byte fru;
- byte sense_key_specific[3];
-};
-
-struct packet_command {
- char *buffer;
- int buflen;
- int stat;
- struct atapi_request_sense *sense_data;
- unsigned char c[12];
-};
-
-/* Space to hold the disk TOC. */
-
-#define MAX_TRACKS 99
-struct atapi_toc_header {
- unsigned short toc_length;
- byte first_track;
- byte last_track;
-};
-
-struct atapi_toc_entry {
- byte reserved1;
- unsigned control : 4;
- unsigned adr : 4;
- byte track;
- byte reserved2;
- union {
- unsigned lba;
- struct {
- byte reserved3;
- byte m;
- byte s;
- byte f;
- } msf;
- } addr;
-};
-
-struct atapi_toc {
- int last_session_lba;
- int xa_flag;
- unsigned capacity;
- struct atapi_toc_header hdr;
- struct atapi_toc_entry ent[MAX_TRACKS+1]; /* One extra for the leadout. */
-};
-
-
-/* This structure is annoyingly close to, but not identical with,
- the cdrom_subchnl structure from cdrom.h. */
-struct atapi_cdrom_subchnl
-{
- u_char acdsc_reserved;
- u_char acdsc_audiostatus;
- u_short acdsc_length;
- u_char acdsc_format;
-
- u_char acdsc_adr: 4;
- u_char acdsc_ctrl: 4;
- u_char acdsc_trk;
- u_char acdsc_ind;
- union
- {
- struct
- {
- u_char minute;
- u_char second;
- u_char frame;
- } msf;
- int lba;
- } acdsc_absaddr;
- union
- {
- struct
- {
- u_char minute;
- u_char second;
- u_char frame;
- } msf;
- int lba;
- } acdsc_reladdr;
-};
-
-
-/* Extra per-device info for cdrom drives. */
-struct cdrom_info {
-
- /* Buffer for table of contents. NULL if we haven't allocated
- a TOC buffer for this device yet. */
-
- struct atapi_toc *toc;
-
- /* Sector buffer. If a read request wants only the first part of a cdrom
- block, we cache the rest of the block here, in the expectation that that
- data is going to be wanted soon. SECTOR_BUFFERED is the number of the
- first buffered sector, and NSECTORS_BUFFERED is the number of sectors
- in the buffer. Before the buffer is allocated, we should have
- SECTOR_BUFFER == NULL and NSECTORS_BUFFERED == 0. */
-
- unsigned long sector_buffered;
- unsigned long nsectors_buffered;
- char *sector_buffer;
-
- /* The result of the last successful request sense command
- on this device. */
- struct atapi_request_sense sense_data;
-};
-
-#endif /* CONFIG_BLK_DEV_IDECD */
-
-/*
- * Now for the data we need to maintain per-drive: ide_drive_t
- */
-
-typedef enum {ide_disk, ide_cdrom, ide_tape} ide_media_t;
-
-typedef union {
- unsigned all : 8; /* all of the bits together */
- struct {
- unsigned set_geometry : 1; /* respecify drive geometry */
- unsigned recalibrate : 1; /* seek to cyl 0 */
- unsigned set_multmode : 1; /* set multmode count */
- unsigned set_pio : 1; /* set pio mode */
- unsigned reserved : 4; /* unused */
- } b;
- } special_t;
-
-typedef union {
- unsigned all : 8; /* all of the bits together */
- struct {
- unsigned head : 4; /* always zeros here */
- unsigned unit : 1; /* drive select number, 0 or 1 */
- unsigned bit5 : 1; /* always 1 */
- unsigned lba : 1; /* using LBA instead of CHS */
- unsigned bit7 : 1; /* always 1 */
- } b;
- } select_t;
-
-typedef struct ide_drive_s {
- special_t special; /* special action flags */
- unsigned present : 1; /* drive is physically present */
- unsigned noprobe : 1; /* from: hdx=noprobe */
- unsigned keep_settings : 1; /* restore settings after drive reset */
- unsigned busy : 1; /* currently doing revalidate_disk() */
- unsigned removeable : 1; /* 1 if need to do check_media_change */
- unsigned using_dma : 1; /* disk is using dma for read/write */
- unsigned forced_geom : 1; /* 1 if hdx=c,h,s was given at boot */
- unsigned unmask : 1; /* flag: okay to unmask other irqs */
- unsigned autotune : 2; /* 1=autotune, 2=noautotune, 0=default */
-#if FAKE_FDISK_FOR_EZDRIVE
- unsigned remap_0_to_1 : 1; /* flag: partitioned with ezdrive */
-#endif /* FAKE_FDISK_FOR_EZDRIVE */
- ide_media_t media; /* disk, cdrom, tape */
- select_t select; /* basic drive/head select reg value */
- byte ctl; /* "normal" value for IDE_CONTROL_REG */
- byte ready_stat; /* min status value for drive ready */
- byte mult_count; /* current multiple sector setting */
- byte mult_req; /* requested multiple sector setting */
- byte pio_req; /* requested multiple sector setting */
- byte io_32bit; /* 0=16-bit, 1=32-bit, 2/3=32bit+sync */
- byte bad_wstat; /* used for ignoring WRERR_STAT */
- byte sect0; /* offset of first sector for DM6:DDO */
- byte usage; /* current "open()" count for drive */
- byte head; /* "real" number of heads */
- byte sect; /* "real" sectors per track */
- byte bios_head; /* BIOS/fdisk/LILO number of heads */
- byte bios_sect; /* BIOS/fdisk/LILO sectors per track */
- unsigned short bios_cyl; /* BIOS/fdisk/LILO number of cyls */
- unsigned short cyl; /* "real" number of cyls */
- void *hwif; /* actually (ide_hwif_t *) */
- struct wait_queue *wqueue; /* used to wait for drive in open() */
- struct hd_driveid *id; /* drive model identification info */
- struct hd_struct *part; /* drive partition table */
- char name[4]; /* drive name, such as "hda" */
-#ifdef CONFIG_BLK_DEV_IDECD
- struct cdrom_info cdrom_info; /* for ide-cd.c */
-#endif /* CONFIG_BLK_DEV_IDECD */
-#ifdef CONFIG_BLK_DEV_IDETAPE
- idetape_tape_t tape; /* for ide-tape.c */
-#endif /* CONFIG_BLK_DEV_IDETAPE */
-
- } ide_drive_t;
-
-/*
- * An ide_dmaproc_t() initiates/aborts DMA read/write operations on a drive.
- *
- * The caller is assumed to have selected the drive and programmed the drive's
- * sector address using CHS or LBA. All that remains is to prepare for DMA
- * and then issue the actual read/write DMA/PIO command to the drive.
- *
- * Returns 0 if all went well.
- * Returns 1 if DMA read/write could not be started, in which case the caller
- * should either try again later, or revert to PIO for the current request.
- */
-typedef enum { ide_dma_read = 0, ide_dma_write = 1,
- ide_dma_abort = 2, ide_dma_check = 3,
- ide_dma_status_bad = 4, ide_dma_transferred = 5,
- ide_dma_begin = 6 }
- ide_dma_action_t;
-
-typedef int (ide_dmaproc_t)(ide_dma_action_t, ide_drive_t *);
-
-
-/*
- * An ide_tuneproc_t() is used to set the speed of an IDE interface
- * to a particular PIO mode. The "byte" parameter is used
- * to select the PIO mode by number (0,1,2,3,4,5), and a value of 255
- * indicates that the interface driver should "auto-tune" the PIO mode
- * according to the drive capabilities in drive->id;
- *
- * Not all interface types support tuning, and not all of those
- * support all possible PIO settings. They may silently ignore
- * or round values as they see fit.
- */
-typedef void (ide_tuneproc_t)(ide_drive_t *, byte);
-
-/*
- * This is used to provide HT6560B interface support.
- * It will probably also be used by the DC4030VL driver.
- */
-typedef void (ide_selectproc_t) (ide_drive_t *);
-
-/*
- * hwif_chipset_t is used to keep track of the specific hardware
- * chipset used by each IDE interface, if known.
- */
-typedef enum { ide_unknown, ide_generic, ide_triton,
- ide_cmd640, ide_dtc2278, ide_ali14xx,
- ide_qd6580, ide_umc8672, ide_ht6560b }
- hwif_chipset_t;
-
-typedef struct hwif_s {
- struct hwif_s *next; /* for linked-list in ide_hwgroup_t */
- void *hwgroup; /* actually (ide_hwgroup_t *) */
- unsigned short io_base; /* base io port addr */
- unsigned short ctl_port; /* usually io_base+0x206 */
- ide_drive_t drives[MAX_DRIVES]; /* drive info */
- struct gendisk *gd; /* gendisk structure */
- ide_tuneproc_t *tuneproc; /* routine to tune PIO mode for drives */
-#ifdef CONFIG_BLK_DEV_HT6560B
- ide_selectproc_t *selectproc; /* tweaks hardware to select drive */
-#endif /* CONFIG_BLK_DEV_HT6560B */
- ide_dmaproc_t *dmaproc; /* dma read/write/abort routine */
- unsigned long *dmatable; /* dma physical region descriptor table */
- unsigned short dma_base; /* base addr for dma ports (triton) */
- byte irq; /* our irq number */
- byte major; /* our major number */
- char name[5]; /* name of interface, eg. "ide0" */
- byte index; /* 0 for ide0; 1 for ide1; ... */
- hwif_chipset_t chipset; /* sub-module for tuning.. */
- unsigned noprobe : 1; /* don't probe for this interface */
- unsigned present : 1; /* this interface exists */
- unsigned serialized : 1; /* valid only for ide_hwifs[0] */
- unsigned no_unmask : 1; /* disallow setting unmask bits */
-#if (DISK_RECOVERY_TIME > 0)
- unsigned long last_time; /* time when previous rq was done */
-#endif
-#ifdef CONFIG_BLK_DEV_IDECD
- struct request request_sense_request; /* from ide-cd.c */
- struct packet_command request_sense_pc; /* from ide-cd.c */
-#endif /* CONFIG_BLK_DEV_IDECD */
-#ifdef CONFIG_BLK_DEV_IDETAPE
- ide_drive_t *tape_drive; /* Pointer to the tape on this interface */
-#endif /* CONFIG_BLK_DEV_IDETAPE */
- } ide_hwif_t;
-
-/*
- * internal ide interrupt handler type
- */
-typedef void (ide_handler_t)(ide_drive_t *);
-
-typedef struct hwgroup_s {
- ide_handler_t *handler;/* irq handler, if active */
- ide_drive_t *drive; /* current drive */
- ide_hwif_t *hwif; /* ptr to current hwif in linked-list */
- struct request *rq; /* current request */
- struct timer_list timer; /* failsafe timer */
- struct request wrq; /* local copy of current write rq */
- unsigned long poll_timeout; /* timeout value during long polls */
- } ide_hwgroup_t;
-
-/*
- * ide_hwifs[] is the master data structure used to keep track
- * of just about everything in ide.c. Whenever possible, routines
- * should be using pointers to a drive (ide_drive_t *) or
- * pointers to a hwif (ide_hwif_t *), rather than indexing this
- * structure directly (the allocation/layout may change!).
- */
-#ifdef _IDE_C
- ide_hwif_t ide_hwifs[MAX_HWIFS]; /* master data repository */
-#else
-extern ide_hwif_t ide_hwifs[];
-#endif
-
-/*
- * One final include file, which references some of the data/defns from above
- */
-#define IDE_DRIVER /* "parameter" for blk.h */
-#include <linux/blk.h>
-
-#if (DISK_RECOVERY_TIME > 0)
-void ide_set_recovery_timer (ide_hwif_t *);
-#define SET_RECOVERY_TIMER(drive) ide_set_recovery_timer (drive)
-#else
-#define SET_RECOVERY_TIMER(drive)
-#endif
-
-/*
- * This is used for (nearly) all data transfers from the IDE interface
- */
-void ide_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount);
-
-/*
- * This is used for (nearly) all data transfers to the IDE interface
- */
-void ide_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount);
-
-/*
- * This is used on exit from the driver, to designate the next irq handler
- * and also to start the safety timer.
- */
-void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, unsigned int timeout);
-
-/*
- * Error reporting, in human readable form (luxurious, but a memory hog).
- */
-byte ide_dump_status (ide_drive_t *drive, const char *msg, byte stat);
-
-/*
- * ide_error() takes action based on the error returned by the controller.
- * The calling function must return afterwards, to restart the request.
- */
-void ide_error (ide_drive_t *drive, const char *msg, byte stat);
-
-/*
- * ide_fixstring() cleans up and (optionally) byte-swaps a text string,
- * removing leading/trailing blanks and compressing internal blanks.
- * It is primarily used to tidy up the model name/number fields as
- * returned by the WIN_[P]IDENTIFY commands.
- */
-void ide_fixstring (byte *s, const int bytecount, const int byteswap);
-
-/*
- * This routine busy-waits for the drive status to be not "busy".
- * It then checks the status for all of the "good" bits and none
- * of the "bad" bits, and if all is okay it returns 0. All other
- * cases return 1 after invoking ide_error() -- caller should return.
- *
- */
-int ide_wait_stat (ide_drive_t *drive, byte good, byte bad, unsigned long timeout);
-
-/*
- * This routine is called from the partition-table code in genhd.c
- * to "convert" a drive to a logical geometry with fewer than 1024 cyls.
- *
- * The second parameter, "xparm", determines exactly how the translation
- * will be handled:
- * 0 = convert to CHS with fewer than 1024 cyls
- * using the same method as Ontrack DiskManager.
- * 1 = same as "0", plus offset everything by 63 sectors.
- * -1 = similar to "0", plus redirect sector 0 to sector 1.
- * >1 = convert to a CHS geometry with "xparm" heads.
- *
- * Returns 0 if the translation was not possible, if the device was not
- * an IDE disk drive, or if a geometry was "forced" on the commandline.
- * Returns 1 if the geometry translation was successful.
- */
-int ide_xlate_1024 (kdev_t, int, const char *);
-
-/*
- * Start a reset operation for an IDE interface.
- * The caller should return immediately after invoking this.
- */
-void ide_do_reset (ide_drive_t *);
-
-/*
- * This function is intended to be used prior to invoking ide_do_drive_cmd().
- */
-void ide_init_drive_cmd (struct request *rq);
-
-/*
- * "action" parameter type for ide_do_drive_cmd() below.
- */
-typedef enum
- {ide_wait, /* insert rq at end of list, and wait for it */
- ide_next, /* insert rq immediately after current request */
- ide_preempt, /* insert rq in front of current request */
- ide_end} /* insert rq at end of list, but don't wait for it */
- ide_action_t;
-
-/*
- * This function issues a special IDE device request
- * onto the request queue.
- *
- * If action is ide_wait, then then rq is queued at the end of
- * the request queue, and the function sleeps until it has been
- * processed. This is for use when invoked from an ioctl handler.
- *
- * If action is ide_preempt, then the rq is queued at the head of
- * the request queue, displacing the currently-being-processed
- * request and this function returns immediately without waiting
- * for the new rq to be completed. This is VERY DANGEROUS, and is
- * intended for careful use by the ATAPI tape/cdrom driver code.
- *
- * If action is ide_next, then the rq is queued immediately after
- * the currently-being-processed-request (if any), and the function
- * returns without waiting for the new rq to be completed. As above,
- * This is VERY DANGEROUS, and is intended for careful use by the
- * ATAPI tape/cdrom driver code.
- *
- * If action is ide_end, then the rq is queued at the end of the
- * request queue, and the function returns immediately without waiting
- * for the new rq to be completed. This is again intended for careful
- * use by the ATAPI tape/cdrom driver code. (Currently used by ide-tape.c,
- * when operating in the pipelined operation mode).
- */
-int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t action);
-
-/*
- * Clean up after success/failure of an explicit drive cmd.
- * stat/err are used only when (HWGROUP(drive)->rq->cmd == IDE_DRIVE_CMD).
- */
-void ide_end_drive_cmd (ide_drive_t *drive, byte stat, byte err);
-
-#ifdef CONFIG_BLK_DEV_IDECD
-/*
- * These are routines in ide-cd.c invoked from ide.c
- */
-void ide_do_rw_cdrom (ide_drive_t *, unsigned long);
-int ide_cdrom_ioctl (ide_drive_t *, struct inode *, struct file *, unsigned int, unsigned long);
-int ide_cdrom_check_media_change (ide_drive_t *);
-int ide_cdrom_open (struct inode *, struct file *, ide_drive_t *);
-void ide_cdrom_release (struct inode *, struct file *, ide_drive_t *);
-void ide_cdrom_setup (ide_drive_t *);
-#endif /* CONFIG_BLK_DEV_IDECD */
-
-#ifdef CONFIG_BLK_DEV_IDETAPE
-
-/*
- * Functions in ide-tape.c which are invoked from ide.c:
- */
-
-/*
- * idetape_identify_device is called during device probing stage to
- * probe for an ide atapi tape drive and to initialize global variables
- * in ide-tape.c which provide the link between the character device
- * and the correspoding block device.
- *
- * Returns 1 if an ide tape was detected and is supported.
- * Returns 0 otherwise.
- */
-
-int idetape_identify_device (ide_drive_t *drive,struct hd_driveid *id);
-
-/*
- * idetape_setup is called a bit later than idetape_identify_device,
- * during the search for disk partitions, to initialize various tape
- * state variables in ide_drive_t *drive.
- */
-
-void idetape_setup (ide_drive_t *drive);
-
-/*
- * idetape_do_request is our request function. It is called by ide.c
- * to process a new request.
- */
-
-void idetape_do_request (ide_drive_t *drive, struct request *rq, unsigned long block);
-
-/*
- * idetape_end_request is used to finish servicing a request, and to
- * insert a pending pipeline request into the main device queue.
- */
-
-void idetape_end_request (byte uptodate, ide_hwgroup_t *hwgroup);
-
-/*
- * Block device interface functions.
- */
-
-int idetape_blkdev_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg);
-int idetape_blkdev_open (struct inode *inode, struct file *filp, ide_drive_t *drive);
-void idetape_blkdev_release (struct inode *inode, struct file *filp, ide_drive_t *drive);
-
-/*
- * idetape_register_chrdev initializes the character device interface to
- * the ide tape drive.
- */
-
-void idetape_register_chrdev (void);
-
-#endif /* CONFIG_BLK_DEV_IDETAPE */
-
-#ifdef CONFIG_BLK_DEV_TRITON
-void ide_init_triton (byte, byte);
-#endif /* CONFIG_BLK_DEV_TRITON */
diff --git a/i386/i386at/gpl/linux/block/ide_modes.h b/i386/i386at/gpl/linux/block/ide_modes.h
deleted file mode 100644
index e174d5dc..00000000
--- a/i386/i386at/gpl/linux/block/ide_modes.h
+++ /dev/null
@@ -1,142 +0,0 @@
-#ifndef _IDE_MODES_H
-#define _IDE_MODES_H
-/*
- * linux/drivers/block/ide_modes.h
- *
- * Copyright (C) 1996 Linus Torvalds, Igor Abramov, and Mark Lord
- */
-
-/*
- * Shared data/functions for determining best PIO mode for an IDE drive.
- * Most of this stuff originally lived in cmd640.c, and changes to the
- * ide_pio_blacklist[] table should be made with EXTREME CAUTION to avoid
- * breaking the fragile cmd640.c support.
- */
-
-#if defined(CONFIG_BLK_DEV_CMD640) || defined(CONFIG_IDE_CHIPSETS)
-
-#ifndef _IDE_C
-
-int ide_scan_pio_blacklist (char *model);
-unsigned int ide_get_best_pio_mode (ide_drive_t *drive);
-
-#else /* _IDE_C */
-
-/*
- * Black list. Some drives incorrectly report their maximal PIO mode,
- * at least in respect to CMD640. Here we keep info on some known drives.
- */
-static struct ide_pio_info {
- const char *name;
- int pio;
-} ide_pio_blacklist [] = {
-/* { "Conner Peripherals 1275MB - CFS1275A", 4 }, */
-
- { "WDC AC2700", 3 },
- { "WDC AC2540", 3 },
- { "WDC AC2420", 3 },
- { "WDC AC2340", 3 },
- { "WDC AC2250", 0 },
- { "WDC AC2200", 0 },
- { "WDC AC2120", 0 },
- { "WDC AC2850", 3 },
- { "WDC AC1270", 3 },
- { "WDC AC1170", 3 },
- { "WDC AC1210", 1 },
- { "WDC AC280", 0 },
-/* { "WDC AC21000", 4 }, */
- { "WDC AC31000", 3 },
-/* { "WDC AC21200", 4 }, */
- { "WDC AC31200", 3 },
-/* { "WDC AC31600", 4 }, */
-
- { "Maxtor 7131 AT", 1 },
- { "Maxtor 7171 AT", 1 },
- { "Maxtor 7213 AT", 1 },
- { "Maxtor 7245 AT", 1 },
- { "Maxtor 7345 AT", 1 },
- { "Maxtor 7546 AT", 3 },
- { "Maxtor 7540 AV", 3 },
-
- { "SAMSUNG SHD-3121A", 1 },
- { "SAMSUNG SHD-3122A", 1 },
- { "SAMSUNG SHD-3172A", 1 },
-
-/* { "ST51080A", 4 },
- * { "ST51270A", 4 },
- * { "ST31220A", 4 },
- * { "ST31640A", 4 },
- * { "ST32140A", 4 },
- * { "ST3780A", 4 },
- */
- { "ST5660A", 3 },
- { "ST3660A", 3 },
- { "ST3630A", 3 },
- { "ST3655A", 3 },
- { "ST3391A", 3 },
- { "ST3390A", 1 },
- { "ST3600A", 1 },
- { "ST3290A", 0 },
- { "ST3144A", 0 },
-
- { "QUANTUM ELS127A", 0 },
- { "QUANTUM ELS170A", 0 },
- { "QUANTUM LPS240A", 0 },
- { "QUANTUM LPS210A", 3 },
- { "QUANTUM LPS270A", 3 },
- { "QUANTUM LPS365A", 3 },
- { "QUANTUM LPS540A", 3 },
- { "QUANTUM FIREBALL", 3 }, /* For models 540/640/1080/1280 */
- /* 1080A works fine in mode4 with triton */
- { NULL, 0 }
-};
-
-/*
- * This routine searches the ide_pio_blacklist for an entry
- * matching the start/whole of the supplied model name.
- *
- * Returns -1 if no match found.
- * Otherwise returns the recommended PIO mode from ide_pio_blacklist[].
- */
-int ide_scan_pio_blacklist (char *model)
-{
- struct ide_pio_info *p;
-
- for (p = ide_pio_blacklist; p->name != NULL; p++) {
- if (strncmp(p->name, model, strlen(p->name)) == 0)
- return p->pio;
- }
- return -1;
-}
-
-/*
- * This routine returns the recommended PIO mode for a given drive,
- * based on the drive->id information and the ide_pio_blacklist[].
- * This is used by most chipset support modules when "auto-tuning".
- */
-unsigned int ide_get_best_pio_mode (ide_drive_t *drive)
-{
- unsigned int pio = 0;
- struct hd_driveid *id = drive->id;
-
- if (id != NULL) {
- if (HWIF(drive)->chipset != ide_cmd640 && !strcmp("QUANTUM FIREBALL1080A", id->model))
- pio = 4;
- else
- pio = ide_scan_pio_blacklist(id->model);
- if (pio == -1) {
- pio = (id->tPIO < 2) ? id->tPIO : 2;
- if (id->field_valid & 2) {
- byte modes = id->eide_pio_modes;
- if (modes & 4) pio = 5;
- else if (modes & 2) pio = 4;
- else if (modes & 1) pio = 3;
- }
- }
- }
- return pio;
-}
-
-#endif /* _IDE_C */
-#endif /* defined(CONFIG_BLK_DEV_CMD640) || defined(CONFIG_IDE_CHIPSETS) */
-#endif /* _IDE_MODES_H */
diff --git a/i386/i386at/gpl/linux/block/rz1000.c b/i386/i386at/gpl/linux/block/rz1000.c
deleted file mode 100644
index 11f1dbd5..00000000
--- a/i386/i386at/gpl/linux/block/rz1000.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * linux/drivers/block/rz1000.c Version 0.02 Feb 08, 1996
- *
- * Copyright (C) 1995-1996 Linus Torvalds & author (see below)
- */
-
-/*
- * Principal Author/Maintainer: mlord@bnr.ca (Mark Lord)
- *
- * This file provides support for disabling the buggy read-ahead
- * mode of the RZ1000 IDE chipset, commonly used on Intel motherboards.
- */
-
-#undef REALLY_SLOW_IO /* most systems can safely undef this */
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
-#include <linux/ioport.h>
-#include <linux/blkdev.h>
-#include <linux/hdreg.h>
-#include <asm/io.h>
-#include <linux/bios32.h>
-#include <linux/pci.h>
-#include "ide.h"
-
-static void ide_pci_access_error (int rc)
-{
- printk("ide: pcibios access failed - %s\n", pcibios_strerror(rc));
-}
-
-void init_rz1000 (byte bus, byte fn)
-{
- int rc;
- unsigned short reg;
-
- printk("ide: buggy RZ1000 interface: ");
- if ((rc = pcibios_read_config_word (bus, fn, PCI_COMMAND, &reg))) {
- ide_pci_access_error (rc);
- } else if (!(reg & 1)) {
- printk("not enabled\n");
- } else {
- if ((rc = pcibios_read_config_word(bus, fn, 0x40, &reg))
- || (rc = pcibios_write_config_word(bus, fn, 0x40, reg & 0xdfff)))
- {
- ide_hwifs[0].no_unmask = 1;
- ide_hwifs[1].no_unmask = 1;
- ide_hwifs[0].serialized = 1;
- ide_pci_access_error (rc);
- printk("serialized, disabled unmasking\n");
- } else
- printk("disabled read-ahead\n");
- }
-}
diff --git a/i386/i386at/gpl/linux/block/triton.c b/i386/i386at/gpl/linux/block/triton.c
deleted file mode 100644
index 4f825f69..00000000
--- a/i386/i386at/gpl/linux/block/triton.c
+++ /dev/null
@@ -1,467 +0,0 @@
-/*
- * linux/drivers/block/triton.c Version 1.06 Feb 6, 1996
- *
- * Copyright (c) 1995-1996 Mark Lord
- * May be copied or modified under the terms of the GNU General Public License
- */
-
-/*
- * This module provides support for the Bus Master IDE DMA function
- * of the Intel PCI Triton chipset (82371FB).
- *
- * DMA is currently supported only for hard disk drives (not cdroms).
- *
- * Support for cdroms will likely be added at a later date,
- * after broader experience has been obtained with hard disks.
- *
- * Up to four drives may be enabled for DMA, and the Triton chipset will
- * (hopefully) arbitrate the PCI bus among them. Note that the 82371FB chip
- * provides a single "line buffer" for the BM IDE function, so performance of
- * multiple (two) drives doing DMA simultaneously will suffer somewhat,
- * as they contest for that resource bottleneck. This is handled transparently
- * inside the 82371FB chip.
- *
- * By default, DMA support is prepared for use, but is currently enabled only
- * for drives which support multi-word DMA mode2 (mword2), or which are
- * recognized as "good" (see table below). Drives with only mode0 or mode1
- * (single or multi) DMA should also work with this chipset/driver (eg. MC2112A)
- * but are not enabled by default. Use "hdparm -i" to view modes supported
- * by a given drive.
- *
- * The hdparm-2.4 (or later) utility can be used for manually enabling/disabling
- * DMA support, but must be (re-)compiled against this kernel version or later.
- *
- * To enable DMA, use "hdparm -d1 /dev/hd?" on a per-drive basis after booting.
- * If problems arise, ide.c will disable DMA operation after a few retries.
- * This error recovery mechanism works and has been extremely well exercised.
- *
- * IDE drives, depending on their vintage, may support several different modes
- * of DMA operation. The boot-time modes are indicated with a "*" in
- * the "hdparm -i" listing, and can be changed with *knowledgeable* use of
- * the "hdparm -X" feature. There is seldom a need to do this, as drives
- * normally power-up with their "best" PIO/DMA modes enabled.
- *
- * Testing was done with an ASUS P55TP4XE/100 system and the following drives:
- *
- * Quantum Fireball 1080A (1Gig w/83kB buffer), DMA mode2, PIO mode4.
- * - DMA mode2 works well (7.4MB/sec), despite the tiny on-drive buffer.
- * - This drive also does PIO mode4, at about the same speed as DMA mode2.
- * An awesome drive for the price!
- *
- * Fujitsu M1606TA (1Gig w/256kB buffer), DMA mode2, PIO mode4.
- * - DMA mode2 gives horrible performance (1.6MB/sec), despite the good
- * size of the on-drive buffer and a boasted 10ms average access time.
- * - PIO mode4 was better, but peaked at a mere 4.5MB/sec.
- *
- * Micropolis MC2112A (1Gig w/508kB buffer), drive pre-dates EIDE and ATA2.
- * - DMA works fine (2.2MB/sec), probably due to the large on-drive buffer.
- * - This older drive can also be tweaked for fastPIO (3.7MB/sec) by using
- * maximum clock settings (5,4) and setting all flags except prefetch.
- *
- * Western Digital AC31000H (1Gig w/128kB buffer), DMA mode1, PIO mode3.
- * - DMA does not work reliably. The drive appears to be somewhat tardy
- * in deasserting DMARQ at the end of a sector. This is evident in
- * the observation that WRITEs work most of the time, depending on
- * cache-buffer occupancy, but multi-sector reads seldom work.
- *
- * Testing was done with a Gigabyte GA-586 ATE system and the following drive:
- * (Uwe Bonnes - bon@elektron.ikp.physik.th-darmstadt.de)
- *
- * Western Digital AC31600H (1.6Gig w/128kB buffer), DMA mode2, PIO mode4.
- * - much better than its 1Gig cousin, this drive is reported to work
- * very well with DMA (7.3MB/sec).
- *
- * Other drives:
- *
- * Maxtor 7540AV (515Meg w/32kB buffer), DMA modes mword0/sword2, PIO mode3.
- * - a budget drive, with budget performance, around 3MB/sec.
- *
- * Western Digital AC2850F (814Meg w/64kB buffer), DMA mode1, PIO mode3.
- * - another "caviar" drive, similar to the AC31000, except that this one
- * worked with DMA in at least one system. Throughput is about 3.8MB/sec
- * for both DMA and PIO.
- *
- * Conner CFS850A (812Meg w/64kB buffer), DMA mode2, PIO mode4.
- * - like most Conner models, this drive proves that even a fast interface
- * cannot improve slow media. Both DMA and PIO peak around 3.5MB/sec.
- *
- * If you have any drive models to add, email your results to: mlord@bnr.ca
- * Keep an eye on /var/adm/messages for "DMA disabled" messages.
- *
- * Some people have reported trouble with Intel Zappa motherboards.
- * This can be fixed by upgrading the AMI BIOS to version 1.00.04.BS0,
- * available from ftp://ftp.intel.com/pub/bios/10004bs0.exe
- * (thanks to Glen Morrell <glen@spin.Stanford.edu> for researching this).
- *
- * And, yes, Intel Zappa boards really *do* use the Triton IDE ports.
- */
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/blkdev.h>
-#include <linux/hdreg.h>
-#include <linux/pci.h>
-#include <linux/bios32.h>
-
-#include <asm/io.h>
-#include <asm/dma.h>
-
-#include "ide.h"
-
-/*
- * good_dma_drives() lists the model names (from "hdparm -i")
- * of drives which do not support mword2 DMA but which are
- * known to work fine with this interface under Linux.
- */
-const char *good_dma_drives[] = {"Micropolis 2112A",
- "CONNER CTMA 4000"};
-
-/*
- * Our Physical Region Descriptor (PRD) table should be large enough
- * to handle the biggest I/O request we are likely to see. Since requests
- * can have no more than 256 sectors, and since the typical blocksize is
- * two sectors, we could get by with a limit of 128 entries here for the
- * usual worst case. Most requests seem to include some contiguous blocks,
- * further reducing the number of table entries required.
- *
- * The driver reverts to PIO mode for individual requests that exceed
- * this limit (possible with 512 byte blocksizes, eg. MSDOS f/s), so handling
- * 100% of all crazy scenarios here is not necessary.
- *
- * As it turns out though, we must allocate a full 4KB page for this,
- * so the two PRD tables (ide0 & ide1) will each get half of that,
- * allowing each to have about 256 entries (8 bytes each) from this.
- */
-#define PRD_BYTES 8
-#define PRD_ENTRIES (PAGE_SIZE / (2 * PRD_BYTES))
-
-/*
- * dma_intr() is the handler for disk read/write DMA interrupts
- */
-static void dma_intr (ide_drive_t *drive)
-{
- byte stat, dma_stat;
- int i;
- struct request *rq = HWGROUP(drive)->rq;
- unsigned short dma_base = HWIF(drive)->dma_base;
-
- dma_stat = inb(dma_base+2); /* get DMA status */
- outb(inb(dma_base)&~1, dma_base); /* stop DMA operation */
- stat = GET_STAT(); /* get drive status */
- if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {
- if ((dma_stat & 7) == 4) { /* verify good DMA status */
- rq = HWGROUP(drive)->rq;
- for (i = rq->nr_sectors; i > 0;) {
- i -= rq->current_nr_sectors;
- ide_end_request(1, HWGROUP(drive));
- }
- return;
- }
- printk("%s: bad DMA status: 0x%02x\n", drive->name, dma_stat);
- }
- sti();
- ide_error(drive, "dma_intr", stat);
-}
-
-/*
- * build_dmatable() prepares a dma request.
- * Returns 0 if all went okay, returns 1 otherwise.
- */
-static int build_dmatable (ide_drive_t *drive)
-{
- struct request *rq = HWGROUP(drive)->rq;
- struct buffer_head *bh = rq->bh;
- unsigned long size, addr, *table = HWIF(drive)->dmatable;
- unsigned int count = 0;
-
- do {
- /*
- * Determine addr and size of next buffer area. We assume that
- * individual virtual buffers are always composed linearly in
- * physical memory. For example, we assume that any 8kB buffer
- * is always composed of two adjacent physical 4kB pages rather
- * than two possibly non-adjacent physical 4kB pages.
- */
- if (bh == NULL) { /* paging and tape requests have (rq->bh == NULL) */
- addr = virt_to_bus (rq->buffer);
-#ifdef CONFIG_BLK_DEV_IDETAPE
- if (drive->media == ide_tape)
- size = drive->tape.pc->request_transfer;
- else
-#endif /* CONFIG_BLK_DEV_IDETAPE */
- size = rq->nr_sectors << 9;
- } else {
- /* group sequential buffers into one large buffer */
- addr = virt_to_bus (bh->b_data);
- size = bh->b_size;
- while ((bh = bh->b_reqnext) != NULL) {
- if ((addr + size) != virt_to_bus (bh->b_data))
- break;
- size += bh->b_size;
- }
- }
-
- /*
- * Fill in the dma table, without crossing any 64kB boundaries.
- * We assume 16-bit alignment of all blocks.
- */
- while (size) {
- if (++count >= PRD_ENTRIES) {
- printk("%s: DMA table too small\n", drive->name);
- return 1; /* revert to PIO for this request */
- } else {
- unsigned long bcount = 0x10000 - (addr & 0xffff);
- if (bcount > size)
- bcount = size;
- *table++ = addr;
- *table++ = bcount;
- addr += bcount;
- size -= bcount;
- }
- }
- } while (bh != NULL);
- if (count) {
- *--table |= 0x80000000; /* set End-Of-Table (EOT) bit */
- return 0;
- }
- printk("%s: empty DMA table?\n", drive->name);
- return 1; /* let the PIO routines handle this weirdness */
-}
-
-static int config_drive_for_dma (ide_drive_t *drive)
-{
- const char **list;
-
- struct hd_driveid *id = drive->id;
- if (id && (id->capability & 1)) {
- /* Enable DMA on any drive that supports mword2 DMA */
- if ((id->field_valid & 2) && (id->dma_mword & 0x404) == 0x404) {
- drive->using_dma = 1;
- return 0; /* DMA enabled */
- }
- /* Consult the list of known "good" drives */
- list = good_dma_drives;
- while (*list) {
- if (!strcmp(*list++,id->model)) {
- drive->using_dma = 1;
- return 0; /* DMA enabled */
- }
- }
- }
- return 1; /* DMA not enabled */
-}
-
-/*
- * triton_dmaproc() initiates/aborts DMA read/write operations on a drive.
- *
- * The caller is assumed to have selected the drive and programmed the drive's
- * sector address using CHS or LBA. All that remains is to prepare for DMA
- * and then issue the actual read/write DMA/PIO command to the drive.
- *
- * For ATAPI devices, we just prepare for DMA and return. The caller should
- * then issue the packet command to the drive and call us again with
- * ide_dma_begin afterwards.
- *
- * Returns 0 if all went well.
- * Returns 1 if DMA read/write could not be started, in which case
- * the caller should revert to PIO for the current request.
- */
-static int triton_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
-{
- unsigned long dma_base = HWIF(drive)->dma_base;
- unsigned int reading = (1 << 3);
-
- switch (func) {
- case ide_dma_abort:
- outb(inb(dma_base)&~1, dma_base); /* stop DMA */
- return 0;
- case ide_dma_check:
- return config_drive_for_dma (drive);
- case ide_dma_write:
- reading = 0;
- case ide_dma_read:
- break;
- case ide_dma_status_bad:
- return ((inb(dma_base+2) & 7) != 4); /* verify good DMA status */
- case ide_dma_transferred:
-#if 0
- return (number of bytes actually transferred);
-#else
- return (0);
-#endif
- case ide_dma_begin:
- outb(inb(dma_base)|1, dma_base); /* begin DMA */
- return 0;
- default:
- printk("triton_dmaproc: unsupported func: %d\n", func);
- return 1;
- }
- if (build_dmatable (drive))
- return 1;
- outl(virt_to_bus (HWIF(drive)->dmatable), dma_base + 4); /* PRD table */
- outb(reading, dma_base); /* specify r/w */
- outb(0x26, dma_base+2); /* clear status bits */
-#ifdef CONFIG_BLK_DEV_IDEATAPI
- if (drive->media != ide_disk)
- return 0;
-#endif /* CONFIG_BLK_DEV_IDEATAPI */
- ide_set_handler(drive, &dma_intr, WAIT_CMD); /* issue cmd to drive */
- OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
- outb(inb(dma_base)|1, dma_base); /* begin DMA */
- return 0;
-}
-
-/*
- * print_triton_drive_flags() displays the currently programmed options
- * in the Triton chipset for a given drive.
- *
- * If fastDMA is "no", then slow ISA timings are used for DMA data xfers.
- * If fastPIO is "no", then slow ISA timings are used for PIO data xfers.
- * If IORDY is "no", then IORDY is assumed to always be asserted.
- * If PreFetch is "no", then data pre-fetch/post are not used.
- *
- * When "fastPIO" and/or "fastDMA" are "yes", then faster PCI timings and
- * back-to-back 16-bit data transfers are enabled, using the sample_CLKs
- * and recovery_CLKs (PCI clock cycles) timing parameters for that interface.
- */
-static void print_triton_drive_flags (unsigned int unit, byte flags)
-{
- printk(" %s ", unit ? "slave :" : "master:");
- printk( "fastDMA=%s", (flags&9) ? "on " : "off");
- printk(" PreFetch=%s", (flags&4) ? "on " : "off");
- printk(" IORDY=%s", (flags&2) ? "on " : "off");
- printk(" fastPIO=%s\n", ((flags&9)==1) ? "on " : "off");
-}
-
-static void init_triton_dma (ide_hwif_t *hwif, unsigned short base)
-{
- static unsigned long dmatable = 0;
-
-#if 0
- printk(" %s: BusMaster DMA at 0x%04x-0x%04x", hwif->name, base, base+7);
-#endif
- if (check_region(base, 8)) {
-#if 0
- printk(" -- ERROR, PORTS ALREADY IN USE");
-#endif
- } else {
- request_region(base, 8, "triton DMA");
- hwif->dma_base = base;
- if (!dmatable) {
- /*
- * Since we know we are on a PCI bus, we could
- * actually use __get_free_pages() here instead
- * of __get_dma_pages() -- no ISA limitations.
- */
- dmatable = __get_dma_pages(GFP_KERNEL, 0);
- }
- if (dmatable) {
- hwif->dmatable = (unsigned long *) dmatable;
- dmatable += (PRD_ENTRIES * PRD_BYTES);
- outl(virt_to_bus(hwif->dmatable), base + 4);
- hwif->dmaproc = &triton_dmaproc;
- }
- }
-#if 0
- printk("\n");
-#endif
-}
-
-/*
- * calc_mode() returns the ATA PIO mode number, based on the number
- * of cycle clks passed in. Assumes 33Mhz bus operation (30ns per clk).
- */
-byte calc_mode (byte clks)
-{
- if (clks == 3) return 5;
- if (clks == 4) return 4;
- if (clks < 6) return 3;
- if (clks < 8) return 2;
- if (clks < 13) return 1;
- return 0;
-}
-
-/*
- * ide_init_triton() prepares the IDE driver for DMA operation.
- * This routine is called once, from ide.c during driver initialization,
- * for each triton chipset which is found (unlikely to be more than one).
- */
-void ide_init_triton (byte bus, byte fn)
-{
- int rc = 0, h;
- int dma_enabled = 0;
- unsigned short bmiba, pcicmd;
- unsigned int timings;
-
- printk("ide: Triton BM-IDE on PCI bus %d function %d\n", bus, fn);
- /*
- * See if IDE and BM-DMA features are enabled:
- */
- if ((rc = pcibios_read_config_word(bus, fn, 0x04, &pcicmd)))
- goto quit;
- if ((pcicmd & 1) == 0) {
- printk("ide: Triton IDE ports are not enabled\n");
- goto quit;
- }
- if ((pcicmd & 4) == 0) {
- printk("ide: Triton BM-DMA feature is not enabled -- upgrade your BIOS\n");
- } else {
- /*
- * Get the bmiba base address
- */
- if ((rc = pcibios_read_config_word(bus, fn, 0x20, &bmiba)))
- goto quit;
- bmiba &= 0xfff0; /* extract port base address */
- dma_enabled = 1;
- }
-
- /*
- * See if ide port(s) are enabled
- */
- if ((rc = pcibios_read_config_dword(bus, fn, 0x40, &timings)))
- goto quit;
- if (!(timings & 0x80008000)) {
- printk("ide: neither Triton IDE port is enabled\n");
- goto quit;
- }
-
- /*
- * Save the dma_base port addr for each interface
- */
- for (h = 0; h < MAX_HWIFS; ++h) {
- byte s_clks, r_clks;
- ide_hwif_t *hwif = &ide_hwifs[h];
- unsigned short time;
- if (hwif->io_base == 0x1f0) {
- time = timings & 0xffff;
- if ((timings & 0x8000) == 0) /* interface enabled? */
- continue;
- hwif->chipset = ide_triton;
- if (dma_enabled)
- init_triton_dma(hwif, bmiba);
- } else if (hwif->io_base == 0x170) {
- time = timings >> 16;
- if ((timings & 0x8000) == 0) /* interface enabled? */
- continue;
- hwif->chipset = ide_triton;
- if (dma_enabled)
- init_triton_dma(hwif, bmiba + 8);
- } else
- continue;
- s_clks = ((~time >> 12) & 3) + 2;
- r_clks = ((~time >> 8) & 3) + 1;
-#if 0
- printk(" %s timing: (0x%04x) sample_CLKs=%d, recovery_CLKs=%d (PIO mode%d)\n",
- hwif->name, time, s_clks, r_clks, calc_mode(s_clks+r_clks));
- print_triton_drive_flags (0, time & 0xf);
- print_triton_drive_flags (1, (time >> 4) & 0xf);
-#endif
- }
-
-quit: if (rc) printk("ide: pcibios access failed - %s\n", pcibios_strerror(rc));
-}
-
diff --git a/i386/i386at/gpl/linux/include/asm/bitops.h b/i386/i386at/gpl/linux/include/asm/bitops.h
deleted file mode 100644
index 5387f31d..00000000
--- a/i386/i386at/gpl/linux/include/asm/bitops.h
+++ /dev/null
@@ -1,137 +0,0 @@
-#ifndef _I386_BITOPS_H
-#define _I386_BITOPS_H
-
-/*
- * Copyright 1992, Linus Torvalds.
- */
-
-/*
- * These have to be done with inline assembly: that way the bit-setting
- * is guaranteed to be atomic. All bit operations return 0 if the bit
- * was cleared before the operation and != 0 if it was not.
- *
- * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
- */
-
-#ifdef __SMP__
-#define LOCK_PREFIX "lock ; "
-#else
-#define LOCK_PREFIX ""
-#endif
-
-/*
- * Some hacks to defeat gcc over-optimizations..
- */
-struct __dummy { unsigned long a[100]; };
-#define ADDR (*(struct __dummy *) addr)
-#define CONST_ADDR (*(const struct __dummy *) addr)
-
-extern __inline__ int set_bit(int nr, void * addr)
-{
- int oldbit;
-
- __asm__ __volatile__(LOCK_PREFIX
- "btsl %2,%1\n\tsbbl %0,%0"
- :"=r" (oldbit),"=m" (ADDR)
- :"ir" (nr));
- return oldbit;
-}
-
-extern __inline__ int clear_bit(int nr, void * addr)
-{
- int oldbit;
-
- __asm__ __volatile__(LOCK_PREFIX
- "btrl %2,%1\n\tsbbl %0,%0"
- :"=r" (oldbit),"=m" (ADDR)
- :"ir" (nr));
- return oldbit;
-}
-
-extern __inline__ int change_bit(int nr, void * addr)
-{
- int oldbit;
-
- __asm__ __volatile__(LOCK_PREFIX
- "btcl %2,%1\n\tsbbl %0,%0"
- :"=r" (oldbit),"=m" (ADDR)
- :"ir" (nr));
- return oldbit;
-}
-
-/*
- * This routine doesn't need to be atomic.
- */
-extern __inline__ int test_bit(int nr, const void * addr)
-{
- return 1UL & (((const unsigned int *) addr)[nr >> 5] >> (nr & 31));
-}
-
-/*
- * Find-bit routines..
- */
-extern __inline__ int find_first_zero_bit(void * addr, unsigned size)
-{
- int res;
-
- if (!size)
- return 0;
- __asm__("
- cld
- movl $-1,%%eax
- xorl %%edx,%%edx
- repe; scasl
- je 1f
- xorl -4(%%edi),%%eax
- subl $4,%%edi
- bsfl %%eax,%%edx
-1: subl %%ebx,%%edi
- shll $3,%%edi
- addl %%edi,%%edx"
- :"=d" (res)
- :"c" ((size + 31) >> 5), "D" (addr), "b" (addr)
- :"ax", "cx", "di");
- return res;
-}
-
-extern __inline__ int find_next_zero_bit (void * addr, int size, int offset)
-{
- unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
- int set = 0, bit = offset & 31, res;
-
- if (bit) {
- /*
- * Look for zero in first byte
- */
- __asm__("
- bsfl %1,%0
- jne 1f
- movl $32, %0
-1: "
- : "=r" (set)
- : "r" (~(*p >> bit)));
- if (set < (32 - bit))
- return set + offset;
- set = 32 - bit;
- p++;
- }
- /*
- * No zero yet, search remaining full bytes for a zero
- */
- res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr));
- return (offset + set + res);
-}
-
-/*
- * ffz = Find First Zero in word. Undefined if no zero exists,
- * so code should check against ~0UL first..
- */
-extern __inline__ unsigned long ffz(unsigned long word)
-{
- __asm__("bsfl %1,%0"
- :"=r" (word)
- :"r" (~word));
- return word;
-}
-
-#endif /* _I386_BITOPS_H */
diff --git a/i386/i386at/gpl/linux/include/asm/byteorder.h b/i386/i386at/gpl/linux/include/asm/byteorder.h
deleted file mode 100644
index 3f40767f..00000000
--- a/i386/i386at/gpl/linux/include/asm/byteorder.h
+++ /dev/null
@@ -1,90 +0,0 @@
-#ifndef _I386_BYTEORDER_H
-#define _I386_BYTEORDER_H
-
-#undef ntohl
-#undef ntohs
-#undef htonl
-#undef htons
-
-#ifndef __LITTLE_ENDIAN
-#define __LITTLE_ENDIAN 1234
-#endif
-
-#ifndef __LITTLE_ENDIAN_BITFIELD
-#define __LITTLE_ENDIAN_BITFIELD
-#endif
-
-/* For avoiding bswap on i386 */
-#ifdef __KERNEL__
-#include <linux/config.h>
-#endif
-
-extern unsigned long int ntohl(unsigned long int);
-extern unsigned short int ntohs(unsigned short int);
-extern unsigned long int htonl(unsigned long int);
-extern unsigned short int htons(unsigned short int);
-
-extern __inline__ unsigned long int __ntohl(unsigned long int);
-extern __inline__ unsigned short int __ntohs(unsigned short int);
-extern __inline__ unsigned long int __constant_ntohl(unsigned long int);
-extern __inline__ unsigned short int __constant_ntohs(unsigned short int);
-
-extern __inline__ unsigned long int
-__ntohl(unsigned long int x)
-{
-#if defined(__KERNEL__) && !defined(CONFIG_M386)
- __asm__("bswap %0" : "=r" (x) : "0" (x));
-#else
- __asm__("xchgb %b0,%h0\n\t" /* swap lower bytes */
- "rorl $16,%0\n\t" /* swap words */
- "xchgb %b0,%h0" /* swap higher bytes */
- :"=q" (x)
- : "0" (x));
-#endif
- return x;
-}
-
-#define __constant_ntohl(x) \
- ((unsigned long int)((((unsigned long int)(x) & 0x000000ffU) << 24) | \
- (((unsigned long int)(x) & 0x0000ff00U) << 8) | \
- (((unsigned long int)(x) & 0x00ff0000U) >> 8) | \
- (((unsigned long int)(x) & 0xff000000U) >> 24)))
-
-extern __inline__ unsigned short int
-__ntohs(unsigned short int x)
-{
- __asm__("xchgb %b0,%h0" /* swap bytes */
- : "=q" (x)
- : "0" (x));
- return x;
-}
-
-#define __constant_ntohs(x) \
- ((unsigned short int)((((unsigned short int)(x) & 0x00ff) << 8) | \
- (((unsigned short int)(x) & 0xff00) >> 8))) \
-
-#define __htonl(x) __ntohl(x)
-#define __htons(x) __ntohs(x)
-#define __constant_htonl(x) __constant_ntohl(x)
-#define __constant_htons(x) __constant_ntohs(x)
-
-#ifdef __OPTIMIZE__
-# define ntohl(x) \
-(__builtin_constant_p((long)(x)) ? \
- __constant_ntohl((x)) : \
- __ntohl((x)))
-# define ntohs(x) \
-(__builtin_constant_p((short)(x)) ? \
- __constant_ntohs((x)) : \
- __ntohs((x)))
-# define htonl(x) \
-(__builtin_constant_p((long)(x)) ? \
- __constant_htonl((x)) : \
- __htonl((x)))
-# define htons(x) \
-(__builtin_constant_p((short)(x)) ? \
- __constant_htons((x)) : \
- __htons((x)))
-#endif
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/asm/delay.h b/i386/i386at/gpl/linux/include/asm/delay.h
deleted file mode 100644
index e22e8d6b..00000000
--- a/i386/i386at/gpl/linux/include/asm/delay.h
+++ /dev/null
@@ -1,59 +0,0 @@
-#ifndef _I386_DELAY_H
-#define _I386_DELAY_H
-
-/*
- * Copyright (C) 1993 Linus Torvalds
- *
- * Delay routines, using a pre-computed "loops_per_second" value.
- */
-
-#ifdef __SMP__
-#include <asm/smp.h>
-#endif
-
-extern __inline__ void __delay(int loops)
-{
- __asm__ __volatile__(
- ".align 2,0x90\n1:\tdecl %0\n\tjns 1b"
- :/* no outputs */
- :"a" (loops)
- :"ax");
-}
-
-/*
- * division by multiplication: you don't have to worry about
- * loss of precision.
- *
- * Use only for very small delays ( < 1 msec). Should probably use a
- * lookup table, really, as the multiplications take much too long with
- * short delays. This is a "reasonable" implementation, though (and the
- * first constant multiplications gets optimized away if the delay is
- * a constant)
- */
-extern __inline__ void udelay(unsigned long usecs)
-{
- usecs *= 0x000010c6; /* 2**32 / 1000000 */
- __asm__("mull %0"
- :"=d" (usecs)
-#ifdef __SMP__
- :"a" (usecs),"0" (cpu_data[smp_processor_id()].udelay_val)
-#else
- :"a" (usecs),"0" (loops_per_sec)
-#endif
- :"ax");
-
- __delay(usecs);
-}
-
-extern __inline__ unsigned long muldiv(unsigned long a, unsigned long b, unsigned long c)
-{
- __asm__("mull %1 ; divl %2"
- :"=a" (a)
- :"d" (b),
- "r" (c),
- "0" (a)
- :"dx");
- return a;
-}
-
-#endif /* defined(_I386_DELAY_H) */
diff --git a/i386/i386at/gpl/linux/include/asm/dma.h b/i386/i386at/gpl/linux/include/asm/dma.h
deleted file mode 100644
index b739ed7d..00000000
--- a/i386/i386at/gpl/linux/include/asm/dma.h
+++ /dev/null
@@ -1,271 +0,0 @@
-/* $Id: dma.h,v 1.1.1.1 1997/02/25 21:27:24 thomas Exp $
- * linux/include/asm/dma.h: Defines for using and allocating dma channels.
- * Written by Hennus Bergman, 1992.
- * High DMA channel support & info by Hannu Savolainen
- * and John Boyd, Nov. 1992.
- */
-
-#ifndef _ASM_DMA_H
-#define _ASM_DMA_H
-
-#include <asm/io.h> /* need byte IO */
-
-
-#ifdef HAVE_REALLY_SLOW_DMA_CONTROLLER
-#define dma_outb outb_p
-#else
-#define dma_outb outb
-#endif
-
-#define dma_inb inb
-
-/*
- * NOTES about DMA transfers:
- *
- * controller 1: channels 0-3, byte operations, ports 00-1F
- * controller 2: channels 4-7, word operations, ports C0-DF
- *
- * - ALL registers are 8 bits only, regardless of transfer size
- * - channel 4 is not used - cascades 1 into 2.
- * - channels 0-3 are byte - addresses/counts are for physical bytes
- * - channels 5-7 are word - addresses/counts are for physical words
- * - transfers must not cross physical 64K (0-3) or 128K (5-7) boundaries
- * - transfer count loaded to registers is 1 less than actual count
- * - controller 2 offsets are all even (2x offsets for controller 1)
- * - page registers for 5-7 don't use data bit 0, represent 128K pages
- * - page registers for 0-3 use bit 0, represent 64K pages
- *
- * DMA transfers are limited to the lower 16MB of _physical_ memory.
- * Note that addresses loaded into registers must be _physical_ addresses,
- * not logical addresses (which may differ if paging is active).
- *
- * Address mapping for channels 0-3:
- *
- * A23 ... A16 A15 ... A8 A7 ... A0 (Physical addresses)
- * | ... | | ... | | ... |
- * | ... | | ... | | ... |
- * | ... | | ... | | ... |
- * P7 ... P0 A7 ... A0 A7 ... A0
- * | Page | Addr MSB | Addr LSB | (DMA registers)
- *
- * Address mapping for channels 5-7:
- *
- * A23 ... A17 A16 A15 ... A9 A8 A7 ... A1 A0 (Physical addresses)
- * | ... | \ \ ... \ \ \ ... \ \
- * | ... | \ \ ... \ \ \ ... \ (not used)
- * | ... | \ \ ... \ \ \ ... \
- * P7 ... P1 (0) A7 A6 ... A0 A7 A6 ... A0
- * | Page | Addr MSB | Addr LSB | (DMA registers)
- *
- * Again, channels 5-7 transfer _physical_ words (16 bits), so addresses
- * and counts _must_ be word-aligned (the lowest address bit is _ignored_ at
- * the hardware level, so odd-byte transfers aren't possible).
- *
- * Transfer count (_not # bytes_) is limited to 64K, represented as actual
- * count - 1 : 64K => 0xFFFF, 1 => 0x0000. Thus, count is always 1 or more,
- * and up to 128K bytes may be transferred on channels 5-7 in one operation.
- *
- */
-
-#define MAX_DMA_CHANNELS 8
-
-/* The maximum address that we can perform a DMA transfer to on this platform */
-#define MAX_DMA_ADDRESS 0x1000000
-
-/* 8237 DMA controllers */
-#define IO_DMA1_BASE 0x00 /* 8 bit slave DMA, channels 0..3 */
-#define IO_DMA2_BASE 0xC0 /* 16 bit master DMA, ch 4(=slave input)..7 */
-
-/* DMA controller registers */
-#define DMA1_CMD_REG 0x08 /* command register (w) */
-#define DMA1_STAT_REG 0x08 /* status register (r) */
-#define DMA1_REQ_REG 0x09 /* request register (w) */
-#define DMA1_MASK_REG 0x0A /* single-channel mask (w) */
-#define DMA1_MODE_REG 0x0B /* mode register (w) */
-#define DMA1_CLEAR_FF_REG 0x0C /* clear pointer flip-flop (w) */
-#define DMA1_TEMP_REG 0x0D /* Temporary Register (r) */
-#define DMA1_RESET_REG 0x0D /* Master Clear (w) */
-#define DMA1_CLR_MASK_REG 0x0E /* Clear Mask */
-#define DMA1_MASK_ALL_REG 0x0F /* all-channels mask (w) */
-
-#define DMA2_CMD_REG 0xD0 /* command register (w) */
-#define DMA2_STAT_REG 0xD0 /* status register (r) */
-#define DMA2_REQ_REG 0xD2 /* request register (w) */
-#define DMA2_MASK_REG 0xD4 /* single-channel mask (w) */
-#define DMA2_MODE_REG 0xD6 /* mode register (w) */
-#define DMA2_CLEAR_FF_REG 0xD8 /* clear pointer flip-flop (w) */
-#define DMA2_TEMP_REG 0xDA /* Temporary Register (r) */
-#define DMA2_RESET_REG 0xDA /* Master Clear (w) */
-#define DMA2_CLR_MASK_REG 0xDC /* Clear Mask */
-#define DMA2_MASK_ALL_REG 0xDE /* all-channels mask (w) */
-
-#define DMA_ADDR_0 0x00 /* DMA address registers */
-#define DMA_ADDR_1 0x02
-#define DMA_ADDR_2 0x04
-#define DMA_ADDR_3 0x06
-#define DMA_ADDR_4 0xC0
-#define DMA_ADDR_5 0xC4
-#define DMA_ADDR_6 0xC8
-#define DMA_ADDR_7 0xCC
-
-#define DMA_CNT_0 0x01 /* DMA count registers */
-#define DMA_CNT_1 0x03
-#define DMA_CNT_2 0x05
-#define DMA_CNT_3 0x07
-#define DMA_CNT_4 0xC2
-#define DMA_CNT_5 0xC6
-#define DMA_CNT_6 0xCA
-#define DMA_CNT_7 0xCE
-
-#define DMA_PAGE_0 0x87 /* DMA page registers */
-#define DMA_PAGE_1 0x83
-#define DMA_PAGE_2 0x81
-#define DMA_PAGE_3 0x82
-#define DMA_PAGE_5 0x8B
-#define DMA_PAGE_6 0x89
-#define DMA_PAGE_7 0x8A
-
-#define DMA_MODE_READ 0x44 /* I/O to memory, no autoinit, increment, single mode */
-#define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */
-#define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */
-
-/* enable/disable a specific DMA channel */
-static __inline__ void enable_dma(unsigned int dmanr)
-{
- if (dmanr<=3)
- dma_outb(dmanr, DMA1_MASK_REG);
- else
- dma_outb(dmanr & 3, DMA2_MASK_REG);
-}
-
-static __inline__ void disable_dma(unsigned int dmanr)
-{
- if (dmanr<=3)
- dma_outb(dmanr | 4, DMA1_MASK_REG);
- else
- dma_outb((dmanr & 3) | 4, DMA2_MASK_REG);
-}
-
-/* Clear the 'DMA Pointer Flip Flop'.
- * Write 0 for LSB/MSB, 1 for MSB/LSB access.
- * Use this once to initialize the FF to a known state.
- * After that, keep track of it. :-)
- * --- In order to do that, the DMA routines below should ---
- * --- only be used while interrupts are disabled! ---
- */
-static __inline__ void clear_dma_ff(unsigned int dmanr)
-{
- if (dmanr<=3)
- dma_outb(0, DMA1_CLEAR_FF_REG);
- else
- dma_outb(0, DMA2_CLEAR_FF_REG);
-}
-
-/* set mode (above) for a specific DMA channel */
-static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
-{
- if (dmanr<=3)
- dma_outb(mode | dmanr, DMA1_MODE_REG);
- else
- dma_outb(mode | (dmanr&3), DMA2_MODE_REG);
-}
-
-/* Set only the page register bits of the transfer address.
- * This is used for successive transfers when we know the contents of
- * the lower 16 bits of the DMA current address register, but a 64k boundary
- * may have been crossed.
- */
-static __inline__ void set_dma_page(unsigned int dmanr, char pagenr)
-{
- switch(dmanr) {
- case 0:
- dma_outb(pagenr, DMA_PAGE_0);
- break;
- case 1:
- dma_outb(pagenr, DMA_PAGE_1);
- break;
- case 2:
- dma_outb(pagenr, DMA_PAGE_2);
- break;
- case 3:
- dma_outb(pagenr, DMA_PAGE_3);
- break;
- case 5:
- dma_outb(pagenr & 0xfe, DMA_PAGE_5);
- break;
- case 6:
- dma_outb(pagenr & 0xfe, DMA_PAGE_6);
- break;
- case 7:
- dma_outb(pagenr & 0xfe, DMA_PAGE_7);
- break;
- }
-}
-
-
-/* Set transfer address & page bits for specific DMA channel.
- * Assumes dma flipflop is clear.
- */
-static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
-{
- set_dma_page(dmanr, a>>16);
- if (dmanr <= 3) {
- dma_outb( a & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
- dma_outb( (a>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
- } else {
- dma_outb( (a>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
- dma_outb( (a>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
- }
-}
-
-
-/* Set transfer size (max 64k for DMA1..3, 128k for DMA5..7) for
- * a specific DMA channel.
- * You must ensure the parameters are valid.
- * NOTE: from a manual: "the number of transfers is one more
- * than the initial word count"! This is taken into account.
- * Assumes dma flip-flop is clear.
- * NOTE 2: "count" represents _bytes_ and must be even for channels 5-7.
- */
-static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
-{
- count--;
- if (dmanr <= 3) {
- dma_outb( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
- dma_outb( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
- } else {
- dma_outb( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
- dma_outb( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
- }
-}
-
-
-/* Get DMA residue count. After a DMA transfer, this
- * should return zero. Reading this while a DMA transfer is
- * still in progress will return unpredictable results.
- * If called before the channel has been used, it may return 1.
- * Otherwise, it returns the number of _bytes_ left to transfer.
- *
- * Assumes DMA flip-flop is clear.
- */
-static __inline__ int get_dma_residue(unsigned int dmanr)
-{
- unsigned int io_port = (dmanr<=3)? ((dmanr&3)<<1) + 1 + IO_DMA1_BASE
- : ((dmanr&3)<<2) + 2 + IO_DMA2_BASE;
-
- /* using short to get 16-bit wrap around */
- unsigned short count;
-
- count = 1 + dma_inb(io_port);
- count += dma_inb(io_port) << 8;
-
- return (dmanr<=3)? count : (count<<1);
-}
-
-
-/* These are in kernel/dma.c: */
-extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */
-extern void free_dma(unsigned int dmanr); /* release it again */
-
-
-#endif /* _ASM_DMA_H */
diff --git a/i386/i386at/gpl/linux/include/asm/errno.h b/i386/i386at/gpl/linux/include/asm/errno.h
deleted file mode 100644
index f5c37cad..00000000
--- a/i386/i386at/gpl/linux/include/asm/errno.h
+++ /dev/null
@@ -1,252 +0,0 @@
-#ifndef _I386_ERRNO_H
-#define _I386_ERRNO_H
-
-#ifdef MACH_INCLUDE
-#define LINUX_EPERM 1 /* Operation not permitted */
-#define LINUX_ENOENT 2 /* No such file or directory */
-#define LINUX_ESRCH 3 /* No such process */
-#define LINUX_EINTR 4 /* Interrupted system call */
-#define LINUX_EIO 5 /* I/O error */
-#define LINUX_ENXIO 6 /* No such device or address */
-#define LINUX_E2BIG 7 /* Arg list too long */
-#define LINUX_ENOEXEC 8 /* Exec format error */
-#define LINUX_EBADF 9 /* Bad file number */
-#define LINUX_ECHILD 10 /* No child processes */
-#define LINUX_EAGAIN 11 /* Try again */
-#define LINUX_ENOMEM 12 /* Out of memory */
-#define LINUX_EACCES 13 /* Permission denied */
-#define LINUX_EFAULT 14 /* Bad address */
-#define LINUX_ENOTBLK 15 /* Block device required */
-#define LINUX_EBUSY 16 /* Device or resource busy */
-#define LINUX_EEXIST 17 /* File exists */
-#define LINUX_EXDEV 18 /* Cross-device link */
-#define LINUX_ENODEV 19 /* No such device */
-#define LINUX_ENOTDIR 20 /* Not a directory */
-#define LINUX_EISDIR 21 /* Is a directory */
-#define LINUX_EINVAL 22 /* Invalid argument */
-#define LINUX_ENFILE 23 /* File table overflow */
-#define LINUX_EMFILE 24 /* Too many open files */
-#define LINUX_ENOTTY 25 /* Not a typewriter */
-#define LINUX_ETXTBSY 26 /* Text file busy */
-#define LINUX_EFBIG 27 /* File too large */
-#define LINUX_ENOSPC 28 /* No space left on device */
-#define LINUX_ESPIPE 29 /* Illegal seek */
-#define LINUX_EROFS 30 /* Read-only file system */
-#define LINUX_EMLINK 31 /* Too many links */
-#define LINUX_EPIPE 32 /* Broken pipe */
-#define LINUX_EDOM 33 /* Math argument out of domain of func */
-#define LINUX_ERANGE 34 /* Math result not representable */
-#define LINUX_EDEADLK 35 /* Resource deadlock would occur */
-#define LINUX_ENAMETOOLONG 36 /* File name too long */
-#define LINUX_ENOLCK 37 /* No record locks available */
-#define LINUX_ENOSYS 38 /* Function not implemented */
-#define LINUX_ENOTEMPTY 39 /* Directory not empty */
-#define LINUX_ELOOP 40 /* Too many symbolic links encountered */
-#define LINUX_EWOULDBLOCK LINUX_EAGAIN /* Operation would block */
-#define LINUX_ENOMSG 42 /* No message of desired type */
-#define LINUX_EIDRM 43 /* Identifier removed */
-#define LINUX_ECHRNG 44 /* Channel number out of range */
-#define LINUX_EL2NSYNC 45 /* Level 2 not synchronized */
-#define LINUX_EL3HLT 46 /* Level 3 halted */
-#define LINUX_EL3RST 47 /* Level 3 reset */
-#define LINUX_ELNRNG 48 /* Link number out of range */
-#define LINUX_EUNATCH 49 /* Protocol driver not attached */
-#define LINUX_ENOCSI 50 /* No CSI structure available */
-#define LINUX_EL2HLT 51 /* Level 2 halted */
-#define LINUX_EBADE 52 /* Invalid exchange */
-#define LINUX_EBADR 53 /* Invalid request descriptor */
-#define LINUX_EXFULL 54 /* Exchange full */
-#define LINUX_ENOANO 55 /* No anode */
-#define LINUX_EBADRQC 56 /* Invalid request code */
-#define LINUX_EBADSLT 57 /* Invalid slot */
-#define LINUX_EDEADLOCK 58 /* File locking deadlock error */
-#define LINUX_EBFONT 59 /* Bad font file format */
-#define LINUX_ENOSTR 60 /* Device not a stream */
-#define LINUX_ENODATA 61 /* No data available */
-#define LINUX_ETIME 62 /* Timer expired */
-#define LINUX_ENOSR 63 /* Out of streams resources */
-#define LINUX_ENONET 64 /* Machine is not on the network */
-#define LINUX_ENOPKG 65 /* Package not installed */
-#define LINUX_EREMOTE 66 /* Object is remote */
-#define LINUX_ENOLINK 67 /* Link has been severed */
-#define LINUX_EADV 68 /* Advertise error */
-#define LINUX_ESRMNT 69 /* Srmount error */
-#define LINUX_ECOMM 70 /* Communication error on send */
-#define LINUX_EPROTO 71 /* Protocol error */
-#define LINUX_EMULTIHOP 72 /* Multihop attempted */
-#define LINUX_EDOTDOT 73 /* RFS specific error */
-#define LINUX_EBADMSG 74 /* Not a data message */
-#define LINUX_EOVERFLOW 75 /* Value too large for defined data type */
-#define LINUX_ENOTUNIQ 76 /* Name not unique on network */
-#define LINUX_EBADFD 77 /* File descriptor in bad state */
-#define LINUX_EREMCHG 78 /* Remote address changed */
-#define LINUX_ELIBACC 79 /* Can not access a needed shared library */
-#define LINUX_ELIBBAD 80 /* Accessing a corrupted shared library */
-#define LINUX_ELIBSCN 81 /* .lib section in a.out corrupted */
-#define LINUX_ELIBMAX 82 /* Attempting to link in too many shared libraries */
-#define LINUX_ELIBEXEC 83 /* Cannot exec a shared library directly */
-#define LINUX_EILSEQ 84 /* Illegal byte sequence */
-#define LINUX_ERESTART 85 /* Interrupted system call should be restarted */
-#define LINUX_ESTRPIPE 86 /* Streams pipe error */
-#define LINUX_EUSERS 87 /* Too many users */
-#define LINUX_ENOTSOCK 88 /* Socket operation on non-socket */
-#define LINUX_EDESTADDRREQ 89 /* Destination address required */
-#define LINUX_EMSGSIZE 90 /* Message too long */
-#define LINUX_EPROTOTYPE 91 /* Protocol wrong type for socket */
-#define LINUX_ENOPROTOOPT 92 /* Protocol not available */
-#define LINUX_EPROTONOSUPPORT 93 /* Protocol not supported */
-#define LINUX_ESOCKTNOSUPPORT 94 /* Socket type not supported */
-#define LINUX_EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
-#define LINUX_EPFNOSUPPORT 96 /* Protocol family not supported */
-#define LINUX_EAFNOSUPPORT 97 /* Address family not supported by protocol */
-#define LINUX_EADDRINUSE 98 /* Address already in use */
-#define LINUX_EADDRNOTAVAIL 99 /* Cannot assign requested address */
-#define LINUX_ENETDOWN 100 /* Network is down */
-#define LINUX_ENETUNREACH 101 /* Network is unreachable */
-#define LINUX_ENETRESET 102 /* Network dropped connection because of reset */
-#define LINUX_ECONNABORTED 103 /* Software caused connection abort */
-#define LINUX_ECONNRESET 104 /* Connection reset by peer */
-#define LINUX_ENOBUFS 105 /* No buffer space available */
-#define LINUX_EISCONN 106 /* Transport endpoint is already connected */
-#define LINUX_ENOTCONN 107 /* Transport endpoint is not connected */
-#define LINUX_ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
-#define LINUX_ETOOMANYREFS 109 /* Too many references: cannot splice */
-#define LINUX_ETIMEDOUT 110 /* Connection timed out */
-#define LINUX_ECONNREFUSED 111 /* Connection refused */
-#define LINUX_EHOSTDOWN 112 /* Host is down */
-#define LINUX_EHOSTUNREACH 113 /* No route to host */
-#define LINUX_EALREADY 114 /* Operation already in progress */
-#define LINUX_EINPROGRESS 115 /* Operation now in progress */
-#define LINUX_ESTALE 116 /* Stale NFS file handle */
-#define LINUX_EUCLEAN 117 /* Structure needs cleaning */
-#define LINUX_ENOTNAM 118 /* Not a XENIX named type file */
-#define LINUX_ENAVAIL 119 /* No XENIX semaphores available */
-#define LINUX_EISNAM 120 /* Is a named type file */
-#define LINUX_EREMOTEIO 121 /* Remote I/O error */
-#define LINUX_EDQUOT 122 /* Quota exceeded */
-#else /* ! MACH_INCLUDE */
-#define EPERM 1 /* Operation not permitted */
-#define ENOENT 2 /* No such file or directory */
-#define ESRCH 3 /* No such process */
-#define EINTR 4 /* Interrupted system call */
-#define EIO 5 /* I/O error */
-#define ENXIO 6 /* No such device or address */
-#define E2BIG 7 /* Arg list too long */
-#define ENOEXEC 8 /* Exec format error */
-#define EBADF 9 /* Bad file number */
-#define ECHILD 10 /* No child processes */
-#define EAGAIN 11 /* Try again */
-#define ENOMEM 12 /* Out of memory */
-#define EACCES 13 /* Permission denied */
-#define EFAULT 14 /* Bad address */
-#define ENOTBLK 15 /* Block device required */
-#define EBUSY 16 /* Device or resource busy */
-#define EEXIST 17 /* File exists */
-#define EXDEV 18 /* Cross-device link */
-#define ENODEV 19 /* No such device */
-#define ENOTDIR 20 /* Not a directory */
-#define EISDIR 21 /* Is a directory */
-#define EINVAL 22 /* Invalid argument */
-#define ENFILE 23 /* File table overflow */
-#define EMFILE 24 /* Too many open files */
-#define ENOTTY 25 /* Not a typewriter */
-#define ETXTBSY 26 /* Text file busy */
-#define EFBIG 27 /* File too large */
-#define ENOSPC 28 /* No space left on device */
-#define ESPIPE 29 /* Illegal seek */
-#define EROFS 30 /* Read-only file system */
-#define EMLINK 31 /* Too many links */
-#define EPIPE 32 /* Broken pipe */
-#define EDOM 33 /* Math argument out of domain of func */
-#define ERANGE 34 /* Math result not representable */
-#define EDEADLK 35 /* Resource deadlock would occur */
-#define ENAMETOOLONG 36 /* File name too long */
-#define ENOLCK 37 /* No record locks available */
-#define ENOSYS 38 /* Function not implemented */
-#define ENOTEMPTY 39 /* Directory not empty */
-#define ELOOP 40 /* Too many symbolic links encountered */
-#define EWOULDBLOCK EAGAIN /* Operation would block */
-#define ENOMSG 42 /* No message of desired type */
-#define EIDRM 43 /* Identifier removed */
-#define ECHRNG 44 /* Channel number out of range */
-#define EL2NSYNC 45 /* Level 2 not synchronized */
-#define EL3HLT 46 /* Level 3 halted */
-#define EL3RST 47 /* Level 3 reset */
-#define ELNRNG 48 /* Link number out of range */
-#define EUNATCH 49 /* Protocol driver not attached */
-#define ENOCSI 50 /* No CSI structure available */
-#define EL2HLT 51 /* Level 2 halted */
-#define EBADE 52 /* Invalid exchange */
-#define EBADR 53 /* Invalid request descriptor */
-#define EXFULL 54 /* Exchange full */
-#define ENOANO 55 /* No anode */
-#define EBADRQC 56 /* Invalid request code */
-#define EBADSLT 57 /* Invalid slot */
-#define EDEADLOCK 58 /* File locking deadlock error */
-#define EBFONT 59 /* Bad font file format */
-#define ENOSTR 60 /* Device not a stream */
-#define ENODATA 61 /* No data available */
-#define ETIME 62 /* Timer expired */
-#define ENOSR 63 /* Out of streams resources */
-#define ENONET 64 /* Machine is not on the network */
-#define ENOPKG 65 /* Package not installed */
-#define EREMOTE 66 /* Object is remote */
-#define ENOLINK 67 /* Link has been severed */
-#define EADV 68 /* Advertise error */
-#define ESRMNT 69 /* Srmount error */
-#define ECOMM 70 /* Communication error on send */
-#define EPROTO 71 /* Protocol error */
-#define EMULTIHOP 72 /* Multihop attempted */
-#define EDOTDOT 73 /* RFS specific error */
-#define EBADMSG 74 /* Not a data message */
-#define EOVERFLOW 75 /* Value too large for defined data type */
-#define ENOTUNIQ 76 /* Name not unique on network */
-#define EBADFD 77 /* File descriptor in bad state */
-#define EREMCHG 78 /* Remote address changed */
-#define ELIBACC 79 /* Can not access a needed shared library */
-#define ELIBBAD 80 /* Accessing a corrupted shared library */
-#define ELIBSCN 81 /* .lib section in a.out corrupted */
-#define ELIBMAX 82 /* Attempting to link in too many shared libraries */
-#define ELIBEXEC 83 /* Cannot exec a shared library directly */
-#define EILSEQ 84 /* Illegal byte sequence */
-#define ERESTART 85 /* Interrupted system call should be restarted */
-#define ESTRPIPE 86 /* Streams pipe error */
-#define EUSERS 87 /* Too many users */
-#define ENOTSOCK 88 /* Socket operation on non-socket */
-#define EDESTADDRREQ 89 /* Destination address required */
-#define EMSGSIZE 90 /* Message too long */
-#define EPROTOTYPE 91 /* Protocol wrong type for socket */
-#define ENOPROTOOPT 92 /* Protocol not available */
-#define EPROTONOSUPPORT 93 /* Protocol not supported */
-#define ESOCKTNOSUPPORT 94 /* Socket type not supported */
-#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
-#define EPFNOSUPPORT 96 /* Protocol family not supported */
-#define EAFNOSUPPORT 97 /* Address family not supported by protocol */
-#define EADDRINUSE 98 /* Address already in use */
-#define EADDRNOTAVAIL 99 /* Cannot assign requested address */
-#define ENETDOWN 100 /* Network is down */
-#define ENETUNREACH 101 /* Network is unreachable */
-#define ENETRESET 102 /* Network dropped connection because of reset */
-#define ECONNABORTED 103 /* Software caused connection abort */
-#define ECONNRESET 104 /* Connection reset by peer */
-#define ENOBUFS 105 /* No buffer space available */
-#define EISCONN 106 /* Transport endpoint is already connected */
-#define ENOTCONN 107 /* Transport endpoint is not connected */
-#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */
-#define ETOOMANYREFS 109 /* Too many references: cannot splice */
-#define ETIMEDOUT 110 /* Connection timed out */
-#define ECONNREFUSED 111 /* Connection refused */
-#define EHOSTDOWN 112 /* Host is down */
-#define EHOSTUNREACH 113 /* No route to host */
-#define EALREADY 114 /* Operation already in progress */
-#define EINPROGRESS 115 /* Operation now in progress */
-#define ESTALE 116 /* Stale NFS file handle */
-#define EUCLEAN 117 /* Structure needs cleaning */
-#define ENOTNAM 118 /* Not a XENIX named type file */
-#define ENAVAIL 119 /* No XENIX semaphores available */
-#define EISNAM 120 /* Is a named type file */
-#define EREMOTEIO 121 /* Remote I/O error */
-#define EDQUOT 122 /* Quota exceeded */
-#endif /* ! MACH_INCLUDE */
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/asm/fcntl.h b/i386/i386at/gpl/linux/include/asm/fcntl.h
deleted file mode 100644
index 0cb8fcdb..00000000
--- a/i386/i386at/gpl/linux/include/asm/fcntl.h
+++ /dev/null
@@ -1,64 +0,0 @@
-#ifndef _I386_FCNTL_H
-#define _I386_FCNTL_H
-
-/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
- located on an ext2 file system */
-#define O_ACCMODE 0003
-#define O_RDONLY 00
-#define O_WRONLY 01
-#define O_RDWR 02
-#define O_CREAT 0100 /* not fcntl */
-#define O_EXCL 0200 /* not fcntl */
-#define O_NOCTTY 0400 /* not fcntl */
-#define O_TRUNC 01000 /* not fcntl */
-#define O_APPEND 02000
-#define O_NONBLOCK 04000
-#define O_NDELAY O_NONBLOCK
-#define O_SYNC 010000
-#define FASYNC 020000 /* fcntl, for BSD compatibility */
-
-#define F_DUPFD 0 /* dup */
-#define F_GETFD 1 /* get f_flags */
-#define F_SETFD 2 /* set f_flags */
-#define F_GETFL 3 /* more flags (cloexec) */
-#define F_SETFL 4
-#define F_GETLK 5
-#define F_SETLK 6
-#define F_SETLKW 7
-
-#define F_SETOWN 8 /* for sockets. */
-#define F_GETOWN 9 /* for sockets. */
-
-/* for F_[GET|SET]FL */
-#define FD_CLOEXEC 1 /* actually anything with low bit set goes */
-
-/* for posix fcntl() and lockf() */
-#define F_RDLCK 0
-#define F_WRLCK 1
-#define F_UNLCK 2
-
-/* for old implementation of bsd flock () */
-#define F_EXLCK 4 /* or 3 */
-#define F_SHLCK 8 /* or 4 */
-
-/* operations for bsd flock(), also used by the kernel implementation */
-#define LOCK_SH 1 /* shared lock */
-#define LOCK_EX 2 /* exclusive lock */
-#define LOCK_NB 4 /* or'd with one of the above to prevent
- blocking */
-#define LOCK_UN 8 /* remove lock */
-
-#ifdef __KERNEL__
-#define F_POSIX 1
-#define F_FLOCK 2
-#endif /* __KERNEL__ */
-
-struct flock {
- short l_type;
- short l_whence;
- off_t l_start;
- off_t l_len;
- pid_t l_pid;
-};
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/asm/floppy.h b/i386/i386at/gpl/linux/include/asm/floppy.h
deleted file mode 100644
index 93c58fea..00000000
--- a/i386/i386at/gpl/linux/include/asm/floppy.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Architecture specific parts of the Floppy driver
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1995
- */
-#ifndef __ASM_I386_FLOPPY_H
-#define __ASM_I386_FLOPPY_H
-
-#define fd_inb(port) inb_p(port)
-#define fd_outb(port,value) outb_p(port,value)
-
-#define fd_enable_dma() enable_dma(FLOPPY_DMA)
-#define fd_disable_dma() disable_dma(FLOPPY_DMA)
-#define fd_request_dma() request_dma(FLOPPY_DMA,"floppy")
-#define fd_free_dma() free_dma(FLOPPY_DMA)
-#define fd_clear_dma_ff() clear_dma_ff(FLOPPY_DMA)
-#define fd_set_dma_mode(mode) set_dma_mode(FLOPPY_DMA,mode)
-#define fd_set_dma_addr(addr) set_dma_addr(FLOPPY_DMA,addr)
-#define fd_set_dma_count(count) set_dma_count(FLOPPY_DMA,count)
-#define fd_enable_irq() enable_irq(FLOPPY_IRQ)
-#define fd_disable_irq() disable_irq(FLOPPY_IRQ)
-#define fd_cacheflush(addr,size) /* nothing */
-#define fd_request_irq() request_irq(FLOPPY_IRQ, floppy_interrupt, \
- SA_INTERRUPT|SA_SAMPLE_RANDOM, \
- "floppy")
-#define fd_free_irq() free_irq(FLOPPY_IRQ);
-
-__inline__ void virtual_dma_init(void)
-{
- /* Nothing to do on an i386 */
-}
-
-static int FDC1 = 0x3f0;
-static int FDC2 = -1;
-
-#define FLOPPY0_TYPE ((CMOS_READ(0x10) >> 4) & 15)
-#define FLOPPY1_TYPE (CMOS_READ(0x10) & 15)
-
-#define N_FDC 2
-#define N_DRIVE 8
-
-/*
- * The DMA channel used by the floppy controller cannot access data at
- * addresses >= 16MB
- *
- * Went back to the 1MB limit, as some people had problems with the floppy
- * driver otherwise. It doesn't matter much for performance anyway, as most
- * floppy accesses go through the track buffer.
- */
-#define CROSS_64KB(a,s) ((unsigned long)(a)/K_64 != ((unsigned long)(a) + (s) - 1) / K_64)
-
-#endif /* __ASM_I386_FLOPPY_H */
diff --git a/i386/i386at/gpl/linux/include/asm/io.h b/i386/i386at/gpl/linux/include/asm/io.h
deleted file mode 100644
index 98e32ce6..00000000
--- a/i386/i386at/gpl/linux/include/asm/io.h
+++ /dev/null
@@ -1,213 +0,0 @@
-#ifndef _ASM_IO_H
-#define _ASM_IO_H
-
-/*
- * This file contains the definitions for the x86 IO instructions
- * inb/inw/inl/outb/outw/outl and the "string versions" of the same
- * (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing"
- * versions of the single-IO instructions (inb_p/inw_p/..).
- *
- * This file is not meant to be obfuscating: it's just complicated
- * to (a) handle it all in a way that makes gcc able to optimize it
- * as well as possible and (b) trying to avoid writing the same thing
- * over and over again with slight variations and possibly making a
- * mistake somewhere.
- */
-
-/*
- * Thanks to James van Artsdalen for a better timing-fix than
- * the two short jumps: using outb's to a nonexistent port seems
- * to guarantee better timings even on fast machines.
- *
- * On the other hand, I'd like to be sure of a non-existent port:
- * I feel a bit unsafe about using 0x80 (should be safe, though)
- *
- * Linus
- */
-
-#ifdef SLOW_IO_BY_JUMPING
-#define __SLOW_DOWN_IO __asm__ __volatile__("jmp 1f\n1:\tjmp 1f\n1:")
-#else
-#define __SLOW_DOWN_IO __asm__ __volatile__("outb %al,$0x80")
-#endif
-
-#ifdef REALLY_SLOW_IO
-#define SLOW_DOWN_IO { __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; }
-#else
-#define SLOW_DOWN_IO __SLOW_DOWN_IO
-#endif
-
-/*
- * Change virtual addresses to physical addresses and vv.
- * These are trivial on the 1:1 Linux/i386 mapping (but if we ever
- * make the kernel segment mapped at 0, we need to do translation
- * on the i386 as well)
- */
-extern inline unsigned long virt_to_phys(volatile void * address)
-{
- return (unsigned long) address;
-}
-
-extern inline void * phys_to_virt(unsigned long address)
-{
- return (void *) address;
-}
-
-/*
- * IO bus memory addresses are also 1:1 with the physical address
- */
-#define virt_to_bus virt_to_phys
-#define bus_to_virt phys_to_virt
-
-/*
- * readX/writeX() are used to access memory mapped devices. On some
- * architectures the memory mapped IO stuff needs to be accessed
- * differently. On the x86 architecture, we just read/write the
- * memory location directly.
- */
-#define readb(addr) (*(volatile unsigned char *) (addr))
-#define readw(addr) (*(volatile unsigned short *) (addr))
-#define readl(addr) (*(volatile unsigned int *) (addr))
-
-#define writeb(b,addr) ((*(volatile unsigned char *) (addr)) = (b))
-#define writew(b,addr) ((*(volatile unsigned short *) (addr)) = (b))
-#define writel(b,addr) ((*(volatile unsigned int *) (addr)) = (b))
-
-#define memset_io(a,b,c) memset((void *)(a),(b),(c))
-#define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c))
-#define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c))
-
-/*
- * Again, i386 does not require mem IO specific function.
- */
-
-#define eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),(void *)(b),(c),(d))
-
-/*
- * Talk about misusing macros..
- */
-
-#define __OUT1(s,x) \
-extern inline void __out##s(unsigned x value, unsigned short port) {
-
-#define __OUT2(s,s1,s2) \
-__asm__ __volatile__ ("out" #s " %" s1 "0,%" s2 "1"
-
-#define __OUT(s,s1,x) \
-__OUT1(s,x) __OUT2(s,s1,"w") : : "a" (value), "d" (port)); } \
-__OUT1(s##c,x) __OUT2(s,s1,"") : : "a" (value), "id" (port)); } \
-__OUT1(s##_p,x) __OUT2(s,s1,"w") : : "a" (value), "d" (port)); SLOW_DOWN_IO; } \
-__OUT1(s##c_p,x) __OUT2(s,s1,"") : : "a" (value), "id" (port)); SLOW_DOWN_IO; }
-
-#define __IN1(s) \
-extern inline RETURN_TYPE __in##s(unsigned short port) { RETURN_TYPE _v;
-
-#define __IN2(s,s1,s2) \
-__asm__ __volatile__ ("in" #s " %" s2 "1,%" s1 "0"
-
-#define __IN(s,s1,i...) \
-__IN1(s) __IN2(s,s1,"w") : "=a" (_v) : "d" (port) ,##i ); return _v; } \
-__IN1(s##c) __IN2(s,s1,"") : "=a" (_v) : "id" (port) ,##i ); return _v; } \
-__IN1(s##_p) __IN2(s,s1,"w") : "=a" (_v) : "d" (port) ,##i ); SLOW_DOWN_IO; return _v; } \
-__IN1(s##c_p) __IN2(s,s1,"") : "=a" (_v) : "id" (port) ,##i ); SLOW_DOWN_IO; return _v; }
-
-#define __INS(s) \
-extern inline void ins##s(unsigned short port, void * addr, unsigned long count) \
-{ __asm__ __volatile__ ("cld ; rep ; ins" #s \
-: "=D" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
-
-#define __OUTS(s) \
-extern inline void outs##s(unsigned short port, const void * addr, unsigned long count) \
-{ __asm__ __volatile__ ("cld ; rep ; outs" #s \
-: "=S" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
-
-#define RETURN_TYPE unsigned char
-/* __IN(b,"b","0" (0)) */
-__IN(b,"")
-#undef RETURN_TYPE
-#define RETURN_TYPE unsigned short
-/* __IN(w,"w","0" (0)) */
-__IN(w,"")
-#undef RETURN_TYPE
-#define RETURN_TYPE unsigned int
-__IN(l,"")
-#undef RETURN_TYPE
-
-__OUT(b,"b",char)
-__OUT(w,"w",short)
-__OUT(l,,int)
-
-__INS(b)
-__INS(w)
-__INS(l)
-
-__OUTS(b)
-__OUTS(w)
-__OUTS(l)
-
-/*
- * Note that due to the way __builtin_constant_p() works, you
- * - can't use it inside a inline function (it will never be true)
- * - you don't have to worry about side effects within the __builtin..
- */
-#define outb(val,port) \
-((__builtin_constant_p((port)) && (port) < 256) ? \
- __outbc((val),(port)) : \
- __outb((val),(port)))
-
-#define inb(port) \
-((__builtin_constant_p((port)) && (port) < 256) ? \
- __inbc(port) : \
- __inb(port))
-
-#define outb_p(val,port) \
-((__builtin_constant_p((port)) && (port) < 256) ? \
- __outbc_p((val),(port)) : \
- __outb_p((val),(port)))
-
-#define inb_p(port) \
-((__builtin_constant_p((port)) && (port) < 256) ? \
- __inbc_p(port) : \
- __inb_p(port))
-
-#define outw(val,port) \
-((__builtin_constant_p((port)) && (port) < 256) ? \
- __outwc((val),(port)) : \
- __outw((val),(port)))
-
-#define inw(port) \
-((__builtin_constant_p((port)) && (port) < 256) ? \
- __inwc(port) : \
- __inw(port))
-
-#define outw_p(val,port) \
-((__builtin_constant_p((port)) && (port) < 256) ? \
- __outwc_p((val),(port)) : \
- __outw_p((val),(port)))
-
-#define inw_p(port) \
-((__builtin_constant_p((port)) && (port) < 256) ? \
- __inwc_p(port) : \
- __inw_p(port))
-
-#define outl(val,port) \
-((__builtin_constant_p((port)) && (port) < 256) ? \
- __outlc((val),(port)) : \
- __outl((val),(port)))
-
-#define inl(port) \
-((__builtin_constant_p((port)) && (port) < 256) ? \
- __inlc(port) : \
- __inl(port))
-
-#define outl_p(val,port) \
-((__builtin_constant_p((port)) && (port) < 256) ? \
- __outlc_p((val),(port)) : \
- __outl_p((val),(port)))
-
-#define inl_p(port) \
-((__builtin_constant_p((port)) && (port) < 256) ? \
- __inlc_p(port) : \
- __inl_p(port))
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/asm/ioctl.h b/i386/i386at/gpl/linux/include/asm/ioctl.h
deleted file mode 100644
index cc94e3b9..00000000
--- a/i386/i386at/gpl/linux/include/asm/ioctl.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/* $Id: ioctl.h,v 1.1.1.1 1997/02/25 21:27:24 thomas Exp $
- *
- * linux/ioctl.h for Linux by H.H. Bergman.
- */
-
-#ifndef _ASMI386_IOCTL_H
-#define _ASMI386_IOCTL_H
-
-/* ioctl command encoding: 32 bits total, command in lower 16 bits,
- * size of the parameter structure in the lower 14 bits of the
- * upper 16 bits.
- * Encoding the size of the parameter structure in the ioctl request
- * is useful for catching programs compiled with old versions
- * and to avoid overwriting user space outside the user buffer area.
- * The highest 2 bits are reserved for indicating the ``access mode''.
- * NOTE: This limits the max parameter size to 16kB -1 !
- */
-
-/*
- * The following is for compatibility across the various Linux
- * platforms. The i386 ioctl numbering scheme doesn't really enforce
- * a type field. De facto, however, the top 8 bits of the lower 16
- * bits are indeed used as a type field, so we might just as well make
- * this explicit here. Please be sure to use the decoding macros
- * below from now on.
- */
-#define _IOC_NRBITS 8
-#define _IOC_TYPEBITS 8
-#define _IOC_SIZEBITS 14
-#define _IOC_DIRBITS 2
-
-#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1)
-#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1)
-#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1)
-#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1)
-
-#define _IOC_NRSHIFT 0
-#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
-#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
-#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS)
-
-/*
- * Direction bits.
- */
-#define _IOC_NONE 0U
-#define _IOC_WRITE 1U
-#define _IOC_READ 2U
-
-#define _IOC(dir,type,nr,size) \
- (((dir) << _IOC_DIRSHIFT) | \
- ((type) << _IOC_TYPESHIFT) | \
- ((nr) << _IOC_NRSHIFT) | \
- ((size) << _IOC_SIZESHIFT))
-
-/* used to create numbers */
-#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0)
-#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size))
-#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
-#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
-
-/* used to decode ioctl numbers.. */
-#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
-#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
-#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
-#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
-
-/* ...and for the drivers/sound files... */
-
-#define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT)
-#define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT)
-#define IOC_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
-#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT)
-#define IOCSIZE_SHIFT (_IOC_SIZESHIFT)
-
-#endif /* _ASMI386_IOCTL_H */
diff --git a/i386/i386at/gpl/linux/include/asm/irq.h b/i386/i386at/gpl/linux/include/asm/irq.h
deleted file mode 100644
index 8fd44b48..00000000
--- a/i386/i386at/gpl/linux/include/asm/irq.h
+++ /dev/null
@@ -1,346 +0,0 @@
-#ifndef _ASM_IRQ_H
-#define _ASM_IRQ_H
-
-/*
- * linux/include/asm/irq.h
- *
- * (C) 1992, 1993 Linus Torvalds
- *
- * IRQ/IPI changes taken from work by Thomas Radke <tomsoft@informatik.tu-chemnitz.de>
- */
-
-#include <linux/linkage.h>
-#include <asm/segment.h>
-
-#define NR_IRQS 16
-
-extern void disable_irq(unsigned int);
-extern void enable_irq(unsigned int);
-
-#define __STR(x) #x
-#define STR(x) __STR(x)
-
-#define SAVE_ALL \
- "cld\n\t" \
- "push %gs\n\t" \
- "push %fs\n\t" \
- "push %es\n\t" \
- "push %ds\n\t" \
- "pushl %eax\n\t" \
- "pushl %ebp\n\t" \
- "pushl %edi\n\t" \
- "pushl %esi\n\t" \
- "pushl %edx\n\t" \
- "pushl %ecx\n\t" \
- "pushl %ebx\n\t" \
- "movl $" STR(KERNEL_DS) ",%edx\n\t" \
- "mov %dx,%ds\n\t" \
- "mov %dx,%es\n\t" \
- "movl $" STR(USER_DS) ",%edx\n\t" \
- "mov %dx,%fs\n\t" \
- "movl $0,%edx\n\t" \
- "movl %edx,%db7\n\t"
-
-/*
- * SAVE_MOST/RESTORE_MOST is used for the faster version of IRQ handlers,
- * installed by using the SA_INTERRUPT flag. These kinds of IRQ's don't
- * call the routines that do signal handling etc on return, and can have
- * more relaxed register-saving etc. They are also atomic, and are thus
- * suited for small, fast interrupts like the serial lines or the harddisk
- * drivers, which don't actually need signal handling etc.
- *
- * Also note that we actually save only those registers that are used in
- * C subroutines (%eax, %edx and %ecx), so if you do something weird,
- * you're on your own. The only segments that are saved (not counting the
- * automatic stack and code segment handling) are %ds and %es, and they
- * point to kernel space. No messing around with %fs here.
- */
-#define SAVE_MOST \
- "cld\n\t" \
- "push %es\n\t" \
- "push %ds\n\t" \
- "pushl %eax\n\t" \
- "pushl %edx\n\t" \
- "pushl %ecx\n\t" \
- "movl $" STR(KERNEL_DS) ",%edx\n\t" \
- "mov %dx,%ds\n\t" \
- "mov %dx,%es\n\t"
-
-#define RESTORE_MOST \
- "popl %ecx\n\t" \
- "popl %edx\n\t" \
- "popl %eax\n\t" \
- "pop %ds\n\t" \
- "pop %es\n\t" \
- "iret"
-
-/*
- * The "inb" instructions are not needed, but seem to change the timings
- * a bit - without them it seems that the harddisk driver won't work on
- * all hardware. Arghh.
- */
-#define ACK_FIRST(mask) \
- "inb $0x21,%al\n\t" \
- "jmp 1f\n" \
- "1:\tjmp 1f\n" \
- "1:\torb $" #mask ","SYMBOL_NAME_STR(cache_21)"\n\t" \
- "movb "SYMBOL_NAME_STR(cache_21)",%al\n\t" \
- "outb %al,$0x21\n\t" \
- "jmp 1f\n" \
- "1:\tjmp 1f\n" \
- "1:\tmovb $0x20,%al\n\t" \
- "outb %al,$0x20\n\t"
-
-#define ACK_SECOND(mask) \
- "inb $0xA1,%al\n\t" \
- "jmp 1f\n" \
- "1:\tjmp 1f\n" \
- "1:\torb $" #mask ","SYMBOL_NAME_STR(cache_A1)"\n\t" \
- "movb "SYMBOL_NAME_STR(cache_A1)",%al\n\t" \
- "outb %al,$0xA1\n\t" \
- "jmp 1f\n" \
- "1:\tjmp 1f\n" \
- "1:\tmovb $0x20,%al\n\t" \
- "outb %al,$0xA0\n\t" \
- "jmp 1f\n" \
- "1:\tjmp 1f\n" \
- "1:\toutb %al,$0x20\n\t"
-
-#define UNBLK_FIRST(mask) \
- "inb $0x21,%al\n\t" \
- "jmp 1f\n" \
- "1:\tjmp 1f\n" \
- "1:\tandb $~(" #mask "),"SYMBOL_NAME_STR(cache_21)"\n\t" \
- "movb "SYMBOL_NAME_STR(cache_21)",%al\n\t" \
- "outb %al,$0x21\n\t"
-
-#define UNBLK_SECOND(mask) \
- "inb $0xA1,%al\n\t" \
- "jmp 1f\n" \
- "1:\tjmp 1f\n" \
- "1:\tandb $~(" #mask "),"SYMBOL_NAME_STR(cache_A1)"\n\t" \
- "movb "SYMBOL_NAME_STR(cache_A1)",%al\n\t" \
- "outb %al,$0xA1\n\t"
-
-#define IRQ_NAME2(nr) nr##_interrupt(void)
-#define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)
-#define FAST_IRQ_NAME(nr) IRQ_NAME2(fast_IRQ##nr)
-#define BAD_IRQ_NAME(nr) IRQ_NAME2(bad_IRQ##nr)
-
-#ifdef __SMP__
-
-#ifndef __SMP_PROF__
-#define SMP_PROF_INT_SPINS
-#define SMP_PROF_IPI_CNT
-#else
-#define SMP_PROF_INT_SPINS "incl "SYMBOL_NAME_STR(smp_spins)"(,%eax,4)\n\t"
-#define SMP_PROF_IPI_CNT "incl "SYMBOL_NAME_STR(ipi_count)"\n\t"
-#endif
-
-#define GET_PROCESSOR_ID \
- "movl "SYMBOL_NAME_STR(apic_reg)", %edx\n\t" \
- "movl 32(%edx), %eax\n\t" \
- "shrl $24,%eax\n\t" \
- "andb $0x0F,%al\n"
-
-#define ENTER_KERNEL \
- "pushl %eax\n\t" \
- "pushl %edx\n\t" \
- "pushfl\n\t" \
- "cli\n\t" \
- GET_PROCESSOR_ID \
- "1: " \
- "lock\n\t" \
- "btsl $0, "SYMBOL_NAME_STR(kernel_flag)"\n\t" \
- "jnc 3f\n\t" \
- "cmpb "SYMBOL_NAME_STR(active_kernel_processor)", %al\n\t" \
- "je 4f\n\t" \
- "2: " \
- SMP_PROF_INT_SPINS \
- "btl %al, "SYMBOL_NAME_STR(smp_invalidate_needed)"\n\t" \
- "jnc 5f\n\t" \
- "lock\n\t" \
- "btrl %al, "SYMBOL_NAME_STR(smp_invalidate_needed)"\n\t" \
- "jnc 5f\n\t" \
- "movl %cr3,%edx\n\t" \
- "movl %edx,%cr3\n" \
- "5: btl $0, "SYMBOL_NAME_STR(kernel_flag)"\n\t" \
- "jc 2b\n\t" \
- "jmp 1b\n\t" \
- "3: " \
- "movb %al, "SYMBOL_NAME_STR(active_kernel_processor)"\n\t" \
- "4: " \
- "incl "SYMBOL_NAME_STR(kernel_counter)"\n\t" \
- "popfl\n\t" \
- "popl %edx\n\t" \
- "popl %eax\n\t"
-
-#define LEAVE_KERNEL \
- "pushfl\n\t" \
- "cli\n\t" \
- "decl "SYMBOL_NAME_STR(kernel_counter)"\n\t" \
- "jnz 1f\n\t" \
- "movb $" STR (NO_PROC_ID) ", "SYMBOL_NAME_STR(active_kernel_processor)"\n\t" \
- "lock\n\t" \
- "btrl $0, "SYMBOL_NAME_STR(kernel_flag)"\n\t" \
- "1: " \
- "popfl\n\t"
-
-
-/*
- * the syscall count inc is a gross hack because ret_from_syscall is used by both irq and
- * syscall return paths (urghh).
- */
-
-#define BUILD_IRQ(chip,nr,mask) \
-asmlinkage void IRQ_NAME(nr); \
-asmlinkage void FAST_IRQ_NAME(nr); \
-asmlinkage void BAD_IRQ_NAME(nr); \
-__asm__( \
-"\n"__ALIGN_STR"\n" \
-SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
- "pushl $-"#nr"-2\n\t" \
- SAVE_ALL \
- ENTER_KERNEL \
- ACK_##chip(mask) \
- "incl "SYMBOL_NAME_STR(intr_count)"\n\t"\
- "sti\n\t" \
- "movl %esp,%ebx\n\t" \
- "pushl %ebx\n\t" \
- "pushl $" #nr "\n\t" \
- "call "SYMBOL_NAME_STR(do_IRQ)"\n\t" \
- "addl $8,%esp\n\t" \
- "cli\n\t" \
- UNBLK_##chip(mask) \
- "decl "SYMBOL_NAME_STR(intr_count)"\n\t" \
- "incl "SYMBOL_NAME_STR(syscall_count)"\n\t" \
- "jmp ret_from_sys_call\n" \
-"\n"__ALIGN_STR"\n" \
-SYMBOL_NAME_STR(fast_IRQ) #nr "_interrupt:\n\t" \
- SAVE_MOST \
- ENTER_KERNEL \
- ACK_##chip(mask) \
- "incl "SYMBOL_NAME_STR(intr_count)"\n\t" \
- "pushl $" #nr "\n\t" \
- "call "SYMBOL_NAME_STR(do_fast_IRQ)"\n\t" \
- "addl $4,%esp\n\t" \
- "cli\n\t" \
- UNBLK_##chip(mask) \
- "decl "SYMBOL_NAME_STR(intr_count)"\n\t" \
- LEAVE_KERNEL \
- RESTORE_MOST \
-"\n"__ALIGN_STR"\n" \
-SYMBOL_NAME_STR(bad_IRQ) #nr "_interrupt:\n\t" \
- SAVE_MOST \
- ENTER_KERNEL \
- ACK_##chip(mask) \
- LEAVE_KERNEL \
- RESTORE_MOST);
-
-
-/*
- * Message pass must be a fast IRQ..
- */
-
-#define BUILD_MSGIRQ(chip,nr,mask) \
-asmlinkage void IRQ_NAME(nr); \
-asmlinkage void FAST_IRQ_NAME(nr); \
-asmlinkage void BAD_IRQ_NAME(nr); \
-__asm__( \
-"\n"__ALIGN_STR"\n" \
-SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
- "pushl $-"#nr"-2\n\t" \
- SAVE_ALL \
- ENTER_KERNEL \
- ACK_##chip(mask) \
- "incl "SYMBOL_NAME_STR(intr_count)"\n\t"\
- "sti\n\t" \
- "movl %esp,%ebx\n\t" \
- "pushl %ebx\n\t" \
- "pushl $" #nr "\n\t" \
- "call "SYMBOL_NAME_STR(do_IRQ)"\n\t" \
- "addl $8,%esp\n\t" \
- "cli\n\t" \
- UNBLK_##chip(mask) \
- "decl "SYMBOL_NAME_STR(intr_count)"\n\t" \
- "incl "SYMBOL_NAME_STR(syscall_count)"\n\t" \
- "jmp ret_from_sys_call\n" \
-"\n"__ALIGN_STR"\n" \
-SYMBOL_NAME_STR(fast_IRQ) #nr "_interrupt:\n\t" \
- SAVE_MOST \
- ACK_##chip(mask) \
- SMP_PROF_IPI_CNT \
- "pushl $" #nr "\n\t" \
- "call "SYMBOL_NAME_STR(do_fast_IRQ)"\n\t" \
- "addl $4,%esp\n\t" \
- "cli\n\t" \
- UNBLK_##chip(mask) \
- RESTORE_MOST \
-"\n"__ALIGN_STR"\n" \
-SYMBOL_NAME_STR(bad_IRQ) #nr "_interrupt:\n\t" \
- SAVE_MOST \
- ACK_##chip(mask) \
- RESTORE_MOST);
-
-#define BUILD_RESCHEDIRQ(nr) \
-asmlinkage void IRQ_NAME(nr); \
-__asm__( \
-"\n"__ALIGN_STR"\n" \
-SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
- "pushl $-"#nr"-2\n\t" \
- SAVE_ALL \
- ENTER_KERNEL \
- "incl "SYMBOL_NAME_STR(intr_count)"\n\t"\
- "sti\n\t" \
- "movl %esp,%ebx\n\t" \
- "pushl %ebx\n\t" \
- "pushl $" #nr "\n\t" \
- "call "SYMBOL_NAME_STR(smp_reschedule_irq)"\n\t" \
- "addl $8,%esp\n\t" \
- "cli\n\t" \
- "decl "SYMBOL_NAME_STR(intr_count)"\n\t" \
- "incl "SYMBOL_NAME_STR(syscall_count)"\n\t" \
- "jmp ret_from_sys_call\n");
-#else
-
-#define BUILD_IRQ(chip,nr,mask) \
-asmlinkage void IRQ_NAME(nr); \
-asmlinkage void FAST_IRQ_NAME(nr); \
-asmlinkage void BAD_IRQ_NAME(nr); \
-__asm__( \
-"\n"__ALIGN_STR"\n" \
-SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
- "pushl $-"#nr"-2\n\t" \
- SAVE_ALL \
- ACK_##chip(mask) \
- "incl "SYMBOL_NAME_STR(intr_count)"\n\t"\
- "sti\n\t" \
- "movl %esp,%ebx\n\t" \
- "pushl %ebx\n\t" \
- "pushl $" #nr "\n\t" \
- "call "SYMBOL_NAME_STR(do_IRQ)"\n\t" \
- "addl $8,%esp\n\t" \
- "cli\n\t" \
- UNBLK_##chip(mask) \
- "decl "SYMBOL_NAME_STR(intr_count)"\n\t" \
- "jmp ret_from_sys_call\n" \
-"\n"__ALIGN_STR"\n" \
-SYMBOL_NAME_STR(fast_IRQ) #nr "_interrupt:\n\t" \
- SAVE_MOST \
- ACK_##chip(mask) \
- "incl "SYMBOL_NAME_STR(intr_count)"\n\t" \
- "pushl $" #nr "\n\t" \
- "call "SYMBOL_NAME_STR(do_fast_IRQ)"\n\t" \
- "addl $4,%esp\n\t" \
- "cli\n\t" \
- UNBLK_##chip(mask) \
- "decl "SYMBOL_NAME_STR(intr_count)"\n\t" \
- RESTORE_MOST \
-"\n"__ALIGN_STR"\n" \
-SYMBOL_NAME_STR(bad_IRQ) #nr "_interrupt:\n\t" \
- SAVE_MOST \
- ACK_##chip(mask) \
- RESTORE_MOST);
-
-#endif
-#endif
diff --git a/i386/i386at/gpl/linux/include/asm/page.h b/i386/i386at/gpl/linux/include/asm/page.h
deleted file mode 100644
index 2bb6837e..00000000
--- a/i386/i386at/gpl/linux/include/asm/page.h
+++ /dev/null
@@ -1,64 +0,0 @@
-#ifndef _I386_PAGE_H
-#define _I386_PAGE_H
-
-#ifndef MACH_INCLUDE
-/* PAGE_SHIFT determines the page size */
-#define PAGE_SHIFT 12
-#define PAGE_SIZE (1UL << PAGE_SHIFT)
-#define PAGE_MASK (~(PAGE_SIZE-1))
-#endif
-
-#ifdef __KERNEL__
-
-#define STRICT_MM_TYPECHECKS
-
-#ifdef STRICT_MM_TYPECHECKS
-/*
- * These are used to make use of C type-checking..
- */
-typedef struct { unsigned long pte; } pte_t;
-typedef struct { unsigned long pmd; } pmd_t;
-typedef struct { unsigned long pgd; } pgd_t;
-typedef struct { unsigned long pgprot; } pgprot_t;
-
-#define pte_val(x) ((x).pte)
-#define pmd_val(x) ((x).pmd)
-#define pgd_val(x) ((x).pgd)
-#define pgprot_val(x) ((x).pgprot)
-
-#define __pte(x) ((pte_t) { (x) } )
-#define __pmd(x) ((pmd_t) { (x) } )
-#define __pgd(x) ((pgd_t) { (x) } )
-#define __pgprot(x) ((pgprot_t) { (x) } )
-
-#else
-/*
- * .. while these make it easier on the compiler
- */
-typedef unsigned long pte_t;
-typedef unsigned long pmd_t;
-typedef unsigned long pgd_t;
-typedef unsigned long pgprot_t;
-
-#define pte_val(x) (x)
-#define pmd_val(x) (x)
-#define pgd_val(x) (x)
-#define pgprot_val(x) (x)
-
-#define __pte(x) (x)
-#define __pmd(x) (x)
-#define __pgd(x) (x)
-#define __pgprot(x) (x)
-
-#endif
-
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-
-/* This handles the memory map.. */
-#define PAGE_OFFSET 0
-#define MAP_NR(addr) (((unsigned long)(addr)) >> PAGE_SHIFT)
-
-#endif /* __KERNEL__ */
-
-#endif /* _I386_PAGE_H */
diff --git a/i386/i386at/gpl/linux/include/asm/param.h b/i386/i386at/gpl/linux/include/asm/param.h
deleted file mode 100644
index f821b864..00000000
--- a/i386/i386at/gpl/linux/include/asm/param.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef _ASMi386_PARAM_H
-#define _ASMi386_PARAM_H
-
-#ifndef HZ
-#define HZ 100
-#endif
-
-#define EXEC_PAGESIZE 4096
-
-#ifndef NGROUPS
-#define NGROUPS 32
-#endif
-
-#ifndef NOGROUP
-#define NOGROUP (-1)
-#endif
-
-#define MAXHOSTNAMELEN 64 /* max length of hostname */
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/asm/processor.h b/i386/i386at/gpl/linux/include/asm/processor.h
deleted file mode 100644
index dea7827b..00000000
--- a/i386/i386at/gpl/linux/include/asm/processor.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * include/asm-i386/processor.h
- *
- * Copyright (C) 1994 Linus Torvalds
- */
-
-#ifndef __ASM_I386_PROCESSOR_H
-#define __ASM_I386_PROCESSOR_H
-
-/*
- * System setup and hardware bug flags..
- */
-extern char hard_math;
-extern char x86; /* lower 4 bits */
-extern char x86_vendor_id[13];
-extern char x86_model; /* lower 4 bits */
-extern char x86_mask; /* lower 4 bits */
-extern int x86_capability; /* field of flags */
-extern int fdiv_bug;
-extern char ignore_irq13;
-extern char wp_works_ok; /* doesn't work on a 386 */
-extern char hlt_works_ok; /* problems on some 486Dx4's and old 386's */
-
-/*
- * Bus types (default is ISA, but people can check others with these..)
- * MCA_bus hardcoded to 0 for now.
- */
-extern int EISA_bus;
-#define MCA_bus 0
-#define MCA_bus__is_a_macro /* for versions in ksyms.c */
-
-/*
- * User space process size: 3GB. This is hardcoded into a few places,
- * so don't change it unless you know what you are doing.
- */
-#define TASK_SIZE (0xC0000000UL)
-
-/*
- * Size of io_bitmap in longwords: 32 is ports 0-0x3ff.
- */
-#define IO_BITMAP_SIZE 32
-
-struct i387_hard_struct {
- long cwd;
- long swd;
- long twd;
- long fip;
- long fcs;
- long foo;
- long fos;
- long st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */
-};
-
-struct i387_soft_struct {
- long cwd;
- long swd;
- long twd;
- long fip;
- long fcs;
- long foo;
- long fos;
- long top;
- struct fpu_reg regs[8]; /* 8*16 bytes for each FP-reg = 128 bytes */
- unsigned char lookahead;
- struct info *info;
- unsigned long entry_eip;
-};
-
-union i387_union {
- struct i387_hard_struct hard;
- struct i387_soft_struct soft;
-};
-
-struct thread_struct {
- unsigned short back_link,__blh;
- unsigned long esp0;
- unsigned short ss0,__ss0h;
- unsigned long esp1;
- unsigned short ss1,__ss1h;
- unsigned long esp2;
- unsigned short ss2,__ss2h;
- unsigned long cr3;
- unsigned long eip;
- unsigned long eflags;
- unsigned long eax,ecx,edx,ebx;
- unsigned long esp;
- unsigned long ebp;
- unsigned long esi;
- unsigned long edi;
- unsigned short es, __esh;
- unsigned short cs, __csh;
- unsigned short ss, __ssh;
- unsigned short ds, __dsh;
- unsigned short fs, __fsh;
- unsigned short gs, __gsh;
- unsigned short ldt, __ldth;
- unsigned short trace, bitmap;
- unsigned long io_bitmap[IO_BITMAP_SIZE+1];
- unsigned long tr;
- unsigned long cr2, trap_no, error_code;
-/* floating point info */
- union i387_union i387;
-/* virtual 86 mode info */
- struct vm86_struct * vm86_info;
- unsigned long screen_bitmap;
- unsigned long v86flags, v86mask, v86mode;
-};
-
-#define INIT_MMAP { &init_mm, 0, 0x40000000, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC }
-
-#define INIT_TSS { \
- 0,0, \
- sizeof(init_kernel_stack) + (long) &init_kernel_stack, \
- KERNEL_DS, 0, \
- 0,0,0,0,0,0, \
- (long) &swapper_pg_dir, \
- 0,0,0,0,0,0,0,0,0,0, \
- USER_DS,0,USER_DS,0,USER_DS,0,USER_DS,0,USER_DS,0,USER_DS,0, \
- _LDT(0),0, \
- 0, 0x8000, \
- {~0, }, /* ioperm */ \
- _TSS(0), 0, 0,0, \
- { { 0, }, }, /* 387 state */ \
- NULL, 0, 0, 0, 0 /* vm86_info */ \
-}
-
-#define alloc_kernel_stack() get_free_page(GFP_KERNEL)
-#define free_kernel_stack(page) free_page((page))
-
-static inline void start_thread(struct pt_regs * regs, unsigned long eip, unsigned long esp)
-{
- regs->cs = USER_CS;
- regs->ds = regs->es = regs->ss = regs->fs = regs->gs = USER_DS;
- regs->eip = eip;
- regs->esp = esp;
-}
-
-/*
- * Return saved PC of a blocked thread.
- */
-extern inline unsigned long thread_saved_pc(struct thread_struct *t)
-{
- return ((unsigned long *)t->esp)[3];
-}
-
-#endif /* __ASM_I386_PROCESSOR_H */
diff --git a/i386/i386at/gpl/linux/include/asm/ptrace.h b/i386/i386at/gpl/linux/include/asm/ptrace.h
deleted file mode 100644
index 8e4aa52f..00000000
--- a/i386/i386at/gpl/linux/include/asm/ptrace.h
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef _I386_PTRACE_H
-#define _I386_PTRACE_H
-
-#define EBX 0
-#define ECX 1
-#define EDX 2
-#define ESI 3
-#define EDI 4
-#define EBP 5
-#define EAX 6
-#define DS 7
-#define ES 8
-#define FS 9
-#define GS 10
-#define ORIG_EAX 11
-#define EIP 12
-#define CS 13
-#define EFL 14
-#define UESP 15
-#define SS 16
-
-
-/* this struct defines the way the registers are stored on the
- stack during a system call. */
-
-struct pt_regs {
- long ebx;
- long ecx;
- long edx;
- long esi;
- long edi;
- long ebp;
- long eax;
- unsigned short ds, __dsu;
- unsigned short es, __esu;
- unsigned short fs, __fsu;
- unsigned short gs, __gsu;
- long orig_eax;
- long eip;
- unsigned short cs, __csu;
- long eflags;
- long esp;
- unsigned short ss, __ssu;
-};
-
-#ifdef __KERNEL__
-#define user_mode(regs) ((VM_MASK & (regs)->eflags) || (3 & (regs)->cs))
-#define instruction_pointer(regs) ((regs)->eip)
-extern void show_regs(struct pt_regs *);
-#endif
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/asm/resource.h b/i386/i386at/gpl/linux/include/asm/resource.h
deleted file mode 100644
index 83940d16..00000000
--- a/i386/i386at/gpl/linux/include/asm/resource.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef _I386_RESOURCE_H
-#define _I386_RESOURCE_H
-
-/*
- * Resource limits
- */
-
-#define RLIMIT_CPU 0 /* CPU time in ms */
-#define RLIMIT_FSIZE 1 /* Maximum filesize */
-#define RLIMIT_DATA 2 /* max data size */
-#define RLIMIT_STACK 3 /* max stack size */
-#define RLIMIT_CORE 4 /* max core file size */
-#define RLIMIT_RSS 5 /* max resident set size */
-#define RLIMIT_NPROC 6 /* max number of processes */
-#define RLIMIT_NOFILE 7 /* max number of open files */
-#define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */
-
-#define RLIM_NLIMITS 9
-
-#ifdef __KERNEL__
-
-#define INIT_RLIMITS \
-{ \
- { LONG_MAX, LONG_MAX }, \
- { LONG_MAX, LONG_MAX }, \
- { LONG_MAX, LONG_MAX }, \
- { _STK_LIM, _STK_LIM }, \
- { 0, LONG_MAX }, \
- { LONG_MAX, LONG_MAX }, \
- { MAX_TASKS_PER_USER, MAX_TASKS_PER_USER }, \
- { NR_OPEN, NR_OPEN }, \
- { LONG_MAX, LONG_MAX }, \
-}
-
-#endif /* __KERNEL__ */
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/asm/segment.h b/i386/i386at/gpl/linux/include/asm/segment.h
deleted file mode 100644
index 7cfafa4b..00000000
--- a/i386/i386at/gpl/linux/include/asm/segment.h
+++ /dev/null
@@ -1,347 +0,0 @@
-#ifndef _ASM_SEGMENT_H
-#define _ASM_SEGMENT_H
-
-#ifdef MACH
-#define KERNEL_CS 0x08
-#define KERNEL_DS 0x10
-
-#define USER_CS 0x17
-#define USER_DS 0x1f
-#else
-#define KERNEL_CS 0x10
-#define KERNEL_DS 0x18
-
-#define USER_CS 0x23
-#define USER_DS 0x2B
-#endif
-
-#ifndef __ASSEMBLY__
-
-/*
- * Uh, these should become the main single-value transfer routines..
- * They automatically use the right size if we just have the right
- * pointer type..
- */
-#define put_user(x,ptr) __put_user((unsigned long)(x),(ptr),sizeof(*(ptr)))
-#define get_user(ptr) ((__typeof__(*(ptr)))__get_user((ptr),sizeof(*(ptr))))
-
-/*
- * This is a silly but good way to make sure that
- * the __put_user function is indeed always optimized,
- * and that we use the correct sizes..
- */
-extern int bad_user_access_length(void);
-
-/*
- * dummy pointer type structure.. gcc won't try to do something strange
- * this way..
- */
-struct __segment_dummy { unsigned long a[100]; };
-#define __sd(x) ((struct __segment_dummy *) (x))
-#define __const_sd(x) ((const struct __segment_dummy *) (x))
-
-static inline void __put_user(unsigned long x, void * y, int size)
-{
- switch (size) {
- case 1:
- __asm__ ("movb %b1,%%fs:%0"
- :"=m" (*__sd(y))
- :"iq" ((unsigned char) x), "m" (*__sd(y)));
- break;
- case 2:
- __asm__ ("movw %w1,%%fs:%0"
- :"=m" (*__sd(y))
- :"ir" ((unsigned short) x), "m" (*__sd(y)));
- break;
- case 4:
- __asm__ ("movl %1,%%fs:%0"
- :"=m" (*__sd(y))
- :"ir" (x), "m" (*__sd(y)));
- break;
- default:
- bad_user_access_length();
- }
-}
-
-static inline unsigned long __get_user(const void * y, int size)
-{
- unsigned long result;
-
- switch (size) {
- case 1:
- __asm__ ("movb %%fs:%1,%b0"
- :"=q" (result)
- :"m" (*__const_sd(y)));
- return (unsigned char) result;
- case 2:
- __asm__ ("movw %%fs:%1,%w0"
- :"=r" (result)
- :"m" (*__const_sd(y)));
- return (unsigned short) result;
- case 4:
- __asm__ ("movl %%fs:%1,%0"
- :"=r" (result)
- :"m" (*__const_sd(y)));
- return result;
- default:
- return bad_user_access_length();
- }
-}
-
-static inline void __generic_memcpy_tofs(void * to, const void * from, unsigned long n)
-{
- __asm__ volatile
- (" cld
- push %%es
- movw %%fs,%%cx
- movw %%cx,%%es
- cmpl $3,%0
- jbe 1f
- movl %%edi,%%ecx
- negl %%ecx
- andl $3,%%ecx
- subl %%ecx,%0
- rep; movsb
- movl %0,%%ecx
- shrl $2,%%ecx
- rep; movsl
- andl $3,%0
- 1: movl %0,%%ecx
- rep; movsb
- pop %%es"
- :"=abd" (n)
- :"0" (n),"D" ((long) to),"S" ((long) from)
- :"cx","di","si");
-}
-
-static inline void __constant_memcpy_tofs(void * to, const void * from, unsigned long n)
-{
- switch (n) {
- case 0:
- return;
- case 1:
- __put_user(*(const char *) from, (char *) to, 1);
- return;
- case 2:
- __put_user(*(const short *) from, (short *) to, 2);
- return;
- case 3:
- __put_user(*(const short *) from, (short *) to, 2);
- __put_user(*(2+(const char *) from), 2+(char *) to, 1);
- return;
- case 4:
- __put_user(*(const int *) from, (int *) to, 4);
- return;
- case 8:
- __put_user(*(const int *) from, (int *) to, 4);
- __put_user(*(1+(const int *) from), 1+(int *) to, 4);
- return;
- case 12:
- __put_user(*(const int *) from, (int *) to, 4);
- __put_user(*(1+(const int *) from), 1+(int *) to, 4);
- __put_user(*(2+(const int *) from), 2+(int *) to, 4);
- return;
- case 16:
- __put_user(*(const int *) from, (int *) to, 4);
- __put_user(*(1+(const int *) from), 1+(int *) to, 4);
- __put_user(*(2+(const int *) from), 2+(int *) to, 4);
- __put_user(*(3+(const int *) from), 3+(int *) to, 4);
- return;
- }
-#define COMMON(x) \
-__asm__("cld\n\t" \
- "push %%es\n\t" \
- "push %%fs\n\t" \
- "pop %%es\n\t" \
- "rep ; movsl\n\t" \
- x \
- "pop %%es" \
- : /* no outputs */ \
- :"c" (n/4),"D" ((long) to),"S" ((long) from) \
- :"cx","di","si")
-
- switch (n % 4) {
- case 0:
- COMMON("");
- return;
- case 1:
- COMMON("movsb\n\t");
- return;
- case 2:
- COMMON("movsw\n\t");
- return;
- case 3:
- COMMON("movsw\n\tmovsb\n\t");
- return;
- }
-#undef COMMON
-}
-
-static inline void __generic_memcpy_fromfs(void * to, const void * from, unsigned long n)
-{
- __asm__ volatile
- (" cld
- cmpl $3,%0
- jbe 1f
- movl %%edi,%%ecx
- negl %%ecx
- andl $3,%%ecx
- subl %%ecx,%0
- fs; rep; movsb
- movl %0,%%ecx
- shrl $2,%%ecx
- fs; rep; movsl
- andl $3,%0
- 1: movl %0,%%ecx
- fs; rep; movsb"
- :"=abd" (n)
- :"0" (n),"D" ((long) to),"S" ((long) from)
- :"cx","di","si", "memory");
-}
-
-static inline void __constant_memcpy_fromfs(void * to, const void * from, unsigned long n)
-{
- switch (n) {
- case 0:
- return;
- case 1:
- *(char *)to = __get_user((const char *) from, 1);
- return;
- case 2:
- *(short *)to = __get_user((const short *) from, 2);
- return;
- case 3:
- *(short *) to = __get_user((const short *) from, 2);
- *((char *) to + 2) = __get_user(2+(const char *) from, 1);
- return;
- case 4:
- *(int *) to = __get_user((const int *) from, 4);
- return;
- case 8:
- *(int *) to = __get_user((const int *) from, 4);
- *(1+(int *) to) = __get_user(1+(const int *) from, 4);
- return;
- case 12:
- *(int *) to = __get_user((const int *) from, 4);
- *(1+(int *) to) = __get_user(1+(const int *) from, 4);
- *(2+(int *) to) = __get_user(2+(const int *) from, 4);
- return;
- case 16:
- *(int *) to = __get_user((const int *) from, 4);
- *(1+(int *) to) = __get_user(1+(const int *) from, 4);
- *(2+(int *) to) = __get_user(2+(const int *) from, 4);
- *(3+(int *) to) = __get_user(3+(const int *) from, 4);
- return;
- }
-#define COMMON(x) \
-__asm__("cld\n\t" \
- "rep ; fs ; movsl\n\t" \
- x \
- : /* no outputs */ \
- :"c" (n/4),"D" ((long) to),"S" ((long) from) \
- :"cx","di","si","memory")
-
- switch (n % 4) {
- case 0:
- COMMON("");
- return;
- case 1:
- COMMON("fs ; movsb");
- return;
- case 2:
- COMMON("fs ; movsw");
- return;
- case 3:
- COMMON("fs ; movsw\n\tfs ; movsb");
- return;
- }
-#undef COMMON
-}
-
-#define memcpy_fromfs(to, from, n) \
-(__builtin_constant_p(n) ? \
- __constant_memcpy_fromfs((to),(from),(n)) : \
- __generic_memcpy_fromfs((to),(from),(n)))
-
-#define memcpy_tofs(to, from, n) \
-(__builtin_constant_p(n) ? \
- __constant_memcpy_tofs((to),(from),(n)) : \
- __generic_memcpy_tofs((to),(from),(n)))
-
-/*
- * These are deprecated..
- *
- * Use "put_user()" and "get_user()" with the proper pointer types instead.
- */
-
-#define get_fs_byte(addr) __get_user((const unsigned char *)(addr),1)
-#define get_fs_word(addr) __get_user((const unsigned short *)(addr),2)
-#define get_fs_long(addr) __get_user((const unsigned int *)(addr),4)
-
-#define put_fs_byte(x,addr) __put_user((x),(unsigned char *)(addr),1)
-#define put_fs_word(x,addr) __put_user((x),(unsigned short *)(addr),2)
-#define put_fs_long(x,addr) __put_user((x),(unsigned int *)(addr),4)
-
-#ifdef WE_REALLY_WANT_TO_USE_A_BROKEN_INTERFACE
-
-static inline unsigned short get_user_word(const short *addr)
-{
- return __get_user(addr, 2);
-}
-
-static inline unsigned char get_user_byte(const char * addr)
-{
- return __get_user(addr,1);
-}
-
-static inline unsigned long get_user_long(const int *addr)
-{
- return __get_user(addr, 4);
-}
-
-static inline void put_user_byte(char val,char *addr)
-{
- __put_user(val, addr, 1);
-}
-
-static inline void put_user_word(short val,short * addr)
-{
- __put_user(val, addr, 2);
-}
-
-static inline void put_user_long(unsigned long val,int * addr)
-{
- __put_user(val, addr, 4);
-}
-
-#endif
-
-/*
- * Someone who knows GNU asm better than I should double check the following.
- * It seems to work, but I don't know if I'm doing something subtly wrong.
- * --- TYT, 11/24/91
- * [ nothing wrong here, Linus: I just changed the ax to be any reg ]
- */
-
-static inline unsigned long get_fs(void)
-{
- unsigned long _v;
- __asm__("mov %%fs,%w0":"=r" (_v):"0" (0));
- return _v;
-}
-
-static inline unsigned long get_ds(void)
-{
- unsigned long _v;
- __asm__("mov %%ds,%w0":"=r" (_v):"0" (0));
- return _v;
-}
-
-static inline void set_fs(unsigned long val)
-{
- __asm__ __volatile__("mov %w0,%%fs": /* no output */ :"r" (val));
-}
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* _ASM_SEGMENT_H */
diff --git a/i386/i386at/gpl/linux/include/asm/sigcontext.h b/i386/i386at/gpl/linux/include/asm/sigcontext.h
deleted file mode 100644
index 5b84694f..00000000
--- a/i386/i386at/gpl/linux/include/asm/sigcontext.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef _ASMi386_SIGCONTEXT_H
-#define _ASMi386_SIGCONTEXT_H
-
-struct sigcontext_struct {
- unsigned short gs, __gsh;
- unsigned short fs, __fsh;
- unsigned short es, __esh;
- unsigned short ds, __dsh;
- unsigned long edi;
- unsigned long esi;
- unsigned long ebp;
- unsigned long esp;
- unsigned long ebx;
- unsigned long edx;
- unsigned long ecx;
- unsigned long eax;
- unsigned long trapno;
- unsigned long err;
- unsigned long eip;
- unsigned short cs, __csh;
- unsigned long eflags;
- unsigned long esp_at_signal;
- unsigned short ss, __ssh;
- unsigned long i387;
- unsigned long oldmask;
- unsigned long cr2;
-};
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/asm/signal.h b/i386/i386at/gpl/linux/include/asm/signal.h
deleted file mode 100644
index b37613fe..00000000
--- a/i386/i386at/gpl/linux/include/asm/signal.h
+++ /dev/null
@@ -1,95 +0,0 @@
-#ifndef _ASMi386_SIGNAL_H
-#define _ASMi386_SIGNAL_H
-
-typedef unsigned long sigset_t; /* at least 32 bits */
-
-#define _NSIG 32
-#define NSIG _NSIG
-
-#define SIGHUP 1
-#define SIGINT 2
-#define SIGQUIT 3
-#define SIGILL 4
-#define SIGTRAP 5
-#define SIGABRT 6
-#define SIGIOT 6
-#define SIGBUS 7
-#define SIGFPE 8
-#define SIGKILL 9
-#define SIGUSR1 10
-#define SIGSEGV 11
-#define SIGUSR2 12
-#define SIGPIPE 13
-#define SIGALRM 14
-#define SIGTERM 15
-#define SIGSTKFLT 16
-#define SIGCHLD 17
-#define SIGCONT 18
-#define SIGSTOP 19
-#define SIGTSTP 20
-#define SIGTTIN 21
-#define SIGTTOU 22
-#define SIGURG 23
-#define SIGXCPU 24
-#define SIGXFSZ 25
-#define SIGVTALRM 26
-#define SIGPROF 27
-#define SIGWINCH 28
-#define SIGIO 29
-#define SIGPOLL SIGIO
-/*
-#define SIGLOST 29
-*/
-#define SIGPWR 30
-#define SIGUNUSED 31
-
-/*
- * sa_flags values: SA_STACK is not currently supported, but will allow the
- * usage of signal stacks by using the (now obsolete) sa_restorer field in
- * the sigaction structure as a stack pointer. This is now possible due to
- * the changes in signal handling. LBT 010493.
- * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
- * SA_RESTART flag to get restarting signals (which were the default long ago)
- */
-#define SA_NOCLDSTOP 1
-#define SA_STACK 0x08000000
-#define SA_RESTART 0x10000000
-#define SA_INTERRUPT 0x20000000
-#define SA_NOMASK 0x40000000
-#define SA_ONESHOT 0x80000000
-
-#ifdef __KERNEL__
-/*
- * These values of sa_flags are used only by the kernel as part of the
- * irq handling routines.
- *
- * SA_INTERRUPT is also used by the irq handling routines.
- */
-#define SA_PROBE SA_ONESHOT
-#define SA_SAMPLE_RANDOM SA_RESTART
-#endif
-
-
-#define SIG_BLOCK 0 /* for blocking signals */
-#define SIG_UNBLOCK 1 /* for unblocking signals */
-#define SIG_SETMASK 2 /* for setting the signal mask */
-
-/* Type of a signal handler. */
-typedef void (*__sighandler_t)(int);
-
-#define SIG_DFL ((__sighandler_t)0) /* default signal handling */
-#define SIG_IGN ((__sighandler_t)1) /* ignore signal */
-#define SIG_ERR ((__sighandler_t)-1) /* error return from signal */
-
-struct sigaction {
- __sighandler_t sa_handler;
- sigset_t sa_mask;
- unsigned long sa_flags;
- void (*sa_restorer)(void);
-};
-
-#ifdef __KERNEL__
-#include <asm/sigcontext.h>
-#endif
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/asm/socket.h b/i386/i386at/gpl/linux/include/asm/socket.h
deleted file mode 100644
index dc923006..00000000
--- a/i386/i386at/gpl/linux/include/asm/socket.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef _ASM_SOCKET_H
-#define _ASM_SOCKET_H
-
-/* Socket-level I/O control calls. */
-#define FIOSETOWN 0x8901
-#define SIOCSPGRP 0x8902
-#define FIOGETOWN 0x8903
-#define SIOCGPGRP 0x8904
-#define SIOCATMARK 0x8905
-#define SIOCGSTAMP 0x8906 /* Get stamp */
-
-/* For setsockoptions(2) */
-#define SOL_SOCKET 1
-
-#define SO_DEBUG 1
-#define SO_REUSEADDR 2
-#define SO_TYPE 3
-#define SO_ERROR 4
-#define SO_DONTROUTE 5
-#define SO_BROADCAST 6
-#define SO_SNDBUF 7
-#define SO_RCVBUF 8
-#define SO_KEEPALIVE 9
-#define SO_OOBINLINE 10
-#define SO_NO_CHECK 11
-#define SO_PRIORITY 12
-#define SO_LINGER 13
-#define SO_BSDCOMPAT 14
-/* To add :#define SO_REUSEPORT 15 */
-
-#endif /* _ASM_SOCKET_H */
diff --git a/i386/i386at/gpl/linux/include/asm/stat.h b/i386/i386at/gpl/linux/include/asm/stat.h
deleted file mode 100644
index b4c64869..00000000
--- a/i386/i386at/gpl/linux/include/asm/stat.h
+++ /dev/null
@@ -1,41 +0,0 @@
-#ifndef _I386_STAT_H
-#define _I386_STAT_H
-
-struct old_stat {
- unsigned short st_dev;
- unsigned short st_ino;
- unsigned short st_mode;
- unsigned short st_nlink;
- unsigned short st_uid;
- unsigned short st_gid;
- unsigned short st_rdev;
- unsigned long st_size;
- unsigned long st_atime;
- unsigned long st_mtime;
- unsigned long st_ctime;
-};
-
-struct new_stat {
- unsigned short st_dev;
- unsigned short __pad1;
- unsigned long st_ino;
- unsigned short st_mode;
- unsigned short st_nlink;
- unsigned short st_uid;
- unsigned short st_gid;
- unsigned short st_rdev;
- unsigned short __pad2;
- unsigned long st_size;
- unsigned long st_blksize;
- unsigned long st_blocks;
- unsigned long st_atime;
- unsigned long __unused1;
- unsigned long st_mtime;
- unsigned long __unused2;
- unsigned long st_ctime;
- unsigned long __unused3;
- unsigned long __unused4;
- unsigned long __unused5;
-};
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/asm/statfs.h b/i386/i386at/gpl/linux/include/asm/statfs.h
deleted file mode 100644
index 6efb7411..00000000
--- a/i386/i386at/gpl/linux/include/asm/statfs.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef _I386_STATFS_H
-#define _I386_STATFS_H
-
-typedef struct {
- long val[2];
-} fsid_t;
-
-struct statfs {
- long f_type;
- long f_bsize;
- long f_blocks;
- long f_bfree;
- long f_bavail;
- long f_files;
- long f_ffree;
- fsid_t f_fsid;
- long f_namelen;
- long f_spare[6];
-};
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/asm/string.h b/i386/i386at/gpl/linux/include/asm/string.h
deleted file mode 100644
index d93a2a77..00000000
--- a/i386/i386at/gpl/linux/include/asm/string.h
+++ /dev/null
@@ -1,593 +0,0 @@
-#ifndef _I386_STRING_H_
-#define _I386_STRING_H_
-
-/*
- * This string-include defines all string functions as inline
- * functions. Use gcc. It also assumes ds=es=data space, this should be
- * normal. Most of the string-functions are rather heavily hand-optimized,
- * see especially strtok,strstr,str[c]spn. They should work, but are not
- * very easy to understand. Everything is done entirely within the register
- * set, making the functions fast and clean. String instructions have been
- * used through-out, making for "slightly" unclear code :-)
- *
- * Copyright (C) 1991, 1992 Linus Torvalds
- */
-
-#define __HAVE_ARCH_STRCPY
-extern inline char * strcpy(char * dest,const char *src)
-{
-__asm__ __volatile__(
- "cld\n"
- "1:\tlodsb\n\t"
- "stosb\n\t"
- "testb %%al,%%al\n\t"
- "jne 1b"
- : /* no output */
- :"S" (src),"D" (dest):"si","di","ax","memory");
-return dest;
-}
-
-#define __HAVE_ARCH_STRNCPY
-extern inline char * strncpy(char * dest,const char *src,size_t count)
-{
-__asm__ __volatile__(
- "cld\n"
- "1:\tdecl %2\n\t"
- "js 2f\n\t"
- "lodsb\n\t"
- "stosb\n\t"
- "testb %%al,%%al\n\t"
- "jne 1b\n\t"
- "rep\n\t"
- "stosb\n"
- "2:"
- : /* no output */
- :"S" (src),"D" (dest),"c" (count):"si","di","ax","cx","memory");
-return dest;
-}
-
-#define __HAVE_ARCH_STRCAT
-extern inline char * strcat(char * dest,const char * src)
-{
-__asm__ __volatile__(
- "cld\n\t"
- "repne\n\t"
- "scasb\n\t"
- "decl %1\n"
- "1:\tlodsb\n\t"
- "stosb\n\t"
- "testb %%al,%%al\n\t"
- "jne 1b"
- : /* no output */
- :"S" (src),"D" (dest),"a" (0),"c" (0xffffffff):"si","di","ax","cx");
-return dest;
-}
-
-#define __HAVE_ARCH_STRNCAT
-extern inline char * strncat(char * dest,const char * src,size_t count)
-{
-__asm__ __volatile__(
- "cld\n\t"
- "repne\n\t"
- "scasb\n\t"
- "decl %1\n\t"
- "movl %4,%3\n"
- "1:\tdecl %3\n\t"
- "js 2f\n\t"
- "lodsb\n\t"
- "stosb\n\t"
- "testb %%al,%%al\n\t"
- "jne 1b\n"
- "2:\txorl %2,%2\n\t"
- "stosb"
- : /* no output */
- :"S" (src),"D" (dest),"a" (0),"c" (0xffffffff),"g" (count)
- :"si","di","ax","cx","memory");
-return dest;
-}
-
-#define __HAVE_ARCH_STRCMP
-extern inline int strcmp(const char * cs,const char * ct)
-{
-register int __res;
-__asm__ __volatile__(
- "cld\n"
- "1:\tlodsb\n\t"
- "scasb\n\t"
- "jne 2f\n\t"
- "testb %%al,%%al\n\t"
- "jne 1b\n\t"
- "xorl %%eax,%%eax\n\t"
- "jmp 3f\n"
- "2:\tsbbl %%eax,%%eax\n\t"
- "orb $1,%%eax\n"
- "3:"
- :"=a" (__res):"S" (cs),"D" (ct):"si","di");
-return __res;
-}
-
-#define __HAVE_ARCH_STRNCMP
-extern inline int strncmp(const char * cs,const char * ct,size_t count)
-{
-register int __res;
-__asm__ __volatile__(
- "cld\n"
- "1:\tdecl %3\n\t"
- "js 2f\n\t"
- "lodsb\n\t"
- "scasb\n\t"
- "jne 3f\n\t"
- "testb %%al,%%al\n\t"
- "jne 1b\n"
- "2:\txorl %%eax,%%eax\n\t"
- "jmp 4f\n"
- "3:\tsbbl %%eax,%%eax\n\t"
- "orb $1,%%al\n"
- "4:"
- :"=a" (__res):"S" (cs),"D" (ct),"c" (count):"si","di","cx");
-return __res;
-}
-
-#define __HAVE_ARCH_STRCHR
-extern inline char * strchr(const char * s, int c)
-{
-register char * __res;
-__asm__ __volatile__(
- "cld\n\t"
- "movb %%al,%%ah\n"
- "1:\tlodsb\n\t"
- "cmpb %%ah,%%al\n\t"
- "je 2f\n\t"
- "testb %%al,%%al\n\t"
- "jne 1b\n\t"
- "movl $1,%1\n"
- "2:\tmovl %1,%0\n\t"
- "decl %0"
- :"=a" (__res):"S" (s),"0" (c):"si");
-return __res;
-}
-
-#define __HAVE_ARCH_STRRCHR
-extern inline char * strrchr(const char * s, int c)
-{
-register char * __res;
-__asm__ __volatile__(
- "cld\n\t"
- "movb %%al,%%ah\n"
- "1:\tlodsb\n\t"
- "cmpb %%ah,%%al\n\t"
- "jne 2f\n\t"
- "leal -1(%%esi),%0\n"
- "2:\ttestb %%al,%%al\n\t"
- "jne 1b"
- :"=d" (__res):"0" (0),"S" (s),"a" (c):"ax","si");
-return __res;
-}
-
-#define __HAVE_ARCH_STRSPN
-extern inline size_t strspn(const char * cs, const char * ct)
-{
-register char * __res;
-__asm__ __volatile__(
- "cld\n\t"
- "movl %4,%%edi\n\t"
- "repne\n\t"
- "scasb\n\t"
- "notl %%ecx\n\t"
- "decl %%ecx\n\t"
- "movl %%ecx,%%edx\n"
- "1:\tlodsb\n\t"
- "testb %%al,%%al\n\t"
- "je 2f\n\t"
- "movl %4,%%edi\n\t"
- "movl %%edx,%%ecx\n\t"
- "repne\n\t"
- "scasb\n\t"
- "je 1b\n"
- "2:\tdecl %0"
- :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
- :"ax","cx","dx","di");
-return __res-cs;
-}
-
-#define __HAVE_ARCH_STRCSPN
-extern inline size_t strcspn(const char * cs, const char * ct)
-{
-register char * __res;
-__asm__ __volatile__(
- "cld\n\t"
- "movl %4,%%edi\n\t"
- "repne\n\t"
- "scasb\n\t"
- "notl %%ecx\n\t"
- "decl %%ecx\n\t"
- "movl %%ecx,%%edx\n"
- "1:\tlodsb\n\t"
- "testb %%al,%%al\n\t"
- "je 2f\n\t"
- "movl %4,%%edi\n\t"
- "movl %%edx,%%ecx\n\t"
- "repne\n\t"
- "scasb\n\t"
- "jne 1b\n"
- "2:\tdecl %0"
- :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
- :"ax","cx","dx","di");
-return __res-cs;
-}
-
-#define __HAVE_ARCH_STRPBRK
-extern inline char * strpbrk(const char * cs,const char * ct)
-{
-register char * __res;
-__asm__ __volatile__(
- "cld\n\t"
- "movl %4,%%edi\n\t"
- "repne\n\t"
- "scasb\n\t"
- "notl %%ecx\n\t"
- "decl %%ecx\n\t"
- "movl %%ecx,%%edx\n"
- "1:\tlodsb\n\t"
- "testb %%al,%%al\n\t"
- "je 2f\n\t"
- "movl %4,%%edi\n\t"
- "movl %%edx,%%ecx\n\t"
- "repne\n\t"
- "scasb\n\t"
- "jne 1b\n\t"
- "decl %0\n\t"
- "jmp 3f\n"
- "2:\txorl %0,%0\n"
- "3:"
- :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
- :"ax","cx","dx","di");
-return __res;
-}
-
-#define __HAVE_ARCH_STRSTR
-extern inline char * strstr(const char * cs,const char * ct)
-{
-register char * __res;
-__asm__ __volatile__(
- "cld\n\t" \
- "movl %4,%%edi\n\t"
- "repne\n\t"
- "scasb\n\t"
- "notl %%ecx\n\t"
- "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
- "movl %%ecx,%%edx\n"
- "1:\tmovl %4,%%edi\n\t"
- "movl %%esi,%%eax\n\t"
- "movl %%edx,%%ecx\n\t"
- "repe\n\t"
- "cmpsb\n\t"
- "je 2f\n\t" /* also works for empty string, see above */
- "xchgl %%eax,%%esi\n\t"
- "incl %%esi\n\t"
- "cmpb $0,-1(%%eax)\n\t"
- "jne 1b\n\t"
- "xorl %%eax,%%eax\n\t"
- "2:"
- :"=a" (__res):"0" (0),"c" (0xffffffff),"S" (cs),"g" (ct)
- :"cx","dx","di","si");
-return __res;
-}
-
-#define __HAVE_ARCH_STRLEN
-extern inline size_t strlen(const char * s)
-{
-register int __res;
-__asm__ __volatile__(
- "cld\n\t"
- "repne\n\t"
- "scasb\n\t"
- "notl %0\n\t"
- "decl %0"
- :"=c" (__res):"D" (s),"a" (0),"0" (0xffffffff):"di");
-return __res;
-}
-
-#define __HAVE_ARCH_STRTOK
-extern inline char * strtok(char * s,const char * ct)
-{
-register char * __res;
-__asm__ __volatile__(
- "testl %1,%1\n\t"
- "jne 1f\n\t"
- "testl %0,%0\n\t"
- "je 8f\n\t"
- "movl %0,%1\n"
- "1:\txorl %0,%0\n\t"
- "movl $-1,%%ecx\n\t"
- "xorl %%eax,%%eax\n\t"
- "cld\n\t"
- "movl %4,%%edi\n\t"
- "repne\n\t"
- "scasb\n\t"
- "notl %%ecx\n\t"
- "decl %%ecx\n\t"
- "je 7f\n\t" /* empty delimiter-string */
- "movl %%ecx,%%edx\n"
- "2:\tlodsb\n\t"
- "testb %%al,%%al\n\t"
- "je 7f\n\t"
- "movl %4,%%edi\n\t"
- "movl %%edx,%%ecx\n\t"
- "repne\n\t"
- "scasb\n\t"
- "je 2b\n\t"
- "decl %1\n\t"
- "cmpb $0,(%1)\n\t"
- "je 7f\n\t"
- "movl %1,%0\n"
- "3:\tlodsb\n\t"
- "testb %%al,%%al\n\t"
- "je 5f\n\t"
- "movl %4,%%edi\n\t"
- "movl %%edx,%%ecx\n\t"
- "repne\n\t"
- "scasb\n\t"
- "jne 3b\n\t"
- "decl %1\n\t"
- "cmpb $0,(%1)\n\t"
- "je 5f\n\t"
- "movb $0,(%1)\n\t"
- "incl %1\n\t"
- "jmp 6f\n"
- "5:\txorl %1,%1\n"
- "6:\tcmpb $0,(%0)\n\t"
- "jne 7f\n\t"
- "xorl %0,%0\n"
- "7:\ttestl %0,%0\n\t"
- "jne 8f\n\t"
- "movl %0,%1\n"
- "8:"
- :"=b" (__res),"=S" (___strtok)
- :"0" (___strtok),"1" (s),"g" (ct)
- :"ax","cx","dx","di","memory");
-return __res;
-}
-
-extern inline void * __memcpy(void * to, const void * from, size_t n)
-{
-__asm__ __volatile__(
- "cld\n\t"
- "rep ; movsl\n\t"
- "testb $2,%b1\n\t"
- "je 1f\n\t"
- "movsw\n"
- "1:\ttestb $1,%b1\n\t"
- "je 2f\n\t"
- "movsb\n"
- "2:"
- : /* no output */
- :"c" (n/4), "q" (n),"D" ((long) to),"S" ((long) from)
- : "cx","di","si","memory");
-return (to);
-}
-
-/*
- * This looks horribly ugly, but the compiler can optimize it totally,
- * as the count is constant.
- */
-extern inline void * __constant_memcpy(void * to, const void * from, size_t n)
-{
- switch (n) {
- case 0:
- return to;
- case 1:
- *(unsigned char *)to = *(const unsigned char *)from;
- return to;
- case 2:
- *(unsigned short *)to = *(const unsigned short *)from;
- return to;
- case 3:
- *(unsigned short *)to = *(const unsigned short *)from;
- *(2+(unsigned char *)to) = *(2+(const unsigned char *)from);
- return to;
- case 4:
- *(unsigned long *)to = *(const unsigned long *)from;
- return to;
- }
-#define COMMON(x) \
-__asm__("cld\n\t" \
- "rep ; movsl" \
- x \
- : /* no outputs */ \
- : "c" (n/4),"D" ((long) to),"S" ((long) from) \
- : "cx","di","si","memory");
-
- switch (n % 4) {
- case 0: COMMON(""); return to;
- case 1: COMMON("\n\tmovsb"); return to;
- case 2: COMMON("\n\tmovsw"); return to;
- case 3: COMMON("\n\tmovsw\n\tmovsb"); return to;
- }
-#undef COMMON
-}
-
-#define __HAVE_ARCH_MEMCPY
-#define memcpy(t, f, n) \
-(__builtin_constant_p(n) ? \
- __constant_memcpy((t),(f),(n)) : \
- __memcpy((t),(f),(n)))
-
-#define __HAVE_ARCH_MEMMOVE
-extern inline void * memmove(void * dest,const void * src, size_t n)
-{
-if (dest<src)
-__asm__ __volatile__(
- "cld\n\t"
- "rep\n\t"
- "movsb"
- : /* no output */
- :"c" (n),"S" (src),"D" (dest)
- :"cx","si","di");
-else
-__asm__ __volatile__(
- "std\n\t"
- "rep\n\t"
- "movsb\n\t"
- "cld"
- : /* no output */
- :"c" (n),
- "S" (n-1+(const char *)src),
- "D" (n-1+(char *)dest)
- :"cx","si","di","memory");
-return dest;
-}
-
-#define memcmp __builtin_memcmp
-
-#define __HAVE_ARCH_MEMCHR
-extern inline void * memchr(const void * cs,int c,size_t count)
-{
-register void * __res;
-if (!count)
- return NULL;
-__asm__ __volatile__(
- "cld\n\t"
- "repne\n\t"
- "scasb\n\t"
- "je 1f\n\t"
- "movl $1,%0\n"
- "1:\tdecl %0"
- :"=D" (__res):"a" (c),"D" (cs),"c" (count)
- :"cx");
-return __res;
-}
-
-extern inline void * __memset_generic(void * s, char c,size_t count)
-{
-__asm__ __volatile__(
- "cld\n\t"
- "rep\n\t"
- "stosb"
- : /* no output */
- :"a" (c),"D" (s),"c" (count)
- :"cx","di","memory");
-return s;
-}
-
-/* we might want to write optimized versions of these later */
-#define __constant_count_memset(s,c,count) __memset_generic((s),(c),(count))
-
-/*
- * memset(x,0,y) is a reasonably common thing to do, so we want to fill
- * things 32 bits at a time even when we don't know the size of the
- * area at compile-time..
- */
-extern inline void * __constant_c_memset(void * s, unsigned long c, size_t count)
-{
-__asm__ __volatile__(
- "cld\n\t"
- "rep ; stosl\n\t"
- "testb $2,%b1\n\t"
- "je 1f\n\t"
- "stosw\n"
- "1:\ttestb $1,%b1\n\t"
- "je 2f\n\t"
- "stosb\n"
- "2:"
- : /* no output */
- :"a" (c), "q" (count), "c" (count/4), "D" ((long) s)
- :"cx","di","memory");
-return (s);
-}
-
-/* Added by Gertjan van Wingerde to make minix and sysv module work */
-#define __HAVE_ARCH_STRNLEN
-extern inline size_t strnlen(const char * s, size_t count)
-{
-register int __res;
-__asm__ __volatile__(
- "movl %1,%0\n\t"
- "jmp 2f\n"
- "1:\tcmpb $0,(%0)\n\t"
- "je 3f\n\t"
- "incl %0\n"
- "2:\tdecl %2\n\t"
- "cmpl $-1,%2\n\t"
- "jne 1b\n"
- "3:\tsubl %1,%0"
- :"=a" (__res):"c" (s),"d" (count));
-return __res;
-}
-/* end of additional stuff */
-
-/*
- * This looks horribly ugly, but the compiler can optimize it totally,
- * as we by now know that both pattern and count is constant..
- */
-extern inline void * __constant_c_and_count_memset(void * s, unsigned long pattern, size_t count)
-{
- switch (count) {
- case 0:
- return s;
- case 1:
- *(unsigned char *)s = pattern;
- return s;
- case 2:
- *(unsigned short *)s = pattern;
- return s;
- case 3:
- *(unsigned short *)s = pattern;
- *(2+(unsigned char *)s) = pattern;
- return s;
- case 4:
- *(unsigned long *)s = pattern;
- return s;
- }
-#define COMMON(x) \
-__asm__("cld\n\t" \
- "rep ; stosl" \
- x \
- : /* no outputs */ \
- : "a" (pattern),"c" (count/4),"D" ((long) s) \
- : "cx","di","memory")
-
- switch (count % 4) {
- case 0: COMMON(""); return s;
- case 1: COMMON("\n\tstosb"); return s;
- case 2: COMMON("\n\tstosw"); return s;
- case 3: COMMON("\n\tstosw\n\tstosb"); return s;
- }
-#undef COMMON
-}
-
-#define __constant_c_x_memset(s, c, count) \
-(__builtin_constant_p(count) ? \
- __constant_c_and_count_memset((s),(c),(count)) : \
- __constant_c_memset((s),(c),(count)))
-
-#define __memset(s, c, count) \
-(__builtin_constant_p(count) ? \
- __constant_count_memset((s),(c),(count)) : \
- __memset_generic((s),(c),(count)))
-
-#define __HAVE_ARCH_MEMSET
-#define memset(s, c, count) \
-(__builtin_constant_p(c) ? \
- __constant_c_x_memset((s),(0x01010101UL*(unsigned char)c),(count)) : \
- __memset((s),(c),(count)))
-
-/*
- * find the first occurrence of byte 'c', or 1 past the area if none
- */
-#define __HAVE_ARCH_MEMSCAN
-extern inline void * memscan(void * addr, int c, size_t size)
-{
- if (!size)
- return addr;
- __asm__("cld
- repnz; scasb
- jnz 1f
- dec %%edi
-1: "
- : "=D" (addr), "=c" (size)
- : "0" (addr), "1" (size), "a" (c));
- return addr;
-}
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/asm/system.h b/i386/i386at/gpl/linux/include/asm/system.h
deleted file mode 100644
index 9c6f862a..00000000
--- a/i386/i386at/gpl/linux/include/asm/system.h
+++ /dev/null
@@ -1,301 +0,0 @@
-#ifndef __ASM_SYSTEM_H
-#define __ASM_SYSTEM_H
-
-#include <asm/segment.h>
-
-/*
- * Entry into gdt where to find first TSS. GDT layout:
- * 0 - nul
- * 1 - kernel code segment
- * 2 - kernel data segment
- * 3 - user code segment
- * 4 - user data segment
- * ...
- * 8 - TSS #0
- * 9 - LDT #0
- * 10 - TSS #1
- * 11 - LDT #1
- */
-#define FIRST_TSS_ENTRY 8
-#define FIRST_LDT_ENTRY (FIRST_TSS_ENTRY+1)
-#define _TSS(n) ((((unsigned long) n)<<4)+(FIRST_TSS_ENTRY<<3))
-#define _LDT(n) ((((unsigned long) n)<<4)+(FIRST_LDT_ENTRY<<3))
-#define load_TR(n) __asm__("ltr %%ax": /* no output */ :"a" (_TSS(n)))
-#define load_ldt(n) __asm__("lldt %%ax": /* no output */ :"a" (_LDT(n)))
-#define store_TR(n) \
-__asm__("str %%ax\n\t" \
- "subl %2,%%eax\n\t" \
- "shrl $4,%%eax" \
- :"=a" (n) \
- :"0" (0),"i" (FIRST_TSS_ENTRY<<3))
-
-/* This special macro can be used to load a debugging register */
-
-#define loaddebug(register) \
- __asm__("movl %0,%%edx\n\t" \
- "movl %%edx,%%db" #register "\n\t" \
- : /* no output */ \
- :"m" (current->debugreg[register]) \
- :"dx");
-
-
-/*
- * switch_to(n) should switch tasks to task nr n, first
- * checking that n isn't the current task, in which case it does nothing.
- * This also clears the TS-flag if the task we switched to has used
- * the math co-processor latest.
- *
- * It also reloads the debug regs if necessary..
- */
-
-
-#ifdef __SMP__
- /*
- * Keep the lock depth straight. If we switch on an interrupt from
- * kernel->user task we need to lose a depth, and if we switch the
- * other way we need to gain a depth. Same layer switches come out
- * the same.
- *
- * We spot a switch in user mode because the kernel counter is the
- * same as the interrupt counter depth. (We never switch during the
- * message/invalidate IPI).
- *
- * We fsave/fwait so that an exception goes off at the right time
- * (as a call from the fsave or fwait in effect) rather than to
- * the wrong process.
- */
-
-#define switch_to(tsk) do { \
- cli();\
- if(current->flags&PF_USEDFPU) \
- { \
- __asm__ __volatile__("fnsave %0":"=m" (current->tss.i387.hard)); \
- __asm__ __volatile__("fwait"); \
- current->flags&=~PF_USEDFPU; \
- } \
- current->lock_depth=syscall_count; \
- kernel_counter+=next->lock_depth-current->lock_depth; \
- syscall_count=next->lock_depth; \
-__asm__("pushl %%edx\n\t" \
- "movl "SYMBOL_NAME_STR(apic_reg)",%%edx\n\t" \
- "movl 0x20(%%edx), %%edx\n\t" \
- "shrl $22,%%edx\n\t" \
- "and $0x3C,%%edx\n\t" \
- "xchgl %%ecx,"SYMBOL_NAME_STR(current_set)"(,%%edx)\n\t" \
- "popl %%edx\n\t" \
- "ljmp %0\n\t" \
- "sti\n\t" \
- : /* no output */ \
- :"m" (*(((char *)&tsk->tss.tr)-4)), \
- "c" (tsk) \
- :"cx"); \
- /* Now maybe reload the debug registers */ \
- if(current->debugreg[7]){ \
- loaddebug(0); \
- loaddebug(1); \
- loaddebug(2); \
- loaddebug(3); \
- loaddebug(6); \
- } \
-} while (0)
-
-#else
-#define switch_to(tsk) do { \
-__asm__("cli\n\t" \
- "xchgl %%ecx,"SYMBOL_NAME_STR(current_set)"\n\t" \
- "ljmp %0\n\t" \
- "sti\n\t" \
- "cmpl %%ecx,"SYMBOL_NAME_STR(last_task_used_math)"\n\t" \
- "jne 1f\n\t" \
- "clts\n" \
- "1:" \
- : /* no output */ \
- :"m" (*(((char *)&tsk->tss.tr)-4)), \
- "c" (tsk) \
- :"cx"); \
- /* Now maybe reload the debug registers */ \
- if(current->debugreg[7]){ \
- loaddebug(0); \
- loaddebug(1); \
- loaddebug(2); \
- loaddebug(3); \
- loaddebug(6); \
- } \
-} while (0)
-#endif
-
-#define _set_base(addr,base) \
-__asm__("movw %%dx,%0\n\t" \
- "rorl $16,%%edx\n\t" \
- "movb %%dl,%1\n\t" \
- "movb %%dh,%2" \
- : /* no output */ \
- :"m" (*((addr)+2)), \
- "m" (*((addr)+4)), \
- "m" (*((addr)+7)), \
- "d" (base) \
- :"dx")
-
-#define _set_limit(addr,limit) \
-__asm__("movw %%dx,%0\n\t" \
- "rorl $16,%%edx\n\t" \
- "movb %1,%%dh\n\t" \
- "andb $0xf0,%%dh\n\t" \
- "orb %%dh,%%dl\n\t" \
- "movb %%dl,%1" \
- : /* no output */ \
- :"m" (*(addr)), \
- "m" (*((addr)+6)), \
- "d" (limit) \
- :"dx")
-
-#define set_base(ldt,base) _set_base( ((char *)&(ldt)) , base )
-#define set_limit(ldt,limit) _set_limit( ((char *)&(ldt)) , (limit-1)>>12 )
-
-static inline unsigned long _get_base(char * addr)
-{
- unsigned long __base;
- __asm__("movb %3,%%dh\n\t"
- "movb %2,%%dl\n\t"
- "shll $16,%%edx\n\t"
- "movw %1,%%dx"
- :"=&d" (__base)
- :"m" (*((addr)+2)),
- "m" (*((addr)+4)),
- "m" (*((addr)+7)));
- return __base;
-}
-
-#define get_base(ldt) _get_base( ((char *)&(ldt)) )
-
-static inline unsigned long get_limit(unsigned long segment)
-{
- unsigned long __limit;
- __asm__("lsll %1,%0"
- :"=r" (__limit):"r" (segment));
- return __limit+1;
-}
-
-#define nop() __asm__ __volatile__ ("nop")
-
-/*
- * Clear and set 'TS' bit respectively
- */
-#define clts() __asm__ __volatile__ ("clts")
-#define stts() \
-__asm__ __volatile__ ( \
- "movl %%cr0,%%eax\n\t" \
- "orl $8,%%eax\n\t" \
- "movl %%eax,%%cr0" \
- : /* no outputs */ \
- : /* no inputs */ \
- :"ax")
-
-
-#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
-#define tas(ptr) (xchg((ptr),1))
-
-struct __xchg_dummy { unsigned long a[100]; };
-#define __xg(x) ((volatile struct __xchg_dummy *)(x))
-
-static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
-{
- switch (size) {
- case 1:
- __asm__("xchgb %b0,%1"
- :"=q" (x), "=m" (*__xg(ptr))
- :"0" (x), "m" (*__xg(ptr)));
- break;
- case 2:
- __asm__("xchgw %w0,%1"
- :"=r" (x), "=m" (*__xg(ptr))
- :"0" (x), "m" (*__xg(ptr)));
- break;
- case 4:
- __asm__("xchgl %0,%1"
- :"=r" (x), "=m" (*__xg(ptr))
- :"0" (x), "m" (*__xg(ptr)));
- break;
- }
- return x;
-}
-
-#define mb() __asm__ __volatile__ ("" : : :"memory")
-#define sti() __asm__ __volatile__ ("sti": : :"memory")
-#define cli() __asm__ __volatile__ ("cli": : :"memory")
-
-#define save_flags(x) \
-__asm__ __volatile__("pushfl ; popl %0":"=r" (x): /* no input */ :"memory")
-
-#define restore_flags(x) \
-__asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"r" (x):"memory")
-
-#define iret() __asm__ __volatile__ ("iret": : :"memory")
-
-#define _set_gate(gate_addr,type,dpl,addr) \
-__asm__ __volatile__ ("movw %%dx,%%ax\n\t" \
- "movw %2,%%dx\n\t" \
- "movl %%eax,%0\n\t" \
- "movl %%edx,%1" \
- :"=m" (*((long *) (gate_addr))), \
- "=m" (*(1+(long *) (gate_addr))) \
- :"i" ((short) (0x8000+(dpl<<13)+(type<<8))), \
- "d" ((char *) (addr)),"a" (KERNEL_CS << 16) \
- :"ax","dx")
-
-#define set_intr_gate(n,addr) \
- _set_gate(&idt[n],14,0,addr)
-
-#define set_trap_gate(n,addr) \
- _set_gate(&idt[n],15,0,addr)
-
-#define set_system_gate(n,addr) \
- _set_gate(&idt[n],15,3,addr)
-
-#define set_call_gate(a,addr) \
- _set_gate(a,12,3,addr)
-
-#define _set_seg_desc(gate_addr,type,dpl,base,limit) {\
- *((gate_addr)+1) = ((base) & 0xff000000) | \
- (((base) & 0x00ff0000)>>16) | \
- ((limit) & 0xf0000) | \
- ((dpl)<<13) | \
- (0x00408000) | \
- ((type)<<8); \
- *(gate_addr) = (((base) & 0x0000ffff)<<16) | \
- ((limit) & 0x0ffff); }
-
-#define _set_tssldt_desc(n,addr,limit,type) \
-__asm__ __volatile__ ("movw $" #limit ",%1\n\t" \
- "movw %%ax,%2\n\t" \
- "rorl $16,%%eax\n\t" \
- "movb %%al,%3\n\t" \
- "movb $" type ",%4\n\t" \
- "movb $0x00,%5\n\t" \
- "movb %%ah,%6\n\t" \
- "rorl $16,%%eax" \
- : /* no output */ \
- :"a" (addr+0xc0000000), "m" (*(n)), "m" (*(n+2)), "m" (*(n+4)), \
- "m" (*(n+5)), "m" (*(n+6)), "m" (*(n+7)) \
- )
-
-#define set_tss_desc(n,addr) _set_tssldt_desc(((char *) (n)),((int)(addr)),235,"0x89")
-#define set_ldt_desc(n,addr,size) \
- _set_tssldt_desc(((char *) (n)),((int)(addr)),((size << 3) - 1),"0x82")
-
-/*
- * This is the ldt that every process will get unless we need
- * something other than this.
- */
-extern struct desc_struct default_ldt;
-
-/*
- * disable hlt during certain critical i/o operations
- */
-#ifndef MACH
-#define HAVE_DISABLE_HLT
-#endif
-void disable_hlt(void);
-void enable_hlt(void);
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/asm/termios.h b/i386/i386at/gpl/linux/include/asm/termios.h
deleted file mode 100644
index e9cbf14e..00000000
--- a/i386/i386at/gpl/linux/include/asm/termios.h
+++ /dev/null
@@ -1,304 +0,0 @@
-#ifndef _I386_TERMIOS_H
-#define _I386_TERMIOS_H
-
-/* 0x54 is just a magic number to make these relatively unique ('T') */
-
-#define TCGETS 0x5401
-#define TCSETS 0x5402
-#define TCSETSW 0x5403
-#define TCSETSF 0x5404
-#define TCGETA 0x5405
-#define TCSETA 0x5406
-#define TCSETAW 0x5407
-#define TCSETAF 0x5408
-#define TCSBRK 0x5409
-#define TCXONC 0x540A
-#define TCFLSH 0x540B
-#define TIOCEXCL 0x540C
-#define TIOCNXCL 0x540D
-#define TIOCSCTTY 0x540E
-#define TIOCGPGRP 0x540F
-#define TIOCSPGRP 0x5410
-#define TIOCOUTQ 0x5411
-#define TIOCSTI 0x5412
-#define TIOCGWINSZ 0x5413
-#define TIOCSWINSZ 0x5414
-#define TIOCMGET 0x5415
-#define TIOCMBIS 0x5416
-#define TIOCMBIC 0x5417
-#define TIOCMSET 0x5418
-#define TIOCGSOFTCAR 0x5419
-#define TIOCSSOFTCAR 0x541A
-#define FIONREAD 0x541B
-#define TIOCINQ FIONREAD
-#define TIOCLINUX 0x541C
-#define TIOCCONS 0x541D
-#define TIOCGSERIAL 0x541E
-#define TIOCSSERIAL 0x541F
-#define TIOCPKT 0x5420
-#define FIONBIO 0x5421
-#define TIOCNOTTY 0x5422
-#define TIOCSETD 0x5423
-#define TIOCGETD 0x5424
-#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
-#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */
-#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */
-#define FIOCLEX 0x5451
-#define FIOASYNC 0x5452
-#define TIOCSERCONFIG 0x5453
-#define TIOCSERGWILD 0x5454
-#define TIOCSERSWILD 0x5455
-#define TIOCGLCKTRMIOS 0x5456
-#define TIOCSLCKTRMIOS 0x5457
-#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
-#define TIOCSERGETLSR 0x5459 /* Get line status register */
-#define TIOCSERGETMULTI 0x545A /* Get multiport config */
-#define TIOCSERSETMULTI 0x545B /* Set multiport config */
-
-#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
-#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
-
-/* Used for packet mode */
-#define TIOCPKT_DATA 0
-#define TIOCPKT_FLUSHREAD 1
-#define TIOCPKT_FLUSHWRITE 2
-#define TIOCPKT_STOP 4
-#define TIOCPKT_START 8
-#define TIOCPKT_NOSTOP 16
-#define TIOCPKT_DOSTOP 32
-
-struct winsize {
- unsigned short ws_row;
- unsigned short ws_col;
- unsigned short ws_xpixel;
- unsigned short ws_ypixel;
-};
-
-#define NCC 8
-struct termio {
- unsigned short c_iflag; /* input mode flags */
- unsigned short c_oflag; /* output mode flags */
- unsigned short c_cflag; /* control mode flags */
- unsigned short c_lflag; /* local mode flags */
- unsigned char c_line; /* line discipline */
- unsigned char c_cc[NCC]; /* control characters */
-};
-
-#define NCCS 19
-struct termios {
- tcflag_t c_iflag; /* input mode flags */
- tcflag_t c_oflag; /* output mode flags */
- tcflag_t c_cflag; /* control mode flags */
- tcflag_t c_lflag; /* local mode flags */
- cc_t c_line; /* line discipline */
- cc_t c_cc[NCCS]; /* control characters */
-};
-
-/* c_cc characters */
-#define VINTR 0
-#define VQUIT 1
-#define VERASE 2
-#define VKILL 3
-#define VEOF 4
-#define VTIME 5
-#define VMIN 6
-#define VSWTC 7
-#define VSTART 8
-#define VSTOP 9
-#define VSUSP 10
-#define VEOL 11
-#define VREPRINT 12
-#define VDISCARD 13
-#define VWERASE 14
-#define VLNEXT 15
-#define VEOL2 16
-
-#ifdef __KERNEL__
-/* intr=^C quit=^| erase=del kill=^U
- eof=^D vtime=\0 vmin=\1 sxtc=\0
- start=^Q stop=^S susp=^Z eol=\0
- reprint=^R discard=^U werase=^W lnext=^V
- eol2=\0
-*/
-#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
-#endif
-
-/* c_iflag bits */
-#define IGNBRK 0000001
-#define BRKINT 0000002
-#define IGNPAR 0000004
-#define PARMRK 0000010
-#define INPCK 0000020
-#define ISTRIP 0000040
-#define INLCR 0000100
-#define IGNCR 0000200
-#define ICRNL 0000400
-#define IUCLC 0001000
-#define IXON 0002000
-#define IXANY 0004000
-#define IXOFF 0010000
-#define IMAXBEL 0020000
-
-/* c_oflag bits */
-#define OPOST 0000001
-#define OLCUC 0000002
-#define ONLCR 0000004
-#define OCRNL 0000010
-#define ONOCR 0000020
-#define ONLRET 0000040
-#define OFILL 0000100
-#define OFDEL 0000200
-#define NLDLY 0000400
-#define NL0 0000000
-#define NL1 0000400
-#define CRDLY 0003000
-#define CR0 0000000
-#define CR1 0001000
-#define CR2 0002000
-#define CR3 0003000
-#define TABDLY 0014000
-#define TAB0 0000000
-#define TAB1 0004000
-#define TAB2 0010000
-#define TAB3 0014000
-#define XTABS 0014000
-#define BSDLY 0020000
-#define BS0 0000000
-#define BS1 0020000
-#define VTDLY 0040000
-#define VT0 0000000
-#define VT1 0040000
-#define FFDLY 0100000
-#define FF0 0000000
-#define FF1 0100000
-
-/* c_cflag bit meaning */
-#define CBAUD 0010017
-#define B0 0000000 /* hang up */
-#define B50 0000001
-#define B75 0000002
-#define B110 0000003
-#define B134 0000004
-#define B150 0000005
-#define B200 0000006
-#define B300 0000007
-#define B600 0000010
-#define B1200 0000011
-#define B1800 0000012
-#define B2400 0000013
-#define B4800 0000014
-#define B9600 0000015
-#define B19200 0000016
-#define B38400 0000017
-#define EXTA B19200
-#define EXTB B38400
-#define CSIZE 0000060
-#define CS5 0000000
-#define CS6 0000020
-#define CS7 0000040
-#define CS8 0000060
-#define CSTOPB 0000100
-#define CREAD 0000200
-#define PARENB 0000400
-#define PARODD 0001000
-#define HUPCL 0002000
-#define CLOCAL 0004000
-#define CBAUDEX 0010000
-#define B57600 0010001
-#define B115200 0010002
-#define B230400 0010003
-#define CIBAUD 002003600000 /* input baud rate (not used) */
-#define CRTSCTS 020000000000 /* flow control */
-
-/* c_lflag bits */
-#define ISIG 0000001
-#define ICANON 0000002
-#define XCASE 0000004
-#define ECHO 0000010
-#define ECHOE 0000020
-#define ECHOK 0000040
-#define ECHONL 0000100
-#define NOFLSH 0000200
-#define TOSTOP 0000400
-#define ECHOCTL 0001000
-#define ECHOPRT 0002000
-#define ECHOKE 0004000
-#define FLUSHO 0010000
-#define PENDIN 0040000
-#define IEXTEN 0100000
-
-/* modem lines */
-#define TIOCM_LE 0x001
-#define TIOCM_DTR 0x002
-#define TIOCM_RTS 0x004
-#define TIOCM_ST 0x008
-#define TIOCM_SR 0x010
-#define TIOCM_CTS 0x020
-#define TIOCM_CAR 0x040
-#define TIOCM_RNG 0x080
-#define TIOCM_DSR 0x100
-#define TIOCM_CD TIOCM_CAR
-#define TIOCM_RI TIOCM_RNG
-
-/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
-#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
-
-
-/* tcflow() and TCXONC use these */
-#define TCOOFF 0
-#define TCOON 1
-#define TCIOFF 2
-#define TCION 3
-
-/* tcflush() and TCFLSH use these */
-#define TCIFLUSH 0
-#define TCOFLUSH 1
-#define TCIOFLUSH 2
-
-/* tcsetattr uses these */
-#define TCSANOW 0
-#define TCSADRAIN 1
-#define TCSAFLUSH 2
-
-/* line disciplines */
-#define N_TTY 0
-#define N_SLIP 1
-#define N_MOUSE 2
-#define N_PPP 3
-
-#ifdef __KERNEL__
-
-#include <linux/string.h>
-
-/*
- * Translate a "termio" structure into a "termios". Ugh.
- */
-extern inline void trans_from_termio(struct termio * termio,
- struct termios * termios)
-{
-#define SET_LOW_BITS(x,y) ((x) = (0xffff0000 & (x)) | (y))
- SET_LOW_BITS(termios->c_iflag, termio->c_iflag);
- SET_LOW_BITS(termios->c_oflag, termio->c_oflag);
- SET_LOW_BITS(termios->c_cflag, termio->c_cflag);
- SET_LOW_BITS(termios->c_lflag, termio->c_lflag);
-#undef SET_LOW_BITS
- memcpy(termios->c_cc, termio->c_cc, NCC);
-}
-
-/*
- * Translate a "termios" structure into a "termio". Ugh.
- */
-extern inline void trans_to_termio(struct termios * termios,
- struct termio * termio)
-{
- termio->c_iflag = termios->c_iflag;
- termio->c_oflag = termios->c_oflag;
- termio->c_cflag = termios->c_cflag;
- termio->c_lflag = termios->c_lflag;
- termio->c_line = termios->c_line;
- memcpy(termio->c_cc, termios->c_cc, NCC);
-}
-
-#endif /* __KERNEL__ */
-
-#endif /* _I386_TERMIOS_H */
diff --git a/i386/i386at/gpl/linux/include/asm/types.h b/i386/i386at/gpl/linux/include/asm/types.h
deleted file mode 100644
index 1b82bef4..00000000
--- a/i386/i386at/gpl/linux/include/asm/types.h
+++ /dev/null
@@ -1,109 +0,0 @@
-#ifndef _I386_TYPES_H
-#define _I386_TYPES_H
-
-#ifndef MACH_INCLUDE
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef unsigned int size_t;
-#endif
-
-#ifndef _SSIZE_T
-#define _SSIZE_T
-typedef int ssize_t;
-#endif
-
-#ifndef _PTRDIFF_T
-#define _PTRDIFF_T
-typedef int ptrdiff_t;
-#endif
-
-#ifndef _TIME_T
-#define _TIME_T
-typedef long time_t;
-#endif
-
-#ifndef _CLOCK_T
-#define _CLOCK_T
-typedef long clock_t;
-#endif
-#endif /* ! MACH_INCLUDE */
-
-typedef int pid_t;
-#ifndef MACH_INCLUDE
-typedef unsigned short uid_t;
-typedef unsigned short gid_t;
-typedef unsigned short dev_t;
-typedef unsigned long ino_t;
-typedef unsigned short mode_t;
-#endif
-typedef unsigned short umode_t;
-#ifndef MACH_INCLUDE
-typedef unsigned short nlink_t;
-typedef int daddr_t;
-typedef long off_t;
-#endif
-
-/*
- * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
- * header files exported to user space
- */
-
-typedef __signed__ char __s8;
-typedef unsigned char __u8;
-
-typedef __signed__ short __s16;
-typedef unsigned short __u16;
-
-typedef __signed__ int __s32;
-typedef unsigned int __u32;
-
-#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
-typedef __signed__ long long __s64;
-typedef unsigned long long __u64;
-#endif
-
-/*
- * These aren't exported outside the kernel to avoid name space clashes
- */
-#ifdef __KERNEL__
-
-typedef signed char s8;
-typedef unsigned char u8;
-
-typedef signed short s16;
-typedef unsigned short u16;
-
-typedef signed int s32;
-typedef unsigned int u32;
-
-typedef signed long long s64;
-typedef unsigned long long u64;
-
-#endif /* __KERNEL__ */
-
-#undef __FD_SET
-#define __FD_SET(fd,fdsetp) \
- __asm__ __volatile__("btsl %1,%0": \
- "=m" (*(fd_set *) (fdsetp)):"r" ((int) (fd)))
-
-#undef __FD_CLR
-#define __FD_CLR(fd,fdsetp) \
- __asm__ __volatile__("btrl %1,%0": \
- "=m" (*(fd_set *) (fdsetp)):"r" ((int) (fd)))
-
-#undef __FD_ISSET
-#define __FD_ISSET(fd,fdsetp) (__extension__ ({ \
- unsigned char __result; \
- __asm__ __volatile__("btl %1,%2 ; setb %0" \
- :"=q" (__result) :"r" ((int) (fd)), \
- "m" (*(fd_set *) (fdsetp))); \
- __result; }))
-
-#undef __FD_ZERO
-#define __FD_ZERO(fdsetp) \
- __asm__ __volatile__("cld ; rep ; stosl" \
- :"=m" (*(fd_set *) (fdsetp)) \
- :"a" (0), "c" (__FDSET_INTS), \
- "D" ((fd_set *) (fdsetp)) :"cx","di")
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/asm/unistd.h b/i386/i386at/gpl/linux/include/asm/unistd.h
deleted file mode 100644
index 1837f210..00000000
--- a/i386/i386at/gpl/linux/include/asm/unistd.h
+++ /dev/null
@@ -1,322 +0,0 @@
-#ifndef _ASM_I386_UNISTD_H_
-#define _ASM_I386_UNISTD_H_
-
-/*
- * This file contains the system call numbers.
- */
-
-#define __NR_setup 0 /* used only by init, to get system going */
-#define __NR_exit 1
-#define __NR_fork 2
-#define __NR_read 3
-#define __NR_write 4
-#define __NR_open 5
-#define __NR_close 6
-#define __NR_waitpid 7
-#define __NR_creat 8
-#define __NR_link 9
-#define __NR_unlink 10
-#define __NR_execve 11
-#define __NR_chdir 12
-#define __NR_time 13
-#define __NR_mknod 14
-#define __NR_chmod 15
-#define __NR_chown 16
-#define __NR_break 17
-#define __NR_oldstat 18
-#define __NR_lseek 19
-#define __NR_getpid 20
-#define __NR_mount 21
-#define __NR_umount 22
-#define __NR_setuid 23
-#define __NR_getuid 24
-#define __NR_stime 25
-#define __NR_ptrace 26
-#define __NR_alarm 27
-#define __NR_oldfstat 28
-#define __NR_pause 29
-#define __NR_utime 30
-#define __NR_stty 31
-#define __NR_gtty 32
-#define __NR_access 33
-#define __NR_nice 34
-#define __NR_ftime 35
-#define __NR_sync 36
-#define __NR_kill 37
-#define __NR_rename 38
-#define __NR_mkdir 39
-#define __NR_rmdir 40
-#define __NR_dup 41
-#define __NR_pipe 42
-#define __NR_times 43
-#define __NR_prof 44
-#define __NR_brk 45
-#define __NR_setgid 46
-#define __NR_getgid 47
-#define __NR_signal 48
-#define __NR_geteuid 49
-#define __NR_getegid 50
-#define __NR_acct 51
-#define __NR_phys 52
-#define __NR_lock 53
-#define __NR_ioctl 54
-#define __NR_fcntl 55
-#define __NR_mpx 56
-#define __NR_setpgid 57
-#define __NR_ulimit 58
-#define __NR_oldolduname 59
-#define __NR_umask 60
-#define __NR_chroot 61
-#define __NR_ustat 62
-#define __NR_dup2 63
-#define __NR_getppid 64
-#define __NR_getpgrp 65
-#define __NR_setsid 66
-#define __NR_sigaction 67
-#define __NR_sgetmask 68
-#define __NR_ssetmask 69
-#define __NR_setreuid 70
-#define __NR_setregid 71
-#define __NR_sigsuspend 72
-#define __NR_sigpending 73
-#define __NR_sethostname 74
-#define __NR_setrlimit 75
-#define __NR_getrlimit 76
-#define __NR_getrusage 77
-#define __NR_gettimeofday 78
-#define __NR_settimeofday 79
-#define __NR_getgroups 80
-#define __NR_setgroups 81
-#define __NR_select 82
-#define __NR_symlink 83
-#define __NR_oldlstat 84
-#define __NR_readlink 85
-#define __NR_uselib 86
-#define __NR_swapon 87
-#define __NR_reboot 88
-#define __NR_readdir 89
-#define __NR_mmap 90
-#define __NR_munmap 91
-#define __NR_truncate 92
-#define __NR_ftruncate 93
-#define __NR_fchmod 94
-#define __NR_fchown 95
-#define __NR_getpriority 96
-#define __NR_setpriority 97
-#define __NR_profil 98
-#define __NR_statfs 99
-#define __NR_fstatfs 100
-#define __NR_ioperm 101
-#define __NR_socketcall 102
-#define __NR_syslog 103
-#define __NR_setitimer 104
-#define __NR_getitimer 105
-#define __NR_stat 106
-#define __NR_lstat 107
-#define __NR_fstat 108
-#define __NR_olduname 109
-#define __NR_iopl 110
-#define __NR_vhangup 111
-#define __NR_idle 112
-#define __NR_vm86 113
-#define __NR_wait4 114
-#define __NR_swapoff 115
-#define __NR_sysinfo 116
-#define __NR_ipc 117
-#define __NR_fsync 118
-#define __NR_sigreturn 119
-#define __NR_clone 120
-#define __NR_setdomainname 121
-#define __NR_uname 122
-#define __NR_modify_ldt 123
-#define __NR_adjtimex 124
-#define __NR_mprotect 125
-#define __NR_sigprocmask 126
-#define __NR_create_module 127
-#define __NR_init_module 128
-#define __NR_delete_module 129
-#define __NR_get_kernel_syms 130
-#define __NR_quotactl 131
-#define __NR_getpgid 132
-#define __NR_fchdir 133
-#define __NR_bdflush 134
-#define __NR_sysfs 135
-#define __NR_personality 136
-#define __NR_afs_syscall 137 /* Syscall for Andrew File System */
-#define __NR_setfsuid 138
-#define __NR_setfsgid 139
-#define __NR__llseek 140
-#define __NR_getdents 141
-#define __NR__newselect 142
-#define __NR_flock 143
-#define __NR_msync 144
-#define __NR_readv 145
-#define __NR_writev 146
-#define __NR_getsid 147
-#define __NR_fdatasync 148
-#define __NR__sysctl 149
-#define __NR_mlock 150
-#define __NR_munlock 151
-#define __NR_mlockall 152
-#define __NR_munlockall 153
-#define __NR_sched_setparam 154
-#define __NR_sched_getparam 155
-#define __NR_sched_setscheduler 156
-#define __NR_sched_getscheduler 157
-#define __NR_sched_yield 158
-#define __NR_sched_get_priority_max 159
-#define __NR_sched_get_priority_min 160
-#define __NR_sched_rr_get_interval 161
-#define __NR_nanosleep 162
-
-/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
-#define _syscall0(type,name) \
-type name(void) \
-{ \
-long __res; \
-__asm__ volatile ("int $0x80" \
- : "=a" (__res) \
- : "0" (__NR_##name)); \
-if (__res >= 0) \
- return (type) __res; \
-errno = -__res; \
-return -1; \
-}
-
-#define _syscall1(type,name,type1,arg1) \
-type name(type1 arg1) \
-{ \
-long __res; \
-__asm__ volatile ("int $0x80" \
- : "=a" (__res) \
- : "0" (__NR_##name),"b" ((long)(arg1))); \
-if (__res >= 0) \
- return (type) __res; \
-errno = -__res; \
-return -1; \
-}
-
-#define _syscall2(type,name,type1,arg1,type2,arg2) \
-type name(type1 arg1,type2 arg2) \
-{ \
-long __res; \
-__asm__ volatile ("int $0x80" \
- : "=a" (__res) \
- : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2))); \
-if (__res >= 0) \
- return (type) __res; \
-errno = -__res; \
-return -1; \
-}
-
-#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
-type name(type1 arg1,type2 arg2,type3 arg3) \
-{ \
-long __res; \
-__asm__ volatile ("int $0x80" \
- : "=a" (__res) \
- : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
- "d" ((long)(arg3))); \
-if (__res>=0) \
- return (type) __res; \
-errno=-__res; \
-return -1; \
-}
-
-#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
-type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
-{ \
-long __res; \
-__asm__ volatile ("int $0x80" \
- : "=a" (__res) \
- : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
- "d" ((long)(arg3)),"S" ((long)(arg4))); \
-if (__res>=0) \
- return (type) __res; \
-errno=-__res; \
-return -1; \
-}
-
-#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
- type5,arg5) \
-type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
-{ \
-long __res; \
-__asm__ volatile ("int $0x80" \
- : "=a" (__res) \
- : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
- "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5))); \
-if (__res>=0) \
- return (type) __res; \
-errno=-__res; \
-return -1; \
-}
-
-#ifdef __KERNEL_SYSCALLS__
-
-/*
- * we need this inline - forking from kernel space will result
- * in NO COPY ON WRITE (!!!), until an execve is executed. This
- * is no problem, but for the stack. This is handled by not letting
- * main() use the stack at all after fork(). Thus, no function
- * calls - which means inline code for fork too, as otherwise we
- * would use the stack upon exit from 'fork()'.
- *
- * Actually only pause and fork are needed inline, so that there
- * won't be any messing with the stack from main(), but we define
- * some others too.
- */
-#define __NR__exit __NR_exit
-static inline _syscall0(int,idle)
-static inline _syscall0(int,fork)
-static inline _syscall2(int,clone,unsigned long,flags,char *,esp)
-static inline _syscall0(int,pause)
-static inline _syscall0(int,setup)
-static inline _syscall0(int,sync)
-static inline _syscall0(pid_t,setsid)
-static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
-static inline _syscall1(int,dup,int,fd)
-static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
-static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
-static inline _syscall1(int,close,int,fd)
-static inline _syscall1(int,_exit,int,exitcode)
-static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
-
-static inline pid_t wait(int * wait_stat)
-{
- return waitpid(-1,wait_stat,0);
-}
-
-/*
- * This is the mechanism for creating a new kernel thread.
- *
- * NOTE! Only a kernel-only process(ie the swapper or direct descendants
- * who haven't done an "execve()") should use this: it will work within
- * a system call from a "real" process, but the process memory space will
- * not be free'd until both the parent and the child have exited.
- */
-static inline pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-{
- long retval;
-
- __asm__ __volatile__(
- "movl %%esp,%%esi\n\t"
- "int $0x80\n\t" /* Linux/i386 system call */
- "cmpl %%esp,%%esi\n\t" /* child or parent? */
- "je 1f\n\t" /* parent - jump */
- "pushl %3\n\t" /* push argument */
- "call *%4\n\t" /* call fn */
- "movl %2,%0\n\t" /* exit */
- "int $0x80\n"
- "1:\t"
- :"=a" (retval)
- :"0" (__NR_clone), "i" (__NR_exit),
- "r" (arg), "r" (fn),
- "b" (flags | CLONE_VM)
- :"si");
- return retval;
-}
-
-#endif
-
-#endif /* _ASM_I386_UNISTD_H_ */
diff --git a/i386/i386at/gpl/linux/include/linux/autoconf.h b/i386/i386at/gpl/linux/include/linux/autoconf.h
deleted file mode 100644
index 0d565aed..00000000
--- a/i386/i386at/gpl/linux/include/linux/autoconf.h
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Loadable module support
- */
-#undef CONFIG_MODULES
-#undef CONFIG_MODVERSIONS
-#undef CONFIG_KERNELD
-
-/*
- * General setup
- */
-#undef CONFIG_MATH_EMULATION
-#undef CONFIG_NET
-#undef CONFIG_MAX_16M
-#define CONFIG_PCI
-#define CONFIG_SYSVIPC 1
-#define CONFIG_BINFMT_AOUT 1
-#define CONFIG_BINFMT_ELF 1
-#undef CONFIG_KERNEL_ELF
-#undef CONFIG_M386
-#define CONFIG_M486 1
-#undef CONFIG_M586
-#undef CONFIG_M686
-
-/* Fetch GNUmach driver config file */
-#include <i386/device-drivers.h>
-
-#if 0 /* these are now in device-drivers.h */
-/*
- * Floppy, IDE, and other block devices
- */
-#define CONFIG_BLK_DEV_FD 1
-#define CONFIG_BLK_DEV_IDE 1
-#endif
-
-/*
- * Please see drivers/block/README.ide for help/info on IDE drives
- */
-#define CONFIG_BLK_DEV_HD_IDE 1
-#define CONFIG_BLK_DEV_IDEATAPI 1
-#define CONFIG_BLK_DEV_IDECD 1
-#undef CONFIG_BLK_DEV_IDETAPE
-#define CONFIG_BLK_DEV_CMD640 1
-#define CONFIG_BLK_DEV_RZ1000 1
-#define CONFIG_BLK_DEV_TRITON 1
-#define CONFIG_IDE_CHIPSETS 1
-#undef CONFIG_BLK_DEV_RAM
-#undef CONFIG_BLK_DEV_LOOP
-#undef CONFIG_BLK_DEV_XD
-
-#if 0 /* now in device-drivers.h */
-/*
- * Networking options
- */
-#undef CONFIG_FIREWALL
-#undef CONFIG_NET_ALIAS
-#define CONFIG_INET 1
-#undef CONFIG_IP_FORWARD
-#undef CONFIG_IP_MULTICAST
-#undef CONFIG_IP_ACCT
-#endif
-
-/*
- * (it is safe to leave these untouched)
- */
-#undef CONFIG_INET_PCTCP
-#undef CONFIG_INET_RARP
-#undef CONFIG_NO_PATH_MTU_DISCOVERY
-#undef CONFIG_TCP_NAGLE_OFF
-#define CONFIG_IP_NOSR 1
-#define CONFIG_SKB_LARGE 1
-
-/*
- *
- */
-#undef CONFIG_IPX
-#undef CONFIG_ATALK
-#undef CONFIG_AX25
-#undef CONFIG_NETLINK
-
-#if 0
-/*
- * SCSI support
- */
-#define CONFIG_SCSI 1
-#endif
-
-/*
- * SCSI support type (disk, tape, CDrom)
- */
-#define CONFIG_BLK_DEV_SD 1
-#undef CONFIG_CHR_DEV_ST
-#define CONFIG_BLK_DEV_SR 1
-#undef CONFIG_CHR_DEV_SG
-
-#if 0 /* now in device-drivers.h */
-/*
- * Some SCSI devices (e.g. CD jukebox) support multiple LUNs
- */
-#undef CONFIG_SCSI_MULTI_LUN
-#undef CONFIG_SCSI_CONSTANTS
-
-/*
- * SCSI low-level drivers
- */
-#undef CONFIG_SCSI_ADVANSYS
-#define CONFIG_SCSI_AHA152X 1
-#define CONFIG_SCSI_AHA1542 1
-#define CONFIG_SCSI_AHA1740 1
-#define CONFIG_SCSI_AIC7XXX 1
-#undef CONFIG_SCSI_BUSLOGIC
-#undef CONFIG_SCSI_EATA_DMA
-#undef CONFIG_SCSI_EATA_PIO
-#define CONFIG_SCSI_U14_34F 1
-#undef CONFIG_SCSI_FUTURE_DOMAIN
-#undef CONFIG_SCSI_GENERIC_NCR5380
-#undef CONFIG_SCSI_IN2000
-#undef CONFIG_SCSI_PAS16
-#undef CONFIG_SCSI_QLOGIC
-#define CONFIG_SCSI_SEAGATE 1
-#undef CONFIG_SCSI_T128
-#undef CONFIG_SCSI_ULTRASTOR
-#undef CONFIG_SCSI_7000FASST
-#undef CONFIG_SCSI_EATA
-#undef CONFIG_SCSI_NCR53C406A
-#undef CONFIG_SCSI_AM53C974
-#define CONFIG_SCSI_NCR53C7xx 1
-#endif
-
-/*
- * Network device support
- */
-#undef CONFIG_NETDEVICES
-#undef CONFIG_DUMMY
-#undef CONFIG_SLIP
-#undef CONFIG_SLIP_COMPRESSED
-#undef CONFIG_SLIP_SMART
-#undef CONFIG_PPP
-
-#if 0
-/*
- * CCP compressors for PPP are only built as modules.
- */
-#undef CONFIG_SCC
-#undef CONFIG_PLIP
-#undef CONFIG_EQUALIZER
-#undef CONFIG_NET_ALPHA
-#define CONFIG_NET_VENDOR_SMC 1
-#undef CONFIG_LANCE
-#undef CONFIG_NET_VENDOR_3COM
-#undef CONFIG_EL1
-#undef CONFIG_EL2
-#define CONFIG_EL3 1
-#undef CONFIG_VORTEX
-#define CONFIG_NET_ISA 1
-#undef CONFIG_E2100
-#undef CONFIG_DEPCA
-#undef CONFIG_EWRK3
-#define CONFIG_HPLAN_PLUS 1
-#undef CONFIG_HPLAN
-#undef CONFIG_HP100
-#define CONFIG_NE2000 1
-#undef CONFIG_SK_G16
-#undef CONFIG_NET_EISA
-#undef CONFIG_NET_POCKET
-#undef CONFIG_TR
-#undef CONFIG_ARCNET
-#define CONFIG_DE4X5 1
-#define CONFIG_ULTRA 1
-#define CONFIG_WD80x3 1
-
-/*
- * CD-ROM drivers (not for SCSI or IDE/ATAPI drives)
- */
-#undef CONFIG_CD_NO_IDESCSI
-#endif
-
-/*
- * Filesystems
- */
-#undef CONFIG_QUOTA
-#define CONFIG_MINIX_FS 1
-#undef CONFIG_EXT_FS
-#define CONFIG_EXT2_FS 1
-#undef CONFIG_XIA_FS
-#define CONFIG_FAT_FS 1
-#define CONFIG_MSDOS_FS 1
-#undef CONFIG_VFAT_FS
-#undef CONFIG_UMSDOS_FS
-#define CONFIG_PROC_FS 1
-#define CONFIG_NFS_FS 1
-#undef CONFIG_ROOT_NFS
-#undef CONFIG_SMB_FS
-#define CONFIG_ISO9660_FS 1
-#undef CONFIG_HPFS_FS
-#undef CONFIG_SYSV_FS
-
-#if 0
-/*
- * Character devices
- */
-#undef CONFIG_CYCLADES
-#undef CONFIG_STALDRV
-#define CONFIG_PRINTER 1
-#undef CONFIG_BUSMOUSE
-#undef CONFIG_PSMOUSE
-#undef CONFIG_MS_BUSMOUSE
-#undef CONFIG_ATIXL_BUSMOUSE
-#undef CONFIG_QIC02_TAPE
-#undef CONFIG_APM
-#undef CONFIG_WATCHDOG
-
-/*
- * Sound
- */
-#undef CONFIG_SOUND
-
-/*
- * Kernel hacking
- */
-#undef CONFIG_PROFILE
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/binfmts.h b/i386/i386at/gpl/linux/include/linux/binfmts.h
deleted file mode 100644
index 0d1c403a..00000000
--- a/i386/i386at/gpl/linux/include/linux/binfmts.h
+++ /dev/null
@@ -1,60 +0,0 @@
-#ifndef _LINUX_BINFMTS_H
-#define _LINUX_BINFMTS_H
-
-#include <linux/ptrace.h>
-
-/*
- * MAX_ARG_PAGES defines the number of pages allocated for arguments
- * and envelope for the new program. 32 should suffice, this gives
- * a maximum env+arg of 128kB w/4KB pages!
- */
-#define MAX_ARG_PAGES 32
-
-/*
- * This structure is used to hold the arguments that are used when loading binaries.
- */
-struct linux_binprm{
- char buf[128];
- unsigned long page[MAX_ARG_PAGES];
- unsigned long p;
- int sh_bang;
- struct inode * inode;
- int e_uid, e_gid;
- int argc, envc;
- char * filename; /* Name of binary */
- unsigned long loader, exec;
-};
-
-/*
- * This structure defines the functions that are used to load the binary formats that
- * linux accepts.
- */
-struct linux_binfmt {
- struct linux_binfmt * next;
- int *use_count;
- int (*load_binary)(struct linux_binprm *, struct pt_regs * regs);
- int (*load_shlib)(int fd);
- int (*core_dump)(long signr, struct pt_regs * regs);
-};
-
-extern int register_binfmt(struct linux_binfmt *);
-extern int unregister_binfmt(struct linux_binfmt *);
-
-extern int read_exec(struct inode *inode, unsigned long offset,
- char * addr, unsigned long count, int to_kmem);
-
-extern int open_inode(struct inode * inode, int mode);
-
-extern int init_elf_binfmt(void);
-extern int init_aout_binfmt(void);
-
-extern void flush_old_exec(struct linux_binprm * bprm);
-extern unsigned long setup_arg_pages(unsigned long text_size,unsigned long * page);
-extern unsigned long * create_tables(char * p,struct linux_binprm * bprm,int ibcs);
-extern unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
- unsigned long p, int from_kmem);
-
-/* this eventually goes away */
-#define change_ldt(a,b) setup_arg_pages(a,b)
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/bios32.h b/i386/i386at/gpl/linux/include/linux/bios32.h
deleted file mode 100644
index f57398e5..00000000
--- a/i386/i386at/gpl/linux/include/linux/bios32.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * BIOS32, PCI BIOS functions and defines
- * Copyright 1994, Drew Eckhardt
- *
- * For more information, please consult
- *
- * PCI BIOS Specification Revision
- * PCI Local Bus Specification
- * PCI System Design Guide
- *
- * PCI Special Interest Group
- * M/S HF3-15A
- * 5200 N.E. Elam Young Parkway
- * Hillsboro, Oregon 97124-6497
- * +1 (503) 696-2000
- * +1 (800) 433-5177
- *
- * Manuals are $25 each or $50 for all three, plus $7 shipping
- * within the United States, $35 abroad.
- */
-
-#ifndef BIOS32_H
-#define BIOS32_H
-
-/*
- * Error values that may be returned by the PCI bios. Use
- * pcibios_strerror() to convert to a printable string.
- */
-#define PCIBIOS_SUCCESSFUL 0x00
-#define PCIBIOS_FUNC_NOT_SUPPORTED 0x81
-#define PCIBIOS_BAD_VENDOR_ID 0x83
-#define PCIBIOS_DEVICE_NOT_FOUND 0x86
-#define PCIBIOS_BAD_REGISTER_NUMBER 0x87
-#define PCIBIOS_SET_FAILED 0x88
-#define PCIBIOS_BUFFER_TOO_SMALL 0x89
-
-extern int pcibios_present (void);
-extern unsigned long pcibios_init (unsigned long memory_start,
- unsigned long memory_end);
-extern unsigned long pcibios_fixup (unsigned long memory_start,
- unsigned long memory_end);
-extern int pcibios_find_class (unsigned int class_code, unsigned short index,
- unsigned char *bus, unsigned char *dev_fn);
-extern int pcibios_find_device (unsigned short vendor, unsigned short dev_id,
- unsigned short index, unsigned char *bus,
- unsigned char *dev_fn);
-extern int pcibios_read_config_byte (unsigned char bus, unsigned char dev_fn,
- unsigned char where, unsigned char *val);
-extern int pcibios_read_config_word (unsigned char bus, unsigned char dev_fn,
- unsigned char where, unsigned short *val);
-extern int pcibios_read_config_dword (unsigned char bus, unsigned char dev_fn,
- unsigned char where, unsigned int *val);
-extern int pcibios_write_config_byte (unsigned char bus, unsigned char dev_fn,
- unsigned char where, unsigned char val);
-extern int pcibios_write_config_word (unsigned char bus, unsigned char dev_fn,
- unsigned char where, unsigned short val);
-extern pcibios_write_config_dword (unsigned char bus, unsigned char dev_fn,
- unsigned char where, unsigned int val);
-extern const char *pcibios_strerror (int error);
-
-#endif /* BIOS32_H */
diff --git a/i386/i386at/gpl/linux/include/linux/blk.h b/i386/i386at/gpl/linux/include/linux/blk.h
deleted file mode 100644
index cf236a61..00000000
--- a/i386/i386at/gpl/linux/include/linux/blk.h
+++ /dev/null
@@ -1,408 +0,0 @@
-#ifndef _BLK_H
-#define _BLK_H
-
-#include <linux/blkdev.h>
-#include <linux/locks.h>
-#include <linux/config.h>
-
-/*
- * This is used in the elevator algorithm. We don't prioritise reads
- * over writes any more --- although reads are more time-critical than
- * writes, by treating them equally we increase filesystem throughput.
- * This turns out to give better overall performance. -- sct
- */
-#define IN_ORDER(s1,s2) \
-((s1)->rq_dev < (s2)->rq_dev || (((s1)->rq_dev == (s2)->rq_dev && \
-(s1)->sector < (s2)->sector)))
-
-/*
- * These will have to be changed to be aware of different buffer
- * sizes etc.. It actually needs a major cleanup.
- */
-#ifdef IDE_DRIVER
-#define SECTOR_MASK ((BLOCK_SIZE >> 9) - 1)
-#else
-#define SECTOR_MASK (blksize_size[MAJOR_NR] && \
- blksize_size[MAJOR_NR][MINOR(CURRENT->rq_dev)] ? \
- ((blksize_size[MAJOR_NR][MINOR(CURRENT->rq_dev)] >> 9) - 1) : \
- ((BLOCK_SIZE >> 9) - 1))
-#endif /* IDE_DRIVER */
-
-#define SUBSECTOR(block) (CURRENT->current_nr_sectors > 0)
-
-#ifdef CONFIG_CDU31A
-extern int cdu31a_init(void);
-#endif CONFIG_CDU31A
-#ifdef CONFIG_MCD
-extern int mcd_init(void);
-#endif CONFIG_MCD
-#ifdef CONFIG_MCDX
-extern int mcdx_init(void);
-#endif CONFIG_MCDX
-#ifdef CONFIG_SBPCD
-extern int sbpcd_init(void);
-#endif CONFIG_SBPCD
-#ifdef CONFIG_AZTCD
-extern int aztcd_init(void);
-#endif CONFIG_AZTCD
-#ifdef CONFIG_CDU535
-extern int sony535_init(void);
-#endif CONFIG_CDU535
-#ifdef CONFIG_GSCD
-extern int gscd_init(void);
-#endif CONFIG_GSCD
-#ifdef CONFIG_CM206
-extern int cm206_init(void);
-#endif CONFIG_CM206
-#ifdef CONFIG_OPTCD
-extern int optcd_init(void);
-#endif CONFIG_OPTCD
-#ifdef CONFIG_SJCD
-extern int sjcd_init(void);
-#endif CONFIG_SJCD
-#ifdef CONFIG_CDI_INIT
-extern int cdi_init(void);
-#endif CONFIG_CDI_INIT
-#ifdef CONFIG_BLK_DEV_HD
-extern int hd_init(void);
-#endif
-#ifdef CONFIG_BLK_DEV_IDE
-extern int ide_init(void);
-#endif
-#ifdef CONFIG_BLK_DEV_XD
-extern int xd_init(void);
-#endif
-
-extern void set_device_ro(kdev_t dev,int flag);
-void add_blkdev_randomness(int major);
-
-extern int floppy_init(void);
-extern void rd_load(void);
-extern int rd_init(void);
-extern int rd_doload; /* 1 = load ramdisk, 0 = don't load */
-extern int rd_prompt; /* 1 = prompt for ramdisk, 0 = don't prompt */
-extern int rd_image_start; /* starting block # of image */
-
-#define RO_IOCTLS(dev,where) \
- case BLKROSET: if (!suser()) return -EACCES; \
- set_device_ro((dev),get_fs_long((long *) (where))); return 0; \
- case BLKROGET: { int __err = verify_area(VERIFY_WRITE, (void *) (where), sizeof(long)); \
- if (!__err) put_fs_long(0!=is_read_only(dev),(long *) (where)); return __err; }
-
-#if defined(MAJOR_NR) || defined(IDE_DRIVER)
-
-/*
- * Add entries as needed.
- */
-
-#ifdef IDE_DRIVER
-
-#define DEVICE_NR(device) (MINOR(device) >> PARTN_BITS)
-#define DEVICE_ON(device) /* nothing */
-#define DEVICE_OFF(device) /* nothing */
-
-#elif (MAJOR_NR == RAMDISK_MAJOR)
-
-/* ram disk */
-#define DEVICE_NAME "ramdisk"
-#define DEVICE_REQUEST rd_request
-#define DEVICE_NR(device) (MINOR(device))
-#define DEVICE_ON(device)
-#define DEVICE_OFF(device)
-#define DEVICE_NO_RANDOM
-
-#elif (MAJOR_NR == FLOPPY_MAJOR)
-
-static void floppy_off(unsigned int nr);
-
-#define DEVICE_NAME "floppy"
-#define DEVICE_INTR do_floppy
-#define DEVICE_REQUEST do_fd_request
-#define DEVICE_NR(device) ( (MINOR(device) & 3) | ((MINOR(device) & 0x80 ) >> 5 ))
-#define DEVICE_ON(device)
-#define DEVICE_OFF(device) floppy_off(DEVICE_NR(device))
-
-#elif (MAJOR_NR == HD_MAJOR)
-
-/* harddisk: timeout is 6 seconds.. */
-#define DEVICE_NAME "harddisk"
-#define DEVICE_INTR do_hd
-#define DEVICE_TIMEOUT HD_TIMER
-#define TIMEOUT_VALUE (6*HZ)
-#define DEVICE_REQUEST do_hd_request
-#define DEVICE_NR(device) (MINOR(device)>>6)
-#define DEVICE_ON(device)
-#define DEVICE_OFF(device)
-
-#elif (MAJOR_NR == SCSI_DISK_MAJOR)
-
-#define DEVICE_NAME "scsidisk"
-#define DEVICE_INTR do_sd
-#define TIMEOUT_VALUE (2*HZ)
-#define DEVICE_REQUEST do_sd_request
-#define DEVICE_NR(device) (MINOR(device) >> 4)
-#define DEVICE_ON(device)
-#define DEVICE_OFF(device)
-
-#elif (MAJOR_NR == SCSI_TAPE_MAJOR)
-
-#define DEVICE_NAME "scsitape"
-#define DEVICE_INTR do_st
-#define DEVICE_NR(device) (MINOR(device) & 0x7f)
-#define DEVICE_ON(device)
-#define DEVICE_OFF(device)
-
-#elif (MAJOR_NR == SCSI_CDROM_MAJOR)
-
-#define DEVICE_NAME "CD-ROM"
-#define DEVICE_INTR do_sr
-#define DEVICE_REQUEST do_sr_request
-#define DEVICE_NR(device) (MINOR(device))
-#define DEVICE_ON(device)
-#define DEVICE_OFF(device)
-
-#elif (MAJOR_NR == XT_DISK_MAJOR)
-
-#define DEVICE_NAME "xt disk"
-#define DEVICE_REQUEST do_xd_request
-#define DEVICE_NR(device) (MINOR(device) >> 6)
-#define DEVICE_ON(device)
-#define DEVICE_OFF(device)
-
-#elif (MAJOR_NR == CDU31A_CDROM_MAJOR)
-
-#define DEVICE_NAME "CDU31A"
-#define DEVICE_REQUEST do_cdu31a_request
-#define DEVICE_NR(device) (MINOR(device))
-#define DEVICE_ON(device)
-#define DEVICE_OFF(device)
-
-#elif (MAJOR_NR == MITSUMI_CDROM_MAJOR)
-
-#define DEVICE_NAME "Mitsumi CD-ROM"
-/* #define DEVICE_INTR do_mcd */
-#define DEVICE_REQUEST do_mcd_request
-#define DEVICE_NR(device) (MINOR(device))
-#define DEVICE_ON(device)
-#define DEVICE_OFF(device)
-
-#elif (MAJOR_NR == MITSUMI_X_CDROM_MAJOR)
-
-#define DEVICE_NAME "Mitsumi CD-ROM"
-/* #define DEVICE_INTR do_mcdx */
-#define DEVICE_REQUEST do_mcdx_request
-#define DEVICE_NR(device) (MINOR(device))
-#define DEVICE_ON(device)
-#define DEVICE_OFF(device)
-
-#elif (MAJOR_NR == MATSUSHITA_CDROM_MAJOR)
-
-#define DEVICE_NAME "Matsushita CD-ROM controller #1"
-#define DEVICE_REQUEST do_sbpcd_request
-#define DEVICE_NR(device) (MINOR(device))
-#define DEVICE_ON(device)
-#define DEVICE_OFF(device)
-
-#elif (MAJOR_NR == MATSUSHITA_CDROM2_MAJOR)
-
-#define DEVICE_NAME "Matsushita CD-ROM controller #2"
-#define DEVICE_REQUEST do_sbpcd2_request
-#define DEVICE_NR(device) (MINOR(device))
-#define DEVICE_ON(device)
-#define DEVICE_OFF(device)
-
-#elif (MAJOR_NR == MATSUSHITA_CDROM3_MAJOR)
-
-#define DEVICE_NAME "Matsushita CD-ROM controller #3"
-#define DEVICE_REQUEST do_sbpcd3_request
-#define DEVICE_NR(device) (MINOR(device))
-#define DEVICE_ON(device)
-#define DEVICE_OFF(device)
-
-#elif (MAJOR_NR == MATSUSHITA_CDROM4_MAJOR)
-
-#define DEVICE_NAME "Matsushita CD-ROM controller #4"
-#define DEVICE_REQUEST do_sbpcd4_request
-#define DEVICE_NR(device) (MINOR(device))
-#define DEVICE_ON(device)
-#define DEVICE_OFF(device)
-
-#elif (MAJOR_NR == AZTECH_CDROM_MAJOR)
-
-#define DEVICE_NAME "Aztech CD-ROM"
-#define DEVICE_REQUEST do_aztcd_request
-#define DEVICE_NR(device) (MINOR(device))
-#define DEVICE_ON(device)
-#define DEVICE_OFF(device)
-
-#elif (MAJOR_NR == CDU535_CDROM_MAJOR)
-
-#define DEVICE_NAME "SONY-CDU535"
-#define DEVICE_INTR do_cdu535
-#define DEVICE_REQUEST do_cdu535_request
-#define DEVICE_NR(device) (MINOR(device))
-#define DEVICE_ON(device)
-#define DEVICE_OFF(device)
-
-#elif (MAJOR_NR == GOLDSTAR_CDROM_MAJOR)
-
-#define DEVICE_NAME "Goldstar R420"
-#define DEVICE_REQUEST do_gscd_request
-#define DEVICE_NR(device) (MINOR(device))
-#define DEVICE_ON(device)
-#define DEVICE_OFF(device)
-
-#elif (MAJOR_NR == CM206_CDROM_MAJOR)
-#define DEVICE_NAME "Philips/LMS cd-rom cm206"
-#define DEVICE_REQUEST do_cm206_request
-#define DEVICE_NR(device) (MINOR(device))
-#define DEVICE_ON(device)
-#define DEVICE_OFF(device)
-
-#elif (MAJOR_NR == OPTICS_CDROM_MAJOR)
-
-#define DEVICE_NAME "DOLPHIN 8000AT CD-ROM"
-#define DEVICE_REQUEST do_optcd_request
-#define DEVICE_NR(device) (MINOR(device))
-#define DEVICE_ON(device)
-#define DEVICE_OFF(device)
-
-#elif (MAJOR_NR == SANYO_CDROM_MAJOR)
-
-#define DEVICE_NAME "Sanyo H94A CD-ROM"
-#define DEVICE_REQUEST do_sjcd_request
-#define DEVICE_NR(device) (MINOR(device))
-#define DEVICE_ON(device)
-#define DEVICE_OFF(device)
-
-#endif /* MAJOR_NR == whatever */
-
-#if (MAJOR_NR != SCSI_TAPE_MAJOR) && !defined(IDE_DRIVER)
-
-#ifndef CURRENT
-#define CURRENT (blk_dev[MAJOR_NR].current_request)
-#endif
-
-#define CURRENT_DEV DEVICE_NR(CURRENT->rq_dev)
-
-#ifdef DEVICE_INTR
-void (*DEVICE_INTR)(void) = NULL;
-#endif
-#ifdef DEVICE_TIMEOUT
-
-#define SET_TIMER \
-((timer_table[DEVICE_TIMEOUT].expires = jiffies + TIMEOUT_VALUE), \
-(timer_active |= 1<<DEVICE_TIMEOUT))
-
-#define CLEAR_TIMER \
-timer_active &= ~(1<<DEVICE_TIMEOUT)
-
-#define SET_INTR(x) \
-if ((DEVICE_INTR = (x)) != NULL) \
- SET_TIMER; \
-else \
- CLEAR_TIMER;
-
-#else
-
-#define SET_INTR(x) (DEVICE_INTR = (x))
-
-#endif /* DEVICE_TIMEOUT */
-
-static void (DEVICE_REQUEST)(void);
-
-#ifdef DEVICE_INTR
-#define CLEAR_INTR SET_INTR(NULL)
-#else
-#define CLEAR_INTR
-#endif
-
-#define INIT_REQUEST \
- if (!CURRENT) {\
- CLEAR_INTR; \
- return; \
- } \
- if (MAJOR(CURRENT->rq_dev) != MAJOR_NR) \
- panic(DEVICE_NAME ": request list destroyed"); \
- if (CURRENT->bh) { \
- if (!buffer_locked(CURRENT->bh)) \
- panic(DEVICE_NAME ": block not locked"); \
- }
-
-#endif /* (MAJOR_NR != SCSI_TAPE_MAJOR) && !defined(IDE_DRIVER) */
-
-/* end_request() - SCSI devices have their own version */
-/* - IDE drivers have their own copy too */
-
-#if ! SCSI_MAJOR(MAJOR_NR)
-
-#if defined(IDE_DRIVER) && !defined(_IDE_C) /* shared copy for IDE modules */
-void ide_end_request(byte uptodate, ide_hwgroup_t *hwgroup);
-#else
-
-#ifdef IDE_DRIVER
-void ide_end_request(byte uptodate, ide_hwgroup_t *hwgroup) {
- struct request *req = hwgroup->rq;
-#else
-static void end_request(int uptodate) {
- struct request *req = CURRENT;
-#endif /* IDE_DRIVER */
- struct buffer_head * bh;
-
- req->errors = 0;
- if (!uptodate) {
- printk("end_request: I/O error, dev %s, sector %lu\n",
- kdevname(req->rq_dev), req->sector);
-#ifdef MACH
- for (bh = req->bh; bh; ) {
- struct buffer_head *next = bh->b_reqnext;
- bh->b_reqnext = NULL;
- mark_buffer_uptodate(bh, 0);
- unlock_buffer(bh);
- bh = next;
- }
- req->bh = NULL;
-#else
- req->nr_sectors--;
- req->nr_sectors &= ~SECTOR_MASK;
- req->sector += (BLOCK_SIZE / 512);
- req->sector &= ~SECTOR_MASK;
-#endif
- }
-
- if ((bh = req->bh) != NULL) {
- req->bh = bh->b_reqnext;
- bh->b_reqnext = NULL;
- mark_buffer_uptodate(bh, uptodate);
- unlock_buffer(bh);
- if ((bh = req->bh) != NULL) {
- req->current_nr_sectors = bh->b_size >> 9;
- if (req->nr_sectors < req->current_nr_sectors) {
- req->nr_sectors = req->current_nr_sectors;
- printk("end_request: buffer-list destroyed\n");
- }
- req->buffer = bh->b_data;
- return;
- }
- }
-#ifndef DEVICE_NO_RANDOM
- add_blkdev_randomness(MAJOR(req->rq_dev));
-#endif
-#ifdef IDE_DRIVER
- blk_dev[MAJOR(req->rq_dev)].current_request = req->next;
- hwgroup->rq = NULL;
-#else
- DEVICE_OFF(req->rq_dev);
- CURRENT = req->next;
-#endif /* IDE_DRIVER */
- if (req->sem != NULL)
- up(req->sem);
- req->rq_status = RQ_INACTIVE;
- wake_up(&wait_for_request);
-}
-#endif /* defined(IDE_DRIVER) && !defined(_IDE_C) */
-#endif /* ! SCSI_MAJOR(MAJOR_NR) */
-
-#endif /* defined(MAJOR_NR) || defined(IDE_DRIVER) */
-
-#endif /* _BLK_H */
diff --git a/i386/i386at/gpl/linux/include/linux/blkdev.h b/i386/i386at/gpl/linux/include/linux/blkdev.h
deleted file mode 100644
index ba4d08af..00000000
--- a/i386/i386at/gpl/linux/include/linux/blkdev.h
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef _LINUX_BLKDEV_H
-#define _LINUX_BLKDEV_H
-
-#include <linux/major.h>
-#include <linux/sched.h>
-#include <linux/genhd.h>
-
-/*
- * Ok, this is an expanded form so that we can use the same
- * request for paging requests when that is implemented. In
- * paging, 'bh' is NULL, and the semaphore is used to wait
- * for read/write completion.
- */
-struct request {
- volatile int rq_status; /* should split this into a few status bits */
-#define RQ_INACTIVE (-1)
-#define RQ_ACTIVE 1
-#define RQ_SCSI_BUSY 0xffff
-#define RQ_SCSI_DONE 0xfffe
-#define RQ_SCSI_DISCONNECTING 0xffe0
-
- kdev_t rq_dev;
- int cmd; /* READ or WRITE */
- int errors;
- unsigned long sector;
- unsigned long nr_sectors;
- unsigned long current_nr_sectors;
- char * buffer;
- struct semaphore * sem;
- struct buffer_head * bh;
- struct buffer_head * bhtail;
- struct request * next;
-};
-
-struct blk_dev_struct {
- void (*request_fn)(void);
- struct request * current_request;
-};
-
-struct sec_size {
- unsigned block_size;
- unsigned block_size_bits;
-};
-
-extern struct sec_size * blk_sec[MAX_BLKDEV];
-extern struct blk_dev_struct blk_dev[MAX_BLKDEV];
-extern struct wait_queue * wait_for_request;
-extern void resetup_one_dev(struct gendisk *dev, int drive);
-
-extern int * blk_size[MAX_BLKDEV];
-
-extern int * blksize_size[MAX_BLKDEV];
-
-extern int * hardsect_size[MAX_BLKDEV];
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/cdrom.h b/i386/i386at/gpl/linux/include/linux/cdrom.h
deleted file mode 100644
index 5811ff0f..00000000
--- a/i386/i386at/gpl/linux/include/linux/cdrom.h
+++ /dev/null
@@ -1,465 +0,0 @@
-/*
- * -- <linux/cdrom.h>
- * general (not only SCSI) header library for linux CDROM drivers
- * (C) 1992 David Giller rafetmad@oxy.edu
- * 1994, 1995 Eberhard Moenkeberg emoenke@gwdg.de
- *
- */
-
-#ifndef _LINUX_CDROM_H
-#define _LINUX_CDROM_H
-
-/*
- * some fix numbers
- */
-#define CD_MINS 74 /* max. minutes per CD, not really a limit */
-#define CD_SECS 60 /* seconds per minute */
-#define CD_FRAMES 75 /* frames per second */
-
-#define CD_SYNC_SIZE 12 /* 12 sync bytes per raw data frame, not transfered by the drive */
-#define CD_HEAD_SIZE 4 /* header (address) bytes per raw data frame */
-#define CD_SUBHEAD_SIZE 8 /* subheader bytes per raw XA data frame */
-#define CD_XA_HEAD (CD_HEAD_SIZE+CD_SUBHEAD_SIZE) /* "before data" part of raw XA frame */
-#define CD_XA_SYNC_HEAD (CD_SYNC_SIZE+CD_XA_HEAD)/* sync bytes + header of XA frame */
-
-#define CD_FRAMESIZE 2048 /* bytes per frame, "cooked" mode */
-#define CD_FRAMESIZE_RAW 2352 /* bytes per frame, "raw" mode */
-/* most drives don't deliver everything: */
-#define CD_FRAMESIZE_RAW1 (CD_FRAMESIZE_RAW-CD_SYNC_SIZE) /* 2340 */
-#define CD_FRAMESIZE_RAW0 (CD_FRAMESIZE_RAW-CD_SYNC_SIZE-CD_HEAD_SIZE) /* 2336 */
-
-#define CD_EDC_SIZE 4 /* bytes EDC per most raw data frame types */
-#define CD_ZERO_SIZE 8 /* bytes zero per yellow book mode 1 frame */
-#define CD_ECC_SIZE 276 /* bytes ECC per most raw data frame types */
-#define CD_XA_TAIL (CD_EDC_SIZE+CD_ECC_SIZE) /* "after data" part of raw XA frame */
-
-#define CD_FRAMESIZE_SUB 96 /* subchannel data "frame" size */
-#define CD_MSF_OFFSET 150 /* MSF numbering offset of first frame */
-
-#define CD_CHUNK_SIZE 24 /* lowest-level "data bytes piece" */
-#define CD_NUM_OF_CHUNKS 98 /* chunks per frame */
-
-#define CD_FRAMESIZE_XA CD_FRAMESIZE_RAW1 /* obsolete name */
-#define CD_BLOCK_OFFSET CD_MSF_OFFSET /* obsolete name */
-
-/*
- * the raw frame layout:
- *
- * - audio (red): | audio_sample_bytes |
- * | 2352 |
- *
- * - data (yellow, mode1): | sync - head - data - EDC - zero - ECC |
- * | 12 - 4 - 2048 - 4 - 8 - 276 |
- *
- * - data (yellow, mode2): | sync - head - data |
- * | 12 - 4 - 2336 |
- *
- * - XA data (green, mode2 form1): | sync - head - sub - data - EDC - ECC |
- * | 12 - 4 - 8 - 2048 - 4 - 276 |
- *
- * - XA data (green, mode2 form2): | sync - head - sub - data - EDC |
- * | 12 - 4 - 8 - 2324 - 4 |
- */
-
-/*
- * CDROM IOCTL structures
- */
-
-struct cdrom_blk
-{
- unsigned from;
- unsigned short len;
-};
-
-
-struct cdrom_msf
-{
- u_char cdmsf_min0; /* start minute */
- u_char cdmsf_sec0; /* start second */
- u_char cdmsf_frame0; /* start frame */
- u_char cdmsf_min1; /* end minute */
- u_char cdmsf_sec1; /* end second */
- u_char cdmsf_frame1; /* end frame */
-};
-
-struct cdrom_ti
-{
- u_char cdti_trk0; /* start track */
- u_char cdti_ind0; /* start index */
- u_char cdti_trk1; /* end track */
- u_char cdti_ind1; /* end index */
-};
-
-struct cdrom_tochdr
-{
- u_char cdth_trk0; /* start track */
- u_char cdth_trk1; /* end track */
-};
-
-struct cdrom_tocentry
-{
- u_char cdte_track;
- u_char cdte_adr :4;
- u_char cdte_ctrl :4;
- u_char cdte_format;
- union
- {
- struct
- {
- u_char minute;
- u_char second;
- u_char frame;
- } msf;
- int lba;
- } cdte_addr;
- u_char cdte_datamode;
-};
-
-/*
- * CD-ROM address types (cdrom_tocentry.cdte_format)
- */
-#define CDROM_LBA 0x01 /* "logical block": first frame is #0 */
-#define CDROM_MSF 0x02 /* "minute-second-frame": binary, not bcd here! */
-
-/*
- * bit to tell whether track is data or audio (cdrom_tocentry.cdte_ctrl)
- */
-#define CDROM_DATA_TRACK 0x04
-
-/*
- * The leadout track is always 0xAA, regardless of # of tracks on disc
- */
-#define CDROM_LEADOUT 0xAA
-
-struct cdrom_subchnl
-{
- u_char cdsc_format;
- u_char cdsc_audiostatus;
- u_char cdsc_adr: 4;
- u_char cdsc_ctrl: 4;
- u_char cdsc_trk;
- u_char cdsc_ind;
- union
- {
- struct
- {
- u_char minute;
- u_char second;
- u_char frame;
- } msf;
- int lba;
- } cdsc_absaddr;
- union
- {
- struct
- {
- u_char minute;
- u_char second;
- u_char frame;
- } msf;
- int lba;
- } cdsc_reladdr;
-};
-
-/*
- * audio states (from SCSI-2, but seen with other drives, too)
- */
-#define CDROM_AUDIO_INVALID 0x00 /* audio status not supported */
-#define CDROM_AUDIO_PLAY 0x11 /* audio play operation in progress */
-#define CDROM_AUDIO_PAUSED 0x12 /* audio play operation paused */
-#define CDROM_AUDIO_COMPLETED 0x13 /* audio play successfully completed */
-#define CDROM_AUDIO_ERROR 0x14 /* audio play stopped due to error */
-#define CDROM_AUDIO_NO_STATUS 0x15 /* no current audio status to return */
-
-struct cdrom_volctrl
-{
- u_char channel0;
- u_char channel1;
- u_char channel2;
- u_char channel3;
-};
-
-struct cdrom_read
-{
- int cdread_lba;
- caddr_t cdread_bufaddr;
- int cdread_buflen;
-};
-
-/*
- * extensions for transfering audio frames
- * currently used by sbpcd.c, cdu31a.c, ide-cd.c
- */
-struct cdrom_read_audio
-{
- union
- {
- struct
- {
- u_char minute;
- u_char second;
- u_char frame;
- } msf;
- int lba;
- } addr; /* frame address */
- u_char addr_format; /* CDROM_LBA or CDROM_MSF */
- int nframes; /* number of 2352-byte-frames to read at once, limited by the drivers */
- u_char *buf; /* frame buffer (size: nframes*2352 bytes) */
-};
-
-/*
- * this has to be the "arg" of the CDROMMULTISESSION ioctl
- * for obtaining multi session info.
- * The returned "addr" is valid only if "xa_flag" is true.
- */
-struct cdrom_multisession
-{
- union
- {
- struct
- {
- u_char minute;
- u_char second;
- u_char frame;
- } msf;
- int lba;
- } addr; /* frame address: start-of-last-session (not the new "frame 16"!)*/
- u_char xa_flag; /* 1: "is XA disk" */
- u_char addr_format; /* CDROM_LBA or CDROM_MSF */
-};
-
-#ifdef FIVETWELVE
-#define CDROM_MODE1_SIZE 512
-#else
-#define CDROM_MODE1_SIZE 2048
-#endif FIVETWELVE
-#define CDROM_MODE2_SIZE 2336
-
-/*
- * CD-ROM IOCTL commands
- * For IOCTL calls, we will commandeer byte 0x53, or 'S'.
- */
-
-#define CDROMPAUSE 0x5301
-#define CDROMRESUME 0x5302
-#define CDROMPLAYMSF 0x5303 /* (struct cdrom_msf) */
-#define CDROMPLAYTRKIND 0x5304 /* (struct cdrom_ti) */
-
-#define CDROMREADTOCHDR 0x5305 /* (struct cdrom_tochdr) */
-#define CDROMREADTOCENTRY 0x5306 /* (struct cdrom_tocentry) */
-
-#define CDROMSTOP 0x5307 /* stop the drive motor */
-#define CDROMSTART 0x5308 /* turn the motor on */
-
-#define CDROMEJECT 0x5309 /* eject CD-ROM media */
-
-#define CDROMVOLCTRL 0x530a /* (struct cdrom_volctrl) */
-
-#define CDROMSUBCHNL 0x530b /* (struct cdrom_subchnl) */
-
-#define CDROMREADMODE2 0x530c /* (struct cdrom_read) */
- /* read type-2 data */
-
-#define CDROMREADMODE1 0x530d /* (struct cdrom_read) */
- /* read type-1 data */
-
-#define CDROMREADAUDIO 0x530e /* (struct cdrom_read_audio) */
-
-/*
- * enable (1) / disable (0) auto-ejecting
- */
-#define CDROMEJECT_SW 0x530f /* arg: 0 or 1 */
-
-/*
- * obtain the start-of-last-session address of multi session disks
- */
-#define CDROMMULTISESSION 0x5310 /* (struct cdrom_multisession) */
-
-/*
- * obtain the "universal product code" number
- * (only some data disks have it coded)
- */
-#define CDROM_GET_UPC 0x5311 /* 8 bytes returned */
-
-#define CDROMRESET 0x5312 /* hard-reset the drive */
-#define CDROMVOLREAD 0x5313 /* let the drive tell its volume setting */
- /* (struct cdrom_volctrl) */
-
-/*
- * these ioctls are used in aztcd.c
- */
-#define CDROMREADRAW 0x5314 /* read data in raw mode */
-#define CDROMREADCOOKED 0x5315 /* read data in cooked mode */
-#define CDROMSEEK 0x5316 /* seek msf address */
-
-/*
- * for playing audio in logical block addressing mode
- */
-#define CDROMPLAYBLK 0x5317 /* (struct cdrom_blk) */
-
-
-/*
- * CD-ROM-specific SCSI command opcodes
- */
-
-/*
- * Group 2 (10-byte). All of these are called 'optional' by SCSI-II.
- */
-#define SCMD_READ_TOC 0x43 /* read table of contents */
-#define SCMD_PLAYAUDIO_MSF 0x47 /* play data at time offset */
-#define SCMD_PLAYAUDIO_TI 0x48 /* play data at track/index */
-#define SCMD_PAUSE_RESUME 0x4B /* pause/resume audio */
-#define SCMD_READ_SUBCHANNEL 0x42 /* read SC info on playing disc */
-#define SCMD_PLAYAUDIO10 0x45 /* play data at logical block */
-#define SCMD_READ_HEADER 0x44 /* read TOC header */
-
-/*
- * Group 5
- */
-#define SCMD_PLAYAUDIO12 0xA5 /* play data at logical block */
-#define SCMD_PLAYTRACK_REL12 0xA9 /* play track at relative offset */
-
-/*
- * Group 6 Commands
- */
-#define SCMD_CD_PLAYBACK_CONTROL 0xC9 /* Sony vendor-specific audio */
-#define SCMD_CD_PLAYBACK_STATUS 0xC4 /* control opcodes */
-
-/*
- * CD-ROM capacity structure.
- */
-struct scsi_capacity
-{
- u_long capacity;
- u_long lbasize;
-};
-
-/*
- * CD-ROM MODE_SENSE/MODE_SELECT parameters
- */
-#define ERR_RECOVERY_PARMS 0x01
-#define DISCO_RECO_PARMS 0x02
-#define FORMAT_PARMS 0x03
-#define GEOMETRY_PARMS 0x04
-#define CERTIFICATION_PARMS 0x06
-#define CACHE_PARMS 0x38
-
-/*
- * standard mode-select header prepended to all mode-select commands
- */
-struct ccs_modesel_head
-{
- u_char _r1; /* reserved */
- u_char medium; /* device-specific medium type */
- u_char _r2; /* reserved */
- u_char block_desc_length; /* block descriptor length */
- u_char density; /* device-specific density code */
- u_char number_blocks_hi; /* number of blocks in this block desc */
- u_char number_blocks_med;
- u_char number_blocks_lo;
- u_char _r3;
- u_char block_length_hi; /* block length for blocks in this desc */
- u_short block_length;
-};
-
-/*
- * error recovery parameters
- */
-struct ccs_err_recovery
-{
- u_char _r1 : 2; /* reserved */
- u_char page_code : 6; /* page code */
- u_char page_length; /* page length */
- u_char awre : 1; /* auto write realloc enabled */
- u_char arre : 1; /* auto read realloc enabled */
- u_char tb : 1; /* transfer block */
- u_char rc : 1; /* read continuous */
- u_char eec : 1; /* enable early correction */
- u_char per : 1; /* post error */
- u_char dte : 1; /* disable transfer on error */
- u_char dcr : 1; /* disable correction */
- u_char retry_count; /* error retry count */
- u_char correction_span; /* largest recov. to be attempted, bits */
- u_char head_offset_count; /* head offset (2's C) for each retry */
- u_char strobe_offset_count; /* data strobe */
- u_char recovery_time_limit; /* time limit on recovery attempts */
-};
-
-/*
- * disco/reco parameters
- */
-struct ccs_disco_reco
-{
- u_char _r1 : 2; /* reserved */
- u_char page_code : 6; /* page code */
- u_char page_length; /* page length */
- u_char buffer_full_ratio; /* write buffer reconnect threshold */
- u_char buffer_empty_ratio; /* read */
- u_short bus_inactivity_limit; /* limit on bus inactivity time */
- u_short disconnect_time_limit; /* minimum disconnect time */
- u_short connect_time_limit; /* minimum connect time */
- u_short _r2; /* reserved */
-};
-
-/*
- * drive geometry parameters
- */
-struct ccs_geometry
-{
- u_char _r1 : 2; /* reserved */
- u_char page_code : 6; /* page code */
- u_char page_length; /* page length */
- u_char cyl_ub; /* #cyls */
- u_char cyl_mb;
- u_char cyl_lb;
- u_char heads; /* #heads */
- u_char precomp_cyl_ub; /* precomp start */
- u_char precomp_cyl_mb;
- u_char precomp_cyl_lb;
- u_char current_cyl_ub; /* reduced current start */
- u_char current_cyl_mb;
- u_char current_cyl_lb;
- u_short step_rate; /* stepping motor rate */
- u_char landing_cyl_ub; /* landing zone */
- u_char landing_cyl_mb;
- u_char landing_cyl_lb;
- u_char _r2;
- u_char _r3;
- u_char _r4;
-};
-
-/*
- * cache parameters
- */
-struct ccs_cache
-{
- u_char _r1 : 2; /* reserved */
- u_char page_code : 6; /* page code */
- u_char page_length; /* page length */
- u_char mode; /* cache control byte */
- u_char threshold; /* prefetch threshold */
- u_char max_prefetch; /* maximum prefetch size */
- u_char max_multiplier; /* maximum prefetch multiplier */
- u_char min_prefetch; /* minimum prefetch size */
- u_char min_multiplier; /* minimum prefetch multiplier */
- u_char _r2[8];
-};
-
-#endif _LINUX_CDROM_H
-/*==========================================================================*/
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 8
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -8
- * c-argdecl-indent: 8
- * c-label-offset: -8
- * c-continued-statement-offset: 8
- * c-continued-brace-offset: 0
- * End:
- */
diff --git a/i386/i386at/gpl/linux/include/linux/config.h b/i386/i386at/gpl/linux/include/linux/config.h
deleted file mode 100644
index a54cdff2..00000000
--- a/i386/i386at/gpl/linux/include/linux/config.h
+++ /dev/null
@@ -1,41 +0,0 @@
-#ifndef _LINUX_CONFIG_H
-#define _LINUX_CONFIG_H
-
-#include <linux/autoconf.h>
-
-/*
- * Defines for what uname() should return
- */
-#ifndef UTS_SYSNAME
-#define UTS_SYSNAME "Linux"
-#endif
-
-#ifndef UTS_MACHINE
-#define UTS_MACHINE "unknown"
-#endif
-
-#ifndef UTS_NODENAME
-#define UTS_NODENAME "(none)" /* set by sethostname() */
-#endif
-
-#ifndef UTS_DOMAINNAME
-#define UTS_DOMAINNAME "(none)" /* set by setdomainname() */
-#endif
-
-/*
- * The definitions for UTS_RELEASE and UTS_VERSION are now defined
- * in linux/version.h, and should only be used by linux/version.c
- */
-
-/* Don't touch these, unless you really know what your doing. */
-#define DEF_INITSEG 0x9000
-#define DEF_SYSSEG 0x1000
-#define DEF_SETUPSEG 0x9020
-#define DEF_SYSSIZE 0x7F00
-
-/* internal svga startup constants */
-#define NORMAL_VGA 0xffff /* 80x25 mode */
-#define EXTENDED_VGA 0xfffe /* 80x50 mode */
-#define ASK_VGA 0xfffd /* ask for it at bootup */
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/delay.h b/i386/i386at/gpl/linux/include/linux/delay.h
deleted file mode 100644
index 50b5d0b1..00000000
--- a/i386/i386at/gpl/linux/include/linux/delay.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef _LINUX_DELAY_H
-#define _LINUX_DELAY_H
-
-/*
- * Copyright (C) 1993 Linus Torvalds
- *
- * Delay routines, using a pre-computed "loops_per_second" value.
- */
-
-extern unsigned long loops_per_sec;
-
-#include <asm/delay.h>
-
-#endif /* defined(_LINUX_DELAY_H) */
diff --git a/i386/i386at/gpl/linux/include/linux/errno.h b/i386/i386at/gpl/linux/include/linux/errno.h
deleted file mode 100644
index ac212844..00000000
--- a/i386/i386at/gpl/linux/include/linux/errno.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef _LINUX_ERRNO_H
-#define _LINUX_ERRNO_H
-
-#include <asm/errno.h>
-
-#ifdef __KERNEL__
-
-/* Should never be seen by user programs */
-#define ERESTARTSYS 512
-#define ERESTARTNOINTR 513
-#define ERESTARTNOHAND 514 /* restart if no handler.. */
-#define ENOIOCTLCMD 515 /* No ioctl command */
-
-#endif
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/etherdevice.h b/i386/i386at/gpl/linux/include/linux/etherdevice.h
deleted file mode 100644
index b29b76b9..00000000
--- a/i386/i386at/gpl/linux/include/linux/etherdevice.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * INET An implementation of the TCP/IP protocol suite for the LINUX
- * operating system. NET is implemented using the BSD Socket
- * interface as the means of communication with the user level.
- *
- * Definitions for the Ethernet handlers.
- *
- * Version: @(#)eth.h 1.0.4 05/13/93
- *
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
- * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- *
- * Relocated to include/linux where it belongs by Alan Cox
- * <gw4pts@gw4pts.ampr.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- * WARNING: This move may well be temporary. This file will get merged with others RSN.
- *
- */
-#ifndef _LINUX_ETHERDEVICE_H
-#define _LINUX_ETHERDEVICE_H
-
-
-#include <linux/if_ether.h>
-
-#ifdef __KERNEL__
-extern int eth_header(struct sk_buff *skb, struct device *dev,
- unsigned short type, void *daddr,
- void *saddr, unsigned len);
-extern int eth_rebuild_header(void *buff, struct device *dev,
- unsigned long dst, struct sk_buff *skb);
-#ifdef MACH
-#define eth_type_trans(skb, dev) 0
-#else
-extern unsigned short eth_type_trans(struct sk_buff *skb, struct device *dev);
-#endif
-extern void eth_header_cache_bind(struct hh_cache ** hhp, struct device *dev,
- unsigned short htype, __u32 daddr);
-extern void eth_header_cache_update(struct hh_cache *hh, struct device *dev, unsigned char * haddr);
-#ifdef MACH
-#define eth_copy_and_sum(skb, src, length, base) \
- memcpy ((skb)->data, src, length)
-#else
-extern void eth_copy_and_sum(struct sk_buff *dest,
- unsigned char *src, int length, int base);
-#endif
-extern struct device * init_etherdev(struct device *, int);
-
-#endif
-
-#endif /* _LINUX_ETHERDEVICE_H */
diff --git a/i386/i386at/gpl/linux/include/linux/fcntl.h b/i386/i386at/gpl/linux/include/linux/fcntl.h
deleted file mode 100644
index 9de3512e..00000000
--- a/i386/i386at/gpl/linux/include/linux/fcntl.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _LINUX_FCNTL_H
-#define _LINUX_FCNTL_H
-
-#include <asm/fcntl.h>
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/fd.h b/i386/i386at/gpl/linux/include/linux/fd.h
deleted file mode 100644
index 87a837b6..00000000
--- a/i386/i386at/gpl/linux/include/linux/fd.h
+++ /dev/null
@@ -1,368 +0,0 @@
-#ifndef _LINUX_FD_H
-#define _LINUX_FD_H
-
-#include <linux/ioctl.h>
-
-/* New file layout: Now the ioctl definitions immediately follow the
- * definitions of the structures that they use */
-
-/*
- * Geometry
- */
-struct floppy_struct {
- unsigned int size, /* nr of sectors total */
- sect, /* sectors per track */
- head, /* nr of heads */
- track, /* nr of tracks */
- stretch; /* !=0 means double track steps */
-#define FD_STRETCH 1
-#define FD_SWAPSIDES 2
-
- unsigned char gap, /* gap1 size */
-
- rate, /* data rate. |= 0x40 for perpendicular */
-#define FD_2M 0x4
-#define FD_SIZECODEMASK 0x38
-#define FD_SIZECODE(floppy) (((((floppy)->rate&FD_SIZECODEMASK)>> 3)+ 2) %8)
-#define FD_SECTSIZE(floppy) ( (floppy)->rate & FD_2M ? \
- 512 : 128 << FD_SIZECODE(floppy) )
-#define FD_PERP 0x40
-
- spec1, /* stepping rate, head unload time */
- fmt_gap; /* gap2 size */
- const char * name; /* used only for predefined formats */
-};
-
-
-/* commands needing write access have 0x40 set */
-/* commands needing super user access have 0x80 set */
-
-#define FDCLRPRM _IO(2, 0x41)
-/* clear user-defined parameters */
-
-#define FDSETPRM _IOW(2, 0x42, struct floppy_struct)
-#define FDSETMEDIAPRM FDSETPRM
-/* set user-defined parameters for current media */
-
-#define FDDEFPRM _IOW(2, 0x43, struct floppy_struct)
-#define FDGETPRM _IOR(2, 0x04, struct floppy_struct)
-#define FDDEFMEDIAPRM FDDEFPRM
-#define FDGETMEDIAPRM FDGETPRM
-/* set/get disk parameters */
-
-
-#define FDMSGON _IO(2,0x45)
-#define FDMSGOFF _IO(2,0x46)
-/* issue/don't issue kernel messages on media type change */
-
-
-/*
- * Formatting (obsolete)
- */
-#define FD_FILL_BYTE 0xF6 /* format fill byte. */
-
-struct format_descr {
- unsigned int device,head,track;
-};
-
-#define FDFMTBEG _IO(2,0x47)
-/* begin formatting a disk */
-#define FDFMTTRK _IOW(2,0x48, struct format_descr)
-/* format the specified track */
-#define FDFMTEND _IO(2,0x49)
-/* end formatting a disk */
-
-
-/*
- * Error thresholds
- */
-struct floppy_max_errors {
- unsigned int
- abort, /* number of errors to be reached before aborting */
- read_track, /* maximal number of errors permitted to read an
- * entire track at once */
- reset, /* maximal number of errors before a reset is tried */
- recal, /* maximal number of errors before a recalibrate is
- * tried */
-
- /*
- * Threshold for reporting FDC errors to the console.
- * Setting this to zero may flood your screen when using
- * ultra cheap floppies ;-)
- */
- reporting;
-
-};
-
-#define FDSETEMSGTRESH _IO(2,0x4a)
-/* set fdc error reporting threshold */
-
-#define FDFLUSH _IO(2,0x4b)
-/* flush buffers for media; either for verifying media, or for
- * handling a media change without closing the file descriptor */
-
-#define FDSETMAXERRS _IOW(2, 0x4c, struct floppy_max_errors)
-#define FDGETMAXERRS _IOR(2, 0x0e, struct floppy_max_errors)
-/* set/get abortion and read_track threshold. See also floppy_drive_params
- * structure */
-
-
-typedef char floppy_drive_name[16];
-#define FDGETDRVTYP _IOR(2, 0x0f, floppy_drive_name)
-/* get drive type: 5 1/4 or 3 1/2 */
-
-
-/*
- * Drive parameters (user modifyable)
- */
-struct floppy_drive_params {
- char cmos; /* cmos type */
-
- /* Spec2 is (HLD<<1 | ND), where HLD is head load time (1=2ms, 2=4 ms
- * etc) and ND is set means no DMA. Hardcoded to 6 (HLD=6ms, use DMA).
- */
- unsigned long max_dtr; /* Step rate, usec */
- unsigned long hlt; /* Head load/settle time, msec */
- unsigned long hut; /* Head unload time (remnant of
- * 8" drives) */
- unsigned long srt; /* Step rate, usec */
-
- unsigned long spinup; /* time needed for spinup (expressed
- * in jiffies) */
- unsigned long spindown; /* timeout needed for spindown */
- unsigned char spindown_offset; /* decides in which position the disk
- * will stop */
- unsigned char select_delay; /* delay to wait after select */
- unsigned char rps; /* rotations per second */
- unsigned char tracks; /* maximum number of tracks */
- unsigned long timeout; /* timeout for interrupt requests */
-
- unsigned char interleave_sect; /* if there are more sectors, use
- * interleave */
-
- struct floppy_max_errors max_errors;
-
- char flags; /* various flags, including ftd_msg */
-/*
- * Announce successful media type detection and media information loss after
- * disk changes.
- * Also used to enable/disable printing of overrun warnings.
- */
-
-#define FTD_MSG 0x10
-#define FD_BROKEN_DCL 0x20
-#define FD_DEBUG 0x02
-#define FD_SILENT_DCL_CLEAR 0x4
-#define FD_INVERTED_DCL 0x80
-
- char read_track; /* use readtrack during probing? */
-
-/*
- * Auto-detection. Each drive type has eight formats which are
- * used in succession to try to read the disk. If the FDC cannot lock onto
- * the disk, the next format is tried. This uses the variable 'probing'.
- */
- short autodetect[8]; /* autodetected formats */
-
- int checkfreq; /* how often should the drive be checked for disk
- * changes */
- int native_format; /* native format of this drive */
-};
-
-enum {
- FD_NEED_TWADDLE_BIT, /* more magic */
- FD_VERIFY_BIT, /* inquire for write protection */
- FD_DISK_NEWCHANGE_BIT, /* change detected, and no action undertaken yet
- * to clear media change status */
- FD_UNUSED_BIT,
- FD_DISK_CHANGED_BIT, /* disk has been changed since last i/o */
- FD_DISK_WRITABLE_BIT /* disk is writable */
-};
-
-#define FDSETDRVPRM _IOW(2, 0x90, struct floppy_drive_params)
-#define FDGETDRVPRM _IOR(2, 0x11, struct floppy_drive_params)
-/* set/get drive parameters */
-
-
-/*
- * Current drive state (not directly modifyable by user, readonly)
- */
-struct floppy_drive_struct {
- signed char flags;
-/* values for these flags */
-#define FD_NEED_TWADDLE (1 << FD_NEED_TWADDLE_BIT)
-#define FD_VERIFY (1 << FD_VERIFY_BIT)
-#define FD_DISK_NEWCHANGE (1 << FD_DISK_NEWCHANGE_BIT)
-#define FD_DISK_CHANGED (1 << FD_DISK_CHANGED_BIT)
-#define FD_DISK_WRITABLE (1 << FD_DISK_WRITABLE_BIT)
-
- unsigned long spinup_date;
- unsigned long select_date;
- unsigned long first_read_date;
- short probed_format;
- short track; /* current track */
- short maxblock; /* id of highest block read */
- short maxtrack; /* id of highest half track read */
- int generation; /* how many diskchanges? */
-
-/*
- * (User-provided) media information is _not_ discarded after a media change
- * if the corresponding keep_data flag is non-zero. Positive values are
- * decremented after each probe.
- */
- int keep_data;
-
- /* Prevent "aliased" accesses. */
- int fd_ref;
- int fd_device;
- int last_checked; /* when was the drive last checked for a disk
- * change? */
-
- char *dmabuf;
- int bufblocks;
-};
-
-#define FDGETDRVSTAT _IOR(2, 0x12, struct floppy_drive_struct)
-#define FDPOLLDRVSTAT _IOR(2, 0x13, struct floppy_drive_struct)
-/* get drive state: GET returns the cached state, POLL polls for new state */
-
-
-/*
- * reset FDC
- */
-enum reset_mode {
- FD_RESET_IF_NEEDED, /* reset only if the reset flags is set */
- FD_RESET_IF_RAWCMD, /* obsolete */
- FD_RESET_ALWAYS /* reset always */
-};
-#define FDRESET _IO(2, 0x54)
-
-
-/*
- * FDC state
- */
-struct floppy_fdc_state {
- int spec1; /* spec1 value last used */
- int spec2; /* spec2 value last used */
- int dtr;
- unsigned char version; /* FDC version code */
- unsigned char dor;
- int address; /* io address */
- unsigned int rawcmd:2;
- unsigned int reset:1;
- unsigned int need_configure:1;
- unsigned int perp_mode:2;
- unsigned int has_fifo:1;
- unsigned int driver_version; /* version code for floppy driver */
-#define FD_DRIVER_VERSION 0x100
-/* user programs using the floppy API should use floppy_fdc_state to
- * get the version number of the floppy driver that they are running
- * on. If this version number is bigger than the one compiled into the
- * user program (the FD_DRIVER_VERSION define), it should be prepared
- * to bigger structures
- */
-
- unsigned char track[4];
- /* Position of the heads of the 4 units attached to this FDC,
- * as stored on the FDC. In the future, the position as stored
- * on the FDC might not agree with the actual physical
- * position of these drive heads. By allowing such
- * disagreement, it will be possible to reset the FDC without
- * incurring the expensive cost of repositioning all heads.
- * Right now, these positions are hard wired to 0. */
-
-};
-
-#define FDGETFDCSTAT _IOR(2, 0x15, struct floppy_fdc_state)
-
-
-/*
- * Asynchronous Write error tracking
- */
-struct floppy_write_errors {
- /* Write error logging.
- *
- * These fields can be cleared with the FDWERRORCLR ioctl.
- * Only writes that were attempted but failed due to a physical media
- * error are logged. write(2) calls that fail and return an error code
- * to the user process are not counted.
- */
-
- unsigned int write_errors; /* number of physical write errors
- * encountered */
-
- /* position of first and last write errors */
- unsigned long first_error_sector;
- int first_error_generation;
- unsigned long last_error_sector;
- int last_error_generation;
-
- unsigned int badness; /* highest retry count for a read or write
- * operation */
-};
-
-#define FDWERRORCLR _IO(2, 0x56)
-/* clear write error and badness information */
-#define FDWERRORGET _IOR(2, 0x17, struct floppy_write_errors)
-/* get write error and badness information */
-
-
-/*
- * Raw commands
- */
-/* new interface flag: now we can do them in batches */
-#define FDHAVEBATCHEDRAWCMD
-
-struct floppy_raw_cmd {
- unsigned int flags;
-#define FD_RAW_READ 1
-#define FD_RAW_WRITE 2
-#define FD_RAW_NO_MOTOR 4
-#define FD_RAW_DISK_CHANGE 4 /* out: disk change flag was set */
-#define FD_RAW_INTR 8 /* wait for an interrupt */
-#define FD_RAW_SPIN 0x10 /* spin up the disk for this command */
-#define FD_RAW_NO_MOTOR_AFTER 0x20 /* switch the motor off after command
- * completion */
-#define FD_RAW_NEED_DISK 0x40 /* this command needs a disk to be present */
-#define FD_RAW_NEED_SEEK 0x80 /* this command uses an implied seek (soft) */
-
-/* more "in" flags */
-#define FD_RAW_MORE 0x100 /* more records follow */
-#define FD_RAW_STOP_IF_FAILURE 0x200 /* stop if we encounter a failure */
-#define FD_RAW_STOP_IF_SUCCESS 0x400 /* stop if command successful */
-#define FD_RAW_SOFTFAILURE 0x800 /* consider the return value for failure
- * detection too */
-
-/* more "out" flags */
-#define FD_RAW_FAILURE 0x10000 /* command sent to fdc, fdc returned error */
-#define FD_RAW_HARDFAILURE 0x20000 /* fdc had to be reset, or timed out */
-
- void *data;
- char *kernel_data; /* location of data buffer in the kernel */
- struct floppy_raw_cmd *next; /* used for chaining of raw cmd's
- * withing the kernel */
- long length; /* in: length of dma transfer. out: remaining bytes */
- long phys_length; /* physical length, if different from dma length */
- int buffer_length; /* length of allocated buffer */
-
- unsigned char rate;
- unsigned char cmd_count;
- unsigned char cmd[16];
- unsigned char reply_count;
- unsigned char reply[16];
- int track;
- int resultcode;
-
- int reserved1;
- int reserved2;
-};
-
-#define FDRAWCMD _IO(2, 0x58)
-/* send a raw command to the fdc. Structure size not included, because of
- * batches */
-
-#define FDTWADDLE _IO(2, 0x59)
-/* flicker motor-on bit before reading a sector. Experimental */
-
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/fdreg.h b/i386/i386at/gpl/linux/include/linux/fdreg.h
deleted file mode 100644
index 03d8893d..00000000
--- a/i386/i386at/gpl/linux/include/linux/fdreg.h
+++ /dev/null
@@ -1,127 +0,0 @@
-#ifndef _LINUX_FDREG_H
-#define _LINUX_FDREG_H
-/*
- * This file contains some defines for the floppy disk controller.
- * Various sources. Mostly "IBM Microcomputers: A Programmers
- * Handbook", Sanches and Canton.
- */
-
-#ifdef FDPATCHES
-
-#define FD_IOPORT fdc_state[fdc].address
-
-/* Fd controller regs. S&C, about page 340 */
-#define FD_STATUS (4 + FD_IOPORT )
-#define FD_DATA (5 + FD_IOPORT )
-
-/* Digital Output Register */
-#define FD_DOR (2 + FD_IOPORT )
-
-/* Digital Input Register (read) */
-#define FD_DIR (7 + FD_IOPORT )
-
-/* Diskette Control Register (write)*/
-#define FD_DCR (7 + FD_IOPORT )
-
-#else
-
-#define FD_STATUS 0x3f4
-#define FD_DATA 0x3f5
-#define FD_DOR 0x3f2 /* Digital Output Register */
-#define FD_DIR 0x3f7 /* Digital Input Register (read) */
-#define FD_DCR 0x3f7 /* Diskette Control Register (write)*/
-
-#endif
-
-/* Bits of main status register */
-#define STATUS_BUSYMASK 0x0F /* drive busy mask */
-#define STATUS_BUSY 0x10 /* FDC busy */
-#define STATUS_DMA 0x20 /* 0- DMA mode */
-#define STATUS_DIR 0x40 /* 0- cpu->fdc */
-#define STATUS_READY 0x80 /* Data reg ready */
-
-/* Bits of FD_ST0 */
-#define ST0_DS 0x03 /* drive select mask */
-#define ST0_HA 0x04 /* Head (Address) */
-#define ST0_NR 0x08 /* Not Ready */
-#define ST0_ECE 0x10 /* Equipment check error */
-#define ST0_SE 0x20 /* Seek end */
-#define ST0_INTR 0xC0 /* Interrupt code mask */
-
-/* Bits of FD_ST1 */
-#define ST1_MAM 0x01 /* Missing Address Mark */
-#define ST1_WP 0x02 /* Write Protect */
-#define ST1_ND 0x04 /* No Data - unreadable */
-#define ST1_OR 0x10 /* OverRun */
-#define ST1_CRC 0x20 /* CRC error in data or addr */
-#define ST1_EOC 0x80 /* End Of Cylinder */
-
-/* Bits of FD_ST2 */
-#define ST2_MAM 0x01 /* Missing Address Mark (again) */
-#define ST2_BC 0x02 /* Bad Cylinder */
-#define ST2_SNS 0x04 /* Scan Not Satisfied */
-#define ST2_SEH 0x08 /* Scan Equal Hit */
-#define ST2_WC 0x10 /* Wrong Cylinder */
-#define ST2_CRC 0x20 /* CRC error in data field */
-#define ST2_CM 0x40 /* Control Mark = deleted */
-
-/* Bits of FD_ST3 */
-#define ST3_HA 0x04 /* Head (Address) */
-#define ST3_DS 0x08 /* drive is double-sided */
-#define ST3_TZ 0x10 /* Track Zero signal (1=track 0) */
-#define ST3_RY 0x20 /* drive is ready */
-#define ST3_WP 0x40 /* Write Protect */
-#define ST3_FT 0x80 /* Drive Fault */
-
-/* Values for FD_COMMAND */
-#define FD_RECALIBRATE 0x07 /* move to track 0 */
-#define FD_SEEK 0x0F /* seek track */
-#define FD_READ 0xE6 /* read with MT, MFM, SKip deleted */
-#define FD_WRITE 0xC5 /* write with MT, MFM */
-#define FD_SENSEI 0x08 /* Sense Interrupt Status */
-#define FD_SPECIFY 0x03 /* specify HUT etc */
-#define FD_FORMAT 0x4D /* format one track */
-#define FD_VERSION 0x10 /* get version code */
-#define FD_CONFIGURE 0x13 /* configure FIFO operation */
-#define FD_PERPENDICULAR 0x12 /* perpendicular r/w mode */
-#define FD_GETSTATUS 0x04 /* read ST3 */
-#define FD_DUMPREGS 0x0E /* dump the contents of the fdc regs */
-#define FD_READID 0xEA /* prints the header of a sector */
-#define FD_UNLOCK 0x14 /* Fifo config unlock */
-#define FD_LOCK 0x94 /* Fifo config lock */
-#define FD_RSEEK_OUT 0x8f /* seek out (i.e. to lower tracks) */
-#define FD_RSEEK_IN 0xcf /* seek in (i.e. to higher tracks) */
-#define FD_PARTID 0x18 /* part id ("extended" version cmd) */
-#define FD_SAVE 0x2e /* save fdc regs for later restore */
-
-/* DMA commands */
-#define DMA_READ 0x46
-#define DMA_WRITE 0x4A
-
-/* FDC version return types */
-#define FDC_NONE 0x00
-#define FDC_UNKNOWN 0x10 /* DO NOT USE THIS TYPE EXCEPT IF IDENTIFICATION
- FAILS EARLY */
-#define FDC_8272A 0x20 /* Intel 8272a, NEC 765 */
-#define FDC_765ED 0x30 /* Non-Intel 1MB-compatible FDC, can't detect */
-#define FDC_82072 0x40 /* Intel 82072; 8272a + FIFO + DUMPREGS */
-#define FDC_82077_ORIG 0x50 /* Original version of 82077AA, sans LOCK */
-#define FDC_82077 0x52 /* 82077AA-1 */
-#define FDC_82077_UNKN 0x53 /* Unknown 82077 variant */
-#define FDC_82078 0x60 /* 44pin 82078 or 64pin 82078SL */
-#define FDC_82078_1 0x61 /* 82078-1 (2Mbps fdc) */
-#define FDC_S82078B 0x62 /* S82078B (first seen on Adaptec AVA-2825 VLB
- * SCSI/EIDE/Floppy controller) */
-#define FDC_87306 0x63 /* National Semiconductor PC 87306 */
-
-/*
- * Beware: the fdc type list is roughly sorted by increasing features.
- * Presence of features is tested by comparing the FDC version id with the
- * "oldest" version that has the needed feature.
- * If during FDC detection, an obscure test fails late in the sequence, don't
- * assign FDC_UNKNOWN. Else the FDC will be treated as a dumb 8272a, or worse.
- * This is especially true if the tests are unneeded.
- */
-
-#define FD_RESET_DELAY 20
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/fs.h b/i386/i386at/gpl/linux/include/linux/fs.h
deleted file mode 100644
index 278aa361..00000000
--- a/i386/i386at/gpl/linux/include/linux/fs.h
+++ /dev/null
@@ -1,698 +0,0 @@
-#ifndef _LINUX_FS_H
-#define _LINUX_FS_H
-
-/*
- * This file has definitions for some important file table
- * structures etc.
- */
-
-#include <linux/linkage.h>
-#include <linux/limits.h>
-#include <linux/wait.h>
-#include <linux/types.h>
-#include <linux/vfs.h>
-#include <linux/net.h>
-#include <linux/kdev_t.h>
-#include <linux/ioctl.h>
-
-/*
- * It's silly to have NR_OPEN bigger than NR_FILE, but I'll fix
- * that later. Anyway, now the file code is no longer dependent
- * on bitmaps in unsigned longs, but uses the new fd_set structure..
- *
- * Some programs (notably those using select()) may have to be
- * recompiled to take full advantage of the new limits..
- */
-
-/* Fixed constants first: */
-#undef NR_OPEN
-#define NR_OPEN 256
-
-#define NR_SUPER 64
-#define NR_IHASH 131
-#define BLOCK_SIZE 1024
-#define BLOCK_SIZE_BITS 10
-
-/* And dynamically-tunable limits and defaults: */
-extern int max_inodes, nr_inodes;
-extern int max_files, nr_files;
-#define NR_INODE 2048 /* this should be bigger than NR_FILE */
-#define NR_FILE 1024 /* this can well be larger on a larger system */
-
-#define MAY_EXEC 1
-#define MAY_WRITE 2
-#define MAY_READ 4
-
-#define FMODE_READ 1
-#define FMODE_WRITE 2
-
-#define READ 0
-#define WRITE 1
-#define READA 2 /* read-ahead - don't pause */
-#define WRITEA 3 /* "write-ahead" - silly, but somewhat useful */
-
-#ifndef NULL
-#define NULL ((void *) 0)
-#endif
-
-#define NIL_FILP ((struct file *)0)
-#define SEL_IN 1
-#define SEL_OUT 2
-#define SEL_EX 4
-
-/*
- * These are the fs-independent mount-flags: up to 16 flags are supported
- */
-#define MS_RDONLY 1 /* Mount read-only */
-#define MS_NOSUID 2 /* Ignore suid and sgid bits */
-#define MS_NODEV 4 /* Disallow access to device special files */
-#define MS_NOEXEC 8 /* Disallow program execution */
-#define MS_SYNCHRONOUS 16 /* Writes are synced at once */
-#define MS_REMOUNT 32 /* Alter flags of a mounted FS */
-#define S_WRITE 128 /* Write on file/directory/symlink */
-#define S_APPEND 256 /* Append-only file */
-#define S_IMMUTABLE 512 /* Immutable file */
-
-/*
- * Flags that can be altered by MS_REMOUNT
- */
-#define MS_RMT_MASK (MS_RDONLY)
-
-/*
- * Magic mount flag number. Has to be or-ed to the flag values.
- */
-#define MS_MGC_VAL 0xC0ED0000 /* magic flag number to indicate "new" flags */
-#define MS_MGC_MSK 0xffff0000 /* magic flag number mask */
-
-/*
- * Note that read-only etc flags are inode-specific: setting some file-system
- * flags just means all the inodes inherit those flags by default. It might be
- * possible to override it selectively if you really wanted to with some
- * ioctl() that is not currently implemented.
- *
- * Exception: MS_RDONLY is always applied to the entire file system.
- */
-#define IS_RDONLY(inode) (((inode)->i_sb) && ((inode)->i_sb->s_flags & MS_RDONLY))
-#define IS_NOSUID(inode) ((inode)->i_flags & MS_NOSUID)
-#define IS_NODEV(inode) ((inode)->i_flags & MS_NODEV)
-#define IS_NOEXEC(inode) ((inode)->i_flags & MS_NOEXEC)
-#define IS_SYNC(inode) ((inode)->i_flags & MS_SYNCHRONOUS)
-
-#define IS_WRITABLE(inode) ((inode)->i_flags & S_WRITE)
-#define IS_APPEND(inode) ((inode)->i_flags & S_APPEND)
-#define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE)
-
-/* the read-only stuff doesn't really belong here, but any other place is
- probably as bad and I don't want to create yet another include file. */
-
-#define BLKROSET _IO(0x12,93) /* set device read-only (0 = read-write) */
-#define BLKROGET _IO(0x12,94) /* get read-only status (0 = read_write) */
-#define BLKRRPART _IO(0x12,95) /* re-read partition table */
-#define BLKGETSIZE _IO(0x12,96) /* return device size */
-#define BLKFLSBUF _IO(0x12,97) /* flush buffer cache */
-#define BLKRASET _IO(0x12,98) /* Set read ahead for block device */
-#define BLKRAGET _IO(0x12,99) /* get current read ahead setting */
-
-#define BMAP_IOCTL 1 /* obsolete - kept for compatibility */
-#define FIBMAP _IO(0x00,1) /* bmap access */
-#define FIGETBSZ _IO(0x00,2) /* get the block size used for bmap */
-
-#ifdef __KERNEL__
-
-#include <asm/bitops.h>
-
-extern void buffer_init(void);
-extern unsigned long inode_init(unsigned long start, unsigned long end);
-extern unsigned long file_table_init(unsigned long start, unsigned long end);
-extern unsigned long name_cache_init(unsigned long start, unsigned long end);
-
-typedef char buffer_block[BLOCK_SIZE];
-
-/* bh state bits */
-#define BH_Uptodate 0 /* 1 if the buffer contains valid data */
-#define BH_Dirty 1 /* 1 if the buffer is dirty */
-#define BH_Lock 2 /* 1 if the buffer is locked */
-#define BH_Req 3 /* 0 if the buffer has been invalidated */
-#define BH_Touched 4 /* 1 if the buffer has been touched (aging) */
-#define BH_Has_aged 5 /* 1 if the buffer has been aged (aging) */
-#define BH_Protected 6 /* 1 if the buffer is protected */
-#define BH_FreeOnIO 7 /* 1 to discard the buffer_head after IO */
-
-/*
- * Try to keep the most commonly used fields in single cache lines (16
- * bytes) to improve performance. This ordering should be
- * particularly beneficial on 32-bit processors.
- *
- * We use the first 16 bytes for the data which is used in searches
- * over the block hash lists (ie. getblk(), find_buffer() and
- * friends).
- *
- * The second 16 bytes we use for lru buffer scans, as used by
- * sync_buffers() and refill_freelist(). -- sct
- */
-struct buffer_head {
- /* First cache line: */
- unsigned long b_blocknr; /* block number */
- kdev_t b_dev; /* device (B_FREE = free) */
- struct buffer_head * b_next; /* Hash queue list */
- struct buffer_head * b_this_page; /* circular list of buffers in one page */
-
- /* Second cache line: */
- unsigned long b_state; /* buffer state bitmap (see above) */
- struct buffer_head * b_next_free;
- unsigned int b_count; /* users using this block */
- unsigned long b_size; /* block size */
-
- /* Non-performance-critical data follows. */
- char * b_data; /* pointer to data block (1024 bytes) */
- unsigned int b_list; /* List that this buffer appears */
- unsigned long b_flushtime; /* Time when this (dirty) buffer
- * should be written */
- unsigned long b_lru_time; /* Time when this buffer was
- * last used. */
- struct wait_queue * b_wait;
- struct buffer_head * b_prev; /* doubly linked list of hash-queue */
- struct buffer_head * b_prev_free; /* doubly linked list of buffers */
- struct buffer_head * b_reqnext; /* request queue */
-};
-
-static inline int buffer_uptodate(struct buffer_head * bh)
-{
- return test_bit(BH_Uptodate, &bh->b_state);
-}
-
-static inline int buffer_dirty(struct buffer_head * bh)
-{
- return test_bit(BH_Dirty, &bh->b_state);
-}
-
-static inline int buffer_locked(struct buffer_head * bh)
-{
- return test_bit(BH_Lock, &bh->b_state);
-}
-
-static inline int buffer_req(struct buffer_head * bh)
-{
- return test_bit(BH_Req, &bh->b_state);
-}
-
-static inline int buffer_touched(struct buffer_head * bh)
-{
- return test_bit(BH_Touched, &bh->b_state);
-}
-
-static inline int buffer_has_aged(struct buffer_head * bh)
-{
- return test_bit(BH_Has_aged, &bh->b_state);
-}
-
-static inline int buffer_protected(struct buffer_head * bh)
-{
- return test_bit(BH_Protected, &bh->b_state);
-}
-
-#ifndef MACH
-#include <linux/pipe_fs_i.h>
-#include <linux/minix_fs_i.h>
-#include <linux/ext_fs_i.h>
-#include <linux/ext2_fs_i.h>
-#include <linux/hpfs_fs_i.h>
-#include <linux/msdos_fs_i.h>
-#include <linux/umsdos_fs_i.h>
-#include <linux/iso_fs_i.h>
-#include <linux/nfs_fs_i.h>
-#include <linux/xia_fs_i.h>
-#include <linux/sysv_fs_i.h>
-#endif
-
-/*
- * Attribute flags. These should be or-ed together to figure out what
- * has been changed!
- */
-#define ATTR_MODE 1
-#define ATTR_UID 2
-#define ATTR_GID 4
-#define ATTR_SIZE 8
-#define ATTR_ATIME 16
-#define ATTR_MTIME 32
-#define ATTR_CTIME 64
-#define ATTR_ATIME_SET 128
-#define ATTR_MTIME_SET 256
-#define ATTR_FORCE 512 /* Not a change, but a change it */
-
-/*
- * This is the Inode Attributes structure, used for notify_change(). It
- * uses the above definitions as flags, to know which values have changed.
- * Also, in this manner, a Filesystem can look at only the values it cares
- * about. Basically, these are the attributes that the VFS layer can
- * request to change from the FS layer.
- *
- * Derek Atkins <warlord@MIT.EDU> 94-10-20
- */
-struct iattr {
- unsigned int ia_valid;
- umode_t ia_mode;
- uid_t ia_uid;
- gid_t ia_gid;
- off_t ia_size;
- time_t ia_atime;
- time_t ia_mtime;
- time_t ia_ctime;
-};
-
-#include <linux/quota.h>
-
-#ifdef MACH
-struct inode
-{
- umode_t i_mode;
- kdev_t i_rdev;
-};
-
-struct file
-{
- mode_t f_mode;
- loff_t f_pos;
- unsigned short f_flags;
- int f_resid;
- void *f_object;
- void *f_np;
-};
-
-struct vm_area_struct;
-struct page;
-#else /* ! MACH */
-struct inode {
- kdev_t i_dev;
- unsigned long i_ino;
- umode_t i_mode;
- nlink_t i_nlink;
- uid_t i_uid;
- gid_t i_gid;
- kdev_t i_rdev;
- off_t i_size;
- time_t i_atime;
- time_t i_mtime;
- time_t i_ctime;
- unsigned long i_blksize;
- unsigned long i_blocks;
- unsigned long i_version;
- unsigned long i_nrpages;
- struct semaphore i_sem;
- struct inode_operations *i_op;
- struct super_block *i_sb;
- struct wait_queue *i_wait;
- struct file_lock *i_flock;
- struct vm_area_struct *i_mmap;
- struct page *i_pages;
- struct dquot *i_dquot[MAXQUOTAS];
- struct inode *i_next, *i_prev;
- struct inode *i_hash_next, *i_hash_prev;
- struct inode *i_bound_to, *i_bound_by;
- struct inode *i_mount;
- unsigned short i_count;
- unsigned short i_flags;
- unsigned char i_lock;
- unsigned char i_dirt;
- unsigned char i_pipe;
- unsigned char i_sock;
- unsigned char i_seek;
- unsigned char i_update;
- unsigned short i_writecount;
- union {
- struct pipe_inode_info pipe_i;
- struct minix_inode_info minix_i;
- struct ext_inode_info ext_i;
- struct ext2_inode_info ext2_i;
- struct hpfs_inode_info hpfs_i;
- struct msdos_inode_info msdos_i;
- struct umsdos_inode_info umsdos_i;
- struct iso_inode_info isofs_i;
- struct nfs_inode_info nfs_i;
- struct xiafs_inode_info xiafs_i;
- struct sysv_inode_info sysv_i;
- struct socket socket_i;
- void * generic_ip;
- } u;
-};
-
-struct file {
- mode_t f_mode;
- loff_t f_pos;
- unsigned short f_flags;
- unsigned short f_count;
- off_t f_reada;
- struct file *f_next, *f_prev;
- int f_owner; /* pid or -pgrp where SIGIO should be sent */
- struct inode * f_inode;
- struct file_operations * f_op;
- unsigned long f_version;
- void *private_data; /* needed for tty driver, and maybe others */
-};
-#endif /* ! MACH */
-
-struct file_lock {
- struct file_lock *fl_next; /* singly linked list for this inode */
- struct file_lock *fl_nextlink; /* doubly linked list of all locks */
- struct file_lock *fl_prevlink; /* used to simplify lock removal */
- struct file_lock *fl_block;
- struct task_struct *fl_owner;
- struct wait_queue *fl_wait;
- struct file *fl_file;
- char fl_flags;
- char fl_type;
- off_t fl_start;
- off_t fl_end;
-};
-
-struct fasync_struct {
- int magic;
- struct fasync_struct *fa_next; /* singly linked list */
- struct file *fa_file;
-};
-
-#define FASYNC_MAGIC 0x4601
-
-extern int fasync_helper(struct inode *, struct file *, int, struct fasync_struct **);
-
-#ifndef MACH
-#include <linux/minix_fs_sb.h>
-#include <linux/ext_fs_sb.h>
-#include <linux/ext2_fs_sb.h>
-#include <linux/hpfs_fs_sb.h>
-#include <linux/msdos_fs_sb.h>
-#include <linux/iso_fs_sb.h>
-#include <linux/nfs_fs_sb.h>
-#include <linux/xia_fs_sb.h>
-#include <linux/sysv_fs_sb.h>
-
-struct super_block {
- kdev_t s_dev;
- unsigned long s_blocksize;
- unsigned char s_blocksize_bits;
- unsigned char s_lock;
- unsigned char s_rd_only;
- unsigned char s_dirt;
- struct file_system_type *s_type;
- struct super_operations *s_op;
- struct dquot_operations *dq_op;
- unsigned long s_flags;
- unsigned long s_magic;
- unsigned long s_time;
- struct inode * s_covered;
- struct inode * s_mounted;
- struct wait_queue * s_wait;
- union {
- struct minix_sb_info minix_sb;
- struct ext_sb_info ext_sb;
- struct ext2_sb_info ext2_sb;
- struct hpfs_sb_info hpfs_sb;
- struct msdos_sb_info msdos_sb;
- struct isofs_sb_info isofs_sb;
- struct nfs_sb_info nfs_sb;
- struct xiafs_sb_info xiafs_sb;
- struct sysv_sb_info sysv_sb;
- void *generic_sbp;
- } u;
-};
-#endif /* ! MACH */
-
-/*
- * This is the "filldir" function type, used by readdir() to let
- * the kernel specify what kind of dirent layout it wants to have.
- * This allows the kernel to read directories into kernel space or
- * to have different dirent layouts depending on the binary type.
- */
-typedef int (*filldir_t)(void *, const char *, int, off_t, ino_t);
-
-struct file_operations {
- int (*lseek) (struct inode *, struct file *, off_t, int);
- int (*read) (struct inode *, struct file *, char *, int);
- int (*write) (struct inode *, struct file *, const char *, int);
- int (*readdir) (struct inode *, struct file *, void *, filldir_t);
- int (*select) (struct inode *, struct file *, int, select_table *);
- int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
- int (*mmap) (struct inode *, struct file *, struct vm_area_struct *);
- int (*open) (struct inode *, struct file *);
- void (*release) (struct inode *, struct file *);
- int (*fsync) (struct inode *, struct file *);
- int (*fasync) (struct inode *, struct file *, int);
- int (*check_media_change) (kdev_t dev);
- int (*revalidate) (kdev_t dev);
-};
-
-struct inode_operations {
- struct file_operations * default_file_ops;
- int (*create) (struct inode *,const char *,int,int,struct inode **);
- int (*lookup) (struct inode *,const char *,int,struct inode **);
- int (*link) (struct inode *,struct inode *,const char *,int);
- int (*unlink) (struct inode *,const char *,int);
- int (*symlink) (struct inode *,const char *,int,const char *);
- int (*mkdir) (struct inode *,const char *,int,int);
- int (*rmdir) (struct inode *,const char *,int);
- int (*mknod) (struct inode *,const char *,int,int,int);
- int (*rename) (struct inode *,const char *,int,struct inode *,const char *,int);
- int (*readlink) (struct inode *,char *,int);
- int (*follow_link) (struct inode *,struct inode *,int,int,struct inode **);
- int (*readpage) (struct inode *, struct page *);
- int (*writepage) (struct inode *, struct page *);
- int (*bmap) (struct inode *,int);
- void (*truncate) (struct inode *);
- int (*permission) (struct inode *, int);
- int (*smap) (struct inode *,int);
-};
-
-struct super_operations {
- void (*read_inode) (struct inode *);
- int (*notify_change) (struct inode *, struct iattr *);
- void (*write_inode) (struct inode *);
- void (*put_inode) (struct inode *);
- void (*put_super) (struct super_block *);
- void (*write_super) (struct super_block *);
- void (*statfs) (struct super_block *, struct statfs *, int);
- int (*remount_fs) (struct super_block *, int *, char *);
-};
-
-struct dquot_operations {
- void (*initialize) (struct inode *, short);
- void (*drop) (struct inode *);
- int (*alloc_block) (const struct inode *, unsigned long);
- int (*alloc_inode) (const struct inode *, unsigned long);
- void (*free_block) (const struct inode *, unsigned long);
- void (*free_inode) (const struct inode *, unsigned long);
- int (*transfer) (struct inode *, struct iattr *, char);
-};
-
-struct file_system_type {
- struct super_block *(*read_super) (struct super_block *, void *, int);
- const char *name;
- int requires_dev;
- struct file_system_type * next;
-};
-
-extern int register_filesystem(struct file_system_type *);
-extern int unregister_filesystem(struct file_system_type *);
-
-asmlinkage int sys_open(const char *, int, int);
-asmlinkage int sys_close(unsigned int); /* yes, it's really unsigned */
-
-extern void kill_fasync(struct fasync_struct *fa, int sig);
-
-extern int getname(const char * filename, char **result);
-extern void putname(char * name);
-extern int do_truncate(struct inode *, unsigned long);
-extern int register_blkdev(unsigned int, const char *, struct file_operations *);
-extern int unregister_blkdev(unsigned int major, const char * name);
-extern int blkdev_open(struct inode * inode, struct file * filp);
-extern struct file_operations def_blk_fops;
-extern struct inode_operations blkdev_inode_operations;
-
-extern int register_chrdev(unsigned int, const char *, struct file_operations *);
-extern int unregister_chrdev(unsigned int major, const char * name);
-extern int chrdev_open(struct inode * inode, struct file * filp);
-extern struct file_operations def_chr_fops;
-extern struct inode_operations chrdev_inode_operations;
-
-extern void init_fifo(struct inode * inode);
-
-extern struct file_operations connecting_fifo_fops;
-extern struct file_operations read_fifo_fops;
-extern struct file_operations write_fifo_fops;
-extern struct file_operations rdwr_fifo_fops;
-extern struct file_operations read_pipe_fops;
-extern struct file_operations write_pipe_fops;
-extern struct file_operations rdwr_pipe_fops;
-
-extern struct file_system_type *get_fs_type(const char *name);
-
-extern int fs_may_mount(kdev_t dev);
-extern int fs_may_umount(kdev_t dev, struct inode * mount_root);
-extern int fs_may_remount_ro(kdev_t dev);
-
-extern struct file *first_file;
-extern struct super_block super_blocks[NR_SUPER];
-
-extern void refile_buffer(struct buffer_head * buf);
-extern void set_writetime(struct buffer_head * buf, int flag);
-extern void refill_freelist(int size);
-extern int try_to_free_buffer(struct buffer_head*, struct buffer_head**, int);
-
-extern struct buffer_head ** buffer_pages;
-extern int nr_buffers;
-extern int buffermem;
-extern int nr_buffer_heads;
-
-#define BUF_CLEAN 0
-#define BUF_UNSHARED 1 /* Buffers that were shared but are not any more */
-#define BUF_LOCKED 2 /* Buffers scheduled for write */
-#define BUF_LOCKED1 3 /* Supers, inodes */
-#define BUF_DIRTY 4 /* Dirty buffers, not yet scheduled for write */
-#define BUF_SHARED 5 /* Buffers shared */
-#define NR_LIST 6
-
-#ifdef MACH
-extern inline void
-mark_buffer_uptodate (struct buffer_head *bh, int on)
-{
- if (on)
- set_bit (BH_Uptodate, &bh->b_state);
- else
- clear_bit (BH_Uptodate, &bh->b_state);
-}
-#else
-void mark_buffer_uptodate(struct buffer_head * bh, int on);
-#endif
-
-extern inline void mark_buffer_clean(struct buffer_head * bh)
-{
-#ifdef MACH
- clear_bit(BH_Dirty, &bh->b_state);
-#else
- if (clear_bit(BH_Dirty, &bh->b_state)) {
- if (bh->b_list == BUF_DIRTY)
- refile_buffer(bh);
- }
-#endif
-}
-
-extern inline void mark_buffer_dirty(struct buffer_head * bh, int flag)
-{
-#ifdef MACH
- set_bit(BH_Dirty, &bh->b_state);
-#else
- if (!set_bit(BH_Dirty, &bh->b_state)) {
- set_writetime(bh, flag);
- if (bh->b_list != BUF_DIRTY)
- refile_buffer(bh);
- }
-#endif
-}
-
-extern int check_disk_change(kdev_t dev);
-#ifdef MACH
-#define invalidate_inodes(dev)
-#else
-extern void invalidate_inodes(kdev_t dev);
-#endif
-extern void invalidate_inode_pages(struct inode *, unsigned long);
-#ifdef MACH
-#define invalidate_buffers(dev)
-#else
-extern void invalidate_buffers(kdev_t dev);
-#endif
-extern int floppy_is_wp(int minor);
-extern void sync_inodes(kdev_t dev);
-#ifdef MACH
-#define sync_dev(dev)
-#define fsync_dev(dev)
-#else
-extern void sync_dev(kdev_t dev);
-extern int fsync_dev(kdev_t dev);
-#endif
-extern void sync_supers(kdev_t dev);
-extern int bmap(struct inode * inode,int block);
-extern int notify_change(struct inode *, struct iattr *);
-extern int namei(const char * pathname, struct inode ** res_inode);
-extern int lnamei(const char * pathname, struct inode ** res_inode);
-#ifdef MACH
-#define permission(i, m) 0
-#else
-extern int permission(struct inode * inode,int mask);
-#endif
-extern int get_write_access(struct inode *inode);
-extern void put_write_access(struct inode *inode);
-extern int open_namei(const char * pathname, int flag, int mode,
- struct inode ** res_inode, struct inode * base);
-extern int do_mknod(const char * filename, int mode, dev_t dev);
-extern int do_pipe(int *);
-extern void iput(struct inode * inode);
-extern struct inode * __iget(struct super_block * sb,int nr,int crsmnt);
-extern struct inode * get_empty_inode(void);
-extern void insert_inode_hash(struct inode *);
-extern void clear_inode(struct inode *);
-extern struct inode * get_pipe_inode(void);
-extern struct file * get_empty_filp(void);
-extern int close_fp(struct file *filp);
-extern struct buffer_head * get_hash_table(kdev_t dev, int block, int size);
-extern struct buffer_head * getblk(kdev_t dev, int block, int size);
-extern void ll_rw_block(int rw, int nr, struct buffer_head * bh[]);
-extern void ll_rw_page(int rw, kdev_t dev, unsigned long nr, char * buffer);
-extern void ll_rw_swap_file(int rw, kdev_t dev, unsigned int *b, int nb, char *buffer);
-extern int is_read_only(kdev_t dev);
-extern void __brelse(struct buffer_head *buf);
-extern inline void brelse(struct buffer_head *buf)
-{
- if (buf)
- __brelse(buf);
-}
-extern void __bforget(struct buffer_head *buf);
-extern inline void bforget(struct buffer_head *buf)
-{
- if (buf)
- __bforget(buf);
-}
-extern void set_blocksize(kdev_t dev, int size);
-extern struct buffer_head * bread(kdev_t dev, int block, int size);
-extern struct buffer_head * breada(kdev_t dev,int block, int size,
- unsigned int pos, unsigned int filesize);
-
-extern int generic_readpage(struct inode *, struct page *);
-extern int generic_file_read(struct inode *, struct file *, char *, int);
-extern int generic_mmap(struct inode *, struct file *, struct vm_area_struct *);
-extern int brw_page(int, unsigned long, kdev_t, int [], int, int);
-
-extern void put_super(kdev_t dev);
-unsigned long generate_cluster(kdev_t dev, int b[], int size);
-extern kdev_t ROOT_DEV;
-
-extern void show_buffers(void);
-extern void mount_root(void);
-
-extern int char_read(struct inode *, struct file *, char *, int);
-extern int block_read(struct inode *, struct file *, char *, int);
-extern int read_ahead[];
-
-extern int char_write(struct inode *, struct file *, const char *, int);
-extern int block_write(struct inode *, struct file *, const char *, int);
-
-extern int block_fsync(struct inode *, struct file *);
-extern int file_fsync(struct inode *, struct file *);
-
-extern void dcache_add(struct inode *, const char *, int, unsigned long);
-extern int dcache_lookup(struct inode *, const char *, int, unsigned long *);
-
-extern int inode_change_ok(struct inode *, struct iattr *);
-extern void inode_setattr(struct inode *, struct iattr *);
-
-extern inline struct inode * iget(struct super_block * sb,int nr)
-{
- return __iget(sb, nr, 1);
-}
-
-/* kludge to get SCSI modules working */
-#include <linux/minix_fs.h>
-#include <linux/minix_fs_sb.h>
-
-#endif /* __KERNEL__ */
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/genhd.h b/i386/i386at/gpl/linux/include/linux/genhd.h
deleted file mode 100644
index e1c5888d..00000000
--- a/i386/i386at/gpl/linux/include/linux/genhd.h
+++ /dev/null
@@ -1,73 +0,0 @@
-#ifndef _LINUX_GENHD_H
-#define _LINUX_GENHD_H
-
-/*
- * genhd.h Copyright (C) 1992 Drew Eckhardt
- * Generic hard disk header file by
- * Drew Eckhardt
- *
- * <drew@colorado.edu>
- */
-
-#define CONFIG_MSDOS_PARTITION 1
-
-#ifdef __alpha__
-#define CONFIG_OSF_PARTITION 1
-#endif
-
-#ifdef __sparc__
-#define CONFIG_SUN_PARTITION 1
-#endif
-
-/* These two have identical behaviour; use the second one if DOS fdisk gets
- confused about extended/logical partitions starting past cylinder 1023. */
-#define DOS_EXTENDED_PARTITION 5
-#define LINUX_EXTENDED_PARTITION 0x85
-
-#define DM6_PARTITION 0x54 /* has DDO: use xlated geom & offset */
-#define EZD_PARTITION 0x55 /* EZ-DRIVE: same as DM6 (we think) */
-#define DM6_AUX1PARTITION 0x51 /* no DDO: use xlated geom */
-#define DM6_AUX3PARTITION 0x53 /* no DDO: use xlated geom */
-
-#ifdef MACH_INCLUDE
-struct linux_partition {
-#else
-struct partition {
-#endif
- unsigned char boot_ind; /* 0x80 - active */
- unsigned char head; /* starting head */
- unsigned char sector; /* starting sector */
- unsigned char cyl; /* starting cylinder */
- unsigned char sys_ind; /* What partition type */
- unsigned char end_head; /* end head */
- unsigned char end_sector; /* end sector */
- unsigned char end_cyl; /* end cylinder */
- unsigned int start_sect; /* starting sector counting from 0 */
- unsigned int nr_sects; /* nr of sectors in partition */
-};
-
-struct hd_struct {
- long start_sect;
- long nr_sects;
-};
-
-struct gendisk {
- int major; /* major number of driver */
- const char *major_name; /* name of major driver */
- int minor_shift; /* number of times minor is shifted to
- get real minor */
- int max_p; /* maximum partitions per device */
- int max_nr; /* maximum number of real devices */
-
- void (*init)(struct gendisk *); /* Initialization called before we do our thing */
- struct hd_struct *part; /* partition table */
- int *sizes; /* device size in blocks, copied to blk_size[] */
- int nr_real; /* number of real devices */
-
- void *real_devices; /* internal use */
- struct gendisk *next;
-};
-
-extern struct gendisk *gendisk_head; /* linked list of disks */
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/hdreg.h b/i386/i386at/gpl/linux/include/linux/hdreg.h
deleted file mode 100644
index 58a9a5df..00000000
--- a/i386/i386at/gpl/linux/include/linux/hdreg.h
+++ /dev/null
@@ -1,171 +0,0 @@
-#ifndef _LINUX_HDREG_H
-#define _LINUX_HDREG_H
-
-/*
- * This file contains some defines for the AT-hd-controller.
- * Various sources.
- */
-
-#define HD_IRQ 14 /* the standard disk interrupt */
-
-/* ide.c has it's own port definitions in "ide.h" */
-
-/* Hd controller regs. Ref: IBM AT Bios-listing */
-#define HD_DATA 0x1f0 /* _CTL when writing */
-#define HD_ERROR 0x1f1 /* see err-bits */
-#define HD_NSECTOR 0x1f2 /* nr of sectors to read/write */
-#define HD_SECTOR 0x1f3 /* starting sector */
-#define HD_LCYL 0x1f4 /* starting cylinder */
-#define HD_HCYL 0x1f5 /* high byte of starting cyl */
-#define HD_CURRENT 0x1f6 /* 101dhhhh , d=drive, hhhh=head */
-#define HD_STATUS 0x1f7 /* see status-bits */
-#define HD_FEATURE HD_ERROR /* same io address, read=error, write=feature */
-#define HD_PRECOMP HD_FEATURE /* obsolete use of this port - predates IDE */
-#define HD_COMMAND HD_STATUS /* same io address, read=status, write=cmd */
-
-#define HD_CMD 0x3f6 /* used for resets */
-#define HD_ALTSTATUS 0x3f6 /* same as HD_STATUS but doesn't clear irq */
-
-/* remainder is shared between hd.c, ide.c, ide-cd.c, and the hdparm utility */
-
-/* Bits of HD_STATUS */
-#define ERR_STAT 0x01
-#define INDEX_STAT 0x02
-#define ECC_STAT 0x04 /* Corrected error */
-#define DRQ_STAT 0x08
-#define SEEK_STAT 0x10
-#define WRERR_STAT 0x20
-#define READY_STAT 0x40
-#define BUSY_STAT 0x80
-
-/* Values for HD_COMMAND */
-#define WIN_RESTORE 0x10
-#define WIN_READ 0x20
-#define WIN_WRITE 0x30
-#define WIN_VERIFY 0x40
-#define WIN_FORMAT 0x50
-#define WIN_INIT 0x60
-#define WIN_SEEK 0x70
-#define WIN_DIAGNOSE 0x90
-#define WIN_SPECIFY 0x91 /* set drive geometry translation */
-#define WIN_SETIDLE1 0xE3
-#define WIN_SETIDLE2 0x97
-
-#define WIN_DOORLOCK 0xde /* lock door on removeable drives */
-#define WIN_DOORUNLOCK 0xdf /* unlock door on removeable drives */
-
-#define WIN_MULTREAD 0xC4 /* read sectors using multiple mode */
-#define WIN_MULTWRITE 0xC5 /* write sectors using multiple mode */
-#define WIN_SETMULT 0xC6 /* enable/disable multiple mode */
-#define WIN_IDENTIFY 0xEC /* ask drive to identify itself */
-#define WIN_SETFEATURES 0xEF /* set special drive features */
-#define WIN_READDMA 0xc8 /* read sectors using DMA transfers */
-#define WIN_WRITEDMA 0xca /* write sectors using DMA transfers */
-
-/* Additional drive command codes used by ATAPI devices. */
-#define WIN_PIDENTIFY 0xA1 /* identify ATAPI device */
-#define WIN_SRST 0x08 /* ATAPI soft reset command */
-#define WIN_PACKETCMD 0xa0 /* Send a packet command. */
-
-/* Bits for HD_ERROR */
-#define MARK_ERR 0x01 /* Bad address mark */
-#define TRK0_ERR 0x02 /* couldn't find track 0 */
-#define ABRT_ERR 0x04 /* Command aborted */
-#define ID_ERR 0x10 /* ID field not found */
-#define ECC_ERR 0x40 /* Uncorrectable ECC error */
-#define BBD_ERR 0x80 /* block marked bad */
-
-struct hd_geometry {
- unsigned char heads;
- unsigned char sectors;
- unsigned short cylinders;
- unsigned long start;
-};
-
-/* hd/ide ctl's that pass (arg) ptrs to user space are numbered 0x030n/0x031n */
-#define HDIO_GETGEO 0x0301 /* get device geometry */
-#define HDIO_GET_UNMASKINTR 0x0302 /* get current unmask setting */
-#define HDIO_GET_MULTCOUNT 0x0304 /* get current IDE blockmode setting */
-#define HDIO_GET_IDENTITY 0x0307 /* get IDE identification info */
-#define HDIO_GET_KEEPSETTINGS 0x0308 /* get keep-settings-on-reset flag */
-#define HDIO_GET_32BIT 0x0309 /* get current io_32bit setting */
-#define HDIO_GET_NOWERR 0x030a /* get ignore-write-error flag */
-#define HDIO_GET_DMA 0x030b /* get use-dma flag */
-#define HDIO_DRIVE_CMD 0x031f /* execute a special drive command */
-
-/* hd/ide ctl's that pass (arg) non-ptr values are numbered 0x032n/0x033n */
-#define HDIO_SET_MULTCOUNT 0x0321 /* change IDE blockmode */
-#define HDIO_SET_UNMASKINTR 0x0322 /* permit other irqs during I/O */
-#define HDIO_SET_KEEPSETTINGS 0x0323 /* keep ioctl settings on reset */
-#define HDIO_SET_32BIT 0x0324 /* change io_32bit flags */
-#define HDIO_SET_NOWERR 0x0325 /* change ignore-write-error flag */
-#define HDIO_SET_DMA 0x0326 /* change use-dma flag */
-#define HDIO_SET_PIO_MODE 0x0327 /* reconfig interface to new speed */
-
-/* structure returned by HDIO_GET_IDENTITY, as per ANSI ATA2 rev.2f spec */
-struct hd_driveid {
- unsigned short config; /* lots of obsolete bit flags */
- unsigned short cyls; /* "physical" cyls */
- unsigned short reserved2; /* reserved (word 2) */
- unsigned short heads; /* "physical" heads */
- unsigned short track_bytes; /* unformatted bytes per track */
- unsigned short sector_bytes; /* unformatted bytes per sector */
- unsigned short sectors; /* "physical" sectors per track */
- unsigned short vendor0; /* vendor unique */
- unsigned short vendor1; /* vendor unique */
- unsigned short vendor2; /* vendor unique */
- unsigned char serial_no[20]; /* 0 = not_specified */
- unsigned short buf_type;
- unsigned short buf_size; /* 512 byte increments; 0 = not_specified */
- unsigned short ecc_bytes; /* for r/w long cmds; 0 = not_specified */
- unsigned char fw_rev[8]; /* 0 = not_specified */
- unsigned char model[40]; /* 0 = not_specified */
- unsigned char max_multsect; /* 0=not_implemented */
- unsigned char vendor3; /* vendor unique */
- unsigned short dword_io; /* 0=not_implemented; 1=implemented */
- unsigned char vendor4; /* vendor unique */
- unsigned char capability; /* bits 0:DMA 1:LBA 2:IORDYsw 3:IORDYsup*/
- unsigned short reserved50; /* reserved (word 50) */
- unsigned char vendor5; /* vendor unique */
- unsigned char tPIO; /* 0=slow, 1=medium, 2=fast */
- unsigned char vendor6; /* vendor unique */
- unsigned char tDMA; /* 0=slow, 1=medium, 2=fast */
- unsigned short field_valid; /* bits 0:cur_ok 1:eide_ok */
- unsigned short cur_cyls; /* logical cylinders */
- unsigned short cur_heads; /* logical heads */
- unsigned short cur_sectors; /* logical sectors per track */
- unsigned short cur_capacity0; /* logical total sectors on drive */
- unsigned short cur_capacity1; /* (2 words, misaligned int) */
- unsigned char multsect; /* current multiple sector count */
- unsigned char multsect_valid; /* when (bit0==1) multsect is ok */
- unsigned int lba_capacity; /* total number of sectors */
- unsigned short dma_1word; /* single-word dma info */
- unsigned short dma_mword; /* multiple-word dma info */
- unsigned short eide_pio_modes; /* bits 0:mode3 1:mode4 */
- unsigned short eide_dma_min; /* min mword dma cycle time (ns) */
- unsigned short eide_dma_time; /* recommended mword dma cycle time (ns) */
- unsigned short eide_pio; /* min cycle time (ns), no IORDY */
- unsigned short eide_pio_iordy; /* min cycle time (ns), with IORDY */
- unsigned short reserved69; /* reserved (word 69) */
- unsigned short reserved70; /* reserved (word 70) */
- /* unsigned short reservedxx[57];*/ /* reserved (words 71-127) */
- /* unsigned short vendor7 [32];*/ /* vendor unique (words 128-159) */
- /* unsigned short reservedyy[96];*/ /* reserved (words 160-255) */
-};
-
-#ifdef __KERNEL__
-/*
- * These routines are used for kernel command line parameters from main.c:
- */
-#include <linux/config.h>
-
-#ifdef CONFIG_BLK_DEV_HD
-void hd_setup(char *, int *);
-#endif /* CONFIG_BLK_DEV_HD */
-#ifdef CONFIG_BLK_DEV_IDE
-void ide_setup(char *);
-#endif /* CONFIG_BLK_DEV_IDE */
-
-#endif /* __KERNEL__ */
-
-#endif /* _LINUX_HDREG_H */
diff --git a/i386/i386at/gpl/linux/include/linux/head.h b/i386/i386at/gpl/linux/include/linux/head.h
deleted file mode 100644
index 3829b1c3..00000000
--- a/i386/i386at/gpl/linux/include/linux/head.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef _LINUX_HEAD_H
-#define _LINUX_HEAD_H
-
-typedef struct desc_struct {
- unsigned long a,b;
-} desc_table[256];
-
-extern desc_table idt,gdt;
-
-#define GDT_NUL 0
-#define GDT_CODE 1
-#define GDT_DATA 2
-#define GDT_TMP 3
-
-#define LDT_NUL 0
-#define LDT_CODE 1
-#define LDT_DATA 2
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/if.h b/i386/i386at/gpl/linux/include/linux/if.h
deleted file mode 100644
index 73ef7feb..00000000
--- a/i386/i386at/gpl/linux/include/linux/if.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * INET An implementation of the TCP/IP protocol suite for the LINUX
- * operating system. INET is implemented using the BSD Socket
- * interface as the means of communication with the user level.
- *
- * Global definitions for the INET interface module.
- *
- * Version: @(#)if.h 1.0.2 04/18/93
- *
- * Authors: Original taken from Berkeley UNIX 4.3, (c) UCB 1982-1988
- * Ross Biro, <bir7@leland.Stanford.Edu>
- * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#ifndef _LINUX_IF_H
-#define _LINUX_IF_H
-
-#include <linux/types.h> /* for "caddr_t" et al */
-#include <linux/socket.h> /* for "struct sockaddr" et al */
-
-/* Standard interface flags. */
-#define LINUX_IFF_UP 0x1 /* interface is up */
-#define LINUX_IFF_BROADCAST 0x2 /* broadcast address valid */
-#define LINUX_IFF_DEBUG 0x4 /* turn on debugging */
-#define LINUX_IFF_LOOPBACK 0x8 /* is a loopback net */
-#define LINUX_IFF_POINTOPOINT 0x10 /* interface is has p-p link */
-#define LINUX_IFF_NOTRAILERS 0x20 /* avoid use of trailers */
-#define LINUX_IFF_RUNNING 0x40 /* resources allocated */
-#define LINUX_IFF_NOARP 0x80 /* no ARP protocol */
-#define LINUX_IFF_PROMISC 0x100 /* receive all packets */
-/* Not supported */
-#define LINUX_IFF_ALLMULTI 0x200 /* receive all multicast packets*/
-
-#define LINUX_IFF_MASTER 0x400 /* master of a load balancer */
-#define LINUX_IFF_SLAVE 0x800 /* slave of a load balancer */
-
-#define LINUX_IFF_MULTICAST 0x1000 /* Supports multicast */
-
-#ifdef MACH
-#ifndef MACH_INCLUDE
-#define IFF_UP LINUX_IFF_UP
-#define IFF_BROADCAST LINUX_IFF_BROADCAST
-#define IFF_DEBUG LINUX_IFF_DEBUG
-#define IFF_LOOPBACK LINUX_IFF_LOOPBACK
-#define IFF_POINTOPOINT LINUX_IFF_POINTOPOINT
-#define IFF_NOTRAILERS LINUX_IFF_NOTRAILERS
-#define IFF_RUNNING LINUX_IFF_RUNNING
-#define IFF_NOARP LINUX_IFF_NOARP
-#define IFF_PROMISC LINUX_IFF_PROMISC
-#define IFF_ALLMULTI LINUX_IFF_ALLMULTI
-#define IFF_MASTER LINUX_IFF_MASTER
-#define IFF_SLAVE LINUX_IFF_SLAVE
-#define IFF_MULTICAST LINUX_IFF_MULTICAST
-#endif
-#endif
-
-/*
- * The ifaddr structure contains information about one address
- * of an interface. They are maintained by the different address
- * families, are allocated and attached when an address is set,
- * and are linked together so all addresses for an interface can
- * be located.
- */
-
-struct ifaddr
-{
- struct sockaddr ifa_addr; /* address of interface */
- union {
- struct sockaddr ifu_broadaddr;
- struct sockaddr ifu_dstaddr;
- } ifa_ifu;
- struct iface *ifa_ifp; /* back-pointer to interface */
- struct ifaddr *ifa_next; /* next address for interface */
-};
-
-#define ifa_broadaddr ifa_ifu.ifu_broadaddr /* broadcast address */
-#define ifa_dstaddr ifa_ifu.ifu_dstaddr /* other end of link */
-
-/*
- * Device mapping structure. I'd just gone off and designed a
- * beautiful scheme using only loadable modules with arguments
- * for driver options and along come the PCMCIA people 8)
- *
- * Ah well. The get() side of this is good for WDSETUP, and it'll
- * be handy for debugging things. The set side is fine for now and
- * being very small might be worth keeping for clean configuration.
- */
-
-struct ifmap
-{
- unsigned long mem_start;
- unsigned long mem_end;
- unsigned short base_addr;
- unsigned char irq;
- unsigned char dma;
- unsigned char port;
- /* 3 bytes spare */
-};
-
-/*
- * Interface request structure used for socket
- * ioctl's. All interface ioctl's must have parameter
- * definitions which begin with ifr_name. The
- * remainder may be interface specific.
- */
-
-struct ifreq
-{
-#define IFHWADDRLEN 6
-#define IFNAMSIZ 16
- union
- {
- char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */
- } ifr_ifrn;
-
- union {
- struct sockaddr ifru_addr;
- struct sockaddr ifru_dstaddr;
- struct sockaddr ifru_broadaddr;
- struct sockaddr ifru_netmask;
- struct sockaddr ifru_hwaddr;
- short ifru_flags;
- int ifru_metric;
- int ifru_mtu;
- struct ifmap ifru_map;
- char ifru_slave[IFNAMSIZ]; /* Just fits the size */
- caddr_t ifru_data;
- } ifr_ifru;
-};
-
-#define ifr_name ifr_ifrn.ifrn_name /* interface name */
-#define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */
-#define ifr_addr ifr_ifru.ifru_addr /* address */
-#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-p lnk */
-#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
-#define ifr_netmask ifr_ifru.ifru_netmask /* interface net mask */
-#define ifr_flags ifr_ifru.ifru_flags /* flags */
-#define ifr_metric ifr_ifru.ifru_metric /* metric */
-#define ifr_mtu ifr_ifru.ifru_mtu /* mtu */
-#define ifr_map ifr_ifru.ifru_map /* device map */
-#define ifr_slave ifr_ifru.ifru_slave /* slave device */
-#define ifr_data ifr_ifru.ifru_data /* for use by interface */
-
-/*
- * Structure used in SIOCGIFCONF request.
- * Used to retrieve interface configuration
- * for machine (useful for programs which
- * must know all networks accessible).
- */
-
-struct ifconf
-{
- int ifc_len; /* size of buffer */
- union
- {
- caddr_t ifcu_buf;
- struct ifreq *ifcu_req;
- } ifc_ifcu;
-};
-#define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */
-#define ifc_req ifc_ifcu.ifcu_req /* array of structures */
-
-#endif /* _LINUX_IF_H */
diff --git a/i386/i386at/gpl/linux/include/linux/if_arp.h b/i386/i386at/gpl/linux/include/linux/if_arp.h
deleted file mode 100644
index fa350688..00000000
--- a/i386/i386at/gpl/linux/include/linux/if_arp.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * INET An implementation of the TCP/IP protocol suite for the LINUX
- * operating system. INET is implemented using the BSD Socket
- * interface as the means of communication with the user level.
- *
- * Global definitions for the ARP (RFC 826) protocol.
- *
- * Version: @(#)if_arp.h 1.0.1 04/16/93
- *
- * Authors: Original taken from Berkeley UNIX 4.3, (c) UCB 1986-1988
- * Portions taken from the KA9Q/NOS (v2.00m PA0GRI) source.
- * Ross Biro, <bir7@leland.Stanford.Edu>
- * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- * Florian La Roche.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#ifndef _LINUX_IF_ARP_H
-#define _LINUX_IF_ARP_H
-
-/* ARP protocol HARDWARE identifiers. */
-#define ARPHRD_NETROM 0 /* from KA9Q: NET/ROM pseudo */
-#define ARPHRD_ETHER 1 /* Ethernet 10Mbps */
-#define ARPHRD_EETHER 2 /* Experimental Ethernet */
-#define ARPHRD_AX25 3 /* AX.25 Level 2 */
-#define ARPHRD_PRONET 4 /* PROnet token ring */
-#define ARPHRD_CHAOS 5 /* Chaosnet */
-#define ARPHRD_IEEE802 6 /* IEEE 802.2 Ethernet/TR/TB */
-#define ARPHRD_ARCNET 7 /* ARCnet */
-#define ARPHRD_APPLETLK 8 /* APPLEtalk */
-/* Dummy types for non ARP hardware */
-#define ARPHRD_SLIP 256
-#define ARPHRD_CSLIP 257
-#define ARPHRD_SLIP6 258
-#define ARPHRD_CSLIP6 259
-#define ARPHRD_RSRVD 260 /* Notional KISS type */
-#define ARPHRD_ADAPT 264
-#define ARPHRD_PPP 512
-#define ARPHRD_TUNNEL 768 /* IPIP tunnel */
-#define ARPHRD_TUNNEL6 769 /* IPIP6 tunnel */
-#define ARPHRD_FRAD 770 /* Frame Relay */
-#define ARPHRD_SKIP 771 /* SKIP vif */
-#define ARPHRD_LOOPBACK 772 /* Loopback device */
-
-/* ARP protocol opcodes. */
-#define ARPOP_REQUEST 1 /* ARP request */
-#define ARPOP_REPLY 2 /* ARP reply */
-#define ARPOP_RREQUEST 3 /* RARP request */
-#define ARPOP_RREPLY 4 /* RARP reply */
-
-
-/* ARP ioctl request. */
-struct arpreq {
- struct sockaddr arp_pa; /* protocol address */
- struct sockaddr arp_ha; /* hardware address */
- int arp_flags; /* flags */
- struct sockaddr arp_netmask; /* netmask (only for proxy arps) */
- char arp_dev[16];
-};
-
-struct arpreq_old {
- struct sockaddr arp_pa; /* protocol address */
- struct sockaddr arp_ha; /* hardware address */
- int arp_flags; /* flags */
- struct sockaddr arp_netmask; /* netmask (only for proxy arps) */
-};
-
-/* ARP Flag values. */
-#define ATF_COM 0x02 /* completed entry (ha valid) */
-#define ATF_PERM 0x04 /* permanent entry */
-#define ATF_PUBL 0x08 /* publish entry */
-#define ATF_USETRAILERS 0x10 /* has requested trailers */
-#define ATF_NETMASK 0x20 /* want to use a netmask (only
- for proxy entries) */
-
-/*
- * This structure defines an ethernet arp header.
- */
-
-struct arphdr
-{
- unsigned short ar_hrd; /* format of hardware address */
- unsigned short ar_pro; /* format of protocol address */
- unsigned char ar_hln; /* length of hardware address */
- unsigned char ar_pln; /* length of protocol address */
- unsigned short ar_op; /* ARP opcode (command) */
-
-#if 0
- /*
- * Ethernet looks like this : This bit is variable sized however...
- */
- unsigned char ar_sha[ETH_ALEN]; /* sender hardware address */
- unsigned char ar_sip[4]; /* sender IP address */
- unsigned char ar_tha[ETH_ALEN]; /* target hardware address */
- unsigned char ar_tip[4]; /* target IP address */
-#endif
-
-};
-
-#endif /* _LINUX_IF_ARP_H */
diff --git a/i386/i386at/gpl/linux/include/linux/if_ether.h b/i386/i386at/gpl/linux/include/linux/if_ether.h
deleted file mode 100644
index 14078472..00000000
--- a/i386/i386at/gpl/linux/include/linux/if_ether.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * INET An implementation of the TCP/IP protocol suite for the LINUX
- * operating system. INET is implemented using the BSD Socket
- * interface as the means of communication with the user level.
- *
- * Global definitions for the Ethernet IEEE 802.3 interface.
- *
- * Version: @(#)if_ether.h 1.0.1a 02/08/94
- *
- * Author: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- * Donald Becker, <becker@super.org>
- * Alan Cox, <alan@cymru.net>
- * Steve Whitehouse, <gw7rrm@eeshack3.swan.ac.uk>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#ifndef _LINUX_IF_ETHER_H
-#define _LINUX_IF_ETHER_H
-
-/* IEEE 802.3 Ethernet magic constants. The frame sizes omit the preamble
- and FCS/CRC (frame check sequence). */
-#define ETH_ALEN 6 /* Octets in one ethernet addr */
-#define ETH_HLEN 14 /* Total octets in header. */
-#define ETH_ZLEN 60 /* Min. octets in frame sans FCS */
-#define ETH_DATA_LEN 1500 /* Max. octets in payload */
-#define ETH_FRAME_LEN 1514 /* Max. octets in frame sans FCS */
-
-
-/* These are the defined Ethernet Protocol ID's. */
-#define ETH_P_LOOP 0x0060 /* Ethernet Loopback packet */
-#define ETH_P_ECHO 0x0200 /* Ethernet Echo packet */
-#define ETH_P_PUP 0x0400 /* Xerox PUP packet */
-#define ETH_P_IP 0x0800 /* Internet Protocol packet */
-#define ETH_P_X25 0x0805 /* CCITT X.25 */
-#define ETH_P_ARP 0x0806 /* Address Resolution packet */
-#define ETH_P_BPQ 0x08FF /* G8BPQ AX.25 Ethernet Packet [ NOT AN OFFICIALLY REGISTERED ID ] */
-#define ETH_P_DEC 0x6000 /* DEC Assigned proto */
-#define ETH_P_DNA_DL 0x6001 /* DEC DNA Dump/Load */
-#define ETH_P_DNA_RC 0x6002 /* DEC DNA Remote Console */
-#define ETH_P_DNA_RT 0x6003 /* DEC DNA Routing */
-#define ETH_P_LAT 0x6004 /* DEC LAT */
-#define ETH_P_DIAG 0x6005 /* DEC Diagnostics */
-#define ETH_P_CUST 0x6006 /* DEC Customer use */
-#define ETH_P_SCA 0x6007 /* DEC Systems Comms Arch */
-#define ETH_P_RARP 0x8035 /* Reverse Addr Res packet */
-#define ETH_P_ATALK 0x809B /* Appletalk DDP */
-#define ETH_P_AARP 0x80F3 /* Appletalk AARP */
-#define ETH_P_IPX 0x8137 /* IPX over DIX */
-#define ETH_P_IPV6 0x86DD /* IPv6 over bluebook */
-#define ETH_P_802_3 0x0001 /* Dummy type for 802.3 frames */
-#define ETH_P_AX25 0x0002 /* Dummy protocol id for AX.25 */
-#define ETH_P_ALL 0x0003 /* Every packet (be careful!!!) */
-#define ETH_P_802_2 0x0004 /* 802.2 frames */
-#define ETH_P_SNAP 0x0005 /* Internal only */
-#define ETH_P_DDCMP 0x0006 /* DEC DDCMP: Internal only */
-#define ETH_P_WAN_PPP 0x0007 /* Dummy type for WAN PPP frames*/
-#define ETH_P_PPP_MP 0x0008 /* Dummy type for PPP MP frames */
-
-/* This is an Ethernet frame header. */
-struct ethhdr {
- unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
- unsigned char h_source[ETH_ALEN]; /* source ether addr */
- unsigned short h_proto; /* packet type ID field */
-};
-
-/* Ethernet statistics collection data. */
-struct enet_statistics{
- int rx_packets; /* total packets received */
- int tx_packets; /* total packets transmitted */
- int rx_errors; /* bad packets received */
- int tx_errors; /* packet transmit problems */
- int rx_dropped; /* no space in linux buffers */
- int tx_dropped; /* no space available in linux */
- int multicast; /* multicast packets received */
- int collisions;
-
- /* detailed rx_errors: */
- int rx_length_errors;
- int rx_over_errors; /* receiver ring buff overflow */
- int rx_crc_errors; /* recved pkt with crc error */
- int rx_frame_errors; /* recv'd frame alignment error */
- int rx_fifo_errors; /* recv'r fifo overrun */
- int rx_missed_errors; /* receiver missed packet */
-
- /* detailed tx_errors */
- int tx_aborted_errors;
- int tx_carrier_errors;
- int tx_fifo_errors;
- int tx_heartbeat_errors;
- int tx_window_errors;
-};
-
-#endif /* _LINUX_IF_ETHER_H */
diff --git a/i386/i386at/gpl/linux/include/linux/if_tr.h b/i386/i386at/gpl/linux/include/linux/if_tr.h
deleted file mode 100644
index 61629332..00000000
--- a/i386/i386at/gpl/linux/include/linux/if_tr.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * INET An implementation of the TCP/IP protocol suite for the LINUX
- * operating system. INET is implemented using the BSD Socket
- * interface as the means of communication with the user level.
- *
- * Global definitions for the Token-Ring IEEE 802.5 interface.
- *
- * Version: @(#)if_tr.h 0.0 07/11/94
- *
- * Author: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- * Donald Becker, <becker@super.org>
- * Peter De Schrijver, <stud11@cc4.kuleuven.ac.be>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#ifndef _LINUX_IF_TR_H
-#define _LINUX_IF_TR_H
-
-
-/* IEEE 802.5 Token-Ring magic constants. The frame sizes omit the preamble
- and FCS/CRC (frame check sequence). */
-#define TR_ALEN 6 /* Octets in one ethernet addr */
-#define TR_HLEN (sizeof(struct trh_hdr)+sizeof(struct trllc))
-#define AC 0x10
-#define LLC_FRAME 0x40
-#if 0
-#define ETH_HLEN 14 /* Total octets in header. */
-#define ETH_ZLEN 60 /* Min. octets in frame sans FCS */
-#define ETH_DATA_LEN 1500 /* Max. octets in payload */
-#define ETH_FRAME_LEN 1514 /* Max. octets in frame sans FCS */
-#endif
-
-
-/* These are some defined Ethernet Protocol ID's. */
-#define ETH_P_IP 0x0800 /* Internet Protocol packet */
-#define ETH_P_ARP 0x0806 /* Address Resolution packet */
-#define ETH_P_RARP 0x8035 /* Reverse Addr Res packet */
-
-/* LLC and SNAP constants */
-#define EXTENDED_SAP 0xAA
-#define UI_CMD 0x03
-
-/* This is an Token-Ring frame header. */
-struct trh_hdr {
- unsigned char ac; /* access control field */
- unsigned char fc; /* frame control field */
- unsigned char daddr[TR_ALEN]; /* destination address */
- unsigned char saddr[TR_ALEN]; /* source address */
- unsigned short rcf; /* route control field */
- unsigned short rseg[8];/* routing registers */
-};
-
-/* This is an Token-Ring LLC structure */
-struct trllc {
- unsigned char dsap; /* destination SAP */
- unsigned char ssap; /* source SAP */
- unsigned char llc; /* LLC control field */
- unsigned char protid[3]; /* protocol id */
- unsigned short ethertype; /* ether type field */
-};
-
-
-/* Token-Ring statistics collection data. */
-struct tr_statistics{
- int rx_packets; /* total packets received */
- int tx_packets; /* total packets transmitted */
- int rx_errors; /* bad packets received */
- int tx_errors; /* packet transmit problems */
- int rx_dropped; /* no space in linux buffers */
- int tx_dropped; /* no space available in linux */
- int multicast; /* multicast packets received */
- int transmit_collision;
-
- /* detailed Token-Ring errors. See IBM Token-Ring Network Architecture
- for more info */
-
- int line_errors;
- int internal_errors;
- int burst_errors;
- int A_C_errors;
- int abort_delimiters;
- int lost_frames;
- int recv_congest_count;
- int frame_copied_errors;
- int frequency_errors;
- int token_errors;
- int dummy1;
-
-};
-
-/* source routing stuff */
-
-#define TR_RII 0x80
-#define TR_RCF_DIR_BIT 0x80
-#define TR_RCF_LEN_MASK 0x1f00
-#define TR_RCF_BROADCAST 0x8000
-#define TR_RCF_LIMITED_BROADCAST 0xA000
-#define TR_RCF_FRAME2K 0x20
-#define TR_RCF_BROADCAST_MASK 0xC000
-
-#endif /* _LINUX_IF_TR_H */
diff --git a/i386/i386at/gpl/linux/include/linux/igmp.h b/i386/i386at/gpl/linux/include/linux/igmp.h
deleted file mode 100644
index 161528f1..00000000
--- a/i386/i386at/gpl/linux/include/linux/igmp.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Linux NET3: Internet Gateway Management Protocol [IGMP]
- *
- * Authors:
- * Alan Cox <Alan.Cox@linux.org>
- *
- * Extended to talk the BSD extended IGMP protocol of mrouted 3.6
- *
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#ifndef _LINUX_IGMP_H
-#define _LINUX_IGMP_H
-
-/*
- * IGMP protocol structures
- */
-
-/*
- * Header in on cable format
- */
-
-struct igmphdr
-{
- __u8 type;
- __u8 code; /* For newer IGMP */
- __u16 csum;
- __u32 group;
-};
-
-#define IGMP_HOST_MEMBERSHIP_QUERY 0x11 /* From RFC1112 */
-#define IGMP_HOST_MEMBERSHIP_REPORT 0x12 /* Ditto */
-#define IGMP_DVMRP 0x13 /* DVMRP routing */
-#define IGMP_PIM 0x14 /* PIM routing */
-#define IGMP_HOST_NEW_MEMBERSHIP_REPORT 0x16 /* New version of 0x11 */
-#define IGMP_HOST_LEAVE_MESSAGE 0x17 /* An extra BSD seems to send */
-
-#define IGMP_MTRACE_RESP 0x1e
-#define IGMP_MTRACE 0x1f
-
-
-/*
- * Use the BSD names for these for compatibility
- */
-
-#define IGMP_DELAYING_MEMBER 0x01
-#define IGMP_IDLE_MEMBER 0x02
-#define IGMP_LAZY_MEMBER 0x03
-#define IGMP_SLEEPING_MEMBER 0x04
-#define IGMP_AWAKENING_MEMBER 0x05
-
-#define IGMP_OLD_ROUTER 0x00
-#define IGMP_NEW_ROUTER 0x01
-
-#define IGMP_MINLEN 8
-
-#define IGMP_MAX_HOST_REPORT_DELAY 10 /* max delay for response to */
- /* query (in seconds) */
-
-#define IGMP_TIMER_SCALE 10 /* denotes that the igmphdr->timer field */
- /* specifies time in 10th of seconds */
-
-#define IGMP_AGE_THRESHOLD 540 /* If this host don't hear any IGMP V1 */
- /* message in this period of time, */
- /* revert to IGMP v2 router. */
-
-#define IGMP_ALL_HOSTS htonl(0xE0000001L)
-#define IGMP_ALL_ROUTER htonl(0xE0000002L)
-#define IGMP_LOCAL_GROUP htonl(0xE0000000L)
-#define IGMP_LOCAL_GROUP_MASK htonl(0xFFFFFF00L)
-
-/*
- * struct for keeping the multicast list in
- */
-
-#ifdef __KERNEL__
-struct ip_mc_socklist
-{
- unsigned long multiaddr[IP_MAX_MEMBERSHIPS]; /* This is a speed trade off */
- struct device *multidev[IP_MAX_MEMBERSHIPS];
-};
-
-struct ip_mc_list
-{
- struct device *interface;
- unsigned long multiaddr;
- struct ip_mc_list *next;
- struct timer_list timer;
- int tm_running;
- int users;
-};
-
-struct ip_router_info
-{
- struct device *dev;
- int type; /* type of router which is querier on this interface */
- int time; /* # of slow timeouts since last old query */
- struct timer_list timer;
- struct ip_router_info *next;
-};
-
-extern struct ip_mc_list *ip_mc_head;
-
-
-extern int igmp_rcv(struct sk_buff *, struct device *, struct options *, __u32, unsigned short,
- __u32, int , struct inet_protocol *);
-extern void ip_mc_drop_device(struct device *dev);
-extern int ip_mc_join_group(struct sock *sk, struct device *dev, unsigned long addr);
-extern int ip_mc_leave_group(struct sock *sk, struct device *dev,unsigned long addr);
-extern void ip_mc_drop_socket(struct sock *sk);
-extern void ip_mr_init(void);
-#endif
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/in.h b/i386/i386at/gpl/linux/include/linux/in.h
deleted file mode 100644
index c8e156e8..00000000
--- a/i386/i386at/gpl/linux/include/linux/in.h
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * INET An implementation of the TCP/IP protocol suite for the LINUX
- * operating system. INET is implemented using the BSD Socket
- * interface as the means of communication with the user level.
- *
- * Definitions of the Internet Protocol.
- *
- * Version: @(#)in.h 1.0.1 04/21/93
- *
- * Authors: Original taken from the GNU Project <netinet/in.h> file.
- * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#ifndef _LINUX_IN_H
-#define _LINUX_IN_H
-
-#include <linux/types.h>
-
-/* Standard well-defined IP protocols. */
-enum {
- IPPROTO_IP = 0, /* Dummy protocol for TCP */
- IPPROTO_ICMP = 1, /* Internet Control Message Protocol */
- IPPROTO_IGMP = 2, /* Internet Gateway Management Protocol */
- IPPROTO_IPIP = 4, /* IPIP tunnels (older KA9Q tunnels use 94) */
- IPPROTO_TCP = 6, /* Transmission Control Protocol */
- IPPROTO_EGP = 8, /* Exterior Gateway Protocol */
- IPPROTO_PUP = 12, /* PUP protocol */
- IPPROTO_UDP = 17, /* User Datagram Protocol */
- IPPROTO_IDP = 22, /* XNS IDP protocol */
-
- IPPROTO_RAW = 255, /* Raw IP packets */
- IPPROTO_MAX
-};
-
-
-/* Internet address. */
-struct in_addr {
- __u32 s_addr;
-};
-
-/* Request struct for multicast socket ops */
-
-struct ip_mreq
-{
- struct in_addr imr_multiaddr; /* IP multicast address of group */
- struct in_addr imr_interface; /* local IP address of interface */
-};
-
-
-/* Structure describing an Internet (IP) socket address. */
-#define __SOCK_SIZE__ 16 /* sizeof(struct sockaddr) */
-struct sockaddr_in {
- short int sin_family; /* Address family */
- unsigned short int sin_port; /* Port number */
- struct in_addr sin_addr; /* Internet address */
-
- /* Pad to size of `struct sockaddr'. */
- unsigned char __pad[__SOCK_SIZE__ - sizeof(short int) -
- sizeof(unsigned short int) - sizeof(struct in_addr)];
-};
-#define sin_zero __pad /* for BSD UNIX comp. -FvK */
-
-
-/*
- * Definitions of the bits in an Internet address integer.
- * On subnets, host and network parts are found according
- * to the subnet mask, not these masks.
- */
-#define IN_CLASSA(a) ((((long int) (a)) & 0x80000000) == 0)
-#define IN_CLASSA_NET 0xff000000
-#define IN_CLASSA_NSHIFT 24
-#define IN_CLASSA_HOST (0xffffffff & ~IN_CLASSA_NET)
-#define IN_CLASSA_MAX 128
-
-#define IN_CLASSB(a) ((((long int) (a)) & 0xc0000000) == 0x80000000)
-#define IN_CLASSB_NET 0xffff0000
-#define IN_CLASSB_NSHIFT 16
-#define IN_CLASSB_HOST (0xffffffff & ~IN_CLASSB_NET)
-#define IN_CLASSB_MAX 65536
-
-#define IN_CLASSC(a) ((((long int) (a)) & 0xe0000000) == 0xc0000000)
-#define IN_CLASSC_NET 0xffffff00
-#define IN_CLASSC_NSHIFT 8
-#define IN_CLASSC_HOST (0xffffffff & ~IN_CLASSC_NET)
-
-#define IN_CLASSD(a) ((((long int) (a)) & 0xf0000000) == 0xe0000000)
-#define IN_MULTICAST(a) IN_CLASSD(a)
-#define IN_MULTICAST_NET 0xF0000000
-
-#define IN_EXPERIMENTAL(a) ((((long int) (a)) & 0xe0000000) == 0xe0000000)
-#define IN_BADCLASS(a) ((((long int) (a)) & 0xf0000000) == 0xf0000000)
-
-/* Address to accept any incoming messages. */
-#define INADDR_ANY ((unsigned long int) 0x00000000)
-
-/* Address to send to all hosts. */
-#define INADDR_BROADCAST ((unsigned long int) 0xffffffff)
-
-/* Address indicating an error return. */
-#define INADDR_NONE 0xffffffff
-
-/* Network number for local host loopback. */
-#define IN_LOOPBACKNET 127
-
-/* Address to loopback in software to local host. */
-#define INADDR_LOOPBACK 0x7f000001 /* 127.0.0.1 */
-#define IN_LOOPBACK(a) ((((long int) (a)) & 0xff000000) == 0x7f000000)
-
-/* Defines for Multicast INADDR */
-#define INADDR_UNSPEC_GROUP 0xe0000000 /* 224.0.0.0 */
-#define INADDR_ALLHOSTS_GROUP 0xe0000001 /* 224.0.0.1 */
-#define INADDR_MAX_LOCAL_GROUP 0xe00000ff /* 224.0.0.255 */
-
-/* <asm/byteorder.h> contains the htonl type stuff.. */
-
-#include <asm/byteorder.h>
-
-/* Some random defines to make it easier in the kernel.. */
-#ifdef __KERNEL__
-
-#define LOOPBACK(x) (((x) & htonl(0xff000000)) == htonl(0x7f000000))
-#define MULTICAST(x) (((x) & htonl(0xf0000000)) == htonl(0xe0000000))
-
-#endif
-
-/*
- * IPv6 definitions as we start to include them. This is just
- * a beginning dont get excited 8)
- */
-
-struct in_addr6
-{
- unsigned char s6_addr[16];
-};
-
-struct sockaddr_in6
-{
- unsigned short sin6_family;
- unsigned short sin6_port;
- unsigned long sin6_flowinfo;
- struct in_addr6 sin6_addr;
-};
-
-
-#endif /* _LINUX_IN_H */
diff --git a/i386/i386at/gpl/linux/include/linux/inet.h b/i386/i386at/gpl/linux/include/linux/inet.h
deleted file mode 100644
index 9ecc9cb3..00000000
--- a/i386/i386at/gpl/linux/include/linux/inet.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Swansea University Computer Society NET3
- *
- * This work is derived from NET2Debugged, which is in turn derived
- * from NET2D which was written by:
- * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- *
- * This work was derived from Ross Biro's inspirational work
- * for the LINUX operating system. His version numbers were:
- *
- * $Id: inet.h,v 1.1.1.1 1997/02/25 21:27:28 thomas Exp $
- * $Id: inet.h,v 1.1.1.1 1997/02/25 21:27:28 thomas Exp $
- * $Id: inet.h,v 1.1.1.1 1997/02/25 21:27:28 thomas Exp $
- * $Id: inet.h,v 1.1.1.1 1997/02/25 21:27:28 thomas Exp $
- * $Id: inet.h,v 1.1.1.1 1997/02/25 21:27:28 thomas Exp $
- * $Id: inet.h,v 1.1.1.1 1997/02/25 21:27:28 thomas Exp $
- * $Id: inet.h,v 1.1.1.1 1997/02/25 21:27:28 thomas Exp $
- * $Id: inet.h,v 1.1.1.1 1997/02/25 21:27:28 thomas Exp $
- * $Id: inet.h,v 1.1.1.1 1997/02/25 21:27:28 thomas Exp $
- * $Id: inet.h,v 1.1.1.1 1997/02/25 21:27:28 thomas Exp $
- * $Id: inet.h,v 1.1.1.1 1997/02/25 21:27:28 thomas Exp $
- * $Id: inet.h,v 1.1.1.1 1997/02/25 21:27:28 thomas Exp $
- * $Id: inet.h,v 1.1.1.1 1997/02/25 21:27:28 thomas Exp $
- * $Id: inet.h,v 1.1.1.1 1997/02/25 21:27:28 thomas Exp $
- * $Id: inet.h,v 1.1.1.1 1997/02/25 21:27:28 thomas Exp $
- * $Id: inet.h,v 1.1.1.1 1997/02/25 21:27:28 thomas Exp $
- * $Id: inet.h,v 1.1.1.1 1997/02/25 21:27:28 thomas Exp $
- * $Id: inet.h,v 1.1.1.1 1997/02/25 21:27:28 thomas Exp $
- * $Id: inet.h,v 1.1.1.1 1997/02/25 21:27:28 thomas Exp $
- * $Id: inet.h,v 1.1.1.1 1997/02/25 21:27:28 thomas Exp $
- * $Id: inet.h,v 1.1.1.1 1997/02/25 21:27:28 thomas Exp $
- * $Id: inet.h,v 1.1.1.1 1997/02/25 21:27:28 thomas Exp $
- * $Id: inet.h,v 1.1.1.1 1997/02/25 21:27:28 thomas Exp $
- * $Id: inet.h,v 1.1.1.1 1997/02/25 21:27:28 thomas Exp $
- * $Id: inet.h,v 1.1.1.1 1997/02/25 21:27:28 thomas Exp $
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#ifndef _LINUX_INET_H
-#define _LINUX_INET_H
-
-#ifdef __KERNEL__
-
-extern void inet_proto_init(struct net_proto *pro);
-extern char *in_ntoa(unsigned long in);
-extern unsigned long in_aton(const char *str);
-
-#endif
-#endif /* _LINUX_INET_H */
diff --git a/i386/i386at/gpl/linux/include/linux/interrupt.h b/i386/i386at/gpl/linux/include/linux/interrupt.h
deleted file mode 100644
index a20cbe8e..00000000
--- a/i386/i386at/gpl/linux/include/linux/interrupt.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/* interrupt.h */
-#ifndef _LINUX_INTERRUPT_H
-#define _LINUX_INTERRUPT_H
-
-#include <linux/kernel.h>
-#include <asm/bitops.h>
-
-struct bh_struct {
- void (*routine)(void *);
- void *data;
-};
-
-extern unsigned long bh_active;
-extern unsigned long bh_mask;
-extern struct bh_struct bh_base[32];
-
-asmlinkage void do_bottom_half(void);
-
-/* Who gets which entry in bh_base. Things which will occur most often
- should come first - in which case NET should be up the top with SERIAL/TQUEUE! */
-
-enum {
- TIMER_BH = 0,
- CONSOLE_BH,
- TQUEUE_BH,
- SERIAL_BH,
- NET_BH,
- IMMEDIATE_BH,
- KEYBOARD_BH,
- CYCLADES_BH,
- CM206_BH
-};
-
-extern inline void mark_bh(int nr)
-{
- set_bit(nr, &bh_active);
-}
-
-extern inline void disable_bh(int nr)
-{
- clear_bit(nr, &bh_mask);
-}
-
-extern inline void enable_bh(int nr)
-{
- set_bit(nr, &bh_mask);
-}
-
-extern inline void start_bh_atomic(void)
-{
- intr_count++;
- barrier();
-}
-
-extern inline void end_bh_atomic(void)
-{
- barrier();
- intr_count--;
-}
-
-/*
- * Autoprobing for irqs:
- *
- * probe_irq_on() and probe_irq_off() provide robust primitives
- * for accurate IRQ probing during kernel initialization. They are
- * reasonably simple to use, are not "fooled" by spurious interrupts,
- * and, unlike other attempts at IRQ probing, they do not get hung on
- * stuck interrupts (such as unused PS2 mouse interfaces on ASUS boards).
- *
- * For reasonably foolproof probing, use them as follows:
- *
- * 1. clear and/or mask the device's internal interrupt.
- * 2. sti();
- * 3. irqs = probe_irq_on(); // "take over" all unassigned idle IRQs
- * 4. enable the device and cause it to trigger an interrupt.
- * 5. wait for the device to interrupt, using non-intrusive polling or a delay.
- * 6. irq = probe_irq_off(irqs); // get IRQ number, 0=none, negative=multiple
- * 7. service the device to clear its pending interrupt.
- * 8. loop again if paranoia is required.
- *
- * probe_irq_on() returns a mask of allocated irq's.
- *
- * probe_irq_off() takes the mask as a parameter,
- * and returns the irq number which occurred,
- * or zero if none occurred, or a negative irq number
- * if more than one irq occurred.
- */
-extern unsigned long probe_irq_on(void); /* returns 0 on failure */
-extern int probe_irq_off(unsigned long); /* returns 0 or negative on failure */
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/ioctl.h b/i386/i386at/gpl/linux/include/linux/ioctl.h
deleted file mode 100644
index aa91eb39..00000000
--- a/i386/i386at/gpl/linux/include/linux/ioctl.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef _LINUX_IOCTL_H
-#define _LINUX_IOCTL_H
-
-#include <asm/ioctl.h>
-
-#endif /* _LINUX_IOCTL_H */
-
diff --git a/i386/i386at/gpl/linux/include/linux/ioport.h b/i386/i386at/gpl/linux/include/linux/ioport.h
deleted file mode 100644
index 335e3b65..00000000
--- a/i386/i386at/gpl/linux/include/linux/ioport.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * portio.h Definitions of routines for detecting, reserving and
- * allocating system resources.
- *
- * Version: 0.01 8/30/93
- *
- * Author: Donald Becker (becker@super.org)
- */
-
-#ifndef _LINUX_PORTIO_H
-#define _LINUX_PORTIO_H
-
-#define HAVE_PORTRESERVE
-/*
- * Call check_region() before probing for your hardware.
- * Once you have found you hardware, register it with request_region().
- * If you unload the driver, use release_region to free ports.
- */
-extern void reserve_setup(char *str, int *ints);
-extern int check_region(unsigned int from, unsigned int extent);
-extern void request_region(unsigned int from, unsigned int extent,const char *name);
-extern void release_region(unsigned int from, unsigned int extent);
-extern int get_ioport_list(char *);
-
-
-#define HAVE_AUTOIRQ
-extern void *irq2dev_map[16]; /* Use only if you own the IRQ. */
-extern int autoirq_setup(int waittime);
-extern int autoirq_report(int waittime);
-
-#endif /* _LINUX_PORTIO_H */
diff --git a/i386/i386at/gpl/linux/include/linux/ip.h b/i386/i386at/gpl/linux/include/linux/ip.h
deleted file mode 100644
index 4d5d70c1..00000000
--- a/i386/i386at/gpl/linux/include/linux/ip.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * INET An implementation of the TCP/IP protocol suite for the LINUX
- * operating system. INET is implemented using the BSD Socket
- * interface as the means of communication with the user level.
- *
- * Definitions for the IP protocol.
- *
- * Version: @(#)ip.h 1.0.2 04/28/93
- *
- * Authors: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#ifndef _LINUX_IP_H
-#define _LINUX_IP_H
-#include <asm/byteorder.h>
-
-#define IPOPT_END 0
-#define IPOPT_NOOP 1
-#define IPOPT_SEC 130
-#define IPOPT_LSRR 131
-#define IPOPT_SSRR 137
-#define IPOPT_RR 7
-#define IPOPT_SID 136
-#define IPOPT_TIMESTAMP 68
-
-
-#define MAXTTL 255
-
-struct timestamp {
- __u8 len;
- __u8 ptr;
-#if defined(__LITTLE_ENDIAN_BITFIELD)
- __u8 flags:4,
- overflow:4;
-#elif defined(__BIG_ENDIAN_BITFIELD)
- __u8 overflow:4,
- flags:4;
-#else
-#error "Please fix <asm/byteorder.h>"
-#endif
- __u32 data[9];
-};
-
-
-#define MAX_ROUTE 16
-
-struct route {
- char route_size;
- char pointer;
- unsigned long route[MAX_ROUTE];
-};
-
-#define IPOPT_OPTVAL 0
-#define IPOPT_OLEN 1
-#define IPOPT_OFFSET 2
-#define IPOPT_MINOFF 4
-#define MAX_IPOPTLEN 40
-#define IPOPT_NOP IPOPT_NOOP
-#define IPOPT_EOL IPOPT_END
-#define IPOPT_TS IPOPT_TIMESTAMP
-
-#define IPOPT_TS_TSONLY 0 /* timestamps only */
-#define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */
-#define IPOPT_TS_PRESPEC 2 /* specified modules only */
-
-struct options {
- __u32 faddr; /* Saved first hop address */
- unsigned char optlen;
- unsigned char srr;
- unsigned char rr;
- unsigned char ts;
- unsigned char is_setbyuser:1, /* Set by setsockopt? */
- is_data:1, /* Options in __data, rather than skb */
- is_strictroute:1, /* Strict source route */
- srr_is_hit:1, /* Packet destination addr was our one */
- is_changed:1, /* IP checksum more not valid */
- rr_needaddr:1, /* Need to record addr of outgoing dev */
- ts_needtime:1, /* Need to record timestamp */
- ts_needaddr:1; /* Need to record addr of outgoing dev */
- unsigned char __pad1;
- unsigned char __pad2;
- unsigned char __pad3;
- unsigned char __data[0];
-};
-
-struct iphdr {
-#if defined(__LITTLE_ENDIAN_BITFIELD)
- __u8 ihl:4,
- version:4;
-#elif defined (__BIG_ENDIAN_BITFIELD)
- __u8 version:4,
- ihl:4;
-#else
-#error "Please fix <asm/byteorder.h>"
-#endif
- __u8 tos;
- __u16 tot_len;
- __u16 id;
- __u16 frag_off;
- __u8 ttl;
- __u8 protocol;
- __u16 check;
- __u32 saddr;
- __u32 daddr;
- /*The options start here. */
-};
-
-
-#endif /* _LINUX_IP_H */
diff --git a/i386/i386at/gpl/linux/include/linux/ipc.h b/i386/i386at/gpl/linux/include/linux/ipc.h
deleted file mode 100644
index 3878e020..00000000
--- a/i386/i386at/gpl/linux/include/linux/ipc.h
+++ /dev/null
@@ -1,67 +0,0 @@
-#ifndef _LINUX_IPC_H
-#define _LINUX_IPC_H
-#include <linux/types.h>
-
-typedef int key_t; /* should go in <types.h> type for IPC key */
-#define IPC_PRIVATE ((key_t) 0)
-
-struct ipc_perm
-{
- key_t key;
- ushort uid; /* owner euid and egid */
- ushort gid;
- ushort cuid; /* creator euid and egid */
- ushort cgid;
- ushort mode; /* access modes see mode flags below */
- ushort seq; /* sequence number */
-};
-
-
-/* resource get request flags */
-#define IPC_CREAT 00001000 /* create if key is nonexistent */
-#define IPC_EXCL 00002000 /* fail if key exists */
-#define IPC_NOWAIT 00004000 /* return error on wait */
-
-
-/*
- * Control commands used with semctl, msgctl and shmctl
- * see also specific commands in sem.h, msg.h and shm.h
- */
-#define IPC_RMID 0 /* remove resource */
-#define IPC_SET 1 /* set ipc_perm options */
-#define IPC_STAT 2 /* get ipc_perm options */
-#define IPC_INFO 3 /* see ipcs */
-
-#ifdef __KERNEL__
-
-/* special shmsegs[id], msgque[id] or semary[id] values */
-#define IPC_UNUSED ((void *) -1)
-#define IPC_NOID ((void *) -2) /* being allocated/destroyed */
-
-/*
- * These are used to wrap system calls. See ipc/util.c.
- */
-struct ipc_kludge {
- struct msgbuf *msgp;
- long msgtyp;
-};
-
-#define SEMOP 1
-#define SEMGET 2
-#define SEMCTL 3
-#define MSGSND 11
-#define MSGRCV 12
-#define MSGGET 13
-#define MSGCTL 14
-#define SHMAT 21
-#define SHMDT 22
-#define SHMGET 23
-#define SHMCTL 24
-
-#define IPCCALL(version,op) ((version)<<16 | (op))
-
-#endif /* __KERNEL__ */
-
-#endif /* _LINUX_IPC_H */
-
-
diff --git a/i386/i386at/gpl/linux/include/linux/kdev_t.h b/i386/i386at/gpl/linux/include/linux/kdev_t.h
deleted file mode 100644
index 0497ea8c..00000000
--- a/i386/i386at/gpl/linux/include/linux/kdev_t.h
+++ /dev/null
@@ -1,114 +0,0 @@
-#ifndef _LINUX_KDEV_T_H
-#define _LINUX_KDEV_T_H
-#ifdef __KERNEL__
-/*
-As a preparation for the introduction of larger device numbers,
-we introduce a type kdev_t to hold them. No information about
-this type is known outside of this include file.
-
-Objects of type kdev_t designate a device. Outside of the kernel
-the corresponding things are objects of type dev_t - usually an
-integral type with the device major and minor in the high and low
-bits, respectively. Conversion is done by
-
-extern kdev_t to_kdev_t(int);
-
-It is up to the various file systems to decide how objects of type
-dev_t are stored on disk.
-The only other point of contact between kernel and outside world
-are the system calls stat and mknod, new versions of which will
-eventually have to be used in libc.
-
-[Unfortunately, the floppy control ioctls fail to hide the internal
-kernel structures, and the fd_device field of a struct floppy_drive_struct
-is user-visible. So, it remains a dev_t for the moment, with some ugly
-conversions in floppy.c.]
-
-Inside the kernel, we aim for a kdev_t type that is a pointer
-to a structure with information about the device (like major,
-minor, size, blocksize, sectorsize, name, read-only flag,
-struct file_operations etc.).
-
-However, for the time being we let kdev_t be almost the same as dev_t:
-
-typedef struct { unsigned short major, minor; } kdev_t;
-
-Admissible operations on an object of type kdev_t:
-- passing it along
-- comparing it for equality with another such object
-- storing it in ROOT_DEV, inode->i_dev, inode->i_rdev, sb->s_dev,
- bh->b_dev, req->rq_dev, de->dc_dev, tty->device
-- using its bit pattern as argument in a hash function
-- finding its major and minor
-- complaining about it
-
-An object of type kdev_t is created only by the function MKDEV(),
-with the single exception of the constant 0 (no device).
-
-Right now the other information mentioned above is usually found
-in static arrays indexed by major or major,minor.
-
-An obstacle to immediately using
- typedef struct { ... (* lots of information *) } *kdev_t
-is the case of mknod used to create a block device that the
-kernel doesn't know about at present (but first learns about
-when some module is inserted).
-
-aeb - 950811
-*/
-
-/* Since MINOR(dev) is used as index in static arrays,
- the kernel is not quite ready yet for larger minors.
- However, everything runs fine with an arbitrary kdev_t type. */
-
-#define MINORBITS 8
-#define MINORMASK ((1<<MINORBITS) - 1)
-
-typedef unsigned short kdev_t;
-
-#define MAJOR(dev) ((dev) >> MINORBITS)
-#define MINOR(dev) ((dev) & MINORMASK)
-#define HASHDEV(dev) (dev)
-#define NODEV 0
-#define MKDEV(ma,mi) (((ma) << MINORBITS) | (mi))
-#define B_FREE 0xffff /* yuk */
-
-extern char * kdevname(kdev_t); /* note: returns pointer to static data! */
-
-/*
-As long as device numbers in the outside world have 16 bits only,
-we use these conversions.
-*/
-
-static inline unsigned int kdev_t_to_nr(kdev_t dev) {
- return (MAJOR(dev)<<8) | MINOR(dev);
-}
-
-static inline kdev_t to_kdev_t(int dev)
-{
- int major, minor;
-#if 0
- major = (dev >> 16);
- if (!major) {
- major = (dev >> 8);
- minor = (dev & 0xff);
- } else
- minor = (dev & 0xffff);
-#else
- major = (dev >> 8);
- minor = (dev & 0xff);
-#endif
- return MKDEV(major, minor);
-}
-
-#else /* __KERNEL__ */
-
-/*
-Some programs want their definitions of MAJOR and MINOR and MKDEV
-from the kernel sources. These must be the externally visible ones.
-*/
-#define MAJOR(dev) ((dev)>>8)
-#define MINOR(dev) ((dev) & 0xff)
-#define MKDEV(ma,mi) ((ma)<<8 | (mi))
-#endif /* __KERNEL__ */
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/kernel.h b/i386/i386at/gpl/linux/include/linux/kernel.h
deleted file mode 100644
index d4985576..00000000
--- a/i386/i386at/gpl/linux/include/linux/kernel.h
+++ /dev/null
@@ -1,94 +0,0 @@
-#ifndef _LINUX_KERNEL_H
-#define _LINUX_KERNEL_H
-
-/*
- * 'kernel.h' contains some often-used function prototypes etc
- */
-
-#ifdef __KERNEL__
-
-#include <stdarg.h>
-#include <linux/linkage.h>
-
-#define INT_MAX ((int)(~0U>>1))
-#define UINT_MAX (~0U)
-#define LONG_MAX ((long)(~0UL>>1))
-#define ULONG_MAX (~0UL)
-
-#define STACK_MAGIC 0xdeadbeef
-
-#define KERN_EMERG "<0>" /* system is unusable */
-#define KERN_ALERT "<1>" /* action must be taken immediately */
-#define KERN_CRIT "<2>" /* critical conditions */
-#define KERN_ERR "<3>" /* error conditions */
-#define KERN_WARNING "<4>" /* warning conditions */
-#define KERN_NOTICE "<5>" /* normal but significant condition */
-#define KERN_INFO "<6>" /* informational */
-#define KERN_DEBUG "<7>" /* debug-level messages */
-
-#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)
-# define NORET_TYPE __volatile__
-# define ATTRIB_NORET /**/
-# define NORET_AND /**/
-#else
-# define NORET_TYPE /**/
-# define ATTRIB_NORET __attribute__((noreturn))
-# define NORET_AND noreturn,
-#endif
-
-extern void math_error(void);
-NORET_TYPE void panic(const char * fmt, ...)
- __attribute__ ((NORET_AND format (printf, 1, 2)));
-NORET_TYPE void do_exit(long error_code)
- ATTRIB_NORET;
-extern unsigned long simple_strtoul(const char *,char **,unsigned int);
-extern int linux_sprintf(char * buf, const char * fmt, ...);
-extern int linux_vsprintf(char *buf, const char *, va_list);
-#ifndef MACH_INCLUDE
-#define sprintf linux_sprintf
-#define vsprintf linux_vsprintf
-#endif
-
-extern int session_of_pgrp(int pgrp);
-
-extern int kill_proc(int pid, int sig, int priv);
-extern int kill_pg(int pgrp, int sig, int priv);
-extern int kill_sl(int sess, int sig, int priv);
-
-asmlinkage int printk(const char * fmt, ...)
- __attribute__ ((format (printf, 1, 2)));
-
-/*
- * This is defined as a macro, but at some point this might become a
- * real subroutine that sets a flag if it returns true (to do
- * BSD-style accounting where the process is flagged if it uses root
- * privs). The implication of this is that you should do normal
- * permissions checks first, and check suser() last.
- *
- * "suser()" checks against the effective user id, while "fsuser()"
- * is used for file permission checking and checks against the fsuid..
- */
-#ifdef MACH
-#define suser() 1
-#else
-#define suser() (current->euid == 0)
-#endif
-#define fsuser() (current->fsuid == 0)
-
-#endif /* __KERNEL__ */
-
-#define SI_LOAD_SHIFT 16
-struct sysinfo {
- long uptime; /* Seconds since boot */
- unsigned long loads[3]; /* 1, 5, and 15 minute load averages */
- unsigned long totalram; /* Total usable main memory size */
- unsigned long freeram; /* Available memory size */
- unsigned long sharedram; /* Amount of shared memory */
- unsigned long bufferram; /* Memory used by buffers */
- unsigned long totalswap; /* Total swap space size */
- unsigned long freeswap; /* swap space still available */
- unsigned short procs; /* Number of current processes */
- char _f[22]; /* Pads structure to 64 bytes */
-};
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/kernel_stat.h b/i386/i386at/gpl/linux/include/linux/kernel_stat.h
deleted file mode 100644
index 1966490a..00000000
--- a/i386/i386at/gpl/linux/include/linux/kernel_stat.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef _LINUX_KERNEL_STAT_H
-#define _LINUX_KERNEL_STAT_H
-
-#include <asm/irq.h>
-
-/*
- * 'kernel_stat.h' contains the definitions needed for doing
- * some kernel statistics (cpu usage, context switches ...),
- * used by rstatd/perfmeter
- */
-
-#define DK_NDRIVE 4
-
-struct kernel_stat {
- unsigned int cpu_user, cpu_nice, cpu_system;
- unsigned int dk_drive[DK_NDRIVE];
- unsigned int dk_drive_rio[DK_NDRIVE];
- unsigned int dk_drive_wio[DK_NDRIVE];
- unsigned int dk_drive_rblk[DK_NDRIVE];
- unsigned int dk_drive_wblk[DK_NDRIVE];
- unsigned int pgpgin, pgpgout;
- unsigned int pswpin, pswpout;
- unsigned int interrupts[NR_IRQS];
- unsigned int ipackets, opackets;
- unsigned int ierrors, oerrors;
- unsigned int collisions;
- unsigned int context_swtch;
-};
-
-extern struct kernel_stat kstat;
-
-#endif /* _LINUX_KERNEL_STAT_H */
diff --git a/i386/i386at/gpl/linux/include/linux/limits.h b/i386/i386at/gpl/linux/include/linux/limits.h
deleted file mode 100644
index d0f300c4..00000000
--- a/i386/i386at/gpl/linux/include/linux/limits.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef _LINUX_LIMITS_H
-#define _LINUX_LIMITS_H
-
-#define NR_OPEN 256
-
-#define NGROUPS_MAX 32 /* supplemental group IDs are available */
-#define ARG_MAX 131072 /* # bytes of args + environ for exec() */
-#define CHILD_MAX 999 /* no limit :-) */
-#define OPEN_MAX 256 /* # open files a process may have */
-#define LINK_MAX 127 /* # links a file may have */
-#define MAX_CANON 255 /* size of the canonical input queue */
-#define MAX_INPUT 255 /* size of the type-ahead buffer */
-#define NAME_MAX 255 /* # chars in a file name */
-#define PATH_MAX 1024 /* # chars in a path name */
-#define PIPE_BUF 4096 /* # bytes in atomic write to a pipe */
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/linkage.h b/i386/i386at/gpl/linux/include/linux/linkage.h
deleted file mode 100644
index c8a7a491..00000000
--- a/i386/i386at/gpl/linux/include/linux/linkage.h
+++ /dev/null
@@ -1,59 +0,0 @@
-#ifndef _LINUX_LINKAGE_H
-#define _LINUX_LINKAGE_H
-
-#ifdef __cplusplus
-#define asmlinkage extern "C"
-#else
-#define asmlinkage
-#endif
-
-#ifdef __ELF__
-#define SYMBOL_NAME_STR(X) #X
-#define SYMBOL_NAME(X) X
-#ifdef __STDC__
-#define SYMBOL_NAME_LABEL(X) X##:
-#else
-#define SYMBOL_NAME_LABEL(X) X/**/:
-#endif
-#else
-#define SYMBOL_NAME_STR(X) "_"#X
-#ifdef __STDC__
-#define SYMBOL_NAME(X) _##X
-#define SYMBOL_NAME_LABEL(X) _##X##:
-#else
-#define SYMBOL_NAME(X) _/**/X
-#define SYMBOL_NAME_LABEL(X) _/**/X/**/:
-#endif
-#endif
-
-#if !defined(__i486__) && !defined(__i586__)
-#ifdef __ELF__
-#define __ALIGN .align 4,0x90
-#define __ALIGN_STR ".align 4,0x90"
-#else /* __ELF__ */
-#define __ALIGN .align 2,0x90
-#define __ALIGN_STR ".align 2,0x90"
-#endif /* __ELF__ */
-#else /* __i486__/__i586__ */
-#ifdef __ELF__
-#define __ALIGN .align 16,0x90
-#define __ALIGN_STR ".align 16,0x90"
-#else /* __ELF__ */
-#define __ALIGN .align 4,0x90
-#define __ALIGN_STR ".align 4,0x90"
-#endif /* __ELF__ */
-#endif /* __i486__/__i586__ */
-
-#ifdef __ASSEMBLY__
-
-#define ALIGN __ALIGN
-#define ALIGN_STRING __ALIGN_STRING
-
-#define ENTRY(name) \
- .globl SYMBOL_NAME(name); \
- ALIGN; \
- SYMBOL_NAME_LABEL(name)
-
-#endif
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/locks.h b/i386/i386at/gpl/linux/include/linux/locks.h
deleted file mode 100644
index c3202b08..00000000
--- a/i386/i386at/gpl/linux/include/linux/locks.h
+++ /dev/null
@@ -1,66 +0,0 @@
-#ifndef _LINUX_LOCKS_H
-#define _LINUX_LOCKS_H
-
-#ifndef _LINUX_MM_H
-#include <linux/mm.h>
-#endif
-#ifndef _LINUX_PAGEMAP_H
-#include <linux/pagemap.h>
-#endif
-
-/*
- * Unlocked, temporary IO buffer_heads gets moved to the reuse_list
- * once their page becomes unlocked.
- */
-extern struct buffer_head *reuse_list;
-
-/*
- * Buffer cache locking - note that interrupts may only unlock, not
- * lock buffers.
- */
-extern void __wait_on_buffer(struct buffer_head *);
-
-extern inline void wait_on_buffer(struct buffer_head * bh)
-{
- if (test_bit(BH_Lock, &bh->b_state))
- __wait_on_buffer(bh);
-}
-
-extern inline void lock_buffer(struct buffer_head * bh)
-{
- if (set_bit(BH_Lock, &bh->b_state))
- __wait_on_buffer(bh);
-}
-
-void unlock_buffer(struct buffer_head *);
-
-#ifndef MACH
-/*
- * super-block locking. Again, interrupts may only unlock
- * a super-block (although even this isn't done right now.
- * nfs may need it).
- */
-extern void __wait_on_super(struct super_block *);
-
-extern inline void wait_on_super(struct super_block * sb)
-{
- if (sb->s_lock)
- __wait_on_super(sb);
-}
-
-extern inline void lock_super(struct super_block * sb)
-{
- if (sb->s_lock)
- __wait_on_super(sb);
- sb->s_lock = 1;
-}
-
-extern inline void unlock_super(struct super_block * sb)
-{
- sb->s_lock = 0;
- wake_up(&sb->s_wait);
-}
-#endif /* ! MACH */
-
-#endif /* _LINUX_LOCKS_H */
-
diff --git a/i386/i386at/gpl/linux/include/linux/major.h b/i386/i386at/gpl/linux/include/linux/major.h
deleted file mode 100644
index c1b2dcf0..00000000
--- a/i386/i386at/gpl/linux/include/linux/major.h
+++ /dev/null
@@ -1,119 +0,0 @@
-#ifndef _LINUX_MAJOR_H
-#define _LINUX_MAJOR_H
-
-/*
- * This file has definitions for major device numbers
- */
-
-/* limits */
-
-#define MAX_CHRDEV 64
-#define MAX_BLKDEV 64
-
-/*
- * assignments
- *
- * devices are as follows (same as minix, so we can use the minix fs):
- *
- * character block comments
- * -------------------- -------------------- --------------------
- * 0 - unnamed unnamed minor 0 = true nodev
- * 1 - /dev/mem ramdisk
- * 2 - /dev/ptyp* floppy
- * 3 - /dev/ttyp* ide0 or hd
- * 4 - /dev/tty*
- * 5 - /dev/tty; /dev/cua*
- * 6 - lp
- * 7 - /dev/vcs*
- * 8 - scsi disk
- * 9 - scsi tape
- * 10 - mice
- * 11 - scsi cdrom
- * 12 - qic02 tape
- * 13 - xt disk
- * 14 - sound card
- * 15 - cdu31a cdrom
- * 16 - sockets goldstar cdrom
- * 17 - af_unix optics cdrom
- * 18 - af_inet sanyo cdrom
- * 19 - cyclades /dev/ttyC*
- * 20 - cyclades /dev/cub* mitsumi (mcdx) cdrom
- * 21 - scsi generic
- * 22 - ide1
- * 23 - mitsumi cdrom
- * 24 - sony535 cdrom
- * 25 - matsushita cdrom minors 0..3
- * 26 - matsushita cdrom 2 minors 0..3
- * 27 - qic117 tape matsushita cdrom 3 minors 0..3
- * 28 - matsushita cdrom 4 minors 0..3
- * 29 - aztech/orchid/okano/wearnes cdrom
- * 32 - philips/lms cm206 cdrom
- * 33 - ide2
- * 34 - z8530 driver ide3
- * 36 - netlink
- */
-
-#define UNNAMED_MAJOR 0
-#define MEM_MAJOR 1
-#define RAMDISK_MAJOR 1
-#define FLOPPY_MAJOR 2
-#define PTY_MASTER_MAJOR 2
-#define IDE0_MAJOR 3
-#define PTY_SLAVE_MAJOR 3
-#define HD_MAJOR IDE0_MAJOR
-#define TTY_MAJOR 4
-#define TTYAUX_MAJOR 5
-#define LP_MAJOR 6
-#define VCS_MAJOR 7
-#define SCSI_DISK_MAJOR 8
-#define SCSI_TAPE_MAJOR 9
-#define MOUSE_MAJOR 10
-#define SCSI_CDROM_MAJOR 11
-#define QIC02_TAPE_MAJOR 12
-#define XT_DISK_MAJOR 13
-#define SOUND_MAJOR 14
-#define CDU31A_CDROM_MAJOR 15
-#define SOCKET_MAJOR 16
-#define GOLDSTAR_CDROM_MAJOR 16
-#define AF_UNIX_MAJOR 17
-#define OPTICS_CDROM_MAJOR 17
-#define AF_INET_MAJOR 18
-#define SANYO_CDROM_MAJOR 18
-#define CYCLADES_MAJOR 19
-#define CYCLADESAUX_MAJOR 20
-#define MITSUMI_X_CDROM_MAJOR 20
-#define SCSI_GENERIC_MAJOR 21
-#define Z8530_MAJOR 34
-#define IDE1_MAJOR 22
-#define MITSUMI_CDROM_MAJOR 23
-#define CDU535_CDROM_MAJOR 24
-#define STL_SERIALMAJOR 24
-#define MATSUSHITA_CDROM_MAJOR 25
-#define STL_CALLOUTMAJOR 25
-#define MATSUSHITA_CDROM2_MAJOR 26
-#define QIC117_TAPE_MAJOR 27
-#define MATSUSHITA_CDROM3_MAJOR 27
-#define MATSUSHITA_CDROM4_MAJOR 28
-#define STL_SIOMEMMAJOR 28
-#define AZTECH_CDROM_MAJOR 29
-#define CM206_CDROM_MAJOR 32
-#define IDE2_MAJOR 33
-#define IDE3_MAJOR 34
-#define NETLINK_MAJOR 36
-#define IDETAPE_MAJOR 37
-
-/*
- * Tests for SCSI devices.
- */
-
-#define SCSI_MAJOR(M) \
- ((M) == SCSI_DISK_MAJOR \
- || (M) == SCSI_TAPE_MAJOR \
- || (M) == SCSI_CDROM_MAJOR \
- || (M) == SCSI_GENERIC_MAJOR)
-
-static inline int scsi_major(int m) {
- return SCSI_MAJOR(m);
-}
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/malloc.h b/i386/i386at/gpl/linux/include/linux/malloc.h
deleted file mode 100644
index 847383ad..00000000
--- a/i386/i386at/gpl/linux/include/linux/malloc.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef _LINUX_MALLOC_H
-#define _LINUX_MALLOC_H
-
-#include <linux/mm.h>
-
-#ifndef MACH_INCLUDE
-#define kmalloc linux_kmalloc
-#define kfree linux_kfree
-#endif
-
-void *linux_kmalloc(unsigned int size, int priority);
-void linux_kfree(void * obj);
-
-#define kfree_s(a,b) linux_kfree(a)
-
-#endif /* _LINUX_MALLOC_H */
diff --git a/i386/i386at/gpl/linux/include/linux/math_emu.h b/i386/i386at/gpl/linux/include/linux/math_emu.h
deleted file mode 100644
index 0d9606d9..00000000
--- a/i386/i386at/gpl/linux/include/linux/math_emu.h
+++ /dev/null
@@ -1,43 +0,0 @@
-#ifndef _LINUX_MATH_EMU_H
-#define _LINUX_MATH_EMU_H
-
-struct fpu_reg {
- char sign;
- char tag;
- long exp;
- unsigned sigl;
- unsigned sigh;
-};
-
-
-/* This structure matches the layout of the data saved to the stack
- following a device-not-present interrupt, part of it saved
- automatically by the 80386/80486.
- */
-struct info {
- long ___orig_eip;
- long ___ret_from_system_call;
- long ___ebx;
- long ___ecx;
- long ___edx;
- long ___esi;
- long ___edi;
- long ___ebp;
- long ___eax;
- long ___ds;
- long ___es;
- long ___fs;
- long ___gs;
- long ___orig_eax;
- long ___eip;
- long ___cs;
- long ___eflags;
- long ___esp;
- long ___ss;
- long ___vm86_es; /* This and the following only in vm86 mode */
- long ___vm86_ds;
- long ___vm86_fs;
- long ___vm86_gs;
-};
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/mc146818rtc.h b/i386/i386at/gpl/linux/include/linux/mc146818rtc.h
deleted file mode 100644
index d2e709a1..00000000
--- a/i386/i386at/gpl/linux/include/linux/mc146818rtc.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/* mc146818rtc.h - register definitions for the Real-Time-Clock / CMOS RAM
- * Copyright Torsten Duwe <duwe@informatik.uni-erlangen.de> 1993
- * derived from Data Sheet, Copyright Motorola 1984 (!).
- * It was written to be part of the Linux operating system.
- */
-/* permission is hereby granted to copy, modify and redistribute this code
- * in terms of the GNU Library General Public License, Version 2 or later,
- * at your option.
- */
-
-#ifndef _MC146818RTC_H
-#define _MC146818RTC_H
-#include <asm/io.h>
-
-#ifndef RTC_PORT
-#define RTC_PORT(x) (0x70 + (x))
-#define RTC_ALWAYS_BCD 1
-#endif
-
-#define CMOS_READ(addr) ({ \
-outb_p((addr),RTC_PORT(0)); \
-inb_p(RTC_PORT(1)); \
-})
-#define CMOS_WRITE(val, addr) ({ \
-outb_p((addr),RTC_PORT(0)); \
-outb_p((val),RTC_PORT(1)); \
-})
-
-/**********************************************************************
- * register summary
- **********************************************************************/
-#define RTC_SECONDS 0
-#define RTC_SECONDS_ALARM 1
-#define RTC_MINUTES 2
-#define RTC_MINUTES_ALARM 3
-#define RTC_HOURS 4
-#define RTC_HOURS_ALARM 5
-/* RTC_*_alarm is always true if 2 MSBs are set */
-# define RTC_ALARM_DONT_CARE 0xC0
-
-#define RTC_DAY_OF_WEEK 6
-#define RTC_DAY_OF_MONTH 7
-#define RTC_MONTH 8
-#define RTC_YEAR 9
-
-/* control registers - Moto names
- */
-#define RTC_REG_A 10
-#define RTC_REG_B 11
-#define RTC_REG_C 12
-#define RTC_REG_D 13
-
-/**********************************************************************
- * register details
- **********************************************************************/
-#define RTC_FREQ_SELECT RTC_REG_A
-
-/* update-in-progress - set to "1" 244 microsecs before RTC goes off the bus,
- * reset after update (may take 1.984ms @ 32768Hz RefClock) is complete,
- * totalling to a max high interval of 2.228 ms.
- */
-# define RTC_UIP 0x80
-# define RTC_DIV_CTL 0x70
- /* divider control: refclock values 4.194 / 1.049 MHz / 32.768 kHz */
-# define RTC_REF_CLCK_4MHZ 0x00
-# define RTC_REF_CLCK_1MHZ 0x10
-# define RTC_REF_CLCK_32KHZ 0x20
- /* 2 values for divider stage reset, others for "testing purposes only" */
-# define RTC_DIV_RESET1 0x60
-# define RTC_DIV_RESET2 0x70
- /* Periodic intr. / Square wave rate select. 0=none, 1=32.8kHz,... 15=2Hz */
-# define RTC_RATE_SELECT 0x0F
-
-/**********************************************************************/
-#define RTC_CONTROL RTC_REG_B
-# define RTC_SET 0x80 /* disable updates for clock setting */
-# define RTC_PIE 0x40 /* periodic interrupt enable */
-# define RTC_AIE 0x20 /* alarm interrupt enable */
-# define RTC_UIE 0x10 /* update-finished interrupt enable */
-# define RTC_SQWE 0x08 /* enable square-wave output */
-# define RTC_DM_BINARY 0x04 /* all time/date values are BCD if clear */
-# define RTC_24H 0x02 /* 24 hour mode - else hours bit 7 means pm */
-# define RTC_DST_EN 0x01 /* auto switch DST - works f. USA only */
-
-/**********************************************************************/
-#define RTC_INTR_FLAGS RTC_REG_C
-/* caution - cleared by read */
-# define RTC_IRQF 0x80 /* any of the following 3 is active */
-# define RTC_PF 0x40
-# define RTC_AF 0x20
-# define RTC_UF 0x10
-
-/**********************************************************************/
-#define RTC_VALID RTC_REG_D
-# define RTC_VRT 0x80 /* valid RAM and time */
-/**********************************************************************/
-
-/* example: !(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY)
- * determines if the following two #defines are needed
- */
-#ifndef BCD_TO_BIN
-#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
-#endif
-
-#ifndef BIN_TO_BCD
-#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
-#endif
-
-#endif /* _MC146818RTC_H */
diff --git a/i386/i386at/gpl/linux/include/linux/minix_fs.h b/i386/i386at/gpl/linux/include/linux/minix_fs.h
deleted file mode 100644
index f0ecdea0..00000000
--- a/i386/i386at/gpl/linux/include/linux/minix_fs.h
+++ /dev/null
@@ -1,135 +0,0 @@
-#ifndef _LINUX_MINIX_FS_H
-#define _LINUX_MINIX_FS_H
-
-/*
- * The minix filesystem constants/structures
- */
-
-/*
- * Thanks to Kees J Bot for sending me the definitions of the new
- * minix filesystem (aka V2) with bigger inodes and 32-bit block
- * pointers.
- */
-
-#define MINIX_ROOT_INO 1
-
-/* Not the same as the bogus LINK_MAX in <linux/limits.h>. Oh well. */
-#define MINIX_LINK_MAX 250
-
-#define MINIX_I_MAP_SLOTS 8
-#define MINIX_Z_MAP_SLOTS 64
-#define MINIX_SUPER_MAGIC 0x137F /* original minix fs */
-#define MINIX_SUPER_MAGIC2 0x138F /* minix fs, 30 char names */
-#define MINIX2_SUPER_MAGIC 0x2468 /* minix V2 fs */
-#define MINIX2_SUPER_MAGIC2 0x2478 /* minix V2 fs, 30 char names */
-#define MINIX_VALID_FS 0x0001 /* Clean fs. */
-#define MINIX_ERROR_FS 0x0002 /* fs has errors. */
-
-#define MINIX_INODES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct minix_inode)))
-#define MINIX2_INODES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct minix2_inode)))
-
-#define MINIX_V1 0x0001 /* original minix fs */
-#define MINIX_V2 0x0002 /* minix V2 fs */
-
-#define INODE_VERSION(inode) inode->i_sb->u.minix_sb.s_version
-
-/*
- * This is the original minix inode layout on disk.
- * Note the 8-bit gid and atime and ctime.
- */
-struct minix_inode {
- __u16 i_mode;
- __u16 i_uid;
- __u32 i_size;
- __u32 i_time;
- __u8 i_gid;
- __u8 i_nlinks;
- __u16 i_zone[9];
-};
-
-/*
- * The new minix inode has all the time entries, as well as
- * long block numbers and a third indirect block (7+1+1+1
- * instead of 7+1+1). Also, some previously 8-bit values are
- * now 16-bit. The inode is now 64 bytes instead of 32.
- */
-struct minix2_inode {
- __u16 i_mode;
- __u16 i_nlinks;
- __u16 i_uid;
- __u16 i_gid;
- __u32 i_size;
- __u32 i_atime;
- __u32 i_mtime;
- __u32 i_ctime;
- __u32 i_zone[10];
-};
-
-/*
- * minix super-block data on disk
- */
-struct minix_super_block {
- __u16 s_ninodes;
- __u16 s_nzones;
- __u16 s_imap_blocks;
- __u16 s_zmap_blocks;
- __u16 s_firstdatazone;
- __u16 s_log_zone_size;
- __u32 s_max_size;
- __u16 s_magic;
- __u16 s_state;
- __u32 s_zones;
-};
-
-struct minix_dir_entry {
- __u16 inode;
- char name[0];
-};
-
-#ifdef __KERNEL__
-
-extern int minix_lookup(struct inode * dir,const char * name, int len,
- struct inode ** result);
-extern int minix_create(struct inode * dir,const char * name, int len, int mode,
- struct inode ** result);
-extern int minix_mkdir(struct inode * dir, const char * name, int len, int mode);
-extern int minix_rmdir(struct inode * dir, const char * name, int len);
-extern int minix_unlink(struct inode * dir, const char * name, int len);
-extern int minix_symlink(struct inode * inode, const char * name, int len,
- const char * symname);
-extern int minix_link(struct inode * oldinode, struct inode * dir, const char * name, int len);
-extern int minix_mknod(struct inode * dir, const char * name, int len, int mode, int rdev);
-extern int minix_rename(struct inode * old_dir, const char * old_name, int old_len,
- struct inode * new_dir, const char * new_name, int new_len);
-extern struct inode * minix_new_inode(const struct inode * dir);
-extern void minix_free_inode(struct inode * inode);
-extern unsigned long minix_count_free_inodes(struct super_block *sb);
-extern int minix_new_block(struct super_block * sb);
-extern void minix_free_block(struct super_block * sb, int block);
-extern unsigned long minix_count_free_blocks(struct super_block *sb);
-
-extern int minix_bmap(struct inode *,int);
-
-extern struct buffer_head * minix_getblk(struct inode *, int, int);
-extern struct buffer_head * minix_bread(struct inode *, int, int);
-
-extern void minix_truncate(struct inode *);
-extern void minix_put_super(struct super_block *);
-extern struct super_block *minix_read_super(struct super_block *,void *,int);
-extern int init_minix_fs(void);
-extern void minix_write_super(struct super_block *);
-extern int minix_remount (struct super_block * sb, int * flags, char * data);
-extern void minix_read_inode(struct inode *);
-extern void minix_write_inode(struct inode *);
-extern void minix_put_inode(struct inode *);
-extern void minix_statfs(struct super_block *, struct statfs *, int);
-extern int minix_sync_inode(struct inode *);
-extern int minix_sync_file(struct inode *, struct file *);
-
-extern struct inode_operations minix_file_inode_operations;
-extern struct inode_operations minix_dir_inode_operations;
-extern struct inode_operations minix_symlink_inode_operations;
-
-#endif /* __KERNEL__ */
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/minix_fs_sb.h b/i386/i386at/gpl/linux/include/linux/minix_fs_sb.h
deleted file mode 100644
index e77b4efc..00000000
--- a/i386/i386at/gpl/linux/include/linux/minix_fs_sb.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef _MINIX_FS_SB
-#define _MINIX_FS_SB
-
-/*
- * minix super-block data in memory
- */
-struct minix_sb_info {
- unsigned long s_ninodes;
- unsigned long s_nzones;
- unsigned long s_imap_blocks;
- unsigned long s_zmap_blocks;
- unsigned long s_firstdatazone;
- unsigned long s_log_zone_size;
- unsigned long s_max_size;
- struct buffer_head * s_imap[8];
- struct buffer_head * s_zmap[64];
- unsigned long s_dirsize;
- unsigned long s_namelen;
- struct buffer_head * s_sbh;
- struct minix_super_block * s_ms;
- unsigned short s_mount_state;
- unsigned short s_version;
-};
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/mm.h b/i386/i386at/gpl/linux/include/linux/mm.h
deleted file mode 100644
index f8bbb9ba..00000000
--- a/i386/i386at/gpl/linux/include/linux/mm.h
+++ /dev/null
@@ -1,297 +0,0 @@
-#ifndef _LINUX_MM_H
-#define _LINUX_MM_H
-
-#include <linux/sched.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-
-extern unsigned long high_memory;
-
-#include <asm/page.h>
-
-#ifdef __KERNEL__
-
-#define VERIFY_READ 0
-#define VERIFY_WRITE 1
-
-extern int verify_area(int, const void *, unsigned long);
-
-/*
- * Linux kernel virtual memory manager primitives.
- * The idea being to have a "virtual" mm in the same way
- * we have a virtual fs - giving a cleaner interface to the
- * mm details, and allowing different kinds of memory mappings
- * (from shared memory to executable loading to arbitrary
- * mmap() functions).
- */
-
-/*
- * This struct defines a memory VMM memory area. There is one of these
- * per VM-area/task. A VM area is any part of the process virtual memory
- * space that has a special rule for the page-fault handlers (ie a shared
- * library, the executable area etc).
- */
-struct vm_area_struct {
- struct mm_struct * vm_mm; /* VM area parameters */
- unsigned long vm_start;
- unsigned long vm_end;
- pgprot_t vm_page_prot;
- unsigned short vm_flags;
-/* AVL tree of VM areas per task, sorted by address */
- short vm_avl_height;
- struct vm_area_struct * vm_avl_left;
- struct vm_area_struct * vm_avl_right;
-/* linked list of VM areas per task, sorted by address */
- struct vm_area_struct * vm_next;
-/* for areas with inode, the circular list inode->i_mmap */
-/* for shm areas, the circular list of attaches */
-/* otherwise unused */
- struct vm_area_struct * vm_next_share;
- struct vm_area_struct * vm_prev_share;
-/* more */
- struct vm_operations_struct * vm_ops;
- unsigned long vm_offset;
- struct inode * vm_inode;
- unsigned long vm_pte; /* shared mem */
-};
-
-/*
- * vm_flags..
- */
-#define VM_READ 0x0001 /* currently active flags */
-#define VM_WRITE 0x0002
-#define VM_EXEC 0x0004
-#define VM_SHARED 0x0008
-
-#define VM_MAYREAD 0x0010 /* limits for mprotect() etc */
-#define VM_MAYWRITE 0x0020
-#define VM_MAYEXEC 0x0040
-#define VM_MAYSHARE 0x0080
-
-#define VM_GROWSDOWN 0x0100 /* general info on the segment */
-#define VM_GROWSUP 0x0200
-#define VM_SHM 0x0400 /* shared memory area, don't swap out */
-#define VM_DENYWRITE 0x0800 /* ETXTBSY on write attempts.. */
-
-#define VM_EXECUTABLE 0x1000
-#define VM_LOCKED 0x2000
-
-#define VM_STACK_FLAGS 0x0177
-
-/*
- * mapping from the currently active vm_flags protection bits (the
- * low four bits) to a page protection mask..
- */
-extern pgprot_t protection_map[16];
-
-
-/*
- * These are the virtual MM functions - opening of an area, closing and
- * unmapping it (needed to keep files on disk up-to-date etc), pointer
- * to the functions called when a no-page or a wp-page exception occurs.
- */
-struct vm_operations_struct {
- void (*open)(struct vm_area_struct * area);
- void (*close)(struct vm_area_struct * area);
- void (*unmap)(struct vm_area_struct *area, unsigned long, size_t);
- void (*protect)(struct vm_area_struct *area, unsigned long, size_t, unsigned int newprot);
- int (*sync)(struct vm_area_struct *area, unsigned long, size_t, unsigned int flags);
- void (*advise)(struct vm_area_struct *area, unsigned long, size_t, unsigned int advise);
- unsigned long (*nopage)(struct vm_area_struct * area, unsigned long address, int write_access);
- unsigned long (*wppage)(struct vm_area_struct * area, unsigned long address,
- unsigned long page);
- int (*swapout)(struct vm_area_struct *, unsigned long, pte_t *);
- pte_t (*swapin)(struct vm_area_struct *, unsigned long, unsigned long);
-};
-
-/*
- * Try to keep the most commonly accessed fields in single cache lines
- * here (16 bytes or greater). This ordering should be particularly
- * beneficial on 32-bit processors.
- *
- * The first line is data used in linear searches (eg. clock algorithm
- * scans). The second line is data used in page searches through the
- * page-cache. -- sct
- */
-typedef struct page {
- unsigned int count;
- unsigned dirty:16,
- age:8,
- uptodate:1,
- error:1,
- referenced:1,
- locked:1,
- free_after:1,
- unused:2,
- reserved:1;
- struct wait_queue *wait;
- struct page *next;
-
- struct page *next_hash;
- unsigned long offset;
- struct inode *inode;
- struct page *write_list;
-
- struct page *prev;
- struct page *prev_hash;
-} mem_map_t;
-
-extern mem_map_t * mem_map;
-
-/*
- * Free area management
- */
-
-#define NR_MEM_LISTS 6
-
-struct mem_list {
- struct mem_list * next;
- struct mem_list * prev;
-};
-
-extern struct mem_list free_area_list[NR_MEM_LISTS];
-extern unsigned int * free_area_map[NR_MEM_LISTS];
-
-/*
- * This is timing-critical - most of the time in getting a new page
- * goes to clearing the page. If you want a page without the clearing
- * overhead, just use __get_free_page() directly..
- */
-#define __get_free_page(priority) __get_free_pages((priority),0,~0UL)
-#define __get_dma_pages(priority, order) __get_free_pages((priority),(order),MAX_DMA_ADDRESS)
-extern unsigned long __get_free_pages(int priority, unsigned long gfporder, unsigned long max_addr);
-
-extern inline unsigned long get_free_page(int priority)
-{
- unsigned long page;
-
- page = __get_free_page(priority);
- if (page)
- memset((void *) page, 0, PAGE_SIZE);
- return page;
-}
-
-/* memory.c & swap.c*/
-
-#define free_page(addr) free_pages((addr),0)
-extern void free_pages(unsigned long addr, unsigned long order);
-
-extern void show_free_areas(void);
-extern unsigned long put_dirty_page(struct task_struct * tsk,unsigned long page,
- unsigned long address);
-
-extern void free_page_tables(struct task_struct * tsk);
-extern void clear_page_tables(struct task_struct * tsk);
-extern int new_page_tables(struct task_struct * tsk);
-extern int copy_page_tables(struct task_struct * to);
-
-extern int zap_page_range(struct mm_struct *mm, unsigned long address, unsigned long size);
-extern int copy_page_range(struct mm_struct *dst, struct mm_struct *src, struct vm_area_struct *vma);
-extern int remap_page_range(unsigned long from, unsigned long to, unsigned long size, pgprot_t prot);
-extern int zeromap_page_range(unsigned long from, unsigned long size, pgprot_t prot);
-
-extern void vmtruncate(struct inode * inode, unsigned long offset);
-extern void handle_mm_fault(struct vm_area_struct *vma, unsigned long address, int write_access);
-extern void do_wp_page(struct task_struct * tsk, struct vm_area_struct * vma, unsigned long address, int write_access);
-extern void do_no_page(struct task_struct * tsk, struct vm_area_struct * vma, unsigned long address, int write_access);
-
-extern unsigned long paging_init(unsigned long start_mem, unsigned long end_mem);
-extern void mem_init(unsigned long start_mem, unsigned long end_mem);
-extern void show_mem(void);
-extern void oom(struct task_struct * tsk);
-extern void si_meminfo(struct sysinfo * val);
-
-/* vmalloc.c */
-
-extern void * vmalloc(unsigned long size);
-extern void * vremap(unsigned long offset, unsigned long size);
-extern void vfree(void * addr);
-extern int vread(char *buf, char *addr, int count);
-
-/* mmap.c */
-extern unsigned long do_mmap(struct file * file, unsigned long addr, unsigned long len,
- unsigned long prot, unsigned long flags, unsigned long off);
-extern void merge_segments(struct task_struct *, unsigned long, unsigned long);
-extern void insert_vm_struct(struct task_struct *, struct vm_area_struct *);
-extern void remove_shared_vm_struct(struct vm_area_struct *);
-extern void build_mmap_avl(struct mm_struct *);
-extern void exit_mmap(struct mm_struct *);
-extern int do_munmap(unsigned long, size_t);
-extern unsigned long get_unmapped_area(unsigned long, unsigned long);
-
-/* filemap.c */
-extern unsigned long page_unuse(unsigned long);
-extern int shrink_mmap(int, unsigned long);
-extern void truncate_inode_pages(struct inode *, unsigned long);
-
-#define GFP_BUFFER 0x00
-#define GFP_ATOMIC 0x01
-#define GFP_USER 0x02
-#define GFP_KERNEL 0x03
-#define GFP_NOBUFFER 0x04
-#define GFP_NFS 0x05
-
-/* Flag - indicates that the buffer will be suitable for DMA. Ignored on some
- platforms, used as appropriate on others */
-
-#define GFP_DMA 0x80
-
-#define GFP_LEVEL_MASK 0xf
-
-#define avl_empty (struct vm_area_struct *) NULL
-
-#ifndef MACH
-static inline int expand_stack(struct vm_area_struct * vma, unsigned long address)
-{
- unsigned long grow;
-
- address &= PAGE_MASK;
- if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur)
- return -ENOMEM;
- grow = vma->vm_start - address;
- vma->vm_start = address;
- vma->vm_offset -= grow;
- vma->vm_mm->total_vm += grow >> PAGE_SHIFT;
- if (vma->vm_flags & VM_LOCKED)
- vma->vm_mm->locked_vm += grow >> PAGE_SHIFT;
- return 0;
-}
-
-/* Look up the first VMA which satisfies addr < vm_end, NULL if none. */
-static inline struct vm_area_struct * find_vma (struct task_struct * task, unsigned long addr)
-{
- struct vm_area_struct * result = NULL;
- struct vm_area_struct * tree;
-
- if (!task->mm)
- return NULL;
- for (tree = task->mm->mmap_avl ; ; ) {
- if (tree == avl_empty)
- return result;
- if (tree->vm_end > addr) {
- if (tree->vm_start <= addr)
- return tree;
- result = tree;
- tree = tree->vm_avl_left;
- } else
- tree = tree->vm_avl_right;
- }
-}
-
-/* Look up the first VMA which intersects the interval start_addr..end_addr-1,
- NULL if none. Assume start_addr < end_addr. */
-static inline struct vm_area_struct * find_vma_intersection (struct task_struct * task, unsigned long start_addr, unsigned long end_addr)
-{
- struct vm_area_struct * vma;
-
- vma = find_vma(task,start_addr);
- if (!vma || end_addr <= vma->vm_start)
- return NULL;
- return vma;
-}
-#endif /* ! MACH */
-
-#endif /* __KERNEL__ */
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/module.h b/i386/i386at/gpl/linux/include/linux/module.h
deleted file mode 100644
index a91ad19b..00000000
--- a/i386/i386at/gpl/linux/include/linux/module.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Dynamic loading of modules into the kernel.
- *
- * Modified by Bjorn Ekwall <bj0rn@blox.se>
- */
-
-#ifndef _LINUX_MODULE_H
-#define _LINUX_MODULE_H
-
-#ifdef __GENKSYMS__
-# define _set_ver(sym,vers) sym
-# undef MODVERSIONS
-# define MODVERSIONS
-#else /* ! __GENKSYMS__ */
-# if defined(MODVERSIONS) && !defined(MODULE) && defined(EXPORT_SYMTAB)
-# define _set_ver(sym,vers) sym
-# include <linux/modversions.h>
-# endif
-#endif /* __GENKSYMS__ */
-
-/* values of module.state */
-#define MOD_UNINITIALIZED 0
-#define MOD_RUNNING 1
-#define MOD_DELETED 2
-
-/* maximum length of module name */
-#define MOD_MAX_NAME 64
-
-/* magic marker for modules inserted from kerneld, to be auto-reaped */
-#define MOD_AUTOCLEAN 0x40000000 /* big enough, but no sign problems... */
-
-/* maximum length of symbol name */
-#define SYM_MAX_NAME 60
-
-struct kernel_sym { /* sent to "insmod" */
- unsigned long value; /* value of symbol */
- char name[SYM_MAX_NAME]; /* name of symbol */
-};
-
-struct module_ref {
- struct module *module;
- struct module_ref *next;
-};
-
-struct internal_symbol {
- void *addr;
- const char *name;
- };
-
-struct symbol_table { /* received from "insmod" */
- int size; /* total, including string table!!! */
- int n_symbols;
- int n_refs;
- struct internal_symbol symbol[0]; /* actual size defined by n_symbols */
- struct module_ref ref[0]; /* actual size defined by n_refs */
-};
-/*
- * Note: The string table follows immediately after the symbol table in memory!
- */
-
-struct module {
- struct module *next;
- struct module_ref *ref; /* the list of modules that refer to me */
- struct symbol_table *symtab;
- const char *name;
- int size; /* size of module in pages */
- void* addr; /* address of module */
- int state;
- void (*cleanup)(void); /* cleanup routine */
-};
-
-struct mod_routines {
- int (*init)(void); /* initialization routine */
- void (*cleanup)(void); /* cleanup routine */
-};
-
-/* rename_module_symbol(old_name, new_name) WOW! */
-extern int rename_module_symbol(char *, char *);
-
-/* insert new symbol table */
-extern int register_symtab(struct symbol_table *);
-
-/*
- * The first word of the module contains the use count.
- */
-#define GET_USE_COUNT(module) (* (long *) (module)->addr)
-/*
- * define the count variable, and usage macros.
- */
-
-#ifdef MODULE
-
-extern long mod_use_count_;
-#define MOD_INC_USE_COUNT mod_use_count_++
-#define MOD_DEC_USE_COUNT mod_use_count_--
-#define MOD_IN_USE ((mod_use_count_ & ~MOD_AUTOCLEAN) != 0)
-
-#ifndef __NO_VERSION__
-#include <linux/version.h>
-char kernel_version[]=UTS_RELEASE;
-#endif
-
-#if defined(MODVERSIONS) && !defined(__GENKSYMS__)
-int Using_Versions; /* gcc will handle this global (used as a flag) correctly */
-#endif
-
-#else
-
-#define MOD_INC_USE_COUNT do { } while (0)
-#define MOD_DEC_USE_COUNT do { } while (0)
-#define MOD_IN_USE 1
-
-#endif
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/mount.h b/i386/i386at/gpl/linux/include/linux/mount.h
deleted file mode 100644
index 357c7ae6..00000000
--- a/i386/i386at/gpl/linux/include/linux/mount.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- *
- * Definitions for mount interface. This describes the in the kernel build
- * linkedlist with mounted filesystems.
- *
- * Author: Marco van Wieringen <mvw@mcs.ow.nl> <mvw@tnix.net> <mvw@cistron.nl>
- *
- * Version: $Id: mount.h,v 1.1.1.1 1997/02/25 21:27:29 thomas Exp $
- *
- */
-#ifndef _LINUX_MOUNT_H
-#define _LINUX_MOUNT_H
-
-struct vfsmount
-{
- kdev_t mnt_dev; /* Device this applies to */
- char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */
- char *mnt_dirname; /* Name of directory mounted on */
- unsigned int mnt_flags; /* Flags of this device */
- struct semaphore mnt_sem; /* lock device while I/O in progress */
- struct super_block *mnt_sb; /* pointer to superblock */
- struct file *mnt_quotas[MAXQUOTAS]; /* fp's to quotafiles */
- time_t mnt_iexp[MAXQUOTAS]; /* expiretime for inodes */
- time_t mnt_bexp[MAXQUOTAS]; /* expiretime for blocks */
- struct vfsmount *mnt_next; /* pointer to next in linkedlist */
-};
-
-struct vfsmount *lookup_vfsmnt(kdev_t dev);
-
-#endif /* _LINUX_MOUNT_H */
diff --git a/i386/i386at/gpl/linux/include/linux/net.h b/i386/i386at/gpl/linux/include/linux/net.h
deleted file mode 100644
index 1fbe98a0..00000000
--- a/i386/i386at/gpl/linux/include/linux/net.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * NET An implementation of the SOCKET network access protocol.
- * This is the master header file for the Linux NET layer,
- * or, in plain English: the networking handling part of the
- * kernel.
- *
- * Version: @(#)net.h 1.0.3 05/25/93
- *
- * Authors: Orest Zborowski, <obz@Kodak.COM>
- * Ross Biro, <bir7@leland.Stanford.Edu>
- * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#ifndef _LINUX_NET_H
-#define _LINUX_NET_H
-
-
-#include <linux/wait.h>
-#include <linux/socket.h>
-
-
-#define NSOCKETS 2000 /* Dynamic, this is MAX LIMIT */
-#define NSOCKETS_UNIX 128 /* unix domain static limit */
-#define NPROTO 16 /* should be enough for now.. */
-
-
-#define SYS_SOCKET 1 /* sys_socket(2) */
-#define SYS_BIND 2 /* sys_bind(2) */
-#define SYS_CONNECT 3 /* sys_connect(2) */
-#define SYS_LISTEN 4 /* sys_listen(2) */
-#define SYS_ACCEPT 5 /* sys_accept(2) */
-#define SYS_GETSOCKNAME 6 /* sys_getsockname(2) */
-#define SYS_GETPEERNAME 7 /* sys_getpeername(2) */
-#define SYS_SOCKETPAIR 8 /* sys_socketpair(2) */
-#define SYS_SEND 9 /* sys_send(2) */
-#define SYS_RECV 10 /* sys_recv(2) */
-#define SYS_SENDTO 11 /* sys_sendto(2) */
-#define SYS_RECVFROM 12 /* sys_recvfrom(2) */
-#define SYS_SHUTDOWN 13 /* sys_shutdown(2) */
-#define SYS_SETSOCKOPT 14 /* sys_setsockopt(2) */
-#define SYS_GETSOCKOPT 15 /* sys_getsockopt(2) */
-#define SYS_SENDMSG 16 /* sys_sendmsg(2) */
-#define SYS_RECVMSG 17 /* sys_recvmsg(2) */
-
-
-typedef enum {
- SS_FREE = 0, /* not allocated */
- SS_UNCONNECTED, /* unconnected to any socket */
- SS_CONNECTING, /* in process of connecting */
- SS_CONNECTED, /* connected to socket */
- SS_DISCONNECTING /* in process of disconnecting */
-} socket_state;
-
-#define SO_ACCEPTCON (1<<16) /* performed a listen */
-#define SO_WAITDATA (1<<17) /* wait data to read */
-#define SO_NOSPACE (1<<18) /* no space to write */
-
-#ifdef __KERNEL__
-/*
- * Internal representation of a socket. not all the fields are used by
- * all configurations:
- *
- * server client
- * conn client connected to server connected to
- * iconn list of clients -unused-
- * awaiting connections
- * wait sleep for clients, sleep for connection,
- * sleep for i/o sleep for i/o
- */
-struct socket {
- short type; /* SOCK_STREAM, ... */
- socket_state state;
- long flags;
- struct proto_ops *ops; /* protocols do most everything */
- void *data; /* protocol data */
- struct socket *conn; /* server socket connected to */
- struct socket *iconn; /* incomplete client conn.s */
- struct socket *next;
- struct wait_queue **wait; /* ptr to place to wait on */
- struct inode *inode;
- struct fasync_struct *fasync_list; /* Asynchronous wake up list */
-};
-
-#define SOCK_INODE(S) ((S)->inode)
-
-struct proto_ops {
- int family;
-
- int (*create) (struct socket *sock, int protocol);
- int (*dup) (struct socket *newsock, struct socket *oldsock);
- int (*release) (struct socket *sock, struct socket *peer);
- int (*bind) (struct socket *sock, struct sockaddr *umyaddr,
- int sockaddr_len);
- int (*connect) (struct socket *sock, struct sockaddr *uservaddr,
- int sockaddr_len, int flags);
- int (*socketpair) (struct socket *sock1, struct socket *sock2);
- int (*accept) (struct socket *sock, struct socket *newsock,
- int flags);
- int (*getname) (struct socket *sock, struct sockaddr *uaddr,
- int *usockaddr_len, int peer);
- int (*select) (struct socket *sock, int sel_type,
- select_table *wait);
- int (*ioctl) (struct socket *sock, unsigned int cmd,
- unsigned long arg);
- int (*listen) (struct socket *sock, int len);
- int (*shutdown) (struct socket *sock, int flags);
- int (*setsockopt) (struct socket *sock, int level, int optname,
- char *optval, int optlen);
- int (*getsockopt) (struct socket *sock, int level, int optname,
- char *optval, int *optlen);
- int (*fcntl) (struct socket *sock, unsigned int cmd,
- unsigned long arg);
- int (*sendmsg) (struct socket *sock, struct msghdr *m, int total_len, int nonblock, int flags);
- int (*recvmsg) (struct socket *sock, struct msghdr *m, int total_len, int nonblock, int flags, int *addr_len);
-};
-
-struct net_proto {
- const char *name; /* Protocol name */
- void (*init_func)(struct net_proto *); /* Bootstrap */
-};
-
-extern int sock_wake_async(struct socket *sock, int how);
-extern int sock_register(int family, struct proto_ops *ops);
-extern int sock_unregister(int family);
-extern struct socket *sock_alloc(void);
-extern void sock_release(struct socket *sock);
-#endif /* __KERNEL__ */
-#endif /* _LINUX_NET_H */
diff --git a/i386/i386at/gpl/linux/include/linux/netdevice.h b/i386/i386at/gpl/linux/include/linux/netdevice.h
deleted file mode 100644
index 9e1143be..00000000
--- a/i386/i386at/gpl/linux/include/linux/netdevice.h
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
- * INET An implementation of the TCP/IP protocol suite for the LINUX
- * operating system. INET is implemented using the BSD Socket
- * interface as the means of communication with the user level.
- *
- * Definitions for the Interfaces handler.
- *
- * Version: @(#)dev.h 1.0.10 08/12/93
- *
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
- * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- * Corey Minyard <wf-rch!minyard@relay.EU.net>
- * Donald J. Becker, <becker@super.org>
- * Alan Cox, <A.Cox@swansea.ac.uk>
- * Bjorn Ekwall. <bj0rn@blox.se>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- * Moved to /usr/include/linux for NET3
- */
-#ifndef _LINUX_NETDEVICE_H
-#define _LINUX_NETDEVICE_H
-
-#include <linux/config.h>
-#include <linux/if.h>
-#include <linux/if_ether.h>
-#include <linux/skbuff.h>
-
-/* for future expansion when we will have different priorities. */
-#define DEV_NUMBUFFS 3
-#define MAX_ADDR_LEN 7
-#ifndef CONFIG_AX25
-#ifndef CONFIG_TR
-#ifndef CONFIG_NET_IPIP
-#define MAX_HEADER 32 /* We really need about 18 worst case .. so 32 is aligned */
-#else
-#define MAX_HEADER 48 /* We need to allow for having tunnel headers */
-#endif /* IPIP */
-#else
-#define MAX_HEADER 48 /* Token Ring header needs 40 bytes ... 48 is aligned */
-#endif /* TR */
-#else
-#define MAX_HEADER 96 /* AX.25 + NetROM */
-#endif /* AX25 */
-
-#define IS_MYADDR 1 /* address is (one of) our own */
-#define IS_LOOPBACK 2 /* address is for LOOPBACK */
-#define IS_BROADCAST 3 /* address is a valid broadcast */
-#define IS_INVBCAST 4 /* Wrong netmask bcast not for us (unused)*/
-#define IS_MULTICAST 5 /* Multicast IP address */
-
-/*
- * We tag multicasts with these structures.
- */
-
-struct dev_mc_list
-{
- struct dev_mc_list *next;
- char dmi_addr[MAX_ADDR_LEN];
- unsigned short dmi_addrlen;
- unsigned short dmi_users;
-};
-
-struct hh_cache
-{
- struct hh_cache *hh_next;
- void *hh_arp; /* Opaque pointer, used by
- * any address resolution module,
- * not only ARP.
- */
- unsigned int hh_refcnt; /* number of users */
- unsigned short hh_type; /* protocol identifier, f.e ETH_P_IP */
- char hh_uptodate; /* hh_data is valid */
- char hh_data[16]; /* cached hardware header */
-};
-
-/*
- * The DEVICE structure.
- * Actually, this whole structure is a big mistake. It mixes I/O
- * data with strictly "high-level" data, and it has to know about
- * almost every data structure used in the INET module.
- */
-#ifdef MACH
-#ifndef MACH_INCLUDE
-#define device linux_device
-#endif
-struct linux_device
-#else
-struct device
-#endif
-{
-
- /*
- * This is the first field of the "visible" part of this structure
- * (i.e. as seen by users in the "Space.c" file). It is the name
- * the interface.
- */
- char *name;
-
- /* I/O specific fields - FIXME: Merge these and struct ifmap into one */
- unsigned long rmem_end; /* shmem "recv" end */
- unsigned long rmem_start; /* shmem "recv" start */
- unsigned long mem_end; /* shared mem end */
- unsigned long mem_start; /* shared mem start */
- unsigned long base_addr; /* device I/O address */
- unsigned char irq; /* device IRQ number */
-
- /* Low-level status flags. */
- volatile unsigned char start, /* start an operation */
- interrupt; /* interrupt arrived */
- unsigned long tbusy; /* transmitter busy must be long for bitops */
-
- struct linux_device *next;
-
- /* The device initialization function. Called only once. */
- int (*init)(struct linux_device *dev);
-
- /* Some hardware also needs these fields, but they are not part of the
- usual set specified in Space.c. */
- unsigned char if_port; /* Selectable AUI, TP,..*/
- unsigned char dma; /* DMA channel */
-
- struct enet_statistics* (*get_stats)(struct linux_device *dev);
-
- /*
- * This marks the end of the "visible" part of the structure. All
- * fields hereafter are internal to the system, and may change at
- * will (read: may be cleaned up at will).
- */
-
- /* These may be needed for future network-power-down code. */
- unsigned long trans_start; /* Time (in jiffies) of last Tx */
- unsigned long last_rx; /* Time of last Rx */
-
- unsigned short flags; /* interface flags (a la BSD) */
- unsigned short family; /* address family ID (AF_INET) */
- unsigned short metric; /* routing metric (not used) */
- unsigned short mtu; /* interface MTU value */
- unsigned short type; /* interface hardware type */
- unsigned short hard_header_len; /* hardware hdr length */
- void *priv; /* pointer to private data */
-
- /* Interface address info. */
- unsigned char broadcast[MAX_ADDR_LEN]; /* hw bcast add */
- unsigned char pad; /* make dev_addr aligned to 8 bytes */
- unsigned char dev_addr[MAX_ADDR_LEN]; /* hw address */
- unsigned char addr_len; /* hardware address length */
- unsigned long pa_addr; /* protocol address */
- unsigned long pa_brdaddr; /* protocol broadcast addr */
- unsigned long pa_dstaddr; /* protocol P-P other side addr */
- unsigned long pa_mask; /* protocol netmask */
- unsigned short pa_alen; /* protocol address length */
-
- struct dev_mc_list *mc_list; /* Multicast mac addresses */
- int mc_count; /* Number of installed mcasts */
-
- struct ip_mc_list *ip_mc_list; /* IP multicast filter chain */
- __u32 tx_queue_len; /* Max frames per queue allowed */
-
- /* For load balancing driver pair support */
-
- unsigned long pkt_queue; /* Packets queued */
- struct linux_device *slave; /* Slave device */
- struct net_alias_info *alias_info; /* main dev alias info */
- struct net_alias *my_alias; /* alias devs */
-
- /* Pointer to the interface buffers. */
- struct sk_buff_head buffs[DEV_NUMBUFFS];
-
- /* Pointers to interface service routines. */
- int (*open)(struct linux_device *dev);
- int (*stop)(struct linux_device *dev);
- int (*hard_start_xmit) (struct sk_buff *skb,
- struct linux_device *dev);
- int (*hard_header) (struct sk_buff *skb,
- struct linux_device *dev,
- unsigned short type,
- void *daddr,
- void *saddr,
- unsigned len);
- int (*rebuild_header)(void *eth,
- struct linux_device *dev,
- unsigned long raddr, struct sk_buff *skb);
-#define HAVE_MULTICAST
- void (*set_multicast_list)(struct linux_device *dev);
-#define HAVE_SET_MAC_ADDR
- int (*set_mac_address)(struct linux_device *dev,
- void *addr);
-#define HAVE_PRIVATE_IOCTL
- int (*do_ioctl)(struct linux_device *dev,
- struct ifreq *ifr, int cmd);
-#define HAVE_SET_CONFIG
- int (*set_config)(struct linux_device *dev,
- struct ifmap *map);
-#define HAVE_HEADER_CACHE
- void (*header_cache_bind)(struct hh_cache **hhp,
- struct linux_device *dev,
- unsigned short htype,
- __u32 daddr);
- void (*header_cache_update)(struct hh_cache *hh,
- struct linux_device *dev,
- unsigned char * haddr);
-#ifdef MACH
-#ifdef MACH_INCLUDE
- struct net_data *net_data;
-#else
- void *net_data;
-#endif
-#endif
-};
-
-
-struct packet_type {
- unsigned short type; /* This is really htons(ether_type). */
- struct linux_device * dev;
- int (*func) (struct sk_buff *, struct linux_device *,
- struct packet_type *);
- void *data;
- struct packet_type *next;
-};
-
-
-#ifdef __KERNEL__
-
-#include <linux/notifier.h>
-
-/* Used by dev_rint */
-#define IN_SKBUFF 1
-
-extern volatile unsigned long in_bh;
-
-extern struct linux_device loopback_dev;
-extern struct linux_device *dev_base;
-extern struct packet_type *ptype_base[16];
-
-
-extern int ip_addr_match(unsigned long addr1, unsigned long addr2);
-extern int ip_chk_addr(unsigned long addr);
-extern struct linux_device *ip_dev_check(unsigned long daddr);
-extern unsigned long ip_my_addr(void);
-extern unsigned long ip_get_mask(unsigned long addr);
-extern struct linux_device *ip_dev_find(unsigned long addr);
-extern struct linux_device *dev_getbytype(unsigned short type);
-
-extern void dev_add_pack(struct packet_type *pt);
-extern void dev_remove_pack(struct packet_type *pt);
-extern struct linux_device *dev_get(const char *name);
-extern int dev_open(struct linux_device *dev);
-extern int dev_close(struct linux_device *dev);
-extern void dev_queue_xmit(struct sk_buff *skb,
- struct linux_device *dev,
- int pri);
-#define HAVE_NETIF_RX 1
-extern void netif_rx(struct sk_buff *skb);
-extern void dev_transmit(void);
-extern int in_net_bh(void);
-extern void net_bh(void *tmp);
-#ifdef MACH
-#define dev_tint(dev)
-#else
-extern void dev_tint(struct linux_device *dev);
-#endif
-extern int dev_get_info(char *buffer, char **start, off_t offset, int length, int dummy);
-extern int dev_ioctl(unsigned int cmd, void *);
-
-extern void dev_init(void);
-
-/* Locking protection for page faults during outputs to devices unloaded during the fault */
-
-extern int dev_lockct;
-
-/*
- * These two dont currently need to be interrupt safe
- * but they may do soon. Do it properly anyway.
- */
-
-extern __inline__ void dev_lock_list(void)
-{
- unsigned long flags;
- save_flags(flags);
- cli();
- dev_lockct++;
- restore_flags(flags);
-}
-
-extern __inline__ void dev_unlock_list(void)
-{
- unsigned long flags;
- save_flags(flags);
- cli();
- dev_lockct--;
- restore_flags(flags);
-}
-
-/*
- * This almost never occurs, isnt in performance critical paths
- * and we can thus be relaxed about it
- */
-
-extern __inline__ void dev_lock_wait(void)
-{
- while(dev_lockct)
- schedule();
-}
-
-
-/* These functions live elsewhere (drivers/net/net_init.c, but related) */
-
-extern void ether_setup(struct linux_device *dev);
-extern void tr_setup(struct linux_device *dev);
-extern int ether_config(struct linux_device *dev,
- struct ifmap *map);
-/* Support for loadable net-drivers */
-extern int register_netdev(struct linux_device *dev);
-extern void unregister_netdev(struct linux_device *dev);
-extern int register_netdevice_notifier(struct notifier_block *nb);
-extern int unregister_netdevice_notifier(struct notifier_block *nb);
-/* Functions used for multicast support */
-extern void dev_mc_upload(struct linux_device *dev);
-extern void dev_mc_delete(struct linux_device *dev,
- void *addr, int alen, int all);
-extern void dev_mc_add(struct linux_device *dev,
- void *addr, int alen, int newonly);
-extern void dev_mc_discard(struct linux_device *dev);
-/* This is the wrong place but it'll do for the moment */
-extern void ip_mc_allhost(struct linux_device *dev);
-#endif /* __KERNEL__ */
-
-#endif /* _LINUX_DEV_H */
diff --git a/i386/i386at/gpl/linux/include/linux/nfs.h b/i386/i386at/gpl/linux/include/linux/nfs.h
deleted file mode 100644
index ceb0cd1b..00000000
--- a/i386/i386at/gpl/linux/include/linux/nfs.h
+++ /dev/null
@@ -1,172 +0,0 @@
-#ifndef _LINUX_NFS_H
-#define _LINUX_NFS_H
-
-#ifndef MACH_INCLUDE
-#define NFS_PORT 2049
-#define NFS_MAXDATA 8192
-#define NFS_MAXPATHLEN 1024
-#define NFS_MAXNAMLEN 255
-#define NFS_MAXGROUPS 16
-#define NFS_FHSIZE 32
-#define NFS_COOKIESIZE 4
-#define NFS_FIFO_DEV (-1)
-#define NFSMODE_FMT 0170000
-#define NFSMODE_DIR 0040000
-#define NFSMODE_CHR 0020000
-#define NFSMODE_BLK 0060000
-#define NFSMODE_REG 0100000
-#define NFSMODE_LNK 0120000
-#define NFSMODE_SOCK 0140000
-#define NFSMODE_FIFO 0010000
-
-#ifdef __KERNEL__ /* user programs should get these from the rpc header files */
-
-#define RPC_VERSION 2
-
-enum rpc_auth_flavor {
- RPC_AUTH_NULL = 0,
- RPC_AUTH_UNIX = 1,
- RPC_AUTH_SHORT = 2
-};
-
-enum rpc_msg_type {
- RPC_CALL = 0,
- RPC_REPLY = 1
-};
-
-enum rpc_reply_stat {
- RPC_MSG_ACCEPTED = 0,
- RPC_MSG_DENIED = 1
-};
-
-enum rpc_accept_stat {
- RPC_SUCCESS = 0,
- RPC_PROG_UNAVAIL = 1,
- RPC_PROG_MISMATCH = 2,
- RPC_PROC_UNAVAIL = 3,
- RPC_GARBAGE_ARGS = 4
-};
-
-enum rpc_reject_stat {
- RPC_MISMATCH = 0,
- RPC_AUTH_ERROR = 1
-};
-
-enum rpc_auth_stat {
- RPC_AUTH_BADCRED = 1,
- RPC_AUTH_REJECTEDCRED = 2,
- RPC_AUTH_BADVERF = 3,
- RPC_AUTH_REJECTEDVERF = 4,
- RPC_AUTH_TOOWEAK = 5
-};
-
-#endif /* __KERNEL__ */
-
-enum nfs_stat {
- NFS_OK = 0,
- NFSERR_PERM = 1,
- NFSERR_NOENT = 2,
- NFSERR_IO = 5,
- NFSERR_NXIO = 6,
- NFSERR_EAGAIN = 11,
- NFSERR_ACCES = 13,
- NFSERR_EXIST = 17,
- NFSERR_NODEV = 19,
- NFSERR_NOTDIR = 20,
- NFSERR_ISDIR = 21,
- NFSERR_INVAL = 22, /* that Sun forgot */
- NFSERR_FBIG = 27,
- NFSERR_NOSPC = 28,
- NFSERR_ROFS = 30,
- NFSERR_NAMETOOLONG = 63,
- NFSERR_NOTEMPTY = 66,
- NFSERR_DQUOT = 69,
- NFSERR_STALE = 70,
- NFSERR_WFLUSH = 99
-};
-
-enum nfs_ftype {
- NFNON = 0,
- NFREG = 1,
- NFDIR = 2,
- NFBLK = 3,
- NFCHR = 4,
- NFLNK = 5,
- NFSOCK = 6,
- NFBAD = 7,
- NFFIFO = 8
-};
-
-#define NFS_PROGRAM 100003
-#define NFS_VERSION 2
-#define NFSPROC_NULL 0
-#define NFSPROC_GETATTR 1
-#define NFSPROC_SETATTR 2
-#define NFSPROC_ROOT 3
-#define NFSPROC_LOOKUP 4
-#define NFSPROC_READLINK 5
-#define NFSPROC_READ 6
-#define NFSPROC_WRITECACHE 7
-#define NFSPROC_WRITE 8
-#define NFSPROC_CREATE 9
-#define NFSPROC_REMOVE 10
-#define NFSPROC_RENAME 11
-#define NFSPROC_LINK 12
-#define NFSPROC_SYMLINK 13
-#define NFSPROC_MKDIR 14
-#define NFSPROC_RMDIR 15
-#define NFSPROC_READDIR 16
-#define NFSPROC_STATFS 17
-
-struct nfs_fh {
- char data[NFS_FHSIZE];
-};
-
-struct nfs_time {
- u_int seconds;
- u_int useconds;
-};
-
-struct nfs_fattr {
- enum nfs_ftype type;
- u_int mode;
- u_int nlink;
- u_int uid;
- u_int gid;
- u_int size;
- u_int blocksize;
- u_int rdev;
- u_int blocks;
- u_int fsid;
- u_int fileid;
- struct nfs_time atime;
- struct nfs_time mtime;
- struct nfs_time ctime;
-};
-
-struct nfs_sattr {
- u_int mode;
- u_int uid;
- u_int gid;
- u_int size;
- struct nfs_time atime;
- struct nfs_time mtime;
-};
-
-struct nfs_entry {
- u_int fileid;
- char *name;
- int cookie;
- int eof;
-};
-
-struct nfs_fsinfo {
- u_int tsize;
- u_int bsize;
- u_int blocks;
- u_int bfree;
- u_int bavail;
-};
-
-#endif /* ! MACH_INCLUDE */
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/notifier.h b/i386/i386at/gpl/linux/include/linux/notifier.h
deleted file mode 100644
index 3de4d976..00000000
--- a/i386/i386at/gpl/linux/include/linux/notifier.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Routines to manage notifier chains for passing status changes to any
- * interested routines. We need this instead of hard coded call lists so
- * that modules can poke their nose into the innards. The network devices
- * needed them so here they are for the rest of you.
- *
- * Alan Cox <Alan.Cox@linux.org>
- */
-
-#ifndef _LINUX_NOTIFIER_H
-#define _LINUX_NOTIFIER_H
-#include <linux/errno.h>
-
-struct notifier_block
-{
- int (*notifier_call)(struct notifier_block *this, unsigned long, void *);
- struct notifier_block *next;
- int priority;
-};
-
-
-#ifdef __KERNEL__
-
-#define NOTIFY_DONE 0x0000 /* Don't care */
-#define NOTIFY_OK 0x0001 /* Suits me */
-#define NOTIFY_STOP_MASK 0x8000 /* Don't call further */
-#define NOTIFY_BAD (NOTIFY_STOP_MASK|0x0002) /* Bad/Veto action */
-
-extern __inline__ int notifier_chain_register(struct notifier_block **list, struct notifier_block *n)
-{
- while(*list)
- {
- if(n->priority > (*list)->priority)
- break;
- list= &((*list)->next);
- }
- n->next = *list;
- *list=n;
- return 0;
-}
-
-/*
- * Warning to any non GPL module writers out there.. these functions are
- * GPL'd
- */
-
-extern __inline__ int notifier_chain_unregister(struct notifier_block **nl, struct notifier_block *n)
-{
- while((*nl)!=NULL)
- {
- if((*nl)==n)
- {
- *nl=n->next;
- return 0;
- }
- nl=&((*nl)->next);
- }
-#ifdef MACH_INCLUDE
- return -LINUX_ENOENT;
-#else
- return -ENOENT;
-#endif
-}
-
-/*
- * This is one of these things that is generally shorter inline
- */
-
-extern __inline__ int notifier_call_chain(struct notifier_block **n, unsigned long val, void *v)
-{
- int ret=NOTIFY_DONE;
- struct notifier_block *nb = *n;
- while(nb)
- {
- ret=nb->notifier_call(nb,val,v);
- if(ret&NOTIFY_STOP_MASK)
- return ret;
- nb=nb->next;
- }
- return ret;
-}
-
-
-/*
- * Declared notifiers so far. I can imagine quite a few more chains
- * over time (eg laptop power reset chains, reboot chain (to clean
- * device units up), device [un]mount chain, module load/unload chain,
- * low memory chain, screenblank chain (for plug in modular screenblankers)
- * VC switch chains (for loadable kernel svgalib VC switch helpers) etc...
- */
-
-/* netdevice notifier chain */
-#define NETDEV_UP 0x0001 /* For now you can't veto a device up/down */
-#define NETDEV_DOWN 0x0002
-#define NETDEV_REBOOT 0x0003 /* Tell a protocol stack a network interface
- detected a hardware crash and restarted
- - we can use this eg to kick tcp sessions
- once done */
-#endif
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/pagemap.h b/i386/i386at/gpl/linux/include/linux/pagemap.h
deleted file mode 100644
index 6de993b3..00000000
--- a/i386/i386at/gpl/linux/include/linux/pagemap.h
+++ /dev/null
@@ -1,131 +0,0 @@
-#ifndef _LINUX_PAGEMAP_H
-#define _LINUX_PAGEMAP_H
-
-#include <asm/system.h>
-
-/*
- * Page-mapping primitive inline functions
- *
- * Copyright 1995 Linus Torvalds
- */
-
-#ifndef MACH
-static inline unsigned long page_address(struct page * page)
-{
- return PAGE_OFFSET + PAGE_SIZE*(page - mem_map);
-}
-
-#define PAGE_HASH_BITS 10
-#define PAGE_HASH_SIZE (1 << PAGE_HASH_BITS)
-
-#define PAGE_AGE_VALUE 16
-
-extern unsigned long page_cache_size;
-extern struct page * page_hash_table[PAGE_HASH_SIZE];
-
-/*
- * We use a power-of-two hash table to avoid a modulus,
- * and get a reasonable hash by knowing roughly how the
- * inode pointer and offsets are distributed (ie, we
- * roughly know which bits are "significant")
- */
-static inline unsigned long _page_hashfn(struct inode * inode, unsigned long offset)
-{
-#define i (((unsigned long) inode)/sizeof(unsigned long))
-#define o (offset >> PAGE_SHIFT)
-#define s(x) ((x)+((x)>>PAGE_HASH_BITS))
- return s(i+o) & (PAGE_HASH_SIZE-1);
-#undef i
-#undef o
-#undef s
-}
-
-#define page_hash(inode,offset) page_hash_table[_page_hashfn(inode,offset)]
-
-static inline struct page * find_page(struct inode * inode, unsigned long offset)
-{
- struct page *page;
- unsigned long flags;
-
- for (page = page_hash(inode, offset); page ; page = page->next_hash) {
- if (page->inode != inode)
- continue;
- if (page->offset != offset)
- continue;
- save_flags(flags);
- cli();
- page->referenced = 1;
- page->count++;
- restore_flags(flags);
- break;
- }
- return page;
-}
-
-static inline void remove_page_from_hash_queue(struct page * page)
-{
- struct page **p = &page_hash(page->inode,page->offset);
-
- page_cache_size--;
- if (page->next_hash)
- page->next_hash->prev_hash = page->prev_hash;
- if (page->prev_hash)
- page->prev_hash->next_hash = page->next_hash;
- if (*p == page)
- *p = page->next_hash;
- page->next_hash = page->prev_hash = NULL;
-}
-
-static inline void add_page_to_hash_queue(struct inode * inode, struct page * page)
-{
- struct page **p = &page_hash(inode,page->offset);
-
- page_cache_size++;
- page->referenced = 1;
- page->age = PAGE_AGE_VALUE;
- page->prev_hash = NULL;
- if ((page->next_hash = *p) != NULL)
- page->next_hash->prev_hash = page;
- *p = page;
-}
-
-static inline void remove_page_from_inode_queue(struct page * page)
-{
- struct inode * inode = page->inode;
-
- page->inode = NULL;
- inode->i_nrpages--;
- if (inode->i_pages == page)
- inode->i_pages = page->next;
- if (page->next)
- page->next->prev = page->prev;
- if (page->prev)
- page->prev->next = page->next;
- page->next = NULL;
- page->prev = NULL;
-}
-
-static inline void add_page_to_inode_queue(struct inode * inode, struct page * page)
-{
- struct page **p = &inode->i_pages;
-
- inode->i_nrpages++;
- page->inode = inode;
- page->prev = NULL;
- if ((page->next = *p) != NULL)
- page->next->prev = page;
- *p = page;
-}
-
-extern void __wait_on_page(struct page *);
-static inline void wait_on_page(struct page * page)
-{
- if (page->locked)
- __wait_on_page(page);
-}
-
-extern void update_vm_cache(struct inode *, unsigned long, const char *, int);
-
-#endif /* ! MACH */
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/param.h b/i386/i386at/gpl/linux/include/linux/param.h
deleted file mode 100644
index 092e92f6..00000000
--- a/i386/i386at/gpl/linux/include/linux/param.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _LINUX_PARAM_H
-#define _LINUX_PARAM_H
-
-#include <asm/param.h>
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/pci.h b/i386/i386at/gpl/linux/include/linux/pci.h
deleted file mode 100644
index 9e059501..00000000
--- a/i386/i386at/gpl/linux/include/linux/pci.h
+++ /dev/null
@@ -1,618 +0,0 @@
-/*
- * PCI defines and function prototypes
- * Copyright 1994, Drew Eckhardt
- *
- * For more information, please consult
- *
- * PCI BIOS Specification Revision
- * PCI Local Bus Specification
- * PCI System Design Guide
- *
- * PCI Special Interest Group
- * M/S HF3-15A
- * 5200 N.E. Elam Young Parkway
- * Hillsboro, Oregon 97124-6497
- * +1 (503) 696-2000
- * +1 (800) 433-5177
- *
- * Manuals are $25 each or $50 for all three, plus $7 shipping
- * within the United States, $35 abroad.
- */
-
-
-
-/* PROCEDURE TO REPORT NEW PCI DEVICES
- * We are trying to collect informations on new PCI devices, using
- * the standart PCI identification procedure. If some warning is
- * displayed at boot time, please report
- * - /proc/pci
- * - your exact hardware description. Try to find out
- * which device is unknown. It may be you mainboard chipset.
- * PCI-CPU bridge or PCI-ISA bridge.
- * - If you can't find the actual information in your hardware
- * booklet, try to read the references of the chip on the board.
- * - Send all that, with the word PCIPROBE in the subject,
- * to frederic@cao-vlsi.ibp.fr, and I'll add your device to
- * the list as soon as possible
- * fred.
- */
-
-
-
-#ifndef PCI_H
-#define PCI_H
-
-/*
- * Under PCI, each device has 256 bytes of configuration address space,
- * of which the first 64 bytes are standardized as follows:
- */
-#define PCI_VENDOR_ID 0x00 /* 16 bits */
-#define PCI_DEVICE_ID 0x02 /* 16 bits */
-#define PCI_COMMAND 0x04 /* 16 bits */
-#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */
-#define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */
-#define PCI_COMMAND_MASTER 0x4 /* Enable bus mastering */
-#define PCI_COMMAND_SPECIAL 0x8 /* Enable response to special cycles */
-#define PCI_COMMAND_INVALIDATE 0x10 /* Use memory write and invalidate */
-#define PCI_COMMAND_VGA_PALETTE 0x20 /* Enable palette snooping */
-#define PCI_COMMAND_PARITY 0x40 /* Enable parity checking */
-#define PCI_COMMAND_WAIT 0x80 /* Enable address/data stepping */
-#define PCI_COMMAND_SERR 0x100 /* Enable SERR */
-#define PCI_COMMAND_FAST_BACK 0x200 /* Enable back-to-back writes */
-
-#define PCI_STATUS 0x06 /* 16 bits */
-#define PCI_STATUS_66MHZ 0x20 /* Support 66 Mhz PCI 2.1 bus */
-#define PCI_STATUS_UDF 0x40 /* Support User Definable Features */
-
-#define PCI_STATUS_FAST_BACK 0x80 /* Accept fast-back to back */
-#define PCI_STATUS_PARITY 0x100 /* Detected parity error */
-#define PCI_STATUS_DEVSEL_MASK 0x600 /* DEVSEL timing */
-#define PCI_STATUS_DEVSEL_FAST 0x000
-#define PCI_STATUS_DEVSEL_MEDIUM 0x200
-#define PCI_STATUS_DEVSEL_SLOW 0x400
-#define PCI_STATUS_SIG_TARGET_ABORT 0x800 /* Set on target abort */
-#define PCI_STATUS_REC_TARGET_ABORT 0x1000 /* Master ack of " */
-#define PCI_STATUS_REC_MASTER_ABORT 0x2000 /* Set on master abort */
-#define PCI_STATUS_SIG_SYSTEM_ERROR 0x4000 /* Set when we drive SERR */
-#define PCI_STATUS_DETECTED_PARITY 0x8000 /* Set on parity error */
-
-#define PCI_CLASS_REVISION 0x08 /* High 24 bits are class, low 8
- revision */
-#define PCI_REVISION_ID 0x08 /* Revision ID */
-#define PCI_CLASS_PROG 0x09 /* Reg. Level Programming Interface */
-#define PCI_CLASS_DEVICE 0x0a /* Device class */
-
-#define PCI_CACHE_LINE_SIZE 0x0c /* 8 bits */
-#define PCI_LATENCY_TIMER 0x0d /* 8 bits */
-#define PCI_HEADER_TYPE 0x0e /* 8 bits */
-#define PCI_BIST 0x0f /* 8 bits */
-#define PCI_BIST_CODE_MASK 0x0f /* Return result */
-#define PCI_BIST_START 0x40 /* 1 to start BIST, 2 secs or less */
-#define PCI_BIST_CAPABLE 0x80 /* 1 if BIST capable */
-
-/*
- * Base addresses specify locations in memory or I/O space.
- * Decoded size can be determined by writing a value of
- * 0xffffffff to the register, and reading it back. Only
- * 1 bits are decoded.
- */
-#define PCI_BASE_ADDRESS_0 0x10 /* 32 bits */
-#define PCI_BASE_ADDRESS_1 0x14 /* 32 bits */
-#define PCI_BASE_ADDRESS_2 0x18 /* 32 bits */
-#define PCI_BASE_ADDRESS_3 0x1c /* 32 bits */
-#define PCI_BASE_ADDRESS_4 0x20 /* 32 bits */
-#define PCI_BASE_ADDRESS_5 0x24 /* 32 bits */
-#define PCI_BASE_ADDRESS_SPACE 0x01 /* 0 = memory, 1 = I/O */
-#define PCI_BASE_ADDRESS_SPACE_IO 0x01
-#define PCI_BASE_ADDRESS_SPACE_MEMORY 0x00
-#define PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06
-#define PCI_BASE_ADDRESS_MEM_TYPE_32 0x00 /* 32 bit address */
-#define PCI_BASE_ADDRESS_MEM_TYPE_1M 0x02 /* Below 1M */
-#define PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 /* 64 bit address */
-#define PCI_BASE_ADDRESS_MEM_PREFETCH 0x08 /* prefetchable? */
-#define PCI_BASE_ADDRESS_MEM_MASK (~0x0f)
-#define PCI_BASE_ADDRESS_IO_MASK (~0x03)
-/* bit 1 is reserved if address_space = 1 */
-
-#define PCI_CARDBUS_CIS 0x28
-#define PCI_SUBSYSTEM_ID 0x2c
-#define PCI_SUBSYSTEM_VENDOR_ID 0x2e
-#define PCI_ROM_ADDRESS 0x30 /* 32 bits */
-#define PCI_ROM_ADDRESS_ENABLE 0x01 /* Write 1 to enable ROM,
- bits 31..11 are address,
- 10..2 are reserved */
-/* 0x34-0x3b are reserved */
-#define PCI_INTERRUPT_LINE 0x3c /* 8 bits */
-#define PCI_INTERRUPT_PIN 0x3d /* 8 bits */
-#define PCI_MIN_GNT 0x3e /* 8 bits */
-#define PCI_MAX_LAT 0x3f /* 8 bits */
-
-#define PCI_CLASS_NOT_DEFINED 0x0000
-#define PCI_CLASS_NOT_DEFINED_VGA 0x0001
-
-#define PCI_BASE_CLASS_STORAGE 0x01
-#define PCI_CLASS_STORAGE_SCSI 0x0100
-#define PCI_CLASS_STORAGE_IDE 0x0101
-#define PCI_CLASS_STORAGE_FLOPPY 0x0102
-#define PCI_CLASS_STORAGE_IPI 0x0103
-#define PCI_CLASS_STORAGE_RAID 0x0104
-#define PCI_CLASS_STORAGE_OTHER 0x0180
-
-#define PCI_BASE_CLASS_NETWORK 0x02
-#define PCI_CLASS_NETWORK_ETHERNET 0x0200
-#define PCI_CLASS_NETWORK_TOKEN_RING 0x0201
-#define PCI_CLASS_NETWORK_FDDI 0x0202
-#define PCI_CLASS_NETWORK_ATM 0x0203
-#define PCI_CLASS_NETWORK_OTHER 0x0280
-
-#define PCI_BASE_CLASS_DISPLAY 0x03
-#define PCI_CLASS_DISPLAY_VGA 0x0300
-#define PCI_CLASS_DISPLAY_XGA 0x0301
-#define PCI_CLASS_DISPLAY_OTHER 0x0380
-
-#define PCI_BASE_CLASS_MULTIMEDIA 0x04
-#define PCI_CLASS_MULTIMEDIA_VIDEO 0x0400
-#define PCI_CLASS_MULTIMEDIA_AUDIO 0x0401
-#define PCI_CLASS_MULTIMEDIA_OTHER 0x0480
-
-#define PCI_BASE_CLASS_MEMORY 0x05
-#define PCI_CLASS_MEMORY_RAM 0x0500
-#define PCI_CLASS_MEMORY_FLASH 0x0501
-#define PCI_CLASS_MEMORY_OTHER 0x0580
-
-#define PCI_BASE_CLASS_BRIDGE 0x06
-#define PCI_CLASS_BRIDGE_HOST 0x0600
-#define PCI_CLASS_BRIDGE_ISA 0x0601
-#define PCI_CLASS_BRIDGE_EISA 0x0602
-#define PCI_CLASS_BRIDGE_MC 0x0603
-#define PCI_CLASS_BRIDGE_PCI 0x0604
-#define PCI_CLASS_BRIDGE_PCMCIA 0x0605
-#define PCI_CLASS_BRIDGE_NUBUS 0x0606
-#define PCI_CLASS_BRIDGE_CARDBUS 0x0607
-#define PCI_CLASS_BRIDGE_OTHER 0x0680
-
-
-#define PCI_BASE_CLASS_COMMUNICATION 0x07
-#define PCI_CLASS_COMMUNICATION_SERIAL 0x0700
-#define PCI_CLASS_COMMUNICATION_PARALLEL 0x0701
-#define PCI_CLASS_COMMUNICATION_OTHER 0x0780
-
-#define PCI_BASE_CLASS_SYSTEM 0x08
-#define PCI_CLASS_SYSTEM_PIC 0x0800
-#define PCI_CLASS_SYSTEM_DMA 0x0801
-#define PCI_CLASS_SYSTEM_TIMER 0x0802
-#define PCI_CLASS_SYSTEM_RTC 0x0803
-#define PCI_CLASS_SYSTEM_OTHER 0x0880
-
-#define PCI_BASE_CLASS_INPUT 0x09
-#define PCI_CLASS_INPUT_KEYBOARD 0x0900
-#define PCI_CLASS_INPUT_PEN 0x0901
-#define PCI_CLASS_INPUT_MOUSE 0x0902
-#define PCI_CLASS_INPUT_OTHER 0x0980
-
-#define PCI_BASE_CLASS_DOCKING 0x0a
-#define PCI_CLASS_DOCKING_GENERIC 0x0a00
-#define PCI_CLASS_DOCKING_OTHER 0x0a01
-
-#define PCI_BASE_CLASS_PROCESSOR 0x0b
-#define PCI_CLASS_PROCESSOR_386 0x0b00
-#define PCI_CLASS_PROCESSOR_486 0x0b01
-#define PCI_CLASS_PROCESSOR_PENTIUM 0x0b02
-#define PCI_CLASS_PROCESSOR_ALPHA 0x0b10
-#define PCI_CLASS_PROCESSOR_POWERPC 0x0b20
-#define PCI_CLASS_PROCESSOR_CO 0x0b40
-
-#define PCI_BASE_CLASS_SERIAL 0x0c
-#define PCI_CLASS_SERIAL_FIREWIRE 0x0c00
-#define PCI_CLASS_SERIAL_ACCESS 0x0c01
-#define PCI_CLASS_SERIAL_SSA 0x0c02
-#define PCI_CLASS_SERIAL_USB 0x0c03
-#define PCI_CLASS_SERIAL_FIBER 0x0c04
-
-#define PCI_CLASS_OTHERS 0xff
-
-/*
- * Vendor and card ID's: sort these numerically according to vendor
- * (and according to card ID within vendor)
- */
-#define PCI_VENDOR_ID_COMPAQ 0x0e11
-#define PCI_DEVICE_ID_COMPAQ_1280 0x3033
-#define PCI_DEVICE_ID_COMPAQ_THUNDER 0xf130
-
-#define PCI_VENDOR_ID_NCR 0x1000
-#define PCI_DEVICE_ID_NCR_53C810 0x0001
-#define PCI_DEVICE_ID_NCR_53C820 0x0002
-#define PCI_DEVICE_ID_NCR_53C825 0x0003
-#define PCI_DEVICE_ID_NCR_53C815 0x0004
-
-#define PCI_VENDOR_ID_ATI 0x1002
-#define PCI_DEVICE_ID_ATI_68800 0x4158
-#define PCI_DEVICE_ID_ATI_215CT222 0x4354
-#define PCI_DEVICE_ID_ATI_210888CX 0x4358
-#define PCI_DEVICE_ID_ATI_210888GX 0x4758
-
-#define PCI_VENDOR_ID_VLSI 0x1004
-#define PCI_DEVICE_ID_VLSI_82C592 0x0005
-#define PCI_DEVICE_ID_VLSI_82C593 0x0006
-#define PCI_DEVICE_ID_VLSI_82C594 0x0007
-#define PCI_DEVICE_ID_VLSI_82C597 0x0009
-
-#define PCI_VENDOR_ID_ADL 0x1005
-#define PCI_DEVICE_ID_ADL_2301 0x2301
-
-#define PCI_VENDOR_ID_NS 0x100b
-#define PCI_DEVICE_ID_NS_87410 0xd001
-
-#define PCI_VENDOR_ID_TSENG 0x100c
-#define PCI_DEVICE_ID_TSENG_W32P_2 0x3202
-#define PCI_DEVICE_ID_TSENG_W32P_b 0x3205
-#define PCI_DEVICE_ID_TSENG_W32P_c 0x3206
-#define PCI_DEVICE_ID_TSENG_W32P_d 0x3207
-
-#define PCI_VENDOR_ID_WEITEK 0x100e
-#define PCI_DEVICE_ID_WEITEK_P9000 0x9001
-#define PCI_DEVICE_ID_WEITEK_P9100 0x9100
-
-#define PCI_VENDOR_ID_DEC 0x1011
-#define PCI_DEVICE_ID_DEC_BRD 0x0001
-#define PCI_DEVICE_ID_DEC_TULIP 0x0002
-#define PCI_DEVICE_ID_DEC_TGA 0x0004
-#define PCI_DEVICE_ID_DEC_TULIP_FAST 0x0009
-#define PCI_DEVICE_ID_DEC_FDDI 0x000F
-#define PCI_DEVICE_ID_DEC_TULIP_PLUS 0x0014
-
-#define PCI_VENDOR_ID_CIRRUS 0x1013
-#define PCI_DEVICE_ID_CIRRUS_5430 0x00a0
-#define PCI_DEVICE_ID_CIRRUS_5434_4 0x00a4
-#define PCI_DEVICE_ID_CIRRUS_5434_8 0x00a8
-#define PCI_DEVICE_ID_CIRRUS_5436 0x00ac
-#define PCI_DEVICE_ID_CIRRUS_6205 0x0205
-#define PCI_DEVICE_ID_CIRRUS_6729 0x1100
-#define PCI_DEVICE_ID_CIRRUS_7542 0x1200
-#define PCI_DEVICE_ID_CIRRUS_7543 0x1202
-
-#define PCI_VENDOR_ID_IBM 0x1014
-#define PCI_DEVICE_ID_IBM_82G2675 0x001d
-
-#define PCI_VENDOR_ID_WD 0x101c
-#define PCI_DEVICE_ID_WD_7197 0x3296
-
-#define PCI_VENDOR_ID_AMD 0x1022
-#define PCI_DEVICE_ID_AMD_LANCE 0x2000
-#define PCI_DEVICE_ID_AMD_SCSI 0x2020
-
-#define PCI_VENDOR_ID_TRIDENT 0x1023
-#define PCI_DEVICE_ID_TRIDENT_9420 0x9420
-#define PCI_DEVICE_ID_TRIDENT_9440 0x9440
-#define PCI_DEVICE_ID_TRIDENT_9660 0x9660
-
-#define PCI_VENDOR_ID_AI 0x1025
-#define PCI_DEVICE_ID_AI_M1435 0x1435
-
-#define PCI_VENDOR_ID_MATROX 0x102B
-#define PCI_DEVICE_ID_MATROX_MGA_2 0x0518
-#define PCI_DEVICE_ID_MATROX_MIL 0x0519
-#define PCI_DEVICE_ID_MATROX_MGA_IMP 0x0d10
-
-#define PCI_VENDOR_ID_CT 0x102c
-#define PCI_DEVICE_ID_CT_65545 0x00d8
-
-#define PCI_VENDOR_ID_FD 0x1036
-#define PCI_DEVICE_ID_FD_36C70 0x0000
-
-#define PCI_VENDOR_ID_SI 0x1039
-#define PCI_DEVICE_ID_SI_6201 0x0001
-#define PCI_DEVICE_ID_SI_6202 0x0002
-#define PCI_DEVICE_ID_SI_503 0x0008
-#define PCI_DEVICE_ID_SI_501 0x0406
-#define PCI_DEVICE_ID_SI_496 0x0496
-#define PCI_DEVICE_ID_SI_601 0x0601
-#define PCI_DEVICE_ID_SI_5511 0x5511
-#define PCI_DEVICE_ID_SI_5513 0x5513
-
-#define PCI_VENDOR_ID_HP 0x103c
-#define PCI_DEVICE_ID_HP_J2585A 0x1030
-
-#define PCI_VENDOR_ID_PCTECH 0x1042
-#define PCI_DEVICE_ID_PCTECH_RZ1000 0x1000
-
-#define PCI_VENDOR_ID_DPT 0x1044
-#define PCI_DEVICE_ID_DPT 0xa400
-
-#define PCI_VENDOR_ID_OPTI 0x1045
-#define PCI_DEVICE_ID_OPTI_92C178 0xc178
-#define PCI_DEVICE_ID_OPTI_82C557 0xc557
-#define PCI_DEVICE_ID_OPTI_82C558 0xc558
-#define PCI_DEVICE_ID_OPTI_82C621 0xc621
-#define PCI_DEVICE_ID_OPTI_82C822 0xc822
-
-#define PCI_VENDOR_ID_SGS 0x104a
-#define PCI_DEVICE_ID_SGS_2000 0x0008
-#define PCI_DEVICE_ID_SGS_1764 0x0009
-
-#define PCI_VENDOR_ID_BUSLOGIC 0x104B
-#define PCI_DEVICE_ID_BUSLOGIC_946C_2 0x0140
-#define PCI_DEVICE_ID_BUSLOGIC_946C 0x1040
-#define PCI_DEVICE_ID_BUSLOGIC_930 0x8130
-
-#define PCI_VENDOR_ID_OAK 0x104e
-#define PCI_DEVICE_ID_OAK_OTI107 0x0107
-
-#define PCI_VENDOR_ID_PROMISE 0x105a
-#define PCI_DEVICE_ID_PROMISE_5300 0x5300
-
-#define PCI_VENDOR_ID_N9 0x105d
-#define PCI_DEVICE_ID_N9_I128 0x2309
-#define PCI_DEVICE_ID_N9_I128_2 0x2339
-
-#define PCI_VENDOR_ID_UMC 0x1060
-#define PCI_DEVICE_ID_UMC_UM8673F 0x0101
-#define PCI_DEVICE_ID_UMC_UM8891A 0x0891
-#define PCI_DEVICE_ID_UMC_UM8886BF 0x673a
-#define PCI_DEVICE_ID_UMC_UM8886A 0x886a
-#define PCI_DEVICE_ID_UMC_UM8881F 0x8881
-#define PCI_DEVICE_ID_UMC_UM8886F 0x8886
-#define PCI_DEVICE_ID_UMC_UM9017F 0x9017
-#define PCI_DEVICE_ID_UMC_UM8886N 0xe886
-#define PCI_DEVICE_ID_UMC_UM8891N 0xe891
-
-#define PCI_VENDOR_ID_X 0x1061
-#define PCI_DEVICE_ID_X_AGX016 0x0001
-
-#define PCI_VENDOR_ID_NEXGEN 0x1074
-#define PCI_DEVICE_ID_NEXGEN_82C501 0x4e78
-
-#define PCI_VENDOR_ID_QLOGIC 0x1077
-#define PCI_DEVICE_ID_QLOGIC_ISP1020 0x1020
-#define PCI_DEVICE_ID_QLOGIC_ISP1022 0x1022
-
-#define PCI_VENDOR_ID_LEADTEK 0x107d
-#define PCI_DEVICE_ID_LEADTEK_805 0x0000
-
-#define PCI_VENDOR_ID_CONTAQ 0x1080
-#define PCI_DEVICE_ID_CONTAQ_82C599 0x0600
-
-#define PCI_VENDOR_ID_FOREX 0x1083
-
-#define PCI_VENDOR_ID_OLICOM 0x108d
-
-#define PCI_VENDOR_ID_CMD 0x1095
-#define PCI_DEVICE_ID_CMD_640 0x0640
-#define PCI_DEVICE_ID_CMD_646 0x0646
-
-#define PCI_VENDOR_ID_VISION 0x1098
-#define PCI_DEVICE_ID_VISION_QD8500 0x0001
-#define PCI_DEVICE_ID_VISION_QD8580 0x0002
-
-#define PCI_VENDOR_ID_SIERRA 0x10a8
-#define PCI_DEVICE_ID_SIERRA_STB 0x0000
-
-#define PCI_VENDOR_ID_ACC 0x10aa
-#define PCI_DEVICE_ID_ACC_2056 0x0000
-
-#define PCI_VENDOR_ID_WINBOND 0x10ad
-#define PCI_DEVICE_ID_WINBOND_83769 0x0001
-#define PCI_DEVICE_ID_WINBOND_82C105 0x0105
-
-#define PCI_VENDOR_ID_3COM 0x10b7
-#define PCI_DEVICE_ID_3COM_3C590 0x5900
-#define PCI_DEVICE_ID_3COM_3C595TX 0x5950
-#define PCI_DEVICE_ID_3COM_3C595T4 0x5951
-#define PCI_DEVICE_ID_3COM_3C595MII 0x5952
-
-#define PCI_VENDOR_ID_AL 0x10b9
-#define PCI_DEVICE_ID_AL_M1445 0x1445
-#define PCI_DEVICE_ID_AL_M1449 0x1449
-#define PCI_DEVICE_ID_AL_M1451 0x1451
-#define PCI_DEVICE_ID_AL_M1461 0x1461
-#define PCI_DEVICE_ID_AL_M1489 0x1489
-#define PCI_DEVICE_ID_AL_M1511 0x1511
-#define PCI_DEVICE_ID_AL_M1513 0x1513
-#define PCI_DEVICE_ID_AL_M4803 0x5215
-
-#define PCI_VENDOR_ID_ASP 0x10cd
-#define PCI_DEVICE_ID_ASP_ABP940 0x1200
-
-#define PCI_VENDOR_ID_IMS 0x10e0
-#define PCI_DEVICE_ID_IMS_8849 0x8849
-
-#define PCI_VENDOR_ID_TEKRAM2 0x10e1
-#define PCI_DEVICE_ID_TEKRAM2_690c 0x690c
-
-#define PCI_VENDOR_ID_AMCC 0x10e8
-#define PCI_DEVICE_ID_AMCC_MYRINET 0x8043
-
-#define PCI_VENDOR_ID_INTERG 0x10ea
-#define PCI_DEVICE_ID_INTERG_1680 0x1680
-
-#define PCI_VENDOR_ID_REALTEK 0x10ec
-#define PCI_DEVICE_ID_REALTEK_8029 0x8029
-
-#define PCI_VENDOR_ID_INIT 0x1101
-#define PCI_DEVICE_ID_INIT_320P 0x9100
-
-#define PCI_VENDOR_ID_VIA 0x1106
-#define PCI_DEVICE_ID_VIA_82C505 0x0505
-#define PCI_DEVICE_ID_VIA_82C561 0x0561
-#define PCI_DEVICE_ID_VIA_82C576 0x0576
-#define PCI_DEVICE_ID_VIA_82C416 0x1571
-
-#define PCI_VENDOR_ID_VORTEX 0x1119
-#define PCI_DEVICE_ID_VORTEX_GDT 0x0001
-
-#define PCI_VENDOR_ID_EF 0x111a
-#define PCI_DEVICE_ID_EF_ATM_FPGA 0x0000
-#define PCI_DEVICE_ID_EF_ATM_ASIC 0x0002
-
-#define PCI_VENDOR_ID_FORE 0x1127
-#define PCI_DEVICE_ID_FORE_PCA200PC 0x0210
-
-#define PCI_VENDOR_ID_IMAGINGTECH 0x112f
-#define PCI_DEVICE_ID_IMAGINGTECH_ICPCI 0x0000
-
-#define PCI_VENDOR_ID_PLX 0x113c
-#define PCI_DEVICE_ID_PLX_9060 0x0001
-
-#define PCI_VENDOR_ID_ALLIANCE 0x1142
-#define PCI_DEVICE_ID_ALLIANCE_PROMOTIO 0x3210
-#define PCI_DEVICE_ID_ALLIANCE_PROVIDEO 0x6422
-
-#define PCI_VENDOR_ID_MUTECH 0x1159
-#define PCI_DEVICE_ID_MUTECH_MV1000 0x0001
-
-#define PCI_VENDOR_ID_ZEITNET 0x1193
-#define PCI_DEVICE_ID_ZEITNET_1221 0x0001
-#define PCI_DEVICE_ID_ZEITNET_1225 0x0002
-
-#define PCI_VENDOR_ID_SPECIALIX 0x11cb
-#define PCI_DEVICE_ID_SPECIALIX_XIO 0x4000
-#define PCI_DEVICE_ID_SPECIALIX_RIO 0x8000
-
-#define PCI_VENDOR_ID_RP 0x11fe
-#define PCI_DEVICE_ID_RP8OCTA 0x0001
-#define PCI_DEVICE_ID_RP8INTF 0x0002
-#define PCI_DEVICE_ID_RP16INTF 0x0003
-#define PCI_DEVICE_ID_RP32INTF 0x0004
-
-#define PCI_VENDOR_ID_CYCLADES 0x120e
-#define PCI_DEVICE_ID_CYCLADES_Y 0x0100
-
-#define PCI_VENDOR_ID_SYMPHONY 0x1c1c
-#define PCI_DEVICE_ID_SYMPHONY_101 0x0001
-
-#define PCI_VENDOR_ID_TEKRAM 0x1de1
-#define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29
-
-#define PCI_VENDOR_ID_AVANCE 0x4005
-#define PCI_DEVICE_ID_AVANCE_2302 0x2302
-
-#define PCI_VENDOR_ID_S3 0x5333
-#define PCI_DEVICE_ID_S3_811 0x8811
-#define PCI_DEVICE_ID_S3_868 0x8880
-#define PCI_DEVICE_ID_S3_928 0x88b0
-#define PCI_DEVICE_ID_S3_864_1 0x88c0
-#define PCI_DEVICE_ID_S3_864_2 0x88c1
-#define PCI_DEVICE_ID_S3_964_1 0x88d0
-#define PCI_DEVICE_ID_S3_964_2 0x88d1
-#define PCI_DEVICE_ID_S3_968 0x88f0
-
-#define PCI_VENDOR_ID_INTEL 0x8086
-#define PCI_DEVICE_ID_INTEL_82375 0x0482
-#define PCI_DEVICE_ID_INTEL_82424 0x0483
-#define PCI_DEVICE_ID_INTEL_82378 0x0484
-#define PCI_DEVICE_ID_INTEL_82430 0x0486
-#define PCI_DEVICE_ID_INTEL_82434 0x04a3
-#define PCI_DEVICE_ID_INTEL_7116 0x1223
-#define PCI_DEVICE_ID_INTEL_82596 0x1226
-#define PCI_DEVICE_ID_INTEL_82865 0x1227
-#define PCI_DEVICE_ID_INTEL_82557 0x1229
-#define PCI_DEVICE_ID_INTEL_82437 0x122d
-#define PCI_DEVICE_ID_INTEL_82371_0 0x122e
-#define PCI_DEVICE_ID_INTEL_82371_1 0x1230
-#define PCI_DEVICE_ID_INTEL_P6 0x84c4
-
-#define PCI_VENDOR_ID_ADAPTEC 0x9004
-#define PCI_DEVICE_ID_ADAPTEC_7850 0x5078
-#define PCI_DEVICE_ID_ADAPTEC_7870 0x7078
-#define PCI_DEVICE_ID_ADAPTEC_7871 0x7178
-#define PCI_DEVICE_ID_ADAPTEC_7872 0x7278
-#define PCI_DEVICE_ID_ADAPTEC_7873 0x7378
-#define PCI_DEVICE_ID_ADAPTEC_7874 0x7478
-#define PCI_DEVICE_ID_ADAPTEC_7880 0x8078
-#define PCI_DEVICE_ID_ADAPTEC_7881 0x8178
-#define PCI_DEVICE_ID_ADAPTEC_7882 0x8278
-#define PCI_DEVICE_ID_ADAPTEC_7883 0x8378
-#define PCI_DEVICE_ID_ADAPTEC_7884 0x8478
-
-#define PCI_VENDOR_ID_ATRONICS 0x907f
-#define PCI_DEVICE_ID_ATRONICS_2015 0x2015
-
-#define PCI_VENDOR_ID_HER 0xedd8
-#define PCI_DEVICE_ID_HER_STING 0xa091
-#define PCI_DEVICE_ID_HER_STINGARK 0xa099
-
-/*
- * The PCI interface treats multi-function devices as independent
- * devices. The slot/function address of each device is encoded
- * in a single byte as follows:
- *
- * 7:4 = slot
- * 3:0 = function
- */
-#define PCI_DEVFN(slot,func) ((((slot) & 0x1f) << 3) | ((func) & 0x07))
-#define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f)
-#define PCI_FUNC(devfn) ((devfn) & 0x07)
-
-/*
- * There is one pci_dev structure for each slot-number/function-number
- * combination:
- */
-struct pci_dev {
- struct pci_bus *bus; /* bus this device is on */
- struct pci_dev *sibling; /* next device on this bus */
- struct pci_dev *next; /* chain of all devices */
-
- void *sysdata; /* hook for sys-specific extension */
-
- unsigned int devfn; /* encoded device & function index */
- unsigned short vendor;
- unsigned short device;
- unsigned int class; /* 3 bytes: (base,sub,prog-if) */
- unsigned int master : 1; /* set if device is master capable */
- /*
- * In theory, the irq level can be read from configuration
- * space and all would be fine. However, old PCI chips don't
- * support these registers and return 0 instead. For example,
- * the Vision864-P rev 0 chip can uses INTA, but returns 0 in
- * the interrupt line and pin registers. pci_init()
- * initializes this field with the value at PCI_INTERRUPT_LINE
- * and it is the job of pcibios_fixup() to change it if
- * necessary. The field must not be 0 unless the device
- * cannot generate interrupts at all.
- */
- unsigned char irq; /* irq generated by this device */
-};
-
-struct pci_bus {
- struct pci_bus *parent; /* parent bus this bridge is on */
- struct pci_bus *children; /* chain of P2P bridges on this bus */
- struct pci_bus *next; /* chain of all PCI buses */
-
- struct pci_dev *self; /* bridge device as seen by parent */
- struct pci_dev *devices; /* devices behind this bridge */
-
- void *sysdata; /* hook for sys-specific extension */
-
- unsigned char number; /* bus number */
- unsigned char primary; /* number of primary bridge */
- unsigned char secondary; /* number of secondary bridge */
- unsigned char subordinate; /* max number of subordinate buses */
-};
-
-/*
- * This is used to map a vendor-id/device-id pair into device-specific
- * information.
- */
-struct pci_dev_info {
- unsigned short vendor; /* vendor id */
- unsigned short device; /* device id */
-
- const char *name; /* device name */
- unsigned char bridge_type; /* bridge type or 0xff */
-};
-
-extern struct pci_bus pci_root; /* root bus */
-extern struct pci_dev *pci_devices; /* list of all devices */
-
-
-extern unsigned long pci_init (unsigned long mem_start, unsigned long mem_end);
-
-extern struct pci_dev_info *pci_lookup_dev (unsigned int vendor,
- unsigned int dev);
-extern const char *pci_strclass (unsigned int class);
-extern const char *pci_strvendor (unsigned int vendor);
-extern const char *pci_strdev (unsigned int vendor, unsigned int device);
-
-extern int get_pci_list (char *buf);
-
-#endif /* PCI_H */
diff --git a/i386/i386at/gpl/linux/include/linux/personality.h b/i386/i386at/gpl/linux/include/linux/personality.h
deleted file mode 100644
index 3e465eaa..00000000
--- a/i386/i386at/gpl/linux/include/linux/personality.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#ifndef _PERSONALITY_H
-#define _PERSONALITY_H
-
-#include <linux/linkage.h>
-#include <linux/ptrace.h>
-
-
-/* Flags for bug emulation. These occupy the top three bytes. */
-#define STICKY_TIMEOUTS 0x4000000
-#define WHOLE_SECONDS 0x2000000
-
-/* Personality types. These go in the low byte. Avoid using the top bit,
- * it will conflict with error returns.
- */
-#define PER_MASK (0x00ff)
-#define PER_LINUX (0x0000)
-#define PER_SVR4 (0x0001 | STICKY_TIMEOUTS)
-#define PER_SVR3 (0x0002 | STICKY_TIMEOUTS)
-#define PER_SCOSVR3 (0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS)
-#define PER_WYSEV386 (0x0004 | STICKY_TIMEOUTS)
-#define PER_ISCR4 (0x0005 | STICKY_TIMEOUTS)
-#define PER_BSD (0x0006)
-#define PER_XENIX (0x0007 | STICKY_TIMEOUTS)
-
-/* Prototype for an lcall7 syscall handler. */
-typedef asmlinkage void (*lcall7_func)(struct pt_regs *);
-
-
-/* Description of an execution domain - personality range supported,
- * lcall7 syscall handler, start up / shut down functions etc.
- * N.B. The name and lcall7 handler must be where they are since the
- * offset of the handler is hard coded in kernel/sys_call.S.
- */
-struct exec_domain {
- const char *name;
- lcall7_func handler;
- unsigned char pers_low, pers_high;
- unsigned long * signal_map;
- unsigned long * signal_invmap;
- int *use_count;
- struct exec_domain *next;
-};
-
-extern struct exec_domain default_exec_domain;
-
-extern struct exec_domain *lookup_exec_domain(unsigned long personality);
-extern int register_exec_domain(struct exec_domain *it);
-extern int unregister_exec_domain(struct exec_domain *it);
-extern asmlinkage int sys_personality(unsigned long personality);
-
-#endif /* _PERSONALITY_H */
diff --git a/i386/i386at/gpl/linux/include/linux/proc_fs.h b/i386/i386at/gpl/linux/include/linux/proc_fs.h
deleted file mode 100644
index cc674c9b..00000000
--- a/i386/i386at/gpl/linux/include/linux/proc_fs.h
+++ /dev/null
@@ -1,269 +0,0 @@
-#ifndef _LINUX_PROC_FS_H
-#define _LINUX_PROC_FS_H
-
-#include <linux/fs.h>
-#include <linux/malloc.h>
-
-/*
- * The proc filesystem constants/structures
- */
-
-/*
- * We always define these enumerators
- */
-
-enum root_directory_inos {
- PROC_ROOT_INO = 1,
- PROC_LOADAVG,
- PROC_UPTIME,
- PROC_MEMINFO,
- PROC_KMSG,
- PROC_VERSION,
- PROC_CPUINFO,
- PROC_PCI,
- PROC_SELF, /* will change inode # */
- PROC_NET,
- PROC_SCSI,
- PROC_MALLOC,
- PROC_KCORE,
- PROC_MODULES,
- PROC_STAT,
- PROC_DEVICES,
- PROC_INTERRUPTS,
- PROC_FILESYSTEMS,
- PROC_KSYMS,
- PROC_DMA,
- PROC_IOPORTS,
- PROC_APM,
-#ifdef __SMP_PROF__
- PROC_SMP_PROF,
-#endif
- PROC_PROFILE, /* whether enabled or not */
- PROC_CMDLINE,
- PROC_SYS,
- PROC_MTAB
-};
-
-enum pid_directory_inos {
- PROC_PID_INO = 2,
- PROC_PID_STATUS,
- PROC_PID_MEM,
- PROC_PID_CWD,
- PROC_PID_ROOT,
- PROC_PID_EXE,
- PROC_PID_FD,
- PROC_PID_ENVIRON,
- PROC_PID_CMDLINE,
- PROC_PID_STAT,
- PROC_PID_STATM,
- PROC_PID_MAPS
-};
-
-enum pid_subdirectory_inos {
- PROC_PID_FD_DIR = 1
-};
-
-enum net_directory_inos {
- PROC_NET_UNIX = 128,
- PROC_NET_ARP,
- PROC_NET_ROUTE,
- PROC_NET_DEV,
- PROC_NET_RAW,
- PROC_NET_TCP,
- PROC_NET_UDP,
- PROC_NET_SNMP,
- PROC_NET_RARP,
- PROC_NET_IGMP,
- PROC_NET_IPMR_VIF,
- PROC_NET_IPMR_MFC,
- PROC_NET_IPFWFWD,
- PROC_NET_IPFWIN,
- PROC_NET_IPFWOUT,
- PROC_NET_IPACCT,
- PROC_NET_IPMSQHST,
- PROC_NET_WAVELAN,
- PROC_NET_IPX_INTERFACE,
- PROC_NET_IPX_ROUTE,
- PROC_NET_IPX,
- PROC_NET_ATALK,
- PROC_NET_AT_ROUTE,
- PROC_NET_ATIF,
- PROC_NET_AX25_ROUTE,
- PROC_NET_AX25,
- PROC_NET_AX25_CALLS,
- PROC_NET_NR_NODES,
- PROC_NET_NR_NEIGH,
- PROC_NET_NR,
- PROC_NET_SOCKSTAT,
- PROC_NET_RTCACHE,
- PROC_NET_AX25_BPQETHER,
- PROC_NET_ALIAS_TYPES,
- PROC_NET_ALIASES,
- PROC_NET_LAST
-};
-
-enum scsi_directory_inos {
- PROC_SCSI_SCSI = 256,
- PROC_SCSI_ADVANSYS,
- PROC_SCSI_EATA,
- PROC_SCSI_EATA_PIO,
- PROC_SCSI_AHA152X,
- PROC_SCSI_AHA1542,
- PROC_SCSI_AHA1740,
- PROC_SCSI_AIC7XXX,
- PROC_SCSI_BUSLOGIC,
- PROC_SCSI_U14_34F,
- PROC_SCSI_FDOMAIN,
- PROC_SCSI_GENERIC_NCR5380,
- PROC_SCSI_IN2000,
- PROC_SCSI_PAS16,
- PROC_SCSI_QLOGIC,
- PROC_SCSI_SEAGATE,
- PROC_SCSI_T128,
- PROC_SCSI_NCR53C7xx,
- PROC_SCSI_ULTRASTOR,
- PROC_SCSI_7000FASST,
- PROC_SCSI_EATA2X,
- PROC_SCSI_AM53C974,
- PROC_SCSI_SSC,
- PROC_SCSI_NCR53C406A,
- PROC_SCSI_SCSI_DEBUG,
- PROC_SCSI_NOT_PRESENT,
- PROC_SCSI_FILE, /* I'm asuming here that we */
- PROC_SCSI_LAST = (PROC_SCSI_FILE + 16) /* won't ever see more than */
-}; /* 16 HBAs in one machine */
-
-/* Finally, the dynamically allocatable proc entries are reserved: */
-
-#define PROC_DYNAMIC_FIRST 4096
-#define PROC_NDYNAMIC 4096
-
-#define PROC_SUPER_MAGIC 0x9fa0
-
-/*
- * This is not completely implemented yet. The idea is to
- * create a in-memory tree (like the actual /proc filesystem
- * tree) of these proc_dir_entries, so that we can dynamically
- * add new files to /proc.
- *
- * The "next" pointer creates a linked list of one /proc directory,
- * while parent/subdir create the directory structure (every
- * /proc file has a parent, but "subdir" is NULL for all
- * non-directory entries).
- *
- * "get_info" is called at "read", while "fill_inode" is used to
- * fill in file type/protection/owner information specific to the
- * particular /proc file.
- */
-struct proc_dir_entry {
- unsigned short low_ino;
- unsigned short namelen;
- const char *name;
- mode_t mode;
- nlink_t nlink;
- uid_t uid;
- gid_t gid;
- unsigned long size;
- struct inode_operations * ops;
- int (*get_info)(char *, char **, off_t, int, int);
- void (*fill_inode)(struct inode *);
- struct proc_dir_entry *next, *parent, *subdir;
- void *data;
-};
-
-extern int (* dispatch_scsi_info_ptr) (int ino, char *buffer, char **start,
- off_t offset, int length, int inout);
-
-extern struct proc_dir_entry proc_root;
-extern struct proc_dir_entry proc_net;
-extern struct proc_dir_entry proc_scsi;
-extern struct proc_dir_entry proc_sys;
-extern struct proc_dir_entry proc_pid;
-extern struct proc_dir_entry proc_pid_fd;
-
-extern struct inode_operations proc_scsi_inode_operations;
-
-extern void proc_root_init(void);
-extern void proc_base_init(void);
-extern void proc_net_init(void);
-
-extern int proc_register(struct proc_dir_entry *, struct proc_dir_entry *);
-extern int proc_register_dynamic(struct proc_dir_entry *,
- struct proc_dir_entry *);
-extern int proc_unregister(struct proc_dir_entry *, int);
-
-static inline int proc_net_register(struct proc_dir_entry * x)
-{
- return proc_register(&proc_net, x);
-}
-
-static inline int proc_net_unregister(int x)
-{
- return proc_unregister(&proc_net, x);
-}
-
-static inline int proc_scsi_register(struct proc_dir_entry *driver,
- struct proc_dir_entry *x)
-{
- x->ops = &proc_scsi_inode_operations;
- if(x->low_ino < PROC_SCSI_FILE){
- return(proc_register(&proc_scsi, x));
- }else{
- return(proc_register(driver, x));
- }
-}
-
-static inline int proc_scsi_unregister(struct proc_dir_entry *driver, int x)
-{
- extern void scsi_init_free(char *ptr, unsigned int size);
-
- if(x <= PROC_SCSI_FILE)
- return(proc_unregister(&proc_scsi, x));
- else {
- struct proc_dir_entry **p = &driver->subdir, *dp;
- int ret;
-
- while ((dp = *p) != NULL) {
- if (dp->low_ino == x)
- break;
- p = &dp->next;
- }
- ret = proc_unregister(driver, x);
- scsi_init_free((char *) dp, sizeof(struct proc_dir_entry) + 4);
- return(ret);
- }
-}
-
-extern struct super_block *proc_read_super(struct super_block *,void *,int);
-extern int init_proc_fs(void);
-extern struct inode * proc_get_inode(struct super_block *, int, struct proc_dir_entry *);
-extern void proc_statfs(struct super_block *, struct statfs *, int);
-extern void proc_read_inode(struct inode *);
-extern void proc_write_inode(struct inode *);
-extern int proc_match(int, const char *, struct proc_dir_entry *);
-
-/*
- * These are generic /proc routines that use the internal
- * "struct proc_dir_entry" tree to traverse the filesystem.
- *
- * The /proc root directory has extended versions to take care
- * of the /proc/<pid> subdirectories.
- */
-extern int proc_readdir(struct inode *, struct file *, void *, filldir_t);
-extern int proc_lookup(struct inode *, const char *, int, struct inode **);
-
-extern struct inode_operations proc_dir_inode_operations;
-extern struct inode_operations proc_net_inode_operations;
-extern struct inode_operations proc_netdir_inode_operations;
-extern struct inode_operations proc_scsi_inode_operations;
-extern struct inode_operations proc_mem_inode_operations;
-extern struct inode_operations proc_sys_inode_operations;
-extern struct inode_operations proc_array_inode_operations;
-extern struct inode_operations proc_arraylong_inode_operations;
-extern struct inode_operations proc_kcore_inode_operations;
-extern struct inode_operations proc_profile_inode_operations;
-extern struct inode_operations proc_kmsg_inode_operations;
-extern struct inode_operations proc_link_inode_operations;
-extern struct inode_operations proc_fd_inode_operations;
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/ptrace.h b/i386/i386at/gpl/linux/include/linux/ptrace.h
deleted file mode 100644
index 0a02879d..00000000
--- a/i386/i386at/gpl/linux/include/linux/ptrace.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef _LINUX_PTRACE_H
-#define _LINUX_PTRACE_H
-/* ptrace.h */
-/* structs and defines to help the user use the ptrace system call. */
-
-/* has the defines to get at the registers. */
-
-#define PTRACE_TRACEME 0
-#define PTRACE_PEEKTEXT 1
-#define PTRACE_PEEKDATA 2
-#define PTRACE_PEEKUSR 3
-#define PTRACE_POKETEXT 4
-#define PTRACE_POKEDATA 5
-#define PTRACE_POKEUSR 6
-#define PTRACE_CONT 7
-#define PTRACE_KILL 8
-#define PTRACE_SINGLESTEP 9
-
-#define PTRACE_ATTACH 0x10
-#define PTRACE_DETACH 0x11
-
-#define PTRACE_SYSCALL 24
-
-#include <asm/ptrace.h>
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/quota.h b/i386/i386at/gpl/linux/include/linux/quota.h
deleted file mode 100644
index 59b86fe8..00000000
--- a/i386/i386at/gpl/linux/include/linux/quota.h
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright (c) 1982, 1986 Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Robert Elz at The University of Melbourne.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Version: $Id: quota.h,v 1.1.1.1 1997/02/25 21:27:30 thomas Exp $
- */
-
-#ifndef _LINUX_QUOTA_
-#define _LINUX_QUOTA_
-
-#include <linux/errno.h>
-
-/*
- * Convert diskblocks to blocks and the other way around.
- * currently only to fool the BSD source. :-)
- */
-#define dbtob(num) (num << 10)
-#define btodb(num) (num >> 10)
-
-/*
- * Convert count of filesystem blocks to diskquota blocks, meant
- * for filesystems where i_blksize != BLOCK_SIZE
- */
-#define fs_to_dq_blocks(num, blksize) (((num) * (blksize)) / BLOCK_SIZE)
-
-/*
- * Definitions for disk quotas imposed on the average user
- * (big brother finally hits Linux).
- *
- * The following constants define the amount of time given a user
- * before the soft limits are treated as hard limits (usually resulting
- * in an allocation failure). The timer is started when the user crosses
- * their soft limit, it is reset when they go below their soft limit.
- */
-#define MAX_IQ_TIME 604800 /* (7*24*60*60) 1 week */
-#define MAX_DQ_TIME 604800 /* (7*24*60*60) 1 week */
-
-#define MAXQUOTAS 2
-#define USRQUOTA 0 /* element used for user quotas */
-#define GRPQUOTA 1 /* element used for group quotas */
-
-#include <linux/mount.h>
-
-/*
- * Definitions for the default names of the quotas files.
- */
-#define INITQFNAMES { \
- "user", /* USRQUOTA */ \
- "group", /* GRPQUOTA */ \
- "undefined", \
-};
-
-#define QUOTAFILENAME "quota"
-#define QUOTAGROUP "staff"
-
-#define NR_DQHASH 43 /* Just an arbitrary number any suggestions ? */
-#define NR_DQUOTS 256 /* Number of quotas active at one time */
-
-/*
- * Command definitions for the 'quotactl' system call.
- * The commands are broken into a main command defined below
- * and a subcommand that is used to convey the type of
- * quota that is being manipulated (see above).
- */
-#define SUBCMDMASK 0x00ff
-#define SUBCMDSHIFT 8
-#define QCMD(cmd, type) (((cmd) << SUBCMDSHIFT) | ((type) & SUBCMDMASK))
-
-#define Q_QUOTAON 0x0100 /* enable quotas */
-#define Q_QUOTAOFF 0x0200 /* disable quotas */
-#define Q_GETQUOTA 0x0300 /* get limits and usage */
-#define Q_SETQUOTA 0x0400 /* set limits and usage */
-#define Q_SETUSE 0x0500 /* set usage */
-#define Q_SYNC 0x0600 /* sync disk copy of a filesystems quotas */
-#define Q_SETQLIM 0x0700 /* set limits */
-#define Q_GETSTATS 0x0800 /* get collected stats */
-
-/*
- * The following structure defines the format of the disk quota file
- * (as it appears on disk) - the file is an array of these structures
- * indexed by user or group number.
- */
-struct dqblk {
- __u32 dqb_bhardlimit; /* absolute limit on disk blks alloc */
- __u32 dqb_bsoftlimit; /* preferred limit on disk blks */
- __u32 dqb_curblocks; /* current block count */
- __u32 dqb_ihardlimit; /* maximum # allocated inodes */
- __u32 dqb_isoftlimit; /* preferred inode limit */
- __u32 dqb_curinodes; /* current # allocated inodes */
- time_t dqb_btime; /* time limit for excessive disk use */
- time_t dqb_itime; /* time limit for excessive files */
-};
-
-/*
- * Shorthand notation.
- */
-#define dq_bhardlimit dq_dqb.dqb_bhardlimit
-#define dq_bsoftlimit dq_dqb.dqb_bsoftlimit
-#define dq_curblocks dq_dqb.dqb_curblocks
-#define dq_ihardlimit dq_dqb.dqb_ihardlimit
-#define dq_isoftlimit dq_dqb.dqb_isoftlimit
-#define dq_curinodes dq_dqb.dqb_curinodes
-#define dq_btime dq_dqb.dqb_btime
-#define dq_itime dq_dqb.dqb_itime
-
-#define dqoff(UID) ((off_t)((UID) * sizeof (struct dqblk)))
-
-struct dqstats {
- __u32 lookups;
- __u32 drops;
- __u32 reads;
- __u32 writes;
- __u32 cache_hits;
- __u32 pages_allocated;
- __u32 allocated_dquots;
- __u32 free_dquots;
- __u32 syncs;
-};
-
-#ifdef __KERNEL__
-
-/*
- * Maximum lenght of a message generated in the quota system,
- * that needs to be kicked onto the tty.
- */
-#define MAX_QUOTA_MESSAGE 75
-
-#define DQ_LOCKED 0x01 /* locked for update */
-#define DQ_WANT 0x02 /* wanted for update */
-#define DQ_MOD 0x04 /* dquot modified since read */
-#define DQ_BLKS 0x10 /* uid/gid has been warned about blk limit */
-#define DQ_INODES 0x20 /* uid/gid has been warned about inode limit */
-#define DQ_FAKE 0x40 /* no limits only usage */
-
-struct dquot {
- unsigned int dq_id; /* id this applies to (uid, gid) */
- short dq_type; /* type of quota */
- kdev_t dq_dev; /* Device this applies to */
- short dq_flags; /* see DQ_* */
- short dq_count; /* reference count */
- struct vfsmount *dq_mnt; /* vfsmountpoint this applies to */
- struct dqblk dq_dqb; /* diskquota usage */
- struct wait_queue *dq_wait; /* pointer to waitqueue */
- struct dquot *dq_prev; /* pointer to prev dquot */
- struct dquot *dq_next; /* pointer to next dquot */
- struct dquot *dq_hash_prev; /* pointer to prev dquot */
- struct dquot *dq_hash_next; /* pointer to next dquot */
-};
-
-#define NODQUOT (struct dquot *)NULL
-
-/*
- * Flags used for set_dqblk.
- */
-#define QUOTA_SYSCALL 0x01
-#define SET_QUOTA 0x02
-#define SET_USE 0x04
-#define SET_QLIMIT 0x08
-
-#define QUOTA_OK 0
-#define NO_QUOTA 1
-
-/*
- * declaration of quota_function calls in kernel.
- */
-
-extern void dquot_initialize(struct inode *inode, short type);
-extern void dquot_drop(struct inode *inode);
-extern int dquot_alloc_block(const struct inode *inode, unsigned long number);
-extern int dquot_alloc_inode(const struct inode *inode, unsigned long number);
-extern void dquot_free_block(const struct inode *inode, unsigned long number);
-extern void dquot_free_inode(const struct inode *inode, unsigned long number);
-extern int dquot_transfer(struct inode *inode, struct iattr *iattr, char direction);
-
-extern void invalidate_dquots(kdev_t dev, short type);
-extern int quota_off(kdev_t dev, short type);
-extern int sync_dquots(kdev_t dev, short type);
-
-#else
-
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-int quotactl __P ((int, const char *, int, caddr_t));
-__END_DECLS
-
-#endif /* __KERNEL__ */
-#endif /* _QUOTA_ */
diff --git a/i386/i386at/gpl/linux/include/linux/resource.h b/i386/i386at/gpl/linux/include/linux/resource.h
deleted file mode 100644
index f3bffbd7..00000000
--- a/i386/i386at/gpl/linux/include/linux/resource.h
+++ /dev/null
@@ -1,60 +0,0 @@
-#ifndef _LINUX_RESOURCE_H
-#define _LINUX_RESOURCE_H
-
-#include <linux/time.h>
-
-/*
- * Resource control/accounting header file for linux
- */
-
-/*
- * Definition of struct rusage taken from BSD 4.3 Reno
- *
- * We don't support all of these yet, but we might as well have them....
- * Otherwise, each time we add new items, programs which depend on this
- * structure will lose. This reduces the chances of that happening.
- */
-#define RUSAGE_SELF 0
-#define RUSAGE_CHILDREN (-1)
-#define RUSAGE_BOTH (-2) /* sys_wait4() uses this */
-
-struct rusage {
- struct timeval ru_utime; /* user time used */
- struct timeval ru_stime; /* system time used */
- long ru_maxrss; /* maximum resident set size */
- long ru_ixrss; /* integral shared memory size */
- long ru_idrss; /* integral unshared data size */
- long ru_isrss; /* integral unshared stack size */
- long ru_minflt; /* page reclaims */
- long ru_majflt; /* page faults */
- long ru_nswap; /* swaps */
- long ru_inblock; /* block input operations */
- long ru_oublock; /* block output operations */
- long ru_msgsnd; /* messages sent */
- long ru_msgrcv; /* messages received */
- long ru_nsignals; /* signals received */
- long ru_nvcsw; /* voluntary context switches */
- long ru_nivcsw; /* involuntary " */
-};
-
-#define RLIM_INFINITY ((long)(~0UL>>1))
-
-struct rlimit {
- long rlim_cur;
- long rlim_max;
-};
-
-#define PRIO_MIN (-20)
-#define PRIO_MAX 20
-
-#define PRIO_PROCESS 0
-#define PRIO_PGRP 1
-#define PRIO_USER 2
-
-/*
- * Due to binary compatibility, the actual resource numbers
- * may be different for different linux versions..
- */
-#include <asm/resource.h>
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/route.h b/i386/i386at/gpl/linux/include/linux/route.h
deleted file mode 100644
index 5be4853e..00000000
--- a/i386/i386at/gpl/linux/include/linux/route.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * INET An implementation of the TCP/IP protocol suite for the LINUX
- * operating system. INET is implemented using the BSD Socket
- * interface as the means of communication with the user level.
- *
- * Global definitions for the IP router interface.
- *
- * Version: @(#)route.h 1.0.3 05/27/93
- *
- * Authors: Original taken from Berkeley UNIX 4.3, (c) UCB 1986-1988
- * for the purposes of compatibility only.
- *
- * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#ifndef _LINUX_ROUTE_H
-#define _LINUX_ROUTE_H
-
-#include <linux/if.h>
-
-
-/* This structure gets passed by the SIOCADDRT and SIOCDELRT calls. */
-struct rtentry
-{
- unsigned long rt_hash; /* hash key for lookups */
- struct sockaddr rt_dst; /* target address */
- struct sockaddr rt_gateway; /* gateway addr (RTF_GATEWAY) */
- struct sockaddr rt_genmask; /* target network mask (IP) */
- short rt_flags;
- short rt_refcnt;
- unsigned long rt_use;
- struct ifnet *rt_ifp;
- short rt_metric; /* +1 for binary compatibility! */
- char *rt_dev; /* forcing the device at add */
- unsigned long rt_mss; /* per route MTU/Window */
- unsigned long rt_window; /* Window clamping */
- unsigned short rt_irtt; /* Initial RTT */
-};
-
-
-#define RTF_UP 0x0001 /* route usable */
-#define RTF_GATEWAY 0x0002 /* destination is a gateway */
-#define RTF_HOST 0x0004 /* host entry (net otherwise) */
-#define RTF_REINSTATE 0x0008 /* reinstate route after tmout */
-#define RTF_DYNAMIC 0x0010 /* created dyn. (by redirect) */
-#define RTF_MODIFIED 0x0020 /* modified dyn. (by redirect) */
-#define RTF_MSS 0x0040 /* specific MSS for this route */
-#define RTF_WINDOW 0x0080 /* per route window clamping */
-#define RTF_IRTT 0x0100 /* Initial round trip time */
-#define RTF_REJECT 0x0200 /* Reject route */
-
-/*
- * This structure is passed from the kernel to user space by netlink
- * routing/device announcements
- */
-
-struct netlink_rtinfo
-{
- unsigned long rtmsg_type;
- struct sockaddr rtmsg_dst;
- struct sockaddr rtmsg_gateway;
- struct sockaddr rtmsg_genmask;
- short rtmsg_flags;
- short rtmsg_metric;
- char rtmsg_device[16];
-};
-
-#define RTMSG_NEWROUTE 0x01
-#define RTMSG_DELROUTE 0x02
-#define RTMSG_NEWDEVICE 0x11
-#define RTMSG_DELDEVICE 0x12
-
-#endif /* _LINUX_ROUTE_H */
-
diff --git a/i386/i386at/gpl/linux/include/linux/sched.h b/i386/i386at/gpl/linux/include/linux/sched.h
deleted file mode 100644
index 28fe7ef0..00000000
--- a/i386/i386at/gpl/linux/include/linux/sched.h
+++ /dev/null
@@ -1,492 +0,0 @@
-#ifndef _LINUX_SCHED_H
-#define _LINUX_SCHED_H
-
-/*
- * define DEBUG if you want the wait-queues to have some extra
- * debugging code. It's not normally used, but might catch some
- * wait-queue coding errors.
- *
- * #define DEBUG
- */
-
-#include <asm/param.h> /* for HZ */
-
-extern unsigned long intr_count;
-extern unsigned long event;
-
-#include <linux/binfmts.h>
-#include <linux/personality.h>
-#include <linux/tasks.h>
-#include <linux/kernel.h>
-#include <asm/system.h>
-#include <asm/page.h>
-
-#include <linux/smp.h>
-#include <linux/tty.h>
-#include <linux/sem.h>
-
-/*
- * cloning flags:
- */
-#define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
-#define CLONE_VM 0x00000100 /* set if VM shared between processes */
-#define CLONE_FS 0x00000200 /* set if fs info shared between processes */
-#define CLONE_FILES 0x00000400 /* set if open files shared between processes */
-#define CLONE_SIGHAND 0x00000800 /* set if signal handlers shared */
-#define CLONE_PID 0x00001000 /* set if pid shared */
-
-/*
- * These are the constant used to fake the fixed-point load-average
- * counting. Some notes:
- * - 11 bit fractions expand to 22 bits by the multiplies: this gives
- * a load-average precision of 10 bits integer + 11 bits fractional
- * - if you want to count load-averages more often, you need more
- * precision, or rounding will get you. With 2-second counting freq,
- * the EXP_n values would be 1981, 2034 and 2043 if still using only
- * 11 bit fractions.
- */
-extern unsigned long avenrun[]; /* Load averages */
-
-#define FSHIFT 11 /* nr of bits of precision */
-#define FIXED_1 (1<<FSHIFT) /* 1.0 as fixed-point */
-#define LOAD_FREQ (5*HZ) /* 5 sec intervals */
-#define EXP_1 1884 /* 1/exp(5sec/1min) as fixed-point */
-#define EXP_5 2014 /* 1/exp(5sec/5min) */
-#define EXP_15 2037 /* 1/exp(5sec/15min) */
-
-#define CALC_LOAD(load,exp,n) \
- load *= exp; \
- load += n*(FIXED_1-exp); \
- load >>= FSHIFT;
-
-#define CT_TO_SECS(x) ((x) / HZ)
-#define CT_TO_USECS(x) (((x) % HZ) * 1000000/HZ)
-
-extern int nr_running, nr_tasks;
-
-#define FIRST_TASK task[0]
-#define LAST_TASK task[NR_TASKS-1]
-
-#include <linux/head.h>
-#include <linux/fs.h>
-#include <linux/signal.h>
-#include <linux/time.h>
-#include <linux/param.h>
-#include <linux/resource.h>
-#include <linux/vm86.h>
-#include <linux/math_emu.h>
-#include <linux/ptrace.h>
-#include <linux/timer.h>
-
-#include <asm/processor.h>
-
-#define TASK_RUNNING 0
-#define TASK_INTERRUPTIBLE 1
-#define TASK_UNINTERRUPTIBLE 2
-#define TASK_ZOMBIE 3
-#define TASK_STOPPED 4
-#define TASK_SWAPPING 5
-
-/*
- * Scheduling policies
- */
-#define SCHED_OTHER 0
-#define SCHED_FIFO 1
-#define SCHED_RR 2
-
-struct sched_param {
- int sched_priority;
-};
-
-#ifndef NULL
-#define NULL ((void *) 0)
-#endif
-
-#ifdef __KERNEL__
-
-#define barrier() __asm__("": : :"memory")
-
-extern void sched_init(void);
-extern void show_state(void);
-extern void trap_init(void);
-
-asmlinkage void schedule(void);
-
-struct files_struct {
- int count;
- fd_set close_on_exec;
- struct file * fd[NR_OPEN];
-};
-
-#define INIT_FILES { \
- 1, \
- { { 0, } }, \
- { NULL, } \
-}
-
-struct fs_struct {
- int count;
- unsigned short umask;
- struct inode * root, * pwd;
-};
-
-#define INIT_FS { \
- 1, \
- 0022, \
- NULL, NULL \
-}
-
-struct mm_struct {
- int count;
- pgd_t * pgd;
- unsigned long context;
- unsigned long start_code, end_code, start_data, end_data;
- unsigned long start_brk, brk, start_stack, start_mmap;
- unsigned long arg_start, arg_end, env_start, env_end;
- unsigned long rss, total_vm, locked_vm;
- unsigned long def_flags;
- struct vm_area_struct * mmap;
- struct vm_area_struct * mmap_avl;
-};
-
-#define INIT_MM { \
- 1, \
- swapper_pg_dir, \
- 0, \
- 0, 0, 0, 0, \
- 0, 0, 0, 0, \
- 0, 0, 0, 0, \
- 0, 0, 0, \
- 0, \
- &init_mmap, &init_mmap }
-
-struct signal_struct {
- int count;
- struct sigaction action[32];
-};
-
-#define INIT_SIGNALS { \
- 1, \
- { {0,}, } }
-
-struct task_struct {
-/* these are hardcoded - don't touch */
- volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
- long counter;
- long priority;
- unsigned long signal;
- unsigned long blocked; /* bitmap of masked signals */
- unsigned long flags; /* per process flags, defined below */
- int errno;
- long debugreg[8]; /* Hardware debugging registers */
- struct exec_domain *exec_domain;
-/* various fields */
- struct linux_binfmt *binfmt;
- struct task_struct *next_task, *prev_task;
- struct task_struct *next_run, *prev_run;
- unsigned long saved_kernel_stack;
- unsigned long kernel_stack_page;
- int exit_code, exit_signal;
- unsigned long personality;
- int dumpable:1;
- int did_exec:1;
- int pid,pgrp,tty_old_pgrp,session,leader;
- int groups[NGROUPS];
- /*
- * pointers to (original) parent process, youngest child, younger sibling,
- * older sibling, respectively. (p->father can be replaced with
- * p->p_pptr->pid)
- */
- struct task_struct *p_opptr, *p_pptr, *p_cptr, *p_ysptr, *p_osptr;
- struct wait_queue *wait_chldexit; /* for wait4() */
- unsigned short uid,euid,suid,fsuid;
- unsigned short gid,egid,sgid,fsgid;
- unsigned long timeout, policy, rt_priority;
- unsigned long it_real_value, it_prof_value, it_virt_value;
- unsigned long it_real_incr, it_prof_incr, it_virt_incr;
- struct timer_list real_timer;
- long utime, stime, cutime, cstime, start_time;
-/* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */
- unsigned long min_flt, maj_flt, nswap, cmin_flt, cmaj_flt, cnswap;
- int swappable:1;
- unsigned long swap_address;
- unsigned long old_maj_flt; /* old value of maj_flt */
- unsigned long dec_flt; /* page fault count of the last time */
- unsigned long swap_cnt; /* number of pages to swap on next pass */
-/* limits */
- struct rlimit rlim[RLIM_NLIMITS];
- unsigned short used_math;
- char comm[16];
-/* file system info */
- int link_count;
- struct tty_struct *tty; /* NULL if no tty */
-/* ipc stuff */
- struct sem_undo *semundo;
- struct sem_queue *semsleeping;
-/* ldt for this task - used by Wine. If NULL, default_ldt is used */
- struct desc_struct *ldt;
-/* tss for this task */
- struct thread_struct tss;
-/* filesystem information */
- struct fs_struct *fs;
-/* open file information */
- struct files_struct *files;
-/* memory management info */
- struct mm_struct *mm;
-/* signal handlers */
- struct signal_struct *sig;
-#ifdef __SMP__
- int processor;
- int last_processor;
- int lock_depth; /* Lock depth. We can context switch in and out of holding a syscall kernel lock... */
-#endif
-};
-
-/*
- * Per process flags
- */
-#define PF_ALIGNWARN 0x00000001 /* Print alignment warning msgs */
- /* Not implemented yet, only for 486*/
-#define PF_PTRACED 0x00000010 /* set if ptrace (0) has been called. */
-#define PF_TRACESYS 0x00000020 /* tracing system calls */
-
-#define PF_STARTING 0x00000100 /* being created */
-#define PF_EXITING 0x00000200 /* getting shut down */
-
-#define PF_USEDFPU 0x00100000 /* Process used the FPU this quantum (SMP only) */
-
-/*
- * Limit the stack by to some sane default: root can always
- * increase this limit if needed.. 8MB seems reasonable.
- */
-#define _STK_LIM (8*1024*1024)
-
-#define DEF_PRIORITY (20*HZ/100) /* 200 ms time slices */
-
-/*
- * INIT_TASK is used to set up the first task table, touch at
- * your own risk!. Base=0, limit=0x1fffff (=2MB)
- */
-#define INIT_TASK \
-/* state etc */ { 0,DEF_PRIORITY,DEF_PRIORITY,0,0,0,0, \
-/* debugregs */ { 0, }, \
-/* exec domain */&default_exec_domain, \
-/* binfmt */ NULL, \
-/* schedlink */ &init_task,&init_task, &init_task, &init_task, \
-/* stack */ 0,(unsigned long) &init_kernel_stack, \
-/* ec,brk... */ 0,0,0,0,0, \
-/* pid etc.. */ 0,0,0,0,0, \
-/* suppl grps*/ {NOGROUP,}, \
-/* proc links*/ &init_task,&init_task,NULL,NULL,NULL,NULL, \
-/* uid etc */ 0,0,0,0,0,0,0,0, \
-/* timeout */ 0,SCHED_OTHER,0,0,0,0,0,0,0, \
-/* timer */ { NULL, NULL, 0, 0, it_real_fn }, \
-/* utime */ 0,0,0,0,0, \
-/* flt */ 0,0,0,0,0,0, \
-/* swp */ 0,0,0,0,0, \
-/* rlimits */ INIT_RLIMITS, \
-/* math */ 0, \
-/* comm */ "swapper", \
-/* fs info */ 0,NULL, \
-/* ipc */ NULL, NULL, \
-/* ldt */ NULL, \
-/* tss */ INIT_TSS, \
-/* fs */ &init_fs, \
-/* files */ &init_files, \
-/* mm */ &init_mm, \
-/* signals */ &init_signals, \
-}
-
-extern struct mm_struct init_mm;
-extern struct task_struct init_task;
-extern struct task_struct *task[NR_TASKS];
-extern struct task_struct *last_task_used_math;
-extern struct task_struct *current_set[NR_CPUS];
-/*
- * On a single processor system this comes out as current_set[0] when cpp
- * has finished with it, which gcc will optimise away.
- */
-#define current (0+current_set[smp_processor_id()]) /* Current on this processor */
-extern unsigned long volatile jiffies;
-extern unsigned long itimer_ticks;
-extern unsigned long itimer_next;
-extern struct timeval xtime;
-extern int need_resched;
-extern void do_timer(struct pt_regs *);
-
-extern unsigned int * prof_buffer;
-extern unsigned long prof_len;
-extern unsigned long prof_shift;
-
-extern int securelevel; /* system security level */
-
-#define CURRENT_TIME (xtime.tv_sec)
-
-extern void sleep_on(struct wait_queue ** p);
-extern void interruptible_sleep_on(struct wait_queue ** p);
-extern void wake_up(struct wait_queue ** p);
-extern void wake_up_interruptible(struct wait_queue ** p);
-extern void wake_up_process(struct task_struct * tsk);
-
-extern void notify_parent(struct task_struct * tsk);
-extern int send_sig(unsigned long sig,struct task_struct * p,int priv);
-extern int in_group_p(gid_t grp);
-
-extern int request_irq(unsigned int irq,void (*handler)(int, struct pt_regs *),
- unsigned long flags, const char *device);
-extern void free_irq(unsigned int irq);
-
-extern void copy_thread(int, unsigned long, unsigned long, struct task_struct *, struct pt_regs *);
-extern void flush_thread(void);
-extern void exit_thread(void);
-
-extern void exit_fs(struct task_struct *);
-extern void exit_files(struct task_struct *);
-extern void exit_sighand(struct task_struct *);
-extern void release_thread(struct task_struct *);
-
-extern int do_execve(char *, char **, char **, struct pt_regs *);
-extern int do_fork(unsigned long, unsigned long, struct pt_regs *);
-
-#ifdef MACH
-extern void add_wait_queue(struct wait_queue **, struct wait_queue *);
-extern void remove_wait_queue(struct wait_queue **, struct wait_queue *);
-#else /* ! MACH */
-/*
- * The wait-queues are circular lists, and you have to be *very* sure
- * to keep them correct. Use only these two functions to add/remove
- * entries in the queues.
- */
-extern inline void add_wait_queue(struct wait_queue ** p, struct wait_queue * wait)
-{
- unsigned long flags;
-
-#ifdef DEBUG
- if (wait->next) {
- __label__ here;
- unsigned long pc;
- pc = (unsigned long) &&here;
- here:
- printk("add_wait_queue (%08lx): wait->next = %08lx\n",pc,(unsigned long) wait->next);
- }
-#endif
- save_flags(flags);
- cli();
- if (!*p) {
- wait->next = wait;
- *p = wait;
- } else {
- wait->next = (*p)->next;
- (*p)->next = wait;
- }
- restore_flags(flags);
-}
-
-extern inline void remove_wait_queue(struct wait_queue ** p, struct wait_queue * wait)
-{
- unsigned long flags;
- struct wait_queue * tmp;
-#ifdef DEBUG
- unsigned long ok = 0;
-#endif
-
- save_flags(flags);
- cli();
- if ((*p == wait) &&
-#ifdef DEBUG
- (ok = 1) &&
-#endif
- ((*p = wait->next) == wait)) {
- *p = NULL;
- } else {
- tmp = wait;
- while (tmp->next != wait) {
- tmp = tmp->next;
-#ifdef DEBUG
- if (tmp == *p)
- ok = 1;
-#endif
- }
- tmp->next = wait->next;
- }
- wait->next = NULL;
- restore_flags(flags);
-#ifdef DEBUG
- if (!ok) {
- __label__ here;
- ok = (unsigned long) &&here;
- printk("removed wait_queue not on list.\n");
- printk("list = %08lx, queue = %08lx\n",(unsigned long) p, (unsigned long) wait);
- here:
- printk("eip = %08lx\n",ok);
- }
-#endif
-}
-
-extern inline void select_wait(struct wait_queue ** wait_address, select_table * p)
-{
- struct select_table_entry * entry;
-
- if (!p || !wait_address)
- return;
- if (p->nr >= __MAX_SELECT_TABLE_ENTRIES)
- return;
- entry = p->entry + p->nr;
- entry->wait_address = wait_address;
- entry->wait.task = current;
- entry->wait.next = NULL;
- add_wait_queue(wait_address,&entry->wait);
- p->nr++;
-}
-#endif /* ! MACH */
-
-extern void __down(struct semaphore * sem);
-
-/*
- * These are not yet interrupt-safe
- */
-extern inline void down(struct semaphore * sem)
-{
- if (sem->count <= 0)
- __down(sem);
- sem->count--;
-}
-
-extern inline void up(struct semaphore * sem)
-{
- sem->count++;
- wake_up(&sem->wait);
-}
-
-#define REMOVE_LINKS(p) do { unsigned long flags; \
- save_flags(flags) ; cli(); \
- (p)->next_task->prev_task = (p)->prev_task; \
- (p)->prev_task->next_task = (p)->next_task; \
- restore_flags(flags); \
- if ((p)->p_osptr) \
- (p)->p_osptr->p_ysptr = (p)->p_ysptr; \
- if ((p)->p_ysptr) \
- (p)->p_ysptr->p_osptr = (p)->p_osptr; \
- else \
- (p)->p_pptr->p_cptr = (p)->p_osptr; \
- } while (0)
-
-#define SET_LINKS(p) do { unsigned long flags; \
- save_flags(flags); cli(); \
- (p)->next_task = &init_task; \
- (p)->prev_task = init_task.prev_task; \
- init_task.prev_task->next_task = (p); \
- init_task.prev_task = (p); \
- restore_flags(flags); \
- (p)->p_ysptr = NULL; \
- if (((p)->p_osptr = (p)->p_pptr->p_cptr) != NULL) \
- (p)->p_osptr->p_ysptr = p; \
- (p)->p_pptr->p_cptr = p; \
- } while (0)
-
-#define for_each_task(p) \
- for (p = &init_task ; (p = p->next_task) != &init_task ; )
-
-#endif /* __KERNEL__ */
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/scsi.h b/i386/i386at/gpl/linux/include/linux/scsi.h
deleted file mode 100644
index a05072cf..00000000
--- a/i386/i386at/gpl/linux/include/linux/scsi.h
+++ /dev/null
@@ -1,198 +0,0 @@
-#ifndef _LINUX_SCSI_H
-#define _LINUX_SCSI_H
-
-/*
- * This header file contains public constants and structures used by
- * the scsi code for linux.
- */
-
-/*
- $Header: cvs/gnumach/i386/i386at/gpl/linux/include/linux/Attic/scsi.h,v 1.1.1.1 1997/02/25 21:27:31 thomas Exp $
-
- For documentation on the OPCODES, MESSAGES, and SENSE values,
- please consult the SCSI standard.
-
-*/
-
-/*
- * SCSI opcodes
- */
-
-#define TEST_UNIT_READY 0x00
-#define REZERO_UNIT 0x01
-#define REQUEST_SENSE 0x03
-#define FORMAT_UNIT 0x04
-#define READ_BLOCK_LIMITS 0x05
-#define REASSIGN_BLOCKS 0x07
-#define READ_6 0x08
-#define WRITE_6 0x0a
-#define SEEK_6 0x0b
-#define READ_REVERSE 0x0f
-#define WRITE_FILEMARKS 0x10
-#define SPACE 0x11
-#define INQUIRY 0x12
-#define RECOVER_BUFFERED_DATA 0x14
-#define MODE_SELECT 0x15
-#define RESERVE 0x16
-#define RELEASE 0x17
-#define COPY 0x18
-#define ERASE 0x19
-#define MODE_SENSE 0x1a
-#define START_STOP 0x1b
-#define RECEIVE_DIAGNOSTIC 0x1c
-#define SEND_DIAGNOSTIC 0x1d
-#define ALLOW_MEDIUM_REMOVAL 0x1e
-
-#define SET_WINDOW 0x24
-#define READ_CAPACITY 0x25
-#define READ_10 0x28
-#define WRITE_10 0x2a
-#define SEEK_10 0x2b
-#define WRITE_VERIFY 0x2e
-#define VERIFY 0x2f
-#define SEARCH_HIGH 0x30
-#define SEARCH_EQUAL 0x31
-#define SEARCH_LOW 0x32
-#define SET_LIMITS 0x33
-#define PRE_FETCH 0x34
-#define READ_POSITION 0x34
-#define SYNCHRONIZE_CACHE 0x35
-#define LOCK_UNLOCK_CACHE 0x36
-#define READ_DEFECT_DATA 0x37
-#define MEDIUM_SCAN 0x38
-#define COMPARE 0x39
-#define COPY_VERIFY 0x3a
-#define WRITE_BUFFER 0x3b
-#define READ_BUFFER 0x3c
-#define UPDATE_BLOCK 0x3d
-#define READ_LONG 0x3e
-#define WRITE_LONG 0x3f
-#define CHANGE_DEFINITION 0x40
-#define WRITE_SAME 0x41
-#define LOG_SELECT 0x4c
-#define LOG_SENSE 0x4d
-#define MODE_SELECT_10 0x55
-#define MODE_SENSE_10 0x5a
-#define READ_12 0xa8
-#define WRITE_12 0xaa
-#define WRITE_VERIFY_12 0xae
-#define SEARCH_HIGH_12 0xb0
-#define SEARCH_EQUAL_12 0xb1
-#define SEARCH_LOW_12 0xb2
-#define SEND_VOLUME_TAG 0xb6
-#define WRITE_LONG_2 0xea
-
-/*
- * Status codes
- */
-
-#define GOOD 0x00
-#define CHECK_CONDITION 0x01
-#define CONDITION_GOOD 0x02
-#define BUSY 0x04
-#define INTERMEDIATE_GOOD 0x08
-#define INTERMEDIATE_C_GOOD 0x0a
-#define RESERVATION_CONFLICT 0x0c
-#define QUEUE_FULL 0x1a
-
-#define STATUS_MASK 0x1e
-
-/*
- * SENSE KEYS
- */
-
-#define NO_SENSE 0x00
-#define RECOVERED_ERROR 0x01
-#define NOT_READY 0x02
-#define MEDIUM_ERROR 0x03
-#define HARDWARE_ERROR 0x04
-#define ILLEGAL_REQUEST 0x05
-#define UNIT_ATTENTION 0x06
-#define DATA_PROTECT 0x07
-#define BLANK_CHECK 0x08
-#define COPY_ABORTED 0x0a
-#define ABORTED_COMMAND 0x0b
-#define VOLUME_OVERFLOW 0x0d
-#define MISCOMPARE 0x0e
-
-
-/*
- * DEVICE TYPES
- */
-
-#define TYPE_DISK 0x00
-#define TYPE_TAPE 0x01
-#define TYPE_PROCESSOR 0x03 /* HP scanners use this */
-#define TYPE_WORM 0x04 /* Treated as ROM by our system */
-#define TYPE_ROM 0x05
-#define TYPE_SCANNER 0x06
-#define TYPE_MOD 0x07 /* Magneto-optical disk -
- * - treated as TYPE_DISK */
-#define TYPE_NO_LUN 0x7f
-
-
-/*
- * MESSAGE CODES
- */
-
-#define COMMAND_COMPLETE 0x00
-#define EXTENDED_MESSAGE 0x01
-#define EXTENDED_MODIFY_DATA_POINTER 0x00
-#define EXTENDED_SDTR 0x01
-#define EXTENDED_EXTENDED_IDENTIFY 0x02 /* SCSI-I only */
-#define EXTENDED_WDTR 0x03
-#define SAVE_POINTERS 0x02
-#define RESTORE_POINTERS 0x03
-#define DISCONNECT 0x04
-#define INITIATOR_ERROR 0x05
-#define ABORT 0x06
-#define MESSAGE_REJECT 0x07
-#define NOP 0x08
-#define MSG_PARITY_ERROR 0x09
-#define LINKED_CMD_COMPLETE 0x0a
-#define LINKED_FLG_CMD_COMPLETE 0x0b
-#define BUS_DEVICE_RESET 0x0c
-
-#define INITIATE_RECOVERY 0x0f /* SCSI-II only */
-#define RELEASE_RECOVERY 0x10 /* SCSI-II only */
-
-#define SIMPLE_QUEUE_TAG 0x20
-#define HEAD_OF_QUEUE_TAG 0x21
-#define ORDERED_QUEUE_TAG 0x22
-
-/*
- * Here are some scsi specific ioctl commands which are sometimes useful.
- */
-/* These are a few other constants only used by scsi devices */
-
-#define SCSI_IOCTL_GET_IDLUN 0x5382
-
-/* Used to turn on and off tagged queuing for scsi devices */
-
-#define SCSI_IOCTL_TAGGED_ENABLE 0x5383
-#define SCSI_IOCTL_TAGGED_DISABLE 0x5384
-
-/* Used to obtain the host number of a device. */
-#define SCSI_IOCTL_PROBE_HOST 0x5385
-
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 4
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * c-continued-statement-offset: 4
- * c-continued-brace-offset: 0
- * indent-tabs-mode: nil
- * tab-width: 8
- * End:
- */
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/scsicam.h b/i386/i386at/gpl/linux/include/linux/scsicam.h
deleted file mode 100644
index 954e1407..00000000
--- a/i386/i386at/gpl/linux/include/linux/scsicam.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * scsicam.h - SCSI CAM support functions, use for HDIO_GETGEO, etc.
- *
- * Copyright 1993, 1994 Drew Eckhardt
- * Visionary Computing
- * (Unix and Linux consulting and custom programming)
- * drew@Colorado.EDU
- * +1 (303) 786-7975
- *
- * For more information, please consult the SCSI-CAM draft.
- */
-
-#ifndef SCSICAM_H
-#define SCSICAM_H
-#include <linux/kdev_t.h>
-extern int scsicam_bios_param (Disk *disk, kdev_t dev, int *ip);
-#endif /* def SCSICAM_H */
diff --git a/i386/i386at/gpl/linux/include/linux/sem.h b/i386/i386at/gpl/linux/include/linux/sem.h
deleted file mode 100644
index 0eb1d024..00000000
--- a/i386/i386at/gpl/linux/include/linux/sem.h
+++ /dev/null
@@ -1,112 +0,0 @@
-#ifndef _LINUX_SEM_H
-#define _LINUX_SEM_H
-#include <linux/ipc.h>
-
-/* semop flags */
-#define SEM_UNDO 0x1000 /* undo the operation on exit */
-
-/* semctl Command Definitions. */
-#define GETPID 11 /* get sempid */
-#define GETVAL 12 /* get semval */
-#define GETALL 13 /* get all semval's */
-#define GETNCNT 14 /* get semncnt */
-#define GETZCNT 15 /* get semzcnt */
-#define SETVAL 16 /* set semval */
-#define SETALL 17 /* set all semval's */
-
-/* One semid data structure for each set of semaphores in the system. */
-struct semid_ds {
- struct ipc_perm sem_perm; /* permissions .. see ipc.h */
- time_t sem_otime; /* last semop time */
- time_t sem_ctime; /* last change time */
- struct sem *sem_base; /* ptr to first semaphore in array */
- struct sem_queue *sem_pending; /* pending operations to be processed */
- struct sem_queue **sem_pending_last; /* last pending operation */
- struct sem_undo *undo; /* undo requests on this array */
- ushort sem_nsems; /* no. of semaphores in array */
-};
-
-/* semop system calls takes an array of these. */
-struct sembuf {
- ushort sem_num; /* semaphore index in array */
- short sem_op; /* semaphore operation */
- short sem_flg; /* operation flags */
-};
-
-/* arg for semctl system calls. */
-union semun {
- int val; /* value for SETVAL */
- struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET */
- ushort *array; /* array for GETALL & SETALL */
- struct seminfo *__buf; /* buffer for IPC_INFO */
- void *__pad;
-};
-
-struct seminfo {
- int semmap;
- int semmni;
- int semmns;
- int semmnu;
- int semmsl;
- int semopm;
- int semume;
- int semusz;
- int semvmx;
- int semaem;
-};
-
-#define SEMMNI 128 /* ? max # of semaphore identifiers */
-#define SEMMSL 32 /* <= 512 max num of semaphores per id */
-#define SEMMNS (SEMMNI*SEMMSL) /* ? max # of semaphores in system */
-#define SEMOPM 32 /* ~ 100 max num of ops per semop call */
-#define SEMVMX 32767 /* semaphore maximum value */
-
-/* unused */
-#define SEMUME SEMOPM /* max num of undo entries per process */
-#define SEMMNU SEMMNS /* num of undo structures system wide */
-#define SEMAEM (SEMVMX >> 1) /* adjust on exit max value */
-#define SEMMAP SEMMNS /* # of entries in semaphore map */
-#define SEMUSZ 20 /* sizeof struct sem_undo */
-
-#ifdef __KERNEL__
-
-/* One semaphore structure for each semaphore in the system. */
-struct sem {
- short semval; /* current value */
- short sempid; /* pid of last operation */
-};
-
-/* ipcs ctl cmds */
-#define SEM_STAT 18
-#define SEM_INFO 19
-
-/* One queue for each semaphore set in the system. */
-struct sem_queue {
- struct sem_queue * next; /* next entry in the queue */
- struct sem_queue ** prev; /* previous entry in the queue, *(q->prev) == q */
- struct wait_queue * sleeper; /* sleeping process */
- struct sem_undo * undo; /* undo structure */
- int pid; /* process id of requesting process */
- int status; /* completion status of operation */
- struct semid_ds * sma; /* semaphore array for operations */
- struct sembuf * sops; /* array of pending operations */
- int nsops; /* number of operations */
-};
-
-/* Each task has a list of undo requests. They are executed automatically
- * when the process exits.
- */
-struct sem_undo {
- struct sem_undo * proc_next; /* next entry on this process */
- struct sem_undo * id_next; /* next entry on this semaphore set */
- int semid; /* semaphore set identifier */
- short * semadj; /* array of adjustments, one per semaphore */
-};
-
-asmlinkage int sys_semget (key_t key, int nsems, int semflg);
-asmlinkage int sys_semop (int semid, struct sembuf *sops, unsigned nsops);
-asmlinkage int sys_semctl (int semid, int semnum, int cmd, union semun arg);
-
-#endif /* __KERNEL__ */
-
-#endif /* _LINUX_SEM_H */
diff --git a/i386/i386at/gpl/linux/include/linux/signal.h b/i386/i386at/gpl/linux/include/linux/signal.h
deleted file mode 100644
index 9d1afa91..00000000
--- a/i386/i386at/gpl/linux/include/linux/signal.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _LINUX_SIGNAL_H
-#define _LINUX_SIGNAL_H
-
-#include <asm/signal.h>
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/skbuff.h b/i386/i386at/gpl/linux/include/linux/skbuff.h
deleted file mode 100644
index 65418168..00000000
--- a/i386/i386at/gpl/linux/include/linux/skbuff.h
+++ /dev/null
@@ -1,474 +0,0 @@
-/*
- * Definitions for the 'struct sk_buff' memory handlers.
- *
- * Authors:
- * Alan Cox, <gw4pts@gw4pts.ampr.org>
- * Florian La Roche, <rzsfl@rz.uni-sb.de>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#ifndef _LINUX_SKBUFF_H
-#define _LINUX_SKBUFF_H
-#include <linux/malloc.h>
-#include <linux/wait.h>
-#include <linux/time.h>
-#include <linux/config.h>
-
-#define CONFIG_SKB_CHECK 0
-
-#define HAVE_ALLOC_SKB /* For the drivers to know */
-#define HAVE_ALIGNABLE_SKB /* Ditto 8) */
-
-
-#define FREE_READ 1
-#define FREE_WRITE 0
-
-#define CHECKSUM_NONE 0
-#define CHECKSUM_HW 1
-#define CHECKSUM_UNNECESSARY 2
-
-struct sk_buff_head
-{
- struct sk_buff * volatile next;
- struct sk_buff * volatile prev;
- __u32 qlen; /* Must be same length as a pointer
- for using debugging */
-#if CONFIG_SKB_CHECK
- int magic_debug_cookie;
-#endif
-};
-
-
-struct sk_buff
-{
- struct sk_buff * volatile next; /* Next buffer in list */
- struct sk_buff * volatile prev; /* Previous buffer in list */
- struct sk_buff_head * list; /* List we are on */
-#if CONFIG_SKB_CHECK
- int magic_debug_cookie;
-#endif
- struct sk_buff * volatile link3; /* Link for IP protocol level buffer chains */
- struct sock *sk; /* Socket we are owned by */
- unsigned long when; /* used to compute rtt's */
- struct timeval stamp; /* Time we arrived */
- struct linux_device *dev; /* Device we arrived on/are leaving by */
- union
- {
- struct tcphdr *th;
- struct ethhdr *eth;
- struct iphdr *iph;
- struct udphdr *uh;
- unsigned char *raw;
- /* for passing an fd in a unix domain socket */
- struct file *filp;
- } h;
-
- union
- {
- /* As yet incomplete physical layer views */
- unsigned char *raw;
- struct ethhdr *ethernet;
- } mac;
-
- struct iphdr *ip_hdr; /* For IPPROTO_RAW */
- unsigned long len; /* Length of actual data */
- unsigned long csum; /* Checksum */
- __u32 saddr; /* IP source address */
- __u32 daddr; /* IP target address */
- __u32 raddr; /* IP next hop address */
- __u32 seq; /* TCP sequence number */
- __u32 end_seq; /* seq [+ fin] [+ syn] + datalen */
- __u32 ack_seq; /* TCP ack sequence number */
- unsigned char proto_priv[16]; /* Protocol private data */
- volatile char acked, /* Are we acked ? */
- used, /* Are we in use ? */
- free, /* How to free this buffer */
- arp; /* Has IP/ARP resolution finished */
- unsigned char tries, /* Times tried */
- lock, /* Are we locked ? */
- localroute, /* Local routing asserted for this frame */
- pkt_type, /* Packet class */
- ip_summed; /* Driver fed us an IP checksum */
-#define PACKET_HOST 0 /* To us */
-#define PACKET_BROADCAST 1 /* To all */
-#define PACKET_MULTICAST 2 /* To group */
-#define PACKET_OTHERHOST 3 /* To someone else */
- unsigned short users; /* User count - see datagram.c,tcp.c */
- unsigned short protocol; /* Packet protocol from driver. */
- unsigned short truesize; /* Buffer size */
-
- int count; /* reference count */
- struct sk_buff *data_skb; /* Link to the actual data skb */
- unsigned char *head; /* Head of buffer */
- unsigned char *data; /* Data head pointer */
- unsigned char *tail; /* Tail pointer */
- unsigned char *end; /* End pointer */
- void (*destructor)(struct sk_buff *this); /* Destruct function */
-#ifdef MACH
-#ifdef MACH_INCLUDE
- ipc_port_t reply;
- mach_msg_type_name_t reply_type;
- vm_map_copy_t copy;
-#else
- void *reply;
- unsigned reply_type;
- void *copy;
-#endif
-#endif
-};
-
-#ifdef CONFIG_SKB_LARGE
-#define SK_WMEM_MAX 65535
-#define SK_RMEM_MAX 65535
-#else
-#define SK_WMEM_MAX 32767
-#define SK_RMEM_MAX 32767
-#endif
-
-#if CONFIG_SKB_CHECK
-#define SK_FREED_SKB 0x0DE2C0DE
-#define SK_GOOD_SKB 0xDEC0DED1
-#define SK_HEAD_SKB 0x12231298
-#endif
-
-#ifdef __KERNEL__
-/*
- * Handling routines are only of interest to the kernel
- */
-
-#include <asm/system.h>
-
-#if 0
-extern void print_skb(struct sk_buff *);
-#endif
-extern void kfree_skb(struct sk_buff *skb, int rw);
-extern void skb_queue_head_init(struct sk_buff_head *list);
-extern void skb_queue_head(struct sk_buff_head *list,struct sk_buff *buf);
-extern void skb_queue_tail(struct sk_buff_head *list,struct sk_buff *buf);
-extern struct sk_buff * skb_dequeue(struct sk_buff_head *list);
-extern void skb_insert(struct sk_buff *old,struct sk_buff *newsk);
-extern void skb_append(struct sk_buff *old,struct sk_buff *newsk);
-extern void skb_unlink(struct sk_buff *buf);
-extern __u32 skb_queue_len(struct sk_buff_head *list);
-extern struct sk_buff * skb_peek_copy(struct sk_buff_head *list);
-extern struct sk_buff * alloc_skb(unsigned int size, int priority);
-extern struct sk_buff * dev_alloc_skb(unsigned int size);
-extern void kfree_skbmem(struct sk_buff *skb);
-extern struct sk_buff * skb_clone(struct sk_buff *skb, int priority);
-extern struct sk_buff * skb_copy(struct sk_buff *skb, int priority);
-extern void skb_device_lock(struct sk_buff *skb);
-extern void skb_device_unlock(struct sk_buff *skb);
-extern void dev_kfree_skb(struct sk_buff *skb, int mode);
-extern int skb_device_locked(struct sk_buff *skb);
-#ifdef MACH
-#define skb_put(skb, len) ((skb)->data)
-#else
-extern unsigned char * skb_put(struct sk_buff *skb, int len);
-#endif
-extern unsigned char * skb_push(struct sk_buff *skb, int len);
-extern unsigned char * skb_pull(struct sk_buff *skb, int len);
-extern int skb_headroom(struct sk_buff *skb);
-extern int skb_tailroom(struct sk_buff *skb);
-#ifdef MACH
-#define skb_reserve(skb, len)
-#else
-extern void skb_reserve(struct sk_buff *skb, int len);
-#endif
-extern void skb_trim(struct sk_buff *skb, int len);
-
-/*
- * Peek an sk_buff. Unlike most other operations you _MUST_
- * be careful with this one. A peek leaves the buffer on the
- * list and someone else may run off with it. For an interrupt
- * type system cli() peek the buffer copy the data and sti();
- */
-extern __inline__ struct sk_buff *skb_peek(struct sk_buff_head *list_)
-{
- struct sk_buff *list = ((struct sk_buff *)list_)->next;
- if (list == (struct sk_buff *)list_)
- list = NULL;
- return list;
-}
-
-/*
- * Return the length of an sk_buff queue
- */
-
-extern __inline__ __u32 skb_queue_len(struct sk_buff_head *list_)
-{
- return(list_->qlen);
-}
-
-#if CONFIG_SKB_CHECK
-extern int skb_check(struct sk_buff *skb,int,int, char *);
-#define IS_SKB(skb) skb_check((skb), 0, __LINE__,__FILE__)
-#define IS_SKB_HEAD(skb) skb_check((skb), 1, __LINE__,__FILE__)
-#else
-#define IS_SKB(skb)
-#define IS_SKB_HEAD(skb)
-
-extern __inline__ void skb_queue_head_init(struct sk_buff_head *list)
-{
- list->prev = (struct sk_buff *)list;
- list->next = (struct sk_buff *)list;
- list->qlen = 0;
-}
-
-/*
- * Insert an sk_buff at the start of a list.
- *
- * The "__skb_xxxx()" functions are the non-atomic ones that
- * can only be called with interrupts disabled.
- */
-
-extern __inline__ void __skb_queue_head(struct sk_buff_head *list, struct sk_buff *newsk)
-{
- struct sk_buff *prev, *next;
-
- newsk->list = list;
- list->qlen++;
- prev = (struct sk_buff *)list;
- next = prev->next;
- newsk->next = next;
- newsk->prev = prev;
- next->prev = newsk;
- prev->next = newsk;
-}
-
-extern __inline__ void skb_queue_head(struct sk_buff_head *list, struct sk_buff *newsk)
-{
- unsigned long flags;
-
- save_flags(flags);
- cli();
- __skb_queue_head(list, newsk);
- restore_flags(flags);
-}
-
-/*
- * Insert an sk_buff at the end of a list.
- */
-
-extern __inline__ void __skb_queue_tail(struct sk_buff_head *list, struct sk_buff *newsk)
-{
- struct sk_buff *prev, *next;
-
- newsk->list = list;
- list->qlen++;
- next = (struct sk_buff *)list;
- prev = next->prev;
- newsk->next = next;
- newsk->prev = prev;
- next->prev = newsk;
- prev->next = newsk;
-}
-
-extern __inline__ void skb_queue_tail(struct sk_buff_head *list, struct sk_buff *newsk)
-{
- unsigned long flags;
-
- save_flags(flags);
- cli();
- __skb_queue_tail(list, newsk);
- restore_flags(flags);
-}
-
-/*
- * Remove an sk_buff from a list.
- */
-
-extern __inline__ struct sk_buff *__skb_dequeue(struct sk_buff_head *list)
-{
- struct sk_buff *next, *prev, *result;
-
- prev = (struct sk_buff *) list;
- next = prev->next;
- result = NULL;
- if (next != prev) {
- result = next;
- next = next->next;
- list->qlen--;
- next->prev = prev;
- prev->next = next;
- result->next = NULL;
- result->prev = NULL;
- result->list = NULL;
- }
- return result;
-}
-
-extern __inline__ struct sk_buff *skb_dequeue(struct sk_buff_head *list)
-{
- long flags;
- struct sk_buff *result;
-
- save_flags(flags);
- cli();
- result = __skb_dequeue(list);
- restore_flags(flags);
- return result;
-}
-
-/*
- * Insert a packet before another one in a list.
- */
-
-extern __inline__ void __skb_insert(struct sk_buff *next, struct sk_buff *newsk)
-{
- struct sk_buff * prev = next->prev;
-
- newsk->next = next;
- newsk->prev = prev;
- next->prev = newsk;
- prev->next = newsk;
- newsk->list = next->list;
- newsk->list->qlen++;
-}
-
-extern __inline__ void skb_insert(struct sk_buff *old, struct sk_buff *newsk)
-{
- unsigned long flags;
-
- save_flags(flags);
- cli();
- __skb_insert(old, newsk);
- restore_flags(flags);
-}
-
-/*
- * Place a packet after a given packet in a list.
- */
-
-extern __inline__ void __skb_append(struct sk_buff *prev, struct sk_buff *newsk)
-{
- struct sk_buff * next = prev->next;
-
- newsk->next = next;
- newsk->prev = prev;
- next->prev = newsk;
- prev->next = newsk;
- newsk->list = prev->list;
- newsk->list->qlen++;
-}
-
-extern __inline__ void skb_append(struct sk_buff *old, struct sk_buff *newsk)
-{
- unsigned long flags;
-
- save_flags(flags);
- cli();
- __skb_append(old, newsk);
- restore_flags(flags);
-}
-
-/*
- * remove sk_buff from list. _Must_ be called atomically, and with
- * the list known..
- */
-extern __inline__ void __skb_unlink(struct sk_buff *skb, struct sk_buff_head *list)
-{
- struct sk_buff * next, * prev;
-
- list->qlen--;
- next = skb->next;
- prev = skb->prev;
- skb->next = NULL;
- skb->prev = NULL;
- skb->list = NULL;
- next->prev = prev;
- prev->next = next;
-}
-
-/*
- * Remove an sk_buff from its list. Works even without knowing the list it
- * is sitting on, which can be handy at times. It also means that THE LIST
- * MUST EXIST when you unlink. Thus a list must have its contents unlinked
- * _FIRST_.
- */
-
-extern __inline__ void skb_unlink(struct sk_buff *skb)
-{
- unsigned long flags;
-
- save_flags(flags);
- cli();
- if(skb->list)
- __skb_unlink(skb, skb->list);
- restore_flags(flags);
-}
-
-#ifndef MACH
-/*
- * Add data to an sk_buff
- */
-
-extern __inline__ unsigned char *skb_put(struct sk_buff *skb, int len)
-{
- unsigned char *tmp=skb->tail;
- skb->tail+=len;
- skb->len+=len;
- if(skb->tail>skb->end)
- panic("skput:over: %p:%d", __builtin_return_address(0),len);
- return tmp;
-}
-#endif
-
-extern __inline__ unsigned char *skb_push(struct sk_buff *skb, int len)
-{
- skb->data-=len;
- skb->len+=len;
- if(skb->data<skb->head)
- panic("skpush:under: %p:%d", __builtin_return_address(0),len);
- return skb->data;
-}
-
-extern __inline__ unsigned char * skb_pull(struct sk_buff *skb, int len)
-{
- if(len > skb->len)
- return NULL;
- skb->data+=len;
- skb->len-=len;
- return skb->data;
-}
-
-extern __inline__ int skb_headroom(struct sk_buff *skb)
-{
- return skb->data-skb->head;
-}
-
-extern __inline__ int skb_tailroom(struct sk_buff *skb)
-{
- return skb->end-skb->tail;
-}
-
-#ifndef MACH
-extern __inline__ void skb_reserve(struct sk_buff *skb, int len)
-{
- skb->data+=len;
- skb->tail+=len;
-}
-#endif
-
-extern __inline__ void skb_trim(struct sk_buff *skb, int len)
-{
- if(skb->len>len)
- {
- skb->len=len;
- skb->tail=skb->data+len;
- }
-}
-
-#endif
-
-extern struct sk_buff * skb_recv_datagram(struct sock *sk,unsigned flags,int noblock, int *err);
-extern int datagram_select(struct sock *sk, int sel_type, select_table *wait);
-extern void skb_copy_datagram(struct sk_buff *from, int offset, char *to,int size);
-extern void skb_copy_datagram_iovec(struct sk_buff *from, int offset, struct iovec *to,int size);
-extern void skb_free_datagram(struct sock * sk, struct sk_buff *skb);
-
-#endif /* __KERNEL__ */
-#endif /* _LINUX_SKBUFF_H */
diff --git a/i386/i386at/gpl/linux/include/linux/smp.h b/i386/i386at/gpl/linux/include/linux/smp.h
deleted file mode 100644
index 72984f15..00000000
--- a/i386/i386at/gpl/linux/include/linux/smp.h
+++ /dev/null
@@ -1,54 +0,0 @@
-#ifndef __LINUX_SMP_H
-#define __LINUX_SMP_H
-
-/*
- * Generic SMP support
- * Alan Cox. <alan@cymru.net>
- */
-
-#ifdef __SMP__
-#include <asm/smp.h>
-
-extern void smp_message_pass(int target, int msg, unsigned long data, int wait);
-extern void smp_boot_cpus(void); /* Boot processor call to load the other CPU's */
-extern void smp_callin(void); /* Processor call in. Must hold processors until .. */
-extern void smp_commence(void); /* Multiprocessors may now schedule */
-extern int smp_num_cpus;
-extern int smp_threads_ready; /* True once the per process idle is forked */
-#ifdef __SMP_PROF__
-extern volatile unsigned long smp_spins[NR_CPUS]; /* count of interrupt spins */
-extern volatile unsigned long smp_spins_sys_idle[]; /* count of idle spins */
-extern volatile unsigned long smp_spins_syscall[]; /* count of syscall spins */
-extern volatile unsigned long smp_spins_syscall_cur[]; /* count of syscall spins for the current
- call */
-extern volatile unsigned long smp_idle_count[1+NR_CPUS];/* count idle ticks */
-extern volatile unsigned long smp_idle_map; /* map with idle cpus */
-#else
-extern volatile unsigned long smp_spins;
-#endif
-
-
-extern volatile unsigned long smp_msg_data;
-extern volatile int smp_src_cpu;
-extern volatile int smp_msg_id;
-
-#define MSG_ALL_BUT_SELF 0x8000 /* Assume <32768 CPU's */
-#define MSG_ALL 0x8001
-
-#define MSG_INVALIDATE_TLB 0x0001 /* Remote processor TLB invalidate */
-#define MSG_STOP_CPU 0x0002 /* Sent to shut down slave CPU's when rebooting */
-#define MSG_RESCHEDULE 0x0003 /* Reschedule request from master CPU */
-
-#else
-
-/*
- * These macros fold the SMP functionality into a single CPU system
- */
-
-#define smp_num_cpus 1
-#define smp_processor_id() 0
-#define smp_message_pass(t,m,d,w)
-#define smp_threads_ready 1
-#define kernel_lock()
-#endif
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/socket.h b/i386/i386at/gpl/linux/include/linux/socket.h
deleted file mode 100644
index bf2991ad..00000000
--- a/i386/i386at/gpl/linux/include/linux/socket.h
+++ /dev/null
@@ -1,126 +0,0 @@
-#ifndef _LINUX_SOCKET_H
-#define _LINUX_SOCKET_H
-
-#include <asm/socket.h> /* arch-dependent defines */
-#include <linux/sockios.h> /* the SIOCxxx I/O controls */
-#include <linux/uio.h> /* iovec support */
-
-struct sockaddr {
- unsigned short sa_family; /* address family, AF_xxx */
- char sa_data[14]; /* 14 bytes of protocol address */
-};
-
-struct linger {
- int l_onoff; /* Linger active */
- int l_linger; /* How long to linger for */
-};
-
-struct msghdr
-{
- void * msg_name; /* Socket name */
- int msg_namelen; /* Length of name */
- struct iovec * msg_iov; /* Data blocks */
- int msg_iovlen; /* Number of blocks */
- void * msg_accrights; /* Per protocol magic (eg BSD file descriptor passing) */
- int msg_accrightslen; /* Length of rights list */
-};
-
-/* Socket types. */
-#define SOCK_STREAM 1 /* stream (connection) socket */
-#define SOCK_DGRAM 2 /* datagram (conn.less) socket */
-#define SOCK_RAW 3 /* raw socket */
-#define SOCK_RDM 4 /* reliably-delivered message */
-#define SOCK_SEQPACKET 5 /* sequential packet socket */
-#define SOCK_PACKET 10 /* linux specific way of */
- /* getting packets at the dev */
- /* level. For writing rarp and */
- /* other similar things on the */
- /* user level. */
-
-/* Supported address families. */
-#define AF_UNSPEC 0
-#define AF_UNIX 1 /* Unix domain sockets */
-#define AF_INET 2 /* Internet IP Protocol */
-#define AF_AX25 3 /* Amateur Radio AX.25 */
-#define AF_IPX 4 /* Novell IPX */
-#define AF_APPLETALK 5 /* Appletalk DDP */
-#define AF_NETROM 6 /* Amateur radio NetROM */
-#define AF_BRIDGE 7 /* Multiprotocol bridge */
-#define AF_AAL5 8 /* Reserved for Werner's ATM */
-#define AF_X25 9 /* Reserved for X.25 project */
-#define AF_INET6 10 /* IP version 6 */
-#define AF_MAX 12 /* For now.. */
-
-/* Protocol families, same as address families. */
-#define PF_UNSPEC AF_UNSPEC
-#define PF_UNIX AF_UNIX
-#define PF_INET AF_INET
-#define PF_AX25 AF_AX25
-#define PF_IPX AF_IPX
-#define PF_APPLETALK AF_APPLETALK
-#define PF_NETROM AF_NETROM
-#define PF_BRIDGE AF_BRIDGE
-#define PF_AAL5 AF_AAL5
-#define PF_X25 AF_X25
-#define PF_INET6 AF_INET6
-
-#define PF_MAX AF_MAX
-
-/* Maximum queue length specificable by listen. */
-#define SOMAXCONN 128
-
-/* Flags we can use with send/ and recv. */
-#define MSG_OOB 1
-#define MSG_PEEK 2
-#define MSG_DONTROUTE 4
-
-/* Setsockoptions(2) level. Thanks to BSD these must match IPPROTO_xxx */
-#define SOL_IP 0
-#define SOL_IPX 256
-#define SOL_AX25 257
-#define SOL_ATALK 258
-#define SOL_NETROM 259
-#define SOL_TCP 6
-#define SOL_UDP 17
-
-/* IP options */
-#define IP_TOS 1
-#define IPTOS_LOWDELAY 0x10
-#define IPTOS_THROUGHPUT 0x08
-#define IPTOS_RELIABILITY 0x04
-#define IP_TTL 2
-#define IP_HDRINCL 3
-#define IP_OPTIONS 4
-
-#define IP_MULTICAST_IF 32
-#define IP_MULTICAST_TTL 33
-#define IP_MULTICAST_LOOP 34
-#define IP_ADD_MEMBERSHIP 35
-#define IP_DROP_MEMBERSHIP 36
-
-
-/* These need to appear somewhere around here */
-#define IP_DEFAULT_MULTICAST_TTL 1
-#define IP_DEFAULT_MULTICAST_LOOP 1
-#define IP_MAX_MEMBERSHIPS 20
-
-/* IPX options */
-#define IPX_TYPE 1
-
-/* TCP options - this way around because someone left a set in the c library includes */
-#define TCP_NODELAY 1
-#define TCP_MAXSEG 2
-
-/* The various priorities. */
-#define SOPRI_INTERACTIVE 0
-#define SOPRI_NORMAL 1
-#define SOPRI_BACKGROUND 2
-
-#ifdef __KERNEL__
-extern void memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len);
-extern int verify_iovec(struct msghdr *m, struct iovec *iov, char *address, int mode);
-extern void memcpy_toiovec(struct iovec *v, unsigned char *kdata, int len);
-extern int move_addr_to_user(void *kaddr, int klen, void *uaddr, int *ulen);
-extern int move_addr_to_kernel(void *uaddr, int ulen, void *kaddr);
-#endif
-#endif /* _LINUX_SOCKET_H */
diff --git a/i386/i386at/gpl/linux/include/linux/sockios.h b/i386/i386at/gpl/linux/include/linux/sockios.h
deleted file mode 100644
index ee20a0b1..00000000
--- a/i386/i386at/gpl/linux/include/linux/sockios.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * INET An implementation of the TCP/IP protocol suite for the LINUX
- * operating system. INET is implemented using the BSD Socket
- * interface as the means of communication with the user level.
- *
- * Definitions of the socket-level I/O control calls.
- *
- * Version: @(#)sockios.h 1.0.2 03/09/93
- *
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
- * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#ifndef _LINUX_SOCKIOS_H
-#define _LINUX_SOCKIOS_H
-
-/* Routing table calls. */
-#define SIOCADDRT 0x890B /* add routing table entry */
-#define SIOCDELRT 0x890C /* delete routing table entry */
-
-/* Socket configuration controls. */
-#define SIOCGIFNAME 0x8910 /* get iface name */
-#define SIOCSIFLINK 0x8911 /* set iface channel */
-#define SIOCGIFCONF 0x8912 /* get iface list */
-#define SIOCGIFFLAGS 0x8913 /* get flags */
-#define SIOCSIFFLAGS 0x8914 /* set flags */
-#define SIOCGIFADDR 0x8915 /* get PA address */
-#define SIOCSIFADDR 0x8916 /* set PA address */
-#define SIOCGIFDSTADDR 0x8917 /* get remote PA address */
-#define SIOCSIFDSTADDR 0x8918 /* set remote PA address */
-#define SIOCGIFBRDADDR 0x8919 /* get broadcast PA address */
-#define SIOCSIFBRDADDR 0x891a /* set broadcast PA address */
-#define SIOCGIFNETMASK 0x891b /* get network PA mask */
-#define SIOCSIFNETMASK 0x891c /* set network PA mask */
-#define SIOCGIFMETRIC 0x891d /* get metric */
-#define SIOCSIFMETRIC 0x891e /* set metric */
-#define SIOCGIFMEM 0x891f /* get memory address (BSD) */
-#define SIOCSIFMEM 0x8920 /* set memory address (BSD) */
-#define SIOCGIFMTU 0x8921 /* get MTU size */
-#define SIOCSIFMTU 0x8922 /* set MTU size */
-#define SIOCSIFHWADDR 0x8924 /* set hardware address (NI) */
-#define SIOCGIFENCAP 0x8925 /* get/set slip encapsulation */
-#define SIOCSIFENCAP 0x8926
-#define SIOCGIFHWADDR 0x8927 /* Get hardware address */
-#define SIOCGIFSLAVE 0x8929 /* Driver slaving support */
-#define SIOCSIFSLAVE 0x8930
-/* begin multicast support change */
-#define SIOCADDMULTI 0x8931
-#define SIOCDELMULTI 0x8932
-/* end multicast support change */
-
-/* ARP cache control calls. */
-#define OLD_SIOCDARP 0x8950 /* old delete ARP table entry */
-#define OLD_SIOCGARP 0x8951 /* old get ARP table entry */
-#define OLD_SIOCSARP 0x8952 /* old set ARP table entry */
-#define SIOCDARP 0x8953 /* delete ARP table entry */
-#define SIOCGARP 0x8954 /* get ARP table entry */
-#define SIOCSARP 0x8955 /* set ARP table entry */
-
-/* RARP cache control calls. */
-#define SIOCDRARP 0x8960 /* delete RARP table entry */
-#define SIOCGRARP 0x8961 /* get RARP table entry */
-#define SIOCSRARP 0x8962 /* set RARP table entry */
-
-/* Driver configuration calls */
-
-#define SIOCGIFMAP 0x8970 /* Get device parameters */
-#define SIOCSIFMAP 0x8971 /* Set device parameters */
-
-
-/* Device private ioctl calls */
-
-/*
- * These 16 ioctls are available to devices via the do_ioctl() device
- * vector. Each device should include this file and redefine these names
- * as their own. Because these are device dependent it is a good idea
- * _NOT_ to issue them to random objects and hope.
- */
-
-#define SIOCDEVPRIVATE 0x89F0 /* to 89FF */
-
-/*
- * These 16 ioctl calls are protocol private
- */
-
-#define SIOCPROTOPRIVATE 0x89E0 /* to 89EF */
-#endif /* _LINUX_SOCKIOS_H */
diff --git a/i386/i386at/gpl/linux/include/linux/stat.h b/i386/i386at/gpl/linux/include/linux/stat.h
deleted file mode 100644
index d86b1646..00000000
--- a/i386/i386at/gpl/linux/include/linux/stat.h
+++ /dev/null
@@ -1,53 +0,0 @@
-#ifndef _LINUX_STAT_H
-#define _LINUX_STAT_H
-
-#ifdef __KERNEL__
-
-#include <asm/stat.h>
-
-#endif
-
-#define S_IFMT 00170000
-#define S_IFSOCK 0140000
-#define S_IFLNK 0120000
-#define S_IFREG 0100000
-#define S_IFBLK 0060000
-#define S_IFDIR 0040000
-#define S_IFCHR 0020000
-#define S_IFIFO 0010000
-#define S_ISUID 0004000
-#define S_ISGID 0002000
-#define S_ISVTX 0001000
-
-#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
-#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
-#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
-#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
-#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
-#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
-#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
-
-#define S_IRWXU 00700
-#define S_IRUSR 00400
-#define S_IWUSR 00200
-#define S_IXUSR 00100
-
-#define S_IRWXG 00070
-#define S_IRGRP 00040
-#define S_IWGRP 00020
-#define S_IXGRP 00010
-
-#define S_IRWXO 00007
-#define S_IROTH 00004
-#define S_IWOTH 00002
-#define S_IXOTH 00001
-
-#ifdef __KERNEL__
-#define S_IRWXUGO (S_IRWXU|S_IRWXG|S_IRWXO)
-#define S_IALLUGO (S_ISUID|S_ISGID|S_ISVTX|S_IRWXUGO)
-#define S_IRUGO (S_IRUSR|S_IRGRP|S_IROTH)
-#define S_IWUGO (S_IWUSR|S_IWGRP|S_IWOTH)
-#define S_IXUGO (S_IXUSR|S_IXGRP|S_IXOTH)
-#endif
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/stddef.h b/i386/i386at/gpl/linux/include/linux/stddef.h
deleted file mode 100644
index c6221e71..00000000
--- a/i386/i386at/gpl/linux/include/linux/stddef.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef _LINUX_STDDEF_H
-#define _LINUX_STDDEF_H
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef unsigned int size_t;
-#endif
-
-#undef NULL
-#define NULL ((void *)0)
-
-#undef offsetof
-#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/string.h b/i386/i386at/gpl/linux/include/linux/string.h
deleted file mode 100644
index e9162b38..00000000
--- a/i386/i386at/gpl/linux/include/linux/string.h
+++ /dev/null
@@ -1,44 +0,0 @@
-#ifndef _LINUX_STRING_H_
-#define _LINUX_STRING_H_
-
-#include <linux/types.h> /* for size_t */
-
-#ifndef NULL
-#define NULL ((void *) 0)
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern char * ___strtok;
-extern char * strcpy(char *,const char *);
-extern char * strncpy(char *,const char *,size_t);
-extern char * strcat(char *, const char *);
-extern char * strncat(char *, const char *, size_t);
-extern char * strchr(const char *,int);
-extern char * strpbrk(const char *,const char *);
-extern char * strtok(char *,const char *);
-extern char * strstr(const char *,const char *);
-extern size_t strlen(const char *);
-extern size_t strnlen(const char *,size_t);
-extern size_t strspn(const char *,const char *);
-extern int strcmp(const char *,const char *);
-extern int strncmp(const char *,const char *,size_t);
-
-extern void * memset(void *,int,size_t);
-extern void * memcpy(void *,const void *,size_t);
-extern void * memmove(void *,const void *,size_t);
-extern void * memscan(void *,int,size_t);
-extern int memcmp(const void *,const void *,size_t);
-
-/*
- * Include machine specific inline routines
- */
-#include <asm/string.h>
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _LINUX_STRING_H_ */
diff --git a/i386/i386at/gpl/linux/include/linux/tasks.h b/i386/i386at/gpl/linux/include/linux/tasks.h
deleted file mode 100644
index 4540e34f..00000000
--- a/i386/i386at/gpl/linux/include/linux/tasks.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef _LINUX_TASKS_H
-#define _LINUX_TASKS_H
-
-/*
- * This is the maximum nr of tasks - change it if you need to
- */
-
-#ifdef __SMP__
-#define NR_CPUS 32 /* Max processors that can be running in SMP */
-#else
-#define NR_CPUS 1
-#endif
-
-#define NR_TASKS 512
-
-#define MAX_TASKS_PER_USER (NR_TASKS/2)
-#define MIN_TASKS_LEFT_FOR_ROOT 4
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/tcp.h b/i386/i386at/gpl/linux/include/linux/tcp.h
deleted file mode 100644
index ae6a063e..00000000
--- a/i386/i386at/gpl/linux/include/linux/tcp.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * INET An implementation of the TCP/IP protocol suite for the LINUX
- * operating system. INET is implemented using the BSD Socket
- * interface as the means of communication with the user level.
- *
- * Definitions for the TCP protocol.
- *
- * Version: @(#)tcp.h 1.0.2 04/28/93
- *
- * Author: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#ifndef _LINUX_TCP_H
-#define _LINUX_TCP_H
-
-#include <linux/types.h>
-#include <asm/byteorder.h>
-
-struct tcphdr {
- __u16 source;
- __u16 dest;
- __u32 seq;
- __u32 ack_seq;
-#if defined(__LITTLE_ENDIAN_BITFIELD)
- __u16 res1:4,
- doff:4,
- fin:1,
- syn:1,
- rst:1,
- psh:1,
- ack:1,
- urg:1,
- res2:2;
-#elif defined(__BIG_ENDIAN_BITFIELD)
- __u16 doff:4,
- res1:4,
- res2:2,
- urg:1,
- ack:1,
- psh:1,
- rst:1,
- syn:1,
- fin:1;
-#else
-#error "Adjust your <asm/byteorder.h> defines"
-#endif
- __u16 window;
- __u16 check;
- __u16 urg_ptr;
-};
-
-
-enum {
- TCP_ESTABLISHED = 1,
- TCP_SYN_SENT,
- TCP_SYN_RECV,
- TCP_FIN_WAIT1,
- TCP_FIN_WAIT2,
- TCP_TIME_WAIT,
- TCP_CLOSE,
- TCP_CLOSE_WAIT,
- TCP_LAST_ACK,
- TCP_LISTEN,
- TCP_CLOSING /* now a valid state */
-};
-
-#endif /* _LINUX_TCP_H */
diff --git a/i386/i386at/gpl/linux/include/linux/termios.h b/i386/i386at/gpl/linux/include/linux/termios.h
deleted file mode 100644
index 47866288..00000000
--- a/i386/i386at/gpl/linux/include/linux/termios.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef _LINUX_TERMIOS_H
-#define _LINUX_TERMIOS_H
-
-#include <linux/types.h>
-#include <asm/termios.h>
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/time.h b/i386/i386at/gpl/linux/include/linux/time.h
deleted file mode 100644
index 269e9dc6..00000000
--- a/i386/i386at/gpl/linux/include/linux/time.h
+++ /dev/null
@@ -1,50 +0,0 @@
-#ifndef _LINUX_TIME_H
-#define _LINUX_TIME_H
-
-struct timespec {
- long tv_sec; /* seconds */
- long tv_nsec; /* nanoseconds */
-};
-
-struct timeval {
- int tv_sec; /* seconds */
- int tv_usec; /* microseconds */
-};
-
-struct timezone {
- int tz_minuteswest; /* minutes west of Greenwich */
- int tz_dsttime; /* type of dst correction */
-};
-
-#define NFDBITS __NFDBITS
-
-#ifdef __KERNEL__
-void do_gettimeofday(struct timeval *tv);
-void do_settimeofday(struct timeval *tv);
-#endif
-
-#define FD_SETSIZE __FD_SETSIZE
-#define FD_SET(fd,fdsetp) __FD_SET(fd,fdsetp)
-#define FD_CLR(fd,fdsetp) __FD_CLR(fd,fdsetp)
-#define FD_ISSET(fd,fdsetp) __FD_ISSET(fd,fdsetp)
-#define FD_ZERO(fdsetp) __FD_ZERO(fdsetp)
-
-/*
- * Names of the interval timers, and structure
- * defining a timer setting.
- */
-#define ITIMER_REAL 0
-#define ITIMER_VIRTUAL 1
-#define ITIMER_PROF 2
-
-struct itimerspec {
- struct timespec it_interval; /* timer period */
- struct timespec it_value; /* timer expiration */
-};
-
-struct itimerval {
- struct timeval it_interval; /* timer interval */
- struct timeval it_value; /* current value */
-};
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/timer.h b/i386/i386at/gpl/linux/include/linux/timer.h
deleted file mode 100644
index c54e8c5e..00000000
--- a/i386/i386at/gpl/linux/include/linux/timer.h
+++ /dev/null
@@ -1,101 +0,0 @@
-#ifndef _LINUX_TIMER_H
-#define _LINUX_TIMER_H
-
-/*
- * DON'T CHANGE THESE!! Most of them are hardcoded into some assembly language
- * as well as being defined here.
- */
-
-/*
- * The timers are:
- *
- * BLANK_TIMER console screen-saver timer
- *
- * BEEP_TIMER console beep timer
- *
- * RS_TIMER timer for the RS-232 ports
- *
- * SWAP_TIMER timer for the background pageout daemon
- *
- * HD_TIMER harddisk timer
- *
- * HD_TIMER2 (atdisk2 patches)
- *
- * FLOPPY_TIMER floppy disk timer (not used right now)
- *
- * SCSI_TIMER scsi.c timeout timer
- *
- * NET_TIMER tcp/ip timeout timer
- *
- * COPRO_TIMER 387 timeout for buggy hardware..
- *
- * QIC02_TAPE_TIMER timer for QIC-02 tape driver (it's not hardcoded)
- *
- * MCD_TIMER Mitsumi CD-ROM Timer
- *
- * GSCD_TIMER Goldstar CD-ROM Timer
- *
- * OPTCD_TIMER Optics Storage CD-ROM Timer
- *
- */
-
-#define BLANK_TIMER 0
-#define BEEP_TIMER 1
-#define RS_TIMER 2
-#define SWAP_TIMER 3
-
-#define HD_TIMER 16
-#define FLOPPY_TIMER 17
-#define SCSI_TIMER 18
-#define NET_TIMER 19
-#define SOUND_TIMER 20
-#define COPRO_TIMER 21
-
-#define QIC02_TAPE_TIMER 22 /* hhb */
-#define MCD_TIMER 23
-
-#define HD_TIMER2 24
-#define GSCD_TIMER 25
-#define OPTCD_TIMER 26
-
-struct timer_struct {
- unsigned long expires;
- void (*fn)(void);
-};
-
-extern unsigned long timer_active;
-extern struct timer_struct timer_table[32];
-
-/*
- * This is completely separate from the above, and is the
- * "new and improved" way of handling timers more dynamically.
- * Hopefully efficient and general enough for most things.
- *
- * The "hardcoded" timers above are still useful for well-
- * defined problems, but the timer-list is probably better
- * when you need multiple outstanding timers or similar.
- *
- * The "data" field is in case you want to use the same
- * timeout function for several timeouts. You can use this
- * to distinguish between the different invocations.
- */
-struct timer_list {
- struct timer_list *next;
- struct timer_list *prev;
- unsigned long expires;
- unsigned long data;
- void (*function)(unsigned long);
-};
-
-extern void add_timer(struct timer_list * timer);
-extern int del_timer(struct timer_list * timer);
-
-extern void it_real_fn(unsigned long);
-
-extern inline void init_timer(struct timer_list * timer)
-{
- timer->next = NULL;
- timer->prev = NULL;
-}
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/tqueue.h b/i386/i386at/gpl/linux/include/linux/tqueue.h
deleted file mode 100644
index d483a155..00000000
--- a/i386/i386at/gpl/linux/include/linux/tqueue.h
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * tqueue.h --- task queue handling for Linux.
- *
- * Mostly based on a proposed bottom-half replacement code written by
- * Kai Petzke, wpp@marie.physik.tu-berlin.de.
- *
- * Modified for use in the Linux kernel by Theodore Ts'o,
- * tytso@mit.edu. Any bugs are my fault, not Kai's.
- *
- * The original comment follows below.
- */
-
-#ifndef _LINUX_TQUEUE_H
-#define _LINUX_TQUEUE_H
-
-#include <asm/bitops.h>
-#include <asm/system.h>
-
-#ifdef INCLUDE_INLINE_FUNCS
-#define _INLINE_ extern
-#else
-#define _INLINE_ extern __inline__
-#endif
-
-/*
- * New proposed "bottom half" handlers:
- * (C) 1994 Kai Petzke, wpp@marie.physik.tu-berlin.de
- *
- * Advantages:
- * - Bottom halfs are implemented as a linked list. You can have as many
- * of them, as you want.
- * - No more scanning of a bit field is required upon call of a bottom half.
- * - Support for chained bottom half lists. The run_task_queue() function can be
- * used as a bottom half handler. This is for example useful for bottom
- * halfs, which want to be delayed until the next clock tick.
- *
- * Problems:
- * - The queue_task_irq() inline function is only atomic with respect to itself.
- * Problems can occur, when queue_task_irq() is called from a normal system
- * call, and an interrupt comes in. No problems occur, when queue_task_irq()
- * is called from an interrupt or bottom half, and interrupted, as run_task_queue()
- * will not be executed/continued before the last interrupt returns. If in
- * doubt, use queue_task(), not queue_task_irq().
- * - Bottom halfs are called in the reverse order that they were linked into
- * the list.
- */
-
-struct tq_struct {
- struct tq_struct *next; /* linked list of active bh's */
- int sync; /* must be initialized to zero */
- void (*routine)(void *); /* function to call */
- void *data; /* argument to function */
-};
-
-typedef struct tq_struct * task_queue;
-
-#define DECLARE_TASK_QUEUE(q) task_queue q = &tq_last
-
-extern struct tq_struct tq_last;
-extern task_queue tq_timer, tq_immediate, tq_scheduler;
-
-#ifdef INCLUDE_INLINE_FUNCS
-struct tq_struct tq_last = {
- &tq_last, 0, 0, 0
-};
-#endif
-
-/*
- * To implement your own list of active bottom halfs, use the following
- * two definitions:
- *
- * struct tq_struct *my_bh = &tq_last;
- * struct tq_struct run_my_bh = {
- * 0, 0, (void *)(void *) run_task_queue, &my_bh
- * };
- *
- * To activate a bottom half on your list, use:
- *
- * queue_task(tq_pointer, &my_bh);
- *
- * To run the bottom halfs on your list put them on the immediate list by:
- *
- * queue_task(&run_my_bh, &tq_immediate);
- *
- * This allows you to do deferred procession. For example, you could
- * have a bottom half list tq_timer, which is marked active by the timer
- * interrupt.
- */
-
-/*
- * queue_task_irq: put the bottom half handler "bh_pointer" on the list
- * "bh_list". You may call this function only from an interrupt
- * handler or a bottom half handler.
- */
-_INLINE_ void queue_task_irq(struct tq_struct *bh_pointer,
- task_queue *bh_list)
-{
- if (!set_bit(0,&bh_pointer->sync)) {
- bh_pointer->next = *bh_list;
- *bh_list = bh_pointer;
- }
-}
-
-/*
- * queue_task_irq_off: put the bottom half handler "bh_pointer" on the list
- * "bh_list". You may call this function only when interrupts are off.
- */
-_INLINE_ void queue_task_irq_off(struct tq_struct *bh_pointer,
- task_queue *bh_list)
-{
- if (!(bh_pointer->sync & 1)) {
- bh_pointer->sync = 1;
- bh_pointer->next = *bh_list;
- *bh_list = bh_pointer;
- }
-}
-
-
-/*
- * queue_task: as queue_task_irq, but can be called from anywhere.
- */
-_INLINE_ void queue_task(struct tq_struct *bh_pointer,
- task_queue *bh_list)
-{
- if (!set_bit(0,&bh_pointer->sync)) {
- unsigned long flags;
- save_flags(flags);
- cli();
- bh_pointer->next = *bh_list;
- *bh_list = bh_pointer;
- restore_flags(flags);
- }
-}
-
-/*
- * Call all "bottom halfs" on a given list.
- */
-_INLINE_ void run_task_queue(task_queue *list)
-{
- register struct tq_struct *save_p;
- register struct tq_struct *p;
- void *arg;
- void (*f) (void *);
-
- while(1) {
- p = xchg(list,&tq_last);
- if(p == &tq_last)
- break;
-
- do {
- arg = p -> data;
- f = p -> routine;
- save_p = p -> next;
- p -> sync = 0;
- (*f)(arg);
- p = save_p;
- } while(p != &tq_last);
- }
-}
-
-#undef _INLINE_
-
-#endif /* _LINUX_TQUEUE_H */
diff --git a/i386/i386at/gpl/linux/include/linux/trdevice.h b/i386/i386at/gpl/linux/include/linux/trdevice.h
deleted file mode 100644
index 96801763..00000000
--- a/i386/i386at/gpl/linux/include/linux/trdevice.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * INET An implementation of the TCP/IP protocol suite for the LINUX
- * operating system. NET is implemented using the BSD Socket
- * interface as the means of communication with the user level.
- *
- * Definitions for the Ethernet handlers.
- *
- * Version: @(#)eth.h 1.0.4 05/13/93
- *
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
- * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- *
- * Relocated to include/linux where it belongs by Alan Cox
- * <gw4pts@gw4pts.ampr.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- * WARNING: This move may well be temporary. This file will get merged with others RSN.
- *
- */
-#ifndef _LINUX_TRDEVICE_H
-#define _LINUX_TRDEVICE_H
-
-
-#include <linux/if_tr.h>
-
-#ifdef __KERNEL__
-extern int tr_header(struct sk_buff *skb, struct device *dev,
- unsigned short type, void *daddr,
- void *saddr, unsigned len);
-extern int tr_rebuild_header(void *buff, struct device *dev,
- unsigned long raddr, struct sk_buff *skb);
-extern unsigned short tr_type_trans(struct sk_buff *skb, struct device *dev);
-
-#endif
-
-#endif /* _LINUX_TRDEVICE_H */
diff --git a/i386/i386at/gpl/linux/include/linux/tty.h b/i386/i386at/gpl/linux/include/linux/tty.h
deleted file mode 100644
index fe139511..00000000
--- a/i386/i386at/gpl/linux/include/linux/tty.h
+++ /dev/null
@@ -1,340 +0,0 @@
-#ifndef _LINUX_TTY_H
-#define _LINUX_TTY_H
-
-/*
- * 'tty.h' defines some structures used by tty_io.c and some defines.
- */
-
-#ifdef __KERNEL__
-#include <linux/fs.h>
-#include <linux/termios.h>
-#include <linux/tqueue.h>
-#include <linux/tty_driver.h>
-#include <linux/tty_ldisc.h>
-
-#include <asm/system.h>
-
-
-/*
- * Note: don't mess with NR_PTYS until you understand the tty minor
- * number allocation game...
- * (Note: the *_driver.minor_start values 1, 64, 128, 192 are
- * hardcoded at present.)
- */
-#define MIN_NR_CONSOLES 1 /* must be at least 1 */
-#define MAX_NR_CONSOLES 63 /* serial lines start at 64 */
-#define MAX_NR_USER_CONSOLES 63 /* must be root to allocate above this */
- /* Note: the ioctl VT_GETSTATE does not work for
- consoles 16 and higher (since it returns a short) */
-#define NR_PTYS 256
-#define NR_LDISCS 16
-
-/*
- * These are set up by the setup-routine at boot-time:
- */
-
-struct screen_info {
- unsigned char orig_x;
- unsigned char orig_y;
- unsigned char unused1[2];
- unsigned short orig_video_page;
- unsigned char orig_video_mode;
- unsigned char orig_video_cols;
- unsigned short unused2;
- unsigned short orig_video_ega_bx;
- unsigned short unused3;
- unsigned char orig_video_lines;
- unsigned char orig_video_isVGA;
- unsigned short orig_video_points;
-};
-
-extern struct screen_info screen_info;
-
-#define ORIG_X (screen_info.orig_x)
-#define ORIG_Y (screen_info.orig_y)
-#define ORIG_VIDEO_PAGE (screen_info.orig_video_page)
-#define ORIG_VIDEO_MODE (screen_info.orig_video_mode)
-#define ORIG_VIDEO_COLS (screen_info.orig_video_cols)
-#define ORIG_VIDEO_EGA_BX (screen_info.orig_video_ega_bx)
-#define ORIG_VIDEO_LINES (screen_info.orig_video_lines)
-#define ORIG_VIDEO_ISVGA (screen_info.orig_video_isVGA)
-#define ORIG_VIDEO_POINTS (screen_info.orig_video_points)
-
-#define VIDEO_TYPE_MDA 0x10 /* Monochrome Text Display */
-#define VIDEO_TYPE_CGA 0x11 /* CGA Display */
-#define VIDEO_TYPE_EGAM 0x20 /* EGA/VGA in Monochrome Mode */
-#define VIDEO_TYPE_EGAC 0x21 /* EGA in Color Mode */
-#define VIDEO_TYPE_VGAC 0x22 /* VGA+ in Color Mode */
-
-#define VIDEO_TYPE_TGAC 0x40 /* DEC TGA */
-
-/*
- * This character is the same as _POSIX_VDISABLE: it cannot be used as
- * a c_cc[] character, but indicates that a particular special character
- * isn't in use (eg VINTR has no character etc)
- */
-#define __DISABLED_CHAR '\0'
-
-/*
- * This is the flip buffer used for the tty driver. The buffer is
- * located in the tty structure, and is used as a high speed interface
- * between the tty driver and the tty line discipline.
- */
-#define TTY_FLIPBUF_SIZE 512
-
-struct tty_flip_buffer {
- struct tq_struct tqueue;
- unsigned char char_buf[2*TTY_FLIPBUF_SIZE];
- char flag_buf[2*TTY_FLIPBUF_SIZE];
- char *char_buf_ptr;
- unsigned char *flag_buf_ptr;
- int count;
- int buf_num;
-};
-
-/*
- * When a break, frame error, or parity error happens, these codes are
- * stuffed into the flags buffer.
- */
-#define TTY_NORMAL 0
-#define TTY_BREAK 1
-#define TTY_FRAME 2
-#define TTY_PARITY 3
-#define TTY_OVERRUN 4
-
-#define INTR_CHAR(tty) ((tty)->termios->c_cc[VINTR])
-#define QUIT_CHAR(tty) ((tty)->termios->c_cc[VQUIT])
-#define ERASE_CHAR(tty) ((tty)->termios->c_cc[VERASE])
-#define KILL_CHAR(tty) ((tty)->termios->c_cc[VKILL])
-#define EOF_CHAR(tty) ((tty)->termios->c_cc[VEOF])
-#define TIME_CHAR(tty) ((tty)->termios->c_cc[VTIME])
-#define MIN_CHAR(tty) ((tty)->termios->c_cc[VMIN])
-#define SWTC_CHAR(tty) ((tty)->termios->c_cc[VSWTC])
-#define START_CHAR(tty) ((tty)->termios->c_cc[VSTART])
-#define STOP_CHAR(tty) ((tty)->termios->c_cc[VSTOP])
-#define SUSP_CHAR(tty) ((tty)->termios->c_cc[VSUSP])
-#define EOL_CHAR(tty) ((tty)->termios->c_cc[VEOL])
-#define REPRINT_CHAR(tty) ((tty)->termios->c_cc[VREPRINT])
-#define DISCARD_CHAR(tty) ((tty)->termios->c_cc[VDISCARD])
-#define WERASE_CHAR(tty) ((tty)->termios->c_cc[VWERASE])
-#define LNEXT_CHAR(tty) ((tty)->termios->c_cc[VLNEXT])
-#define EOL2_CHAR(tty) ((tty)->termios->c_cc[VEOL2])
-
-#define _I_FLAG(tty,f) ((tty)->termios->c_iflag & (f))
-#define _O_FLAG(tty,f) ((tty)->termios->c_oflag & (f))
-#define _C_FLAG(tty,f) ((tty)->termios->c_cflag & (f))
-#define _L_FLAG(tty,f) ((tty)->termios->c_lflag & (f))
-
-#define I_IGNBRK(tty) _I_FLAG((tty),IGNBRK)
-#define I_BRKINT(tty) _I_FLAG((tty),BRKINT)
-#define I_IGNPAR(tty) _I_FLAG((tty),IGNPAR)
-#define I_PARMRK(tty) _I_FLAG((tty),PARMRK)
-#define I_INPCK(tty) _I_FLAG((tty),INPCK)
-#define I_ISTRIP(tty) _I_FLAG((tty),ISTRIP)
-#define I_INLCR(tty) _I_FLAG((tty),INLCR)
-#define I_IGNCR(tty) _I_FLAG((tty),IGNCR)
-#define I_ICRNL(tty) _I_FLAG((tty),ICRNL)
-#define I_IUCLC(tty) _I_FLAG((tty),IUCLC)
-#define I_IXON(tty) _I_FLAG((tty),IXON)
-#define I_IXANY(tty) _I_FLAG((tty),IXANY)
-#define I_IXOFF(tty) _I_FLAG((tty),IXOFF)
-#define I_IMAXBEL(tty) _I_FLAG((tty),IMAXBEL)
-
-#define O_OPOST(tty) _O_FLAG((tty),OPOST)
-#define O_OLCUC(tty) _O_FLAG((tty),OLCUC)
-#define O_ONLCR(tty) _O_FLAG((tty),ONLCR)
-#define O_OCRNL(tty) _O_FLAG((tty),OCRNL)
-#define O_ONOCR(tty) _O_FLAG((tty),ONOCR)
-#define O_ONLRET(tty) _O_FLAG((tty),ONLRET)
-#define O_OFILL(tty) _O_FLAG((tty),OFILL)
-#define O_OFDEL(tty) _O_FLAG((tty),OFDEL)
-#define O_NLDLY(tty) _O_FLAG((tty),NLDLY)
-#define O_CRDLY(tty) _O_FLAG((tty),CRDLY)
-#define O_TABDLY(tty) _O_FLAG((tty),TABDLY)
-#define O_BSDLY(tty) _O_FLAG((tty),BSDLY)
-#define O_VTDLY(tty) _O_FLAG((tty),VTDLY)
-#define O_FFDLY(tty) _O_FLAG((tty),FFDLY)
-
-#define C_BAUD(tty) _C_FLAG((tty),CBAUD)
-#define C_CSIZE(tty) _C_FLAG((tty),CSIZE)
-#define C_CSTOPB(tty) _C_FLAG((tty),CSTOPB)
-#define C_CREAD(tty) _C_FLAG((tty),CREAD)
-#define C_PARENB(tty) _C_FLAG((tty),PARENB)
-#define C_PARODD(tty) _C_FLAG((tty),PARODD)
-#define C_HUPCL(tty) _C_FLAG((tty),HUPCL)
-#define C_CLOCAL(tty) _C_FLAG((tty),CLOCAL)
-#define C_CIBAUD(tty) _C_FLAG((tty),CIBAUD)
-#define C_CRTSCTS(tty) _C_FLAG((tty),CRTSCTS)
-
-#define L_ISIG(tty) _L_FLAG((tty),ISIG)
-#define L_ICANON(tty) _L_FLAG((tty),ICANON)
-#define L_XCASE(tty) _L_FLAG((tty),XCASE)
-#define L_ECHO(tty) _L_FLAG((tty),ECHO)
-#define L_ECHOE(tty) _L_FLAG((tty),ECHOE)
-#define L_ECHOK(tty) _L_FLAG((tty),ECHOK)
-#define L_ECHONL(tty) _L_FLAG((tty),ECHONL)
-#define L_NOFLSH(tty) _L_FLAG((tty),NOFLSH)
-#define L_TOSTOP(tty) _L_FLAG((tty),TOSTOP)
-#define L_ECHOCTL(tty) _L_FLAG((tty),ECHOCTL)
-#define L_ECHOPRT(tty) _L_FLAG((tty),ECHOPRT)
-#define L_ECHOKE(tty) _L_FLAG((tty),ECHOKE)
-#define L_FLUSHO(tty) _L_FLAG((tty),FLUSHO)
-#define L_PENDIN(tty) _L_FLAG((tty),PENDIN)
-#define L_IEXTEN(tty) _L_FLAG((tty),IEXTEN)
-
-/*
- * Where all of the state associated with a tty is kept while the tty
- * is open. Since the termios state should be kept even if the tty
- * has been closed --- for things like the baud rate, etc --- it is
- * not stored here, but rather a pointer to the real state is stored
- * here. Possible the winsize structure should have the same
- * treatment, but (1) the default 80x24 is usually right and (2) it's
- * most often used by a windowing system, which will set the correct
- * size each time the window is created or resized anyway.
- * IMPORTANT: since this structure is dynamically allocated, it must
- * be no larger than 4096 bytes. Changing TTY_BUF_SIZE will change
- * the size of this structure, and it needs to be done with care.
- * - TYT, 9/14/92
- */
-struct tty_struct {
- int magic;
- struct tty_driver driver;
- struct tty_ldisc ldisc;
- struct termios *termios, *termios_locked;
- int pgrp;
- int session;
- kdev_t device;
- unsigned long flags;
- int count;
- struct winsize winsize;
- unsigned char stopped:1, hw_stopped:1, packet:1;
- unsigned char ctrl_status;
-
- struct tty_struct *link;
- struct fasync_struct *fasync;
- struct tty_flip_buffer flip;
- int max_flip_cnt;
- struct wait_queue *write_wait;
- struct wait_queue *read_wait;
- void *disc_data;
- void *driver_data;
-
-#define N_TTY_BUF_SIZE 4096
-
- /*
- * The following is data for the N_TTY line discipline. For
- * historical reasons, this is included in the tty structure.
- */
- unsigned int column;
- unsigned char lnext:1, erasing:1, raw:1, real_raw:1, icanon:1;
- unsigned char closing:1;
- unsigned short minimum_to_wake;
- unsigned overrun_time;
- int num_overrun;
- unsigned long process_char_map[256/(8*sizeof(unsigned long))];
- char *read_buf;
- int read_head;
- int read_tail;
- int read_cnt;
- unsigned long read_flags[N_TTY_BUF_SIZE/(8*sizeof(unsigned long))];
- int canon_data;
- unsigned long canon_head;
- unsigned int canon_column;
-};
-
-/* tty magic number */
-#define TTY_MAGIC 0x5401
-
-/*
- * These bits are used in the flags field of the tty structure.
- *
- * So that interrupts won't be able to mess up the queues,
- * copy_to_cooked must be atomic with respect to itself, as must
- * tty->write. Thus, you must use the inline functions set_bit() and
- * clear_bit() to make things atomic.
- */
-#define TTY_THROTTLED 0
-#define TTY_IO_ERROR 1
-#define TTY_SLAVE_CLOSED 2
-#define TTY_EXCLUSIVE 3
-#define TTY_DEBUG 4
-#define TTY_DO_WRITE_WAKEUP 5
-#define TTY_PUSH 6
-#define TTY_CLOSING 7
-
-#define TTY_WRITE_FLUSH(tty) tty_write_flush((tty))
-
-extern void tty_write_flush(struct tty_struct *);
-
-extern struct termios tty_std_termios;
-extern struct tty_struct * redirect;
-extern struct tty_ldisc ldiscs[];
-extern int fg_console, last_console, want_console;
-
-extern int kmsg_redirect;
-extern struct wait_queue * keypress_wait;
-
-extern unsigned long con_init(unsigned long);
-
-extern int rs_init(void);
-extern int lp_init(void);
-extern int pty_init(void);
-extern int tty_init(void);
-extern int vcs_init(void);
-extern int cy_init(void);
-extern int stl_init(void);
-extern int stli_init(void);
-
-extern int tty_paranoia_check(struct tty_struct *tty, kdev_t device,
- const char *routine);
-extern char *_tty_name(struct tty_struct *tty, char *buf);
-extern char *tty_name(struct tty_struct *tty);
-extern void tty_wait_until_sent(struct tty_struct * tty, int timeout);
-extern int tty_check_change(struct tty_struct * tty);
-extern void stop_tty(struct tty_struct * tty);
-extern void start_tty(struct tty_struct * tty);
-extern int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc);
-extern int tty_register_driver(struct tty_driver *driver);
-extern int tty_unregister_driver(struct tty_driver *driver);
-extern int tty_read_raw_data(struct tty_struct *tty, unsigned char *bufp,
- int buflen);
-extern void tty_write_message(struct tty_struct *tty, char *msg);
-
-extern int is_orphaned_pgrp(int pgrp);
-extern int is_ignored(int sig);
-extern int tty_signal(int sig, struct tty_struct *tty);
-extern void tty_hangup(struct tty_struct * tty);
-extern void tty_vhangup(struct tty_struct * tty);
-extern void tty_unhangup(struct file *filp);
-extern int tty_hung_up_p(struct file * filp);
-extern void do_SAK(struct tty_struct *tty);
-extern void disassociate_ctty(int priv);
-
-/* n_tty.c */
-extern struct tty_ldisc tty_ldisc_N_TTY;
-
-/* tty_ioctl.c */
-extern int n_tty_ioctl(struct tty_struct * tty, struct file * file,
- unsigned int cmd, unsigned long arg);
-
-/* serial.c */
-
-extern int rs_open(struct tty_struct * tty, struct file * filp);
-
-/* pty.c */
-
-extern int pty_open(struct tty_struct * tty, struct file * filp);
-
-/* console.c */
-
-extern int con_open(struct tty_struct * tty, struct file * filp);
-extern void update_screen(int new_console);
-extern void console_print(const char *);
-
-/* vt.c */
-
-extern int vt_ioctl(struct tty_struct *tty, struct file * file,
- unsigned int cmd, unsigned long arg);
-
-#endif /* __KERNEL__ */
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/tty_driver.h b/i386/i386at/gpl/linux/include/linux/tty_driver.h
deleted file mode 100644
index 3468fa2d..00000000
--- a/i386/i386at/gpl/linux/include/linux/tty_driver.h
+++ /dev/null
@@ -1,189 +0,0 @@
-#ifndef _LINUX_TTY_DRIVER_H
-#define _LINUX_TTY_DRIVER_H
-
-/*
- * This structure defines the interface between the low-level tty
- * driver and the tty routines. The following routines can be
- * defined; unless noted otherwise, they are optional, and can be
- * filled in with a null pointer.
- *
- * int (*open)(struct tty_struct * tty, struct file * filp);
- *
- * This routine is called when a particular tty device is opened.
- * This routine is mandatory; if this routine is not filled in,
- * the attempted open will fail with ENODEV.
- *
- * void (*close)(struct tty_struct * tty, struct file * filp);
- *
- * This routine is called when a particular tty device is closed.
- *
- * int (*write)(struct tty_struct * tty, int from_user,
- * const unsigned char *buf, int count);
- *
- * This routine is called by the kernel to write a series of
- * characters to the tty device. The characters may come from
- * user space or kernel space. This routine will return the
- * number of characters actually accepted for writing. This
- * routine is mandatory.
- *
- * void (*put_char)(struct tty_struct *tty, unsigned char ch);
- *
- * This routine is called by the kernel to write a single
- * character to the tty device. If the kernel uses this routine,
- * it must call the flush_chars() routine (if defined) when it is
- * done stuffing characters into the driver. If there is no room
- * in the queue, the character is ignored.
- *
- * void (*flush_chars)(struct tty_struct *tty);
- *
- * This routine is called by the kernel after it has written a
- * series of characters to the tty device using put_char().
- *
- * int (*write_room)(struct tty_struct *tty);
- *
- * This routine returns the numbers of characters the tty driver
- * will accept for queuing to be written. This number is subject
- * to change as output buffers get emptied, or if the output flow
- * control is acted.
- *
- * int (*ioctl)(struct tty_struct *tty, struct file * file,
- * unsigned int cmd, unsigned long arg);
- *
- * This routine allows the tty driver to implement
- * device-specific ioctl's. If the ioctl number passed in cmd
- * is not recognized by the driver, it should return ENOIOCTLCMD.
- *
- * void (*set_termios)(struct tty_struct *tty, struct termios * old);
- *
- * This routine allows the tty driver to be notified when
- * device's termios settings have changed. Note that a
- * well-designed tty driver should be prepared to accept the case
- * where old == NULL, and try to do something rational.
- *
- * void (*set_ldisc)(struct tty_struct *tty);
- *
- * This routine allows the tty driver to be notified when the
- * device's termios settings have changed.
- *
- * void (*throttle)(struct tty_struct * tty);
- *
- * This routine notifies the tty driver that input buffers for
- * the line discipline are close to full, and it should somehow
- * signal that no more characters should be sent to the tty.
- *
- * void (*unthrottle)(struct tty_struct * tty);
- *
- * This routine notifies the tty drivers that it should signals
- * that characters can now be sent to the tty without fear of
- * overrunning the input buffers of the line disciplines.
- *
- * void (*stop)(struct tty_struct *tty);
- *
- * This routine notifies the tty driver that it should stop
- * outputting characters to the tty device.
- *
- * void (*start)(struct tty_struct *tty);
- *
- * This routine notifies the tty driver that it resume sending
- * characters to the tty device.
- *
- * void (*hangup)(struct tty_struct *tty);
- *
- * This routine notifies the tty driver that it should hangup the
- * tty device.
- *
- */
-
-#include <linux/fs.h>
-
-struct tty_driver {
- int magic; /* magic number for this structure */
- const char *name;
- int name_base; /* offset of printed name */
- short major; /* major device number */
- short minor_start; /* start of minor device number*/
- short num; /* number of devices */
- short type; /* type of tty driver */
- short subtype; /* subtype of tty driver */
- struct termios init_termios; /* Initial termios */
- int flags; /* tty driver flags */
- int *refcount; /* for loadable tty drivers */
- struct tty_driver *other; /* only used for the PTY driver */
-
- /*
- * Pointer to the tty data structures
- */
- struct tty_struct **table;
- struct termios **termios;
- struct termios **termios_locked;
-
- /*
- * Interface routines from the upper tty layer to the tty
- * driver.
- */
- int (*open)(struct tty_struct * tty, struct file * filp);
- void (*close)(struct tty_struct * tty, struct file * filp);
- int (*write)(struct tty_struct * tty, int from_user,
- const unsigned char *buf, int count);
- void (*put_char)(struct tty_struct *tty, unsigned char ch);
- void (*flush_chars)(struct tty_struct *tty);
- int (*write_room)(struct tty_struct *tty);
- int (*chars_in_buffer)(struct tty_struct *tty);
- int (*ioctl)(struct tty_struct *tty, struct file * file,
- unsigned int cmd, unsigned long arg);
- void (*set_termios)(struct tty_struct *tty, struct termios * old);
- void (*throttle)(struct tty_struct * tty);
- void (*unthrottle)(struct tty_struct * tty);
- void (*stop)(struct tty_struct *tty);
- void (*start)(struct tty_struct *tty);
- void (*hangup)(struct tty_struct *tty);
- void (*flush_buffer)(struct tty_struct *tty);
- void (*set_ldisc)(struct tty_struct *tty);
-
- /*
- * linked list pointers
- */
- struct tty_driver *next;
- struct tty_driver *prev;
-};
-
-/* tty driver magic number */
-#define TTY_DRIVER_MAGIC 0x5402
-
-/*
- * tty driver flags
- *
- * TTY_DRIVER_RESET_TERMIOS --- requests the tty layer to reset the
- * termios setting when the last process has closed the device.
- * Used for PTY's, in particular.
- *
- * TTY_DRIVER_REAL_RAW --- if set, indicates that the driver will
- * guarantee never not to set any special character handling
- * flags if ((IGNBRK || (!BRKINT && !PARMRK)) && (IGNPAR ||
- * !INPCK)). That is, if there is no reason for the driver to
- * send notifications of parity and break characters up to the
- * line driver, it won't do so. This allows the line driver to
- * optimize for this case if this flag is set. (Note that there
- * is also a promise, if the above case is true, not to signal
- * overruns, either.)
- */
-#define TTY_DRIVER_INSTALLED 0x0001
-#define TTY_DRIVER_RESET_TERMIOS 0x0002
-#define TTY_DRIVER_REAL_RAW 0x0004
-
-/* tty driver types */
-#define TTY_DRIVER_TYPE_SYSTEM 0x0001
-#define TTY_DRIVER_TYPE_CONSOLE 0x0002
-#define TTY_DRIVER_TYPE_SERIAL 0x0003
-#define TTY_DRIVER_TYPE_PTY 0x0004
-#define TTY_DRIVER_TYPE_SCC 0x0005 /* scc driver */
-
-/* system subtypes (magic, used by tty_io.c) */
-#define SYSTEM_TYPE_TTY 0x0001
-#define SYSTEM_TYPE_CONSOLE 0x0002
-
-/* pty subtypes (magic, used by tty_io.c) */
-#define PTY_TYPE_MASTER 0x0001
-#define PTY_TYPE_SLAVE 0x0002
-
-#endif /* #ifdef _LINUX_TTY_DRIVER_H */
diff --git a/i386/i386at/gpl/linux/include/linux/tty_ldisc.h b/i386/i386at/gpl/linux/include/linux/tty_ldisc.h
deleted file mode 100644
index 87b54ca3..00000000
--- a/i386/i386at/gpl/linux/include/linux/tty_ldisc.h
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef _LINUX_TTY_LDISC_H
-#define _LINUX_TTY_LDISC_H
-
-/*
- * Definitions for the tty line discipline
- */
-
-#include <linux/fs.h>
-#include <linux/wait.h>
-
-struct tty_ldisc {
- int magic;
- int num;
- int flags;
- /*
- * The following routines are called from above.
- */
- int (*open)(struct tty_struct *);
- void (*close)(struct tty_struct *);
- void (*flush_buffer)(struct tty_struct *tty);
- int (*chars_in_buffer)(struct tty_struct *tty);
- int (*read)(struct tty_struct * tty, struct file * file,
- unsigned char * buf, unsigned int nr);
- int (*write)(struct tty_struct * tty, struct file * file,
- const unsigned char * buf, unsigned int nr);
- int (*ioctl)(struct tty_struct * tty, struct file * file,
- unsigned int cmd, unsigned long arg);
- void (*set_termios)(struct tty_struct *tty, struct termios * old);
- int (*select)(struct tty_struct * tty, struct inode * inode,
- struct file * file, int sel_type,
- struct select_table_struct *wait);
-
- /*
- * The following routines are called from below.
- */
- void (*receive_buf)(struct tty_struct *, const unsigned char *cp,
- char *fp, int count);
- int (*receive_room)(struct tty_struct *);
- void (*write_wakeup)(struct tty_struct *);
-};
-
-#define TTY_LDISC_MAGIC 0x5403
-
-#define LDISC_FLAG_DEFINED 0x00000001
-
-#endif /* _LINUX_TTY_LDISC_H */
diff --git a/i386/i386at/gpl/linux/include/linux/types.h b/i386/i386at/gpl/linux/include/linux/types.h
deleted file mode 100644
index 376d3ac3..00000000
--- a/i386/i386at/gpl/linux/include/linux/types.h
+++ /dev/null
@@ -1,72 +0,0 @@
-#ifndef _LINUX_TYPES_H
-#define _LINUX_TYPES_H
-
-/*
- * This allows for 256 file descriptors: if NR_OPEN is ever grown beyond that
- * you'll have to change this too. But 256 fd's seem to be enough even for such
- * "real" unices like SunOS, so hopefully this is one limit that doesn't have
- * to be changed.
- *
- * Note that POSIX wants the FD_CLEAR(fd,fdsetp) defines to be in <sys/time.h>
- * (and thus <linux/time.h>) - but this is a more logical place for them. Solved
- * by having dummy defines in <sys/time.h>.
- */
-
-/*
- * Those macros may have been defined in <gnu/types.h>. But we always
- * use the ones here.
- */
-#undef __NFDBITS
-#define __NFDBITS (8 * sizeof(unsigned int))
-
-#undef __FD_SETSIZE
-#define __FD_SETSIZE 256
-
-#undef __FDSET_INTS
-#define __FDSET_INTS (__FD_SETSIZE/__NFDBITS)
-
-typedef struct fd_set {
- unsigned int fds_bits [__FDSET_INTS];
-} fd_set;
-
-#include <asm/types.h>
-
-#ifndef NULL
-#define NULL ((void *) 0)
-#endif
-
-#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
-#define _LOFF_T
-typedef long long loff_t;
-#endif
-
-#ifndef MACH_INCLUDE
-/* bsd */
-typedef unsigned char u_char;
-typedef unsigned short u_short;
-typedef unsigned int u_int;
-typedef unsigned long u_long;
-#endif
-
-/* sysv */
-typedef unsigned char unchar;
-typedef unsigned short ushort;
-typedef unsigned int uint;
-typedef unsigned long ulong;
-
-#ifndef MACH_INCLUDE
-typedef char *caddr_t;
-#endif
-
-typedef unsigned char cc_t;
-typedef unsigned int speed_t;
-typedef unsigned int tcflag_t;
-
-struct ustat {
- daddr_t f_tfree;
- ino_t f_tinode;
- char f_fname[6];
- char f_fpack[6];
-};
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/uio.h b/i386/i386at/gpl/linux/include/linux/uio.h
deleted file mode 100644
index 8051b3d0..00000000
--- a/i386/i386at/gpl/linux/include/linux/uio.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef __LINUX_UIO_H
-#define __LINUX_UIO_H
-
-/*
- * Berkeley style UIO structures - Alan Cox 1994.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-
-/* A word of warning: Our uio structure will clash with the C library one (which is now obsolete). Remove the C
- library one from sys/uio.h */
-
-struct iovec
-{
- void *iov_base; /* BSD uses caddr_t (same thing in effect) */
- int iov_len;
-};
-
-#define MAX_IOVEC 8 /* Maximum iovec's in one operation */
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/unistd.h b/i386/i386at/gpl/linux/include/linux/unistd.h
deleted file mode 100644
index 10ed9834..00000000
--- a/i386/i386at/gpl/linux/include/linux/unistd.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef _LINUX_UNISTD_H_
-#define _LINUX_UNISTD_H_
-
-extern int errno;
-
-/*
- * Include machine specific syscallX macros
- */
-#include <asm/unistd.h>
-
-#endif /* _LINUX_UNISTD_H_ */
diff --git a/i386/i386at/gpl/linux/include/linux/utsname.h b/i386/i386at/gpl/linux/include/linux/utsname.h
deleted file mode 100644
index 7aef28fc..00000000
--- a/i386/i386at/gpl/linux/include/linux/utsname.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef _LINUX_UTSNAME_H
-#define _LINUX_UTSNAME_H
-
-#define __OLD_UTS_LEN 8
-
-struct oldold_utsname {
- char sysname[9];
- char nodename[9];
- char release[9];
- char version[9];
- char machine[9];
-};
-
-#define __NEW_UTS_LEN 64
-
-struct old_utsname {
- char sysname[65];
- char nodename[65];
- char release[65];
- char version[65];
- char machine[65];
-};
-
-struct new_utsname {
- char sysname[65];
- char nodename[65];
- char release[65];
- char version[65];
- char machine[65];
- char domainname[65];
-};
-
-extern struct new_utsname system_utsname;
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/version.h b/i386/i386at/gpl/linux/include/linux/version.h
deleted file mode 100644
index 39c1b599..00000000
--- a/i386/i386at/gpl/linux/include/linux/version.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#define UTS_RELEASE "1.3.68"
-#define UTS_VERSION "#1 Thu Feb 29 16:37:10 MST 1996"
-#define LINUX_COMPILE_TIME "09:03:52"
-#define LINUX_COMPILE_BY "goel"
-#define LINUX_COMPILE_HOST "stamp.cs.utah.edu"
-#define LINUX_COMPILE_DOMAIN "cs.utah.edu"
-#define LINUX_COMPILER "gcc version 2.7.2"
-#define LINUX_VERSION_CODE (65536 + 4 * 256)
diff --git a/i386/i386at/gpl/linux/include/linux/vfs.h b/i386/i386at/gpl/linux/include/linux/vfs.h
deleted file mode 100644
index b3a58657..00000000
--- a/i386/i386at/gpl/linux/include/linux/vfs.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _LINUX_VFS_H
-#define _LINUX_VFS_H
-
-#include <asm/statfs.h>
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/vm86.h b/i386/i386at/gpl/linux/include/linux/vm86.h
deleted file mode 100644
index ceb10358..00000000
--- a/i386/i386at/gpl/linux/include/linux/vm86.h
+++ /dev/null
@@ -1,109 +0,0 @@
-#ifndef _LINUX_VM86_H
-#define _LINUX_VM86_H
-
-/*
- * I'm guessing at the VIF/VIP flag usage, but hope that this is how
- * the Pentium uses them. Linux will return from vm86 mode when both
- * VIF and VIP is set.
- *
- * On a Pentium, we could probably optimize the virtual flags directly
- * in the eflags register instead of doing it "by hand" in vflags...
- *
- * Linus
- */
-
-#define TF_MASK 0x00000100
-#define IF_MASK 0x00000200
-#define IOPL_MASK 0x00003000
-#define NT_MASK 0x00004000
-#define VM_MASK 0x00020000
-#define AC_MASK 0x00040000
-#define VIF_MASK 0x00080000 /* virtual interrupt flag */
-#define VIP_MASK 0x00100000 /* virtual interrupt pending */
-#define ID_MASK 0x00200000
-
-#define BIOSSEG 0x0f000
-
-#define CPU_086 0
-#define CPU_186 1
-#define CPU_286 2
-#define CPU_386 3
-#define CPU_486 4
-#define CPU_586 5
-
-/*
- * Return values for the 'vm86()' system call
- */
-#define VM86_TYPE(retval) ((retval) & 0xff)
-#define VM86_ARG(retval) ((retval) >> 8)
-
-#define VM86_SIGNAL 0 /* return due to signal */
-#define VM86_UNKNOWN 1 /* unhandled GP fault - IO-instruction or similar */
-#define VM86_INTx 2 /* int3/int x instruction (ARG = x) */
-#define VM86_STI 3 /* sti/popf/iret instruction enabled virtual interrupts */
-
-/*
- * This is the stack-layout when we have done a "SAVE_ALL" from vm86
- * mode - the main change is that the old segment descriptors aren't
- * useful any more and are forced to be zero by the kernel (and the
- * hardware when a trap occurs), and the real segment descriptors are
- * at the end of the structure. Look at ptrace.h to see the "normal"
- * setup.
- */
-
-struct vm86_regs {
-/*
- * normal regs, with special meaning for the segment descriptors..
- */
- long ebx;
- long ecx;
- long edx;
- long esi;
- long edi;
- long ebp;
- long eax;
- long __null_ds;
- long __null_es;
- long __null_fs;
- long __null_gs;
- long orig_eax;
- long eip;
- unsigned short cs, __csh;
- long eflags;
- long esp;
- unsigned short ss, __ssh;
-/*
- * these are specific to v86 mode:
- */
- unsigned short es, __esh;
- unsigned short ds, __dsh;
- unsigned short fs, __fsh;
- unsigned short gs, __gsh;
-};
-
-struct revectored_struct {
- unsigned long __map[8]; /* 256 bits */
-};
-
-struct vm86_struct {
- struct vm86_regs regs;
- unsigned long flags;
- unsigned long screen_bitmap;
- unsigned long cpu_type;
- struct revectored_struct int_revectored;
- struct revectored_struct int21_revectored;
-};
-
-/*
- * flags masks
- */
-#define VM86_SCREEN_BITMAP 0x0001
-
-#ifdef __KERNEL__
-
-void handle_vm86_fault(struct vm86_regs *, long);
-void handle_vm86_debug(struct vm86_regs *, long);
-
-#endif
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/linux/wait.h b/i386/i386at/gpl/linux/include/linux/wait.h
deleted file mode 100644
index 90ffe7b3..00000000
--- a/i386/i386at/gpl/linux/include/linux/wait.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef _LINUX_WAIT_H
-#define _LINUX_WAIT_H
-
-#define WNOHANG 0x00000001
-#define WUNTRACED 0x00000002
-
-#define __WCLONE 0x80000000
-
-#ifdef __KERNEL__
-
-struct wait_queue {
- struct task_struct * task;
- struct wait_queue * next;
-};
-
-struct semaphore {
- int count;
- struct wait_queue * wait;
-};
-
-#define MUTEX ((struct semaphore) { 1, NULL })
-#define MUTEX_LOCKED ((struct semaphore) { 0, NULL })
-
-struct select_table_entry {
- struct wait_queue wait;
- struct wait_queue ** wait_address;
-};
-
-typedef struct select_table_struct {
- int nr;
- struct select_table_entry * entry;
-} select_table;
-
-#define __MAX_SELECT_TABLE_ENTRIES (4096 / sizeof (struct select_table_entry))
-
-#endif /* __KERNEL__ */
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/net/af_unix.h b/i386/i386at/gpl/linux/include/net/af_unix.h
deleted file mode 100644
index dc4a48d6..00000000
--- a/i386/i386at/gpl/linux/include/net/af_unix.h
+++ /dev/null
@@ -1,4 +0,0 @@
-extern void unix_proto_init(struct net_proto *pro);
-
-typedef struct sock unix_socket;
-
diff --git a/i386/i386at/gpl/linux/include/net/arp.h b/i386/i386at/gpl/linux/include/net/arp.h
deleted file mode 100644
index db7a29c3..00000000
--- a/i386/i386at/gpl/linux/include/net/arp.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* linux/net/inet/arp.h */
-#ifndef _ARP_H
-#define _ARP_H
-
-extern void arp_init(void);
-extern int arp_rcv(struct sk_buff *skb, struct device *dev,
- struct packet_type *pt);
-extern int arp_query(unsigned char *haddr, u32 paddr, struct device *dev);
-extern int arp_find(unsigned char *haddr, u32 paddr,
- struct device *dev, u32 saddr, struct sk_buff *skb);
-extern int arp_ioctl(unsigned int cmd, void *arg);
-extern void arp_send(int type, int ptype, u32 dest_ip,
- struct device *dev, u32 src_ip,
- unsigned char *dest_hw, unsigned char *src_hw, unsigned char *th);
-extern int arp_bind_cache(struct hh_cache ** hhp, struct device *dev, unsigned short type, __u32 daddr);
-extern int arp_update_cache(struct hh_cache * hh);
-#endif /* _ARP_H */
diff --git a/i386/i386at/gpl/linux/include/net/atalkcall.h b/i386/i386at/gpl/linux/include/net/atalkcall.h
deleted file mode 100644
index 726e33cd..00000000
--- a/i386/i386at/gpl/linux/include/net/atalkcall.h
+++ /dev/null
@@ -1,2 +0,0 @@
-/* Separate to keep compilation of protocols.c simpler */
-extern void atalk_proto_init(struct net_proto *pro);
diff --git a/i386/i386at/gpl/linux/include/net/ax25.h b/i386/i386at/gpl/linux/include/net/ax25.h
deleted file mode 100644
index 45967cb1..00000000
--- a/i386/i386at/gpl/linux/include/net/ax25.h
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Declarations of AX.25 type objects.
- *
- * Alan Cox (GW4PTS) 10/11/93
- */
-
-#ifndef _AX25_H
-#define _AX25_H
-#include <linux/ax25.h>
-
-#define PR_SLOWHZ 10 /* Run timing at 1/10 second - gives us better resolution for 56kbit links */
-
-#define AX25_T1CLAMPLO (1 * PR_SLOWHZ) /* If defined, clamp at 1 second **/
-#define AX25_T1CLAMPHI (30 * PR_SLOWHZ) /* If defined, clamp at 30 seconds **/
-
-#define AX25_BROKEN_NETMAC
-
-#define AX25_BPQ_HEADER_LEN 16
-#define AX25_KISS_HEADER_LEN 1
-
-#define AX25_HEADER_LEN 17
-#define AX25_ADDR_LEN 7
-#define AX25_DIGI_HEADER_LEN (AX25_MAX_DIGIS * AX25_ADDR_LEN)
-#define AX25_MAX_HEADER_LEN (AX25_HEADER_LEN + AX25_DIGI_HEADER_LEN)
-
-#define AX25_P_IP 0xCC
-#define AX25_P_ARP 0xCD
-#define AX25_P_TEXT 0xF0
-#define AX25_P_NETROM 0xCF
-#define AX25_P_SEGMENT 0x08
-
-#define SEG_REM 0x7F
-#define SEG_FIRST 0x80
-
-#define LAPB_UI 0x03
-#define LAPB_C 0x80
-#define LAPB_E 0x01
-
-#define SSSID_SPARE 0x60 /* Unused bits in SSID for standard AX.25 */
-#define ESSID_SPARE 0x20 /* Unused bits in SSID for extended AX.25 */
-#define DAMA_FLAG 0x40 /* Well, it is *NOT* unused! (dl1bke 951121 */
-
-#define AX25_REPEATED 0x80
-
-#define ACK_PENDING_CONDITION 0x01
-#define REJECT_CONDITION 0x02
-#define PEER_RX_BUSY_CONDITION 0x04
-#define OWN_RX_BUSY_CONDITION 0x08
-
-#ifndef _LINUX_NETDEVICE_H
-#include <linux/netdevice.h>
-#endif
-
-/*
- * These headers are taken from the KA9Q package by Phil Karn. These specific
- * files have been placed under the GPL (not the whole package) by Phil.
- *
- *
- * Copyright 1991 Phil Karn, KA9Q
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 dated June, 1991.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave., Cambridge, MA 02139, USA.
- */
-
-/* Upper sub-layer (LAPB) definitions */
-
-/* Control field templates */
-#define I 0x00 /* Information frames */
-#define S 0x01 /* Supervisory frames */
-#define RR 0x01 /* Receiver ready */
-#define RNR 0x05 /* Receiver not ready */
-#define REJ 0x09 /* Reject */
-#define U 0x03 /* Unnumbered frames */
-#define SABM 0x2f /* Set Asynchronous Balanced Mode */
-#define SABME 0x6f /* Set Asynchronous Balanced Mode Extended */
-#define DISC 0x43 /* Disconnect */
-#define DM 0x0f /* Disconnected mode */
-#define UA 0x63 /* Unnumbered acknowledge */
-#define FRMR 0x87 /* Frame reject */
-#define UI 0x03 /* Unnumbered information */
-#define PF 0x10 /* Poll/final bit for standard AX.25 */
-#define EPF 0x01 /* Poll/final bit for extended AX.25 */
-
-#define ILLEGAL 0x100 /* Impossible to be a real frame type */
-
-#define POLLOFF 0
-#define POLLON 1
-
-/* AX25 L2 C-bit */
-
-#define C_COMMAND 1 /* C_ otherwise it clashes with the de600 defines (sigh)) */
-#define C_RESPONSE 2
-
-/* Define Link State constants. */
-
-#define AX25_STATE_0 0
-#define AX25_STATE_1 1
-#define AX25_STATE_2 2
-#define AX25_STATE_3 3
-#define AX25_STATE_4 4
-
-#define MODULUS 8 /* Standard AX.25 modulus */
-#define EMODULUS 128 /* Extended AX.25 modulus */
-
-#define AX25_DEF_IPDEFMODE 'D'
-#define AX25_DEF_AXDEFMODE 8
-#define AX25_DEF_NETROM 1
-#define AX25_DEF_TEXT 1
-#define AX25_DEF_BACKOFF 'E'
-#define AX25_DEF_CONMODE 1
-#define AX25_DEF_WINDOW 2
-#define AX25_DEF_EWINDOW 32
-#define AX25_DEF_T1 10
-#define AX25_DEF_T2 3
-#define AX25_DEF_T3 300
-#define AX25_DEF_N2 10
-#define AX25_DEF_DIGI (AX25_DIGI_INBAND|AX25_DIGI_XBAND)
-
-typedef struct ax25_uid_assoc {
- struct ax25_uid_assoc *next;
- uid_t uid;
- ax25_address call;
-} ax25_uid_assoc;
-
-typedef struct {
- ax25_address calls[AX25_MAX_DIGIS];
- unsigned char repeated[AX25_MAX_DIGIS];
- unsigned char ndigi;
- char lastrepeat;
-} ax25_digi;
-
-typedef struct ax25_cb {
- struct ax25_cb *next;
- ax25_address source_addr, dest_addr;
- struct device *device;
- unsigned char dama_slave; /* dl1bke 951121 */
- unsigned char state, modulus, hdrincl;
- unsigned short vs, vr, va;
- unsigned char condition, backoff;
- unsigned char n2, n2count;
- unsigned short t1, t2, t3, rtt;
- unsigned short t1timer, t2timer, t3timer;
- unsigned short fragno, fraglen;
- ax25_digi *digipeat;
- struct sk_buff_head write_queue;
- struct sk_buff_head reseq_queue;
- struct sk_buff_head ack_queue;
- struct sk_buff_head frag_queue;
- unsigned char window;
- struct timer_list timer;
- struct sock *sk; /* Backlink to socket */
-} ax25_cb;
-
-/* af_ax25.c */
-extern ax25_address null_ax25_address;
-extern char *ax2asc(ax25_address *);
-extern int ax25cmp(ax25_address *, ax25_address *);
-extern int ax25_send_frame(struct sk_buff *, ax25_address *, ax25_address *, ax25_digi *, struct device *);
-extern void ax25_destroy_socket(ax25_cb *);
-extern struct device *ax25rtr_get_dev(ax25_address *);
-extern int ax25_encapsulate(struct sk_buff *, struct device *, unsigned short,
- void *, void *, unsigned int);
-extern int ax25_rebuild_header(unsigned char *, struct device *, unsigned long, struct sk_buff *);
-extern ax25_uid_assoc *ax25_uid_list;
-extern int ax25_uid_policy;
-extern ax25_address *ax25_findbyuid(uid_t);
-extern void ax25_queue_xmit(struct sk_buff *, struct device *, int);
-extern int ax25_dev_is_dama_slave(struct device *); /* dl1bke 951121 */
-
-#include <net/ax25call.h>
-
-/* ax25_in.c */
-extern int ax25_process_rx_frame(ax25_cb *, struct sk_buff *, int, int);
-
-/* ax25_out.c */
-extern void ax25_output(ax25_cb *, struct sk_buff *);
-extern void ax25_kick(ax25_cb *);
-extern void ax25_transmit_buffer(ax25_cb *, struct sk_buff *, int);
-extern void ax25_nr_error_recovery(ax25_cb *);
-extern void ax25_establish_data_link(ax25_cb *);
-extern void ax25_transmit_enquiry(ax25_cb *);
-extern void ax25_enquiry_response(ax25_cb *);
-extern void ax25_timeout_response(ax25_cb *);
-extern void ax25_check_iframes_acked(ax25_cb *, unsigned short);
-extern void ax25_check_need_response(ax25_cb *, int, int);
-extern void dama_enquiry_response(ax25_cb *); /* dl1bke 960114 */
-extern void dama_check_need_response(ax25_cb *, int, int); /* dl1bke 960114 */
-extern void dama_establish_data_link(ax25_cb *);
-
-/* ax25_route.c */
-extern void ax25_rt_rx_frame(ax25_address *, struct device *, ax25_digi *);
-extern int ax25_rt_get_info(char *, char **, off_t, int, int);
-extern int ax25_cs_get_info(char *, char **, off_t, int, int);
-extern int ax25_rt_autobind(ax25_cb *, ax25_address *);
-extern void ax25_rt_build_path(ax25_cb *, ax25_address *);
-extern void ax25_dg_build_path(struct sk_buff *, ax25_address *, struct device *);
-extern void ax25_rt_device_down(struct device *);
-extern int ax25_rt_ioctl(unsigned int, void *);
-extern void ax25_ip_mode_set(ax25_address *, struct device *, char);
-extern char ax25_ip_mode_get(ax25_address *, struct device *);
-extern unsigned short ax25_dev_get_value(struct device *, int);
-extern void ax25_dev_device_up(struct device *);
-extern void ax25_dev_device_down(struct device *);
-extern int ax25_dev_ioctl(unsigned int, void *);
-extern int ax25_bpq_get_info(char *, char **, off_t, int, int);
-extern ax25_address *ax25_bpq_get_addr(struct device *);
-extern int ax25_bpq_ioctl(unsigned int, void *);
-
-/* ax25_subr.c */
-extern void ax25_clear_queues(ax25_cb *);
-extern void ax25_frames_acked(ax25_cb *, unsigned short);
-extern void ax25_requeue_frames(ax25_cb *);
-extern int ax25_validate_nr(ax25_cb *, unsigned short);
-extern int ax25_decode(ax25_cb *, struct sk_buff *, int *, int *, int *);
-extern void ax25_send_control(ax25_cb *, int, int, int);
-extern unsigned short ax25_calculate_t1(ax25_cb *);
-extern void ax25_calculate_rtt(ax25_cb *);
-extern unsigned char *ax25_parse_addr(unsigned char *, int, ax25_address *,
- ax25_address *, ax25_digi *, int *, int *); /* dl1bke 951121 */
-extern int build_ax25_addr(unsigned char *, ax25_address *, ax25_address *,
- ax25_digi *, int, int);
-extern int size_ax25_addr(ax25_digi *);
-extern void ax25_digi_invert(ax25_digi *, ax25_digi *);
-extern void ax25_return_dm(struct device *, ax25_address *, ax25_address *, ax25_digi *);
-extern void ax25_dama_on(ax25_cb *); /* dl1bke 951121 */
-extern void ax25_dama_off(ax25_cb *); /* dl1bke 951121 */
-
-/* ax25_timer */
-extern void ax25_set_timer(ax25_cb *);
-extern void ax25_t1_timeout(ax25_cb *);
-
-/* ... */
-
-extern ax25_cb * volatile ax25_list;
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/net/ax25call.h b/i386/i386at/gpl/linux/include/net/ax25call.h
deleted file mode 100644
index 89569656..00000000
--- a/i386/i386at/gpl/linux/include/net/ax25call.h
+++ /dev/null
@@ -1,2 +0,0 @@
-/* Seperate to keep compilation of protocols.c simpler */
-extern void ax25_proto_init(struct net_proto *pro);
diff --git a/i386/i386at/gpl/linux/include/net/checksum.h b/i386/i386at/gpl/linux/include/net/checksum.h
deleted file mode 100644
index aee4fd47..00000000
--- a/i386/i386at/gpl/linux/include/net/checksum.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * INET An implementation of the TCP/IP protocol suite for the LINUX
- * operating system. INET is implemented using the BSD Socket
- * interface as the means of communication with the user level.
- *
- * Checksumming functions for IP, TCP, UDP and so on
- *
- * Authors: Jorge Cwik, <jorge@laser.satlink.net>
- * Arnt Gulbrandsen, <agulbra@nvg.unit.no>
- * Borrows very liberally from tcp.c and ip.c, see those
- * files for more names.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#ifndef _CHECKSUM_H
-#define _CHECKSUM_H
-
-#include <asm/byteorder.h>
-#include <net/ip.h>
-#include <asm/checksum.h>
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/net/datalink.h b/i386/i386at/gpl/linux/include/net/datalink.h
deleted file mode 100644
index 44e56990..00000000
--- a/i386/i386at/gpl/linux/include/net/datalink.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef _NET_INET_DATALINK_H_
-#define _NET_INET_DATALINK_H_
-
-struct datalink_proto {
- unsigned short type_len;
- unsigned char type[8];
- const char *string_name;
- unsigned short header_length;
- int (*rcvfunc)(struct sk_buff *, struct device *,
- struct packet_type *);
- void (*datalink_header)(struct datalink_proto *, struct sk_buff *,
- unsigned char *);
- struct datalink_proto *next;
-};
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/net/icmp.h b/i386/i386at/gpl/linux/include/net/icmp.h
deleted file mode 100644
index e4ae8213..00000000
--- a/i386/i386at/gpl/linux/include/net/icmp.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * INET An implementation of the TCP/IP protocol suite for the LINUX
- * operating system. INET is implemented using the BSD Socket
- * interface as the means of communication with the user level.
- *
- * Definitions for the ICMP module.
- *
- * Version: @(#)icmp.h 1.0.4 05/13/93
- *
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
- * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#ifndef _ICMP_H
-#define _ICMP_H
-
-#include <linux/icmp.h>
-#include <linux/skbuff.h>
-
-#include <net/sock.h>
-#include <net/protocol.h>
-
-extern struct icmp_err icmp_err_convert[];
-extern struct icmp_mib icmp_statistics;
-
-extern void icmp_send(struct sk_buff *skb_in, int type, int code,
- unsigned long info, struct device *dev);
-extern int icmp_rcv(struct sk_buff *skb1, struct device *dev,
- struct options *opt, __u32 daddr,
- unsigned short len, __u32 saddr,
- int redo, struct inet_protocol *protocol);
-extern int icmp_ioctl(struct sock *sk, int cmd,
- unsigned long arg);
-extern void icmp_init(struct proto_ops *ops);
-
-#endif /* _ICMP_H */
diff --git a/i386/i386at/gpl/linux/include/net/ip.h b/i386/i386at/gpl/linux/include/net/ip.h
deleted file mode 100644
index c7bd9987..00000000
--- a/i386/i386at/gpl/linux/include/net/ip.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * INET An implementation of the TCP/IP protocol suite for the LINUX
- * operating system. INET is implemented using the BSD Socket
- * interface as the means of communication with the user level.
- *
- * Definitions for the IP module.
- *
- * Version: @(#)ip.h 1.0.2 05/07/93
- *
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
- * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- * Alan Cox, <gw4pts@gw4pts.ampr.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#ifndef _IP_H
-#define _IP_H
-
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/ip.h>
-#include <linux/netdevice.h>
-#include <net/route.h>
-
-#ifndef _SNMP_H
-#include <net/snmp.h>
-#endif
-
-#include <net/sock.h> /* struct sock */
-
-/* IP flags. */
-#define IP_CE 0x8000 /* Flag: "Congestion" */
-#define IP_DF 0x4000 /* Flag: "Don't Fragment" */
-#define IP_MF 0x2000 /* Flag: "More Fragments" */
-#define IP_OFFSET 0x1FFF /* "Fragment Offset" part */
-
-#define IP_FRAG_TIME (30 * HZ) /* fragment lifetime */
-
-#ifdef CONFIG_IP_MULTICAST
-extern void ip_mc_dropsocket(struct sock *);
-extern void ip_mc_dropdevice(struct device *dev);
-extern int ip_mc_procinfo(char *, char **, off_t, int, int);
-#endif
-
-#include <net/ip_forward.h>
-
-/* Describe an IP fragment. */
-struct ipfrag
-{
- int offset; /* offset of fragment in IP datagram */
- int end; /* last byte of data in datagram */
- int len; /* length of this fragment */
- struct sk_buff *skb; /* complete received fragment */
- unsigned char *ptr; /* pointer into real fragment data */
- struct ipfrag *next; /* linked list pointers */
- struct ipfrag *prev;
-};
-
-/*
- * Describe an entry in the "incomplete datagrams" queue.
- */
-
-struct ipq
-{
- unsigned char *mac; /* pointer to MAC header */
- struct iphdr *iph; /* pointer to IP header */
- int len; /* total length of original datagram */
- short ihlen; /* length of the IP header */
- short maclen; /* length of the MAC header */
- struct timer_list timer; /* when will this queue expire? */
- struct ipfrag *fragments; /* linked list of received fragments */
- struct ipq *next; /* linked list pointers */
- struct ipq *prev;
- struct device *dev; /* Device - for icmp replies */
-};
-
-/*
- * Functions provided by ip.c
- */
-
-extern void ip_print(const struct iphdr *ip);
-extern int ip_ioctl(struct sock *sk, int cmd, unsigned long arg);
-extern void ip_route_check(__u32 daddr);
-extern int ip_send(struct rtable *rt, struct sk_buff *skb, __u32 daddr, int len, struct device *dev, __u32 saddr);
-extern int ip_build_header(struct sk_buff *skb,
- __u32 saddr,
- __u32 daddr,
- struct device **dev, int type,
- struct options *opt, int len,
- int tos,int ttl,struct rtable **rp);
-extern int ip_rcv(struct sk_buff *skb, struct device *dev,
- struct packet_type *pt);
-extern int ip_options_echo(struct options * dopt, struct options * sopt,
- __u32 daddr, __u32 saddr,
- struct sk_buff * skb);
-extern int ip_options_compile(struct options * opt, struct sk_buff * skb);
-extern void ip_send_check(struct iphdr *ip);
-extern int ip_id_count;
-extern void ip_queue_xmit(struct sock *sk,
- struct device *dev, struct sk_buff *skb,
- int free);
-extern void ip_init(void);
-extern int ip_build_xmit(struct sock *sk,
- void getfrag (const void *,
- __u32,
- char *,
- unsigned int,
- unsigned int),
- const void *frag,
- unsigned short int length,
- __u32 daddr,
- __u32 saddr,
- struct options * opt,
- int flags,
- int type,
- int noblock);
-
-extern struct ip_mib ip_statistics;
-
-/*
- * Functions provided by ip_fragment.o
- */
-
-struct sk_buff *ip_defrag(struct iphdr *iph, struct sk_buff *skb, struct device *dev);
-void ip_fragment(struct sock *sk, struct sk_buff *skb, struct device *dev, int is_frag);
-
-/*
- * Functions provided by ip_forward.c
- */
-
-extern int ip_forward(struct sk_buff *skb, struct device *dev, int is_frag, __u32 target_addr);
-
-/*
- * Functions provided by ip_options.c
- */
-
-extern void ip_options_build(struct sk_buff *skb, struct options *opt, __u32 daddr, __u32 saddr, int is_frag);
-extern int ip_options_echo(struct options *dopt, struct options *sopt, __u32 daddr, __u32 saddr, struct sk_buff *skb);
-extern void ip_options_fragment(struct sk_buff *skb);
-extern int ip_options_compile(struct options *opt, struct sk_buff *skb);
-
-/*
- * Functions provided by ip_sockglue.c
- */
-
-extern int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int optlen);
-extern int ip_getsockopt(struct sock *sk, int level, int optname, char *optval, int *optlen);
-
-#endif /* _IP_H */
diff --git a/i386/i386at/gpl/linux/include/net/ip_alias.h b/i386/i386at/gpl/linux/include/net/ip_alias.h
deleted file mode 100644
index 683a0427..00000000
--- a/i386/i386at/gpl/linux/include/net/ip_alias.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * IP_ALIAS (AF_INET) aliasing definitions.
- *
- *
- * Version: @(#)ip_alias.h 0.43 12/20/95
- *
- * Author: Juan Jose Ciarlante, <jjciarla@raiz.uncu.edu.ar>
- *
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- */
-
-#ifndef _IP_ALIAS_H
-#define _IP_ALIAS_H
-
-extern int ip_alias_init(void);
-extern int ip_alias_done(void);
-
-#endif /* _IP_ALIAS_H */
diff --git a/i386/i386at/gpl/linux/include/net/ip_forward.h b/i386/i386at/gpl/linux/include/net/ip_forward.h
deleted file mode 100644
index b8596500..00000000
--- a/i386/i386at/gpl/linux/include/net/ip_forward.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef __NET_IP_FORWARD_H
-#define __NET_IP_FORWARD_H
-
-#define IPFWD_FRAGMENT 1
-#define IPFWD_LASTFRAG 2
-#define IPFWD_MASQUERADED 4
-#define IPFWD_MULTICASTING 8
-#define IPFWD_MULTITUNNEL 16
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/net/ipip.h b/i386/i386at/gpl/linux/include/net/ipip.h
deleted file mode 100644
index bba1492e..00000000
--- a/i386/i386at/gpl/linux/include/net/ipip.h
+++ /dev/null
@@ -1,4 +0,0 @@
-extern int ipip_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
- __u32 daddr, unsigned short len, __u32 saddr,
- int redo, struct inet_protocol *protocol);
-
diff --git a/i386/i386at/gpl/linux/include/net/ipx.h b/i386/i386at/gpl/linux/include/net/ipx.h
deleted file mode 100644
index 96c62405..00000000
--- a/i386/i386at/gpl/linux/include/net/ipx.h
+++ /dev/null
@@ -1,85 +0,0 @@
-
-/*
- * The following information is in its entirety obtained from:
- *
- * Novell 'IPX Router Specification' Version 1.10
- * Part No. 107-000029-001
- *
- * Which is available from ftp.novell.com
- */
-
-#ifndef _NET_INET_IPX_H_
-#define _NET_INET_IPX_H_
-
-#include <linux/skbuff.h>
-#include <net/datalink.h>
-#include <linux/ipx.h>
-
-typedef struct
-{
- unsigned long net;
- unsigned char node[IPX_NODE_LEN];
- unsigned short sock;
-} ipx_address;
-
-#define ipx_broadcast_node "\377\377\377\377\377\377"
-#define ipx_this_node "\0\0\0\0\0\0"
-
-typedef struct ipx_packet
-{
- unsigned short ipx_checksum;
-#define IPX_NO_CHECKSUM 0xFFFF
- unsigned short ipx_pktsize;
- unsigned char ipx_tctrl;
- unsigned char ipx_type;
-#define IPX_TYPE_UNKNOWN 0x00
-#define IPX_TYPE_RIP 0x01 /* may also be 0 */
-#define IPX_TYPE_SAP 0x04 /* may also be 0 */
-#define IPX_TYPE_SPX 0x05 /* Not yet implemented */
-#define IPX_TYPE_NCP 0x11 /* $lots for docs on this (SPIT) */
-#define IPX_TYPE_PPROP 0x14 /* complicated flood fill brdcast [Not supported] */
- ipx_address ipx_dest __attribute__ ((packed));
- ipx_address ipx_source __attribute__ ((packed));
-} ipx_packet;
-
-
-typedef struct sock ipx_socket;
-
-#include <net/ipxcall.h>
-extern int ipx_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt);
-extern void ipxrtr_device_down(struct device *dev);
-
-typedef struct ipx_interface {
- /* IPX address */
- unsigned long if_netnum;
- unsigned char if_node[IPX_NODE_LEN];
-
- /* physical device info */
- struct device *if_dev;
- struct datalink_proto *if_dlink;
- unsigned short if_dlink_type;
-
- /* socket support */
- unsigned short if_sknum;
- ipx_socket *if_sklist;
-
- /* administrative overhead */
- int if_ipx_offset;
- unsigned char if_internal;
- unsigned char if_primary;
-
- struct ipx_interface *if_next;
-} ipx_interface;
-
-typedef struct ipx_route {
- unsigned long ir_net;
- ipx_interface *ir_intrfc;
- unsigned char ir_routed;
- unsigned char ir_router_node[IPX_NODE_LEN];
- struct ipx_route *ir_next;
-} ipx_route;
-
-#define IPX_MIN_EPHEMERAL_SOCKET 0x4000
-#define IPX_MAX_EPHEMERAL_SOCKET 0x7fff
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/net/ipxcall.h b/i386/i386at/gpl/linux/include/net/ipxcall.h
deleted file mode 100644
index eb5bd2bd..00000000
--- a/i386/i386at/gpl/linux/include/net/ipxcall.h
+++ /dev/null
@@ -1,2 +0,0 @@
-/* Separate to keep compilation of protocols.c simpler */
-extern void ipx_proto_init(struct net_proto *pro);
diff --git a/i386/i386at/gpl/linux/include/net/netlink.h b/i386/i386at/gpl/linux/include/net/netlink.h
deleted file mode 100644
index e32af15b..00000000
--- a/i386/i386at/gpl/linux/include/net/netlink.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef __NET_NETLINK_H
-#define __NET_NETLINK_H
-
-#define NET_MAJOR 36 /* Major 18 is reserved for networking */
-#define MAX_LINKS 4 /* 18,0 for route updates, 18,1 for SKIP, 18,2 debug tap 18,3 PPP reserved */
-#define MAX_QBYTES 32768 /* Maximum bytes in the queue */
-
-#include <linux/config.h>
-
-extern int netlink_attach(int unit, int (*function)(struct sk_buff *skb));
-extern int netlink_donothing(struct sk_buff *skb);
-extern void netlink_detach(int unit);
-extern int netlink_post(int unit, struct sk_buff *skb);
-extern int init_netlink(void);
-
-#define NETLINK_ROUTE 0 /* Routing/device hook */
-#define NETLINK_SKIP 1 /* Reserved for ENskip */
-#define NETLINK_USERSOCK 2 /* Reserved for user mode socket protocols */
-#define NETLINK_FIREWALL 3 /* Firewalling hook */
-
-#ifdef CONFIG_RTNETLINK
-extern void ip_netlink_msg(unsigned long, __u32, __u32, __u32, short, short, char *);
-#else
-#define ip_netlink_msg(a,b,c,d,e,f,g)
-#endif
-#endif
diff --git a/i386/i386at/gpl/linux/include/net/netrom.h b/i386/i386at/gpl/linux/include/net/netrom.h
deleted file mode 100644
index 5e343bbc..00000000
--- a/i386/i386at/gpl/linux/include/net/netrom.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Declarations of NET/ROM type objects.
- *
- * Jonathan Naylor G4KLX 9/4/95
- */
-
-#ifndef _NETROM_H
-#define _NETROM_H
-#include <linux/netrom.h>
-
-#define NR_T1CLAMPLO (1 * PR_SLOWHZ) /* If defined, clamp at 1 second **/
-#define NR_T1CLAMPHI (300 * PR_SLOWHZ) /* If defined, clamp at 30 seconds **/
-
-#define NR_NETWORK_LEN 15
-#define NR_TRANSPORT_LEN 5
-
-#define NR_PROTO_IP 0x0C
-
-#define NR_PROTOEXT 0x00
-#define NR_CONNREQ 0x01
-#define NR_CONNACK 0x02
-#define NR_DISCREQ 0x03
-#define NR_DISCACK 0x04
-#define NR_INFO 0x05
-#define NR_INFOACK 0x06
-
-#define NR_CHOKE_FLAG 0x80
-#define NR_NAK_FLAG 0x40
-#define NR_MORE_FLAG 0x20
-
-/* Define Link State constants. */
-
-#define NR_STATE_0 0
-#define NR_STATE_1 1
-#define NR_STATE_2 2
-#define NR_STATE_3 3
-
-#define NR_DEFAULT_T1 (120 * PR_SLOWHZ) /* Outstanding frames - 120 seconds */
-#define NR_DEFAULT_T2 (5 * PR_SLOWHZ) /* Response delay - 5 seconds */
-#define NR_DEFAULT_N2 3 /* Number of Retries */
-#define NR_DEFAULT_T4 (180 * PR_SLOWHZ) /* Transport Busy Delay */
-#define NR_DEFAULT_WINDOW 4 /* Default Window Size */
-#define NR_DEFAULT_OBS 6 /* Default Obscolesence Count */
-#define NR_DEFAULT_QUAL 10 /* Default Neighbour Quality */
-#define NR_DEFAULT_TTL 16 /* Default Time To Live */
-#define NR_MODULUS 256
-#define NR_MAX_WINDOW_SIZE 127 /* Maximum Window Allowable */
-
-typedef struct {
- ax25_address user_addr, source_addr, dest_addr;
- struct device *device;
- unsigned char my_index, my_id;
- unsigned char your_index, your_id;
- unsigned char state, condition, bpqext, hdrincl;
- unsigned short vs, vr, va, vl;
- unsigned char n2, n2count;
- unsigned short t1, t2, rtt;
- unsigned short t1timer, t2timer, t4timer;
- unsigned short fraglen;
- struct sk_buff_head ack_queue;
- struct sk_buff_head reseq_queue;
- struct sk_buff_head frag_queue;
- struct sock *sk; /* Backlink to socket */
-} nr_cb;
-
-struct nr_route {
- unsigned char quality;
- unsigned char obs_count;
- unsigned short neighbour;
-};
-
-struct nr_node {
- struct nr_node *next;
- ax25_address callsign;
- char mnemonic[7];
- unsigned char which;
- unsigned char count;
- struct nr_route routes[3];
-};
-
-struct nr_neigh {
- struct nr_neigh *next;
- ax25_address callsign;
- ax25_digi *digipeat;
- struct device *dev;
- unsigned char quality;
- unsigned char locked;
- unsigned short count;
- unsigned short number;
-};
-
-/* af_netrom.c */
-extern struct nr_parms_struct nr_default;
-extern int nr_rx_frame(struct sk_buff *, struct device *);
-extern void nr_destroy_socket(struct sock *);
-
-/* nr_dev.c */
-extern int nr_rx_ip(struct sk_buff *, struct device *);
-extern int nr_init(struct device *);
-
-#include <net/nrcall.h>
-
-/* nr_in.c */
-extern int nr_process_rx_frame(struct sock *, struct sk_buff *);
-
-/* nr_out.c */
-extern void nr_output(struct sock *, struct sk_buff *);
-extern void nr_send_nak_frame(struct sock *);
-extern void nr_kick(struct sock *);
-extern void nr_transmit_buffer(struct sock *, struct sk_buff *);
-extern void nr_establish_data_link(struct sock *);
-extern void nr_enquiry_response(struct sock *);
-extern void nr_check_iframes_acked(struct sock *, unsigned short);
-
-/* nr_route.c */
-extern void nr_rt_device_down(struct device *);
-extern struct device *nr_dev_first(void);
-extern struct device *nr_dev_get(ax25_address *);
-extern int nr_rt_ioctl(unsigned int, void *);
-extern void nr_link_failed(ax25_address *, struct device *);
-extern int nr_route_frame(struct sk_buff *, ax25_cb *);
-extern int nr_nodes_get_info(char *, char **, off_t, int, int);
-extern int nr_neigh_get_info(char *, char **, off_t, int, int);
-
-/* nr_subr.c */
-extern void nr_clear_queues(struct sock *);
-extern void nr_frames_acked(struct sock *, unsigned short);
-extern void nr_requeue_frames(struct sock *);
-extern int nr_validate_nr(struct sock *, unsigned short);
-extern int nr_in_rx_window(struct sock *, unsigned short);
-extern void nr_write_internal(struct sock *, int);
-extern void nr_transmit_dm(struct sk_buff *);
-extern unsigned short nr_calculate_t1(struct sock *);
-extern void nr_calculate_rtt(struct sock *);
-
-/* ax25_timer */
-extern void nr_set_timer(struct sock *);
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/net/nrcall.h b/i386/i386at/gpl/linux/include/net/nrcall.h
deleted file mode 100644
index f58c2d4f..00000000
--- a/i386/i386at/gpl/linux/include/net/nrcall.h
+++ /dev/null
@@ -1,2 +0,0 @@
-/* Seperate to keep compilation of protocols.c simpler */
-extern void nr_proto_init(struct net_proto *pro);
diff --git a/i386/i386at/gpl/linux/include/net/p8022.h b/i386/i386at/gpl/linux/include/net/p8022.h
deleted file mode 100644
index 52c676be..00000000
--- a/i386/i386at/gpl/linux/include/net/p8022.h
+++ /dev/null
@@ -1,2 +0,0 @@
-struct datalink_proto *register_8022_client(unsigned char type, int (*rcvfunc)(struct sk_buff *, struct device *, struct packet_type *));
-
diff --git a/i386/i386at/gpl/linux/include/net/p8022call.h b/i386/i386at/gpl/linux/include/net/p8022call.h
deleted file mode 100644
index 14f0c2ce..00000000
--- a/i386/i386at/gpl/linux/include/net/p8022call.h
+++ /dev/null
@@ -1,2 +0,0 @@
-/* Separate to keep compilation of Space.c simpler */
-extern void p8022_proto_init(struct net_proto *);
diff --git a/i386/i386at/gpl/linux/include/net/protocol.h b/i386/i386at/gpl/linux/include/net/protocol.h
deleted file mode 100644
index ae328b69..00000000
--- a/i386/i386at/gpl/linux/include/net/protocol.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * INET An implementation of the TCP/IP protocol suite for the LINUX
- * operating system. INET is implemented using the BSD Socket
- * interface as the means of communication with the user level.
- *
- * Definitions for the protocol dispatcher.
- *
- * Version: @(#)protocol.h 1.0.2 05/07/93
- *
- * Author: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- * Changes:
- * Alan Cox : Added a name field and a frag handler
- * field for later.
- * Alan Cox : Cleaned up, and sorted types.
- */
-
-#ifndef _PROTOCOL_H
-#define _PROTOCOL_H
-
-#define MAX_INET_PROTOS 32 /* Must be a power of 2 */
-
-
-/* This is used to register protocols. */
-struct inet_protocol {
- int (*handler)(struct sk_buff *skb, struct device *dev,
- struct options *opt, __u32 daddr,
- unsigned short len, __u32 saddr,
- int redo, struct inet_protocol *protocol);
- void (*err_handler)(int type, int code, unsigned char *buff,
- __u32 daddr,
- __u32 saddr,
- struct inet_protocol *protocol);
- struct inet_protocol *next;
- unsigned char protocol;
- unsigned char copy:1;
- void *data;
- const char *name;
-};
-
-
-extern struct inet_protocol *inet_protocol_base;
-extern struct inet_protocol *inet_protos[MAX_INET_PROTOS];
-
-
-extern void inet_add_protocol(struct inet_protocol *prot);
-extern int inet_del_protocol(struct inet_protocol *prot);
-
-
-#endif /* _PROTOCOL_H */
diff --git a/i386/i386at/gpl/linux/include/net/psnap.h b/i386/i386at/gpl/linux/include/net/psnap.h
deleted file mode 100644
index b69859db..00000000
--- a/i386/i386at/gpl/linux/include/net/psnap.h
+++ /dev/null
@@ -1,2 +0,0 @@
-struct datalink_proto *register_snap_client(unsigned char *desc, int (*rcvfunc)(struct sk_buff *, struct device *, struct packet_type *));
-
diff --git a/i386/i386at/gpl/linux/include/net/psnapcall.h b/i386/i386at/gpl/linux/include/net/psnapcall.h
deleted file mode 100644
index 9da5763c..00000000
--- a/i386/i386at/gpl/linux/include/net/psnapcall.h
+++ /dev/null
@@ -1,2 +0,0 @@
-/* Separate to keep compilation of Space.c simpler */
-extern void snap_proto_init(struct net_proto *);
diff --git a/i386/i386at/gpl/linux/include/net/rarp.h b/i386/i386at/gpl/linux/include/net/rarp.h
deleted file mode 100644
index 7bfb08ef..00000000
--- a/i386/i386at/gpl/linux/include/net/rarp.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* linux/net/inet/rarp.h */
-#ifndef _RARP_H
-#define _RARP_H
-
-extern int rarp_ioctl(unsigned int cmd, void *arg);
-extern int rarp_get_info(char *buffer,
- char **start,
- off_t offset,
- int length,
- int dummy);
-#endif /* _RARP_H */
-
diff --git a/i386/i386at/gpl/linux/include/net/raw.h b/i386/i386at/gpl/linux/include/net/raw.h
deleted file mode 100644
index 4b424879..00000000
--- a/i386/i386at/gpl/linux/include/net/raw.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * INET An implementation of the TCP/IP protocol suite for the LINUX
- * operating system. INET is implemented using the BSD Socket
- * interface as the means of communication with the user level.
- *
- * Definitions for the RAW-IP module.
- *
- * Version: @(#)raw.h 1.0.2 05/07/93
- *
- * Author: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#ifndef _RAW_H
-#define _RAW_H
-
-
-extern struct proto raw_prot;
-
-
-extern void raw_err(int type, int code, unsigned char *header, __u32 daddr,
- __u32 saddr, struct inet_protocol *protocol);
-extern int raw_recvfrom(struct sock *sk, unsigned char *to,
- int len, int noblock, unsigned flags,
- struct sockaddr_in *sin, int *addr_len);
-extern int raw_read(struct sock *sk, unsigned char *buff,
- int len, int noblock, unsigned flags);
-extern int raw_rcv(struct sock *, struct sk_buff *, struct device *,
- __u32, __u32);
-
-#endif /* _RAW_H */
diff --git a/i386/i386at/gpl/linux/include/net/route.h b/i386/i386at/gpl/linux/include/net/route.h
deleted file mode 100644
index 8ce67383..00000000
--- a/i386/i386at/gpl/linux/include/net/route.h
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * INET An implementation of the TCP/IP protocol suite for the LINUX
- * operating system. INET is implemented using the BSD Socket
- * interface as the means of communication with the user level.
- *
- * Definitions for the IP router.
- *
- * Version: @(#)route.h 1.0.4 05/27/93
- *
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
- * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- * Fixes:
- * Alan Cox : Reformatted. Added ip_rt_local()
- * Alan Cox : Support for TCP parameters.
- * Alexey Kuznetsov: Major changes for new routing code.
- *
- * FIXME:
- * Modules stuff is broken at the moment.
- * Make atomic ops more generic and hide them in asm/...
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#ifndef _ROUTE_H
-#define _ROUTE_H
-
-#include <linux/config.h>
-
-/*
- * 0 - no debugging messages
- * 1 - rare events and bugs situations (default)
- * 2 - trace mode.
- */
-#define RT_CACHE_DEBUG 1
-
-#define RT_HASH_DIVISOR 256
-#define RT_CACHE_SIZE_MAX 256
-
-#define RTZ_HASH_DIVISOR 256
-
-#if RT_CACHE_DEBUG >= 2
-#define RTZ_HASHING_LIMIT 0
-#else
-#define RTZ_HASHING_LIMIT 16
-#endif
-
-/*
- * Maximal time to live for unused entry.
- */
-#define RT_CACHE_TIMEOUT (HZ*300)
-
-/*
- * Prevents LRU trashing, entries considered equivalent,
- * if the difference between last use times is less then this number.
- */
-#define RT_CACHE_BUBBLE_THRESHOULD (HZ*5)
-
-#include <linux/route.h>
-
-#ifdef __KERNEL__
-#define RTF_LOCAL 0x8000
-#endif
-
-/*
- * Semaphores.
- */
-#if defined(__alpha__)
-
-static __inline__ void ATOMIC_INCR(unsigned int * addr)
-{
- unsigned tmp;
-
- __asm__ __volatile__(
- "1:\n\
- ldl_l %1,%2\n\
- addl %1,1,%1\n\
- stl_c %1,%0\n\
- beq %1,1b\n"
- : "m=" (*addr), "r=&" (tmp)
- : "m"(*addr));
-}
-
-static __inline__ void ATOMIC_DECR(unsigned int * addr)
-{
- unsigned tmp;
-
- __asm__ __volatile__(
- "1:\n\
- ldl_l %1,%2\n\
- subl %1,1,%1\n\
- stl_c %1,%0\n\
- beq %1,1b\n"
- : "m=" (*addr), "r=&" (tmp)
- : "m"(*addr));
-}
-
-static __inline__ int ATOMIC_DECR_AND_CHECK (unsigned int * addr)
-{
- unsigned tmp;
- int result;
-
- __asm__ __volatile__(
- "1:\n\
- ldl_l %1,%3\n\
- subl %1,1,%1\n\
- mov %1,%2\n\
- stl_c %1,%0\n\
- beq %1,1b\n"
- : "m=" (*addr), "r=&" (tmp), "r=&"(result)
- : "m"(*addr));
- return result;
-}
-
-#elif defined(__i386__)
-#include <asm/bitops.h>
-
-extern __inline__ void ATOMIC_INCR(void * addr)
-{
- __asm__ __volatile__(
- "incl %0"
- :"=m" (ADDR));
-}
-
-extern __inline__ void ATOMIC_DECR(void * addr)
-{
- __asm__ __volatile__(
- "decl %0"
- :"=m" (ADDR));
-}
-
-/*
- * It is DECR that is ATOMIC, not CHECK!
- * If you want to do atomic checks, use cli()/sti(). --ANK
- */
-
-extern __inline__ unsigned long ATOMIC_DECR_AND_CHECK(void * addr)
-{
- unsigned long retval;
- __asm__ __volatile__(
- "decl %0\nmovl %0,%1"
- : "=m" (ADDR), "=r"(retval));
- return retval;
-}
-
-
-#else
-
-static __inline__ void ATOMIC_INCR(unsigned int * addr)
-{
- (*(__volatile__ unsigned int*)addr)++;
-}
-
-static __inline__ void ATOMIC_DECR(unsigned int * addr)
-{
- (*(__volatile__ unsigned int*)addr)--;
-}
-
-static __inline__ int ATOMIC_DECR_AND_CHECK (unsigned int * addr)
-{
- ATOMIC_DECR(addr);
- return *(volatile unsigned int*)addr;
-}
-
-#endif
-
-
-
-struct rtable
-{
- struct rtable *rt_next;
- __u32 rt_dst;
- __u32 rt_src;
- __u32 rt_gateway;
- unsigned rt_refcnt;
- unsigned rt_use;
- unsigned long rt_window;
- unsigned long rt_lastuse;
- struct hh_cache *rt_hh;
- struct device *rt_dev;
- unsigned short rt_flags;
- unsigned short rt_mtu;
- unsigned short rt_irtt;
- unsigned char rt_tos;
-};
-
-extern void ip_rt_flush(struct device *dev);
-extern void ip_rt_redirect(__u32 src, __u32 dst, __u32 gw, struct device *dev);
-extern struct rtable *ip_rt_slow_route(__u32 daddr, int local);
-extern int rt_get_info(char * buffer, char **start, off_t offset, int length, int dummy);
-extern int rt_cache_get_info(char *buffer, char **start, off_t offset, int length, int dummy);
-extern int ip_rt_ioctl(unsigned int cmd, void *arg);
-extern int ip_rt_new(struct rtentry *rt);
-extern void ip_rt_check_expire(void);
-extern void ip_rt_advice(struct rtable **rp, int advice);
-
-extern void ip_rt_run_bh(void);
-extern int ip_rt_lock;
-extern unsigned ip_rt_bh_mask;
-extern struct rtable *ip_rt_hash_table[RT_HASH_DIVISOR];
-
-extern __inline__ void ip_rt_fast_lock(void)
-{
- ATOMIC_INCR(&ip_rt_lock);
-}
-
-extern __inline__ void ip_rt_fast_unlock(void)
-{
- ATOMIC_DECR(&ip_rt_lock);
-}
-
-extern __inline__ void ip_rt_unlock(void)
-{
- if (!ATOMIC_DECR_AND_CHECK(&ip_rt_lock) && ip_rt_bh_mask)
- ip_rt_run_bh();
-}
-
-extern __inline__ unsigned ip_rt_hash_code(__u32 addr)
-{
- unsigned tmp = addr + (addr>>16);
- return (tmp + (tmp>>8)) & 0xFF;
-}
-
-
-extern __inline__ void ip_rt_put(struct rtable * rt)
-#ifndef MODULE
-{
- if (rt)
- ATOMIC_DECR(&rt->rt_refcnt);
-}
-#else
-;
-#endif
-
-#ifdef CONFIG_KERNELD
-extern struct rtable * ip_rt_route(__u32 daddr, int local);
-#else
-extern __inline__ struct rtable * ip_rt_route(__u32 daddr, int local)
-#ifndef MODULE
-{
- struct rtable * rth;
-
- ip_rt_fast_lock();
-
- for (rth=ip_rt_hash_table[ip_rt_hash_code(daddr)^local]; rth; rth=rth->rt_next)
- {
- if (rth->rt_dst == daddr)
- {
- rth->rt_lastuse = jiffies;
- ATOMIC_INCR(&rth->rt_use);
- ATOMIC_INCR(&rth->rt_refcnt);
- ip_rt_unlock();
- return rth;
- }
- }
- return ip_rt_slow_route (daddr, local);
-}
-#else
-;
-#endif
-#endif
-
-extern __inline__ struct rtable * ip_check_route(struct rtable ** rp,
- __u32 daddr, int local)
-{
- struct rtable * rt = *rp;
-
- if (!rt || rt->rt_dst != daddr || !(rt->rt_flags&RTF_UP)
- || ((local==1)^((rt->rt_flags&RTF_LOCAL) != 0)))
- {
- ip_rt_put(rt);
- rt = ip_rt_route(daddr, local);
- *rp = rt;
- }
- return rt;
-}
-
-
-#endif /* _ROUTE_H */
diff --git a/i386/i386at/gpl/linux/include/net/slhc.h b/i386/i386at/gpl/linux/include/net/slhc.h
deleted file mode 100644
index c7b39db5..00000000
--- a/i386/i386at/gpl/linux/include/net/slhc.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __NET_SLHC_H
-#define __NET_SLHC_H
-
-extern void slhc_install(void);
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/net/snmp.h b/i386/i386at/gpl/linux/include/net/snmp.h
deleted file mode 100644
index 552292be..00000000
--- a/i386/i386at/gpl/linux/include/net/snmp.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- *
- * SNMP MIB entries for the IP subsystem.
- *
- * Alan Cox <gw4pts@gw4pts.ampr.org>
- *
- * We don't chose to implement SNMP in the kernel (this would
- * be silly as SNMP is a pain in the backside in places). We do
- * however need to collect the MIB statistics and export them
- * out of /proc (eventually)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- */
-
-#ifndef _SNMP_H
-#define _SNMP_H
-
-/*
- * We use all unsigned longs. Linux will soon be so reliable that even these
- * will rapidly get too small 8-). Seriously consider the IpInReceives count
- * on the 20Gb/s + networks people expect in a few years time!
- */
-
-struct ip_mib
-{
- unsigned long IpForwarding;
- unsigned long IpDefaultTTL;
- unsigned long IpInReceives;
- unsigned long IpInHdrErrors;
- unsigned long IpInAddrErrors;
- unsigned long IpForwDatagrams;
- unsigned long IpInUnknownProtos;
- unsigned long IpInDiscards;
- unsigned long IpInDelivers;
- unsigned long IpOutRequests;
- unsigned long IpOutDiscards;
- unsigned long IpOutNoRoutes;
- unsigned long IpReasmTimeout;
- unsigned long IpReasmReqds;
- unsigned long IpReasmOKs;
- unsigned long IpReasmFails;
- unsigned long IpFragOKs;
- unsigned long IpFragFails;
- unsigned long IpFragCreates;
-};
-
-
-struct icmp_mib
-{
- unsigned long IcmpInMsgs;
- unsigned long IcmpInErrors;
- unsigned long IcmpInDestUnreachs;
- unsigned long IcmpInTimeExcds;
- unsigned long IcmpInParmProbs;
- unsigned long IcmpInSrcQuenchs;
- unsigned long IcmpInRedirects;
- unsigned long IcmpInEchos;
- unsigned long IcmpInEchoReps;
- unsigned long IcmpInTimestamps;
- unsigned long IcmpInTimestampReps;
- unsigned long IcmpInAddrMasks;
- unsigned long IcmpInAddrMaskReps;
- unsigned long IcmpOutMsgs;
- unsigned long IcmpOutErrors;
- unsigned long IcmpOutDestUnreachs;
- unsigned long IcmpOutTimeExcds;
- unsigned long IcmpOutParmProbs;
- unsigned long IcmpOutSrcQuenchs;
- unsigned long IcmpOutRedirects;
- unsigned long IcmpOutEchos;
- unsigned long IcmpOutEchoReps;
- unsigned long IcmpOutTimestamps;
- unsigned long IcmpOutTimestampReps;
- unsigned long IcmpOutAddrMasks;
- unsigned long IcmpOutAddrMaskReps;
-};
-
-struct tcp_mib
-{
- unsigned long TcpRtoAlgorithm;
- unsigned long TcpRtoMin;
- unsigned long TcpRtoMax;
- unsigned long TcpMaxConn;
- unsigned long TcpActiveOpens;
- unsigned long TcpPassiveOpens;
- unsigned long TcpAttemptFails;
- unsigned long TcpEstabResets;
- unsigned long TcpCurrEstab;
- unsigned long TcpInSegs;
- unsigned long TcpOutSegs;
- unsigned long TcpRetransSegs;
-};
-
-struct udp_mib
-{
- unsigned long UdpInDatagrams;
- unsigned long UdpNoPorts;
- unsigned long UdpInErrors;
- unsigned long UdpOutDatagrams;
-};
-
-
-#endif
diff --git a/i386/i386at/gpl/linux/include/net/sock.h b/i386/i386at/gpl/linux/include/net/sock.h
deleted file mode 100644
index dc7a4a90..00000000
--- a/i386/i386at/gpl/linux/include/net/sock.h
+++ /dev/null
@@ -1,486 +0,0 @@
-/*
- * INET An implementation of the TCP/IP protocol suite for the LINUX
- * operating system. INET is implemented using the BSD Socket
- * interface as the means of communication with the user level.
- *
- * Definitions for the AF_INET socket handler.
- *
- * Version: @(#)sock.h 1.0.4 05/13/93
- *
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
- * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- * Corey Minyard <wf-rch!minyard@relay.EU.net>
- * Florian La Roche <flla@stud.uni-sb.de>
- *
- * Fixes:
- * Alan Cox : Volatiles in skbuff pointers. See
- * skbuff comments. May be overdone,
- * better to prove they can be removed
- * than the reverse.
- * Alan Cox : Added a zapped field for tcp to note
- * a socket is reset and must stay shut up
- * Alan Cox : New fields for options
- * Pauline Middelink : identd support
- * Alan Cox : Eliminate low level recv/recvfrom
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#ifndef _SOCK_H
-#define _SOCK_H
-
-#include <linux/timer.h>
-#include <linux/ip.h> /* struct options */
-#include <linux/in.h> /* struct sockaddr_in */
-#include <linux/tcp.h> /* struct tcphdr */
-#include <linux/config.h>
-
-#include <linux/netdevice.h>
-#include <linux/skbuff.h> /* struct sk_buff */
-#include <net/protocol.h> /* struct inet_protocol */
-#ifdef CONFIG_AX25
-#include <net/ax25.h>
-#ifdef CONFIG_NETROM
-#include <net/netrom.h>
-#endif
-#endif
-#ifdef CONFIG_IPX
-#include <net/ipx.h>
-#endif
-#ifdef CONFIG_ATALK
-#include <linux/atalk.h>
-#endif
-
-#include <linux/igmp.h>
-
-/* Think big (also on some systems a byte is faster) */
-#define SOCK_ARRAY_SIZE 256
-
-
-/*
- * The AF_UNIX specific socket options
- */
-
-struct unix_opt
-{
- int family;
- char * name;
- int locks;
- struct inode * inode;
- struct semaphore readsem;
- struct sock * other;
-};
-
-/*
- * IP packet socket options
- */
-
-struct inet_packet_opt
-{
- struct notifier_block notifier; /* Used when bound */
- struct device *bound_dev;
- unsigned long dev_stamp;
- struct packet_type *prot_hook;
- char device_name[15];
-};
-
-
-/*
- * This structure really needs to be cleaned up.
- * Most of it is for TCP, and not used by any of
- * the other protocols.
- */
-struct sock
-{
- struct options *opt;
- volatile unsigned long wmem_alloc;
- volatile unsigned long rmem_alloc;
- unsigned long allocation; /* Allocation mode */
- __u32 write_seq;
- __u32 sent_seq;
- __u32 acked_seq;
- __u32 copied_seq;
- __u32 rcv_ack_seq;
- __u32 window_seq;
- __u32 fin_seq;
- __u32 urg_seq;
- __u32 urg_data;
- int users; /* user count */
- /*
- * Not all are volatile, but some are, so we
- * might as well say they all are.
- */
- volatile char dead,
- urginline,
- intr,
- blog,
- done,
- reuse,
- keepopen,
- linger,
- delay_acks,
- destroy,
- ack_timed,
- no_check,
- zapped, /* In ax25 & ipx means not linked */
- broadcast,
- nonagle,
- bsdism;
- unsigned long lingertime;
- int proc;
- struct sock *next;
- struct sock *prev; /* Doubly linked chain.. */
- struct sock *pair;
- struct sk_buff * volatile send_head;
- struct sk_buff * volatile send_tail;
- struct sk_buff_head back_log;
- struct sk_buff *partial;
- struct timer_list partial_timer;
- long retransmits;
- struct sk_buff_head write_queue,
- receive_queue;
- struct proto *prot;
- struct wait_queue **sleep;
- __u32 daddr;
- __u32 saddr; /* Sending source */
- __u32 rcv_saddr; /* Bound address */
- unsigned short max_unacked;
- unsigned short window;
- __u32 lastwin_seq; /* sequence number when we last updated the window we offer */
- volatile unsigned long ato; /* ack timeout */
- volatile unsigned long lrcvtime; /* jiffies at last rcv */
- unsigned short bytes_rcv;
-/*
- * mss is min(mtu, max_window)
- */
- unsigned short mtu; /* mss negotiated in the syn's */
- volatile unsigned short mss; /* current eff. mss - can change */
- volatile unsigned short user_mss; /* mss requested by user in ioctl */
- volatile unsigned short max_window;
- unsigned long window_clamp;
- unsigned short num;
- volatile unsigned short cong_window;
- volatile unsigned short cong_count;
- volatile unsigned short ssthresh;
- volatile unsigned short packets_out;
- volatile unsigned short shutdown;
- volatile unsigned long rtt;
- volatile unsigned long mdev;
- volatile unsigned long rto;
-
-/*
- * currently backoff isn't used, but I'm maintaining it in case
- * we want to go back to a backoff formula that needs it
- */
-
- volatile unsigned short backoff;
- volatile int err, err_soft; /* Soft holds errors that don't
- cause failure but are the cause
- of a persistent failure not just
- 'timed out' */
- unsigned char protocol;
- volatile unsigned char state;
- volatile unsigned char ack_backlog;
- unsigned char max_ack_backlog;
- unsigned char priority;
- unsigned char debug;
- unsigned short rcvbuf;
- unsigned short sndbuf;
- unsigned short type;
- unsigned char localroute; /* Route locally only */
-#ifdef CONFIG_IPX
-/*
- * Once the IPX ncpd patches are in these are going into protinfo
- */
- ipx_address ipx_dest_addr;
- ipx_interface *ipx_intrfc;
- unsigned short ipx_port;
-
-/* To handle asynchronous messages from the NetWare server, we have to
- * know the connection this socket belongs to. Sorry to blow up this
- * structure even more. */
- struct ncp_server *ipx_ncp_server;
-
-#ifdef CONFIG_IPX_INTERN
- unsigned char ipx_node[IPX_NODE_LEN];
-#endif
- unsigned short ipx_type;
-#endif
-#ifdef CONFIG_AX25
- ax25_cb *ax25;
-#ifdef CONFIG_NETROM
- nr_cb *nr;
-#endif
-#endif
-
-/*
- * This is where all the private (optional) areas that don't
- * overlap will eventually live.
- */
-
- union
- {
- struct unix_opt af_unix;
-#ifdef CONFIG_ATALK
- struct atalk_sock af_at;
-#endif
-#ifdef CONFIG_INET
- struct inet_packet_opt af_packet;
-#endif
- } protinfo;
-
-/*
- * IP 'private area' or will be eventually
- */
- int ip_ttl; /* TTL setting */
- int ip_tos; /* TOS */
- struct tcphdr dummy_th;
- struct timer_list keepalive_timer; /* TCP keepalive hack */
- struct timer_list retransmit_timer; /* TCP retransmit timer */
- struct timer_list ack_timer; /* TCP delayed ack timer */
- int ip_xmit_timeout; /* Why the timeout is running */
- struct rtable *ip_route_cache; /* Cached output route */
- unsigned char ip_hdrincl; /* Include headers ? */
-#ifdef CONFIG_IP_MULTICAST
- int ip_mc_ttl; /* Multicasting TTL */
- int ip_mc_loop; /* Loopback */
- char ip_mc_name[MAX_ADDR_LEN];/* Multicast device name */
- struct ip_mc_socklist *ip_mc_list; /* Group array */
-#endif
-
-/*
- * This part is used for the timeout functions (timer.c).
- */
-
- int timeout; /* What are we waiting for? */
- struct timer_list timer; /* This is the TIME_WAIT/receive timer
- * when we are doing IP
- */
- struct timeval stamp;
-
- /*
- * Identd
- */
-
- struct socket *socket;
-
- /*
- * Callbacks
- */
-
- void (*state_change)(struct sock *sk);
- void (*data_ready)(struct sock *sk,int bytes);
- void (*write_space)(struct sock *sk);
- void (*error_report)(struct sock *sk);
-
-};
-
-/*
- * IP protocol blocks we attach to sockets.
- */
-
-struct proto
-{
- void (*close)(struct sock *sk, unsigned long timeout);
- int (*build_header)(struct sk_buff *skb,
- __u32 saddr,
- __u32 daddr,
- struct device **dev, int type,
- struct options *opt, int len,
- int tos, int ttl, struct rtable ** rp);
- int (*connect)(struct sock *sk,
- struct sockaddr_in *usin, int addr_len);
- struct sock * (*accept) (struct sock *sk, int flags);
- void (*queue_xmit)(struct sock *sk,
- struct device *dev, struct sk_buff *skb,
- int free);
- void (*retransmit)(struct sock *sk, int all);
- void (*write_wakeup)(struct sock *sk);
- void (*read_wakeup)(struct sock *sk);
- int (*rcv)(struct sk_buff *buff, struct device *dev,
- struct options *opt, __u32 daddr,
- unsigned short len, __u32 saddr,
- int redo, struct inet_protocol *protocol);
- int (*select)(struct sock *sk, int which,
- select_table *wait);
- int (*ioctl)(struct sock *sk, int cmd,
- unsigned long arg);
- int (*init)(struct sock *sk);
- void (*shutdown)(struct sock *sk, int how);
- int (*setsockopt)(struct sock *sk, int level, int optname,
- char *optval, int optlen);
- int (*getsockopt)(struct sock *sk, int level, int optname,
- char *optval, int *option);
- int (*sendmsg)(struct sock *sk, struct msghdr *msg, int len,
- int noblock, int flags);
- int (*recvmsg)(struct sock *sk, struct msghdr *msg, int len,
- int noblock, int flags, int *addr_len);
- int (*bind)(struct sock *sk, struct sockaddr *uaddr, int addr_len);
- unsigned short max_header;
- unsigned long retransmits;
- char name[32];
- int inuse, highestinuse;
- struct sock * sock_array[SOCK_ARRAY_SIZE];
-};
-
-#define TIME_WRITE 1
-#define TIME_CLOSE 2
-#define TIME_KEEPOPEN 3
-#define TIME_DESTROY 4
-#define TIME_DONE 5 /* Used to absorb those last few packets */
-#define TIME_PROBE0 6
-/*
- * About 10 seconds
- */
-#define SOCK_DESTROY_TIME (10*HZ)
-
-
-/*
- * Sockets 0-1023 can't be bound too unless you are superuser
- */
-
-#define PROT_SOCK 1024
-
-
-#define SHUTDOWN_MASK 3
-#define RCV_SHUTDOWN 1
-#define SEND_SHUTDOWN 2
-
-/*
- * Used by processes to "lock" a socket state, so that
- * interrupts and bottom half handlers won't change it
- * from under us. It essentially blocks any incoming
- * packets, so that we won't get any new data or any
- * packets that change the state of the socket.
- *
- * Note the 'barrier()' calls: gcc may not move a lock
- * "downwards" or a unlock "upwards" when optimizing.
- */
-extern void __release_sock(struct sock *sk);
-
-static inline void lock_sock(struct sock *sk)
-{
-#if 1
-/* debugging code: the test isn't even 100% correct, but it can catch bugs */
-/* Note that a double lock is ok in theory - it's just _usually_ a bug */
- if (sk->users) {
- __label__ here;
- printk("double lock on socket at %p\n", &&here);
-here:
- }
-#endif
- sk->users++;
- barrier();
-}
-
-static inline void release_sock(struct sock *sk)
-{
- barrier();
-#if 1
-/* debugging code: remove me when ok */
- if (sk->users == 0) {
- __label__ here;
- sk->users = 1;
- printk("trying to unlock unlocked socket at %p\n", &&here);
-here:
- }
-#endif
- if (!--sk->users)
- __release_sock(sk);
-}
-
-
-extern void destroy_sock(struct sock *sk);
-extern unsigned short get_new_socknum(struct proto *,
- unsigned short);
-extern void put_sock(unsigned short, struct sock *);
-extern struct sock *get_sock(struct proto *, unsigned short,
- unsigned long, unsigned short,
- unsigned long);
-extern struct sock *get_sock_mcast(struct sock *, unsigned short,
- unsigned long, unsigned short,
- unsigned long);
-extern struct sock *get_sock_raw(struct sock *, unsigned short,
- unsigned long, unsigned long);
-
-extern struct sk_buff *sock_wmalloc(struct sock *sk,
- unsigned long size, int force,
- int priority);
-extern struct sk_buff *sock_rmalloc(struct sock *sk,
- unsigned long size, int force,
- int priority);
-extern void sock_wfree(struct sock *sk,
- struct sk_buff *skb);
-extern void sock_rfree(struct sock *sk,
- struct sk_buff *skb);
-extern unsigned long sock_rspace(struct sock *sk);
-extern unsigned long sock_wspace(struct sock *sk);
-
-extern int sock_setsockopt(struct sock *sk, int level,
- int op, char *optval,
- int optlen);
-
-extern int sock_getsockopt(struct sock *sk, int level,
- int op, char *optval,
- int *optlen);
-extern struct sk_buff *sock_alloc_send_skb(struct sock *skb,
- unsigned long size,
- unsigned long fallback,
- int noblock,
- int *errcode);
-
-/*
- * Queue a received datagram if it will fit. Stream and sequenced
- * protocols can't normally use this as they need to fit buffers in
- * and play with them.
- *
- * Inlined as its very short and called for pretty much every
- * packet ever received.
- */
-
-extern __inline__ int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
-{
- unsigned long flags;
- if(sk->rmem_alloc + skb->truesize >= sk->rcvbuf)
- return -ENOMEM;
- save_flags(flags);
- cli();
- sk->rmem_alloc+=skb->truesize;
- skb->sk=sk;
- restore_flags(flags);
- skb_queue_tail(&sk->receive_queue,skb);
- if(!sk->dead)
- sk->data_ready(sk,skb->len);
- return 0;
-}
-
-/*
- * Recover an error report and clear atomically
- */
-
-extern __inline__ int sock_error(struct sock *sk)
-{
- int err=xchg(&sk->err,0);
- return -err;
-}
-
-/*
- * Declarations from timer.c
- */
-
-extern struct sock *timer_base;
-
-extern void delete_timer (struct sock *);
-extern void reset_timer (struct sock *, int, unsigned long);
-extern void net_timer (unsigned long);
-
-
-/*
- * Enable debug/info messages
- */
-
-#define NETDEBUG(x) x
-
-#endif /* _SOCK_H */
diff --git a/i386/i386at/gpl/linux/include/net/tcp.h b/i386/i386at/gpl/linux/include/net/tcp.h
deleted file mode 100644
index 3c7eb7de..00000000
--- a/i386/i386at/gpl/linux/include/net/tcp.h
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * INET An implementation of the TCP/IP protocol suite for the LINUX
- * operating system. INET is implemented using the BSD Socket
- * interface as the means of communication with the user level.
- *
- * Definitions for the TCP module.
- *
- * Version: @(#)tcp.h 1.0.5 05/23/93
- *
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
- * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#ifndef _TCP_H
-#define _TCP_H
-
-#include <linux/tcp.h>
-#include <net/checksum.h>
-
-#define MAX_SYN_SIZE 44 + MAX_HEADER + 15
-#define MAX_FIN_SIZE 40 + MAX_HEADER + 15
-#define MAX_ACK_SIZE 40 + MAX_HEADER + 15
-#define MAX_RESET_SIZE 40 + MAX_HEADER + 15
-#define MAX_WINDOW 32767 /* Never offer a window over 32767 without using
- window scaling (not yet supported). Some poor
- stacks do signed 16bit maths! */
-#define MIN_WINDOW 2048
-#define MAX_ACK_BACKLOG 2
-#define MIN_WRITE_SPACE 2048
-#define TCP_WINDOW_DIFF 2048
-
-/* urg_data states */
-#define URG_VALID 0x0100
-#define URG_NOTYET 0x0200
-#define URG_READ 0x0400
-
-#define TCP_RETR1 7 /*
- * This is how many retries it does before it
- * tries to figure out if the gateway is
- * down.
- */
-
-#define TCP_RETR2 15 /*
- * This should take at least
- * 90 minutes to time out.
- */
-
-#define TCP_TIMEOUT_LEN (15*60*HZ) /* should be about 15 mins */
-#define TCP_TIMEWAIT_LEN (60*HZ) /* how long to wait to successfully
- * close the socket, about 60 seconds */
-#define TCP_FIN_TIMEOUT (3*60*HZ) /* BSD style FIN_WAIT2 deadlock breaker */
-#define TCP_ACK_TIME (3*HZ) /* time to delay before sending an ACK */
-#define TCP_DONE_TIME (5*HZ/2)/* maximum time to wait before actually
- * destroying a socket */
-#define TCP_WRITE_TIME (30*HZ) /* initial time to wait for an ACK,
- * after last transmit */
-#define TCP_TIMEOUT_INIT (3*HZ) /* RFC 1122 initial timeout value */
-#define TCP_SYN_RETRIES 10 /* number of times to retry opening a
- * connection (TCP_RETR2-....) */
-#define TCP_PROBEWAIT_LEN (1*HZ)/* time to wait between probes when
- * I've got something to write and
- * there is no window */
-
-#define TCP_NO_CHECK 0 /* turn to one if you want the default
- * to be no checksum */
-
-
-/*
- * TCP option
- */
-
-#define TCPOPT_NOP 1 /* Padding */
-#define TCPOPT_EOL 0 /* End of options */
-#define TCPOPT_MSS 2 /* Segment size negotiating */
-/*
- * We don't use these yet, but they are for PAWS and big windows
- */
-#define TCPOPT_WINDOW 3 /* Window scaling */
-#define TCPOPT_TIMESTAMP 8 /* Better RTT estimations/PAWS */
-
-
-/*
- * The next routines deal with comparing 32 bit unsigned ints
- * and worry about wraparound (automatic with unsigned arithmetic).
- */
-
-extern __inline int before(__u32 seq1, __u32 seq2)
-{
- return (__s32)(seq1-seq2) < 0;
-}
-
-extern __inline int after(__u32 seq1, __u32 seq2)
-{
- return (__s32)(seq2-seq1) < 0;
-}
-
-
-/* is s2<=s1<=s3 ? */
-extern __inline int between(__u32 seq1, __u32 seq2, __u32 seq3)
-{
- return (after(seq1+1, seq2) && before(seq1, seq3+1));
-}
-
-static __inline__ int min(unsigned int a, unsigned int b)
-{
- if (a < b)
- return(a);
- return(b);
-}
-
-extern struct proto tcp_prot;
-extern struct tcp_mib tcp_statistics;
-extern struct wait_queue *master_select_wakeup;
-
-extern void tcp_err(int type, int code, unsigned char *header, __u32 daddr,
- __u32, struct inet_protocol *protocol);
-extern void tcp_shutdown (struct sock *sk, int how);
-extern int tcp_rcv(struct sk_buff *skb, struct device *dev,
- struct options *opt, __u32 daddr,
- unsigned short len, __u32 saddr, int redo,
- struct inet_protocol *protocol);
-
-extern int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg);
-
-extern void tcp_read_wakeup(struct sock *);
-extern void tcp_write_xmit(struct sock *);
-extern void tcp_time_wait(struct sock *);
-extern void tcp_retransmit(struct sock *, int);
-extern void tcp_do_retransmit(struct sock *, int);
-extern void tcp_send_check(struct tcphdr *th, unsigned long saddr,
- unsigned long daddr, int len, struct sk_buff *skb);
-
-/* tcp_output.c */
-
-extern void tcp_send_probe0(struct sock *);
-extern void tcp_send_partial(struct sock *);
-extern void tcp_write_wakeup(struct sock *);
-extern void tcp_send_fin(struct sock *sk);
-extern void tcp_send_synack(struct sock *, struct sock *, struct sk_buff *);
-extern void tcp_send_skb(struct sock *, struct sk_buff *);
-extern void tcp_send_ack(u32, u32, struct sock *sk, struct tcphdr *th, u32);
-extern void tcp_send_reset(unsigned long saddr, unsigned long daddr, struct tcphdr *th,
- struct proto *prot, struct options *opt, struct device *dev, int tos, int ttl);
-
-extern void tcp_enqueue_partial(struct sk_buff *, struct sock *);
-extern struct sk_buff * tcp_dequeue_partial(struct sock *);
-
-/* tcp_input.c */
-extern void tcp_cache_zap(void);
-
-/* tcp_timer.c */
-#define tcp_reset_msl_timer(x,y,z) reset_timer(x,y,z)
-extern void tcp_reset_xmit_timer(struct sock *, int, unsigned long);
-extern void tcp_retransmit_timer(unsigned long);
-
-/*
- * Default sequence number picking algorithm.
- * As close as possible to RFC 793, which
- * suggests using a 250kHz clock.
- * Further reading shows this assumes 2MB/s networks.
- * For 10MB/s ethernet, a 1MHz clock is appropriate.
- * That's funny, Linux has one built in! Use it!
- */
-
-static inline u32 tcp_init_seq(void)
-{
- struct timeval tv;
- do_gettimeofday(&tv);
- return tv.tv_usec+tv.tv_sec*1000000;
-}
-
-/*
- * This function returns the amount that we can raise the
- * usable window based on the following constraints
- *
- * 1. The window can never be shrunk once it is offered (RFC 793)
- * 2. We limit memory per socket
- */
-
-static __inline__ unsigned short tcp_raise_window(struct sock *sk)
-{
- long free_space = sock_rspace(sk);
- long window;
-
- if (free_space > 1024)
- free_space &= ~0x3FF; /* make free space a multiple of 1024 */
-
- if(sk->window_clamp)
- free_space = min(sk->window_clamp, free_space);
-
- /*
- * compute the actual window i.e.
- * old_window - received_bytes_on_that_win
- */
-
- window = sk->window - (sk->acked_seq - sk->lastwin_seq);
-
- if (sk->mss == 0)
- sk->mss = sk->mtu;
-
- if ( window < 0 ) {
- window = 0;
- printk(KERN_DEBUG "TRW: win < 0 w=%d 1=%u 2=%u\n",
- sk->window, sk->acked_seq, sk->lastwin_seq);
- }
-
- if ( (free_space - window) >= min(sk->mss, MAX_WINDOW/2) )
- return ((free_space - window) / sk->mss) * sk->mss;
-
- return 0;
-}
-
-static __inline__ unsigned short tcp_select_window(struct sock *sk)
-{
- long free_space = sock_rspace(sk);
- long window;
-
- if (free_space > 1024)
- free_space &= ~0x3FF; /* make free space a multiple of 1024 */
-
- if (sk->window_clamp)
- free_space = min(sk->window_clamp, free_space);
-
- /*
- * compute the actual window i.e.
- * old_window - received_bytes_on_that_win
- */
-
- if (sk->mss == 0)
- sk->mss = sk->mtu;
-
- window = sk->window - (sk->acked_seq - sk->lastwin_seq);
-
- if ( window < 0 ) {
- window = 0;
- printk(KERN_DEBUG "TSW: win < 0 w=%d 1=%u 2=%u\n",
- sk->window, sk->acked_seq, sk->lastwin_seq);
- }
-
- /*
- * RFC 1122:
- * "the suggested [SWS] avoidance algoritm for the receiver is to keep
- * RECV.NEXT + RCV.WIN fixed until:
- * RCV.BUFF - RCV.USER - RCV.WINDOW >= min(1/2 RCV.BUFF, MSS)"
- *
- * i.e. don't raise the right edge of the window until you can't raise
- * it MSS bytes
- */
-
- if ( (free_space - window) >= min(sk->mss, MAX_WINDOW/2) )
- window += ((free_space - window) / sk->mss) * sk->mss;
-
- sk->window = window;
- sk->lastwin_seq = sk->acked_seq;
-
- return sk->window;
-}
-
-/*
- * List all states of a TCP socket that can be viewed as a "connected"
- * state. This now includes TCP_SYN_RECV, although I am not yet fully
- * convinced that this is the solution for the 'getpeername(2)'
- * problem. Thanks to Stephen A. Wood <saw@cebaf.gov> -FvK
- */
-
-extern __inline const int tcp_connected(const int state)
-{
- return(state == TCP_ESTABLISHED || state == TCP_CLOSE_WAIT ||
- state == TCP_FIN_WAIT1 || state == TCP_FIN_WAIT2 ||
- state == TCP_SYN_RECV);
-}
-
-/*
- * Calculate(/check) TCP checksum
- */
-static __inline__ u16 tcp_check(struct tcphdr *th, int len,
- unsigned long saddr, unsigned long daddr, unsigned long base)
-{
- return csum_tcpudp_magic(saddr,daddr,len,IPPROTO_TCP,base);
-}
-
-#undef STATE_TRACE
-
-#ifdef STATE_TRACE
-static char *statename[]={
- "Unused","Established","Syn Sent","Syn Recv",
- "Fin Wait 1","Fin Wait 2","Time Wait", "Close",
- "Close Wait","Last ACK","Listen","Closing"
-};
-#endif
-
-static __inline__ void tcp_set_state(struct sock *sk, int state)
-{
- int oldstate = sk->state;
-
- sk->state = state;
-
-#ifdef STATE_TRACE
- if(sk->debug)
- printk("TCP sk=%p, State %s -> %s\n",sk, statename[oldstate],statename[state]);
-#endif
-
- switch (state) {
- case TCP_ESTABLISHED:
- if (oldstate != TCP_ESTABLISHED) {
- tcp_statistics.TcpCurrEstab++;
- /* This is a hack but it doesn't occur often and it's going to
- be a real to fix nicely */
- if (oldstate == TCP_SYN_RECV)
- wake_up_interruptible(&master_select_wakeup);
- }
- break;
-
- case TCP_CLOSE:
- tcp_cache_zap();
- /* Should be about 2 rtt's */
- reset_timer(sk, TIME_DONE, min(sk->rtt * 2, TCP_DONE_TIME));
- /* fall through */
- default:
- if (oldstate==TCP_ESTABLISHED)
- tcp_statistics.TcpCurrEstab--;
- }
-}
-
-#endif /* _TCP_H */
diff --git a/i386/i386at/gpl/linux/include/net/udp.h b/i386/i386at/gpl/linux/include/net/udp.h
deleted file mode 100644
index 13735d17..00000000
--- a/i386/i386at/gpl/linux/include/net/udp.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * INET An implementation of the TCP/IP protocol suite for the LINUX
- * operating system. INET is implemented using the BSD Socket
- * interface as the means of communication with the user level.
- *
- * Definitions for the UDP module.
- *
- * Version: @(#)udp.h 1.0.2 05/07/93
- *
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
- * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- *
- * Fixes:
- * Alan Cox : Turned on udp checksums. I don't want to
- * chase 'memory corruption' bugs that aren't!
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#ifndef _UDP_H
-#define _UDP_H
-
-#include <linux/udp.h>
-
-
-#define UDP_NO_CHECK 0
-
-
-extern struct proto udp_prot;
-
-
-extern void udp_err(int type, int code, unsigned char *header, __u32 daddr,
- __u32 saddr, struct inet_protocol *protocol);
-extern void udp_send_check(struct udphdr *uh, __u32 saddr,
- __u32 daddr, int len, struct sock *sk);
-extern int udp_recvfrom(struct sock *sk, unsigned char *to,
- int len, int noblock, unsigned flags,
- struct sockaddr_in *sin, int *addr_len);
-extern int udp_read(struct sock *sk, unsigned char *buff,
- int len, int noblock, unsigned flags);
-extern int udp_connect(struct sock *sk,
- struct sockaddr_in *usin, int addr_len);
-extern int udp_rcv(struct sk_buff *skb, struct device *dev,
- struct options *opt, __u32 daddr,
- unsigned short len, __u32 saddr, int redo,
- struct inet_protocol *protocol);
-extern int udp_ioctl(struct sock *sk, int cmd, unsigned long arg);
-extern void udp_cache_zap(void); /* Remove udp last socket cache */
-
-#endif /* _UDP_H */
diff --git a/i386/i386at/gpl/linux/linux_autoirq.c b/i386/i386at/gpl/linux/linux_autoirq.c
deleted file mode 100644
index 2e3d4e61..00000000
--- a/i386/i386at/gpl/linux/linux_autoirq.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Linux auto-irq support.
- * Copyright (C) 1995 Shantanu Goel.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
- * Written 1994 by Donald Becker.
- *
- * The author may be reached as becker@CESDIS.gsfc.nasa.gov, or C/O
- * Center of Excellence in Space Data and Information Sciences
- * Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
- *
- * This code is a general-purpose IRQ line detector for devices with
- * jumpered IRQ lines. If you can make the device raise an IRQ (and
- * that IRQ line isn't already being used), these routines will tell
- * you what IRQ line it's using -- perfect for those oh-so-cool boot-time
- * device probes!
- *
- * To use this, first call autoirq_setup(timeout). TIMEOUT is how many
- * 'jiffies' (1/100 sec.) to detect other devices that have active IRQ lines,
- * and can usually be zero at boot. 'autoirq_setup()' returns the bit
- * vector of nominally-available IRQ lines (lines may be physically in-use,
- * but not yet registered to a device).
- * Next, set up your device to trigger an interrupt.
- * Finally call autoirq_report(TIMEOUT) to find out which IRQ line was
- * most recently active. The TIMEOUT should usually be zero, but may
- * be set to the number of jiffies to wait for a slow device to raise an IRQ.
- *
- * The idea of using the setup timeout to filter out bogus IRQs came from
- * the serial driver.
- */
-
-#include <i386/pic.h>
-#include <i386/ipl.h>
-
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-
-#include <asm/bitops.h>
-#include <asm/system.h>
-
-/*
- * IRQ to network device map.
- */
-void *irq2dev_map[16];
-
-/*
- * Set of fixed IRQs
- * (fpu, rtc, com1, PIC slave cascade, keyboard, timer).
- */
-int irqs_busy = 0x2147;
-
-static volatile int irq_number; /* latest irq found */
-static volatile int irq_bitmap; /* bitmap of IRQs found */
-static int irq_handled; /* irq lines we have a handler on */
-
-extern unsigned long loops_per_sec;
-
-/*
- * Interrupt handler when probing an IRQ.
- */
-static void
-autoirq_probe(irq)
- int irq;
-{
- /*
- * Mark this IRQ as the last one
- * that interrupted and disable it.
- */
- irq_number = irq;
- set_bit(irq, (void *)&irq_bitmap);
- disable_irq(irq);
-}
-
-/*
- * Set up for auto-irq.
- */
-int
-autoirq_setup(waittime)
- int waittime;
-{
- int i, mask;
- int timeout = jiffies + waittime;
- int boguscount = (waittime * loops_per_sec) / 100;
-
- /*
- * Allocate all possible IRQs.
- */
- irq_handled = 0;
- for (i = 0; i < 16; i++) {
- if (test_bit(i, (void *)&irqs_busy) == 0
- && request_irq(i, autoirq_probe, 0, 0) == 0)
- set_bit(i, (void *)&irq_handled);
- }
-
- irq_number = 0;
- irq_bitmap = 0;
-
- /*
- * Hang out at least <waittime>
- * jiffies waiting for bogus IRQ hits.
- */
- while (timeout > jiffies && --boguscount > 0)
- ;
-
- /*
- * Free IRQs that caused bogus hits.
- */
- for (i = 0, mask = 0x01; i < 16; i++, mask <<= 1) {
- if (irq_bitmap & irq_handled & mask) {
- irq_handled &= ~mask;
- free_irq(i);
- }
- }
-
- return (irq_handled);
-}
-
-/*
- * Return the last IRQ that caused an interrupt.
- */
-int
-autoirq_report(waittime)
- int waittime;
-{
- int i;
- int timeout = jiffies + waittime;
- int boguscount = (waittime * loops_per_sec) / 100;
-
- /*
- * Hang out at least <waittime>
- * jiffies waiting for the IRQ.
- */
- while (timeout > jiffies && --boguscount > 0)
- if (irq_number)
- break;
-
- /*
- * Retract the IRQ handlers that we handled.
- */
- for (i = 0; i < 16; i++) {
- if (test_bit(i, (void *)&irq_handled))
- free_irq(i);
- }
-
- return (irq_number);
-}
diff --git a/i386/i386at/gpl/linux/linux_block.c b/i386/i386at/gpl/linux/linux_block.c
deleted file mode 100644
index 93f1a5cd..00000000
--- a/i386/i386at/gpl/linux/linux_block.c
+++ /dev/null
@@ -1,1625 +0,0 @@
-/*
- * Linux block driver support.
- *
- * Copyright (C) 1996 The University of Utah and the Computer Systems
- * Laboratory at the University of Utah (CSL)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Author: Shantanu Goel, University of Utah CSL
- */
-
-/*
- * linux/drivers/block/ll_rw_blk.c
- *
- * Copyright (C) 1991, 1992 Linus Torvalds
- * Copyright (C) 1994, Karl Keyte: Added support for disk statistics
- */
-
-/*
- * linux/fs/block_dev.c
- *
- * Copyright (C) 1991, 1992 Linus Torvalds
- */
-
-/*
- * linux/fs/buffer.c
- *
- * Copyright (C) 1991, 1992 Linus Torvalds
- */
-
-#include <sys/types.h>
-#include <mach/mach_types.h>
-#include <mach/kern_return.h>
-#include <mach/mig_errors.h>
-#include <mach/port.h>
-#include <mach/vm_param.h>
-#include <mach/notify.h>
-
-#include <ipc/ipc_port.h>
-#include <ipc/ipc_space.h>
-
-#include <vm/vm_map.h>
-#include <vm/vm_kern.h>
-#include <vm/vm_page.h>
-
-#include <device/device_types.h>
-#include <device/device_port.h>
-#include <device/disk_status.h>
-#include "device_reply.h"
-
-#include <i386at/dev_hdr.h>
-#include <i386at/device_emul.h>
-#include <i386at/disk.h>
-
-#include <i386at/gpl/linux/linux_emul.h>
-
-#define MACH_INCLUDE
-#include <linux/fs.h>
-#include <linux/blk.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/fcntl.h>
-#include <linux/major.h>
-#include <linux/kdev_t.h>
-#include <linux/delay.h>
-#include <linux/malloc.h>
-
-/* Location of VTOC in units for sectors (512 bytes). */
-#define PDLOCATION 29
-
-/* Linux kernel variables. */
-
-/* Temporary data allocated on the stack. */
-struct temp_data
-{
- struct inode inode;
- struct file file;
- struct request req;
- queue_head_t pages;
-};
-
-/* One of these exists for each
- driver associated with a major number. */
-struct device_struct
-{
- const char *name; /* device name */
- struct file_operations *fops; /* operations vector */
- int busy:1; /* driver is being opened/closed */
- int want:1; /* someone wants to open/close driver */
- struct gendisk *gd; /* DOS partition information */
- int default_slice; /* what slice to use when none is given */
- struct disklabel **labels; /* disklabels for each DOS partition */
-};
-
-/* An entry in the Mach name to Linux major number conversion table. */
-struct name_map
-{
- const char *name; /* Mach name for device */
- unsigned major; /* Linux major number */
- unsigned unit; /* Linux unit number */
- int read_only; /* 1 if device is read only */
-};
-
-/* Driver operation table. */
-static struct device_struct blkdevs[MAX_BLKDEV];
-
-/* Driver request function table. */
-struct blk_dev_struct blk_dev[MAX_BLKDEV] =
-{
- { NULL, NULL }, /* 0 no_dev */
- { NULL, NULL }, /* 1 dev mem */
- { NULL, NULL }, /* 2 dev fd */
- { NULL, NULL }, /* 3 dev ide0 or hd */
- { NULL, NULL }, /* 4 dev ttyx */
- { NULL, NULL }, /* 5 dev tty */
- { NULL, NULL }, /* 6 dev lp */
- { NULL, NULL }, /* 7 dev pipes */
- { NULL, NULL }, /* 8 dev sd */
- { NULL, NULL }, /* 9 dev st */
- { NULL, NULL }, /* 10 */
- { NULL, NULL }, /* 11 */
- { NULL, NULL }, /* 12 */
- { NULL, NULL }, /* 13 */
- { NULL, NULL }, /* 14 */
- { NULL, NULL }, /* 15 */
- { NULL, NULL }, /* 16 */
- { NULL, NULL }, /* 17 */
- { NULL, NULL }, /* 18 */
- { NULL, NULL }, /* 19 */
- { NULL, NULL }, /* 20 */
- { NULL, NULL }, /* 21 */
- { NULL, NULL } /* 22 dev ide1 */
-};
-
-/*
- * blk_size contains the size of all block-devices in units of 1024 byte
- * sectors:
- *
- * blk_size[MAJOR][MINOR]
- *
- * if (!blk_size[MAJOR]) then no minor size checking is done.
- */
-int *blk_size[MAX_BLKDEV] = { NULL, NULL, };
-
-/*
- * blksize_size contains the size of all block-devices:
- *
- * blksize_size[MAJOR][MINOR]
- *
- * if (!blksize_size[MAJOR]) then 1024 bytes is assumed.
- */
-int *blksize_size[MAX_BLKDEV] = { NULL, NULL, };
-
-/*
- * hardsect_size contains the size of the hardware sector of a device.
- *
- * hardsect_size[MAJOR][MINOR]
- *
- * if (!hardsect_size[MAJOR])
- * then 512 bytes is assumed.
- * else
- * sector_size is hardsect_size[MAJOR][MINOR]
- * This is currently set by some scsi device and read by the msdos fs driver
- * This might be a some uses later.
- */
-int *hardsect_size[MAX_BLKDEV] = { NULL, NULL, };
-
-/* This specifies how many sectors to read ahead on the disk.
- This is unused in Mach. It is here to make drivers compile. */
-int read_ahead[MAX_BLKDEV] = {0, };
-
-/* Use to wait on when there are no free requests.
- This is unused in Mach. It is here to make drivers compile. */
-struct wait_queue *wait_for_request = NULL;
-
-/* Map for allocating device memory. */
-extern vm_map_t device_io_map;
-
-/* Initialize block drivers. */
-void
-blk_dev_init ()
-{
-#ifdef CONFIG_BLK_DEV_IDE
- ide_init ();
-#endif
-#ifdef CONFIG_BLK_DEV_FD
- floppy_init ();
-#endif
-}
-
-/* Return 1 if major number MAJOR corresponds to a disk device. */
-static inline int
-disk_major (int major)
-{
- return (major == IDE0_MAJOR
- || major == IDE1_MAJOR
- || major == IDE2_MAJOR
- || major == IDE3_MAJOR
- || major == SCSI_DISK_MAJOR);
-}
-
-/* Linux kernel block support routines. */
-
-/* Register a driver for major number MAJOR,
- with name NAME, and operations vector FOPS. */
-int
-register_blkdev (unsigned major, const char *name,
- struct file_operations *fops)
-{
- int err = 0;
-
- if (major == 0)
- {
- for (major = MAX_BLKDEV - 1; major > 0; major--)
- if (blkdevs[major].fops == NULL)
- goto out;
- return -LINUX_EBUSY;
- }
- if (major >= MAX_BLKDEV)
- return -LINUX_EINVAL;
- if (blkdevs[major].fops && blkdevs[major].fops != fops)
- return -LINUX_EBUSY;
-
-out:
- blkdevs[major].name = name;
- blkdevs[major].fops = fops;
- blkdevs[major].busy = 0;
- blkdevs[major].want = 0;
- blkdevs[major].gd = NULL;
- blkdevs[major].default_slice = 0;
- blkdevs[major].labels = NULL;
- return 0;
-}
-
-/* Unregister the driver associated with
- major number MAJOR and having the name NAME. */
-int
-unregister_blkdev (unsigned major, const char *name)
-{
- int err;
-
- if (major >= MAX_BLKDEV)
- return -LINUX_EINVAL;
- if (! blkdevs[major].fops || strcmp (blkdevs[major].name, name))
- return -LINUX_EINVAL;
- blkdevs[major].fops = NULL;
- if (blkdevs[major].labels)
- {
- assert (blkdevs[major].gd);
- kfree ((vm_offset_t) blkdevs[major].labels,
- (sizeof (struct disklabel *)
- * blkdevs[major].gd->max_p * blkdevs[major].gd->max_nr));
- }
- return 0;
-}
-
-/* Allocate a buffer SIZE bytes long. */
-static void *
-alloc_buffer (int size)
-{
- vm_page_t m;
- struct temp_data *d;
-
- assert (size <= PAGE_SIZE);
-
- if (! linux_auto_config)
- {
- while ((m = vm_page_grab ()) == 0)
- VM_PAGE_WAIT (0);
- d = current_thread ()->pcb->data;
- assert (d);
- queue_enter (&d->pages, m, vm_page_t, pageq);
- return (void *) m->phys_addr;
- }
- return (void *) __get_free_pages (GFP_KERNEL, 0, ~0UL);
-}
-
-/* Free buffer P which is SIZE bytes long. */
-static void
-free_buffer (void *p, int size)
-{
- int i;
- struct temp_data *d;
- vm_page_t m;
-
- assert (size <= PAGE_SIZE);
-
- if (! linux_auto_config)
- {
- d = current_thread ()->pcb->data;
- assert (d);
- queue_iterate (&d->pages, m, vm_page_t, pageq)
- {
- if (m->phys_addr == (vm_offset_t) p)
- {
- queue_remove (&d->pages, m, vm_page_t, pageq);
- vm_page_lock_queues ();
- vm_page_free (m);
- vm_page_lock_queues ();
- return;
- }
- }
- panic ("free_buffer");
- }
- free_pages ((unsigned long) p, 0);
-}
-
-/* Allocate a buffer of SIZE bytes and
- associate it with block number BLOCK of device DEV. */
-struct buffer_head *
-getblk (kdev_t dev, int block, int size)
-{
- struct buffer_head *bh;
- static struct buffer_head bhead;
-
- assert (size <= PAGE_SIZE);
-
- if (! linux_auto_config)
- bh = (struct buffer_head *) kalloc (sizeof (struct buffer_head));
- else
- bh = &bhead;
- if (bh)
- {
- memset (bh, 0, sizeof (struct buffer_head));
- bh->b_data = alloc_buffer (size);
- if (! bh->b_data)
- {
- if (! linux_auto_config)
- kfree ((vm_offset_t) bh, sizeof (struct buffer_head));
- return NULL;
- }
- bh->b_dev = dev;
- bh->b_size = size;
- bh->b_state = 1 << BH_Lock;
- bh->b_blocknr = block;
- }
- return bh;
-}
-
-/* Release buffer BH previously allocated by getblk. */
-void
-__brelse (struct buffer_head *bh)
-{
- free_buffer (bh->b_data, bh->b_size);
- if (! linux_auto_config)
- kfree ((vm_offset_t) bh, sizeof (*bh));
-}
-
-/* Allocate a buffer of SIZE bytes and fill it with data
- from device DEV starting at block number BLOCK. */
-struct buffer_head *
-bread (kdev_t dev, int block, int size)
-{
- int err;
- struct buffer_head *bh;
-
- bh = getblk (dev, block, size);
- if (bh)
- {
- ll_rw_block (READ, 1, &bh);
- wait_on_buffer (bh);
- if (! buffer_uptodate (bh))
- {
- __brelse (bh);
- return NULL;
- }
- }
- return bh;
-}
-
-/* Return the block size for device DEV in *BSIZE and
- log2(block size) in *BSHIFT. */
-static void
-get_block_size (kdev_t dev, int *bsize, int *bshift)
-{
- int i;
-
- *bsize = BLOCK_SIZE;
- if (blksize_size[MAJOR (dev)]
- && blksize_size[MAJOR (dev)][MINOR (dev)])
- *bsize = blksize_size[MAJOR (dev)][MINOR (dev)];
- for (i = *bsize, *bshift = 0; i != 1; i >>= 1, (*bshift)++)
- ;
-}
-
-/* Enqueue request REQ on a driver's queue. */
-static inline void
-enqueue_request (struct request *req)
-{
- struct request *tmp;
- struct blk_dev_struct *dev;
-
- dev = blk_dev + MAJOR (req->rq_dev);
- cli ();
- tmp = dev->current_request;
- if (! tmp)
- {
- dev->current_request = req;
- (*dev->request_fn) ();
- sti ();
- return;
- }
- while (tmp->next)
- {
- if ((IN_ORDER (tmp, req) || ! IN_ORDER (tmp, tmp->next))
- && IN_ORDER (req, tmp->next))
- break;
- tmp = tmp->next;
- }
- req->next = tmp->next;
- tmp->next = req;
- if (scsi_major (MAJOR (req->rq_dev)))
- (*dev->request_fn) ();
- sti ();
-}
-
-/* Perform the I/O operation RW on the buffer list BH
- containing NR buffers. */
-void
-ll_rw_block (int rw, int nr, struct buffer_head **bh)
-{
- int i, bshift, bsize;
- unsigned major;
- struct request *r;
- static struct request req;
-
- major = MAJOR (bh[0]->b_dev);
- assert (major < MAX_BLKDEV);
-
- get_block_size (bh[0]->b_dev, &bsize, &bshift);
-
- if (! linux_auto_config)
- {
- assert (current_thread ()->pcb->data);
- r = &((struct temp_data *) current_thread ()->pcb->data)->req;
- }
- else
- r = &req;
-
- for (i = 0, r->nr_sectors = 0; i < nr - 1; i++)
- {
- r->nr_sectors += bh[i]->b_size >> 9;
- bh[i]->b_reqnext = bh[i + 1];
- }
- r->nr_sectors += bh[i]->b_size >> 9;
- bh[i]->b_reqnext = NULL;
-
- r->rq_status = RQ_ACTIVE;
- r->rq_dev = bh[0]->b_dev;
- r->cmd = rw;
- r->errors = 0;
- r->sector = bh[0]->b_blocknr << (bshift - 9);
- r->current_nr_sectors = bh[0]->b_size >> 9;
- r->buffer = bh[0]->b_data;
- r->bh = bh[0];
- r->bhtail = bh[nr - 1];
- r->sem = NULL;
- r->next = NULL;
-
- enqueue_request (r);
-}
-
-#define BSIZE (1 << bshift)
-#define BMASK (BSIZE - 1)
-
-/* Perform read/write operation RW on device DEV
- starting at *off to/from buffer *BUF of size *RESID.
- The device block size is given by BSHIFT. *OFF and
- *RESID may be non-multiples of the block size.
- *OFF, *BUF and *RESID are updated if the operation
- completed successfully. */
-static int
-rdwr_partial (int rw, kdev_t dev, loff_t *off,
- char **buf, int *resid, int bshift)
-{
- int c, err = 0, o;
- long sect, nsect;
- struct buffer_head bhead, *bh = &bhead;
- struct gendisk *gd;
-
- memset (bh, 0, sizeof (struct buffer_head));
- bh->b_state = 1 << BH_Lock;
- bh->b_dev = dev;
- bh->b_blocknr = *off >> bshift;
- bh->b_size = BSIZE;
-
- /* Check if this device has non even number of blocks. */
- for (gd = gendisk_head, nsect = -1; gd; gd = gd->next)
- if (gd->major == MAJOR (dev))
- {
- nsect = gd->part[MINOR (dev)].nr_sects;
- break;
- }
- if (nsect > 0)
- {
- sect = bh->b_blocknr << (bshift - 9);
- assert ((nsect - sect) > 0);
- if (nsect - sect < (BSIZE >> 9))
- bh->b_size = (nsect - sect) << 9;
- }
- bh->b_data = alloc_buffer (bh->b_size);
- if (! bh->b_data)
- return -LINUX_ENOMEM;
- ll_rw_block (READ, 1, &bh);
- wait_on_buffer (bh);
- if (buffer_uptodate (bh))
- {
- o = *off & BMASK;
- c = bh->b_size - o;
- assert (*resid <= c);
- if (c > *resid)
- c = *resid;
- if (rw == READ)
- memcpy (*buf, bh->b_data + o, c);
- else
- {
- memcpy (bh->b_data + o, *buf, c);
- bh->b_state = (1 << BH_Dirty) | (1 << BH_Lock);
- ll_rw_block (WRITE, 1, &bh);
- wait_on_buffer (bh);
- if (! buffer_uptodate (bh))
- {
- err = -LINUX_EIO;
- goto out;
- }
- }
- *buf += c;
- *resid -= c;
- *off += c;
- }
- else
- err = -LINUX_EIO;
-out:
- free_buffer (bh->b_data, bh->b_size);
- return err;
-}
-
-#define BH_Bounce 16
-#define MAX_BUF VM_MAP_COPY_PAGE_LIST_MAX
-
-/* Perform read/write operation RW on device DEV
- starting at *off to/from buffer *BUF of size *RESID.
- The device block size is given by BSHIFT. *OFF and
- *RESID must be multiples of the block size.
- *OFF, *BUF and *RESID are updated if the operation
- completed successfully. */
-static int
-rdwr_full (int rw, kdev_t dev, loff_t *off, char **buf, int *resid, int bshift)
-{
- int cc, err = 0, i, j, nb, nbuf;
- long blk;
- struct buffer_head bhead[MAX_BUF], *bh, *bhp[MAX_BUF];
-
- assert ((*off & BMASK) == 0);
- assert (*resid >= bsize);
-
- nbuf = *resid >> bshift;
- blk = *off >> bshift;
- for (i = nb = 0, bh = bhead; nb < nbuf; bh++)
- {
- memset (bh, 0, sizeof (*bh));
- bh->b_dev = dev;
- bh->b_blocknr = blk;
- set_bit (BH_Lock, &bh->b_state);
- if (rw == WRITE)
- set_bit (BH_Dirty, &bh->b_state);
- cc = PAGE_SIZE - (((int) *buf) & PAGE_MASK);
- if (cc >= BSIZE && ((int) *buf & 511) == 0)
- cc &= ~BMASK;
- else
- {
- cc = PAGE_SIZE;
- set_bit (BH_Bounce, &bh->b_state);
- }
- if (cc > ((nbuf - nb) << bshift))
- cc = (nbuf - nb) << bshift;
- if (! test_bit (BH_Bounce, &bh->b_state))
- bh->b_data = (char *) pmap_extract (vm_map_pmap (device_io_map),
- (((vm_offset_t) *buf)
- + (nb << bshift)));
- else
- {
- bh->b_data = alloc_buffer (cc);
- if (! bh->b_data)
- {
- err = -LINUX_ENOMEM;
- break;
- }
- if (rw == WRITE)
- memcpy (bh->b_data, *buf + (nb << bshift), cc);
- }
- bh->b_size = cc;
- bhp[i] = bh;
- nb += cc >> bshift;
- blk += nb;
- if (++i == MAX_BUF)
- break;
- }
- if (! err)
- {
- ll_rw_block (rw, i, bhp);
- wait_on_buffer (bhp[i - 1]);
- }
- for (bh = bhead, cc = 0, j = 0; j < i; cc += bh->b_size, bh++, j++)
- {
- if (! err && buffer_uptodate (bh)
- && rw == READ && test_bit (BH_Bounce, &bh->b_state))
- memcpy (*buf + cc, bh->b_data, bh->b_size);
- else if (! err && ! buffer_uptodate (bh))
- err = -LINUX_EIO;
- if (test_bit (BH_Bounce, &bh->b_state))
- free_buffer (bh->b_data, bh->b_size);
- }
- if (! err)
- {
- *buf += cc;
- *resid -= cc;
- *off += cc;
- }
- return err;
-}
-
-/* Perform read/write operation RW on device DEV
- starting at *off to/from buffer BUF of size COUNT.
- *OFF is updated if the operation completed successfully. */
-static int
-do_rdwr (int rw, kdev_t dev, loff_t *off, char *buf, int count)
-{
- int bsize, bshift, err = 0, resid = count;
-
- get_block_size (dev, &bsize, &bshift);
- if (*off & BMASK)
- err = rdwr_partial (rw, dev, off, &buf, &resid, bshift);
- while (resid >= bsize && ! err)
- err = rdwr_full (rw, dev, off, &buf, &resid, bshift);
- if (! err && resid)
- err = rdwr_partial (rw, dev, off, &buf, &resid, bshift);
- return err ? err : count - resid;
-}
-
-int
-block_write (struct inode *inode, struct file *filp,
- const char *buf, int count)
-{
- return do_rdwr (WRITE, inode->i_rdev, &filp->f_pos, (char *) buf, count);
-}
-
-int
-block_read (struct inode *inode, struct file *filp, char *buf, int count)
-{
- return do_rdwr (READ, inode->i_rdev, &filp->f_pos, buf, count);
-}
-
-/*
- * This routine checks whether a removable media has been changed,
- * and invalidates all buffer-cache-entries in that case. This
- * is a relatively slow routine, so we have to try to minimize using
- * it. Thus it is called only upon a 'mount' or 'open'. This
- * is the best way of combining speed and utility, I think.
- * People changing diskettes in the middle of an operation deserve
- * to loose :-)
- */
-int
-check_disk_change (kdev_t dev)
-{
- unsigned i;
- struct file_operations * fops;
-
- i = MAJOR(dev);
- if (i >= MAX_BLKDEV || (fops = blkdevs[i].fops) == NULL)
- return 0;
- if (fops->check_media_change == NULL)
- return 0;
- if (! (*fops->check_media_change) (dev))
- return 0;
-
- /* printf ("Disk change detected on device %s\n", kdevname(dev));*/
-
- if (fops->revalidate)
- (*fops->revalidate) (dev);
-
- return 1;
-}
-
-/* Mach device interface routines. */
-
-/* Mach name to Linux major/minor number mapping table. */
-static struct name_map name_to_major[] =
-{
- /* IDE disks */
- { "hd0", IDE0_MAJOR, 0, 0 },
- { "hd1", IDE0_MAJOR, 1, 0 },
- { "hd2", IDE1_MAJOR, 0, 0 },
- { "hd3", IDE1_MAJOR, 1, 0 },
- { "hd4", IDE2_MAJOR, 0, 0 },
- { "hd5", IDE2_MAJOR, 1, 0 },
- { "hd6", IDE3_MAJOR, 0, 0 },
- { "hd7", IDE3_MAJOR, 1, 0 },
-
- /* IDE CDROMs */
- { "wcd0", IDE0_MAJOR, 0, 1 },
- { "wcd1", IDE0_MAJOR, 1, 1 },
- { "wcd2", IDE1_MAJOR, 0, 1 },
- { "wcd3", IDE1_MAJOR, 1, 1 },
- { "wcd4", IDE2_MAJOR, 0, 1 },
- { "wcd5", IDE2_MAJOR, 1, 1 },
- { "wcd6", IDE3_MAJOR, 0, 1 },
- { "wcd7", IDE3_MAJOR, 1, 1 },
-
- /* SCSI disks */
- { "sd0", SCSI_DISK_MAJOR, 0, 0 },
- { "sd1", SCSI_DISK_MAJOR, 1, 0 },
- { "sd2", SCSI_DISK_MAJOR, 2, 0 },
- { "sd3", SCSI_DISK_MAJOR, 3, 0 },
- { "sd4", SCSI_DISK_MAJOR, 4, 0 },
- { "sd5", SCSI_DISK_MAJOR, 5, 0 },
- { "sd6", SCSI_DISK_MAJOR, 6, 0 },
- { "sd7", SCSI_DISK_MAJOR, 7, 0 },
-
- /* SCSI CDROMs */
- { "cd0", SCSI_CDROM_MAJOR, 0, 1 },
- { "cd1", SCSI_CDROM_MAJOR, 1, 1 },
-
- /* Floppy disks */
- { "fd0", FLOPPY_MAJOR, 0, 0 },
- { "fd1", FLOPPY_MAJOR, 1, 0 },
-};
-
-#define NUM_NAMES (sizeof (name_to_major) / sizeof (name_to_major[0]))
-
-/* One of these is associated with each open instance of a device. */
-struct block_data
-{
- const char *name; /* Mach name for device */
- int want:1; /* someone is waiting for I/O to complete */
- int open_count; /* number of opens */
- int iocount; /* number of pending I/O operations */
- int part; /* BSD partition number (-1 if none) */
- int flags; /* Linux file flags */
- int mode; /* Linux file mode */
- kdev_t dev; /* Linux device number */
- ipc_port_t port; /* port representing device */
- struct device_struct *ds; /* driver operation table entry */
- struct device device; /* generic device header */
- struct name_map *np; /* name to inode map */
- struct block_data *next; /* forward link */
-};
-
-/* List of open devices. */
-static struct block_data *open_list;
-
-/* Forward declarations. */
-
-extern struct device_emulation_ops linux_block_emulation_ops;
-
-static io_return_t device_close (void *);
-
-/* Return a send right for block device BD. */
-static ipc_port_t
-dev_to_port (void *bd)
-{
- return (bd
- ? ipc_port_make_send (((struct block_data *) bd)->port)
- : IP_NULL);
-}
-
-/* Return 1 if C is a letter of the alphabet. */
-static inline int
-isalpha (int c)
-{
- return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
-}
-
-/* Return 1 if C is a digit. */
-static inline int
-isdigit (int c)
-{
- return c >= '0' && c <= '9';
-}
-
-/* Find the name map entry for device NAME.
- Set *SLICE to be the DOS partition and
- *PART the BSD/Mach partition, if any. */
-static struct name_map *
-find_name (char *name, int *slice, int *part)
-{
- char *p, *q;
- int i, len;
- struct name_map *np;
-
- /* Parse name into name, unit, DOS partition (slice) and partition. */
- for (*slice = 0, *part = -1, p = name; isalpha (*p); p++)
- ;
- if (p == name || ! isdigit (*p))
- return NULL;
- do
- p++;
- while (isdigit (*p));
- if (*p)
- {
- q = p;
- if (*q == 's' && isdigit (*(q + 1)))
- {
- q++;
- do
- *slice = *slice * 10 + *q++ - '0';
- while (isdigit (*q));
- if (! *q)
- goto find_major;
- }
- if (! isalpha (*q) || *(q + 1))
- return NULL;
- *part = *q - 'a';
- }
-
-find_major:
- /* Convert name to major number. */
- for (i = 0, np = name_to_major; i < NUM_NAMES; i++, np++)
- {
- len = strlen (np->name);
- if (len == (p - name) && ! strncmp (np->name, name, len))
- return np;
- }
- return NULL;
-}
-
-/* Attempt to read a BSD disklabel from device DEV. */
-static struct disklabel *
-read_bsd_label (kdev_t dev)
-{
- int bsize, bshift;
- struct buffer_head *bh;
- struct disklabel *dlp, *lp = NULL;
-
- get_block_size (dev, &bsize, &bshift);
- bh = bread (dev, LBLLOC >> (bshift - 9), bsize);
- if (bh)
- {
- dlp = (struct disklabel *) (bh->b_data + ((LBLLOC << 9) & (bsize - 1)));
- if (dlp->d_magic == DISKMAGIC && dlp->d_magic2 == DISKMAGIC)
- {
- lp = (struct disklabel *) kalloc (sizeof (*lp));
- assert (lp);
- memcpy (lp, dlp, sizeof (*lp));
- }
- __brelse (bh);
- }
- return lp;
-}
-
-/* Attempt to read a VTOC from device DEV. */
-static struct disklabel *
-read_vtoc (kdev_t dev)
-{
- int bshift, bsize, i;
- struct buffer_head *bh;
- struct evtoc *evp;
- struct disklabel *lp = NULL;
-
- get_block_size (dev, &bsize, &bshift);
- bh = bread (dev, PDLOCATION >> (bshift - 9), bsize);
- if (bh)
- {
- evp = (struct evtoc *) (bh->b_data + ((PDLOCATION << 9) & (bsize - 1)));
- if (evp->sanity == VTOC_SANE)
- {
- lp = (struct disklabel *) kalloc (sizeof (*lp));
- assert (lp);
- lp->d_npartitions = evp->nparts;
- if (lp->d_npartitions > MAXPARTITIONS)
- lp->d_npartitions = MAXPARTITIONS;
- for (i = 0; i < lp->d_npartitions; i++)
- {
- lp->d_partitions[i].p_size = evp->part[i].p_size;
- lp->d_partitions[i].p_offset = evp->part[i].p_start;
- lp->d_partitions[i].p_fstype = FS_BSDFFS;
- }
- }
- __brelse (bh);
- }
- return lp;
-}
-
-/* Initialize BSD/Mach partition table for device
- specified by NP, DS and *DEV. Check SLICE and *PART for validity. */
-static kern_return_t
-init_partition (struct name_map *np, kdev_t *dev,
- struct device_struct *ds, int slice, int *part)
-{
- int err, i, j;
- struct disklabel *lp;
- struct gendisk *gd = ds->gd;
- struct partition *p;
- struct temp_data *d = current_thread ()->pcb->data;
-
- if (! gd)
- {
- *part = -1;
- return 0;
- }
- if (ds->labels)
- goto check;
- ds->labels = (struct disklabel **) kalloc (sizeof (struct disklabel *)
- * gd->max_nr * gd->max_p);
- if (! ds->labels)
- return D_NO_MEMORY;
- memset ((void *) ds->labels, 0,
- sizeof (struct disklabel *) * gd->max_nr * gd->max_p);
- for (i = 1; i < gd->max_p; i++)
- {
- d->inode.i_rdev = *dev | i;
- if (gd->part[MINOR (d->inode.i_rdev)].nr_sects <= 0
- || gd->part[MINOR (d->inode.i_rdev)].start_sect < 0)
- continue;
- linux_intr_pri = SPL5;
- d->file.f_flags = 0;
- d->file.f_mode = O_RDONLY;
- if (ds->fops->open && (*ds->fops->open) (&d->inode, &d->file))
- continue;
- lp = read_bsd_label (d->inode.i_rdev);
- if (! lp)
- lp = read_vtoc (d->inode.i_rdev);
- if (ds->fops->release)
- (*ds->fops->release) (&d->inode, &d->file);
- if (lp)
- {
- if (ds->default_slice == 0)
- ds->default_slice = i;
- for (j = 0, p = lp->d_partitions; j < lp->d_npartitions; j++, p++)
- {
- if (p->p_offset < 0 || p->p_size <= 0)
- continue;
-
- /* Sanity check. */
- if (p->p_size > gd->part[MINOR (d->inode.i_rdev)].nr_sects)
- p->p_size = gd->part[MINOR (d->inode.i_rdev)].nr_sects;
- }
- }
- ds->labels[MINOR (d->inode.i_rdev)] = lp;
- }
-
-check:
- if (*part >= 0 && slice == 0)
- slice = ds->default_slice;
- if (*part >= 0 && slice == 0)
- return D_NO_SUCH_DEVICE;
- *dev = MKDEV (MAJOR (*dev), MINOR (*dev) | slice);
- if (slice >= gd->max_p
- || gd->part[MINOR (*dev)].start_sect < 0
- || gd->part[MINOR (*dev)].nr_sects <= 0)
- return D_NO_SUCH_DEVICE;
- if (*part >= 0)
- {
- lp = ds->labels[MINOR (*dev)];
- if (! lp
- || *part >= lp->d_npartitions
- || lp->d_partitions[*part].p_offset < 0
- || lp->d_partitions[*part].p_size <= 0)
- return D_NO_SUCH_DEVICE;
- }
- return 0;
-}
-
-#define DECL_DATA struct temp_data td
-#define INIT_DATA() \
-{ \
- queue_init (&td.pages); \
- td.inode.i_rdev = bd->dev; \
- td.file.f_mode = bd->mode; \
- td.file.f_flags = bd->flags; \
- current_thread ()->pcb->data = &td; \
-}
-
-static io_return_t
-device_open (ipc_port_t reply_port, mach_msg_type_name_t reply_port_type,
- dev_mode_t mode, char *name, device_t *devp)
-{
- int part, slice, err;
- unsigned major, minor;
- kdev_t dev;
- ipc_port_t notify;
- struct block_data *bd = NULL, *bdp;
- struct device_struct *ds;
- struct gendisk *gd;
- struct name_map *np;
- DECL_DATA;
-
- np = find_name (name, &slice, &part);
- if (! np)
- return D_NO_SUCH_DEVICE;
- major = np->major;
- ds = &blkdevs[major];
-
- /* Check that driver exists. */
- if (! ds->fops)
- return D_NO_SUCH_DEVICE;
-
- /* Wait for any other open/close calls to finish. */
- ds = &blkdevs[major];
- while (ds->busy)
- {
- ds->want = 1;
- assert_wait ((event_t) ds, FALSE);
- thread_block (0);
- }
- ds->busy = 1;
-
- /* Compute minor number. */
- if (! ds->gd)
- {
- for (gd = gendisk_head; gd && gd->major != major; gd = gd->next)
- ;
- ds->gd = gd;
- }
- minor = np->unit;
- gd = ds->gd;
- if (gd)
- minor <<= gd->minor_shift;
- dev = MKDEV (major, minor);
-
- queue_init (&td.pages);
- current_thread ()->pcb->data = &td;
-
- /* Check partition. */
- err = init_partition (np, &dev, ds, slice, &part);
- if (err)
- goto out;
-
- /* Initialize file structure. */
- switch (mode & (D_READ|D_WRITE))
- {
- case D_WRITE:
- td.file.f_mode = O_WRONLY;
- break;
-
- case D_READ|D_WRITE:
- td.file.f_mode = O_RDWR;
- break;
-
- default:
- td.file.f_mode = O_RDONLY;
- break;
- }
- td.file.f_flags = (mode & D_NODELAY) ? O_NDELAY : 0;
-
- /* Check if the device is currently open. */
- for (bdp = open_list; bdp; bdp = bdp->next)
- if (bdp->dev == dev
- && bdp->part == part
- && bdp->mode == td.file.f_mode
- && bdp->flags == td.file.f_flags)
- {
- bd = bdp;
- goto out;
- }
-
- /* Open the device. */
- if (ds->fops->open)
- {
- td.inode.i_rdev = dev;
- linux_intr_pri = SPL5;
- err = (*ds->fops->open) (&td.inode, &td.file);
- if (err)
- {
- err = linux_to_mach_error (err);
- goto out;
- }
- }
-
- /* Allocate and initialize device data. */
- bd = (struct block_data *) kalloc (sizeof (struct block_data));
- if (! bd)
- {
- err = D_NO_MEMORY;
- goto bad;
- }
- bd->want = 0;
- bd->open_count = 0;
- bd->iocount = 0;
- bd->part = part;
- bd->ds = ds;
- bd->device.emul_data = bd;
- bd->device.emul_ops = &linux_block_emulation_ops;
- bd->dev = dev;
- bd->mode = td.file.f_mode;
- bd->flags = td.file.f_flags;
- bd->port = ipc_port_alloc_kernel ();
- if (bd->port == IP_NULL)
- {
- err = KERN_RESOURCE_SHORTAGE;
- goto bad;
- }
- ipc_kobject_set (bd->port, (ipc_kobject_t) &bd->device, IKOT_DEVICE);
- notify = ipc_port_make_sonce (bd->port);
- ip_lock (bd->port);
- ipc_port_nsrequest (bd->port, 1, notify, &notify);
- assert (notify == IP_NULL);
- goto out;
-
-bad:
- if (ds->fops->release)
- (*ds->fops->release) (&td.inode, &td.file);
-
-out:
- ds->busy = 0;
- if (ds->want)
- {
- ds->want = 0;
- thread_wakeup ((event_t) ds);
- }
-
- if (bd && bd->open_count > 0)
- {
- if (err)
- *devp = NULL;
- else
- {
- *devp = &bd->device;
- bd->open_count++;
- }
- return err;
- }
-
- if (err)
- {
- if (bd)
- {
- if (bd->port != IP_NULL)
- {
- ipc_kobject_set (bd->port, IKO_NULL, IKOT_NONE);
- ipc_port_dealloc_kernel (bd->port);
- }
- kfree ((vm_offset_t) bd, sizeof (struct block_data));
- bd = NULL;
- }
- }
- else
- {
- bd->open_count = 1;
- bd->next = open_list;
- open_list = bd;
- }
-
- if (IP_VALID (reply_port))
- ds_device_open_reply (reply_port, reply_port_type, err, dev_to_port (bd));
- else if (! err)
- device_close (bd);
-
- return MIG_NO_REPLY;
-}
-
-static io_return_t
-device_close (void *d)
-{
- struct block_data *bd = d, *bdp, **prev;
- struct device_struct *ds = bd->ds;
- DECL_DATA;
-
- INIT_DATA ();
-
- /* Wait for any other open/close to complete. */
- while (ds->busy)
- {
- ds->want = 1;
- assert_wait ((event_t) ds, FALSE);
- thread_block (0);
- }
- ds->busy = 1;
-
- if (--bd->open_count == 0)
- {
- /* Wait for pending I/O to complete. */
- while (bd->iocount > 0)
- {
- bd->want = 1;
- assert_wait ((event_t) bd, FALSE);
- thread_block (0);
- }
-
- /* Remove device from open list. */
- prev = &open_list;
- bdp = open_list;
- while (bdp)
- {
- if (bdp == bd)
- {
- *prev = bdp->next;
- break;
- }
- prev = &bdp->next;
- bdp = bdp->next;
- }
-
- assert (bdp == bd);
-
- if (ds->fops->release)
- (*ds->fops->release) (&td.inode, &td.file);
-
- ipc_kobject_set (bd->port, IKO_NULL, IKOT_NONE);
- ipc_port_dealloc_kernel (bd->port);
- kfree ((vm_offset_t) bd, sizeof (struct block_data));
- }
-
- ds->busy = 0;
- if (ds->want)
- {
- ds->want = 0;
- thread_wakeup ((event_t) ds);
- }
- return D_SUCCESS;
-}
-
-#define MAX_COPY (VM_MAP_COPY_PAGE_LIST_MAX << PAGE_SHIFT)
-
-/* Check block BN and size COUNT for I/O validity
- to from device BD. Set *OFF to the byte offset
- where I/O is to begin and return the size of transfer. */
-static int
-check_limit (struct block_data *bd, loff_t *off, long bn, int count)
-{
- int major, minor;
- long maxsz, sz;
- struct disklabel *lp = NULL;
-
- if (count <= 0)
- return count;
-
- major = MAJOR (bd->dev);
- minor = MINOR (bd->dev);
-
- if (bd->ds->gd)
- {
- if (bd->part >= 0)
- {
- assert (bd->ds->labels);
- assert (bd->ds->labels[minor]);
- lp = bd->ds->labels[minor];
- maxsz = lp->d_partitions[bd->part].p_size;
- }
- else
- maxsz = bd->ds->gd->part[minor].nr_sects;
- }
- else
- {
- assert (blk_size[major]);
- maxsz = blk_size[major][minor] << (BLOCK_SIZE_BITS - 9);
- }
- assert (maxsz > 0);
- sz = maxsz - bn;
- if (sz <= 0)
- return sz;
- if (sz < ((count + 511) >> 9))
- count = sz << 9;
- if (lp)
- bn += (lp->d_partitions[bd->part].p_offset
- - bd->ds->gd->part[minor].start_sect);
- *off = (loff_t) bn << 9;
- bd->iocount++;
- return count;
-}
-
-static io_return_t
-device_write (void *d, ipc_port_t reply_port,
- mach_msg_type_name_t reply_port_type, dev_mode_t mode,
- recnum_t bn, io_buf_ptr_t data, unsigned int orig_count,
- int *bytes_written)
-{
- int resid, amt, i;
- int count = (int) orig_count;
- io_return_t err = 0;
- vm_map_copy_t copy;
- vm_offset_t addr, uaddr;
- vm_size_t len, size;
- struct block_data *bd = d;
- DECL_DATA;
-
- INIT_DATA ();
-
- *bytes_written = 0;
-
- if (bd->mode == O_RDONLY)
- return D_INVALID_OPERATION;
- if (! bd->ds->fops->write)
- return D_READ_ONLY;
- count = check_limit (bd, &td.file.f_pos, bn, count);
- if (count < 0)
- return D_INVALID_SIZE;
- if (count == 0)
- {
- vm_map_copy_discard (copy);
- return 0;
- }
-
- resid = count;
- copy = (vm_map_copy_t) data;
- uaddr = copy->offset;
-
- /* Allocate a kernel buffer. */
- size = round_page (uaddr + count) - trunc_page (uaddr);
- if (size > MAX_COPY)
- size = MAX_COPY;
- addr = vm_map_min (device_io_map);
- err = vm_map_enter (device_io_map, &addr, size, 0, TRUE,
- NULL, 0, FALSE, VM_PROT_READ|VM_PROT_WRITE,
- VM_PROT_READ|VM_PROT_WRITE, VM_INHERIT_NONE);
- if (err)
- {
- vm_map_copy_discard (copy);
- goto out;
- }
-
- /* Determine size of I/O this time around. */
- len = size - (uaddr & PAGE_MASK);
- if (len > resid)
- len = resid;
-
- while (1)
- {
- /* Map user pages. */
- for (i = 0; i < copy->cpy_npages; i++)
- pmap_enter (vm_map_pmap (device_io_map),
- addr + (i << PAGE_SHIFT),
- copy->cpy_page_list[i]->phys_addr,
- VM_PROT_READ|VM_PROT_WRITE, TRUE);
-
- /* Do the write. */
- amt = (*bd->ds->fops->write) (&td.inode, &td.file,
- (char *) addr + (uaddr & PAGE_MASK), len);
-
- /* Unmap pages and deallocate copy. */
- pmap_remove (vm_map_pmap (device_io_map),
- addr, addr + (copy->cpy_npages << PAGE_SHIFT));
- vm_map_copy_discard (copy);
-
- /* Check result of write. */
- if (amt > 0)
- {
- resid -= amt;
- if (resid == 0)
- break;
- uaddr += amt;
- }
- else
- {
- if (amt < 0)
- err = linux_to_mach_error (amt);
- break;
- }
-
- /* Determine size of I/O this time around and copy in pages. */
- len = round_page (uaddr + resid) - trunc_page (uaddr);
- if (len > MAX_COPY)
- len = MAX_COPY;
- len -= uaddr & PAGE_MASK;
- if (len > resid)
- len = resid;
- err = vm_map_copyin_page_list (current_map (), uaddr, len,
- FALSE, FALSE, &copy, FALSE);
- if (err)
- break;
- }
-
- /* Delete kernel buffer. */
- vm_map_remove (device_io_map, addr, addr + size);
-
-out:
- if (--bd->iocount == 0 && bd->want)
- {
- bd->want = 0;
- thread_wakeup ((event_t) bd);
- }
- if (IP_VALID (reply_port))
- ds_device_write_reply (reply_port, reply_port_type, err, count - resid);
- return MIG_NO_REPLY;
-}
-
-static io_return_t
-device_read (void *d, ipc_port_t reply_port,
- mach_msg_type_name_t reply_port_type, dev_mode_t mode,
- recnum_t bn, int count, io_buf_ptr_t *data,
- unsigned *bytes_read)
-{
- boolean_t dirty;
- int resid, amt;
- io_return_t err = 0;
- queue_head_t pages;
- vm_map_copy_t copy;
- vm_offset_t addr, offset, alloc_offset, o;
- vm_object_t object;
- vm_page_t m;
- vm_size_t len, size;
- struct block_data *bd = d;
- DECL_DATA;
-
- INIT_DATA ();
-
- *data = 0;
- *bytes_read = 0;
-
- if (! bd->ds->fops->read)
- return D_INVALID_OPERATION;
- count = check_limit (bd, &td.file.f_pos, bn, count);
- if (count < 0)
- return D_INVALID_SIZE;
- if (count == 0)
- return 0;
-
- /* Allocate an object to hold the data. */
- size = round_page (count);
- object = vm_object_allocate (size);
- if (! object)
- {
- err = D_NO_MEMORY;
- goto out;
- }
- alloc_offset = offset = 0;
- resid = count;
-
- /* Allocate a kernel buffer. */
- addr = vm_map_min (device_io_map);
- if (size > MAX_COPY)
- size = MAX_COPY;
- err = vm_map_enter (device_io_map, &addr, size, 0, TRUE, NULL,
- 0, FALSE, VM_PROT_READ|VM_PROT_WRITE,
- VM_PROT_READ|VM_PROT_WRITE, VM_INHERIT_NONE);
- if (err)
- goto out;
-
- queue_init (&pages);
-
- while (resid)
- {
- /* Determine size of I/O this time around. */
- len = round_page (offset + resid) - trunc_page (offset);
- if (len > MAX_COPY)
- len = MAX_COPY;
-
- /* Map any pages left from previous operation. */
- o = trunc_page (offset);
- queue_iterate (&pages, m, vm_page_t, pageq)
- {
- pmap_enter (vm_map_pmap (device_io_map),
- addr + o - trunc_page (offset),
- m->phys_addr, VM_PROT_READ|VM_PROT_WRITE, TRUE);
- o += PAGE_SIZE;
- }
- assert (o == alloc_offset);
-
- /* Allocate and map pages. */
- while (alloc_offset < trunc_page (offset) + len)
- {
- while ((m = vm_page_grab ()) == 0)
- VM_PAGE_WAIT (0);
- assert (! m->active && ! m->inactive);
- m->busy = TRUE;
- queue_enter (&pages, m, vm_page_t, pageq);
- pmap_enter (vm_map_pmap (device_io_map),
- addr + alloc_offset - trunc_page (offset),
- m->phys_addr, VM_PROT_READ|VM_PROT_WRITE, TRUE);
- alloc_offset += PAGE_SIZE;
- }
-
- /* Do the read. */
- amt = len - (offset & PAGE_MASK);
- if (amt > resid)
- amt = resid;
- amt = (*bd->ds->fops->read) (&td.inode, &td.file,
- (char *) addr + (offset & PAGE_MASK), amt);
-
- /* Compute number of pages to insert in object. */
- o = trunc_page (offset);
- if (amt > 0)
- {
- dirty = TRUE;
- resid -= amt;
- if (resid == 0)
- {
- /* Zero any unused space. */
- if (offset + amt < o + len)
- memset ((void *) (addr + offset - o + amt),
- 0, o + len - offset - amt);
- offset = o + len;
- }
- else
- offset += amt;
- }
- else
- {
- dirty = FALSE;
- offset = o + len;
- }
-
- /* Unmap pages and add them to the object. */
- pmap_remove (vm_map_pmap (device_io_map), addr, addr + len);
- vm_object_lock (object);
- while (o < trunc_page (offset))
- {
- m = (vm_page_t) queue_first (&pages);
- assert (! queue_end (&pages, (queue_entry_t) m));
- queue_remove (&pages, m, vm_page_t, pageq);
- assert (m->busy);
- vm_page_lock_queues ();
- if (dirty)
- {
- PAGE_WAKEUP_DONE (m);
- m->dirty = TRUE;
- vm_page_insert (m, object, o);
- }
- else
- vm_page_free (m);
- vm_page_unlock_queues ();
- o += PAGE_SIZE;
- }
- vm_object_unlock (object);
- if (amt <= 0)
- {
- if (amt < 0)
- err = linux_to_mach_error (amt);
- break;
- }
- }
-
- /* Delete kernel buffer. */
- vm_map_remove (device_io_map, addr, addr + size);
-
- assert (queue_empty (&pages));
-
-out:
- if (! err)
- err = vm_map_copyin_object (object, 0, round_page (count), &copy);
- if (! err)
- {
- *data = (io_buf_ptr_t) copy;
- *bytes_read = count - resid;
- }
- else
- vm_object_deallocate (object);
- if (--bd->iocount == 0 && bd->want)
- {
- bd->want = 0;
- thread_wakeup ((event_t) bd);
- }
- return err;
-}
-
-static io_return_t
-device_get_status (void *d, dev_flavor_t flavor, dev_status_t status,
- mach_msg_type_number_t *status_count)
-{
- struct block_data *bd = d;
-
- switch (flavor)
- {
- case DEV_GET_SIZE:
- if (*status_count != DEV_GET_SIZE_COUNT)
- return D_INVALID_SIZE;
- if (disk_major (MAJOR (bd->dev)))
- {
- assert (bd->ds->gd);
-
- if (bd->part >= 0)
- {
- struct disklabel *lp;
-
- assert (bd->ds->labels);
- lp = bd->ds->labels[MINOR (bd->dev)];
- assert (lp);
- (status[DEV_GET_SIZE_DEVICE_SIZE]
- = lp->d_partitions[bd->part].p_size << 9);
- }
- else
- (status[DEV_GET_SIZE_DEVICE_SIZE]
- = bd->ds->gd->part[MINOR (bd->dev)].nr_sects << 9);
- }
- else
- {
- assert (blk_size[MAJOR (bd->dev)]);
- (status[DEV_GET_SIZE_DEVICE_SIZE]
- = (blk_size[MAJOR (bd->dev)][MINOR (bd->dev)]
- << BLOCK_SIZE_BITS));
- }
- /* It would be nice to return the block size as reported by
- the driver, but a lot of user level code assumes the sector
- size to be 512. */
- status[DEV_GET_SIZE_RECORD_SIZE] = 512;
- break;
-
- default:
- return D_INVALID_OPERATION;
- }
-
- return D_SUCCESS;
-}
-
-struct device_emulation_ops linux_block_emulation_ops =
-{
- NULL,
- NULL,
- dev_to_port,
- device_open,
- device_close,
- device_write,
- NULL,
- device_read,
- NULL,
- NULL,
- device_get_status,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL
-};
diff --git a/i386/i386at/gpl/linux/linux_dma.c b/i386/i386at/gpl/linux/linux_dma.c
deleted file mode 100644
index aab0fa8e..00000000
--- a/i386/i386at/gpl/linux/linux_dma.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Linux DMA channel management.
- * Copyright (C) 1995 Shantanu Goel.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#define MACH_INCLUDE
-#include <linux/errno.h>
-#include <asm/dma.h>
-
-/*
- * Bitmap of allocated/free DMA channels.
- */
-static int dma_busy = 0x10;
-
-/*
- * Allocate a DMA channel.
- */
-int
-request_dma(unsigned int drq, const char *name)
-{
- if (drq > 7)
- panic("request_dma: bad DRQ number");
- if (dma_busy & (1 << drq))
- return (-LINUX_EBUSY);
- dma_busy |= 1 << drq;
- return (0);
-}
-
-/*
- * Free a DMA channel.
- */
-void
-free_dma(unsigned int drq)
-{
- if (drq > 7)
- panic("free_dma: bad DRQ number");
- dma_busy &= ~(1 << drq);
-}
diff --git a/i386/i386at/gpl/linux/linux_emul.h b/i386/i386at/gpl/linux/linux_emul.h
deleted file mode 100644
index dc338020..00000000
--- a/i386/i386at/gpl/linux/linux_emul.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Defintions for Linux driver emulation.
- *
- * Copyright (C) 1996 The University of Utah and the Computer Systems
- * Laboratory at the University of Utah (CSL)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Author: Shantanu Goel, University of Utah CSL
- */
-
-#include <i386/ipl.h>
-
-extern int linux_auto_config;
-extern int linux_intr_pri;
-
-int linux_to_mach_error (int);
-void *alloc_contig_mem (unsigned, unsigned, unsigned, vm_page_t *);
-void free_contig_mem (vm_page_t);
-void collect_buffer_pages (void);
diff --git a/i386/i386at/gpl/linux/linux_init.c b/i386/i386at/gpl/linux/linux_init.c
deleted file mode 100644
index 4e7b006a..00000000
--- a/i386/i386at/gpl/linux/linux_init.c
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- * Linux initialization.
- *
- * Copyright (C) 1996 The University of Utah and the Computer Systems
- * Laboratory at the University of Utah (CSL)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Author: Shantanu Goel, University of Utah CSL
- */
-
-/*
- * linux/init/main.c
- *
- * Copyright (C) 1991, 1992 Linus Torvalds
- */
-
-#include <sys/types.h>
-
-#include <mach/vm_param.h>
-#include <mach/vm_prot.h>
-#include <mach/machine.h>
-
-#include <vm/vm_page.h>
-
-#include <i386/ipl.h>
-#include <i386/pic.h>
-#include <i386/pit.h>
-#include <i386/machspl.h>
-#include <i386/pmap.h>
-#include <i386/vm_param.h>
-
-#include <i386at/gpl/linux/linux_emul.h>
-
-#define MACH_INCLUDE
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/ioport.h>
-#include <linux/string.h>
-
-#include <asm/system.h>
-
-#include <i386/device-drivers.h>
-
-/*
- * Set if the machine has an EISA bus.
- */
-int EISA_bus = 0;
-
-/*
- * Timing loop count.
- */
-unsigned long loops_per_sec = 1;
-
-/*
- * End of physical memory.
- */
-unsigned long high_memory;
-
-/*
- * Flag to indicate auto-configuration is in progress.
- */
-int linux_auto_config = 1;
-
-/*
- * Hard drive parameters obtained from the BIOS.
- */
-struct drive_info_struct {
- char dummy[32];
-} drive_info;
-
-/*
- * Forward declarations.
- */
-static void calibrate_delay(void);
-
-extern int hz;
-extern vm_offset_t phys_last_addr;
-
-extern void timer_bh(void *);
-extern void tqueue_bh(void *);
-extern void startrtclock(void);
-extern void linux_version_init(void);
-extern void linux_kmem_init(void);
-extern unsigned long pci_init(unsigned long, unsigned long);
-extern void linux_net_emulation_init (void);
-extern void device_setup(void);
-extern void linux_printk(char *, ...);
-extern int linux_timer_intr();
-
-/*
- * Amount of contiguous memory to allocate for initialization.
- */
-#define CONTIG_ALLOC (512 * 1024)
-
-/*
- * Initialize Linux drivers.
- */
-void
-linux_init()
-{
- char *p;
- int i, addr;
- int (*old_clock_handler)(), old_clock_pri;
- unsigned memory_start, memory_end;
- vm_page_t pages;
-
- /*
- * Initialize memory size.
- */
- high_memory = phys_last_addr;
-
- /*
- * Ensure interrupts are disabled.
- */
- (void) splhigh();
-
- /*
- * Program counter 0 of 8253 to interrupt hz times per second.
- */
- outb(PITCTL_PORT, PIT_C0|PIT_SQUAREMODE|PIT_READMODE);
- outb(PITCTR0_PORT, CLKNUM / hz);
- outb(PITCTR0_PORT, (CLKNUM / hz) >> 8);
-
- /*
- * Install our clock interrupt handler.
- */
- old_clock_handler = ivect[0];
- old_clock_pri = intpri[0];
- ivect[0] = linux_timer_intr;
- intpri[0] = SPLHI;
- form_pic_mask();
-
- /*
- * Enable interrupts.
- */
- (void) spl0();
-
- /*
- * Set Linux version.
- */
- linux_version_init();
-
- /*
- * Check if the machine has an EISA bus.
- */
- p = (char *)0x0FFFD9;
- if (*p++ == 'E' && *p++ == 'I' && *p++ == 'S' && *p == 'A')
- EISA_bus = 1;
-
- /*
- * Permanently allocate standard device ports.
- */
- request_region(0x00, 0x20, "dma1");
- request_region(0x40, 0x20, "timer");
- request_region(0x70, 0x10, "rtc");
- request_region(0x80, 0x20, "dma page reg");
- request_region(0xc0, 0x20, "dma2");
- request_region(0xf0, 0x02, "fpu");
- request_region(0xf8, 0x08, "fpu");
-
- /*
- * Install software interrupt handlers.
- */
- bh_base[TIMER_BH].routine = timer_bh;
- bh_base[TIMER_BH].data = 0;
- enable_bh(TIMER_BH);
- bh_base[TQUEUE_BH].routine = tqueue_bh;
- bh_base[TQUEUE_BH].data = 0;
- enable_bh(TQUEUE_BH);
-
- /*
- * Set loop count.
- */
- calibrate_delay();
-
- /*
- * Initialize drive info.
- */
- addr = *((unsigned *)phystokv(0x104));
- memcpy (&drive_info,
- (void *)((addr & 0xffff) + ((addr >> 12) & 0xffff0)), 16);
- addr = *((unsigned *)phystokv(0x118));
- memcpy ((char *)&drive_info + 16,
- (void *)((addr & 0xffff) + ((addr >> 12) & 0xffff0)), 16);
-
- /*
- * Initialize Linux memory allocator.
- */
- linux_kmem_init();
-
- /*
- * Allocate contiguous memory below 16 MB.
- */
- memory_start = (unsigned long)alloc_contig_mem(CONTIG_ALLOC,
- 16 * 1024 * 1024,
- 0, &pages);
- if (memory_start == 0)
- panic("linux_init: alloc_contig_mem failed");
- memory_end = memory_start + CONTIG_ALLOC;
-
- /*
- * Initialize PCI bus.
- */
- memory_start = pci_init(memory_start, memory_end);
-
- if (memory_start > memory_end)
- panic("linux_init: ran out memory");
-
- /*
- * Free unused memory.
- */
- while (pages && pages->phys_addr < round_page(memory_start))
- pages = (vm_page_t)pages->pageq.next;
- if (pages)
- free_contig_mem(pages);
-
- /*
- * Initialize devices.
- */
-#ifdef CONFIG_INET
- linux_net_emulation_init();
-#endif
- cli();
- device_setup();
-
- /*
- * Disable interrupts.
- */
- (void) splhigh();
-
- /*
- * Restore clock interrupt handler.
- */
- ivect[0] = old_clock_handler;
- intpri[0] = old_clock_pri;
- form_pic_mask();
-
- linux_auto_config = 0;
-}
-
-#ifndef NBPW
-#define NBPW 32
-#endif
-
-/*
- * Allocate contiguous memory with the given constraints.
- * This routine is horribly inefficient but it is presently
- * only used during initialization so it's not that bad.
- */
-void *
-alloc_contig_mem(unsigned size, unsigned limit,
- unsigned mask, vm_page_t *pages)
-{
- int i, j, bits_len;
- unsigned *bits, len;
- void *m;
- vm_page_t p, page_list, tail, prev;
- vm_offset_t addr, max_addr;
-
- if (size == 0)
- return (NULL);
- size = round_page(size);
- if ((size >> PAGE_SHIFT) > vm_page_free_count)
- return (NULL);
-
- /* Allocate bit array. */
- max_addr = phys_last_addr;
- if (max_addr > limit)
- max_addr = limit;
- bits_len = ((((max_addr >> PAGE_SHIFT) + NBPW - 1) / NBPW)
- * sizeof(unsigned));
- bits = (unsigned *)kalloc(bits_len);
- if (!bits)
- return (NULL);
- memset (bits, 0, bits_len);
-
- /*
- * Walk the page free list and set a bit for every usable page.
- */
- simple_lock(&vm_page_queue_free_lock);
- p = vm_page_queue_free;
- while (p) {
- if (p->phys_addr < limit)
- (bits[(p->phys_addr >> PAGE_SHIFT) / NBPW]
- |= 1 << ((p->phys_addr >> PAGE_SHIFT) % NBPW));
- p = (vm_page_t)p->pageq.next;
- }
-
- /*
- * Scan bit array for contiguous pages.
- */
- len = 0;
- m = NULL;
- for (i = 0; len < size && i < bits_len / sizeof (unsigned); i++)
- for (j = 0; len < size && j < NBPW; j++)
- if (!(bits[i] & (1 << j))) {
- len = 0;
- m = NULL;
- } else {
- if (len == 0) {
- addr = ((vm_offset_t)(i * NBPW + j)
- << PAGE_SHIFT);
- if ((addr & mask) == 0) {
- len += PAGE_SIZE;
- m = (void *) addr;
- }
- } else
- len += PAGE_SIZE;
- }
-
- if (len != size) {
- simple_unlock(&vm_page_queue_free_lock);
- kfree ((vm_offset_t)bits, bits_len);
- return (NULL);
- }
-
- /*
- * Remove pages from free list
- * and construct list to return to caller.
- */
- page_list = NULL;
- for (len = 0; len < size; len += PAGE_SIZE, addr += PAGE_SIZE) {
- prev = NULL;
- for (p = vm_page_queue_free; p; p = (vm_page_t)p->pageq.next) {
- if (p->phys_addr == addr)
- break;
- prev = p;
- }
- if (!p)
- panic("alloc_contig_mem: page not on free list");
- if (prev)
- prev->pageq.next = p->pageq.next;
- else
- vm_page_queue_free = (vm_page_t)p->pageq.next;
- p->free = FALSE;
- p->pageq.next = NULL;
- if (!page_list)
- page_list = tail = p;
- else {
- tail->pageq.next = (queue_entry_t)p;
- tail = p;
- }
- vm_page_free_count--;
- }
-
- simple_unlock(&vm_page_queue_free_lock);
- kfree((vm_offset_t)bits, bits_len);
- if (pages)
- *pages = page_list;
- return (m);
-}
-
-/*
- * Free memory allocated by alloc_contig_mem.
- */
-void
-free_contig_mem(vm_page_t pages)
-{
- int i;
- vm_page_t p;
-
- for (p = pages, i = 0; p->pageq.next; p = (vm_page_t)p->pageq.next, i++)
- p->free = TRUE;
- p->free = TRUE;
- simple_lock(&vm_page_queue_free_lock);
- vm_page_free_count += i + 1;
- p->pageq.next = (queue_entry_t)vm_page_queue_free;
- vm_page_queue_free = pages;
- simple_unlock(&vm_page_queue_free_lock);
-}
-
-/*
- * Calibrate delay loop.
- * Lifted straight from Linux.
- */
-static void
-calibrate_delay()
-{
- int ticks;
-
- /* printk("Calibrating delay loop.. "); */
- while (loops_per_sec <<= 1) {
- /* Wait for "start of" clock tick. */
- ticks = jiffies;
- while (ticks == jiffies)
- /* nothing */;
- /* Go .. */
- ticks = jiffies;
- __delay(loops_per_sec);
- ticks = jiffies - ticks;
- if (ticks >= hz) {
- loops_per_sec = muldiv(loops_per_sec,
- hz, ticks);
- /*printk("ok - %lu.%02lu BogoMips\n",
- loops_per_sec / 500000,
- (loops_per_sec / 5000) % 100);*/
- return;
- }
- }
-/* printk("failed\n");*/
-}
diff --git a/i386/i386at/gpl/linux/linux_irq.c b/i386/i386at/gpl/linux/linux_irq.c
deleted file mode 100644
index d04e0531..00000000
--- a/i386/i386at/gpl/linux/linux_irq.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Linux IRQ management.
- * Copyright (C) 1995 Shantanu Goel.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
- * linux/arch/i386/kernel/irq.c
- *
- * Copyright (C) 1992 Linus Torvalds
- */
-
-#include <sys/types.h>
-
-#include <kern/assert.h>
-
-#include <i386/machspl.h>
-#include <i386/ipl.h>
-#include <i386/pic.h>
-
-#define MACH_INCLUDE
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/ptrace.h>
-#include <linux/errno.h>
-#include <linux/delay.h>
-#include <linux/kernel_stat.h>
-
-#include <asm/system.h>
-#include <asm/bitops.h>
-#include <asm/irq.h>
-
-/*
- * Priority at which a Linux handler should be called.
- * This is used at the time of an IRQ allocation. It is
- * set by emulation routines for each class of device.
- */
-spl_t linux_intr_pri;
-
-/*
- * Flag indicating an interrupt is being handled.
- */
-unsigned long intr_count = 0;
-
-/*
- * List of Linux interrupt handlers.
- */
-static void (*linux_handlers[16])(int, struct pt_regs *);
-
-extern spl_t curr_ipl;
-extern int curr_pic_mask;
-extern int pic_mask[];
-
-extern int intnull(), prtnull();
-
-/*
- * Generic interrupt handler for Linux devices.
- * Set up a fake `struct pt_regs' then call the real handler.
- */
-static int
-linux_intr(irq)
- int irq;
-{
- struct pt_regs regs;
-
- kstat.interrupts[irq]++;
- intr_count++;
- (*linux_handlers[irq])(irq, &regs);
- intr_count--;
-}
-
-/*
- * Mask an IRQ.
- */
-void
-disable_irq(irq)
- unsigned int irq;
-{
- int i, flags;
-
- assert (irq < NR_IRQS);
-
- save_flags(flags);
- cli();
- for (i = 0; i < intpri[irq]; i++)
- pic_mask[i] |= 1 << irq;
- if (curr_pic_mask != pic_mask[curr_ipl]) {
- curr_pic_mask = pic_mask[curr_ipl];
- outb(PIC_MASTER_OCW, curr_pic_mask);
- outb(PIC_SLAVE_OCW, curr_pic_mask >> 8);
- }
- restore_flags(flags);
-}
-
-/*
- * Unmask an IRQ.
- */
-void
-enable_irq(irq)
- unsigned int irq;
-{
- int mask, i, flags;
-
- assert (irq < NR_IRQS);
-
- mask = 1 << irq;
- if (irq >= 8)
- mask |= 1 << 2;
- save_flags(flags);
- cli();
- for (i = 0; i < intpri[irq]; i++)
- pic_mask[i] &= ~mask;
- if (curr_pic_mask != pic_mask[curr_ipl]) {
- curr_pic_mask = pic_mask[curr_ipl];
- outb(PIC_MASTER_OCW, curr_pic_mask);
- outb(PIC_SLAVE_OCW, curr_pic_mask >> 8);
- }
- restore_flags(flags);
-}
-
-/*
- * Attach a handler to an IRQ.
- */
-int
-request_irq(unsigned int irq, void (*handler)(int, struct pt_regs *),
- unsigned long flags, const char *device)
-{
- assert(irq < 16);
-
- if (ivect[irq] == intnull || ivect[irq] == prtnull) {
- if (!handler)
- return (-LINUX_EINVAL);
- linux_handlers[irq] = handler;
- ivect[irq] = linux_intr;
- iunit[irq] = irq;
- intpri[irq] = linux_intr_pri;
- enable_irq(irq);
- return (0);
- }
- return (-LINUX_EBUSY);
-}
-
-/*
- * Deallocate an irq.
- */
-void
-free_irq(unsigned int irq)
-{
- if (irq > 15)
- panic("free_irq: bad irq number");
-
- disable_irq(irq);
- ivect[irq] = (irq == 7) ? prtnull : intnull;
- iunit[irq] = irq;
- intpri[irq] = SPL0;
-}
-
-/*
- * IRQ probe interrupt handler.
- */
-void
-probe_intr(irq)
- int irq;
-{
- disable_irq(irq);
-}
-
-/*
- * Set for an irq probe.
- */
-unsigned long
-probe_irq_on()
-{
- unsigned i, irqs = 0;
- unsigned long delay;
-
- assert (curr_ipl == 0);
-
- /*
- * Allocate all available IRQs.
- */
- for (i = 15; i > 0; i--)
- if (request_irq(i, probe_intr, 0, "probe") == 0)
- irqs |= 1 << i;
-
- /*
- * Wait for spurious interrupts to mask themselves out.
- */
- for (delay = jiffies + 2; delay > jiffies; )
- ;
-
- /*
- * Free IRQs that caused spurious interrupts.
- */
- for (i = 15; i > 0; i--) {
- if (irqs & (1 << i) & pic_mask[0]) {
- irqs ^= 1 << i;
- free_irq(i);
- }
- }
-
- return (irqs);
-}
-
-/*
- * Return the result of an irq probe.
- */
-int
-probe_irq_off(unsigned long irqs)
-{
- unsigned i, irqs_save = irqs;
-
- assert (curr_ipl == 0);
-
- irqs &= pic_mask[0];
-
- /*
- * Deallocate IRQs.
- */
- for (i = 15; i > 0; i--)
- if (irqs_save & (1 << i))
- free_irq(i);
-
- /*
- * Return IRQ number.
- */
- if (!irqs)
- return (0);
- i = ffz(~irqs);
- if (irqs != (irqs & (1 << i)))
- i = -i;
- return (i);
-}
diff --git a/i386/i386at/gpl/linux/linux_kmem.c b/i386/i386at/gpl/linux/linux_kmem.c
deleted file mode 100644
index e5e44399..00000000
--- a/i386/i386at/gpl/linux/linux_kmem.c
+++ /dev/null
@@ -1,480 +0,0 @@
-/*
- * Linux memory allocation.
- *
- * Copyright (C) 1996 The University of Utah and the Computer Systems
- * Laboratory at the University of Utah (CSL)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Author: Shantanu Goel, University of Utah CSL
- *
- */
-
-#include <sys/types.h>
-
-#include <mach/mach_types.h>
-#include <mach/vm_param.h>
-
-#include <kern/assert.h>
-#include <kern/kalloc.h>
-
-#include <vm/vm_page.h>
-
-#include <i386at/gpl/linux/linux_emul.h>
-
-#define MACH_INCLUDE
-#include <linux/sched.h>
-#include <linux/malloc.h>
-#include <linux/delay.h>
-
-#include <asm/system.h>
-
-/* Amount of memory to reserve for Linux memory allocator.
- We reserve 64K chunks to stay within DMA limits.
- Increase MEM_CHUNKS if the kernel is running out of memory. */
-#define MEM_CHUNK_SIZE (64 * 1024)
-#define MEM_CHUNKS 7
-
-/* Mininum amount that linux_kmalloc will allocate. */
-#define MIN_ALLOC 12
-
-#ifndef NBPW
-#define NBPW 32
-#endif
-
-/* Memory block header. */
-struct blkhdr
-{
- unsigned short free; /* 1 if block is free */
- unsigned short size; /* size of block */
-};
-
-/* This structure heads a page allocated by linux_kmalloc. */
-struct pagehdr
-{
- unsigned size; /* size (multiple of PAGE_SIZE) */
- struct pagehdr *next; /* next header in list */
-};
-
-/* This structure describes a memory chunk. */
-struct chunkhdr
-{
- unsigned long start; /* start address */
- unsigned long end; /* end address */
- unsigned long bitmap; /* busy/free bitmap of pages */
-};
-
-/* Chunks from which pages are allocated. */
-static struct chunkhdr pages_free[MEM_CHUNKS];
-
-/* Memory list maintained by linux_kmalloc. */
-static struct pagehdr *memlist;
-
-/* Some statistics. */
-int num_block_coalesce = 0;
-int num_page_collect = 0;
-int linux_mem_avail;
-
-/* Initialize the Linux memory allocator. */
-void
-linux_kmem_init ()
-{
- int i, j;
- vm_page_t p, pages;
-
- for (i = 0; i < MEM_CHUNKS; i++)
- {
- /* Allocate memory. */
- pages_free[i].start = (unsigned long) alloc_contig_mem (MEM_CHUNK_SIZE,
- 16 * 1024 * 1024,
- 0xffff, &pages);
-
- assert (pages_free[i].start);
- assert ((pages_free[i].start & 0xffff) == 0);
-
- /* Sanity check: ensure pages are contiguous and within DMA limits. */
- for (p = pages, j = 0; j < MEM_CHUNK_SIZE - PAGE_SIZE; j += PAGE_SIZE)
- {
- assert (p->phys_addr < 16 * 1024 * 1024);
- assert (p->phys_addr + PAGE_SIZE
- == ((vm_page_t) p->pageq.next)->phys_addr);
-
- p = (vm_page_t) p->pageq.next;
- }
-
- pages_free[i].end = pages_free[i].start + MEM_CHUNK_SIZE;
-
- /* Initialize free page bitmap. */
- pages_free[i].bitmap = 0;
- j = MEM_CHUNK_SIZE >> PAGE_SHIFT;
- while (--j >= 0)
- pages_free[i].bitmap |= 1 << j;
- }
-
- linux_mem_avail = (MEM_CHUNKS * MEM_CHUNK_SIZE) >> PAGE_SHIFT;
-}
-
-/* Return the number by which the page size should be
- shifted such that the resulting value is >= SIZE. */
-static unsigned long
-get_page_order (int size)
-{
- unsigned long order;
-
- for (order = 0; (PAGE_SIZE << order) < size; order++)
- ;
- return order;
-}
-
-#ifdef LINUX_DEV_DEBUG
-static void
-check_page_list (int line)
-{
- unsigned size;
- struct pagehdr *ph;
- struct blkhdr *bh;
-
- for (ph = memlist; ph; ph = ph->next)
- {
- if ((int) ph & PAGE_MASK)
- panic ("%s:%d: page header not aligned", __FILE__, line);
-
- size = 0;
- bh = (struct blkhdr *) (ph + 1);
- while (bh < (struct blkhdr *) ((void *) ph + ph->size))
- {
- size += bh->size + sizeof (struct blkhdr);
- bh = (void *) (bh + 1) + bh->size;
- }
-
- if (size + sizeof (struct pagehdr) != ph->size)
- panic ("%s:%d: memory list destroyed", __FILE__, line);
- }
-}
-#else
-#define check_page_list(line)
-#endif
-
-/* Merge adjacent free blocks in the memory list. */
-static void
-coalesce_blocks ()
-{
- struct pagehdr *ph;
- struct blkhdr *bh, *bhp, *ebh;
-
- num_block_coalesce++;
-
- for (ph = memlist; ph; ph = ph->next)
- {
- bh = (struct blkhdr *) (ph + 1);
- ebh = (struct blkhdr *) ((void *) ph + ph->size);
- while (1)
- {
- /* Skip busy blocks. */
- while (bh < ebh && ! bh->free)
- bh = (struct blkhdr *) ((void *) (bh + 1) + bh->size);
- if (bh == ebh)
- break;
-
- /* Merge adjacent free blocks. */
- while (1)
- {
- bhp = (struct blkhdr *) ((void *) (bh + 1) + bh->size);
- if (bhp == ebh)
- {
- bh = bhp;
- break;
- }
- if (! bhp->free)
- {
- bh = (struct blkhdr *) ((void *) (bhp + 1) + bhp->size);
- break;
- }
- bh->size += bhp->size + sizeof (struct blkhdr);
- }
- }
- }
-}
-
-/* Allocate SIZE bytes of memory.
- The PRIORITY parameter specifies various flags
- such as DMA, atomicity, etc. It is not used by Mach. */
-void *
-linux_kmalloc (unsigned int size, int priority)
-{
- int order, coalesced = 0;
- unsigned flags;
- struct pagehdr *ph;
- struct blkhdr *bh, *new_bh;
-
- if (size < MIN_ALLOC)
- size = MIN_ALLOC;
- else
- size = (size + sizeof (int) - 1) & ~(sizeof (int) - 1);
-
- assert (size <= (MEM_CHUNK_SIZE
- - sizeof (struct pagehdr)
- - sizeof (struct blkhdr)));
-
- save_flags (flags);
- cli ();
-
-again:
- check_page_list (__LINE__);
-
- /* Walk the page list and find the first free block with size
- greater than or equal to the one required. */
- for (ph = memlist; ph; ph = ph->next)
- {
- bh = (struct blkhdr *) (ph + 1);
- while (bh < (struct blkhdr *) ((void *) ph + ph->size))
- {
- if (bh->free && bh->size >= size)
- {
- bh->free = 0;
- if (bh->size - size >= MIN_ALLOC + sizeof (struct blkhdr))
- {
- /* Split the current block and create a new free block. */
- new_bh = (void *) (bh + 1) + size;
- new_bh->free = 1;
- new_bh->size = bh->size - size - sizeof (struct blkhdr);
- bh->size = size;
- }
-
- check_page_list (__LINE__);
-
- restore_flags (flags);
- return bh + 1;
- }
- bh = (void *) (bh + 1) + bh->size;
- }
- }
-
- check_page_list (__LINE__);
-
- /* Allocation failed; coalesce free blocks and try again. */
- if (! coalesced)
- {
- coalesce_blocks ();
- coalesced = 1;
- goto again;
- }
-
- /* Allocate more pages. */
- order = get_page_order (size
- + sizeof (struct pagehdr)
- + sizeof (struct blkhdr));
- ph = (struct pagehdr *) __get_free_pages (GFP_KERNEL, order, ~0UL);
- if (! ph)
- {
- restore_flags (flags);
- return NULL;
- }
-
- ph->size = PAGE_SIZE << order;
- ph->next = memlist;
- memlist = ph;
- bh = (struct blkhdr *) (ph + 1);
- bh->free = 0;
- bh->size = ph->size - sizeof (struct pagehdr) - sizeof (struct blkhdr);
- if (bh->size - size >= MIN_ALLOC + sizeof (struct blkhdr))
- {
- new_bh = (void *) (bh + 1) + size;
- new_bh->free = 1;
- new_bh->size = bh->size - size - sizeof (struct blkhdr);
- bh->size = size;
- }
-
- check_page_list (__LINE__);
-
- restore_flags (flags);
- return bh + 1;
-}
-
-/* Free memory P previously allocated by linux_kmalloc. */
-void
-linux_kfree (void *p)
-{
- unsigned flags;
- struct blkhdr *bh, *bhp;
- struct pagehdr *ph;
-
- assert (((int) p & (sizeof (int) - 1)) == 0);
-
- save_flags (flags);
- cli ();
-
- check_page_list (__LINE__);
-
- for (ph = memlist; ph; ph = ph->next)
- if (p >= (void *) ph && p < (void *) ph + ph->size)
- break;
-
- assert (ph);
-
- bh = (struct blkhdr *) p - 1;
-
- assert (! bh->free);
- assert (bh->size >= MIN_ALLOC);
- assert ((bh->size & (sizeof (int) - 1)) == 0);
-
- bh->free = 1;
-
- check_page_list (__LINE__);
-
- restore_flags (flags);
-}
-
-/* Free any pages that are not in use.
- Called by __get_free_pages when pages are running low. */
-static void
-collect_kmalloc_pages ()
-{
- struct blkhdr *bh;
- struct pagehdr *ph, **prev_ph;
-
- check_page_list (__LINE__);
-
- coalesce_blocks ();
-
- check_page_list (__LINE__);
-
- ph = memlist;
- prev_ph = &memlist;
- while (ph)
- {
- bh = (struct blkhdr *) (ph + 1);
- if (bh->free && (void *) (bh + 1) + bh->size == (void *) ph + ph->size)
- {
- *prev_ph = ph->next;
- free_pages ((unsigned long) ph, get_page_order (ph->size));
- ph = *prev_ph;
- }
- else
- {
- prev_ph = &ph->next;
- ph = ph->next;
- }
- }
-
- check_page_list (__LINE__);
-}
-
-/* Allocate ORDER + 1 number of physically contiguous pages.
- PRIORITY and MAX_ADDR are not used in Mach.
-
- XXX: This needs to be dynamic. To do that we need to make
- the Mach page manipulation routines interrupt safe and they
- must provide machine dependant hooks. */
-unsigned long
-__get_free_pages (int priority, unsigned long order, unsigned long max_addr)
-{
- int i, pages_collected = 0;
- unsigned flags, bits, off, j, len;
-
- assert ((PAGE_SIZE << order) <= MEM_CHUNK_SIZE);
-
- /* Construct bitmap of contiguous pages. */
- bits = 0;
- j = 0;
- len = 0;
- while (len < (PAGE_SIZE << order))
- {
- bits |= 1 << j++;
- len += PAGE_SIZE;
- }
-
-again:
- save_flags (flags);
- cli ();
-
- /* Search each chunk for the required number of contiguous pages. */
- for (i = 0; i < MEM_CHUNKS; i++)
- {
- off = 0;
- j = bits;
- while (MEM_CHUNK_SIZE - off >= (PAGE_SIZE << order))
- {
- if ((pages_free[i].bitmap & j) == j)
- {
- pages_free[i].bitmap &= ~j;
- linux_mem_avail -= order + 1;
- restore_flags (flags);
- return pages_free[i].start + off;
- }
- j <<= 1;
- off += PAGE_SIZE;
- }
- }
-
- /* Allocation failed; collect kmalloc and buffer pages
- and try again. */
- if (! pages_collected)
- {
- num_page_collect++;
- collect_kmalloc_pages ();
- pages_collected = 1;
- goto again;
- }
-
- printf ("%s:%d: __get_free_pages: ran out of pages\n", __FILE__, __LINE__);
-
- restore_flags (flags);
- return 0;
-}
-
-/* Free ORDER + 1 number of physically
- contiguous pages starting at address ADDR. */
-void
-free_pages (unsigned long addr, unsigned long order)
-{
- int i;
- unsigned flags, bits, len, j;
-
- assert ((addr & PAGE_MASK) == 0);
-
- for (i = 0; i < MEM_CHUNKS; i++)
- if (addr >= pages_free[i].start && addr < pages_free[i].end)
- break;
-
- assert (i < MEM_CHUNKS);
-
- /* Contruct bitmap of contiguous pages. */
- len = 0;
- j = 0;
- bits = 0;
- while (len < (PAGE_SIZE << order))
- {
- bits |= 1 << j++;
- len += PAGE_SIZE;
- }
- bits <<= (addr - pages_free[i].start) >> PAGE_SHIFT;
-
- save_flags (flags);
- cli ();
-
- assert ((pages_free[i].bitmap & bits) == 0);
-
- pages_free[i].bitmap |= bits;
- linux_mem_avail += order + 1;
- restore_flags (flags);
-}
-
-/* Allocate SIZE bytes of memory. The pages need not be contiguous. */
-void *
-vmalloc (unsigned long size)
-{
- return (void *) __get_free_pages (GFP_KERNEL, get_page_order (size), ~0UL);
-}
diff --git a/i386/i386at/gpl/linux/linux_misc.c b/i386/i386at/gpl/linux/linux_misc.c
deleted file mode 100644
index 6e7b33b9..00000000
--- a/i386/i386at/gpl/linux/linux_misc.c
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- * Miscellaneous routines and data for Linux emulation.
- *
- * Copyright (C) 1996 The University of Utah and the Computer Systems
- * Laboratory at the University of Utah (CSL)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Author: Shantanu Goel, University of Utah CSL
- */
-
-/*
- * linux/fs/proc/scsi.c
- * (c) 1995 Michael Neuffer neuffer@goofy.zdv.uni-mainz.de
- *
- * The original version was derived from linux/fs/proc/net.c,
- * which is Copyright (C) 1991, 1992 Linus Torvalds.
- * Much has been rewritten, but some of the code still remains.
- *
- * /proc/scsi directory handling functions
- *
- * last change: 95/07/04
- *
- * Initial version: March '95
- * 95/05/15 Added subdirectories for each driver and show every
- * registered HBA as a single file.
- * 95/05/30 Added rudimentary write support for parameter passing
- * 95/07/04 Fixed bugs in directory handling
- * 95/09/13 Update to support the new proc-dir tree
- *
- * TODO: Improve support to write to the driver files
- * Add some more comments
- */
-
-/*
- * linux/fs/buffer.c
- *
- * Copyright (C) 1991, 1992 Linus Torvalds
- */
-
-#include <sys/types.h>
-#include <mach/vm_param.h>
-#include <kern/thread.h>
-#include <vm/vm_map.h>
-#include <vm/vm_page.h>
-#include <device/device_types.h>
-#include <i386at/gpl/linux/linux_emul.h>
-
-#define MACH_INCLUDE
-#include <linux/errno.h>
-#include <linux/mm.h>
-#include <linux/fs.h>
-#include <linux/blk.h>
-#include <linux/proc_fs.h>
-#include <linux/kernel_stat.h>
-
-int (*dispatch_scsi_info_ptr) (int ino, char *buffer, char **start,
- off_t offset, int length, int inout) = 0;
-
-struct kernel_stat kstat;
-
-int
-linux_to_mach_error (int err)
-{
- switch (err)
- {
- case 0:
- return D_SUCCESS;
-
- case -LINUX_EPERM:
- return D_INVALID_OPERATION;
-
- case -LINUX_EIO:
- return D_IO_ERROR;
-
- case -LINUX_ENXIO:
- return D_NO_SUCH_DEVICE;
-
- case -LINUX_EACCES:
- return D_INVALID_OPERATION;
-
- case -LINUX_EFAULT:
- return D_INVALID_SIZE;
-
- case -LINUX_EBUSY:
- return D_ALREADY_OPEN;
-
- case -LINUX_EINVAL:
- return D_INVALID_SIZE;
-
- case -LINUX_EROFS:
- return D_READ_ONLY;
-
- case -LINUX_EWOULDBLOCK:
- return D_WOULD_BLOCK;
-
- default:
- printf ("linux_to_mach_error: unknown code %d\n", err);
- return D_IO_ERROR;
- }
-}
-
-int
-issig ()
-{
- return current_thread ()->wait_result != THREAD_AWAKENED;
-}
-
-int
-block_fsync (struct inode *inode, struct file *filp)
-{
- return 0;
-}
-
-int
-verify_area (int rw, const void *p, unsigned long size)
-{
- vm_prot_t prot = (rw == VERIFY_WRITE) ? VM_PROT_WRITE : VM_PROT_READ;
- vm_offset_t addr = trunc_page ((vm_offset_t) p);
- vm_size_t len = round_page ((vm_size_t) size);
- vm_map_entry_t entry;
-
- vm_map_lock_read (current_map ());
-
- while (1)
- {
- if (! vm_map_lookup_entry (current_map (), addr, &entry)
- || (entry->protection & prot) != prot)
- {
- vm_map_unlock_read (current_map ());
- return -LINUX_EFAULT;
- }
- if (entry->vme_end - entry->vme_start >= len)
- break;
- len -= entry->vme_end - entry->vme_start;
- addr += entry->vme_end - entry->vme_start;
- }
-
- vm_map_unlock_read (current_map ());
- return 0;
-}
-
-/*
- * Print device name (in decimal, hexadecimal or symbolic) -
- * at present hexadecimal only.
- * Note: returns pointer to static data!
- */
-char *
-kdevname(kdev_t dev)
-{
- static char buffer[32];
- sprintf(buffer, "%02x:%02x", MAJOR(dev), MINOR(dev));
- return buffer;
-}
-
-/* RO fail safe mechanism */
-
-static long ro_bits[MAX_BLKDEV][8];
-
-int
-is_read_only(kdev_t dev)
-{
- int minor,major;
-
- major = MAJOR(dev);
- minor = MINOR(dev);
- if (major < 0 || major >= MAX_BLKDEV) return 0;
- return ro_bits[major][minor >> 5] & (1 << (minor & 31));
-}
-
-void
-set_device_ro(kdev_t dev,int flag)
-{
- int minor,major;
-
- major = MAJOR(dev);
- minor = MINOR(dev);
- if (major < 0 || major >= MAX_BLKDEV) return;
- if (flag) ro_bits[major][minor >> 5] |= 1 << (minor & 31);
- else ro_bits[major][minor >> 5] &= ~(1 << (minor & 31));
-}
-
-/*
- * linux/lib/string.c
- *
- * Copyright (C) 1991, 1992 Linus Torvalds
- */
-
-/*
- * stupid library routines.. The optimized versions should generally be found
- * as inline code in <asm-xx/string.h>
- *
- * These are buggy as well..
- */
-
-#include <linux/types.h>
-#include <linux/string.h>
-
-char * ___strtok = NULL;
-
-#ifndef __HAVE_ARCH_STRSPN
-size_t strspn(const char *s, const char *accept)
-{
- const char *p;
- const char *a;
- size_t count = 0;
-
- for (p = s; *p != '\0'; ++p) {
- for (a = accept; *a != '\0'; ++a) {
- if (*p == *a)
- break;
- }
- if (*a == '\0')
- return count;
- ++count;
- }
-
- return count;
-}
-#endif
-
-#ifndef __HAVE_ARCH_STRPBRK
-char * strpbrk(const char * cs,const char * ct)
-{
- const char *sc1,*sc2;
-
- for( sc1 = cs; *sc1 != '\0'; ++sc1) {
- for( sc2 = ct; *sc2 != '\0'; ++sc2) {
- if (*sc1 == *sc2)
- return (char *) sc1;
- }
- }
- return NULL;
-}
-#endif
-
-#ifndef __HAVE_ARCH_STRTOK
-char * strtok(char * s,const char * ct)
-{
- char *sbegin, *send;
-
- sbegin = s ? s : ___strtok;
- if (!sbegin) {
- return NULL;
- }
- sbegin += strspn(sbegin,ct);
- if (*sbegin == '\0') {
- ___strtok = NULL;
- return( NULL );
- }
- send = strpbrk( sbegin, ct);
- if (send && *send != '\0')
- *send++ = '\0';
- ___strtok = send;
- return (sbegin);
-}
-#endif
-
-struct proc_dir_entry proc_scsi;
-struct inode_operations proc_scsi_inode_operations;
-struct proc_dir_entry proc_net;
-struct inode_operations proc_net_inode_operations;
-
-int
-proc_register (struct proc_dir_entry *xxx1, struct proc_dir_entry *xxx2)
-{
- return 0;
-}
-
-int
-proc_unregister (struct proc_dir_entry *xxx1, int xxx2)
-{
- return 0;
-}
-
-void
-add_blkdev_randomness (int major)
-{
-}
-
-void
-do_gettimeofday (struct timeval *tv)
-{
- host_get_time (1, tv);
-}
-
-int
-dev_get_info (char *buffer, char **start, off_t offset, int length, int dummy)
-{
- return 0;
-}
diff --git a/i386/i386at/gpl/linux/linux_net.c b/i386/i386at/gpl/linux/linux_net.c
deleted file mode 100644
index 6a83a98f..00000000
--- a/i386/i386at/gpl/linux/linux_net.c
+++ /dev/null
@@ -1,520 +0,0 @@
-/*
- * Linux network driver support.
- *
- * Copyright (C) 1996 The University of Utah and the Computer Systems
- * Laboratory at the University of Utah (CSL)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Author: Shantanu Goel, University of Utah CSL
- */
-
-/*
- * INET An implementation of the TCP/IP protocol suite for the LINUX
- * operating system. INET is implemented using the BSD Socket
- * interface as the means of communication with the user level.
- *
- * Ethernet-type device handling.
- *
- * Version: @(#)eth.c 1.0.7 05/25/93
- *
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
- * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- * Mark Evans, <evansmp@uhura.aston.ac.uk>
- * Florian La Roche, <rzsfl@rz.uni-sb.de>
- * Alan Cox, <gw4pts@gw4pts.ampr.org>
- *
- * Fixes:
- * Mr Linux : Arp problems
- * Alan Cox : Generic queue tidyup (very tiny here)
- * Alan Cox : eth_header ntohs should be htons
- * Alan Cox : eth_rebuild_header missing an htons and
- * minor other things.
- * Tegge : Arp bug fixes.
- * Florian : Removed many unnecessary functions, code cleanup
- * and changes for new arp and skbuff.
- * Alan Cox : Redid header building to reflect new format.
- * Alan Cox : ARP only when compiled with CONFIG_INET
- * Greg Page : 802.2 and SNAP stuff.
- * Alan Cox : MAC layer pointers/new format.
- * Paul Gortmaker : eth_copy_and_sum shouldn't csum padding.
- * Alan Cox : Protect against forwarding explosions with
- * older network drivers and IFF_ALLMULTI
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <sys/types.h>
-
-#include <mach/mach_types.h>
-#include <mach/kern_return.h>
-#include <mach/mig_errors.h>
-#include <mach/port.h>
-#include <mach/vm_param.h>
-#include <mach/notify.h>
-
-#include <ipc/ipc_port.h>
-#include <ipc/ipc_space.h>
-
-#include <vm/vm_map.h>
-#include <vm/vm_kern.h>
-#include <vm/vm_page.h>
-
-#include <device/device_types.h>
-#include <device/device_port.h>
-#include <device/if_hdr.h>
-#include <device/if_ether.h>
-#include <device/if_hdr.h>
-#include <device/net_io.h>
-#include "device_reply.h"
-
-#include <i386at/dev_hdr.h>
-#include <i386at/device_emul.h>
-
-#include <i386at/gpl/linux/linux_emul.h>
-
-#define MACH_INCLUDE
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/malloc.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-
-/* One of these is associated with each instance of a device. */
-struct net_data
-{
- ipc_port_t port; /* device port */
- struct ifnet ifnet; /* Mach ifnet structure (needed for filters) */
- struct device device; /* generic device structure */
- struct linux_device *dev; /* Linux network device structure */
-};
-
-/* List of sk_buffs waiting to be freed. */
-static struct sk_buff_head skb_done_list;
-
-/* Forward declarations. */
-
-extern struct device_emulation_ops linux_net_emulation_ops;
-
-static int print_packet_size = 0;
-
-/* Linux kernel network support routines. */
-
-/* Requeue packet SKB for transmission after the interface DEV
- has timed out. The priority of the packet is PRI.
- In Mach, we simply drop the packet like the native drivers. */
-void
-dev_queue_xmit (struct sk_buff *skb, struct linux_device *dev, int pri)
-{
- dev_kfree_skb (skb, FREE_WRITE);
-}
-
-/* Close the device DEV. */
-int
-dev_close (struct linux_device *dev)
-{
- return 0;
-}
-
-/* Network software interrupt handler. */
-void
-net_bh (void *xxx)
-{
- int len;
- struct sk_buff *skb;
- struct linux_device *dev;
-
- /* Start transmission on interfaces. */
- for (dev = dev_base; dev; dev = dev->next)
- {
- if (dev->base_addr && dev->base_addr != 0xffe0)
- while (1)
- {
- skb = skb_dequeue (&dev->buffs[0]);
- if (skb)
- {
- len = skb->len;
- if ((*dev->hard_start_xmit) (skb, dev))
- {
- skb_queue_head (&dev->buffs[0], skb);
- mark_bh (NET_BH);
- break;
- }
- else if (print_packet_size)
- printf ("net_bh: length %d\n", len);
- }
- else
- break;
- }
- }
-}
-
-/* Free all sk_buffs on the done list.
- This routine is called by the iodone thread in ds_routines.c. */
-void
-free_skbuffs ()
-{
- struct sk_buff *skb;
-
- while (1)
- {
- skb = skb_dequeue (&skb_done_list);
- if (skb)
- {
- if (skb->copy)
- {
- vm_map_copy_discard (skb->copy);
- skb->copy = NULL;
- }
- if (IP_VALID (skb->reply))
- {
- ds_device_write_reply (skb->reply, skb->reply_type, 0, skb->len);
- skb->reply = IP_NULL;
- }
- dev_kfree_skb (skb, FREE_WRITE);
- }
- else
- break;
- }
-}
-
-/* Allocate an sk_buff with SIZE bytes of data space. */
-struct sk_buff *
-alloc_skb (unsigned int size, int priority)
-{
- return dev_alloc_skb (size);
-}
-
-/* Free SKB. */
-void
-kfree_skb (struct sk_buff *skb, int priority)
-{
- dev_kfree_skb (skb, priority);
-}
-
-/* Allocate an sk_buff with SIZE bytes of data space. */
-struct sk_buff *
-dev_alloc_skb (unsigned int size)
-{
- struct sk_buff *skb;
-
- skb = linux_kmalloc (sizeof (struct sk_buff) + size, GFP_KERNEL);
- if (skb)
- {
- skb->dev = NULL;
- skb->reply = IP_NULL;
- skb->copy = NULL;
- skb->len = size;
- skb->prev = skb->next = NULL;
- skb->list = NULL;
- if (size)
- {
- skb->data = (unsigned char *) (skb + 1);
- skb->tail = skb->data + size;
- }
- else
- skb->data = skb->tail = NULL;
- skb->head = skb->data;
- }
- return skb;
-}
-
-/* Free the sk_buff SKB. */
-void
-dev_kfree_skb (struct sk_buff *skb, int mode)
-{
- unsigned flags;
- extern void *io_done_list;
-
- /* Queue sk_buff on done list if there is a
- page list attached or we need to send a reply.
- Wakeup the iodone thread to process the list. */
- if (skb->copy || IP_VALID (skb->reply))
- {
- skb_queue_tail (&skb_done_list, skb);
- save_flags (flags);
- thread_wakeup ((event_t) &io_done_list);
- restore_flags (flags);
- return;
- }
- linux_kfree (skb);
-}
-
-/* Accept packet SKB received on an interface. */
-void
-netif_rx (struct sk_buff *skb)
-{
- ipc_kmsg_t kmsg;
- struct ether_header *eh;
- struct packet_header *ph;
- struct linux_device *dev = skb->dev;
-
- assert (skb != NULL);
-
- if (print_packet_size)
- printf ("netif_rx: length %d\n", skb->len);
-
- /* Allocate a kernel message buffer. */
- kmsg = net_kmsg_get ();
- if (! kmsg)
- {
- dev_kfree_skb (skb, FREE_READ);
- return;
- }
-
- /* Copy packet into message buffer. */
- eh = (struct ether_header *) (net_kmsg (kmsg)->header);
- ph = (struct packet_header *) (net_kmsg (kmsg)->packet);
- memcpy (eh, skb->data, sizeof (struct ether_header));
- memcpy (ph + 1, skb->data + sizeof (struct ether_header),
- skb->len - sizeof (struct ether_header));
- ph->type = eh->ether_type;
- ph->length = (skb->len - sizeof (struct ether_header)
- + sizeof (struct packet_header));
-
- dev_kfree_skb (skb, FREE_READ);
-
- /* Pass packet up to the microkernel. */
- net_packet (&dev->net_data->ifnet, kmsg,
- ph->length, ethernet_priority (kmsg));
-}
-
-/* Mach device interface routines. */
-
-/* Return a send right associated with network device ND. */
-static ipc_port_t
-dev_to_port (void *nd)
-{
- return (nd
- ? ipc_port_make_send (((struct net_data *) nd)->port)
- : IP_NULL);
-}
-
-static io_return_t
-device_open (ipc_port_t reply_port, mach_msg_type_name_t reply_port_type,
- dev_mode_t mode, char *name, device_t *devp)
-{
- io_return_t err = D_SUCCESS;
- ipc_port_t notify;
- struct ifnet *ifp;
- struct linux_device *dev;
- struct net_data *nd;
-
- /* Search for the device. */
- for (dev = dev_base; dev; dev = dev->next)
- if (dev->base_addr
- && dev->base_addr != 0xffe0
- && ! strcmp (name, dev->name))
- break;
- if (! dev)
- return D_NO_SUCH_DEVICE;
-
- /* Allocate and initialize device data if this is the first open. */
- nd = dev->net_data;
- if (! nd)
- {
- dev->net_data = nd = ((struct net_data *)
- kalloc (sizeof (struct net_data)));
- if (! nd)
- {
- err = D_NO_MEMORY;
- goto out;
- }
- nd->dev = dev;
- nd->device.emul_data = nd;
- nd->device.emul_ops = &linux_net_emulation_ops;
- nd->port = ipc_port_alloc_kernel ();
- if (nd->port == IP_NULL)
- {
- err = KERN_RESOURCE_SHORTAGE;
- goto out;
- }
- ipc_kobject_set (nd->port, (ipc_kobject_t) &nd->device, IKOT_DEVICE);
- notify = ipc_port_make_sonce (nd->port);
- ip_lock (nd->port);
- ipc_port_nsrequest (nd->port, 1, notify, &notify);
- assert (notify == IP_NULL);
-
- ifp = &nd->ifnet;
- ifp->if_unit = dev->name[strlen (dev->name) - 1] - '0';
- ifp->if_flags = IFF_UP|IFF_RUNNING;
- ifp->if_mtu = dev->mtu;
- ifp->if_header_size = dev->hard_header_len;
- ifp->if_header_format = dev->type;
- ifp->if_address_size = dev->addr_len;
- ifp->if_address = dev->dev_addr;
- if_init_queues (ifp);
-
- if (dev->open)
- {
- linux_intr_pri = SPL6;
- if ((*dev->open) (dev))
- err = D_NO_SUCH_DEVICE;
- }
-
- out:
- if (err)
- {
- if (nd)
- {
- if (nd->port != IP_NULL)
- {
- ipc_kobject_set (nd->port, IKO_NULL, IKOT_NONE);
- ipc_port_dealloc_kernel (nd->port);
- }
- kfree ((vm_offset_t) nd, sizeof (struct net_data));
- nd = NULL;
- dev->net_data = NULL;
- }
- }
- else
- {
- dev->flags |= LINUX_IFF_UP|LINUX_IFF_RUNNING;
- skb_queue_head_init (&dev->buffs[0]);
- }
- if (IP_VALID (reply_port))
- ds_device_open_reply (reply_port, reply_port_type,
- err, dev_to_port (nd));
- return MIG_NO_REPLY;
- }
-
- *devp = &nd->device;
- return D_SUCCESS;
-}
-
-static io_return_t
-device_write (void *d, ipc_port_t reply_port,
- mach_msg_type_name_t reply_port_type, dev_mode_t mode,
- recnum_t bn, io_buf_ptr_t data, unsigned int count,
- int *bytes_written)
-{
- unsigned char *p;
- int i, amt, skblen, s;
- io_return_t err = 0;
- vm_map_copy_t copy = (vm_map_copy_t) data;
- struct net_data *nd = d;
- struct linux_device *dev = nd->dev;
- struct sk_buff *skb;
-
- if (count == 0 || count > dev->mtu + dev->hard_header_len)
- return D_INVALID_SIZE;
-
- /* Allocate a sk_buff. */
- amt = PAGE_SIZE - (copy->offset & PAGE_MASK);
- skblen = (amt >= count) ? 0 : count;
- skb = dev_alloc_skb (skblen);
- if (! skb)
- return D_NO_MEMORY;
-
- /* Copy user data. This is only required if it spans multiple pages. */
- if (skblen == 0)
- {
- assert (copy->cpy_npages == 1);
-
- skb->copy = copy;
- skb->data = ((void *) copy->cpy_page_list[0]->phys_addr
- + (copy->offset & PAGE_MASK));
- skb->len = count;
- skb->head = skb->data;
- skb->tail = skb->data + skb->len;
- }
- else
- {
- memcpy (skb->data,
- ((void *) copy->cpy_page_list[0]->phys_addr
- + (copy->offset & PAGE_MASK)),
- amt);
- count -= amt;
- p = skb->data + amt;
- for (i = 1; count > 0 && i < copy->cpy_npages; i++)
- {
- amt = PAGE_SIZE;
- if (amt > count)
- amt = count;
- memcpy (p, (void *) copy->cpy_page_list[i]->phys_addr, amt);
- count -= amt;
- p += amt;
- }
-
- assert (count == 0);
-
- vm_map_copy_discard (copy);
- }
-
- skb->dev = dev;
- skb->reply = reply_port;
- skb->reply_type = reply_port_type;
-
- /* Queue packet for transmission and schedule a software interrupt. */
- s = splimp ();
- if (dev->buffs[0].next != (struct sk_buff *) &dev->buffs[0]
- || (*dev->hard_start_xmit) (skb, dev))
- {
- __skb_queue_tail (&dev->buffs[0], skb);
- mark_bh (NET_BH);
- }
- splx (s);
-
- return MIG_NO_REPLY;
-}
-
-static io_return_t
-device_get_status (void *d, dev_flavor_t flavor, dev_status_t status,
- mach_msg_type_number_t *count)
-{
- return net_getstat (&((struct net_data *) d)->ifnet, flavor, status, count);
-}
-
-static io_return_t
-device_set_filter (void *d, ipc_port_t port, int priority,
- filter_t *filter, unsigned filter_count)
-{
- return net_set_filter (&((struct net_data *) d)->ifnet,
- port, priority, filter, filter_count);
-}
-
-struct device_emulation_ops linux_net_emulation_ops =
-{
- NULL,
- NULL,
- dev_to_port,
- device_open,
- NULL,
- device_write,
- NULL,
- NULL,
- NULL,
- NULL,
- device_get_status,
- device_set_filter,
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-/* Do any initialization required for network devices. */
-void
-linux_net_emulation_init ()
-{
- skb_queue_head_init (&skb_done_list);
-}
diff --git a/i386/i386at/gpl/linux/linux_port.c b/i386/i386at/gpl/linux/linux_port.c
deleted file mode 100644
index 4a79c499..00000000
--- a/i386/i386at/gpl/linux/linux_port.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Linux I/O port management.
- * Copyright (C) 1995 Shantanu Goel.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/ioport.h>
-
-#define NPORTS 65536
-#define BITS_PER_WORD 32
-#define NWORDS (NPORTS / BITS_PER_WORD)
-
-/*
- * This bitmap keeps track of all allocated ports.
- * A bit is set if the port has been allocated.
- */
-static unsigned port_bitmap[NWORDS];
-
-void snarf_region(unsigned, unsigned);
-
-/*
- * Check if a region is available for use.
- */
-int
-check_region(unsigned port, unsigned size)
-{
- unsigned i;
-
- for (i = port; i < port + size; i++)
- if (port_bitmap[i/BITS_PER_WORD] & (1 << (i%BITS_PER_WORD)))
- return (1);
- return (0);
-}
-
-/*
- * Allocate a region.
- */
-void
-request_region(unsigned port, unsigned size, const char *name)
-{
- unsigned i;
-
- for (i = port; i < port + size; i++)
- port_bitmap[i / BITS_PER_WORD] |= 1 << (i % BITS_PER_WORD);
-}
-
-/*
- * For compatibility with older kernels.
- */
-void
-snarf_region(unsigned port, unsigned size)
-{
- request_region(port, size, 0);
-}
-
-/*
- * Deallocate a region.
- */
-void
-release_region(unsigned port, unsigned size)
-{
- unsigned i;
-
- for (i = port; i < port + size; i++)
- port_bitmap[i / BITS_PER_WORD] &= ~(1 << (i % BITS_PER_WORD));
-}
diff --git a/i386/i386at/gpl/linux/linux_printk.c b/i386/i386at/gpl/linux/linux_printk.c
deleted file mode 100644
index c4e489d2..00000000
--- a/i386/i386at/gpl/linux/linux_printk.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Linux kernel print routine.
- * Copyright (C) 1995 Shantanu Goel.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
- * linux/kernel/printk.c
- *
- * Copyright (C) 1991, 1992 Linus Torvalds
- */
-
-#include <stdarg.h>
-#include <asm/system.h>
-
-static char buf[2048];
-
-void
-printk(char *fmt, ...)
-{
- va_list args;
- int i, n, flags;
- extern void cnputc();
- extern int linux_vsprintf(char *buf, char *fmt, ...);
-
- save_flags(flags);
- cli();
- va_start(args, fmt);
- n = linux_vsprintf(buf, fmt, args);
- va_end(args);
- for (i = 0; i < n; i++)
- cnputc(buf[i]);
- restore_flags(flags);
-}
diff --git a/i386/i386at/gpl/linux/linux_sched.c b/i386/i386at/gpl/linux/linux_sched.c
deleted file mode 100644
index fdb0f693..00000000
--- a/i386/i386at/gpl/linux/linux_sched.c
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * Linux scheduling support.
- *
- * Copyright (C) 1996 The University of Utah and the Computer Systems
- * Laboratory at the University of Utah (CSL)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Author: Shantanu Goel, University of Utah CSL
- */
-
-/*
- * linux/kernel/sched.c
- *
- * Copyright (C) 1991, 1992 Linus Torvalds
- */
-
-#include <sys/types.h>
-
-#include <mach/boolean.h>
-
-#include <kern/thread.h>
-#include <kern/sched_prim.h>
-
-#include <i386at/gpl/linux/linux_emul.h>
-
-#define MACH_INCLUDE
-#include <linux/sched.h>
-#include <linux/fs.h>
-#include <linux/blkdev.h>
-
-#include <asm/system.h>
-
-struct tq_struct tq_last =
-{
- &tq_last, 0, 0, 0
-};
-
-DECLARE_TASK_QUEUE(tq_timer);
-
-static struct wait_queue **auto_config_queue;
-
-void
-tqueue_bh (void *unused)
-{
- run_task_queue(&tq_timer);
-}
-
-void
-add_wait_queue (struct wait_queue **q, struct wait_queue *wait)
-{
- unsigned long flags;
-
- if (! linux_auto_config)
- {
- save_flags (flags);
- cli ();
- assert_wait ((event_t) q, FALSE);
- restore_flags (flags);
- return;
- }
-
- if (auto_config_queue)
- printf ("add_wait_queue: queue not empty\n");
- auto_config_queue = q;
-}
-
-void
-remove_wait_queue (struct wait_queue **q, struct wait_queue *wait)
-{
- unsigned long flags;
-
- if (! linux_auto_config)
- {
- save_flags (flags);
- thread_wakeup ((event_t) q);
- restore_flags (flags);
- return;
- }
-
- auto_config_queue = NULL;
-}
-
-void
-__down (struct semaphore *sem)
-{
- int s;
- unsigned long flags;
-
- if (! linux_auto_config)
- {
- save_flags (flags);
- s = splhigh ();
- while (sem->count <= 0)
- {
- assert_wait ((event_t) &sem->wait, FALSE);
- splx (s);
- thread_block (0);
- s = splhigh ();
- }
- splx (s);
- restore_flags (flags);
- return;
- }
-
- while (sem->count <= 0)
- barrier ();
-}
-
-void
-__sleep_on (struct wait_queue **q, int interruptible)
-{
- unsigned long flags;
-
- if (! q)
- return;
- save_flags (flags);
- if (! linux_auto_config)
- {
- assert_wait ((event_t) q, interruptible);
- sti ();
- thread_block (0);
- restore_flags (flags);
- return;
- }
-
- add_wait_queue (q, NULL);
- sti ();
- while (auto_config_queue)
- barrier ();
- restore_flags (flags);
-}
-
-void
-sleep_on (struct wait_queue **q)
-{
- __sleep_on (q, FALSE);
-}
-
-void
-interruptible_sleep_on (struct wait_queue **q)
-{
- __sleep_on (q, TRUE);
-}
-
-void
-wake_up (struct wait_queue **q)
-{
- unsigned long flags;
-
- if (! linux_auto_config)
- {
- if (q != &wait_for_request)
- {
- save_flags (flags);
- thread_wakeup ((event_t) q);
- restore_flags (flags);
- }
- return;
- }
-
- if (auto_config_queue == q)
- auto_config_queue = NULL;
-}
-
-void
-__wait_on_buffer (struct buffer_head *bh)
-{
- unsigned long flags;
-
- save_flags (flags);
- if (! linux_auto_config)
- {
- while (1)
- {
- cli ();
- if (! buffer_locked (bh))
- break;
- bh->b_wait = (struct wait_queue *) 1;
- assert_wait ((event_t) bh, FALSE);
- sti ();
- thread_block (0);
- }
- restore_flags (flags);
- return;
- }
-
- sti ();
- while (buffer_locked (bh))
- barrier ();
- restore_flags (flags);
-}
-
-void
-unlock_buffer (struct buffer_head *bh)
-{
- unsigned long flags;
-
- save_flags (flags);
- cli ();
- clear_bit (BH_Lock, &bh->b_state);
- if (bh->b_wait && ! linux_auto_config)
- {
- bh->b_wait = NULL;
- thread_wakeup ((event_t) bh);
- }
- restore_flags (flags);
-}
-
-void
-schedule ()
-{
- if (! linux_auto_config)
- thread_block (0);
-}
-
-void
-cdrom_sleep (int t)
-{
- int xxx;
-
- assert_wait ((event_t) &xxx, TRUE);
- thread_set_timeout (t);
- thread_block (0);
-}
diff --git a/i386/i386at/gpl/linux/linux_soft.c b/i386/i386at/gpl/linux/linux_soft.c
deleted file mode 100644
index efcae987..00000000
--- a/i386/i386at/gpl/linux/linux_soft.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Linux software interrupts.
- * Copyright (C) 1995 Shantanu Goel.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
- * linux/kernel/softirq.c
- *
- * Copyright (C) 1992 Linus Torvalds
- */
-
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <asm/system.h>
-#include <asm/bitops.h>
-
-/*
- * Mask of pending interrupts.
- */
-unsigned long bh_active = 0;
-
-/*
- * Mask of enabled interrupts.
- */
-unsigned long bh_mask = 0;
-
-/*
- * List of software interrupt handlers.
- */
-struct bh_struct bh_base[32];
-
-
-/*
- * Software interrupt handler.
- */
-void
-linux_soft_intr()
-{
- unsigned long active;
- unsigned long mask, left;
- struct bh_struct *bh;
-
- bh = bh_base;
- active = bh_active & bh_mask;
- for (mask = 1, left = ~0;
- left & active; bh++, mask += mask, left += left) {
- if (mask & active) {
- void (*fn)(void *);
-
- bh_active &= ~mask;
- fn = bh->routine;
- if (fn == 0)
- goto bad_bh;
- (*fn)(bh->data);
- }
- }
- return;
- bad_bh:
- printf("linux_soft_intr: bad interrupt handler entry 0x%08lx\n", mask);
-}
diff --git a/i386/i386at/gpl/linux/linux_timer.c b/i386/i386at/gpl/linux/linux_timer.c
deleted file mode 100644
index c1575323..00000000
--- a/i386/i386at/gpl/linux/linux_timer.c
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Linux timers.
- *
- * Copyright (C) 1996 The University of Utah and the Computer Systems
- * Laboratory at the University of Utah (CSL)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Author: Shantanu Goel, University of Utah CSL
- */
-
-/*
- * linux/kernel/sched.c
- *
- * Copyright (C) 1991, 1992 Linus Torvalds
- */
-
-#include <linux/sched.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <asm/system.h>
-
-unsigned long volatile jiffies = 0;
-
-/*
- * Mask of active timers.
- */
-unsigned long timer_active = 0;
-
-/*
- * List of timeout routines.
- */
-struct timer_struct timer_table[32];
-
-/*
- * The head for the timer-list has a "expires" field of MAX_UINT,
- * and the sorting routine counts on this..
- */
-static struct timer_list timer_head =
-{
- &timer_head, &timer_head, ~0, 0, NULL
-};
-
-#define SLOW_BUT_DEBUGGING_TIMERS 0
-
-void
-add_timer(struct timer_list *timer)
-{
- unsigned long flags;
- struct timer_list *p;
-
-#if SLOW_BUT_DEBUGGING_TIMERS
- if (timer->next || timer->prev) {
- printk("add_timer() called with non-zero list from %p\n",
- __builtin_return_address(0));
- return;
- }
-#endif
- p = &timer_head;
- save_flags(flags);
- cli();
- do {
- p = p->next;
- } while (timer->expires > p->expires);
- timer->next = p;
- timer->prev = p->prev;
- p->prev = timer;
- timer->prev->next = timer;
- restore_flags(flags);
-}
-
-int
-del_timer(struct timer_list *timer)
-{
- unsigned long flags;
-#if SLOW_BUT_DEBUGGING_TIMERS
- struct timer_list * p;
-
- p = &timer_head;
- save_flags(flags);
- cli();
- while ((p = p->next) != &timer_head) {
- if (p == timer) {
- timer->next->prev = timer->prev;
- timer->prev->next = timer->next;
- timer->next = timer->prev = NULL;
- restore_flags(flags);
- return 1;
- }
- }
- if (timer->next || timer->prev)
- printk("del_timer() called from %p with timer not initialized\n",
- __builtin_return_address(0));
- restore_flags(flags);
- return 0;
-#else
- struct timer_list * next;
- int ret = 0;
- save_flags(flags);
- cli();
- if ((next = timer->next) != NULL) {
- (next->prev = timer->prev)->next = next;
- timer->next = timer->prev = NULL;
- ret = 1;
- }
- restore_flags(flags);
- return ret;
-#endif
-}
-
-/*
- * Timer software interrupt handler.
- */
-void
-timer_bh()
-{
- unsigned long mask;
- struct timer_struct *tp;
- struct timer_list * timer;
-
- cli();
- while ((timer = timer_head.next) != &timer_head
- && timer->expires <= jiffies) {
- void (*fn)(unsigned long) = timer->function;
- unsigned long data = timer->data;
-
- timer->next->prev = timer->prev;
- timer->prev->next = timer->next;
- timer->next = timer->prev = NULL;
- sti();
- fn(data);
- cli();
- }
- sti();
-
- for (mask = 1, tp = timer_table; mask; tp++, mask <<= 1) {
- if (mask > timer_active)
- break;
- if ((mask & timer_active)
- && tp->expires > jiffies) {
- timer_active &= ~mask;
- (*tp->fn)();
- sti();
- }
- }
-}
-
-int linux_timer_print = 0;
-
-/*
- * Timer interrupt handler.
- */
-void
-linux_timer_intr()
-{
- unsigned long mask;
- struct timer_struct *tp;
- extern int pic_mask[];
-
- jiffies++;
-
- for (mask = 1, tp = timer_table; mask; tp++, mask += mask) {
- if (mask > timer_active)
- break;
- if (!(mask & timer_active))
- continue;
- if (tp->expires > jiffies)
- continue;
- mark_bh(TIMER_BH);
- }
- if (timer_head.next->expires <= jiffies)
- mark_bh(TIMER_BH);
- if (tq_timer != &tq_last)
- mark_bh(TQUEUE_BH);
- if (linux_timer_print)
- printf ("linux_timer_intr: pic_mask[0] %x\n", pic_mask[0]);
-}
-
diff --git a/i386/i386at/gpl/linux/linux_version.c b/i386/i386at/gpl/linux/linux_version.c
deleted file mode 100644
index 0195c42f..00000000
--- a/i386/i386at/gpl/linux/linux_version.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 1996 The University of Utah and
- * the Computer Systems Laboratory at the University of Utah (CSL).
- * All rights reserved.
- *
- * Permission to use, copy, modify and distribute this software is hereby
- * granted provided that (1) source code retains these copyright, permission,
- * and disclaimer notices, and (2) redistributions including binaries
- * reproduce the notices in supporting documentation, and (3) all advertising
- * materials mentioning features or use of this software display the following
- * acknowledgement: ``This product includes software developed by the
- * Computer Systems Laboratory at the University of Utah.''
- *
- * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS
- * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF
- * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * CSL requests users of this software to return to csl-dist@cs.utah.edu any
- * improvements that they make and grant CSL redistribution rights.
- *
- * Author: Shantanu Goel, University of Utah CSL
- */
-
-#include <linux/utsname.h>
-#include <linux/string.h>
-
-struct new_utsname system_utsname;
-
-void
-linux_version_init ()
-{
- strcpy (system_utsname.version, "1.3.68");
-}
diff --git a/i386/i386at/gpl/linux/linux_vsprintf.c b/i386/i386at/gpl/linux/linux_vsprintf.c
deleted file mode 100644
index 236d38da..00000000
--- a/i386/i386at/gpl/linux/linux_vsprintf.c
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- * linux/kernel/vsprintf.c
- *
- * Copyright (C) 1991, 1992 Linus Torvalds
- */
-
-/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
-/*
- * Wirzenius wrote this portably, Torvalds fucked it up :-)
- */
-
-#include <stdarg.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-
-static inline
-isxdigit(c)
- char c;
-{
- return ((c >= '0' && c <= '9')
- || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'));
-}
-
-static inline
-islower(c)
- char c;
-{
- return (c >= 'a' && c <= 'z');
-}
-
-static inline
-toupper(c)
- char c;
-{
- return (islower(c) ? c - 'a' + 'A' : c);
-}
-
-static inline
-isdigit(c)
- char c;
-{
- return (c >= '0' && c <= '9');
-}
-
-unsigned long
-simple_strtoul(const char *cp,char **endp,unsigned int base)
-{
- unsigned long result = 0,value;
-
- if (!base) {
- base = 10;
- if (*cp == '0') {
- base = 8;
- cp++;
- if ((*cp == 'x') && isxdigit(cp[1])) {
- cp++;
- base = 16;
- }
- }
- }
- while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp)
- ? toupper(*cp) : *cp)-'A'+10) < base) {
- result = result*base + value;
- cp++;
- }
- if (endp)
- *endp = (char *)cp;
- return result;
-}
-
-/* we use this so that we can do without the ctype library */
-#define is_digit(c) ((c) >= '0' && (c) <= '9')
-
-static int
-skip_atoi(const char **s)
-{
- int i=0;
-
- while (is_digit(**s))
- i = i*10 + *((*s)++) - '0';
- return i;
-}
-
-#define ZEROPAD 1 /* pad with zero */
-#define SIGN 2 /* unsigned/signed long */
-#define PLUS 4 /* show plus */
-#define SPACE 8 /* space if plus */
-#define LEFT 16 /* left justified */
-#define SPECIAL 32 /* 0x */
-#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
-
-#define do_div(n,base) ({ \
-int __res; \
-__res = ((unsigned long) n) % (unsigned) base; \
-n = ((unsigned long) n) / (unsigned) base; \
-__res; })
-
-static char *
-number(char * str, long num, int base, int size, int precision, int type)
-{
- char c,sign,tmp[36];
- const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
- int i;
-
- if (type & LARGE)
- digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
- if (type & LEFT)
- type &= ~ZEROPAD;
- if (base < 2 || base > 36)
- return 0;
- c = (type & ZEROPAD) ? '0' : ' ';
- sign = 0;
- if (type & SIGN) {
- if (num < 0) {
- sign = '-';
- num = -num;
- size--;
- } else if (type & PLUS) {
- sign = '+';
- size--;
- } else if (type & SPACE) {
- sign = ' ';
- size--;
- }
- }
- if (type & SPECIAL) {
- if (base == 16)
- size -= 2;
- else if (base == 8)
- size--;
- }
- i = 0;
- if (num == 0)
- tmp[i++]='0';
- else while (num != 0)
- tmp[i++] = digits[do_div(num,base)];
- if (i > precision)
- precision = i;
- size -= precision;
- if (!(type&(ZEROPAD+LEFT)))
- while(size-->0)
- *str++ = ' ';
- if (sign)
- *str++ = sign;
- if (type & SPECIAL)
- if (base==8)
- *str++ = '0';
- else if (base==16) {
- *str++ = '0';
- *str++ = digits[33];
- }
- if (!(type & LEFT))
- while (size-- > 0)
- *str++ = c;
- while (i < precision--)
- *str++ = '0';
- while (i-- > 0)
- *str++ = tmp[i];
- while (size-- > 0)
- *str++ = ' ';
- return str;
-}
-
-int
-linux_vsprintf(char *buf, const char *fmt, va_list args)
-{
- int len;
- unsigned long num;
- int i, base;
- char * str;
- char *s;
-
- int flags; /* flags to number() */
-
- int field_width; /* width of output field */
- int precision; /* min. # of digits for integers; max
- number of chars for from string */
- int qualifier; /* 'h', 'l', or 'L' for integer fields */
-
- for (str=buf ; *fmt ; ++fmt) {
- if (*fmt != '%') {
- *str++ = *fmt;
- continue;
- }
-
- /* process flags */
- flags = 0;
- repeat:
- ++fmt; /* this also skips first '%' */
- switch (*fmt) {
- case '-': flags |= LEFT; goto repeat;
- case '+': flags |= PLUS; goto repeat;
- case ' ': flags |= SPACE; goto repeat;
- case '#': flags |= SPECIAL; goto repeat;
- case '0': flags |= ZEROPAD; goto repeat;
- }
-
- /* get field width */
- field_width = -1;
- if (is_digit(*fmt))
- field_width = skip_atoi(&fmt);
- else if (*fmt == '*') {
- ++fmt;
- /* it's the next argument */
- field_width = va_arg(args, int);
- if (field_width < 0) {
- field_width = -field_width;
- flags |= LEFT;
- }
- }
-
- /* get the precision */
- precision = -1;
- if (*fmt == '.') {
- ++fmt;
- if (is_digit(*fmt))
- precision = skip_atoi(&fmt);
- else if (*fmt == '*') {
- ++fmt;
- /* it's the next argument */
- precision = va_arg(args, int);
- }
- if (precision < 0)
- precision = 0;
- }
-
- /* get the conversion qualifier */
- qualifier = -1;
- if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') {
- qualifier = *fmt;
- ++fmt;
- }
-
- /* default base */
- base = 10;
-
- switch (*fmt) {
- case 'c':
- if (!(flags & LEFT))
- while (--field_width > 0)
- *str++ = ' ';
- *str++ = (unsigned char) va_arg(args, int);
- while (--field_width > 0)
- *str++ = ' ';
- continue;
-
- case 's':
- s = va_arg(args, char *);
- if (!s)
- s = "<NULL>";
- len = strlen(s);
- if (precision < 0)
- precision = len;
- else if (len > precision)
- len = precision;
-
- if (!(flags & LEFT))
- while (len < field_width--)
- *str++ = ' ';
- for (i = 0; i < len; ++i)
- *str++ = *s++;
- while (len < field_width--)
- *str++ = ' ';
- continue;
-
- case 'p':
- if (field_width == -1) {
- field_width = 2*sizeof(void *);
- flags |= ZEROPAD;
- }
- str = number(str,
- (unsigned long) va_arg(args, void *), 16,
- field_width, precision, flags);
- continue;
-
-
- case 'n':
- if (qualifier == 'l') {
- long * ip = va_arg(args, long *);
- *ip = (str - buf);
- } else {
- int * ip = va_arg(args, int *);
- *ip = (str - buf);
- }
- continue;
-
- /* integer number formats - set up the flags and "break" */
- case 'o':
- base = 8;
- break;
-
- case 'X':
- flags |= LARGE;
- case 'x':
- base = 16;
- break;
-
- case 'd':
- case 'i':
- flags |= SIGN;
- case 'u':
- break;
-
- default:
- if (*fmt != '%')
- *str++ = '%';
- if (*fmt)
- *str++ = *fmt;
- else
- --fmt;
- continue;
- }
- if (qualifier == 'l')
- num = va_arg(args, unsigned long);
- else if (qualifier == 'h')
- if (flags & SIGN)
- num = va_arg(args, short);
- else
- num = va_arg(args, unsigned short);
- else if (flags & SIGN)
- num = va_arg(args, int);
- else
- num = va_arg(args, unsigned int);
- str = number(str, num, base, field_width, precision, flags);
- }
- *str = '\0';
- return str-buf;
-}
-
-int
-linux_sprintf(char * buf, const char *fmt, ...)
-{
- va_list args;
- int i;
-
- va_start(args, fmt);
- i = linux_vsprintf(buf, fmt, args);
- va_end(args);
- return i;
-}
diff --git a/i386/i386at/gpl/linux/net/3c501.c b/i386/i386at/gpl/linux/net/3c501.c
deleted file mode 100644
index 6f8dceb6..00000000
--- a/i386/i386at/gpl/linux/net/3c501.c
+++ /dev/null
@@ -1,860 +0,0 @@
-/* 3c501.c: A 3Com 3c501 ethernet driver for linux. */
-/*
- Written 1992,1993,1994 Donald Becker
-
- Copyright 1993 United States Government as represented by the
- Director, National Security Agency. This software may be used and
- distributed according to the terms of the GNU Public License,
- incorporated herein by reference.
-
- This is a device driver for the 3Com Etherlink 3c501.
- Do not purchase this card, even as a joke. It's performance is horrible,
- and it breaks in many ways.
-
- The author may be reached as becker@CESDIS.gsfc.nasa.gov, or C/O
- Center of Excellence in Space Data and Information Sciences
- Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
-
- Fixed (again!) the missing interrupt locking on TX/RX shifting.
- Alan Cox <Alan.Cox@linux.org>
-
- Removed calls to init_etherdev since they are no longer needed, and
- cleaned up modularization just a bit. The driver still allows only
- the default address for cards when loaded as a module, but that's
- really less braindead than anyone using a 3c501 board. :)
- 19950208 (invid@msen.com)
-
- Added traps for interrupts hitting the window as we clear and TX load
- the board. Now getting 150K/second FTP with a 3c501 card. Still playing
- with a TX-TX optimisation to see if we can touch 180-200K/second as seems
- theoretically maximum.
- 19950402 Alan Cox <Alan.Cox@linux.org>
-
- Some notes on this thing if you have to hack it. [Alan]
-
- 1] Some documentation is available from 3Com. Due to the boards age
- standard responses when you ask for this will range from 'be serious'
- to 'give it to a museum'. The documentation is incomplete and mostly
- of historical interest anyway.
-
- 2] The basic system is a single buffer which can be used to receive or
- transmit a packet. A third command mode exists when you are setting
- things up.
-
- 3] If it's transmitting it's not receiving and vice versa. In fact the
- time to get the board back into useful state after an operation is
- quite large.
-
- 4] The driver works by keeping the board in receive mode waiting for a
- packet to arrive. When one arrives it is copied out of the buffer
- and delivered to the kernel. The card is reloaded and off we go.
-
- 5] When transmitting dev->tbusy is set and the card is reset (from
- receive mode) [possibly losing a packet just received] to command
- mode. A packet is loaded and transmit mode triggered. The interrupt
- handler runs different code for transmit interrupts and can handle
- returning to receive mode or retransmissions (yes you have to help
- out with those too).
-
- Problems:
- There are a wide variety of undocumented error returns from the card
- and you basically have to kick the board and pray if they turn up. Most
- only occur under extreme load or if you do something the board doesn't
- like (eg touching a register at the wrong time).
-
- The driver is less efficient than it could be. It switches through
- receive mode even if more transmits are queued. If this worries you buy
- a real ethernet card.
-
- The combination of slow receive restart and no real multicast
- filter makes the board unusable with a kernel compiled for IP
- multicasting in a real multicast environment. Thats down to the board,
- but even with no multicast programs running a multicast IP kernel is
- in group 224.0.0.1 and you will therefore be listening to all multicasts.
- One nv conference running over that ethernet and you can give up.
-
-*/
-
-static const char *version =
- "3c501.c: 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov).\n";
-
-/*
- * Braindamage remaining:
- * The 3c501 board.
- */
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-#include <linux/fcntl.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/malloc.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/errno.h>
-#include <linux/config.h> /* for CONFIG_IP_MULTICAST */
-
-#include <asm/bitops.h>
-#include <asm/io.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-
-#define BLOCKOUT_2
-
-/* A zero-terminated list of I/O addresses to be probed.
- The 3c501 can be at many locations, but here are the popular ones. */
-static unsigned int netcard_portlist[] =
- { 0x280, 0x300, 0};
-
-
-/*
- * Index to functions.
- */
-
-int el1_probe(struct device *dev);
-static int el1_probe1(struct device *dev, int ioaddr);
-static int el_open(struct device *dev);
-static int el_start_xmit(struct sk_buff *skb, struct device *dev);
-static void el_interrupt(int irq, struct pt_regs *regs);
-static void el_receive(struct device *dev);
-static void el_reset(struct device *dev);
-static int el1_close(struct device *dev);
-static struct enet_statistics *el1_get_stats(struct device *dev);
-static void set_multicast_list(struct device *dev);
-
-#define EL1_IO_EXTENT 16
-
-#ifndef EL_DEBUG
-#define EL_DEBUG 0 /* use 0 for production, 1 for devel., >2 for debug */
-#endif /* Anything above 5 is wordy death! */
-static int el_debug = EL_DEBUG;
-
-/*
- * Board-specific info in dev->priv.
- */
-
-struct net_local
-{
- struct enet_statistics stats;
- int tx_pkt_start; /* The length of the current Tx packet. */
- int collisions; /* Tx collisions this packet */
- int loading; /* Spot buffer load collisions */
-};
-
-
-#define RX_STATUS (ioaddr + 0x06)
-#define RX_CMD RX_STATUS
-#define TX_STATUS (ioaddr + 0x07)
-#define TX_CMD TX_STATUS
-#define GP_LOW (ioaddr + 0x08)
-#define GP_HIGH (ioaddr + 0x09)
-#define RX_BUF_CLR (ioaddr + 0x0A)
-#define RX_LOW (ioaddr + 0x0A)
-#define RX_HIGH (ioaddr + 0x0B)
-#define SAPROM (ioaddr + 0x0C)
-#define AX_STATUS (ioaddr + 0x0E)
-#define AX_CMD AX_STATUS
-#define DATAPORT (ioaddr + 0x0F)
-#define TX_RDY 0x08 /* In TX_STATUS */
-
-#define EL1_DATAPTR 0x08
-#define EL1_RXPTR 0x0A
-#define EL1_SAPROM 0x0C
-#define EL1_DATAPORT 0x0f
-
-/*
- * Writes to the ax command register.
- */
-
-#define AX_OFF 0x00 /* Irq off, buffer access on */
-#define AX_SYS 0x40 /* Load the buffer */
-#define AX_XMIT 0x44 /* Transmit a packet */
-#define AX_RX 0x48 /* Receive a packet */
-#define AX_LOOP 0x0C /* Loopback mode */
-#define AX_RESET 0x80
-
-/*
- * Normal receive mode written to RX_STATUS. We must intr on short packets
- * to avoid bogus rx lockups.
- */
-
-#define RX_NORM 0xA8 /* 0x68 == all addrs, 0xA8 only to me. */
-#define RX_PROM 0x68 /* Senior Prom, uhmm promiscuous mode. */
-#define RX_MULT 0xE8 /* Accept multicast packets. */
-#define TX_NORM 0x0A /* Interrupt on everything that might hang the chip */
-
-/*
- * TX_STATUS register.
- */
-
-#define TX_COLLISION 0x02
-#define TX_16COLLISIONS 0x04
-#define TX_READY 0x08
-
-#define RX_RUNT 0x08
-#define RX_MISSED 0x01 /* Missed a packet due to 3c501 braindamage. */
-#define RX_GOOD 0x30 /* Good packet 0x20, or simple overflow 0x10. */
-
-
-/*
- * The boilerplate probe code.
- */
-
-#ifdef HAVE_DEVLIST
-struct netdev_entry el1_drv = {"3c501", el1_probe1, EL1_IO_EXTENT, netcard_portlist};
-#else
-
-int el1_probe(struct device *dev)
-{
- int i;
- int base_addr = dev ? dev->base_addr : 0;
-
- if (base_addr > 0x1ff) /* Check a single specified location. */
- return el1_probe1(dev, base_addr);
- else if (base_addr != 0) /* Don't probe at all. */
- return ENXIO;
-
- for (i = 0; netcard_portlist[i]; i++)
- {
- int ioaddr = netcard_portlist[i];
- if (check_region(ioaddr, EL1_IO_EXTENT))
- continue;
- if (el1_probe1(dev, ioaddr) == 0)
- return 0;
- }
-
- return ENODEV;
-}
-#endif
-
-/*
- * The actual probe.
- */
-
-static int el1_probe1(struct device *dev, int ioaddr)
-{
-#ifndef MODULE
-
- const char *mname; /* Vendor name */
- unsigned char station_addr[6];
- int autoirq = 0;
- int i;
-
- /*
- * Read the station address PROM data from the special port.
- */
-
- for (i = 0; i < 6; i++)
- {
- outw(i, ioaddr + EL1_DATAPTR);
- station_addr[i] = inb(ioaddr + EL1_SAPROM);
- }
- /*
- * Check the first three octets of the S.A. for 3Com's prefix, or
- * for the Sager NP943 prefix.
- */
-
- if (station_addr[0] == 0x02 && station_addr[1] == 0x60
- && station_addr[2] == 0x8c)
- {
- mname = "3c501";
- } else if (station_addr[0] == 0x00 && station_addr[1] == 0x80
- && station_addr[2] == 0xC8)
- {
- mname = "NP943";
- }
- else
- return ENODEV;
-
- /*
- * Grab the region so we can find the another board if autoIRQ fails.
- */
-
- request_region(ioaddr, EL1_IO_EXTENT,"3c501");
-
- /*
- * We auto-IRQ by shutting off the interrupt line and letting it float
- * high.
- */
-
- if (dev->irq < 2)
- {
- autoirq_setup(2);
- inb(RX_STATUS); /* Clear pending interrupts. */
- inb(TX_STATUS);
- outb(AX_LOOP + 1, AX_CMD);
-
- outb(0x00, AX_CMD);
-
- autoirq = autoirq_report(1);
-
- if (autoirq == 0)
- {
- printk("%s probe at %#x failed to detect IRQ line.\n",
- mname, ioaddr);
- return EAGAIN;
- }
- }
-
- outb(AX_RESET+AX_LOOP, AX_CMD); /* Loopback mode. */
- dev->base_addr = ioaddr;
- memcpy(dev->dev_addr, station_addr, ETH_ALEN);
-
- if (dev->mem_start & 0xf)
- el_debug = dev->mem_start & 0x7;
- if (autoirq)
- dev->irq = autoirq;
-
- printk("%s: %s EtherLink at %#lx, using %sIRQ %d.\n", dev->name, mname, dev->base_addr,
- autoirq ? "auto":"assigned ", dev->irq);
-
-#ifdef CONFIG_IP_MULTICAST
- printk("WARNING: Use of the 3c501 in a multicast kernel is NOT recommended.\n");
-#endif
-
- if (el_debug)
- printk("%s", version);
-
- /*
- * Initialize the device structure.
- */
-
- dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
- if (dev->priv == NULL)
- return -ENOMEM;
- memset(dev->priv, 0, sizeof(struct net_local));
-
- /*
- * The EL1-specific entries in the device structure.
- */
-
- dev->open = &el_open;
- dev->hard_start_xmit = &el_start_xmit;
- dev->stop = &el1_close;
- dev->get_stats = &el1_get_stats;
- dev->set_multicast_list = &set_multicast_list;
-
- /*
- * Setup the generic properties
- */
-
- ether_setup(dev);
-
-#endif /* !MODULE */
-
- return 0;
-}
-
-/*
- * Open/initialize the board.
- */
-
-static int el_open(struct device *dev)
-{
- int ioaddr = dev->base_addr;
-
- if (el_debug > 2)
- printk("%s: Doing el_open()...", dev->name);
-
- if (request_irq(dev->irq, &el_interrupt, 0, "3c501"))
- return -EAGAIN;
-
- irq2dev_map[dev->irq] = dev;
- el_reset(dev);
-
- dev->start = 1;
-
- outb(AX_RX, AX_CMD); /* Aux control, irq and receive enabled */
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-static int el_start_xmit(struct sk_buff *skb, struct device *dev)
-{
- struct net_local *lp = (struct net_local *)dev->priv;
- int ioaddr = dev->base_addr;
- unsigned long flags;
-
- if(dev->interrupt) /* May be unloading, don't stamp on */
- return 1; /* the packet buffer this time */
-
- if (dev->tbusy)
- {
- if (jiffies - dev->trans_start < 20)
- {
- if (el_debug > 2)
- printk(" transmitter busy, deferred.\n");
- return 1;
- }
- if (el_debug)
- printk ("%s: transmit timed out, txsr %#2x axsr=%02x rxsr=%02x.\n",
- dev->name, inb(TX_STATUS), inb(AX_STATUS), inb(RX_STATUS));
- lp->stats.tx_errors++;
- outb(TX_NORM, TX_CMD);
- outb(RX_NORM, RX_CMD);
- outb(AX_OFF, AX_CMD); /* Just trigger a false interrupt. */
- outb(AX_RX, AX_CMD); /* Aux control, irq and receive enabled */
- dev->tbusy = 0;
- dev->trans_start = jiffies;
- }
-
- if (skb == NULL)
- {
- dev_tint(dev);
- return 0;
- }
-
- save_flags(flags);
-
- /*
- * Avoid incoming interrupts between us flipping tbusy and flipping
- * mode as the driver assumes tbusy is a faithful indicator of card
- * state
- */
-
- cli();
-
- /*
- * Avoid timer-based retransmission conflicts.
- */
-
- if (set_bit(0, (void*)&dev->tbusy) != 0)
- {
- restore_flags(flags);
- printk("%s: Transmitter access conflict.\n", dev->name);
- }
- else
- {
- int gp_start = 0x800 - (ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN);
- unsigned char *buf = skb->data;
-
-load_it_again_sam:
- lp->tx_pkt_start = gp_start;
- lp->collisions = 0;
-
- /*
- * Command mode with status cleared should [in theory]
- * mean no more interrupts can be pending on the card.
- */
-
-#ifdef BLOCKOUT_1
- disable_irq(dev->irq);
-#endif
- outb_p(AX_SYS, AX_CMD);
- inb_p(RX_STATUS);
- inb_p(TX_STATUS);
-
- lp->loading=1;
-
- /*
- * Turn interrupts back on while we spend a pleasant afternoon
- * loading bytes into the board
- */
-
- restore_flags(flags);
- outw(0x00, RX_BUF_CLR); /* Set rx packet area to 0. */
- outw(gp_start, GP_LOW); /* aim - packet will be loaded into buffer start */
- outsb(DATAPORT,buf,skb->len); /* load buffer (usual thing each byte increments the pointer) */
- outw(gp_start, GP_LOW); /* the board reuses the same register */
-#ifndef BLOCKOUT_1
- if(lp->loading==2) /* A receive upset our load, despite our best efforts */
- {
- if(el_debug>2)
- printk("%s: burped during tx load.\n", dev->name);
- goto load_it_again_sam; /* Sigh... */
- }
-#endif
- outb(AX_XMIT, AX_CMD); /* fire ... Trigger xmit. */
- lp->loading=0;
-#ifdef BLOCKOUT_1
- enable_irq(dev->irq);
-#endif
- dev->trans_start = jiffies;
- }
-
- if (el_debug > 2)
- printk(" queued xmit.\n");
- dev_kfree_skb (skb, FREE_WRITE);
- return 0;
-}
-
-
-/*
- * The typical workload of the driver:
- * Handle the ether interface interrupts.
- */
-
-static void el_interrupt(int irq, struct pt_regs *regs)
-{
- struct device *dev = (struct device *)(irq2dev_map[irq]);
- struct net_local *lp;
- int ioaddr;
- int axsr; /* Aux. status reg. */
-
- if (dev == NULL || dev->irq != irq)
- {
- printk ("3c501 driver: irq %d for unknown device.\n", irq);
- return;
- }
-
- ioaddr = dev->base_addr;
- lp = (struct net_local *)dev->priv;
-
- /*
- * What happened ?
- */
-
- axsr = inb(AX_STATUS);
-
- /*
- * Log it
- */
-
- if (el_debug > 3)
- printk("%s: el_interrupt() aux=%#02x", dev->name, axsr);
- if (dev->interrupt)
- printk("%s: Reentering the interrupt driver!\n", dev->name);
- dev->interrupt = 1;
-#ifndef BLOCKOUT_1
- if(lp->loading==1 && !dev->tbusy)
- printk("%s: Inconsistent state loading while not in tx\n",
- dev->name);
-#endif
-#ifdef BLOCKOUT_3
- lp->loading=2; /* So we can spot loading interruptions */
-#endif
-
- if (dev->tbusy)
- {
-
- /*
- * Board in transmit mode. May be loading. If we are
- * loading we shouldn't have got this.
- */
-
- int txsr = inb(TX_STATUS);
-#ifdef BLOCKOUT_2
- if(lp->loading==1)
- {
- if(el_debug > 2)
- {
- printk("%s: Interrupt while loading [", dev->name);
- printk(" txsr=%02x gp=%04x rp=%04x]\n", txsr, inw(GP_LOW),inw(RX_LOW));
- }
- lp->loading=2; /* Force a reload */
- dev->interrupt = 0;
- return;
- }
-#endif
- if (el_debug > 6)
- printk(" txsr=%02x gp=%04x rp=%04x", txsr, inw(GP_LOW),inw(RX_LOW));
-
- if ((axsr & 0x80) && (txsr & TX_READY) == 0)
- {
- /*
- * FIXME: is there a logic to whether to keep on trying or
- * reset immediately ?
- */
- printk("%s: Unusual interrupt during Tx, txsr=%02x axsr=%02x"
- " gp=%03x rp=%03x.\n", dev->name, txsr, axsr,
- inw(ioaddr + EL1_DATAPTR), inw(ioaddr + EL1_RXPTR));
- dev->tbusy = 0;
- mark_bh(NET_BH);
- }
- else if (txsr & TX_16COLLISIONS)
- {
- /*
- * Timed out
- */
- if (el_debug)
- printk("%s: Transmit failed 16 times, ethernet jammed?\n",dev->name);
- outb(AX_SYS, AX_CMD);
- lp->stats.tx_aborted_errors++;
- }
- else if (txsr & TX_COLLISION)
- {
- /*
- * Retrigger xmit.
- */
-
- if (el_debug > 6)
- printk(" retransmitting after a collision.\n");
- /*
- * Poor little chip can't reset its own start pointer
- */
-
- outb(AX_SYS, AX_CMD);
- outw(lp->tx_pkt_start, GP_LOW);
- outb(AX_XMIT, AX_CMD);
- lp->stats.collisions++;
- dev->interrupt = 0;
- return;
- }
- else
- {
- /*
- * It worked.. we will now fall through and receive
- */
- lp->stats.tx_packets++;
- if (el_debug > 6)
- printk(" Tx succeeded %s\n",
- (txsr & TX_RDY) ? "." : "but tx is busy!");
- /*
- * This is safe the interrupt is atomic WRT itself.
- */
-
- dev->tbusy = 0;
- mark_bh(NET_BH); /* In case more to transmit */
- }
- }
- else
- {
- /*
- * In receive mode.
- */
-
- int rxsr = inb(RX_STATUS);
- if (el_debug > 5)
- printk(" rxsr=%02x txsr=%02x rp=%04x", rxsr, inb(TX_STATUS),inw(RX_LOW));
- /*
- * Just reading rx_status fixes most errors.
- */
- if (rxsr & RX_MISSED)
- lp->stats.rx_missed_errors++;
- else if (rxsr & RX_RUNT)
- { /* Handled to avoid board lock-up. */
- lp->stats.rx_length_errors++;
- if (el_debug > 5)
- printk(" runt.\n");
- }
- else if (rxsr & RX_GOOD)
- {
- /*
- * Receive worked.
- */
- el_receive(dev);
- }
- else
- {
- /*
- * Nothing? Something is broken!
- */
- if (el_debug > 2)
- printk("%s: No packet seen, rxsr=%02x **resetting 3c501***\n",
- dev->name, rxsr);
- el_reset(dev);
- }
- if (el_debug > 3)
- printk(".\n");
- }
-
- /*
- * Move into receive mode
- */
-
- outb(AX_RX, AX_CMD);
- outw(0x00, RX_BUF_CLR);
- inb(RX_STATUS); /* Be certain that interrupts are cleared. */
- inb(TX_STATUS);
- dev->interrupt = 0;
- return;
-}
-
-
-/*
- * We have a good packet. Well, not really "good", just mostly not broken.
- * We must check everything to see if it is good.
- */
-
-static void el_receive(struct device *dev)
-{
- struct net_local *lp = (struct net_local *)dev->priv;
- int ioaddr = dev->base_addr;
- int pkt_len;
- struct sk_buff *skb;
-
- pkt_len = inw(RX_LOW);
-
- if (el_debug > 4)
- printk(" el_receive %d.\n", pkt_len);
-
- if ((pkt_len < 60) || (pkt_len > 1536))
- {
- if (el_debug)
- printk("%s: bogus packet, length=%d\n", dev->name, pkt_len);
- lp->stats.rx_over_errors++;
- return;
- }
-
- /*
- * Command mode so we can empty the buffer
- */
-
- outb(AX_SYS, AX_CMD);
- skb = dev_alloc_skb(pkt_len+2);
-
- /*
- * Start of frame
- */
-
- outw(0x00, GP_LOW);
- if (skb == NULL)
- {
- printk("%s: Memory squeeze, dropping packet.\n", dev->name);
- lp->stats.rx_dropped++;
- return;
- }
- else
- {
- skb_reserve(skb,2); /* Force 16 byte alignment */
- skb->dev = dev;
- /*
- * The read increments through the bytes. The interrupt
- * handler will fix the pointer when it returns to
- * receive mode.
- */
- insb(DATAPORT, skb_put(skb,pkt_len), pkt_len);
- skb->protocol=eth_type_trans(skb,dev);
- netif_rx(skb);
- lp->stats.rx_packets++;
- }
- return;
-}
-
-static void el_reset(struct device *dev)
-{
- int ioaddr = dev->base_addr;
-
- if (el_debug> 2)
- printk("3c501 reset...");
- outb(AX_RESET, AX_CMD); /* Reset the chip */
- outb(AX_LOOP, AX_CMD); /* Aux control, irq and loopback enabled */
- {
- int i;
- for (i = 0; i < 6; i++) /* Set the station address. */
- outb(dev->dev_addr[i], ioaddr + i);
- }
-
- outw(0, RX_BUF_CLR); /* Set rx packet area to 0. */
- cli(); /* Avoid glitch on writes to CMD regs */
- outb(TX_NORM, TX_CMD); /* tx irq on done, collision */
- outb(RX_NORM, RX_CMD); /* Set Rx commands. */
- inb(RX_STATUS); /* Clear status. */
- inb(TX_STATUS);
- dev->interrupt = 0;
- dev->tbusy = 0;
- sti();
-}
-
-static int el1_close(struct device *dev)
-{
- int ioaddr = dev->base_addr;
-
- if (el_debug > 2)
- printk("%s: Shutting down ethercard at %#x.\n", dev->name, ioaddr);
-
- dev->tbusy = 1;
- dev->start = 0;
-
- /*
- * Free and disable the IRQ.
- */
-
- free_irq(dev->irq);
- outb(AX_RESET, AX_CMD); /* Reset the chip */
- irq2dev_map[dev->irq] = 0;
-
- MOD_DEC_USE_COUNT;
- return 0;
-}
-
-static struct enet_statistics *el1_get_stats(struct device *dev)
-{
- struct net_local *lp = (struct net_local *)dev->priv;
- return &lp->stats;
-}
-
-/*
- * Set or clear the multicast filter for this adaptor.
- * best-effort filtering.
- */
-
-static void set_multicast_list(struct device *dev)
-{
- int ioaddr = dev->base_addr;
-
- if(dev->flags&IFF_PROMISC)
- {
- outb(RX_PROM, RX_CMD);
- inb(RX_STATUS);
- }
- else if (dev->mc_list || dev->flags&IFF_ALLMULTI)
- {
- outb(RX_MULT, RX_CMD); /* Multicast or all multicast is the same */
- inb(RX_STATUS); /* Clear status. */
- }
- else
- {
- outb(RX_NORM, RX_CMD);
- inb(RX_STATUS);
- }
-}
-
-#ifdef MODULE
-
-static char devicename[9] = { 0, };
-
-static struct device dev_3c501 =
-{
- devicename, /* device name is inserted by linux/drivers/net/net_init.c */
- 0, 0, 0, 0,
- 0x280, 5,
- 0, 0, 0, NULL, el1_probe
-};
-
-static int io=0x280;
-static int irq=5;
-
-int init_module(void)
-{
- dev_3c501.irq=irq;
- dev_3c501.base_addr=io;
- if (register_netdev(&dev_3c501) != 0)
- return -EIO;
- return 0;
-}
-
-void cleanup_module(void)
-{
- /*
- * No need to check MOD_IN_USE, as sys_delete_module() checks.
- */
-
- unregister_netdev(&dev_3c501);
-
- /*
- * Free up the private structure, or leak memory :-)
- */
-
- kfree(dev_3c501.priv);
- dev_3c501.priv = NULL; /* gets re-allocated by el1_probe1 */
-
- /*
- * If we don't do this, we can't re-insmod it later.
- */
- release_region(dev_3c501.base_addr, EL1_IO_EXTENT);
-}
-
-#endif /* MODULE */
-
-/*
- * Local variables:
- * compile-command: "gcc -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -m486 -c -o 3c501.o 3c501.c"
- * kept-new-versions: 5
- * End:
- */
diff --git a/i386/i386at/gpl/linux/net/3c503.c b/i386/i386at/gpl/linux/net/3c503.c
deleted file mode 100644
index 9a0c0b9e..00000000
--- a/i386/i386at/gpl/linux/net/3c503.c
+++ /dev/null
@@ -1,627 +0,0 @@
-/* 3c503.c: A shared-memory NS8390 ethernet driver for linux. */
-/*
- Written 1992-94 by Donald Becker.
-
- Copyright 1993 United States Government as represented by the
- Director, National Security Agency. This software may be used and
- distributed according to the terms of the GNU Public License,
- incorporated herein by reference.
-
- The author may be reached as becker@CESDIS.gsfc.nasa.gov, or C/O
- Center of Excellence in Space Data and Information Sciences
- Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
-
- This driver should work with the 3c503 and 3c503/16. It should be used
- in shared memory mode for best performance, although it may also work
- in programmed-I/O mode.
-
- Sources:
- EtherLink II Technical Reference Manual,
- EtherLink II/16 Technical Reference Manual Supplement,
- 3Com Corporation, 5400 Bayfront Plaza, Santa Clara CA 95052-8145
-
- The Crynwr 3c503 packet driver.
-
- Changelog:
-
- Paul Gortmaker : add support for the 2nd 8kB of RAM on 16 bit cards.
- Paul Gortmaker : multiple card support for module users.
-
-*/
-
-static const char *version =
- "3c503.c:v1.10 9/23/93 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/delay.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-
-#include <asm/io.h>
-#include <asm/system.h>
-
-#include "8390.h"
-#include "3c503.h"
-
-
-int el2_probe(struct device *dev);
-int el2_pio_probe(struct device *dev);
-int el2_probe1(struct device *dev, int ioaddr);
-
-/* A zero-terminated list of I/O addresses to be probed in PIO mode. */
-static unsigned int netcard_portlist[] =
- { 0x300,0x310,0x330,0x350,0x250,0x280,0x2a0,0x2e0,0};
-
-#define EL2_IO_EXTENT 16
-
-#ifdef HAVE_DEVLIST
-/* The 3c503 uses two entries, one for the safe memory-mapped probe and
- the other for the typical I/O probe. */
-struct netdev_entry el2_drv =
-{"3c503", el2_probe, EL1_IO_EXTENT, 0};
-struct netdev_entry el2pio_drv =
-{"3c503pio", el2_pioprobe1, EL1_IO_EXTENT, netcard_portlist};
-#endif
-
-static int el2_open(struct device *dev);
-static int el2_close(struct device *dev);
-static void el2_reset_8390(struct device *dev);
-static void el2_init_card(struct device *dev);
-static void el2_block_output(struct device *dev, int count,
- const unsigned char *buf, const start_page);
-static void el2_block_input(struct device *dev, int count, struct sk_buff *skb,
- int ring_offset);
-static void el2_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr,
- int ring_page);
-
-
-/* This routine probes for a memory-mapped 3c503 board by looking for
- the "location register" at the end of the jumpered boot PROM space.
- This works even if a PROM isn't there.
-
- If the ethercard isn't found there is an optional probe for
- ethercard jumpered to programmed-I/O mode.
- */
-int
-el2_probe(struct device *dev)
-{
- int *addr, addrs[] = { 0xddffe, 0xd9ffe, 0xcdffe, 0xc9ffe, 0};
- int base_addr = dev->base_addr;
-
- if (base_addr > 0x1ff) /* Check a single specified location. */
- return el2_probe1(dev, base_addr);
- else if (base_addr != 0) /* Don't probe at all. */
- return ENXIO;
-
- for (addr = addrs; *addr; addr++) {
- int i;
- unsigned int base_bits = readb(*addr);
- /* Find first set bit. */
- for(i = 7; i >= 0; i--, base_bits >>= 1)
- if (base_bits & 0x1)
- break;
- if (base_bits != 1)
- continue;
- if (check_region(netcard_portlist[i], EL2_IO_EXTENT))
- continue;
- if (el2_probe1(dev, netcard_portlist[i]) == 0)
- return 0;
- }
-#if ! defined(no_probe_nonshared_memory) && ! defined (HAVE_DEVLIST)
- return el2_pio_probe(dev);
-#else
- return ENODEV;
-#endif
-}
-
-#ifndef HAVE_DEVLIST
-/* Try all of the locations that aren't obviously empty. This touches
- a lot of locations, and is much riskier than the code above. */
-int
-el2_pio_probe(struct device *dev)
-{
- int i;
- int base_addr = dev ? dev->base_addr : 0;
-
- if (base_addr > 0x1ff) /* Check a single specified location. */
- return el2_probe1(dev, base_addr);
- else if (base_addr != 0) /* Don't probe at all. */
- return ENXIO;
-
- for (i = 0; netcard_portlist[i]; i++) {
- int ioaddr = netcard_portlist[i];
- if (check_region(ioaddr, EL2_IO_EXTENT))
- continue;
- if (el2_probe1(dev, ioaddr) == 0)
- return 0;
- }
-
- return ENODEV;
-}
-#endif
-
-/* Probe for the Etherlink II card at I/O port base IOADDR,
- returning non-zero on success. If found, set the station
- address and memory parameters in DEVICE. */
-int
-el2_probe1(struct device *dev, int ioaddr)
-{
- int i, iobase_reg, membase_reg, saved_406, wordlength;
- static unsigned version_printed = 0;
- unsigned long vendor_id;
-
- /* Reset and/or avoid any lurking NE2000 */
- if (inb(ioaddr + 0x408) == 0xff) {
- udelay(1000);
- return ENODEV;
- }
-
- /* We verify that it's a 3C503 board by checking the first three octets
- of its ethernet address. */
- iobase_reg = inb(ioaddr+0x403);
- membase_reg = inb(ioaddr+0x404);
- /* ASIC location registers should be 0 or have only a single bit set. */
- if ( (iobase_reg & (iobase_reg - 1))
- || (membase_reg & (membase_reg - 1))) {
- return ENODEV;
- }
- saved_406 = inb_p(ioaddr + 0x406);
- outb_p(ECNTRL_RESET|ECNTRL_THIN, ioaddr + 0x406); /* Reset it... */
- outb_p(ECNTRL_THIN, ioaddr + 0x406);
- /* Map the station addr PROM into the lower I/O ports. We now check
- for both the old and new 3Com prefix */
- outb(ECNTRL_SAPROM|ECNTRL_THIN, ioaddr + 0x406);
- vendor_id = inb(ioaddr)*0x10000 + inb(ioaddr + 1)*0x100 + inb(ioaddr + 2);
- if ((vendor_id != OLD_3COM_ID) && (vendor_id != NEW_3COM_ID)) {
- /* Restore the register we frobbed. */
- outb(saved_406, ioaddr + 0x406);
- return ENODEV;
- }
-
- /* We should have a "dev" from Space.c or the static module table. */
- if (dev == NULL) {
- printk("3c503.c: Passed a NULL device.\n");
- dev = init_etherdev(0, 0);
- }
-
- if (ei_debug && version_printed++ == 0)
- printk(version);
-
- dev->base_addr = ioaddr;
-
- /* Allocate dev->priv and fill in 8390 specific dev fields. */
- if (ethdev_init(dev)) {
- printk ("3c503: unable to allocate memory for dev->priv.\n");
- return -ENOMEM;
- }
-
- printk("%s: 3c503 at i/o base %#3x, node ", dev->name, ioaddr);
-
- /* Retrieve and print the ethernet address. */
- for (i = 0; i < 6; i++)
- printk(" %2.2x", dev->dev_addr[i] = inb(ioaddr + i));
-
- /* Map the 8390 back into the window. */
- outb(ECNTRL_THIN, ioaddr + 0x406);
-
- /* Check for EL2/16 as described in tech. man. */
- outb_p(E8390_PAGE0, ioaddr + E8390_CMD);
- outb_p(0, ioaddr + EN0_DCFG);
- outb_p(E8390_PAGE2, ioaddr + E8390_CMD);
- wordlength = inb_p(ioaddr + EN0_DCFG) & ENDCFG_WTS;
- outb_p(E8390_PAGE0, ioaddr + E8390_CMD);
-
- /* Probe for, turn on and clear the board's shared memory. */
- if (ei_debug > 2) printk(" memory jumpers %2.2x ", membase_reg);
- outb(EGACFR_NORM, ioaddr + 0x405); /* Enable RAM */
-
- /* This should be probed for (or set via an ioctl()) at run-time.
- Right now we use a sleazy hack to pass in the interface number
- at boot-time via the low bits of the mem_end field. That value is
- unused, and the low bits would be discarded even if it was used. */
-#if defined(EI8390_THICK) || defined(EL2_AUI)
- ei_status.interface_num = 1;
-#else
- ei_status.interface_num = dev->mem_end & 0xf;
-#endif
- printk(", using %sternal xcvr.\n", ei_status.interface_num == 0 ? "in" : "ex");
-
- if ((membase_reg & 0xf0) == 0) {
- dev->mem_start = 0;
- ei_status.name = "3c503-PIO";
- } else {
- dev->mem_start = ((membase_reg & 0xc0) ? 0xD8000 : 0xC8000) +
- ((membase_reg & 0xA0) ? 0x4000 : 0);
-
-#define EL2_MEMSIZE (EL2_MB1_STOP_PG - EL2_MB1_START_PG)*256
-#ifdef EL2MEMTEST
- /* This has never found an error, but someone might care.
- Note that it only tests the 2nd 8kB on 16kB 3c503/16
- cards between card addr. 0x2000 and 0x3fff. */
- { /* Check the card's memory. */
- unsigned long mem_base = dev->mem_start;
- unsigned int test_val = 0xbbadf00d;
- writel(0xba5eba5e, mem_base);
- for (i = sizeof(test_val); i < EL2_MEMSIZE; i+=sizeof(test_val)) {
- writel(test_val, mem_base + i);
- if (readl(mem_base) != 0xba5eba5e
- || readl(mem_base + i) != test_val) {
- printk("3c503.c: memory failure or memory address conflict.\n");
- dev->mem_start = 0;
- ei_status.name = "3c503-PIO";
- break;
- }
- test_val += 0x55555555;
- writel(0, mem_base + i);
- }
- }
-#endif /* EL2MEMTEST */
-
- dev->mem_end = dev->rmem_end = dev->mem_start + EL2_MEMSIZE;
-
- if (wordlength) { /* No Tx pages to skip over to get to Rx */
- dev->rmem_start = dev->mem_start;
- ei_status.name = "3c503/16";
- } else {
- dev->rmem_start = TX_PAGES*256 + dev->mem_start;
- ei_status.name = "3c503";
- }
- }
-
- /*
- Divide up the memory on the card. This is the same regardless of
- whether shared-mem or PIO is used. For 16 bit cards (16kB RAM),
- we use the entire 8k of bank1 for an Rx ring. We only use 3k
- of the bank0 for 2 full size Tx packet slots. For 8 bit cards,
- (8kB RAM) we use 3kB of bank1 for two Tx slots, and the remaining
- 5kB for an Rx ring. */
-
- if (wordlength) {
- ei_status.tx_start_page = EL2_MB0_START_PG;
- ei_status.rx_start_page = EL2_MB1_START_PG;
- } else {
- ei_status.tx_start_page = EL2_MB1_START_PG;
- ei_status.rx_start_page = EL2_MB1_START_PG + TX_PAGES;
- }
-
- /* Finish setting the board's parameters. */
- ei_status.stop_page = EL2_MB1_STOP_PG;
- ei_status.word16 = wordlength;
- ei_status.reset_8390 = &el2_reset_8390;
- ei_status.get_8390_hdr = &el2_get_8390_hdr;
- ei_status.block_input = &el2_block_input;
- ei_status.block_output = &el2_block_output;
-
- request_region(ioaddr, EL2_IO_EXTENT, ei_status.name);
-
- if (dev->irq == 2)
- dev->irq = 9;
- else if (dev->irq > 5 && dev->irq != 9) {
- printk("3c503: configured interrupt %d invalid, will use autoIRQ.\n",
- dev->irq);
- dev->irq = 0;
- }
-
- ei_status.saved_irq = dev->irq;
-
- dev->start = 0;
- dev->open = &el2_open;
- dev->stop = &el2_close;
-
- if (dev->mem_start)
- printk("%s: %s - %dkB RAM, 8kB shared mem window at %#6lx-%#6lx.\n",
- dev->name, ei_status.name, (wordlength+1)<<3,
- dev->mem_start, dev->mem_end-1);
-
- else
- printk("\n%s: %s, %dkB RAM, using programmed I/O (REJUMPER for SHARED MEMORY).\n",
- dev->name, ei_status.name, (wordlength+1)<<3);
-
- return 0;
-}
-
-static int
-el2_open(struct device *dev)
-{
-
- if (dev->irq < 2) {
- int irqlist[] = {5, 9, 3, 4, 0};
- int *irqp = irqlist;
-
- outb(EGACFR_NORM, E33G_GACFR); /* Enable RAM and interrupts. */
- do {
- if (request_irq (*irqp, NULL, 0, "bogus") != -EBUSY) {
- /* Twinkle the interrupt, and check if it's seen. */
- autoirq_setup(0);
- outb_p(0x04 << ((*irqp == 9) ? 2 : *irqp), E33G_IDCFR);
- outb_p(0x00, E33G_IDCFR);
- if (*irqp == autoirq_report(0) /* It's a good IRQ line! */
- && request_irq (dev->irq = *irqp, &ei_interrupt, 0, ei_status.name) == 0)
- break;
- }
- } while (*++irqp);
- if (*irqp == 0) {
- outb(EGACFR_IRQOFF, E33G_GACFR); /* disable interrupts. */
- return -EAGAIN;
- }
- } else {
- if (request_irq(dev->irq, &ei_interrupt, 0, ei_status.name)) {
- return -EAGAIN;
- }
- }
-
- el2_init_card(dev);
- ei_open(dev);
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-static int
-el2_close(struct device *dev)
-{
- free_irq(dev->irq);
- dev->irq = ei_status.saved_irq;
- irq2dev_map[dev->irq] = NULL;
- outb(EGACFR_IRQOFF, E33G_GACFR); /* disable interrupts. */
-
- ei_close(dev);
- MOD_DEC_USE_COUNT;
- return 0;
-}
-
-/* This is called whenever we have a unrecoverable failure:
- transmit timeout
- Bad ring buffer packet header
- */
-static void
-el2_reset_8390(struct device *dev)
-{
- if (ei_debug > 1) {
- printk("%s: Resetting the 3c503 board...", dev->name);
- printk("%#lx=%#02x %#lx=%#02x %#lx=%#02x...", E33G_IDCFR, inb(E33G_IDCFR),
- E33G_CNTRL, inb(E33G_CNTRL), E33G_GACFR, inb(E33G_GACFR));
- }
- outb_p(ECNTRL_RESET|ECNTRL_THIN, E33G_CNTRL);
- ei_status.txing = 0;
- outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
- el2_init_card(dev);
- if (ei_debug > 1) printk("done\n");
-}
-
-/* Initialize the 3c503 GA registers after a reset. */
-static void
-el2_init_card(struct device *dev)
-{
- /* Unmap the station PROM and select the DIX or BNC connector. */
- outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
-
- /* Set ASIC copy of rx's first and last+1 buffer pages */
- /* These must be the same as in the 8390. */
- outb(ei_status.rx_start_page, E33G_STARTPG);
- outb(ei_status.stop_page, E33G_STOPPG);
-
- /* Point the vector pointer registers somewhere ?harmless?. */
- outb(0xff, E33G_VP2); /* Point at the ROM restart location 0xffff0 */
- outb(0xff, E33G_VP1);
- outb(0x00, E33G_VP0);
- /* Turn off all interrupts until we're opened. */
- outb_p(0x00, dev->base_addr + EN0_IMR);
- /* Enable IRQs iff started. */
- outb(EGACFR_NORM, E33G_GACFR);
-
- /* Set the interrupt line. */
- outb_p((0x04 << (dev->irq == 9 ? 2 : dev->irq)), E33G_IDCFR);
- outb_p(8, E33G_DRQCNT); /* Set burst size to 8 */
- outb_p(0x20, E33G_DMAAH); /* Put a valid addr in the GA DMA */
- outb_p(0x00, E33G_DMAAL);
- return; /* We always succeed */
-}
-
-/* Either use the shared memory (if enabled on the board) or put the packet
- out through the ASIC FIFO. The latter is probably much slower. */
-static void
-el2_block_output(struct device *dev, int count,
- const unsigned char *buf, const start_page)
-{
- int i; /* Buffer index */
- int boguscount = 0; /* timeout counter */
-
- if (ei_status.word16) /* Tx packets go into bank 0 on EL2/16 card */
- outb(EGACFR_RSEL|EGACFR_TCM, E33G_GACFR);
- else
- outb(EGACFR_NORM, E33G_GACFR);
-
- if (dev->mem_start) { /* Shared memory transfer */
- unsigned long dest_addr = dev->mem_start +
- ((start_page - ei_status.tx_start_page) << 8);
- memcpy_toio(dest_addr, buf, count);
- outb(EGACFR_NORM, E33G_GACFR); /* Back to bank1 in case on bank0 */
- return;
- }
- /* No shared memory, put the packet out the slow way. */
- /* Set up then start the internal memory transfer to Tx Start Page */
- outb(0x00, E33G_DMAAL);
- outb_p(start_page, E33G_DMAAH);
- outb_p((ei_status.interface_num ? ECNTRL_AUI : ECNTRL_THIN ) | ECNTRL_OUTPUT
- | ECNTRL_START, E33G_CNTRL);
-
- /* This is the byte copy loop: it should probably be tuned for
- speed once everything is working. I think it is possible
- to output 8 bytes between each check of the status bit. */
- for(i = 0; i < count; i++) {
- if (i % 8 == 0)
- while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0)
- if (++boguscount > (i<<3) + 32) {
- printk("%s: FIFO blocked in el2_block_output (at %d of %d, bc=%d).\n",
- dev->name, i, count, boguscount);
- outb(EGACFR_NORM, E33G_GACFR); /* To MB1 for EL2/16 */
- return;
- }
- outb(buf[i], E33G_FIFOH);
- }
- outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
- outb(EGACFR_NORM, E33G_GACFR); /* Back to bank1 in case on bank0 */
- return;
-}
-
-/* Read the 4 byte, page aligned 8390 specific header. */
-static void
-el2_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
-{
- unsigned int i;
- unsigned long hdr_start = dev->mem_start + ((ring_page - EL2_MB1_START_PG)<<8);
- unsigned long fifo_watchdog;
-
- if (dev->mem_start) { /* Use the shared memory. */
-#ifdef notdef
- /* Officially this is what we are doing, but the readl() is faster */
- memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
-#else
- ((unsigned int*)hdr)[0] = readl(hdr_start);
-#endif
- return;
- }
-
- /* No shared memory, use programmed I/O. Ugh. */
- outb(0, E33G_DMAAL);
- outb_p(ring_page & 0xff, E33G_DMAAH);
- outb_p((ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI) | ECNTRL_INPUT
- | ECNTRL_START, E33G_CNTRL);
-
- /* Header is < 8 bytes, so only check the FIFO at the beginning. */
- fifo_watchdog = jiffies;
- while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0) {
- if (jiffies - fifo_watchdog > 2*HZ/100) {
- printk("%s: FIFO blocked in el2_get_8390_hdr.\n", dev->name);
- break;
- }
- }
-
- for(i = 0; i < sizeof(struct e8390_pkt_hdr); i++)
- ((char *)(hdr))[i] = inb_p(E33G_FIFOH);
-
- outb_p(ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
-}
-
-/* Returns the new ring pointer. */
-static void
-el2_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset)
-{
- int boguscount = 0;
- int end_of_ring = dev->rmem_end;
- unsigned int i;
-
- /* Maybe enable shared memory just be to be safe... nahh.*/
- if (dev->mem_start) { /* Use the shared memory. */
- ring_offset -= (EL2_MB1_START_PG<<8);
- if (dev->mem_start + ring_offset + count > end_of_ring) {
- /* We must wrap the input move. */
- int semi_count = end_of_ring - (dev->mem_start + ring_offset);
- memcpy_fromio(skb->data, dev->mem_start + ring_offset, semi_count);
- count -= semi_count;
- memcpy_fromio(skb->data + semi_count, dev->rmem_start, count);
- } else {
- /* Packet is in one chunk -- we can copy + cksum. */
- eth_io_copy_and_sum(skb, dev->mem_start + ring_offset, count, 0);
- }
- return;
- }
- /* No shared memory, use programmed I/O. */
- outb(ring_offset & 0xff, E33G_DMAAL);
- outb_p((ring_offset >> 8) & 0xff, E33G_DMAAH);
- outb_p((ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI) | ECNTRL_INPUT
- | ECNTRL_START, E33G_CNTRL);
-
- /* This is the byte copy loop: it should probably be tuned for
- speed once everything is working. */
- for(i = 0; i < count; i++) {
- if (i % 8 == 0)
- while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0)
- if (++boguscount > (i<<3) + 32) {
- printk("%s: FIFO blocked in el2_block_input() (at %d of %d, bc=%d).\n",
- dev->name, i, count, boguscount);
- boguscount = 0;
- break;
- }
- (skb->data)[i] = inb_p(E33G_FIFOH);
- }
- outb_p(ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
-}
-
-
-#ifdef MODULE
-#define MAX_EL2_CARDS 4 /* Max number of EL2 cards per module */
-#define NAMELEN 8 /* # of chars for storing dev->name */
-static char namelist[NAMELEN * MAX_EL2_CARDS] = { 0, };
-static struct device dev_el2[MAX_EL2_CARDS] = {
- {
- NULL, /* assign a chunk of namelist[] below */
- 0, 0, 0, 0,
- 0, 0,
- 0, 0, 0, NULL, NULL
- },
-};
-
-static int io[MAX_EL2_CARDS] = { 0, };
-static int irq[MAX_EL2_CARDS] = { 0, };
-static int xcvr[MAX_EL2_CARDS] = { 0, }; /* choose int. or ext. xcvr */
-
-/* This is set up so that only a single autoprobe takes place per call.
-ISA device autoprobes on a running machine are not recommended. */
-int
-init_module(void)
-{
- int this_dev, found = 0;
-
- for (this_dev = 0; this_dev < MAX_EL2_CARDS; this_dev++) {
- struct device *dev = &dev_el2[this_dev];
- dev->name = namelist+(NAMELEN*this_dev);
- dev->irq = irq[this_dev];
- dev->base_addr = io[this_dev];
- dev->mem_end = xcvr[this_dev]; /* low 4bits = xcvr sel. */
- dev->init = el2_probe;
- if (io[this_dev] == 0) {
- if (this_dev != 0) break; /* only autoprobe 1st one */
- printk(KERN_NOTICE "3c503.c: Presently autoprobing (not recommended) for a single card.\n");
- }
- if (register_netdev(dev) != 0) {
- printk(KERN_WARNING "3c503.c: No 3c503 card found (i/o = 0x%x).\n", io[this_dev]);
- if (found != 0) return 0; /* Got at least one. */
- return -ENXIO;
- }
- found++;
- }
-
- return 0;
-}
-
-void
-cleanup_module(void)
-{
- int this_dev;
-
- for (this_dev = 0; this_dev < MAX_EL2_CARDS; this_dev++) {
- struct device *dev = &dev_el2[this_dev];
- if (dev->priv != NULL) {
- /* NB: el2_close() handles free_irq + irq2dev map */
- kfree(dev->priv);
- dev->priv = NULL;
- release_region(dev->base_addr, EL2_IO_EXTENT);
- unregister_netdev(dev);
- }
- }
-}
-#endif /* MODULE */
-
-/*
- * Local variables:
- * version-control: t
- * kept-new-versions: 5
- * c-indent-level: 4
- * End:
- */
diff --git a/i386/i386at/gpl/linux/net/3c503.h b/i386/i386at/gpl/linux/net/3c503.h
deleted file mode 100644
index b9f8a46f..00000000
--- a/i386/i386at/gpl/linux/net/3c503.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/* Definitions for the 3Com 3c503 Etherlink 2. */
-/* This file is distributed under the GPL.
- Many of these names and comments are directly from the Crynwr packet
- drivers, which are released under the GPL. */
-
-#define EL2H (dev->base_addr + 0x400)
-#define EL2L (dev->base_addr)
-
-/* Vendor unique hardware addr. prefix. 3Com has 2 because they ran
- out of available addresses on the first one... */
-
-#define OLD_3COM_ID 0x02608c
-#define NEW_3COM_ID 0x0020af
-
-/* Shared memory management parameters. NB: The 8 bit cards have only
- one bank (MB1) which serves both Tx and Rx packet space. The 16bit
- cards have 2 banks, MB0 for Tx packets, and MB1 for Rx packets.
- You choose which bank appears in the sh. mem window with EGACFR_MBSn */
-
-#define EL2_MB0_START_PG (0x00) /* EL2/16 Tx packets go in bank 0 */
-#define EL2_MB1_START_PG (0x20) /* First page of bank 1 */
-#define EL2_MB1_STOP_PG (0x40) /* Last page +1 of bank 1 */
-
-/* 3Com 3c503 ASIC registers */
-#define E33G_STARTPG (EL2H+0) /* Start page, matching EN0_STARTPG */
-#define E33G_STOPPG (EL2H+1) /* Stop page, must match EN0_STOPPG */
-#define E33G_DRQCNT (EL2H+2) /* DMA burst count */
-#define E33G_IOBASE (EL2H+3) /* Read of I/O base jumpers. */
- /* (non-useful, but it also appears at the end of EPROM space) */
-#define E33G_ROMBASE (EL2H+4) /* Read of memory base jumpers. */
-#define E33G_GACFR (EL2H+5) /* Config/setup bits for the ASIC GA */
-#define E33G_CNTRL (EL2H+6) /* Board's main control register */
-#define E33G_STATUS (EL2H+7) /* Status on completions. */
-#define E33G_IDCFR (EL2H+8) /* Interrupt/DMA config register */
- /* (Which IRQ to assert, DMA chan to use) */
-#define E33G_DMAAH (EL2H+9) /* High byte of DMA address reg */
-#define E33G_DMAAL (EL2H+10) /* Low byte of DMA address reg */
-/* "Vector pointer" - if this address matches a read, the EPROM (rather than
- shared RAM) is mapped into memory space. */
-#define E33G_VP2 (EL2H+11)
-#define E33G_VP1 (EL2H+12)
-#define E33G_VP0 (EL2H+13)
-#define E33G_FIFOH (EL2H+14) /* FIFO for programmed I/O moves */
-#define E33G_FIFOL (EL2H+15) /* ... low byte of above. */
-
-/* Bits in E33G_CNTRL register: */
-
-#define ECNTRL_RESET (0x01) /* Software reset of the ASIC and 8390 */
-#define ECNTRL_THIN (0x02) /* Onboard xcvr enable, AUI disable */
-#define ECNTRL_AUI (0x00) /* Onboard xcvr disable, AUI enable */
-#define ECNTRL_SAPROM (0x04) /* Map the station address prom */
-#define ECNTRL_DBLBFR (0x20) /* FIFO configuration bit */
-#define ECNTRL_OUTPUT (0x40) /* PC-to-3C503 direction if 1 */
-#define ECNTRL_INPUT (0x00) /* 3C503-to-PC direction if 0 */
-#define ECNTRL_START (0x80) /* Start the DMA logic */
-
-/* Bits in E33G_STATUS register: */
-
-#define ESTAT_DPRDY (0x80) /* Data port (of FIFO) ready */
-#define ESTAT_UFLW (0x40) /* Tried to read FIFO when it was empty */
-#define ESTAT_OFLW (0x20) /* Tried to write FIFO when it was full */
-#define ESTAT_DTC (0x10) /* Terminal Count from PC bus DMA logic */
-#define ESTAT_DIP (0x08) /* DMA In Progress */
-
-/* Bits in E33G_GACFR register: */
-
-#define EGACFR_NIM (0x80) /* NIC interrupt mask */
-#define EGACFR_TCM (0x40) /* DMA term. count interrupt mask */
-#define EGACFR_RSEL (0x08) /* Map a bank of card mem into system mem */
-#define EGACFR_MBS2 (0x04) /* Memory bank select, bit 2. */
-#define EGACFR_MBS1 (0x02) /* Memory bank select, bit 1. */
-#define EGACFR_MBS0 (0x01) /* Memory bank select, bit 0. */
-
-#define EGACFR_NORM (0x49) /* TCM | RSEL | MBS0 */
-#define EGACFR_IRQOFF (0xc9) /* TCM | RSEL | MBS0 | NIM */
-
-/*
- MBS2 MBS1 MBS0 Sh. mem windows card mem at:
- ---- ---- ---- -----------------------------
- 0 0 0 0x0000 -- bank 0
- 0 0 1 0x2000 -- bank 1 (only choice for 8bit card)
- 0 1 0 0x4000 -- bank 2, not used
- 0 1 1 0x6000 -- bank 3, not used
-
-There was going to be a 32k card that used bank 2 and 3, but it
-never got produced.
-
-*/
-
-
-/* End of 3C503 parameter definitions */
diff --git a/i386/i386at/gpl/linux/net/3c505.c b/i386/i386at/gpl/linux/net/3c505.c
deleted file mode 100644
index 63ccc9cf..00000000
--- a/i386/i386at/gpl/linux/net/3c505.c
+++ /dev/null
@@ -1,1518 +0,0 @@
-/*
- * Linux ethernet device driver for the 3Com Etherlink Plus (3C505)
- * By Craig Southeren and Juha Laiho
- *
- * 3c505.c This module implements an interface to the 3Com
- * Etherlink Plus (3c505) ethernet card. Linux device
- * driver interface reverse engineered from the Linux 3C509
- * device drivers. Some 3C505 information gleaned from
- * the Crynwr packet driver. Still this driver would not
- * be here without 3C505 technical reference provided by
- * 3Com.
- *
- * Version: @(#)3c505.c 0.8.4 17-Dec-95
- *
- * Authors: Linux 3c505 device driver by
- * Craig Southeren, <craigs@ineluki.apana.org.au>
- * Final debugging by
- * Andrew Tridgell, <tridge@nimbus.anu.edu.au>
- * Auto irq/address, tuning, cleanup and v1.1.4+ kernel mods by
- * Juha Laiho, <jlaiho@ichaos.nullnet.fi>
- * Linux 3C509 driver by
- * Donald Becker, <becker@super.org>
- * Crynwr packet driver by
- * Krishnan Gopalan and Gregg Stefancik,
- * Clemson University Engineering Computer Operations.
- * Portions of the code have been adapted from the 3c505
- * driver for NCSA Telnet by Bruce Orchard and later
- * modified by Warren Van Houten and krus@diku.dk.
- * 3C505 technical information provided by
- * Terry Murphy, of 3Com Network Adapter Division
- * Linux 1.3.0 changes by
- * Alan Cox <Alan.Cox@linux.org>
- *
- */
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/interrupt.h>
-#include <linux/ptrace.h>
-#include <linux/errno.h>
-#include <linux/in.h>
-#include <linux/malloc.h>
-#include <linux/ioport.h>
-#include <asm/bitops.h>
-#include <asm/io.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-
-#include "3c505.h"
-
-/*********************************************************
- *
- * define debug messages here as common strings to reduce space
- *
- *********************************************************/
-
-static const char * filename = __FILE__;
-
-static const char * null_msg = "*** NULL at %s:%s (line %d) ***\n";
-#define CHECK_NULL(p) \
- if (!p) printk(null_msg, filename,__FUNCTION__,__LINE__)
-
-static const char * timeout_msg = "*** timeout at %s:%s (line %d) ***\n";
-#define TIMEOUT_MSG(lineno) \
- printk(timeout_msg, filename,__FUNCTION__,(lineno))
-
-static const char * invalid_pcb_msg =
- "*** invalid pcb length %d at %s:%s (line %d) ***\n";
-#define INVALID_PCB_MSG(len) \
- printk(invalid_pcb_msg, (len),filename,__FUNCTION__,__LINE__)
-
-static const char * search_msg = "%s: Looking for 3c505 adapter at address %#x...";
-
-static const char * stilllooking_msg = "still looking...";
-
-static const char * found_msg = "found.\n";
-
-static const char * notfound_msg = "not found (reason = %d)\n";
-
-static const char * couldnot_msg = "%s: 3c505 not found\n";
-
-/*********************************************************
- *
- * various other debug stuff
- *
- *********************************************************/
-
-#ifdef ELP_DEBUG
-static int elp_debug = ELP_DEBUG;
-#else
-static int elp_debug = 0;
-#endif
-
-/*
- * 0 = no messages (well, some)
- * 1 = messages when high level commands performed
- * 2 = messages when low level commands performed
- * 3 = messages when interrupts received
- */
-
-#define ELP_VERSION "0.8.4"
-
-#ifdef MACH
-#define ELP_NEED_HARD_RESET 0
-#endif
-
-/*****************************************************************
- *
- * useful macros
- *
- *****************************************************************/
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-
-/*****************************************************************
- *
- * List of I/O-addresses we try to auto-sense
- * Last element MUST BE 0!
- *****************************************************************/
-
-const int addr_list[]={0x300,0x280,0x310,0};
-
-/*****************************************************************
- *
- * Functions for I/O (note the inline !)
- *
- *****************************************************************/
-
-static inline unsigned char
-inb_status (unsigned int base_addr)
-{
- return inb(base_addr+PORT_STATUS);
-}
-
-static inline unsigned char
-inb_control (unsigned int base_addr)
-{
- return inb(base_addr+PORT_CONTROL);
-}
-
-static inline int
-inb_command (unsigned int base_addr)
-{
- return inb(base_addr+PORT_COMMAND);
-}
-
-static inline void
-outb_control (unsigned char val, unsigned int base_addr)
-{
- outb(val, base_addr+PORT_CONTROL);
-}
-
-static inline void
-outb_command (unsigned char val, unsigned int base_addr)
-{
- outb(val, base_addr+PORT_COMMAND);
-}
-
-static inline unsigned int
-inw_data (unsigned int base_addr)
-{
- return inw(base_addr+PORT_DATA);
-}
-
-static inline void
-outw_data (unsigned int val, unsigned int base_addr)
-{
- outw(val, base_addr+PORT_DATA);
-}
-
-
-/*****************************************************************
- *
- * structure to hold context information for adapter
- *
- *****************************************************************/
-
-typedef struct {
- volatile short got[NUM_TRANSMIT_CMDS]; /* flags for command completion */
- pcb_struct tx_pcb; /* PCB for foreground sending */
- pcb_struct rx_pcb; /* PCB for foreground receiving */
- pcb_struct itx_pcb; /* PCB for background sending */
- pcb_struct irx_pcb; /* PCB for background receiving */
- struct enet_statistics stats;
-} elp_device;
-
-static int reset_count=0;
-
-/*****************************************************************
- *
- * useful functions for accessing the adapter
- *
- *****************************************************************/
-
-/*
- * use this routine when accessing the ASF bits as they are
- * changed asynchronously by the adapter
- */
-
-/* get adapter PCB status */
-#define GET_ASF(addr) \
- (get_status(addr)&ASF_PCB_MASK)
-
-static inline int
-get_status (unsigned int base_addr)
-{
- int timeout = jiffies + 10;
- register int stat1;
- do {
- stat1 = inb_status(base_addr);
- } while (stat1 != inb_status(base_addr) && jiffies < timeout);
- if (jiffies >= timeout)
- TIMEOUT_MSG(__LINE__);
- return stat1;
-}
-
-static inline void
-set_hsf (unsigned int base_addr, int hsf)
-{
- cli();
- outb_control((inb_control(base_addr)&~HSF_PCB_MASK)|hsf, base_addr);
- sti();
-}
-
-#define WAIT_HCRE(addr,toval) wait_hcre((addr),(toval),__LINE__)
-static inline int
-wait_hcre (unsigned int base_addr, int toval, int lineno)
-{
- int timeout = jiffies + toval;
- while (((inb_status(base_addr)&HCRE)==0) && (jiffies <= timeout))
- ;
- if (jiffies >= timeout) {
- TIMEOUT_MSG(lineno);
- return FALSE;
- }
- return TRUE;
-}
-
-static inline int
-wait_fast_hcre (unsigned int base_addr, int toval, int lineno)
-{
- int timeout = 0;
- while (((inb_status(base_addr)&HCRE)==0) && (timeout++ < toval))
- ;
- if (timeout >= toval) {
- sti();
- TIMEOUT_MSG(lineno);
- return FALSE;
- }
- return TRUE;
-}
-
-static int start_receive (struct device *, pcb_struct *);
-static void adapter_hard_reset (struct device *);
-
-inline static void
-adapter_reset (struct device * dev)
-{
- int timeout;
- unsigned char orig_hcr=inb_control(dev->base_addr);
-
- elp_device * adapter=dev->priv;
-
- outb_control(0,dev->base_addr);
-
- if (inb_status(dev->base_addr)&ACRF) {
- do {
- inb_command(dev->base_addr);
- timeout=jiffies+2;
- while ((jiffies<=timeout) && !(inb_status(dev->base_addr)&ACRF))
- ;
- } while (inb_status(dev->base_addr)&ACRF);
- set_hsf(dev->base_addr,HSF_PCB_NAK);
- }
-
- outb_control(inb_control(dev->base_addr)|ATTN|DIR,dev->base_addr);
- timeout=jiffies+1;
- while (jiffies<=timeout)
- ;
- outb_control(inb_control(dev->base_addr)&~ATTN,dev->base_addr);
- timeout=jiffies+1;
- while (jiffies<=timeout)
- ;
- outb_control(inb_control(dev->base_addr)|FLSH,dev->base_addr);
- timeout=jiffies+1;
- while (jiffies<=timeout)
- ;
- outb_control(inb_control(dev->base_addr)&~FLSH,dev->base_addr);
- timeout=jiffies+1;
- while (jiffies<=timeout)
- ;
-
- outb_control(orig_hcr, dev->base_addr);
- if (!start_receive(dev, &adapter->tx_pcb))
- printk("%s: start receive command failed \n", dev->name);
-}
-
-/*****************************************************************
- *
- * send_pcb
- * Send a PCB to the adapter.
- *
- * output byte to command reg --<--+
- * wait until HCRE is non zero |
- * loop until all bytes sent -->--+
- * set HSF1 and HSF2 to 1
- * output pcb length
- * wait until ASF give ACK or NAK
- * set HSF1 and HSF2 to 0
- *
- *****************************************************************/
-
-static int
-send_pcb (struct device * dev, pcb_struct * pcb)
-{
- int i;
- int timeout;
- int cont;
-
- /*
- * load each byte into the command register and
- * wait for the HCRE bit to indicate the adapter
- * had read the byte
- */
- set_hsf(dev->base_addr,0);
- if ((cont = WAIT_HCRE(dev->base_addr,5))) {
- cli();
- if (pcb->command==CMD_TRANSMIT_PACKET)
- outb_control(inb_control(dev->base_addr)&~DIR,dev->base_addr);
- outb_command(pcb->command, dev->base_addr);
- sti();
- cont = WAIT_HCRE(dev->base_addr,5);
- }
-
- if (cont) {
- outb_command(pcb->length, dev->base_addr);
- cont = WAIT_HCRE(dev->base_addr,5);
- }
-
- cli();
- for (i = 0; cont && (i < pcb->length); i++) {
- outb_command(pcb->data.raw[i], dev->base_addr);
- cont = wait_fast_hcre(dev->base_addr,20000,__LINE__);
- } /* if wait_fast_hcre() failed, has already done sti() */
-
- /* set the host status bits to indicate end of PCB */
- /* send the total packet length as well */
- /* wait for the adapter to indicate that it has read the PCB */
- if (cont) {
- set_hsf(dev->base_addr,HSF_PCB_END);
- outb_command(2+pcb->length, dev->base_addr);
- sti();
- timeout = jiffies + 7;
- while (jiffies < timeout) {
- i = GET_ASF(dev->base_addr);
- if ((i == ASF_PCB_ACK) || (i == ASF_PCB_NAK))
- break;
- }
-
- if (i == ASF_PCB_ACK) {
- reset_count=0;
- return TRUE;
- }
- else if (i == ASF_PCB_NAK) {
- printk("%s: PCB send was NAKed\n", dev->name);
- } else {
- printk("%s: timeout after sending PCB\n", dev->name);
- }
- } else {
- sti();
- printk("%s: timeout in middle of sending PCB\n", dev->name);
- }
-
- adapter_reset(dev);
- return FALSE;
-}
-
-/*****************************************************************
- *
- * receive_pcb
- * Read a PCB to the adapter
- *
- * wait for ACRF to be non-zero ---<---+
- * input a byte |
- * if ASF1 and ASF2 were not both one |
- * before byte was read, loop --->---+
- * set HSF1 and HSF2 for ack
- *
- *****************************************************************/
-
-static int
-receive_pcb (struct device * dev, pcb_struct * pcb)
-{
- int i, j;
- int total_length;
- int stat;
- int timeout;
-
- CHECK_NULL(pcb);
- CHECK_NULL(dev);
-
- set_hsf(dev->base_addr,0);
-
- /* get the command code */
- timeout = jiffies + 2;
- while (((stat = get_status(dev->base_addr))&ACRF) == 0 && jiffies < timeout)
- ;
- if (jiffies >= timeout) {
- TIMEOUT_MSG(__LINE__);
- return FALSE;
- }
-
- pcb->command = inb_command(dev->base_addr);
-
- /* read the data length */
- timeout = jiffies + 3;
- while (((stat = get_status(dev->base_addr)) & ACRF) == 0 && jiffies < timeout)
- ;
- if (jiffies >= timeout) {
- TIMEOUT_MSG(__LINE__);
- return FALSE;
- }
- pcb->length = inb_command(dev->base_addr);
-
- if (pcb->length > MAX_PCB_DATA) {
- INVALID_PCB_MSG(pcb->length);
- adapter_reset(dev);
- return FALSE;
- }
-
- /* read the data */
- cli();
- i = 0;
- do {
- j = 0;
- while (((stat = get_status(dev->base_addr))&ACRF) == 0 && j++ < 20000)
- ;
- pcb->data.raw[i++] = inb_command(dev->base_addr);
- if (i > MAX_PCB_DATA)
- INVALID_PCB_MSG(i);
- } while ((stat & ASF_PCB_MASK) != ASF_PCB_END && j < 20000);
- sti();
- if (j >= 20000) {
- TIMEOUT_MSG(__LINE__);
- return FALSE;
- }
-
- /* woops, the last "data" byte was really the length! */
- total_length = pcb->data.raw[--i];
-
- /* safety check total length vs data length */
- if (total_length != (pcb->length + 2)) {
- if (elp_debug >= 2)
- printk("%s: mangled PCB received\n", dev->name);
- set_hsf(dev->base_addr,HSF_PCB_NAK);
- return FALSE;
- }
-
- set_hsf(dev->base_addr,HSF_PCB_ACK);
- reset_count=0;
- return TRUE;
-}
-
-static void
-adapter_hard_reset (struct device * dev)
-{
- int timeout;
- long flags;
-
- CHECK_NULL(dev);
-
- save_flags(flags);
- sti();
-
- if (elp_debug > 0)
- printk("%s: Resetting the adapter, please wait (approx 20 s)\n",
- dev->name);
- /*
- * take FLSH and ATTN high
- */
- outb_control(ATTN|FLSH, dev->base_addr);
-
- /*
- * wait for a little bit
- */
- for (timeout = jiffies + 20; jiffies <= timeout; )
- ;
-
- /*
- * now take them low
- */
- outb_control(0, dev->base_addr);
-
- /*
- * wait for a little bit
- */
- for (timeout = jiffies + 20; jiffies <= timeout; )
- ;
-
- /*
- * now hang around until the board gets it's act together
- */
- for (timeout = jiffies + (100 * 15); jiffies <= timeout; )
- if (GET_ASF(dev->base_addr) != ASF_PCB_END)
- break;
- restore_flags(flags);
-}
-
-/******************************************************
- *
- * queue a receive command on the adapter so we will get an
- * interrupt when a packet is received.
- *
- ******************************************************/
-
-static int
-start_receive (struct device * dev, pcb_struct * tx_pcb)
-{
- CHECK_NULL(dev);
- CHECK_NULL(tx_pcb);
-
- if (elp_debug >= 3)
- printk("%s: restarting receiver\n", dev->name);
- tx_pcb->command = CMD_RECEIVE_PACKET;
- tx_pcb->length = sizeof(struct Rcv_pkt);
- tx_pcb->data.rcv_pkt.buf_seg
- = tx_pcb->data.rcv_pkt.buf_ofs = 0; /* Unused */
- tx_pcb->data.rcv_pkt.buf_len = 1600;
- tx_pcb->data.rcv_pkt.timeout = 0; /* set timeout to zero */
- return send_pcb(dev, tx_pcb);
-}
-
-/******************************************************
- *
- * extract a packet from the adapter
- * this routine is only called from within the interrupt
- * service routine, so no cli/sti calls are needed
- * note that the length is always assumed to be even
- *
- ******************************************************/
-
-static void
-receive_packet (struct device * dev, int len)
-{
- register int i;
- unsigned short * ptr;
- int timeout;
- int rlen;
- struct sk_buff *skb;
- elp_device * adapter;
-
- CHECK_NULL(dev);
- adapter=dev->priv;
-
- if (len <= 0 || ((len & ~1) != len))
- if (elp_debug >= 3) {
- sti();
- printk("*** bad packet len %d at %s(%d)\n",len,filename,__LINE__);
- cli();
- }
-
- rlen = (len+1) & ~1;
-
- skb = dev_alloc_skb(rlen+2);
-
- /*
- * make sure the data register is going the right way
- */
-
- outb_control(inb_control(dev->base_addr)|DIR, dev->base_addr);
-
- /*
- * if buffer could not be allocated, swallow it
- */
- if (skb == NULL) {
- for (i = 0; i < (rlen/2); i++) {
- timeout = 0;
- while ((inb_status(dev->base_addr)&HRDY) == 0 && timeout++ < 20000)
- ;
- if (timeout >= 20000) {
- sti();
- TIMEOUT_MSG(__LINE__);
- break;
- }
-
- inw_data(dev->base_addr);
- }
- adapter->stats.rx_dropped++;
-
- } else {
- skb_reserve(skb,2); /* 16 byte alignment */
- skb->dev = dev;
-
- /*
- * now read the data from the adapter
- */
- ptr = (unsigned short *)skb_put(skb,len);
- for (i = 0; i < (rlen/2); i++) {
- timeout = 0;
- while ((inb_status(dev->base_addr)&HRDY) == 0 && timeout++ < 20000)
- ;
- if (timeout >= 20000) {
- sti();
- printk("*** timeout at %s(%d) reading word %d of %d ***\n",
- filename,__LINE__, i, rlen/2);
- kfree_skb(skb, FREE_WRITE);
- return;
- }
-
- *ptr = inw_data(dev->base_addr);
- ptr++;
- }
-
- sti();
- skb->protocol=eth_type_trans(skb,dev);
- netif_rx(skb);
- }
-
- outb_control(inb_control(dev->base_addr)&~DIR, dev->base_addr);
-}
-
-
-/******************************************************
- *
- * interrupt handler
- *
- ******************************************************/
-
-static void
-elp_interrupt (int irq, struct pt_regs *reg_ptr)
-{
- int len;
- int dlen;
- struct device *dev;
- elp_device * adapter;
- int timeout;
-
- if (irq < 0 || irq > 15) {
- printk ("elp_interrupt(): illegal IRQ number found in interrupt routine (%i)\n", irq);
- return;
- }
-
- dev = irq2dev_map[irq];
-
- if (dev == NULL) {
- printk ("elp_interrupt(): irq %d for unknown device.\n", irq);
- return;
- }
-
- adapter = (elp_device *) dev->priv;
-
- CHECK_NULL(adapter);
-
- if (dev->interrupt)
- if (elp_debug >= 2)
- printk("%s: Re-entering the interrupt handler.\n", dev->name);
- dev->interrupt = 1;
-
- /*
- * allow interrupts (we need timers!)
- */
- sti();
-
- /*
- * receive a PCB from the adapter
- */
- timeout = jiffies + 3;
- while ((inb_status(dev->base_addr)&ACRF) != 0 && jiffies < timeout) {
-
- if (receive_pcb(dev, &adapter->irx_pcb)) {
-
- switch (adapter->irx_pcb.command) {
-
- /*
- * received a packet - this must be handled fast
- */
- case CMD_RECEIVE_PACKET_COMPLETE:
- /* if the device isn't open, don't pass packets up the stack */
- if (dev->start == 0)
- break;
- cli();
- /* Set direction of adapter FIFO */
- outb_control(inb_control(dev->base_addr)|DIR,
- dev->base_addr);
- len = adapter->irx_pcb.data.rcv_resp.pkt_len;
- dlen = adapter->irx_pcb.data.rcv_resp.buf_len;
- if (adapter->irx_pcb.data.rcv_resp.timeout != 0) {
- printk("%s: interrupt - packet not received correctly\n", dev->name);
- sti();
- } else {
- if (elp_debug >= 3) {
- sti();
- printk("%s: interrupt - packet received of length %i (%i)\n", dev->name, len, dlen);
- cli();
- }
- receive_packet(dev, dlen);
- sti();
- if (elp_debug >= 3)
- printk("%s: packet received\n", dev->name);
- }
- if (dev->start && !start_receive(dev, &adapter->itx_pcb))
- if (elp_debug >= 2)
- printk("%s: interrupt - failed to send receive start PCB\n", dev->name);
- if (elp_debug >= 3)
- printk("%s: receive procedure complete\n", dev->name);
-
- break;
-
- /*
- * 82586 configured correctly
- */
- case CMD_CONFIGURE_82586_RESPONSE:
- adapter->got[CMD_CONFIGURE_82586] = 1;
- if (elp_debug >= 3)
- printk("%s: interrupt - configure response received\n", dev->name);
- break;
-
- /*
- * Adapter memory configuration
- */
- case CMD_CONFIGURE_ADAPTER_RESPONSE:
- adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] = 1;
- if (elp_debug >= 3)
- printk("%s: Adapter memory configuration %s.\n",dev->name,
- adapter->irx_pcb.data.failed?"failed":"succeeded");
- break;
-
- /*
- * Multicast list loading
- */
- case CMD_LOAD_MULTICAST_RESPONSE:
- adapter->got[CMD_LOAD_MULTICAST_LIST] = 1;
- if (elp_debug >= 3)
- printk("%s: Multicast address list loading %s.\n",dev->name,
- adapter->irx_pcb.data.failed?"failed":"succeeded");
- break;
-
- /*
- * Station address setting
- */
- case CMD_SET_ADDRESS_RESPONSE:
- adapter->got[CMD_SET_STATION_ADDRESS] = 1;
- if (elp_debug >= 3)
- printk("%s: Ethernet address setting %s.\n",dev->name,
- adapter->irx_pcb.data.failed?"failed":"succeeded");
- break;
-
-
- /*
- * received board statistics
- */
- case CMD_NETWORK_STATISTICS_RESPONSE:
- adapter->stats.rx_packets += adapter->irx_pcb.data.netstat.tot_recv;
- adapter->stats.tx_packets += adapter->irx_pcb.data.netstat.tot_xmit;
- adapter->stats.rx_crc_errors += adapter->irx_pcb.data.netstat.err_CRC;
- adapter->stats.rx_frame_errors += adapter->irx_pcb.data.netstat.err_align;
- adapter->stats.rx_fifo_errors += adapter->irx_pcb.data.netstat.err_ovrrun;
- adapter->got[CMD_NETWORK_STATISTICS] = 1;
- if (elp_debug >= 3)
- printk("%s: interrupt - statistics response received\n", dev->name);
- break;
-
- /*
- * sent a packet
- */
- case CMD_TRANSMIT_PACKET_COMPLETE:
- if (elp_debug >= 3)
- printk("%s: interrupt - packet sent\n", dev->name);
- if (dev->start == 0)
- break;
- if (adapter->irx_pcb.data.xmit_resp.c_stat != 0)
- if (elp_debug >= 2)
- printk("%s: interrupt - error sending packet %4.4x\n",
- dev->name, adapter->irx_pcb.data.xmit_resp.c_stat);
- dev->tbusy = 0;
- mark_bh(NET_BH);
- break;
-
- /*
- * some unknown PCB
- */
- default:
- printk("%s: unknown PCB received - %2.2x\n", dev->name, adapter->irx_pcb.command);
- break;
- }
- } else {
- printk("%s: failed to read PCB on interrupt\n", dev->name);
- adapter_reset(dev);
- }
- }
-
- /*
- * indicate no longer in interrupt routine
- */
- dev->interrupt = 0;
-}
-
-
-/******************************************************
- *
- * open the board
- *
- ******************************************************/
-
-static int
-elp_open (struct device *dev)
-{
- elp_device * adapter;
-
- CHECK_NULL(dev);
-
- adapter = dev->priv;
-
- if (elp_debug >= 3)
- printk("%s: request to open device\n", dev->name);
-
- /*
- * make sure we actually found the device
- */
- if (adapter == NULL) {
- printk("%s: Opening a non-existent physical device\n", dev->name);
- return -EAGAIN;
- }
-
- /*
- * disable interrupts on the board
- */
- outb_control(0x00, dev->base_addr);
-
- /*
- * clear any pending interrupts
- */
- inb_command(dev->base_addr);
- adapter_reset(dev);
-
- /*
- * interrupt routine not entered
- */
- dev->interrupt = 0;
-
- /*
- * transmitter not busy
- */
- dev->tbusy = 0;
-
- /*
- * make sure we can find the device header given the interrupt number
- */
- irq2dev_map[dev->irq] = dev;
-
- /*
- * install our interrupt service routine
- */
- if (request_irq(dev->irq, &elp_interrupt, 0, "3c505")) {
- irq2dev_map[dev->irq] = NULL;
- return -EAGAIN;
- }
-
- /*
- * enable interrupts on the board
- */
- outb_control(CMDE, dev->base_addr);
-
- /*
- * device is now officially open!
- */
- dev->start = 1;
-
- /*
- * configure adapter memory: we need 10 multicast addresses, default==0
- */
- if (elp_debug >= 3)
- printk("%s: sending 3c505 memory configuration command\n", dev->name);
- adapter->tx_pcb.command = CMD_CONFIGURE_ADAPTER_MEMORY;
- adapter->tx_pcb.data.memconf.cmd_q = 10;
- adapter->tx_pcb.data.memconf.rcv_q = 20;
- adapter->tx_pcb.data.memconf.mcast = 10;
- adapter->tx_pcb.data.memconf.frame = 20;
- adapter->tx_pcb.data.memconf.rcv_b = 20;
- adapter->tx_pcb.data.memconf.progs = 0;
- adapter->tx_pcb.length = sizeof(struct Memconf);
- adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] = 0;
- if (!send_pcb(dev, &adapter->tx_pcb))
- printk("%s: couldn't send memory configuration command\n", dev->name);
- else {
- int timeout = jiffies + TIMEOUT;
- while (adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] == 0 && jiffies < timeout)
- ;
- if (jiffies >= timeout)
- TIMEOUT_MSG(__LINE__);
- }
-
-
- /*
- * configure adapter to receive broadcast messages and wait for response
- */
- if (elp_debug >= 3)
- printk("%s: sending 82586 configure command\n", dev->name);
- adapter->tx_pcb.command = CMD_CONFIGURE_82586;
- adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD;
- adapter->tx_pcb.length = 2;
- adapter->got[CMD_CONFIGURE_82586] = 0;
- if (!send_pcb(dev, &adapter->tx_pcb))
- printk("%s: couldn't send 82586 configure command\n", dev->name);
- else {
- int timeout = jiffies + TIMEOUT;
- while (adapter->got[CMD_CONFIGURE_82586] == 0 && jiffies < timeout)
- ;
- if (jiffies >= timeout)
- TIMEOUT_MSG(__LINE__);
- }
-
- /*
- * queue receive commands to provide buffering
- */
- if (!start_receive(dev, &adapter->tx_pcb))
- printk("%s: start receive command failed \n", dev->name);
- if (elp_debug >= 3)
- printk("%s: start receive command sent\n", dev->name);
-
- MOD_INC_USE_COUNT;
-
- return 0; /* Always succeed */
-}
-
-
-/******************************************************
- *
- * send a packet to the adapter
- *
- ******************************************************/
-
-static int
-send_packet (struct device * dev, unsigned char * ptr, int len)
-{
- int i;
- int timeout = 0;
- elp_device * adapter;
-
- /*
- * make sure the length is even and no shorter than 60 bytes
- */
- unsigned int nlen = (((len < 60) ? 60 : len) + 1) & (~1);
-
- CHECK_NULL(dev);
- CHECK_NULL(ptr);
-
- adapter = dev->priv;
-
- if (nlen < len)
- printk("Warning, bad length nlen=%d len=%d %s(%d)\n",nlen,len,filename,__LINE__);
-
- /*
- * send the adapter a transmit packet command. Ignore segment and offset
- * and make sure the length is even
- */
- adapter->tx_pcb.command = CMD_TRANSMIT_PACKET;
- adapter->tx_pcb.length = sizeof(struct Xmit_pkt);
- adapter->tx_pcb.data.xmit_pkt.buf_ofs
- = adapter->tx_pcb.data.xmit_pkt.buf_seg = 0; /* Unused */
- adapter->tx_pcb.data.xmit_pkt.pkt_len = nlen;
- if (!send_pcb(dev, &adapter->tx_pcb)) {
- return FALSE;
- }
-
- /*
- * write data to the adapter
- */
- cli();
- for (i = 0; i < (nlen/2);i++) {
- while (((inb_status(dev->base_addr)&HRDY) == 0)
- && (timeout++ < 20000))
- ;
- if (timeout >= 20000) {
- sti();
- printk("%s: timeout at %s(%d) writing word %d of %d ***\n",
- dev->name,filename,__LINE__, i, nlen/2);
- return FALSE;
- }
-
- outw_data(*(short *)ptr, dev->base_addr);
- ptr +=2;
- }
- sti();
-
- return TRUE;
-}
-
-/******************************************************
- *
- * start the transmitter
- * return 0 if sent OK, else return 1
- *
- ******************************************************/
-
-static int
-elp_start_xmit (struct sk_buff *skb, struct device *dev)
-{
- CHECK_NULL(dev);
-
- /*
- * not sure what this does, but the 3c509 driver does it, so...
- */
- if (skb == NULL) {
- dev_tint(dev);
- return 0;
- }
-
- /*
- * if we ended up with a munged length, don't send it
- */
- if (skb->len <= 0)
- return 0;
-
- if (elp_debug >= 3)
- printk("%s: request to send packet of length %d\n", dev->name, (int)skb->len);
-
- /*
- * if the transmitter is still busy, we have a transmit timeout...
- */
- if (dev->tbusy) {
- int tickssofar = jiffies - dev->trans_start;
- int stat;
- if (tickssofar < 50) /* was 500, AJT */
- return 1;
- printk("%s: transmit timed out, not resetting adapter\n", dev->name);
- if (((stat=inb_status(dev->base_addr))&ACRF) != 0)
- printk("%s: hmmm...seemed to have missed an interrupt!\n", dev->name);
- printk("%s: status %#02x\n", dev->name, stat);
- dev->trans_start = jiffies;
- dev->tbusy = 0;
- }
-
- /*
- * send the packet at skb->data for skb->len
- */
- if (!send_packet(dev, skb->data, skb->len)) {
- printk("%s: send packet PCB failed\n", dev->name);
- return 1;
- }
-
- if (elp_debug >= 3)
- printk("%s: packet of length %d sent\n", dev->name, (int)skb->len);
-
-
- /*
- * start the transmit timeout
- */
- dev->trans_start = jiffies;
-
- /*
- * the transmitter is now busy
- */
- dev->tbusy = 1;
-
- /*
- * free the buffer
- */
- dev_kfree_skb(skb, FREE_WRITE);
-
- return 0;
-}
-
-/******************************************************
- *
- * return statistics on the board
- *
- ******************************************************/
-
-static struct enet_statistics *
-elp_get_stats (struct device *dev)
-{
- elp_device *adapter = (elp_device *) dev->priv;
-
- if (elp_debug >= 3)
- printk("%s: request for stats\n", dev->name);
-
- /* If the device is closed, just return the latest stats we have,
- - we cannot ask from the adapter without interrupts */
- if (!dev->start)
- return &adapter->stats;
-
- /* send a get statistics command to the board */
- adapter->tx_pcb.command = CMD_NETWORK_STATISTICS;
- adapter->tx_pcb.length = 0;
- adapter->got[CMD_NETWORK_STATISTICS] = 0;
- if (!send_pcb(dev, &adapter->tx_pcb))
- printk("%s: couldn't send get statistics command\n", dev->name);
- else {
- int timeout = jiffies + TIMEOUT;
- while (adapter->got[CMD_NETWORK_STATISTICS] == 0 && jiffies < timeout)
- ;
- if (jiffies >= timeout) {
- TIMEOUT_MSG(__LINE__);
- return &adapter->stats;
- }
- }
-
- /* statistics are now up to date */
- return &adapter->stats;
-}
-
-/******************************************************
- *
- * close the board
- *
- ******************************************************/
-
-static int
-elp_close (struct device *dev)
-{
- elp_device * adapter;
-
- CHECK_NULL(dev);
- adapter = dev->priv;
- CHECK_NULL(adapter);
-
- if (elp_debug >= 3)
- printk("%s: request to close device\n", dev->name);
-
- /* Someone may request the device statistic information even when
- * the interface is closed. The following will update the statistics
- * structure in the driver, so we'll be able to give current statistics.
- */
- (void) elp_get_stats(dev);
-
- /*
- * disable interrupts on the board
- */
- outb_control(0x00, dev->base_addr);
-
- /*
- * flag transmitter as busy (i.e. not available)
- */
- dev->tbusy = 1;
-
- /*
- * indicate device is closed
- */
- dev->start = 0;
-
- /*
- * release the IRQ
- */
- free_irq(dev->irq);
-
- /*
- * and we no longer have to map irq to dev either
- */
- irq2dev_map[dev->irq] = 0;
-
- MOD_DEC_USE_COUNT;
-
- return 0;
-}
-
-
-/************************************************************
- *
- * Set multicast list
- * num_addrs==0: clear mc_list
- * num_addrs==-1: set promiscuous mode
- * num_addrs>0: set mc_list
- *
- ************************************************************/
-
-static void
-elp_set_mc_list (struct device *dev)
-{
- elp_device *adapter = (elp_device *) dev->priv;
- struct dev_mc_list *dmi=dev->mc_list;
- int i;
-
- if (elp_debug >= 3)
- printk("%s: request to set multicast list\n", dev->name);
-
- if (!(dev->flags&(IFF_PROMISC|IFF_ALLMULTI)))
- {
- /* send a "load multicast list" command to the board, max 10 addrs/cmd */
- /* if num_addrs==0 the list will be cleared */
- adapter->tx_pcb.command = CMD_LOAD_MULTICAST_LIST;
- adapter->tx_pcb.length = 6*dev->mc_count;
- for (i=0;i<dev->mc_count;i++)
- {
- memcpy(adapter->tx_pcb.data.multicast[i], dmi->dmi_addr,6);
- dmi=dmi->next;
- }
- adapter->got[CMD_LOAD_MULTICAST_LIST] = 0;
- if (!send_pcb(dev, &adapter->tx_pcb))
- printk("%s: couldn't send set_multicast command\n", dev->name);
- else {
- int timeout = jiffies + TIMEOUT;
- while (adapter->got[CMD_LOAD_MULTICAST_LIST] == 0 && jiffies < timeout)
- ;
- if (jiffies >= timeout) {
- TIMEOUT_MSG(__LINE__);
- }
- }
- if (dev->mc_count)
- adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD | RECV_MULTI;
- else /* num_addrs == 0 */
- adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD;
- }
- else
- adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_PROMISC;
- /*
- * configure adapter to receive messages (as specified above)
- * and wait for response
- */
- if (elp_debug >= 3)
- printk("%s: sending 82586 configure command\n", dev->name);
- adapter->tx_pcb.command = CMD_CONFIGURE_82586;
- adapter->tx_pcb.length = 2;
- adapter->got[CMD_CONFIGURE_82586] = 0;
- if (!send_pcb(dev, &adapter->tx_pcb))
- printk("%s: couldn't send 82586 configure command\n", dev->name);
- else {
- int timeout = jiffies + TIMEOUT;
- while (adapter->got[CMD_CONFIGURE_82586] == 0 && jiffies < timeout)
- ;
- if (jiffies >= timeout)
- TIMEOUT_MSG(__LINE__);
- }
-}
-
-/******************************************************
- *
- * initialise Etherlink Plus board
- *
- ******************************************************/
-
-static void
-elp_init (struct device *dev)
-{
- elp_device * adapter;
-
- CHECK_NULL(dev);
-
- /*
- * set ptrs to various functions
- */
- dev->open = elp_open; /* local */
- dev->stop = elp_close; /* local */
- dev->get_stats = elp_get_stats; /* local */
- dev->hard_start_xmit = elp_start_xmit; /* local */
- dev->set_multicast_list = elp_set_mc_list; /* local */
-
- /* Setup the generic properties */
- ether_setup(dev);
-
- /*
- * setup ptr to adapter specific information
- */
- adapter = (elp_device *)(dev->priv = kmalloc(sizeof(elp_device), GFP_KERNEL));
- CHECK_NULL(adapter);
- if (adapter == NULL)
- return;
- memset(&(adapter->stats), 0, sizeof(struct enet_statistics));
-
- /*
- * memory information
- */
- dev->mem_start = dev->mem_end = dev->rmem_end = dev->rmem_start = 0;
-}
-
-/************************************************************
- *
- * A couple of tests to see if there's 3C505 or not
- * Called only by elp_autodetect
- ************************************************************/
-
-static int
-elp_sense (struct device * dev)
-{
- int timeout;
- int addr=dev->base_addr;
- const char *name=dev->name;
- long flags;
- byte orig_HCR, orig_HSR;
-
- if (check_region(addr, 0xf))
- return -1;
-
- orig_HCR=inb_control(addr);
- orig_HSR=inb_status(addr);
-
- if (elp_debug > 0)
- printk(search_msg, name, addr);
-
- if (((orig_HCR==0xff) && (orig_HSR==0xff)) ||
- ((orig_HCR & DIR) != (orig_HSR & DIR))) {
- if (elp_debug > 0)
- printk(notfound_msg, 1);
- return -1; /* It can't be 3c505 if HCR.DIR != HSR.DIR */
- }
-
- /* Enable interrupts - we need timers! */
- save_flags(flags);
- sti();
-
- /* Wait for a while; the adapter may still be booting up */
- if (elp_debug > 0)
- printk(stilllooking_msg);
- for (timeout = jiffies + (100 * 15); jiffies <= timeout; )
- if (GET_ASF(addr) != ASF_PCB_END)
- break;
-
- if (orig_HCR & DIR) {
- /* If HCR.DIR is up, we pull it down. HSR.DIR should follow. */
- outb_control(orig_HCR & ~DIR,addr);
- timeout = jiffies+30;
- while (jiffies < timeout)
- ;
- restore_flags(flags);
- if (inb_status(addr) & DIR) {
- outb_control(orig_HCR,addr);
- if (elp_debug > 0)
- printk(notfound_msg, 2);
- return -1;
- }
- } else {
- /* If HCR.DIR is down, we pull it up. HSR.DIR should follow. */
- outb_control(orig_HCR | DIR,addr);
- timeout = jiffies+300;
- while (jiffies < timeout)
- ;
- restore_flags(flags);
- if (!(inb_status(addr) & DIR)) {
- outb_control(orig_HCR,addr);
- if (elp_debug > 0)
- printk(notfound_msg, 3);
- return -1;
- }
- }
- /*
- * It certainly looks like a 3c505. If it has DMA enabled, it needs
- * a hard reset. Also, do a hard reset if selected at the compile time.
- */
- if (elp_debug > 0)
- printk(found_msg);
-
- if (((orig_HCR==0x35) && (orig_HSR==0x5b)) || ELP_NEED_HARD_RESET)
- adapter_hard_reset(dev);
- return 0;
-}
-
-/*************************************************************
- *
- * Search through addr_list[] and try to find a 3C505
- * Called only by eplus_probe
- *************************************************************/
-
-static int
-elp_autodetect (struct device * dev)
-{
- int idx=0;
-
- /* if base address set, then only check that address
- otherwise, run through the table */
- if (dev->base_addr != 0) { /* dev->base_addr == 0 ==> plain autodetect */
- if (elp_sense(dev) == 0)
- return dev->base_addr;
- } else while ( (dev->base_addr=addr_list[idx++]) ) {
- if (elp_sense(dev) == 0)
- return dev->base_addr;
- }
-
- /* could not find an adapter */
- if (elp_debug > 0)
- printk(couldnot_msg, dev->name);
-
- return 0; /* Because of this, the layer above will return -ENODEV */
-}
-
-/******************************************************
- *
- * probe for an Etherlink Plus board at the specified address
- *
- ******************************************************/
-
-int
-elplus_probe (struct device *dev)
-{
- elp_device adapter;
- int i;
-
- CHECK_NULL(dev);
-
- /*
- * setup adapter structure
- */
-
- dev->base_addr = elp_autodetect(dev);
- if ( !(dev->base_addr) )
- return -ENODEV;
-
- /*
- * As we enter here from bootup, the adapter should have IRQs enabled,
- * but we can as well enable them anyway.
- */
- outb_control(inb_control(dev->base_addr) | CMDE, dev->base_addr);
- autoirq_setup(0);
-
- /*
- * use ethernet address command to probe for board in polled mode
- * (this also makes us the IRQ that we need for automatic detection)
- */
- adapter.tx_pcb.command = CMD_STATION_ADDRESS;
- adapter.tx_pcb.length = 0;
- if (!send_pcb (dev, &adapter.tx_pcb) ||
- !receive_pcb(dev, &adapter.rx_pcb) ||
- (adapter.rx_pcb.command != CMD_ADDRESS_RESPONSE) ||
- (adapter.rx_pcb.length != 6)) {
- printk("%s: not responding to first PCB\n", dev->name);
- return -ENODEV;
- }
-
- if (dev->irq) { /* Is there a preset IRQ? */
- if (dev->irq != autoirq_report(0)) {
- printk("%s: Detected IRQ doesn't match user-defined one.\n",dev->name);
- return -ENODEV;
- }
- /* if dev->irq == autoirq_report(0), all is well */
- } else /* No preset IRQ; just use what we can detect */
- dev->irq=autoirq_report(0);
- switch (dev->irq) { /* Legal, sane? */
- case 0:
- printk("%s: No IRQ reported by autoirq_report().\n",dev->name);
- printk("%s: Check the jumpers of your 3c505 board.\n",dev->name);
- return -ENODEV;
- case 1:
- case 6:
- case 8:
- case 13:
- printk("%s: Impossible IRQ %d reported by autoirq_report().\n",
- dev->name, dev->irq);
- return -ENODEV;
- }
- /*
- * Now we have the IRQ number so we can disable the interrupts from
- * the board until the board is opened.
- */
- outb_control(inb_control(dev->base_addr) & ~CMDE, dev->base_addr);
-
- /*
- * copy ethernet address into structure
- */
- for (i = 0; i < 6; i++)
- dev->dev_addr[i] = adapter.rx_pcb.data.eth_addr[i];
-
- /*
- * print remainder of startup message
- */
- printk("%s: 3c505 card found at I/O %#lx using IRQ%d"
- " has address %02x:%02x:%02x:%02x:%02x:%02x\n",
- dev->name, dev->base_addr, dev->irq,
- dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
- dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
-
- /*
- * and reserve the address region
- */
- request_region(dev->base_addr, ELP_IO_EXTENT, "3c505");
-
- /*
- * initialise the device
- */
- elp_init(dev);
- return 0;
-}
-
-#ifdef MODULE
-static char devicename[9] = { 0, };
-static struct device dev_3c505 = {
- devicename, /* device name is inserted by linux/drivers/net/net_init.c */
- 0, 0, 0, 0,
- 0, 0,
- 0, 0, 0, NULL, elplus_probe };
-
-int io = 0x300;
-int irq = 0;
-
-int init_module(void)
-{
- if (io == 0)
- printk("3c505: You should not use auto-probing with insmod!\n");
- dev_3c505.base_addr = io;
- dev_3c505.irq = irq;
- if (register_netdev(&dev_3c505) != 0) {
- printk("3c505: register_netdev() returned non-zero.\n");
- return -EIO;
- }
- return 0;
-}
-
-void
-cleanup_module(void)
-{
- unregister_netdev(&dev_3c505);
- kfree(dev_3c505.priv);
- dev_3c505.priv = NULL;
-
- /* If we don't do this, we can't re-insmod it later. */
- release_region(dev_3c505.base_addr, ELP_IO_EXTENT);
-}
-#endif /* MODULE */
diff --git a/i386/i386at/gpl/linux/net/3c505.h b/i386/i386at/gpl/linux/net/3c505.h
deleted file mode 100644
index f7d28368..00000000
--- a/i386/i386at/gpl/linux/net/3c505.h
+++ /dev/null
@@ -1,245 +0,0 @@
-/*****************************************************************
- *
- * defines for 3Com Etherlink Plus adapter
- *
- *****************************************************************/
-
-/*
- * I/O register offsets
- */
-#define PORT_COMMAND 0x00 /* read/write, 8-bit */
-#define PORT_STATUS 0x02 /* read only, 8-bit */
-#define PORT_AUXDMA 0x02 /* write only, 8-bit */
-#define PORT_DATA 0x04 /* read/write, 16-bit */
-#define PORT_CONTROL 0x06 /* read/write, 8-bit */
-
-#define ELP_IO_EXTENT 0x10 /* size of used IO registers */
-
-/*
- * host control registers bits
- */
-#define ATTN 0x80 /* attention */
-#define FLSH 0x40 /* flush data register */
-#define DMAE 0x20 /* DMA enable */
-#define DIR 0x10 /* direction */
-#define TCEN 0x08 /* terminal count interrupt enable */
-#define CMDE 0x04 /* command register interrupt enable */
-#define HSF2 0x02 /* host status flag 2 */
-#define HSF1 0x01 /* host status flag 1 */
-
-/*
- * combinations of HSF flags used for PCB transmission
- */
-#define HSF_PCB_ACK HSF1
-#define HSF_PCB_NAK HSF2
-#define HSF_PCB_END (HSF2|HSF1)
-#define HSF_PCB_MASK (HSF2|HSF1)
-
-/*
- * host status register bits
- */
-#define HRDY 0x80 /* data register ready */
-#define HCRE 0x40 /* command register empty */
-#define ACRF 0x20 /* adapter command register full */
-/* #define DIR 0x10 direction - same as in control register */
-#define DONE 0x08 /* DMA done */
-#define ASF3 0x04 /* adapter status flag 3 */
-#define ASF2 0x02 /* adapter status flag 2 */
-#define ASF1 0x01 /* adapter status flag 1 */
-
-/*
- * combinations of ASF flags used for PCB reception
- */
-#define ASF_PCB_ACK ASF1
-#define ASF_PCB_NAK ASF2
-#define ASF_PCB_END (ASF2|ASF1)
-#define ASF_PCB_MASK (ASF2|ASF1)
-
-/*
- * host aux DMA register bits
- */
-#define DMA_BRST 0x01 /* DMA burst */
-
-/*
- * maximum amount of data data allowed in a PCB
- */
-#define MAX_PCB_DATA 62
-
-/*****************************************************************
- *
- * timeout value
- * this is a rough value used for loops to stop them from
- * locking up the whole machine in the case of failure or
- * error conditions
- *
- *****************************************************************/
-
-#define TIMEOUT 300
-
-/*****************************************************************
- *
- * PCB commands
- *
- *****************************************************************/
-
-enum {
- /*
- * host PCB commands
- */
- CMD_CONFIGURE_ADAPTER_MEMORY = 0x01,
- CMD_CONFIGURE_82586 = 0x02,
- CMD_STATION_ADDRESS = 0x03,
- CMD_DMA_DOWNLOAD = 0x04,
- CMD_DMA_UPLOAD = 0x05,
- CMD_PIO_DOWNLOAD = 0x06,
- CMD_PIO_UPLOAD = 0x07,
- CMD_RECEIVE_PACKET = 0x08,
- CMD_TRANSMIT_PACKET = 0x09,
- CMD_NETWORK_STATISTICS = 0x0a,
- CMD_LOAD_MULTICAST_LIST = 0x0b,
- CMD_CLEAR_PROGRAM = 0x0c,
- CMD_DOWNLOAD_PROGRAM = 0x0d,
- CMD_EXECUTE_PROGRAM = 0x0e,
- CMD_SELF_TEST = 0x0f,
- CMD_SET_STATION_ADDRESS = 0x10,
- CMD_ADAPTER_INFO = 0x11,
- NUM_TRANSMIT_CMDS,
-
- /*
- * adapter PCB commands
- */
- CMD_CONFIGURE_ADAPTER_RESPONSE = 0x31,
- CMD_CONFIGURE_82586_RESPONSE = 0x32,
- CMD_ADDRESS_RESPONSE = 0x33,
- CMD_DOWNLOAD_DATA_REQUEST = 0x34,
- CMD_UPLOAD_DATA_REQUEST = 0x35,
- CMD_RECEIVE_PACKET_COMPLETE = 0x38,
- CMD_TRANSMIT_PACKET_COMPLETE = 0x39,
- CMD_NETWORK_STATISTICS_RESPONSE = 0x3a,
- CMD_LOAD_MULTICAST_RESPONSE = 0x3b,
- CMD_CLEAR_PROGRAM_RESPONSE = 0x3c,
- CMD_DOWNLOAD_PROGRAM_RESPONSE = 0x3d,
- CMD_EXECUTE_RESPONSE = 0x3e,
- CMD_SELF_TEST_RESPONSE = 0x3f,
- CMD_SET_ADDRESS_RESPONSE = 0x40,
- CMD_ADAPTER_INFO_RESPONSE = 0x41
-};
-
-/* Definitions for the PCB data structure */
-
-/* Data units */
-typedef unsigned char byte;
-typedef unsigned short int word;
-typedef unsigned long int dword;
-
-/* Data structures */
-struct Memconf {
- word cmd_q,
- rcv_q,
- mcast,
- frame,
- rcv_b,
- progs;
-};
-
-struct Rcv_pkt {
- word buf_ofs,
- buf_seg,
- buf_len,
- timeout;
-};
-
-struct Xmit_pkt {
- word buf_ofs,
- buf_seg,
- pkt_len;
-};
-
-struct Rcv_resp {
- word buf_ofs,
- buf_seg,
- buf_len,
- pkt_len,
- timeout,
- status;
- dword timetag;
-};
-
-struct Xmit_resp {
- word buf_ofs,
- buf_seg,
- c_stat,
- status;
-};
-
-
-struct Netstat {
- dword tot_recv,
- tot_xmit;
- word err_CRC,
- err_align,
- err_res,
- err_ovrrun;
-};
-
-
-struct Selftest {
- word error;
- union {
- word ROM_cksum;
- struct {
- word ofs, seg;
- } RAM;
- word i82586;
- } failure;
-};
-
-struct Info {
- byte minor_vers,
- major_vers;
- word ROM_cksum,
- RAM_sz,
- free_ofs,
- free_seg;
-};
-
-struct Memdump {
- word size,
- off,
- seg;
-};
-
-/*
-Primary Command Block. The most important data structure. All communication
-between the host and the adapter is done with these. (Except for the actual
-ethernet data, which has different packaging.)
-*/
-typedef struct {
- byte command;
- byte length;
- union {
- struct Memconf memconf;
- word configure;
- struct Rcv_pkt rcv_pkt;
- struct Xmit_pkt xmit_pkt;
- byte multicast[10][6];
- byte eth_addr[6];
- byte failed;
- struct Rcv_resp rcv_resp;
- struct Xmit_resp xmit_resp;
- struct Netstat netstat;
- struct Selftest selftest;
- struct Info info;
- struct Memdump memdump;
- byte raw[62];
- } data;
-} pcb_struct;
-
-/* These defines for 'configure' */
-#define RECV_STATION 0x00
-#define RECV_BROAD 0x01
-#define RECV_MULTI 0x02
-#define RECV_PROMISC 0x04
-#define NO_LOOPBACK 0x00
-#define INT_LOOPBACK 0x08
-#define EXT_LOOPBACK 0x10
diff --git a/i386/i386at/gpl/linux/net/3c507.c b/i386/i386at/gpl/linux/net/3c507.c
deleted file mode 100644
index f18bc0a3..00000000
--- a/i386/i386at/gpl/linux/net/3c507.c
+++ /dev/null
@@ -1,923 +0,0 @@
-/* 3c507.c: An EtherLink16 device driver for Linux. */
-/*
- Written 1993,1994 by Donald Becker.
-
- Copyright 1993 United States Government as represented by the
- Director, National Security Agency.
-
- This software may be used and distributed according to the terms
- of the GNU Public License, incorporated herein by reference.
-
- The author may be reached as becker@CESDIS.gsfc.nasa.gov, or C/O
- Center of Excellence in Space Data and Information Sciences
- Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
-
- Thanks go to jennings@Montrouge.SMR.slb.com ( Patrick Jennings)
- and jrs@world.std.com (Rick Sladkey) for testing and bugfixes.
- Mark Salazar <leslie@access.digex.net> made the changes for cards with
- only 16K packet buffers.
-
- Things remaining to do:
- Verify that the tx and rx buffers don't have fencepost errors.
- Move the theory of operation and memory map documentation.
- The statistics need to be updated correctly.
-*/
-
-static const char *version =
- "3c507.c:v1.10 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
-
-
-#include <linux/module.h>
-
-/*
- Sources:
- This driver wouldn't have been written with the availability of the
- Crynwr driver source code. It provided a known-working implementation
- that filled in the gaping holes of the Intel documentation. Three cheers
- for Russ Nelson.
-
- Intel Microcommunications Databook, Vol. 1, 1990. It provides just enough
- info that the casual reader might think that it documents the i82586 :-<.
-*/
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ptrace.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/string.h>
-#include <asm/system.h>
-#include <asm/bitops.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <linux/errno.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/malloc.h>
-
-
-/* use 0 for production, 1 for verification, 2..7 for debug */
-#ifndef NET_DEBUG
-#define NET_DEBUG 1
-#endif
-static unsigned int net_debug = NET_DEBUG;
-
-/* A zero-terminated list of common I/O addresses to be probed. */
-static unsigned int netcard_portlist[] =
- { 0x300, 0x320, 0x340, 0x280, 0};
-
-/*
- Details of the i82586.
-
- You'll really need the databook to understand the details of this part,
- but the outline is that the i82586 has two separate processing units.
- Both are started from a list of three configuration tables, of which only
- the last, the System Control Block (SCB), is used after reset-time. The SCB
- has the following fields:
- Status word
- Command word
- Tx/Command block addr.
- Rx block addr.
- The command word accepts the following controls for the Tx and Rx units:
- */
-
-#define CUC_START 0x0100
-#define CUC_RESUME 0x0200
-#define CUC_SUSPEND 0x0300
-#define RX_START 0x0010
-#define RX_RESUME 0x0020
-#define RX_SUSPEND 0x0030
-
-/* The Rx unit uses a list of frame descriptors and a list of data buffer
- descriptors. We use full-sized (1518 byte) data buffers, so there is
- a one-to-one pairing of frame descriptors to buffer descriptors.
-
- The Tx ("command") unit executes a list of commands that look like:
- Status word Written by the 82586 when the command is done.
- Command word Command in lower 3 bits, post-command action in upper 3
- Link word The address of the next command.
- Parameters (as needed).
-
- Some definitions related to the Command Word are:
- */
-#define CMD_EOL 0x8000 /* The last command of the list, stop. */
-#define CMD_SUSP 0x4000 /* Suspend after doing cmd. */
-#define CMD_INTR 0x2000 /* Interrupt after doing cmd. */
-
-enum commands {
- CmdNOp = 0, CmdSASetup = 1, CmdConfigure = 2, CmdMulticastList = 3,
- CmdTx = 4, CmdTDR = 5, CmdDump = 6, CmdDiagnose = 7};
-
-/* Information that need to be kept for each board. */
-struct net_local {
- struct enet_statistics stats;
- int last_restart;
- ushort rx_head;
- ushort rx_tail;
- ushort tx_head;
- ushort tx_cmd_link;
- ushort tx_reap;
-};
-
-/*
- Details of the EtherLink16 Implementation
- The 3c507 is a generic shared-memory i82586 implementation.
- The host can map 16K, 32K, 48K, or 64K of the 64K memory into
- 0x0[CD][08]0000, or all 64K into 0xF[02468]0000.
- */
-
-/* Offsets from the base I/O address. */
-#define SA_DATA 0 /* Station address data, or 3Com signature. */
-#define MISC_CTRL 6 /* Switch the SA_DATA banks, and bus config bits. */
-#define RESET_IRQ 10 /* Reset the latched IRQ line. */
-#define SIGNAL_CA 11 /* Frob the 82586 Channel Attention line. */
-#define ROM_CONFIG 13
-#define MEM_CONFIG 14
-#define IRQ_CONFIG 15
-#define EL16_IO_EXTENT 16
-
-/* The ID port is used at boot-time to locate the ethercard. */
-#define ID_PORT 0x100
-
-/* Offsets to registers in the mailbox (SCB). */
-#define iSCB_STATUS 0x8
-#define iSCB_CMD 0xA
-#define iSCB_CBL 0xC /* Command BLock offset. */
-#define iSCB_RFA 0xE /* Rx Frame Area offset. */
-
-/* Since the 3c507 maps the shared memory window so that the last byte is
- at 82586 address FFFF, the first byte is at 82586 address 0, 16K, 32K, or
- 48K corresponding to window sizes of 64K, 48K, 32K and 16K respectively.
- We can account for this be setting the 'SBC Base' entry in the ISCP table
- below for all the 16 bit offset addresses, and also adding the 'SCB Base'
- value to all 24 bit physical addresses (in the SCP table and the TX and RX
- Buffer Descriptors).
- -Mark
- */
-#define SCB_BASE ((unsigned)64*1024 - (dev->mem_end - dev->mem_start))
-
-/*
- What follows in 'init_words[]' is the "program" that is downloaded to the
- 82586 memory. It's mostly tables and command blocks, and starts at the
- reset address 0xfffff6. This is designed to be similar to the EtherExpress,
- thus the unusual location of the SCB at 0x0008.
-
- Even with the additional "don't care" values, doing it this way takes less
- program space than initializing the individual tables, and I feel it's much
- cleaner.
-
- The databook is particularly useless for the first two structures, I had
- to use the Crynwr driver as an example.
-
- The memory setup is as follows:
- */
-
-#define CONFIG_CMD 0x0018
-#define SET_SA_CMD 0x0024
-#define SA_OFFSET 0x002A
-#define IDLELOOP 0x30
-#define TDR_CMD 0x38
-#define TDR_TIME 0x3C
-#define DUMP_CMD 0x40
-#define DIAG_CMD 0x48
-#define SET_MC_CMD 0x4E
-#define DUMP_DATA 0x56 /* A 170 byte buffer for dump and Set-MC into. */
-
-#define TX_BUF_START 0x0100
-#define NUM_TX_BUFS 4
-#define TX_BUF_SIZE (1518+14+20+16) /* packet+header+TBD */
-
-#define RX_BUF_START 0x2000
-#define RX_BUF_SIZE (1518+14+18) /* packet+header+RBD */
-#define RX_BUF_END (dev->mem_end - dev->mem_start)
-
-/*
- That's it: only 86 bytes to set up the beast, including every extra
- command available. The 170 byte buffer at DUMP_DATA is shared between the
- Dump command (called only by the diagnostic program) and the SetMulticastList
- command.
-
- To complete the memory setup you only have to write the station address at
- SA_OFFSET and create the Tx & Rx buffer lists.
-
- The Tx command chain and buffer list is setup as follows:
- A Tx command table, with the data buffer pointing to...
- A Tx data buffer descriptor. The packet is in a single buffer, rather than
- chaining together several smaller buffers.
- A NoOp command, which initially points to itself,
- And the packet data.
-
- A transmit is done by filling in the Tx command table and data buffer,
- re-writing the NoOp command, and finally changing the offset of the last
- command to point to the current Tx command. When the Tx command is finished,
- it jumps to the NoOp, when it loops until the next Tx command changes the
- "link offset" in the NoOp. This way the 82586 never has to go through the
- slow restart sequence.
-
- The Rx buffer list is set up in the obvious ring structure. We have enough
- memory (and low enough interrupt latency) that we can avoid the complicated
- Rx buffer linked lists by alway associating a full-size Rx data buffer with
- each Rx data frame.
-
- I current use four transmit buffers starting at TX_BUF_START (0x0100), and
- use the rest of memory, from RX_BUF_START to RX_BUF_END, for Rx buffers.
-
- */
-
-unsigned short init_words[] = {
- /* System Configuration Pointer (SCP). */
- 0x0000, /* Set bus size to 16 bits. */
- 0,0, /* pad words. */
- 0x0000,0x0000, /* ISCP phys addr, set in init_82586_mem(). */
-
- /* Intermediate System Configuration Pointer (ISCP). */
- 0x0001, /* Status word that's cleared when init is done. */
- 0x0008,0,0, /* SCB offset, (skip, skip) */
-
- /* System Control Block (SCB). */
- 0,0xf000|RX_START|CUC_START, /* SCB status and cmd. */
- CONFIG_CMD, /* Command list pointer, points to Configure. */
- RX_BUF_START, /* Rx block list. */
- 0,0,0,0, /* Error count: CRC, align, buffer, overrun. */
-
- /* 0x0018: Configure command. Change to put MAC data with packet. */
- 0, CmdConfigure, /* Status, command. */
- SET_SA_CMD, /* Next command is Set Station Addr. */
- 0x0804, /* "4" bytes of config data, 8 byte FIFO. */
- 0x2e40, /* Magic values, including MAC data location. */
- 0, /* Unused pad word. */
-
- /* 0x0024: Setup station address command. */
- 0, CmdSASetup,
- SET_MC_CMD, /* Next command. */
- 0xaa00,0xb000,0x0bad, /* Station address (to be filled in) */
-
- /* 0x0030: NOP, looping back to itself. Point to first Tx buffer to Tx. */
- 0, CmdNOp, IDLELOOP, 0 /* pad */,
-
- /* 0x0038: A unused Time-Domain Reflectometer command. */
- 0, CmdTDR, IDLELOOP, 0,
-
- /* 0x0040: An unused Dump State command. */
- 0, CmdDump, IDLELOOP, DUMP_DATA,
-
- /* 0x0048: An unused Diagnose command. */
- 0, CmdDiagnose, IDLELOOP,
-
- /* 0x004E: An empty set-multicast-list command. */
- 0, CmdMulticastList, IDLELOOP, 0,
-};
-
-/* Index to functions, as function prototypes. */
-
-extern int el16_probe(struct device *dev); /* Called from Space.c */
-
-static int el16_probe1(struct device *dev, int ioaddr);
-static int el16_open(struct device *dev);
-static int el16_send_packet(struct sk_buff *skb, struct device *dev);
-static void el16_interrupt(int irq, struct pt_regs *regs);
-static void el16_rx(struct device *dev);
-static int el16_close(struct device *dev);
-static struct enet_statistics *el16_get_stats(struct device *dev);
-
-static void hardware_send_packet(struct device *dev, void *buf, short length);
-void init_82586_mem(struct device *dev);
-
-
-#ifdef HAVE_DEVLIST
-struct netdev_entry netcard_drv =
-{"3c507", el16_probe1, EL16_IO_EXTENT, netcard_portlist};
-#endif
-
-/* Check for a network adaptor of this type, and return '0' iff one exists.
- If dev->base_addr == 0, probe all likely locations.
- If dev->base_addr == 1, always return failure.
- If dev->base_addr == 2, (detachable devices only) allocate space for the
- device and return success.
- */
-int
-el16_probe(struct device *dev)
-{
- int base_addr = dev ? dev->base_addr : 0;
- int i;
-
- if (base_addr > 0x1ff) /* Check a single specified location. */
- return el16_probe1(dev, base_addr);
- else if (base_addr != 0)
- return ENXIO; /* Don't probe at all. */
-
- for (i = 0; netcard_portlist[i]; i++) {
- int ioaddr = netcard_portlist[i];
- if (check_region(ioaddr, EL16_IO_EXTENT))
- continue;
- if (el16_probe1(dev, ioaddr) == 0)
- return 0;
- }
-
- return ENODEV;
-}
-
-int el16_probe1(struct device *dev, int ioaddr)
-{
- static unsigned char init_ID_done = 0, version_printed = 0;
- int i, irq, irqval;
-
- if (init_ID_done == 0) {
- ushort lrs_state = 0xff;
- /* Send the ID sequence to the ID_PORT to enable the board(s). */
- outb(0x00, ID_PORT);
- for(i = 0; i < 255; i++) {
- outb(lrs_state, ID_PORT);
- lrs_state <<= 1;
- if (lrs_state & 0x100)
- lrs_state ^= 0xe7;
- }
- outb(0x00, ID_PORT);
- init_ID_done = 1;
- }
-
- if (inb(ioaddr) == '*' && inb(ioaddr+1) == '3'
- && inb(ioaddr+2) == 'C' && inb(ioaddr+3) == 'O')
- ;
- else
- return ENODEV;
-
- /* Allocate a new 'dev' if needed. */
- if (dev == NULL)
- dev = init_etherdev(0, sizeof(struct net_local));
-
- if (net_debug && version_printed++ == 0)
- printk(version);
-
- printk("%s: 3c507 at %#x,", dev->name, ioaddr);
-
- /* We should make a few more checks here, like the first three octets of
- the S.A. for the manufacturer's code. */
-
- irq = inb(ioaddr + IRQ_CONFIG) & 0x0f;
-
- irqval = request_irq(irq, &el16_interrupt, 0, "3c507");
- if (irqval) {
- printk ("unable to get IRQ %d (irqval=%d).\n", irq, irqval);
- return EAGAIN;
- }
-
- /* We've committed to using the board, and can start filling in *dev. */
- request_region(ioaddr, EL16_IO_EXTENT, "3c507");
- dev->base_addr = ioaddr;
-
- outb(0x01, ioaddr + MISC_CTRL);
- for (i = 0; i < 6; i++) {
- dev->dev_addr[i] = inb(ioaddr + i);
- printk(" %02x", dev->dev_addr[i]);
- }
-
- if ((dev->mem_start & 0xf) > 0)
- net_debug = dev->mem_start & 7;
-
-#ifdef MEM_BASE
- dev->mem_start = MEM_BASE;
- dev->mem_end = dev->mem_start + 0x10000;
-#else
- {
- int base;
- int size;
- char mem_config = inb(ioaddr + MEM_CONFIG);
- if (mem_config & 0x20) {
- size = 64*1024;
- base = 0xf00000 + (mem_config & 0x08 ? 0x080000
- : ((mem_config & 3) << 17));
- } else {
- size = ((mem_config & 3) + 1) << 14;
- base = 0x0c0000 + ( (mem_config & 0x18) << 12);
- }
- dev->mem_start = base;
- dev->mem_end = base + size;
- }
-#endif
-
- dev->if_port = (inb(ioaddr + ROM_CONFIG) & 0x80) ? 1 : 0;
- dev->irq = inb(ioaddr + IRQ_CONFIG) & 0x0f;
-
- printk(", IRQ %d, %sternal xcvr, memory %#lx-%#lx.\n", dev->irq,
- dev->if_port ? "ex" : "in", dev->mem_start, dev->mem_end-1);
-
- if (net_debug)
- printk(version);
-
- /* Initialize the device structure. */
- dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
- if (dev->priv == NULL)
- return -ENOMEM;
- memset(dev->priv, 0, sizeof(struct net_local));
-
- dev->open = el16_open;
- dev->stop = el16_close;
- dev->hard_start_xmit = el16_send_packet;
- dev->get_stats = el16_get_stats;
-
- ether_setup(dev); /* Generic ethernet behaviour */
-
- dev->flags&=~IFF_MULTICAST; /* Multicast doesn't work */
-
- return 0;
-}
-
-
-
-static int
-el16_open(struct device *dev)
-{
- irq2dev_map[dev->irq] = dev;
-
- /* Initialize the 82586 memory and start it. */
- init_82586_mem(dev);
-
- dev->tbusy = 0;
- dev->interrupt = 0;
- dev->start = 1;
-
- MOD_INC_USE_COUNT;
-
- return 0;
-}
-
-static int
-el16_send_packet(struct sk_buff *skb, struct device *dev)
-{
- struct net_local *lp = (struct net_local *)dev->priv;
- int ioaddr = dev->base_addr;
- short *shmem = (short*)dev->mem_start;
-
- if (dev->tbusy) {
- /* If we get here, some higher level has decided we are broken.
- There should really be a "kick me" function call instead. */
- int tickssofar = jiffies - dev->trans_start;
- if (tickssofar < 5)
- return 1;
- if (net_debug > 1)
- printk("%s: transmit timed out, %s? ", dev->name,
- shmem[iSCB_STATUS>>1] & 0x8000 ? "IRQ conflict" :
- "network cable problem");
- /* Try to restart the adaptor. */
- if (lp->last_restart == lp->stats.tx_packets) {
- if (net_debug > 1) printk("Resetting board.\n");
- /* Completely reset the adaptor. */
- init_82586_mem(dev);
- } else {
- /* Issue the channel attention signal and hope it "gets better". */
- if (net_debug > 1) printk("Kicking board.\n");
- shmem[iSCB_CMD>>1] = 0xf000|CUC_START|RX_START;
- outb(0, ioaddr + SIGNAL_CA); /* Issue channel-attn. */
- lp->last_restart = lp->stats.tx_packets;
- }
- dev->tbusy=0;
- dev->trans_start = jiffies;
- }
-
- /* If some higher layer thinks we've missed an tx-done interrupt
- we are passed NULL. Caution: dev_tint() handles the cli()/sti()
- itself. */
- if (skb == NULL) {
- dev_tint(dev);
- return 0;
- }
-
- /* Block a timer-based transmit from overlapping. */
- if (set_bit(0, (void*)&dev->tbusy) != 0)
- printk("%s: Transmitter access conflict.\n", dev->name);
- else {
- short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
- unsigned char *buf = skb->data;
-
- /* Disable the 82586's input to the interrupt line. */
- outb(0x80, ioaddr + MISC_CTRL);
- hardware_send_packet(dev, buf, length);
- dev->trans_start = jiffies;
- /* Enable the 82586 interrupt input. */
- outb(0x84, ioaddr + MISC_CTRL);
- }
-
- dev_kfree_skb (skb, FREE_WRITE);
-
- /* You might need to clean up and record Tx statistics here. */
-
- return 0;
-}
-
-/* The typical workload of the driver:
- Handle the network interface interrupts. */
-static void
-el16_interrupt(int irq, struct pt_regs *regs)
-{
- struct device *dev = (struct device *)(irq2dev_map[irq]);
- struct net_local *lp;
- int ioaddr, status, boguscount = 0;
- ushort ack_cmd = 0;
- ushort *shmem;
-
- if (dev == NULL) {
- printk ("net_interrupt(): irq %d for unknown device.\n", irq);
- return;
- }
- dev->interrupt = 1;
-
- ioaddr = dev->base_addr;
- lp = (struct net_local *)dev->priv;
- shmem = ((ushort*)dev->mem_start);
-
- status = shmem[iSCB_STATUS>>1];
-
- if (net_debug > 4) {
- printk("%s: 3c507 interrupt, status %4.4x.\n", dev->name, status);
- }
-
- /* Disable the 82586's input to the interrupt line. */
- outb(0x80, ioaddr + MISC_CTRL);
-
- /* Reap the Tx packet buffers. */
- while (lp->tx_reap != lp->tx_head) {
- unsigned short tx_status = shmem[lp->tx_reap>>1];
-
- if (tx_status == 0) {
- if (net_debug > 5) printk("Couldn't reap %#x.\n", lp->tx_reap);
- break;
- }
- if (tx_status & 0x2000) {
- lp->stats.tx_packets++;
- lp->stats.collisions += tx_status & 0xf;
- dev->tbusy = 0;
- mark_bh(NET_BH); /* Inform upper layers. */
- } else {
- lp->stats.tx_errors++;
- if (tx_status & 0x0600) lp->stats.tx_carrier_errors++;
- if (tx_status & 0x0100) lp->stats.tx_fifo_errors++;
- if (!(tx_status & 0x0040)) lp->stats.tx_heartbeat_errors++;
- if (tx_status & 0x0020) lp->stats.tx_aborted_errors++;
- }
- if (net_debug > 5)
- printk("Reaped %x, Tx status %04x.\n" , lp->tx_reap, tx_status);
- lp->tx_reap += TX_BUF_SIZE;
- if (lp->tx_reap > RX_BUF_START - TX_BUF_SIZE)
- lp->tx_reap = TX_BUF_START;
- if (++boguscount > 4)
- break;
- }
-
- if (status & 0x4000) { /* Packet received. */
- if (net_debug > 5)
- printk("Received packet, rx_head %04x.\n", lp->rx_head);
- el16_rx(dev);
- }
-
- /* Acknowledge the interrupt sources. */
- ack_cmd = status & 0xf000;
-
- if ((status & 0x0700) != 0x0200 && dev->start) {
- if (net_debug)
- printk("%s: Command unit stopped, status %04x, restarting.\n",
- dev->name, status);
- /* If this ever occurs we should really re-write the idle loop, reset
- the Tx list, and do a complete restart of the command unit.
- For now we rely on the Tx timeout if the resume doesn't work. */
- ack_cmd |= CUC_RESUME;
- }
-
- if ((status & 0x0070) != 0x0040 && dev->start) {
- static void init_rx_bufs(struct device *);
- /* The Rx unit is not ready, it must be hung. Restart the receiver by
- initializing the rx buffers, and issuing an Rx start command. */
- if (net_debug)
- printk("%s: Rx unit stopped, status %04x, restarting.\n",
- dev->name, status);
- init_rx_bufs(dev);
- shmem[iSCB_RFA >> 1] = RX_BUF_START;
- ack_cmd |= RX_START;
- }
-
- shmem[iSCB_CMD>>1] = ack_cmd;
- outb(0, ioaddr + SIGNAL_CA); /* Issue channel-attn. */
-
- /* Clear the latched interrupt. */
- outb(0, ioaddr + RESET_IRQ);
-
- /* Enable the 82586's interrupt input. */
- outb(0x84, ioaddr + MISC_CTRL);
-
- return;
-}
-
-static int
-el16_close(struct device *dev)
-{
- int ioaddr = dev->base_addr;
- ushort *shmem = (short*)dev->mem_start;
-
- dev->tbusy = 1;
- dev->start = 0;
-
- /* Flush the Tx and disable Rx. */
- shmem[iSCB_CMD >> 1] = RX_SUSPEND | CUC_SUSPEND;
- outb(0, ioaddr + SIGNAL_CA);
-
- /* Disable the 82586's input to the interrupt line. */
- outb(0x80, ioaddr + MISC_CTRL);
-
- /* We always physically use the IRQ line, so we don't do free_irq().
- We do remove ourselves from the map. */
-
- irq2dev_map[dev->irq] = 0;
-
- /* Update the statistics here. */
-
- MOD_DEC_USE_COUNT;
-
- return 0;
-}
-
-/* Get the current statistics. This may be called with the card open or
- closed. */
-static struct enet_statistics *
-el16_get_stats(struct device *dev)
-{
- struct net_local *lp = (struct net_local *)dev->priv;
-
- /* ToDo: decide if there are any useful statistics from the SCB. */
-
- return &lp->stats;
-}
-
-/* Initialize the Rx-block list. */
-static void
-init_rx_bufs(struct device *dev)
-{
- struct net_local *lp = (struct net_local *)dev->priv;
- unsigned short *write_ptr;
- unsigned short SCB_base = SCB_BASE;
-
- int cur_rxbuf = lp->rx_head = RX_BUF_START;
-
- /* Initialize each Rx frame + data buffer. */
- do { /* While there is room for one more. */
-
- write_ptr = (unsigned short *)(dev->mem_start + cur_rxbuf);
-
- *write_ptr++ = 0x0000; /* Status */
- *write_ptr++ = 0x0000; /* Command */
- *write_ptr++ = cur_rxbuf + RX_BUF_SIZE; /* Link */
- *write_ptr++ = cur_rxbuf + 22; /* Buffer offset */
- *write_ptr++ = 0x0000; /* Pad for dest addr. */
- *write_ptr++ = 0x0000;
- *write_ptr++ = 0x0000;
- *write_ptr++ = 0x0000; /* Pad for source addr. */
- *write_ptr++ = 0x0000;
- *write_ptr++ = 0x0000;
- *write_ptr++ = 0x0000; /* Pad for protocol. */
-
- *write_ptr++ = 0x0000; /* Buffer: Actual count */
- *write_ptr++ = -1; /* Buffer: Next (none). */
- *write_ptr++ = cur_rxbuf + 0x20 + SCB_base; /* Buffer: Address low */
- *write_ptr++ = 0x0000;
- /* Finally, the number of bytes in the buffer. */
- *write_ptr++ = 0x8000 + RX_BUF_SIZE-0x20;
-
- lp->rx_tail = cur_rxbuf;
- cur_rxbuf += RX_BUF_SIZE;
- } while (cur_rxbuf <= RX_BUF_END - RX_BUF_SIZE);
-
- /* Terminate the list by setting the EOL bit, and wrap the pointer to make
- the list a ring. */
- write_ptr = (unsigned short *)
- (dev->mem_start + lp->rx_tail + 2);
- *write_ptr++ = 0xC000; /* Command, mark as last. */
- *write_ptr++ = lp->rx_head; /* Link */
-
-}
-
-void
-init_82586_mem(struct device *dev)
-{
- struct net_local *lp = (struct net_local *)dev->priv;
- short ioaddr = dev->base_addr;
- ushort *shmem = (short*)dev->mem_start;
-
- /* Enable loopback to protect the wire while starting up,
- and hold the 586 in reset during the memory initialization. */
- outb(0x20, ioaddr + MISC_CTRL);
-
- /* Fix the ISCP address and base. */
- init_words[3] = SCB_BASE;
- init_words[7] = SCB_BASE;
-
- /* Write the words at 0xfff6 (address-aliased to 0xfffff6). */
- memcpy((void*)dev->mem_end-10, init_words, 10);
-
- /* Write the words at 0x0000. */
- memcpy((char*)dev->mem_start, init_words + 5, sizeof(init_words) - 10);
-
- /* Fill in the station address. */
- memcpy((char*)dev->mem_start+SA_OFFSET, dev->dev_addr,
- sizeof(dev->dev_addr));
-
- /* The Tx-block list is written as needed. We just set up the values. */
- lp->tx_cmd_link = IDLELOOP + 4;
- lp->tx_head = lp->tx_reap = TX_BUF_START;
-
- init_rx_bufs(dev);
-
- /* Start the 586 by releasing the reset line, but leave loopback. */
- outb(0xA0, ioaddr + MISC_CTRL);
-
- /* This was time consuming to track down: you need to give two channel
- attention signals to reliably start up the i82586. */
- outb(0, ioaddr + SIGNAL_CA);
-
- {
- int boguscnt = 50;
- while (shmem[iSCB_STATUS>>1] == 0)
- if (--boguscnt == 0) {
- printk("%s: i82586 initialization timed out with status %04x,"
- "cmd %04x.\n", dev->name,
- shmem[iSCB_STATUS>>1], shmem[iSCB_CMD>>1]);
- break;
- }
- /* Issue channel-attn -- the 82586 won't start. */
- outb(0, ioaddr + SIGNAL_CA);
- }
-
- /* Disable loopback and enable interrupts. */
- outb(0x84, ioaddr + MISC_CTRL);
- if (net_debug > 4)
- printk("%s: Initialized 82586, status %04x.\n", dev->name,
- shmem[iSCB_STATUS>>1]);
- return;
-}
-
-static void
-hardware_send_packet(struct device *dev, void *buf, short length)
-{
- struct net_local *lp = (struct net_local *)dev->priv;
- short ioaddr = dev->base_addr;
- ushort tx_block = lp->tx_head;
- ushort *write_ptr = (ushort *)(dev->mem_start + tx_block);
-
- /* Set the write pointer to the Tx block, and put out the header. */
- *write_ptr++ = 0x0000; /* Tx status */
- *write_ptr++ = CMD_INTR|CmdTx; /* Tx command */
- *write_ptr++ = tx_block+16; /* Next command is a NoOp. */
- *write_ptr++ = tx_block+8; /* Data Buffer offset. */
-
- /* Output the data buffer descriptor. */
- *write_ptr++ = length | 0x8000; /* Byte count parameter. */
- *write_ptr++ = -1; /* No next data buffer. */
- *write_ptr++ = tx_block+22+SCB_BASE;/* Buffer follows the NoOp command. */
- *write_ptr++ = 0x0000; /* Buffer address high bits (always zero). */
-
- /* Output the Loop-back NoOp command. */
- *write_ptr++ = 0x0000; /* Tx status */
- *write_ptr++ = CmdNOp; /* Tx command */
- *write_ptr++ = tx_block+16; /* Next is myself. */
-
- /* Output the packet at the write pointer. */
- memcpy(write_ptr, buf, length);
-
- /* Set the old command link pointing to this send packet. */
- *(ushort*)(dev->mem_start + lp->tx_cmd_link) = tx_block;
- lp->tx_cmd_link = tx_block + 20;
-
- /* Set the next free tx region. */
- lp->tx_head = tx_block + TX_BUF_SIZE;
- if (lp->tx_head > RX_BUF_START - TX_BUF_SIZE)
- lp->tx_head = TX_BUF_START;
-
- if (net_debug > 4) {
- printk("%s: 3c507 @%x send length = %d, tx_block %3x, next %3x.\n",
- dev->name, ioaddr, length, tx_block, lp->tx_head);
- }
-
- if (lp->tx_head != lp->tx_reap)
- dev->tbusy = 0;
-}
-
-static void
-el16_rx(struct device *dev)
-{
- struct net_local *lp = (struct net_local *)dev->priv;
- short *shmem = (short*)dev->mem_start;
- ushort rx_head = lp->rx_head;
- ushort rx_tail = lp->rx_tail;
- ushort boguscount = 10;
- short frame_status;
-
- while ((frame_status = shmem[rx_head>>1]) < 0) { /* Command complete */
- ushort *read_frame = (short *)(dev->mem_start + rx_head);
- ushort rfd_cmd = read_frame[1];
- ushort next_rx_frame = read_frame[2];
- ushort data_buffer_addr = read_frame[3];
- ushort *data_frame = (short *)(dev->mem_start + data_buffer_addr);
- ushort pkt_len = data_frame[0];
-
- if (rfd_cmd != 0 || data_buffer_addr != rx_head + 22
- || (pkt_len & 0xC000) != 0xC000) {
- printk("%s: Rx frame at %#x corrupted, status %04x cmd %04x"
- "next %04x data-buf @%04x %04x.\n", dev->name, rx_head,
- frame_status, rfd_cmd, next_rx_frame, data_buffer_addr,
- pkt_len);
- } else if ((frame_status & 0x2000) == 0) {
- /* Frame Rxed, but with error. */
- lp->stats.rx_errors++;
- if (frame_status & 0x0800) lp->stats.rx_crc_errors++;
- if (frame_status & 0x0400) lp->stats.rx_frame_errors++;
- if (frame_status & 0x0200) lp->stats.rx_fifo_errors++;
- if (frame_status & 0x0100) lp->stats.rx_over_errors++;
- if (frame_status & 0x0080) lp->stats.rx_length_errors++;
- } else {
- /* Malloc up new buffer. */
- struct sk_buff *skb;
-
- pkt_len &= 0x3fff;
- skb = dev_alloc_skb(pkt_len+2);
- if (skb == NULL) {
- printk("%s: Memory squeeze, dropping packet.\n", dev->name);
- lp->stats.rx_dropped++;
- break;
- }
-
- skb_reserve(skb,2);
- skb->dev = dev;
-
- /* 'skb->data' points to the start of sk_buff data area. */
- memcpy(skb_put(skb,pkt_len), data_frame + 5, pkt_len);
-
- skb->protocol=eth_type_trans(skb,dev);
- netif_rx(skb);
- lp->stats.rx_packets++;
- }
-
- /* Clear the status word and set End-of-List on the rx frame. */
- read_frame[0] = 0;
- read_frame[1] = 0xC000;
- /* Clear the end-of-list on the prev. RFD. */
- *(short*)(dev->mem_start + rx_tail + 2) = 0x0000;
-
- rx_tail = rx_head;
- rx_head = next_rx_frame;
- if (--boguscount == 0)
- break;
- }
-
- lp->rx_head = rx_head;
- lp->rx_tail = rx_tail;
-}
-#ifdef MODULE
-static char devicename[9] = { 0, };
-static struct device dev_3c507 = {
- devicename, /* device name is inserted by linux/drivers/net/net_init.c */
- 0, 0, 0, 0,
- 0, 0,
- 0, 0, 0, NULL, el16_probe
-};
-
-static int io = 0x300;
-static int irq = 0;
-
-int init_module(void)
-{
- if (io == 0)
- printk("3c507: You should not use auto-probing with insmod!\n");
- dev_3c507.base_addr = io;
- dev_3c507.irq = irq;
- if (register_netdev(&dev_3c507) != 0) {
- printk("3c507: register_netdev() returned non-zero.\n");
- return -EIO;
- }
- return 0;
-}
-
-void
-cleanup_module(void)
-{
- unregister_netdev(&dev_3c507);
- kfree(dev_3c507.priv);
- dev_3c507.priv = NULL;
-
- /* If we don't do this, we can't re-insmod it later. */
- free_irq(dev_3c507.irq);
- release_region(dev_3c507.base_addr, EL16_IO_EXTENT);
-}
-#endif /* MODULE */
-
-/*
- * Local variables:
- * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -I/usr/src/linux/drivers/net -Wall -Wstrict-prototypes -O6 -m486 -c 3c507.c"
- * version-control: t
- * kept-new-versions: 5
- * tab-width: 4
- * c-indent-level: 4
- * End:
- */
diff --git a/i386/i386at/gpl/linux/net/3c509.c b/i386/i386at/gpl/linux/net/3c509.c
deleted file mode 100644
index 5e7dce4f..00000000
--- a/i386/i386at/gpl/linux/net/3c509.c
+++ /dev/null
@@ -1,739 +0,0 @@
-/* 3c509.c: A 3c509 EtherLink3 ethernet driver for linux. */
-/*
- Written 1993,1994 by Donald Becker.
-
- Copyright 1994 by Donald Becker.
- Copyright 1993 United States Government as represented by the
- Director, National Security Agency. This software may be used and
- distributed according to the terms of the GNU Public License,
- incorporated herein by reference.
-
- This driver is for the 3Com EtherLinkIII series.
-
- The author may be reached as becker@cesdis.gsfc.nasa.gov or
- C/O Center of Excellence in Space Data and Information Sciences
- Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
-
- Known limitations:
- Because of the way 3c509 ISA detection works it's difficult to predict
- a priori which of several ISA-mode cards will be detected first.
-
- This driver does not use predictive interrupt mode, resulting in higher
- packet latency but lower overhead. If interrupts are disabled for an
- unusually long time it could also result in missed packets, but in
- practice this rarely happens.
-*/
-
-static const char *version = "3c509.c:1.03 10/8/94 becker@cesdis.gsfc.nasa.gov\n";
-
-#include <linux/module.h>
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/interrupt.h>
-#include <linux/ptrace.h>
-#include <linux/errno.h>
-#include <linux/in.h>
-#include <linux/malloc.h>
-#include <linux/ioport.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/config.h> /* for CONFIG_MCA */
-
-#include <asm/bitops.h>
-#include <asm/io.h>
-
-
-#ifdef EL3_DEBUG
-int el3_debug = EL3_DEBUG;
-#else
-int el3_debug = 2;
-#endif
-
-/* To minimize the size of the driver source I only define operating
- constants if they are used several times. You'll need the manual
- if you want to understand driver details. */
-/* Offsets from base I/O address. */
-#define EL3_DATA 0x00
-#define EL3_CMD 0x0e
-#define EL3_STATUS 0x0e
-#define ID_PORT 0x100
-#define EEPROM_READ 0x80
-
-#define EL3_IO_EXTENT 16
-
-#define EL3WINDOW(win_num) outw(SelectWindow + (win_num), ioaddr + EL3_CMD)
-
-
-/* The top five bits written to EL3_CMD are a command, the lower
- 11 bits are the parameter, if applicable. */
-enum c509cmd {
- TotalReset = 0<<11, SelectWindow = 1<<11, StartCoax = 2<<11,
- RxDisable = 3<<11, RxEnable = 4<<11, RxReset = 5<<11, RxDiscard = 8<<11,
- TxEnable = 9<<11, TxDisable = 10<<11, TxReset = 11<<11,
- FakeIntr = 12<<11, AckIntr = 13<<11, SetIntrMask = 14<<11,
- SetReadZero = 15<<11, SetRxFilter = 16<<11, SetRxThreshold = 17<<11,
- SetTxThreshold = 18<<11, SetTxStart = 19<<11, StatsEnable = 21<<11,
- StatsDisable = 22<<11, StopCoax = 23<<11,};
-
-/* The SetRxFilter command accepts the following classes: */
-enum RxFilter {
- RxStation = 1, RxMulticast = 2, RxBroadcast = 4, RxProm = 8 };
-
-/* Register window 1 offsets, the window used in normal operation. */
-#define TX_FIFO 0x00
-#define RX_FIFO 0x00
-#define RX_STATUS 0x08
-#define TX_STATUS 0x0B
-#define TX_FREE 0x0C /* Remaining free bytes in Tx buffer. */
-
-#define WN0_IRQ 0x08 /* Window 0: Set IRQ line in bits 12-15. */
-#define WN4_MEDIA 0x0A /* Window 4: Various transcvr/media bits. */
-#define MEDIA_TP 0x00C0 /* Enable link beat and jabber for 10baseT. */
-
-struct el3_private {
- struct enet_statistics stats;
-};
-
-static ushort id_read_eeprom(int index);
-static ushort read_eeprom(short ioaddr, int index);
-static int el3_open(struct device *dev);
-static int el3_start_xmit(struct sk_buff *skb, struct device *dev);
-static void el3_interrupt(int irq, struct pt_regs *regs);
-static void update_stats(int addr, struct device *dev);
-static struct enet_statistics *el3_get_stats(struct device *dev);
-static int el3_rx(struct device *dev);
-static int el3_close(struct device *dev);
-static void set_multicast_list(struct device *dev);
-
-
-
-int el3_probe(struct device *dev)
-{
- short lrs_state = 0xff, i;
- ushort ioaddr, irq, if_port;
- short *phys_addr = (short *)dev->dev_addr;
- static int current_tag = 0;
-
- /* First check all slots of the EISA bus. The next slot address to
- probe is kept in 'eisa_addr' to support multiple probe() calls. */
- if (EISA_bus) {
- static int eisa_addr = 0x1000;
- while (eisa_addr < 0x9000) {
- ioaddr = eisa_addr;
- eisa_addr += 0x1000;
-
- /* Check the standard EISA ID register for an encoded '3Com'. */
- if (inw(ioaddr + 0xC80) != 0x6d50)
- continue;
-
- /* Change the register set to the configuration window 0. */
- outw(SelectWindow | 0, ioaddr + 0xC80 + EL3_CMD);
-
- irq = inw(ioaddr + WN0_IRQ) >> 12;
- if_port = inw(ioaddr + 6)>>14;
- for (i = 0; i < 3; i++)
- phys_addr[i] = htons(read_eeprom(ioaddr, i));
-
- /* Restore the "Product ID" to the EEPROM read register. */
- read_eeprom(ioaddr, 3);
-
- /* Was the EISA code an add-on hack? Nahhhhh... */
- goto found;
- }
- }
-
-#ifdef CONFIG_MCA
- if (MCA_bus) {
- mca_adaptor_select_mode(1);
- for (i = 0; i < 8; i++)
- if ((mca_adaptor_id(i) | 1) == 0x627c) {
- ioaddr = mca_pos_base_addr(i);
- irq = inw(ioaddr + WN0_IRQ) >> 12;
- if_port = inw(ioaddr + 6)>>14;
- for (i = 0; i < 3; i++)
- phys_addr[i] = htons(read_eeprom(ioaddr, i));
-
- mca_adaptor_select_mode(0);
- goto found;
- }
- mca_adaptor_select_mode(0);
-
- }
-#endif
-
- /* Next check for all ISA bus boards by sending the ID sequence to the
- ID_PORT. We find cards past the first by setting the 'current_tag'
- on cards as they are found. Cards with their tag set will not
- respond to subsequent ID sequences. */
-
- if (check_region(ID_PORT,1)) {
- static int once = 1;
- if (once) printk("3c509: Somebody has reserved 0x%x, can't do ID_PORT lookup, nor card auto-probing\n",ID_PORT);
- once = 0;
- return -ENODEV;
- }
-
- outb(0x00, ID_PORT);
- outb(0x00, ID_PORT);
- for(i = 0; i < 255; i++) {
- outb(lrs_state, ID_PORT);
- lrs_state <<= 1;
- lrs_state = lrs_state & 0x100 ? lrs_state ^ 0xcf : lrs_state;
- }
-
- /* For the first probe, clear all board's tag registers. */
- if (current_tag == 0)
- outb(0xd0, ID_PORT);
- else /* Otherwise kill off already-found boards. */
- outb(0xd8, ID_PORT);
-
- if (id_read_eeprom(7) != 0x6d50) {
- return -ENODEV;
- }
-
- /* Read in EEPROM data, which does contention-select.
- Only the lowest address board will stay "on-line".
- 3Com got the byte order backwards. */
- for (i = 0; i < 3; i++) {
- phys_addr[i] = htons(id_read_eeprom(i));
- }
-
- {
- unsigned short iobase = id_read_eeprom(8);
- if_port = iobase >> 14;
- ioaddr = 0x200 + ((iobase & 0x1f) << 4);
- }
- irq = id_read_eeprom(9) >> 12;
-
- if (dev->base_addr != 0
- && dev->base_addr != (unsigned short)ioaddr) {
- return -ENODEV;
- }
-
- /* Set the adaptor tag so that the next card can be found. */
- outb(0xd0 + ++current_tag, ID_PORT);
-
- /* Activate the adaptor at the EEPROM location. */
- outb(0xff, ID_PORT);
-
- EL3WINDOW(0);
- if (inw(ioaddr) != 0x6d50)
- return -ENODEV;
-
- /* Free the interrupt so that some other card can use it. */
- outw(0x0f00, ioaddr + WN0_IRQ);
- found:
- dev->base_addr = ioaddr;
- dev->irq = irq;
- dev->if_port = if_port;
- request_region(dev->base_addr, EL3_IO_EXTENT, "3c509");
-
- {
- const char *if_names[] = {"10baseT", "AUI", "undefined", "BNC"};
- printk("%s: 3c509 at %#3.3lx tag %d, %s port, address ",
- dev->name, dev->base_addr, current_tag, if_names[dev->if_port]);
- }
-
- /* Read in the station address. */
- for (i = 0; i < 6; i++)
- printk(" %2.2x", dev->dev_addr[i]);
- printk(", IRQ %d.\n", dev->irq);
-
- /* Make up a EL3-specific-data structure. */
- dev->priv = kmalloc(sizeof(struct el3_private), GFP_KERNEL);
- if (dev->priv == NULL)
- return -ENOMEM;
- memset(dev->priv, 0, sizeof(struct el3_private));
-
- if (el3_debug > 0)
- printk(version);
-
- /* The EL3-specific entries in the device structure. */
- dev->open = &el3_open;
- dev->hard_start_xmit = &el3_start_xmit;
- dev->stop = &el3_close;
- dev->get_stats = &el3_get_stats;
- dev->set_multicast_list = &set_multicast_list;
-
- /* Fill in the generic fields of the device structure. */
- ether_setup(dev);
- return 0;
-}
-
-/* Read a word from the EEPROM using the regular EEPROM access register.
- Assume that we are in register window zero.
- */
-static ushort read_eeprom(short ioaddr, int index)
-{
- int timer;
-
- outw(EEPROM_READ + index, ioaddr + 10);
- /* Pause for at least 162 us. for the read to take place. */
- for (timer = 0; timer < 162*4 + 400; timer++)
- SLOW_DOWN_IO;
- return inw(ioaddr + 12);
-}
-
-/* Read a word from the EEPROM when in the ISA ID probe state. */
-static ushort id_read_eeprom(int index)
-{
- int timer, bit, word = 0;
-
- /* Issue read command, and pause for at least 162 us. for it to complete.
- Assume extra-fast 16Mhz bus. */
- outb(EEPROM_READ + index, ID_PORT);
-
- /* This should really be done by looking at one of the timer channels. */
- for (timer = 0; timer < 162*4 + 400; timer++)
- SLOW_DOWN_IO;
-
- for (bit = 15; bit >= 0; bit--)
- word = (word << 1) + (inb(ID_PORT) & 0x01);
-
- if (el3_debug > 3)
- printk(" 3c509 EEPROM word %d %#4.4x.\n", index, word);
-
- return word;
-}
-
-
-
-static int
-el3_open(struct device *dev)
-{
- int ioaddr = dev->base_addr;
- int i;
-
- outw(TxReset, ioaddr + EL3_CMD);
- outw(RxReset, ioaddr + EL3_CMD);
- outw(SetReadZero | 0x00, ioaddr + EL3_CMD);
-
- if (request_irq(dev->irq, &el3_interrupt, 0, "3c509")) {
- return -EAGAIN;
- }
-
- EL3WINDOW(0);
- if (el3_debug > 3)
- printk("%s: Opening, IRQ %d status@%x %4.4x.\n", dev->name,
- dev->irq, ioaddr + EL3_STATUS, inw(ioaddr + EL3_STATUS));
-
- /* Activate board: this is probably unnecessary. */
- outw(0x0001, ioaddr + 4);
-
- irq2dev_map[dev->irq] = dev;
-
- /* Set the IRQ line. */
- outw((dev->irq << 12) | 0x0f00, ioaddr + WN0_IRQ);
-
- /* Set the station address in window 2 each time opened. */
- EL3WINDOW(2);
-
- for (i = 0; i < 6; i++)
- outb(dev->dev_addr[i], ioaddr + i);
-
- if (dev->if_port == 3)
- /* Start the thinnet transceiver. We should really wait 50ms...*/
- outw(StartCoax, ioaddr + EL3_CMD);
- else if (dev->if_port == 0) {
- /* 10baseT interface, enabled link beat and jabber check. */
- EL3WINDOW(4);
- outw(inw(ioaddr + WN4_MEDIA) | MEDIA_TP, ioaddr + WN4_MEDIA);
- }
-
- /* Switch to the stats window, and clear all stats by reading. */
- outw(StatsDisable, ioaddr + EL3_CMD);
- EL3WINDOW(6);
- for (i = 0; i < 9; i++)
- inb(ioaddr + i);
- inb(ioaddr + 10);
- inb(ioaddr + 12);
-
- /* Switch to register set 1 for normal use. */
- EL3WINDOW(1);
-
- /* Accept b-case and phys addr only. */
- outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD);
- outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */
-
- dev->interrupt = 0;
- dev->tbusy = 0;
- dev->start = 1;
-
- outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */
- outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */
- /* Allow status bits to be seen. */
- outw(SetReadZero | 0xff, ioaddr + EL3_CMD);
- outw(AckIntr | 0x69, ioaddr + EL3_CMD); /* Ack IRQ */
- outw(SetIntrMask | 0x98, ioaddr + EL3_CMD); /* Set interrupt mask. */
-
- if (el3_debug > 3)
- printk("%s: Opened 3c509 IRQ %d status %4.4x.\n",
- dev->name, dev->irq, inw(ioaddr + EL3_STATUS));
-
- MOD_INC_USE_COUNT;
- return 0; /* Always succeed */
-}
-
-static int
-el3_start_xmit(struct sk_buff *skb, struct device *dev)
-{
- struct el3_private *lp = (struct el3_private *)dev->priv;
- int ioaddr = dev->base_addr;
-
- /* Transmitter timeout, serious problems. */
- if (dev->tbusy) {
- int tickssofar = jiffies - dev->trans_start;
- if (tickssofar < 10)
- return 1;
- printk("%s: transmit timed out, tx_status %2.2x status %4.4x.\n",
- dev->name, inb(ioaddr + TX_STATUS), inw(ioaddr + EL3_STATUS));
- dev->trans_start = jiffies;
- /* Issue TX_RESET and TX_START commands. */
- outw(TxReset, ioaddr + EL3_CMD);
- outw(TxEnable, ioaddr + EL3_CMD);
- dev->tbusy = 0;
- }
-
- if (skb == NULL) {
- dev_tint(dev);
- return 0;
- }
-
- if (skb->len <= 0)
- return 0;
-
- if (el3_debug > 4) {
- printk("%s: el3_start_xmit(length = %ld) called, status %4.4x.\n",
- dev->name, skb->len, inw(ioaddr + EL3_STATUS));
- }
-#ifndef final_version
- { /* Error-checking code, delete for 1.30. */
- ushort status = inw(ioaddr + EL3_STATUS);
- if (status & 0x0001 /* IRQ line active, missed one. */
- && inw(ioaddr + EL3_STATUS) & 1) { /* Make sure. */
- printk("%s: Missed interrupt, status then %04x now %04x"
- " Tx %2.2x Rx %4.4x.\n", dev->name, status,
- inw(ioaddr + EL3_STATUS), inb(ioaddr + TX_STATUS),
- inw(ioaddr + RX_STATUS));
- /* Fake interrupt trigger by masking, acknowledge interrupts. */
- outw(SetReadZero | 0x00, ioaddr + EL3_CMD);
- outw(AckIntr | 0x69, ioaddr + EL3_CMD); /* Ack IRQ */
- outw(SetReadZero | 0xff, ioaddr + EL3_CMD);
- }
- }
-#endif
-
- /* Avoid timer-based retransmission conflicts. */
- if (set_bit(0, (void*)&dev->tbusy) != 0)
- printk("%s: Transmitter access conflict.\n", dev->name);
- else {
- /* Put out the doubleword header... */
- outw(skb->len, ioaddr + TX_FIFO);
- outw(0x00, ioaddr + TX_FIFO);
- /* ... and the packet rounded to a doubleword. */
- outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
-
- dev->trans_start = jiffies;
- if (inw(ioaddr + TX_FREE) > 1536) {
- dev->tbusy = 0;
- } else
- /* Interrupt us when the FIFO has room for max-sized packet. */
- outw(SetTxThreshold + 1536, ioaddr + EL3_CMD);
- }
-
- dev_kfree_skb (skb, FREE_WRITE);
-
- /* Clear the Tx status stack. */
- {
- short tx_status;
- int i = 4;
-
- while (--i > 0 && (tx_status = inb(ioaddr + TX_STATUS)) > 0) {
- if (tx_status & 0x38) lp->stats.tx_aborted_errors++;
- if (tx_status & 0x30) outw(TxReset, ioaddr + EL3_CMD);
- if (tx_status & 0x3C) outw(TxEnable, ioaddr + EL3_CMD);
- outb(0x00, ioaddr + TX_STATUS); /* Pop the status stack. */
- }
- }
- return 0;
-}
-
-/* The EL3 interrupt handler. */
-static void
-el3_interrupt(int irq, struct pt_regs *regs)
-{
- struct device *dev = (struct device *)(irq2dev_map[irq]);
- int ioaddr, status;
- int i = 0;
-
- if (dev == NULL) {
- printk ("el3_interrupt(): irq %d for unknown device.\n", irq);
- return;
- }
-
- if (dev->interrupt)
- printk("%s: Re-entering the interrupt handler.\n", dev->name);
- dev->interrupt = 1;
-
- ioaddr = dev->base_addr;
- status = inw(ioaddr + EL3_STATUS);
-
- if (el3_debug > 4)
- printk("%s: interrupt, status %4.4x.\n", dev->name, status);
-
- while ((status = inw(ioaddr + EL3_STATUS)) & 0x91) {
-
- if (status & 0x10)
- el3_rx(dev);
-
- if (status & 0x08) {
- if (el3_debug > 5)
- printk(" TX room bit was handled.\n");
- /* There's room in the FIFO for a full-sized packet. */
- outw(AckIntr | 0x08, ioaddr + EL3_CMD);
- dev->tbusy = 0;
- mark_bh(NET_BH);
- }
- if (status & 0x80) /* Statistics full. */
- update_stats(ioaddr, dev);
-
- if (++i > 10) {
- printk("%s: Infinite loop in interrupt, status %4.4x.\n",
- dev->name, status);
- /* Clear all interrupts. */
- outw(AckIntr | 0xFF, ioaddr + EL3_CMD);
- break;
- }
- /* Acknowledge the IRQ. */
- outw(AckIntr | 0x41, ioaddr + EL3_CMD); /* Ack IRQ */
-
- }
-
- if (el3_debug > 4) {
- printk("%s: exiting interrupt, status %4.4x.\n", dev->name,
- inw(ioaddr + EL3_STATUS));
- }
-
- dev->interrupt = 0;
- return;
-}
-
-
-static struct enet_statistics *
-el3_get_stats(struct device *dev)
-{
- struct el3_private *lp = (struct el3_private *)dev->priv;
- unsigned long flags;
-
- save_flags(flags);
- cli();
- update_stats(dev->base_addr, dev);
- restore_flags(flags);
- return &lp->stats;
-}
-
-/* Update statistics. We change to register window 6, so this should be run
- single-threaded if the device is active. This is expected to be a rare
- operation, and it's simpler for the rest of the driver to assume that
- window 1 is always valid rather than use a special window-state variable.
- */
-static void update_stats(int ioaddr, struct device *dev)
-{
- struct el3_private *lp = (struct el3_private *)dev->priv;
-
- if (el3_debug > 5)
- printk(" Updating the statistics.\n");
- /* Turn off statistics updates while reading. */
- outw(StatsDisable, ioaddr + EL3_CMD);
- /* Switch to the stats window, and read everything. */
- EL3WINDOW(6);
- lp->stats.tx_carrier_errors += inb(ioaddr + 0);
- lp->stats.tx_heartbeat_errors += inb(ioaddr + 1);
- /* Multiple collisions. */ inb(ioaddr + 2);
- lp->stats.collisions += inb(ioaddr + 3);
- lp->stats.tx_window_errors += inb(ioaddr + 4);
- lp->stats.rx_fifo_errors += inb(ioaddr + 5);
- lp->stats.tx_packets += inb(ioaddr + 6);
- /* Rx packets */ inb(ioaddr + 7);
- /* Tx deferrals */ inb(ioaddr + 8);
- inw(ioaddr + 10); /* Total Rx and Tx octets. */
- inw(ioaddr + 12);
-
- /* Back to window 1, and turn statistics back on. */
- EL3WINDOW(1);
- outw(StatsEnable, ioaddr + EL3_CMD);
- return;
-}
-
-static int
-el3_rx(struct device *dev)
-{
- struct el3_private *lp = (struct el3_private *)dev->priv;
- int ioaddr = dev->base_addr;
- short rx_status;
-
- if (el3_debug > 5)
- printk(" In rx_packet(), status %4.4x, rx_status %4.4x.\n",
- inw(ioaddr+EL3_STATUS), inw(ioaddr+RX_STATUS));
- while ((rx_status = inw(ioaddr + RX_STATUS)) > 0) {
- if (rx_status & 0x4000) { /* Error, update stats. */
- short error = rx_status & 0x3800;
- lp->stats.rx_errors++;
- switch (error) {
- case 0x0000: lp->stats.rx_over_errors++; break;
- case 0x0800: lp->stats.rx_length_errors++; break;
- case 0x1000: lp->stats.rx_frame_errors++; break;
- case 0x1800: lp->stats.rx_length_errors++; break;
- case 0x2000: lp->stats.rx_frame_errors++; break;
- case 0x2800: lp->stats.rx_crc_errors++; break;
- }
- } else {
- short pkt_len = rx_status & 0x7ff;
- struct sk_buff *skb;
-
- skb = dev_alloc_skb(pkt_len+5);
- if (el3_debug > 4)
- printk("Receiving packet size %d status %4.4x.\n",
- pkt_len, rx_status);
- if (skb != NULL) {
- skb->dev = dev;
- skb_reserve(skb,2); /* Align IP on 16 byte boundaries */
-
- /* 'skb->data' points to the start of sk_buff data area. */
- insl(ioaddr+RX_FIFO, skb_put(skb,pkt_len),
- (pkt_len + 3) >> 2);
-
- skb->protocol=eth_type_trans(skb,dev);
- netif_rx(skb);
- outw(RxDiscard, ioaddr + EL3_CMD); /* Pop top Rx packet. */
- lp->stats.rx_packets++;
- continue;
- } else if (el3_debug)
- printk("%s: Couldn't allocate a sk_buff of size %d.\n",
- dev->name, pkt_len);
- }
- lp->stats.rx_dropped++;
- outw(RxDiscard, ioaddr + EL3_CMD);
- while (inw(ioaddr + EL3_STATUS) & 0x1000)
- printk(" Waiting for 3c509 to discard packet, status %x.\n",
- inw(ioaddr + EL3_STATUS) );
- }
-
- return 0;
-}
-
-/*
- * Set or clear the multicast filter for this adaptor.
- */
-
-static void set_multicast_list(struct device *dev)
-{
- short ioaddr = dev->base_addr;
- if (el3_debug > 1) {
- static int old = 0;
- if (old != dev->mc_count) {
- old = dev->mc_count;
- printk("%s: Setting Rx mode to %d addresses.\n", dev->name, dev->mc_count);
- }
- }
- if (dev->flags&IFF_PROMISC)
- {
- outw(SetRxFilter | RxStation | RxMulticast | RxBroadcast | RxProm,
- ioaddr + EL3_CMD);
- }
- else if (dev->mc_count || (dev->flags&IFF_ALLMULTI))
- {
- outw(SetRxFilter|RxStation|RxMulticast|RxBroadcast, ioaddr + EL3_CMD);
- }
- else
- outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD);
-}
-
-static int
-el3_close(struct device *dev)
-{
- int ioaddr = dev->base_addr;
-
- if (el3_debug > 2)
- printk("%s: Shutting down ethercard.\n", dev->name);
-
- dev->tbusy = 1;
- dev->start = 0;
-
- /* Turn off statistics ASAP. We update lp->stats below. */
- outw(StatsDisable, ioaddr + EL3_CMD);
-
- /* Disable the receiver and transmitter. */
- outw(RxDisable, ioaddr + EL3_CMD);
- outw(TxDisable, ioaddr + EL3_CMD);
-
- if (dev->if_port == 3)
- /* Turn off thinnet power. Green! */
- outw(StopCoax, ioaddr + EL3_CMD);
- else if (dev->if_port == 0) {
- /* Disable link beat and jabber, if_port may change ere next open(). */
- EL3WINDOW(4);
- outw(inw(ioaddr + WN4_MEDIA) & ~MEDIA_TP, ioaddr + WN4_MEDIA);
- }
-
- free_irq(dev->irq);
- /* Switching back to window 0 disables the IRQ. */
- EL3WINDOW(0);
- /* But we explicitly zero the IRQ line select anyway. */
- outw(0x0f00, ioaddr + WN0_IRQ);
-
-
- irq2dev_map[dev->irq] = 0;
-
- update_stats(ioaddr, dev);
- MOD_DEC_USE_COUNT;
- return 0;
-}
-
-#ifdef MODULE
-static char devicename[9] = { 0, };
-static struct device dev_3c509 = {
- devicename, /* device name is inserted by linux/drivers/net/net_init.c */
- 0, 0, 0, 0,
- 0, 0,
- 0, 0, 0, NULL, el3_probe };
-
-static int io = 0;
-static int irq = 0;
-
-int
-init_module(void)
-{
- dev_3c509.base_addr = io;
- dev_3c509.irq = irq;
- if (!EISA_bus) {
- printk("3c509: WARNING! Module load-time probing works reliably only for EISA-bus!\n");
- }
- if (register_netdev(&dev_3c509) != 0)
- return -EIO;
- return 0;
-}
-
-void
-cleanup_module(void)
-{
- unregister_netdev(&dev_3c509);
- kfree_s(dev_3c509.priv,sizeof(struct el3_private));
- dev_3c509.priv=NULL;
- /* If we don't do this, we can't re-insmod it later. */
- release_region(dev_3c509.base_addr, EL3_IO_EXTENT);
-}
-#endif /* MODULE */
-
-/*
- * Local variables:
- * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c 3c509.c"
- * version-control: t
- * kept-new-versions: 5
- * tab-width: 4
- * End:
- */
diff --git a/i386/i386at/gpl/linux/net/3c59x.c b/i386/i386at/gpl/linux/net/3c59x.c
deleted file mode 100644
index b5c4d5b7..00000000
--- a/i386/i386at/gpl/linux/net/3c59x.c
+++ /dev/null
@@ -1,1066 +0,0 @@
-/* 3c59x.c: A 3Com 3c590/3c595 "Vortex" ethernet driver for linux. */
-/*
- Written 1995 by Donald Becker.
-
- This software may be used and distributed according to the terms
- of the GNU Public License, incorporated herein by reference.
-
- This driver is for the 3Com "Vortex" series ethercards. Members of
- the series include the 3c590 PCI EtherLink III and 3c595-Tx PCI Fast
- EtherLink. It also works with the 10Mbs-only 3c590 PCI EtherLink III.
-
- The author may be reached as becker@CESDIS.gsfc.nasa.gov, or C/O
- Center of Excellence in Space Data and Information Sciences
- Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
-*/
-
-static char *version = "3c59x.c:v0.13 2/13/96 becker@cesdis.gsfc.nasa.gov\n";
-
-/* "Knobs" that turn on special features. */
-/* Allow the use of bus master transfers instead of programmed-I/O for the
- Tx process. Bus master transfers are always disabled by default, but
- iff this is set they may be turned on using 'options'. */
-#define VORTEX_BUS_MASTER
-
-/* Put out somewhat more debugging messages. (0 - no msg, 1 minimal msgs). */
-#define VORTEX_DEBUG 1
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/ptrace.h>
-#include <linux/errno.h>
-#include <linux/in.h>
-#include <linux/ioport.h>
-#include <linux/malloc.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/bios32.h>
-#include <linux/timer.h>
-#include <asm/bitops.h>
-#include <asm/io.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-
-#ifdef HAVE_SHARED_IRQ
-#define USE_SHARED_IRQ
-#include <linux/shared_irq.h>
-#endif
-
-/* The total size is twice that of the original EtherLinkIII series: the
- runtime register window, window 1, is now always mapped in. */
-#define VORTEX_TOTAL_SIZE 0x20
-
-#ifdef HAVE_DEVLIST
-struct netdev_entry tc59x_drv =
-{"Vortex", vortex_pci_probe, VORTEX_TOTAL_SIZE, NULL};
-#endif
-
-#ifdef VORTEX_DEBUG
-int vortex_debug = VORTEX_DEBUG;
-#else
-int vortex_debug = 1;
-#endif
-
-static int product_ids[] = {0x5900, 0x5950, 0x5951, 0x5952, 0, 0};
-static const char *product_names[] = {
- "3c590 Vortex 10Mbps",
- "3c595 Vortex 100baseTX",
- "3c595 Vortex 100baseT4",
- "3c595 Vortex 100base-MII",
- "EISA Vortex 3c597",
-};
-#define DEMON_INDEX 5 /* Caution! Must be consistent with above! */
-
-/*
- Theory of Operation
-
-I. Board Compatibility
-
-This device driver is designed for the 3Com FastEtherLink, 3Com's PCI to
-10/100baseT adapter. It also works with the 3c590, a similar product
-with only a 10Mbs interface.
-
-II. Board-specific settings
-
-PCI bus devices are configured by the system at boot time, so no jumpers
-need to be set on the board. The system BIOS should be set to assign the
-PCI INTA signal to an otherwise unused system IRQ line. While it's
-physically possible to shared PCI interrupt lines, the 1.2.0 kernel doesn't
-support it.
-
-III. Driver operation
-
-The 3c59x series use an interface that's very similar to the previous 3c5x9
-series. The primary interface is two programmed-I/O FIFOs, with an
-alternate single-contiguous-region bus-master transfer (see next).
-
-One extension that is advertised in a very large font is that the adapters
-are capable of being bus masters. Unfortunately this capability is only for
-a single contiguous region making it less useful than the list of transfer
-regions available with the DEC Tulip or AMD PCnet. Given the significant
-performance impact of taking an extra interrupt for each transfer, using
-DMA transfers is a win only with large blocks.
-
-IIIC. Synchronization
-The driver runs as two independent, single-threaded flows of control. One
-is the send-packet routine, which enforces single-threaded use by the
-dev->tbusy flag. The other thread is the interrupt handler, which is single
-threaded by the hardware and other software.
-
-IV. Notes
-
-Thanks to Cameron Spitzer and Terry Murphy of 3Com for providing both
-3c590 and 3c595 boards.
-The name "Vortex" is the internal 3Com project name for the PCI ASIC, and
-the not-yet-released (3/95) EISA version is called "Demon". According to
-Terry these names come from rides at the local amusement park.
-
-The new chips support both ethernet (1.5K) and FDDI (4.5K) packet sizes!
-This driver only supports ethernet packets because of the skbuff allocation
-limit of 4K.
-*/
-
-#define TCOM_VENDOR_ID 0x10B7 /* 3Com's manufacturer's ID. */
-
-/* Operational defintions.
- These are not used by other compilation units and thus are not
- exported in a ".h" file.
-
- First the windows. There are eight register windows, with the command
- and status registers available in each.
- */
-#define EL3WINDOW(win_num) outw(SelectWindow + (win_num), ioaddr + EL3_CMD)
-#define EL3_CMD 0x0e
-#define EL3_STATUS 0x0e
-
-/* The top five bits written to EL3_CMD are a command, the lower
- 11 bits are the parameter, if applicable.
- Note that 11 parameters bits was fine for ethernet, but the new chip
- can handle FDDI lenght frames (~4500 octets) and now parameters count
- 32-bit 'Dwords' rather than octets. */
-
-enum vortex_cmd {
- TotalReset = 0<<11, SelectWindow = 1<<11, StartCoax = 2<<11,
- RxDisable = 3<<11, RxEnable = 4<<11, RxReset = 5<<11, RxDiscard = 8<<11,
- TxEnable = 9<<11, TxDisable = 10<<11, TxReset = 11<<11,
- FakeIntr = 12<<11, AckIntr = 13<<11, SetIntrEnb = 14<<11,
- SetStatusEnb = 15<<11, SetRxFilter = 16<<11, SetRxThreshold = 17<<11,
- SetTxThreshold = 18<<11, SetTxStart = 19<<11,
- StartDMAUp = 20<<11, StartDMADown = (20<<11)+1, StatsEnable = 21<<11,
- StatsDisable = 22<<11, StopCoax = 23<<11,};
-
-/* The SetRxFilter command accepts the following classes: */
-enum RxFilter {
- RxStation = 1, RxMulticast = 2, RxBroadcast = 4, RxProm = 8 };
-
-/* Bits in the general status register. */
-enum vortex_status {
- IntLatch = 0x0001, AdapterFailure = 0x0002, TxComplete = 0x0004,
- TxAvailable = 0x0008, RxComplete = 0x0010, RxEarly = 0x0020,
- IntReq = 0x0040, StatsFull = 0x0080, DMADone = 1<<8,
- DMAInProgress = 1<<11, /* DMA controller is still busy.*/
- CmdInProgress = 1<<12, /* EL3_CMD is still busy.*/
-};
-
-/* Register window 1 offsets, the window used in normal operation.
- On the Vortex this window is always mapped at offsets 0x10-0x1f. */
-enum Window1 {
- TX_FIFO = 0x10, RX_FIFO = 0x10, RxErrors = 0x14,
- RxStatus = 0x18, Timer=0x1A, TxStatus = 0x1B,
- TxFree = 0x1C, /* Remaining free bytes in Tx buffer. */
-};
-enum Window0 {
- Wn0EepromCmd = 10, /* Window 0: EEPROM command register. */
-};
-enum Win0_EEPROM_bits {
- EEPROM_Read = 0x80, EEPROM_WRITE = 0x40, EEPROM_ERASE = 0xC0,
- EEPROM_EWENB = 0x30, /* Enable erasing/writing for 10 msec. */
- EEPROM_EWDIS = 0x00, /* Disable EWENB before 10 msec timeout. */
-};
-/* EEPROM locations. */
-enum eeprom_offset {
- PhysAddr01=0, PhysAddr23=1, PhysAddr45=2, ModelID=3,
- EtherLink3ID=7, IFXcvrIO=8, IRQLine=9,
- NodeAddr01=10, NodeAddr23=11, NodeAddr45=12,
- DriverTune=13, Checksum=15};
-
-enum Window3 { /* Window 3: MAC/config bits. */
- Wn3_Config=0, Wn3_MAC_Ctrl=6, Wn3_Options=8,
-};
-union wn3_config {
- int i;
- struct w3_config_fields {
- unsigned int ram_size:3, ram_width:1, ram_speed:2, rom_size:2;
- int pad8:8;
- unsigned int ram_split:2, pad18:2, xcvr:3, pad21:1, autoselect:1;
- int pad24:8;
- } u;
-};
-
-enum Window4 {
- Wn4_Media = 0x0A, /* Window 4: Various transcvr/media bits. */
-};
-enum Win4_Media_bits {
- Media_TP = 0x00C0, /* Enable link beat and jabber for 10baseT. */
-};
-enum Window7 { /* Window 7: Bus Master control. */
- Wn7_MasterAddr = 0, Wn7_MasterLen = 6, Wn7_MasterStatus = 12,
-};
-
-struct vortex_private {
- char devname[8]; /* "ethN" string, also for kernel debug. */
- const char *product_name;
- struct device *next_module;
- struct enet_statistics stats;
-#ifdef VORTEX_BUS_MASTER
- struct sk_buff *tx_skb; /* Packet being eaten by bus master ctrl. */
-#endif
- struct timer_list timer; /* Media selection timer. */
- int options; /* User-settable driver options (none yet). */
- unsigned int media_override:3, full_duplex:1, bus_master:1, autoselect:1;
-};
-
-static char *if_names[] = {
- "10baseT", "10Mbs AUI", "undefined", "10base2",
- "100baseTX", "100baseFX", "MII", "undefined"};
-
-static int vortex_scan(struct device *dev);
-static int vortex_found_device(struct device *dev, int ioaddr, int irq,
- int product_index, int options);
-static int vortex_probe1(struct device *dev);
-static int vortex_open(struct device *dev);
-static void vortex_timer(unsigned long arg);
-static int vortex_start_xmit(struct sk_buff *skb, struct device *dev);
-static int vortex_rx(struct device *dev);
-static void vortex_interrupt(int irq, struct pt_regs *regs);
-static int vortex_close(struct device *dev);
-static void update_stats(int addr, struct device *dev);
-static struct enet_statistics *vortex_get_stats(struct device *dev);
-static void set_multicast_list(struct device *dev);
-
-
-/* Unlike the other PCI cards the 59x cards don't need a large contiguous
- memory region, so making the driver a loadable module is feasible.
-
- Unfortuneately maximizing the shared code between the integrated and
- module version of the driver results in a complicated set of initialization
- procedures.
- init_module() -- modules / tc59x_init() -- built-in
- The wrappers for vortex_scan()
- vortex_scan() The common routine that scans for PCI and EISA cards
- vortex_found_device() Allocate a device structure when we find a card.
- Different versions exist for modules and built-in.
- vortex_probe1() Fill in the device structure -- this is seperated
- so that the modules code can put it in dev->init.
-*/
-/* This driver uses 'options' to pass the media type, full-duplex flag, etc. */
-/* Note: this is the only limit on the number of cards supported!! */
-int options[8] = { -1, -1, -1, -1, -1, -1, -1, -1,};
-
-#ifdef MODULE
-static int debug = -1;
-/* A list of all installed Vortex devices, for removing the driver module. */
-static struct device *root_vortex_dev = NULL;
-
-int
-init_module(void)
-{
- int cards_found;
-
- if (debug >= 0)
- vortex_debug = debug;
- if (vortex_debug)
- printk(version);
-
- root_vortex_dev = NULL;
- cards_found = vortex_scan(0);
- return cards_found < 0 ? cards_found : 0;
-}
-
-#else
-unsigned long tc59x_probe(struct device *dev)
-{
- int cards_found = 0;
-
- cards_found = vortex_scan(dev);
-
- if (vortex_debug > 0 && cards_found)
- printk(version);
-
- return cards_found ? 0 : -ENODEV;
-}
-#endif /* not MODULE */
-
-static int vortex_scan(struct device *dev)
-{
- int cards_found = 0;
-
- if (pcibios_present()) {
- static int pci_index = 0;
- for (; pci_index < 8; pci_index++) {
- unsigned char pci_bus, pci_device_fn, pci_irq_line, pci_latency;
- unsigned int pci_ioaddr;
- unsigned short pci_command;
- int index;
-
- for (index = 0; product_ids[index]; index++) {
- if ( ! pcibios_find_device(TCOM_VENDOR_ID, product_ids[index],
- pci_index, &pci_bus,
- &pci_device_fn))
- break;
- }
- if ( ! product_ids[index])
- break;
-
- pcibios_read_config_byte(pci_bus, pci_device_fn,
- PCI_INTERRUPT_LINE, &pci_irq_line);
- pcibios_read_config_dword(pci_bus, pci_device_fn,
- PCI_BASE_ADDRESS_0, &pci_ioaddr);
- /* Remove I/O space marker in bit 0. */
- pci_ioaddr &= ~3;
-
-#ifdef VORTEX_BUS_MASTER
- /* Get and check the bus-master and latency values.
- Some PCI BIOSes fail to set the master-enable bit, and
- the latency timer must be set to the maximum value to avoid
- data corruption that occurs when the timer expires during
- a transfer. Yes, it's a bug. */
- pcibios_read_config_word(pci_bus, pci_device_fn,
- PCI_COMMAND, &pci_command);
- if ( ! (pci_command & PCI_COMMAND_MASTER)) {
- printk(" PCI Master Bit has not been set! Setting...\n");
- pci_command |= PCI_COMMAND_MASTER;
- pcibios_write_config_word(pci_bus, pci_device_fn,
- PCI_COMMAND, pci_command);
- }
- pcibios_read_config_byte(pci_bus, pci_device_fn,
- PCI_LATENCY_TIMER, &pci_latency);
- if (pci_latency != 255) {
- printk(" Overriding PCI latency timer (CFLT) setting of %d, new value is 255.\n", pci_latency);
- pcibios_write_config_byte(pci_bus, pci_device_fn,
- PCI_LATENCY_TIMER, 255);
- }
-#endif /* VORTEX_BUS_MASTER */
- vortex_found_device(dev, pci_ioaddr, pci_irq_line, index,
- dev && dev->mem_start ? dev->mem_start
- : options[cards_found]);
- dev = 0;
- cards_found++;
- }
- }
-
- /* Now check all slots of the EISA bus. */
- if (EISA_bus) {
- static int ioaddr = 0x1000;
- for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) {
- /* Check the standard EISA ID register for an encoded '3Com'. */
- if (inw(ioaddr + 0xC80) != 0x6d50)
- continue;
- /* Check for a product that we support. */
- if ((inw(ioaddr + 0xC82) & 0xFFF0) != 0x5970
- && (inw(ioaddr + 0xC82) & 0xFFF0) != 0x5920)
- continue;
- vortex_found_device(dev, ioaddr, inw(ioaddr + 0xC88) >> 12,
- DEMON_INDEX, dev && dev->mem_start
- ? dev->mem_start : options[cards_found]);
- dev = 0;
- cards_found++;
- }
- }
-
- return cards_found;
-}
-
-static int vortex_found_device(struct device *dev, int ioaddr, int irq,
- int product_index, int options)
-{
- struct vortex_private *vp;
-
-#ifdef MODULE
- /* Allocate and fill new device structure. */
- int dev_size = sizeof(struct device) +
- sizeof(struct vortex_private);
-
- dev = (struct device *) kmalloc(dev_size, GFP_KERNEL);
- memset(dev, 0, dev_size);
- dev->priv = ((void *)dev) + sizeof(struct device);
- vp = (struct vortex_private *)dev->priv;
- dev->name = vp->devname; /* An empty string. */
- dev->base_addr = ioaddr;
- dev->irq = irq;
- dev->init = vortex_probe1;
- vp->product_name = product_names[product_index];
- vp->options = options;
- if (options >= 0) {
- vp->media_override = ((options & 7) == 2) ? 0 : options & 7;
- vp->full_duplex = (options & 8) ? 1 : 0;
- vp->bus_master = (options & 16) ? 1 : 0;
- } else {
- vp->media_override = 7;
- vp->full_duplex = 0;
- vp->bus_master = 0;
- }
- ether_setup(dev);
- vp->next_module = root_vortex_dev;
- root_vortex_dev = dev;
- if (register_netdev(dev) != 0)
- return -EIO;
-#else /* not a MODULE */
- if (dev) {
- dev->priv = kmalloc(sizeof (struct vortex_private), GFP_KERNEL);
- memset(dev->priv, 0, sizeof (struct vortex_private));
- }
- dev = init_etherdev(dev, sizeof(struct vortex_private));
- dev->base_addr = ioaddr;
- dev->irq = irq;
- vp = (struct vortex_private *)dev->priv;
- vp->product_name = product_names[product_index];
- vp->options = options;
- if (options >= 0) {
- vp->media_override = ((options & 7) == 2) ? 0 : options & 7;
- vp->full_duplex = (options & 8) ? 1 : 0;
- vp->bus_master = (options & 16) ? 1 : 0;
- } else {
- vp->media_override = 7;
- vp->full_duplex = 0;
- vp->bus_master = 0;
- }
-
- vortex_probe1(dev);
-#endif /* MODULE */
- return 0;
-}
-
-static int vortex_probe1(struct device *dev)
-{
- int ioaddr = dev->base_addr;
- struct vortex_private *vp = (struct vortex_private *)dev->priv;
- int i;
-
- printk("%s: 3Com %s at %#3x,", dev->name,
- vp->product_name, ioaddr);
-
- /* Read the station address from the EEPROM. */
- EL3WINDOW(0);
- for (i = 0; i < 3; i++) {
- short *phys_addr = (short *)dev->dev_addr;
- int timer;
- outw(EEPROM_Read + PhysAddr01 + i, ioaddr + Wn0EepromCmd);
- /* Pause for at least 162 us. for the read to take place. */
- for (timer = 0; timer < 162*4 + 400; timer++) {
- SLOW_DOWN_IO;
- if ((inw(ioaddr + Wn0EepromCmd) & 0x8000) == 0)
- break;
- }
- phys_addr[i] = htons(inw(ioaddr + 12));
- }
- for (i = 0; i < 6; i++)
- printk("%c%2.2x", i ? ':' : ' ', dev->dev_addr[i]);
- printk(", IRQ %d\n", dev->irq);
- /* Tell them about an invalid IRQ. */
- if (vortex_debug && (dev->irq <= 0 || dev->irq > 15))
- printk(" *** Warning: this IRQ is unlikely to work!\n");
-
- {
- char *ram_split[] = {"5:3", "3:1", "1:1", "invalid"};
- union wn3_config config;
- EL3WINDOW(3);
- config.i = inl(ioaddr + Wn3_Config);
- if (vortex_debug > 1)
- printk(" Internal config register is %4.4x, transceivers %#x.\n",
- config.i, inw(ioaddr + Wn3_Options));
- printk(" %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
- 8 << config.u.ram_size,
- config.u.ram_width ? "word" : "byte",
- ram_split[config.u.ram_split],
- config.u.autoselect ? "autoselect/" : "",
- if_names[config.u.xcvr]);
- dev->if_port = config.u.xcvr;
- vp->autoselect = config.u.autoselect;
- }
-
- /* We do a request_region() only to register /proc/ioports info. */
- request_region(ioaddr, VORTEX_TOTAL_SIZE, vp->product_name);
-
- /* The 3c59x-specific entries in the device structure. */
- dev->open = &vortex_open;
- dev->hard_start_xmit = &vortex_start_xmit;
- dev->stop = &vortex_close;
- dev->get_stats = &vortex_get_stats;
- dev->set_multicast_list = &set_multicast_list;
-#if defined (HAVE_SET_MAC_ADDR) && 0
- dev->set_mac_address = &set_mac_address;
-#endif
-
- return 0;
-}
-
-
-static int
-vortex_open(struct device *dev)
-{
- int ioaddr = dev->base_addr;
- struct vortex_private *vp = (struct vortex_private *)dev->priv;
- union wn3_config config;
- int i;
-
- /* Before initializing select the active media port. */
- EL3WINDOW(3);
- if (vp->full_duplex)
- outb(0x20, ioaddr + Wn3_MAC_Ctrl); /* Set the full-duplex bit. */
- config.i = inl(ioaddr + Wn3_Config);
-
- if (vp->media_override != 7) {
- if (vortex_debug > 1)
- printk("%s: Media override to transceiver %d (%s).\n",
- dev->name, vp->media_override, if_names[vp->media_override]);
- config.u.xcvr = vp->media_override;
- dev->if_port = vp->media_override;
- outl(config.i, ioaddr + Wn3_Config);
- }
-
- if (vortex_debug > 1) {
- printk("%s: vortex_open() InternalConfig %8.8x.\n",
- dev->name, config.i);
- }
-
- outw(TxReset, ioaddr + EL3_CMD);
- for (i = 20; i >= 0 ; i--)
- if ( ! inw(ioaddr + EL3_STATUS) & CmdInProgress)
- break;
-
- outw(RxReset, ioaddr + EL3_CMD);
- /* Wait a few ticks for the RxReset command to complete. */
- for (i = 20; i >= 0 ; i--)
- if ( ! inw(ioaddr + EL3_STATUS) & CmdInProgress)
- break;
-
- outw(SetStatusEnb | 0x00, ioaddr + EL3_CMD);
-
-#ifdef USE_SHARED_IRQ
- i = request_shared_irq(dev->irq, &vortex_interrupt, dev, vp->product_name);
- if (i) /* Error */
- return i;
-#else
- if (dev->irq == 0 || irq2dev_map[dev->irq] != NULL)
- return -EAGAIN;
- irq2dev_map[dev->irq] = dev;
- if (request_irq(dev->irq, &vortex_interrupt, 0, vp->product_name)) {
- irq2dev_map[dev->irq] = NULL;
- return -EAGAIN;
- }
-#endif
-
- if (vortex_debug > 1) {
- EL3WINDOW(4);
- printk("%s: vortex_open() irq %d media status %4.4x.\n",
- dev->name, dev->irq, inw(ioaddr + Wn4_Media));
- }
-
- /* Set the station address and mask in window 2 each time opened. */
- EL3WINDOW(2);
- for (i = 0; i < 6; i++)
- outb(dev->dev_addr[i], ioaddr + i);
- for (; i < 12; i+=2)
- outw(0, ioaddr + i);
-
- if (dev->if_port == 3)
- /* Start the thinnet transceiver. We should really wait 50ms...*/
- outw(StartCoax, ioaddr + EL3_CMD);
- else if (dev->if_port == 0) {
- /* 10baseT interface, enabled link beat and jabber check. */
- EL3WINDOW(4);
- outw(inw(ioaddr + Wn4_Media) | Media_TP, ioaddr + Wn4_Media);
- }
-
- /* Switch to the stats window, and clear all stats by reading. */
- outw(StatsDisable, ioaddr + EL3_CMD);
- EL3WINDOW(6);
- for (i = 0; i < 10; i++)
- inb(ioaddr + i);
- inw(ioaddr + 10);
- inw(ioaddr + 12);
- /* New: On the Vortex we must also clear the BadSSD counter. */
- EL3WINDOW(4);
- inb(ioaddr + 12);
-
- /* Switch to register set 7 for normal use. */
- EL3WINDOW(7);
-
- /* Accept b-case and phys addr only. */
- outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD);
- outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */
-
- dev->tbusy = 0;
- dev->interrupt = 0;
- dev->start = 1;
-
- outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */
- outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */
- /* Allow status bits to be seen. */
- outw(SetStatusEnb | 0xff, ioaddr + EL3_CMD);
- /* Ack all pending events, and set active indicator mask. */
- outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq,
- ioaddr + EL3_CMD);
- outw(SetIntrEnb | IntLatch | TxAvailable | RxComplete | StatsFull
- | DMADone, ioaddr + EL3_CMD);
-
-#ifdef MODULE
- MOD_INC_USE_COUNT;
-#endif
-
- if (vp->autoselect) {
- init_timer(&vp->timer);
- vp->timer.expires = (14*HZ)/10; /* 1.4 sec. */
- vp->timer.data = (unsigned long)dev;
- vp->timer.function = &vortex_timer; /* timer handler */
- add_timer(&vp->timer);
- }
- return 0;
-}
-
-static void vortex_timer(unsigned long data)
-{
- struct device *dev = (struct device *)data;
- if (vortex_debug > 2)
- printk("%s: Media selection timer tick happened.\n", dev->name);
- /* ToDo: active media selection here! */
-}
-
-static int
-vortex_start_xmit(struct sk_buff *skb, struct device *dev)
-{
- struct vortex_private *vp = (struct vortex_private *)dev->priv;
- int ioaddr = dev->base_addr;
-
- /* Transmitter timeout, serious problems. */
- if (dev->tbusy) {
- int tickssofar = jiffies - dev->trans_start;
- if (tickssofar < 40)
- return 1;
- printk("%s: transmit timed out, tx_status %2.2x status %4.4x.\n",
- dev->name, inb(ioaddr + TxStatus), inw(ioaddr + EL3_STATUS));
- vp->stats.tx_errors++;
- /* Issue TX_RESET and TX_START commands. */
- outw(TxReset, ioaddr + EL3_CMD);
- {
- int i;
- for (i = 20; i >= 0 ; i--)
- if ( ! inw(ioaddr + EL3_STATUS) & CmdInProgress)
- break;
- }
- outw(TxEnable, ioaddr + EL3_CMD);
- dev->trans_start = jiffies;
- dev->tbusy = 0;
- return 0;
- }
-
- if (skb == NULL || skb->len <= 0) {
- printk("%s: Obsolete driver layer request made: skbuff==NULL.\n",
- dev->name);
- dev_tint(dev);
- return 0;
- }
-
- /* Block a timer-based transmit from overlapping. This could better be
- done with atomic_swap(1, dev->tbusy), but set_bit() works as well.
- If this ever occurs the queue layer is doing something evil! */
- if (set_bit(0, (void*)&dev->tbusy) != 0) {
- printk("%s: Transmitter access conflict.\n", dev->name);
- return 1;
- }
-
- /* Put out the doubleword header... */
- outl(skb->len, ioaddr + TX_FIFO);
-#ifdef VORTEX_BUS_MASTER
- if (vp->bus_master) {
- /* Set the bus-master controller to transfer the packet. */
- outl((int)(skb->data), ioaddr + Wn7_MasterAddr);
- outw((skb->len + 3) & ~3, ioaddr + Wn7_MasterLen);
- vp->tx_skb = skb;
- outw(StartDMADown, ioaddr + EL3_CMD);
- } else {
- /* ... and the packet rounded to a doubleword. */
- outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
- dev_kfree_skb (skb, FREE_WRITE);
- if (inw(ioaddr + TxFree) > 1536) {
- dev->tbusy = 0;
- } else
- /* Interrupt us when the FIFO has room for max-sized packet. */
- outw(SetTxThreshold + 1536, ioaddr + EL3_CMD);
- }
-#else
- /* ... and the packet rounded to a doubleword. */
- outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
- dev_kfree_skb (skb, FREE_WRITE);
- if (inw(ioaddr + TxFree) > 1536) {
- dev->tbusy = 0;
- } else
- /* Interrupt us when the FIFO has room for max-sized packet. */
- outw(SetTxThreshold + 1536, ioaddr + EL3_CMD);
-#endif /* bus master */
-
- dev->trans_start = jiffies;
-
- /* Clear the Tx status stack. */
- {
- short tx_status;
- int i = 4;
-
- while (--i > 0 && (tx_status = inb(ioaddr + TxStatus)) > 0) {
- if (tx_status & 0x3C) { /* A Tx-disabling error occured. */
- if (vortex_debug > 2)
- printk("%s: Tx error, status %2.2x.\n",
- dev->name, tx_status);
- if (tx_status & 0x04) vp->stats.tx_fifo_errors++;
- if (tx_status & 0x38) vp->stats.tx_aborted_errors++;
- if (tx_status & 0x30) {
- int j;
- outw(TxReset, ioaddr + EL3_CMD);
- for (j = 20; j >= 0 ; j--)
- if ( ! inw(ioaddr + EL3_STATUS) & CmdInProgress)
- break;
- }
- outw(TxEnable, ioaddr + EL3_CMD);
- }
- outb(0x00, ioaddr + TxStatus); /* Pop the status stack. */
- }
- }
- return 0;
-}
-
-/* The interrupt handler does all of the Rx thread work and cleans up
- after the Tx thread. */
-static void vortex_interrupt(int irq, struct pt_regs *regs)
-{
-#ifdef USE_SHARED_IRQ
- struct device *dev = (struct device *)(irq == 0 ? regs : irq2dev_map[irq]);
-#else
- struct device *dev = (struct device *)(irq2dev_map[irq]);
-#endif
- struct vortex_private *lp;
- int ioaddr, status;
- int latency;
- int i = 0;
-
- if (dev == NULL) {
- printk ("vortex_interrupt(): irq %d for unknown device.\n", irq);
- return;
- }
-
- if (dev->interrupt)
- printk("%s: Re-entering the interrupt handler.\n", dev->name);
- dev->interrupt = 1;
-
- ioaddr = dev->base_addr;
- latency = inb(ioaddr + Timer);
- lp = (struct vortex_private *)dev->priv;
-
- status = inw(ioaddr + EL3_STATUS);
-
- if (vortex_debug > 4)
- printk("%s: interrupt, status %4.4x, timer %d.\n", dev->name,
- status, latency);
- if ((status & 0xE000) != 0xE000) {
- static int donedidthis=0;
- /* Some interrupt controllers store a bogus interrupt from boot-time.
- Ignore a single early interrupt, but don't hang the machine for
- other interrupt problems. */
- if (donedidthis++ > 1) {
- printk("%s: Bogus interrupt, bailing. Status %4.4x, start=%d.\n",
- dev->name, status, dev->start);
- free_irq(dev->irq);
- }
- }
-
- do {
- if (vortex_debug > 5)
- printk("%s: In interrupt loop, status %4.4x.\n",
- dev->name, status);
- if (status & RxComplete)
- vortex_rx(dev);
-
- if (status & TxAvailable) {
- if (vortex_debug > 5)
- printk(" TX room bit was handled.\n");
- /* There's room in the FIFO for a full-sized packet. */
- outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
- dev->tbusy = 0;
- mark_bh(NET_BH);
- }
-#ifdef VORTEX_BUS_MASTER
- if (status & DMADone) {
- outw(0x1000, ioaddr + Wn7_MasterStatus); /* Ack the event. */
- dev->tbusy = 0;
- mark_bh(NET_BH);
- }
-#endif
- if (status & (AdapterFailure | RxEarly | StatsFull)) {
- /* Handle all uncommon interrupts at once. */
- if (status & RxEarly) { /* Rx early is unused. */
- vortex_rx(dev);
- outw(AckIntr | RxEarly, ioaddr + EL3_CMD);
- }
- if (status & StatsFull) { /* Empty statistics. */
- static int DoneDidThat = 0;
- if (vortex_debug > 4)
- printk("%s: Updating stats.\n", dev->name);
- update_stats(ioaddr, dev);
- /* DEBUG HACK: Disable statistics as an interrupt source. */
- /* This occurs when we have the wrong media type! */
- if (DoneDidThat == 0 &&
- inw(ioaddr + EL3_STATUS) & StatsFull) {
- int win, reg;
- printk("%s: Updating stats failed, disabling stats as an"
- " interrupt source.\n", dev->name);
- for (win = 0; win < 8; win++) {
- EL3WINDOW(win);
- printk("\n Vortex window %d:", win);
- for (reg = 0; reg < 16; reg++)
- printk(" %2.2x", inb(ioaddr+reg));
- }
- EL3WINDOW(7);
- outw(SetIntrEnb | 0x18, ioaddr + EL3_CMD);
- DoneDidThat++;
- }
- }
- if (status & AdapterFailure) {
- /* Adapter failure requires Rx reset and reinit. */
- outw(RxReset, ioaddr + EL3_CMD);
- /* Set the Rx filter to the current state. */
- outw(SetRxFilter | RxStation | RxBroadcast
- | (dev->flags & IFF_ALLMULTI ? RxMulticast : 0)
- | (dev->flags & IFF_PROMISC ? RxProm : 0),
- ioaddr + EL3_CMD);
- outw(RxEnable, ioaddr + EL3_CMD); /* Re-enable the receiver. */
- outw(AckIntr | AdapterFailure, ioaddr + EL3_CMD);
- }
- }
-
- if (++i > 10) {
- printk("%s: Infinite loop in interrupt, status %4.4x. "
- "Disabling functions (%4.4x).\n",
- dev->name, status, SetStatusEnb | ((~status) & 0xFE));
- /* Disable all pending interrupts. */
- outw(SetStatusEnb | ((~status) & 0xFE), ioaddr + EL3_CMD);
- outw(AckIntr | 0xFF, ioaddr + EL3_CMD);
- break;
- }
- /* Acknowledge the IRQ. */
- outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
-
- } while ((status = inw(ioaddr + EL3_STATUS)) & (IntLatch | RxComplete));
-
- if (vortex_debug > 4)
- printk("%s: exiting interrupt, status %4.4x.\n", dev->name, status);
-
- dev->interrupt = 0;
- return;
-}
-
-static int
-vortex_rx(struct device *dev)
-{
- struct vortex_private *vp = (struct vortex_private *)dev->priv;
- int ioaddr = dev->base_addr;
- int i;
- short rx_status;
-
- if (vortex_debug > 5)
- printk(" In rx_packet(), status %4.4x, rx_status %4.4x.\n",
- inw(ioaddr+EL3_STATUS), inw(ioaddr+RxStatus));
- while ((rx_status = inw(ioaddr + RxStatus)) > 0) {
- if (rx_status & 0x4000) { /* Error, update stats. */
- unsigned char rx_error = inb(ioaddr + RxErrors);
- if (vortex_debug > 4)
- printk(" Rx error: status %2.2x.\n", rx_error);
- vp->stats.rx_errors++;
- if (rx_error & 0x01) vp->stats.rx_over_errors++;
- if (rx_error & 0x02) vp->stats.rx_length_errors++;
- if (rx_error & 0x04) vp->stats.rx_frame_errors++;
- if (rx_error & 0x08) vp->stats.rx_crc_errors++;
- if (rx_error & 0x10) vp->stats.rx_length_errors++;
- } else {
- /* The packet length: up to 4.5K!. */
- short pkt_len = rx_status & 0x1fff;
- struct sk_buff *skb;
-
- skb = dev_alloc_skb(pkt_len + 5);
- if (vortex_debug > 4)
- printk("Receiving packet size %d status %4.4x.\n",
- pkt_len, rx_status);
- if (skb != NULL) {
- skb->dev = dev;
- skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
- /* 'skb_put()' points to the start of sk_buff data area. */
- insl(ioaddr + RX_FIFO, skb_put(skb, pkt_len),
- (pkt_len + 3) >> 2);
- skb->protocol = eth_type_trans(skb, dev);
- netif_rx(skb);
- outw(RxDiscard, ioaddr + EL3_CMD); /* Pop top Rx packet. */
- /* Wait a limited time to go to next packet. */
- for (i = 200; i >= 0; i--)
- if ( ! inw(ioaddr + EL3_STATUS) & CmdInProgress)
- break;
- vp->stats.rx_packets++;
- continue;
- } else if (vortex_debug)
- printk("%s: Couldn't allocate a sk_buff of size %d.\n",
- dev->name, pkt_len);
- }
- vp->stats.rx_dropped++;
- outw(RxDiscard, ioaddr + EL3_CMD);
- /* Wait a limited time to skip this packet. */
- for (i = 200; i >= 0; i--)
- if ( ! inw(ioaddr + EL3_STATUS) & CmdInProgress)
- break;
- }
-
- return 0;
-}
-
-static int
-vortex_close(struct device *dev)
-{
- int ioaddr = dev->base_addr;
-
- dev->start = 0;
- dev->tbusy = 1;
-
- if (vortex_debug > 1)
- printk("%s: vortex_close() status %4.4x, Tx status %2.2x.\n",
- dev->name, inw(ioaddr + EL3_STATUS), inb(ioaddr + TxStatus));
-
- /* Turn off statistics ASAP. We update lp->stats below. */
- outw(StatsDisable, ioaddr + EL3_CMD);
-
- /* Disable the receiver and transmitter. */
- outw(RxDisable, ioaddr + EL3_CMD);
- outw(TxDisable, ioaddr + EL3_CMD);
-
- if (dev->if_port == 3)
- /* Turn off thinnet power. Green! */
- outw(StopCoax, ioaddr + EL3_CMD);
- else if (dev->if_port == 0) {
- /* Disable link beat and jabber, if_port may change ere next open(). */
- EL3WINDOW(4);
- outw(inw(ioaddr + Wn4_Media) & ~Media_TP, ioaddr + Wn4_Media);
- }
-
-#ifdef USE_SHARED_IRQ
- free_shared_irq(dev->irq, dev);
-#else
- free_irq(dev->irq);
- /* Mmmm, we should diable all interrupt sources here. */
- irq2dev_map[dev->irq] = 0;
-#endif
-
- update_stats(ioaddr, dev);
-#ifdef MODULE
- MOD_DEC_USE_COUNT;
-#endif
-
- return 0;
-}
-
-static struct enet_statistics *
-vortex_get_stats(struct device *dev)
-{
- struct vortex_private *vp = (struct vortex_private *)dev->priv;
- unsigned long flags;
-
- save_flags(flags);
- cli();
- update_stats(dev->base_addr, dev);
- restore_flags(flags);
- return &vp->stats;
-}
-
-/* Update statistics.
- Unlike with the EL3 we need not worry about interrupts changing
- the window setting from underneath us, but we must still guard
- against a race condition with a StatsUpdate interrupt updating the
- table. This is done by checking that the ASM (!) code generated uses
- atomic updates with '+='.
- */
-static void update_stats(int ioaddr, struct device *dev)
-{
- struct vortex_private *vp = (struct vortex_private *)dev->priv;
-
- /* Unlike the 3c5x9 we need not turn off stats updates while reading. */
- /* Switch to the stats window, and read everything. */
- EL3WINDOW(6);
- vp->stats.tx_carrier_errors += inb(ioaddr + 0);
- vp->stats.tx_heartbeat_errors += inb(ioaddr + 1);
- /* Multiple collisions. */ inb(ioaddr + 2);
- vp->stats.collisions += inb(ioaddr + 3);
- vp->stats.tx_window_errors += inb(ioaddr + 4);
- vp->stats.rx_fifo_errors += inb(ioaddr + 5);
- vp->stats.tx_packets += inb(ioaddr + 6);
- vp->stats.tx_packets += (inb(ioaddr + 9)&0x30) << 4;
- /* Rx packets */ inb(ioaddr + 7); /* Must read to clear */
- /* Tx deferrals */ inb(ioaddr + 8);
- /* Don't bother with register 9, an extention of registers 6&7.
- If we do use the 6&7 values the atomic update assumption above
- is invalid. */
- inw(ioaddr + 10); /* Total Rx and Tx octets. */
- inw(ioaddr + 12);
- /* New: On the Vortex we must also clear the BadSSD counter. */
- EL3WINDOW(4);
- inb(ioaddr + 12);
-
- /* We change back to window 7 (not 1) with the Vortex. */
- EL3WINDOW(7);
- return;
-}
-
-/* There are two version of set_multicast_list() to support both v1.2 and
- v1.4 kernels. */
-static void
-set_multicast_list(struct device *dev)
-{
- short ioaddr = dev->base_addr;
-
- if ((dev->mc_list) || (dev->flags & IFF_ALLMULTI)) {
- outw(SetRxFilter|RxStation|RxMulticast|RxBroadcast, ioaddr + EL3_CMD);
- if (vortex_debug > 3) {
- printk("%s: Setting Rx multicast mode, %d addresses.\n",
- dev->name, dev->mc_count);
- }
- } else if (dev->flags & IFF_PROMISC) {
- outw(SetRxFilter | RxStation | RxMulticast | RxBroadcast | RxProm,
- ioaddr + EL3_CMD);
- } else
- outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD);
-}
-
-
-#ifdef MODULE
-void
-cleanup_module(void)
-{
- struct device *next_dev;
-
- /* No need to check MOD_IN_USE, as sys_delete_module() checks. */
- while (root_vortex_dev) {
- next_dev = ((struct vortex_private *)root_vortex_dev->priv)->next_module;
- unregister_netdev(root_vortex_dev);
- release_region(root_vortex_dev->base_addr, VORTEX_TOTAL_SIZE);
- kfree(root_vortex_dev);
- root_vortex_dev = next_dev;
- }
-}
-#endif /* MODULE */
-
-/*
- * Local variables:
- * compile-command: "gcc -DMODULE -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c 3c59x.c -o 3c59x.o"
- * c-indent-level: 4
- * tab-width: 4
- * End:
- */
diff --git a/i386/i386at/gpl/linux/net/8390.c b/i386/i386at/gpl/linux/net/8390.c
deleted file mode 100644
index 7962413c..00000000
--- a/i386/i386at/gpl/linux/net/8390.c
+++ /dev/null
@@ -1,727 +0,0 @@
-/* 8390.c: A general NS8390 ethernet driver core for linux. */
-/*
- Written 1992-94 by Donald Becker.
-
- Copyright 1993 United States Government as represented by the
- Director, National Security Agency.
-
- This software may be used and distributed according to the terms
- of the GNU Public License, incorporated herein by reference.
-
- The author may be reached as becker@CESDIS.gsfc.nasa.gov, or C/O
- Center of Excellence in Space Data and Information Sciences
- Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
-
- This is the chip-specific code for many 8390-based ethernet adaptors.
- This is not a complete driver, it must be combined with board-specific
- code such as ne.c, wd.c, 3c503.c, etc.
-
- Changelog:
-
- Paul Gortmaker : remove set_bit lock, other cleanups.
- Paul Gortmaker : add ei_get_8390_hdr() so we can pass skb's to
- ei_block_input() for eth_io_copy_and_sum().
-
- */
-
-static const char *version =
- "8390.c:v1.10 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
-
-/*
- Braindamage remaining:
- Much of this code should have been cleaned up, but every attempt
- has broken some clone part.
-
- Sources:
- The National Semiconductor LAN Databook, and the 3Com 3c503 databook.
- */
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/fs.h>
-#include <linux/types.h>
-#include <linux/ptrace.h>
-#include <linux/string.h>
-#include <asm/system.h>
-#include <asm/segment.h>
-#include <asm/bitops.h>
-#include <asm/io.h>
-#include <linux/errno.h>
-#include <linux/fcntl.h>
-#include <linux/in.h>
-#include <linux/interrupt.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-
-#include "8390.h"
-
-/* These are the operational function interfaces to board-specific
- routines.
- void reset_8390(struct device *dev)
- Resets the board associated with DEV, including a hardware reset of
- the 8390. This is only called when there is a transmit timeout, and
- it is always followed by 8390_init().
- void block_output(struct device *dev, int count, const unsigned char *buf,
- int start_page)
- Write the COUNT bytes of BUF to the packet buffer at START_PAGE. The
- "page" value uses the 8390's 256-byte pages.
- void get_8390_hdr(struct device *dev, struct e8390_hdr *hdr, int ring_page)
- Read the 4 byte, page aligned 8390 header. *If* there is a
- subsequent read, it will be of the rest of the packet.
- void block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset)
- Read COUNT bytes from the packet buffer into the skb data area. Start
- reading from RING_OFFSET, the address as the 8390 sees it. This will always
- follow the read of the 8390 header.
-*/
-#define ei_reset_8390 (ei_local->reset_8390)
-#define ei_block_output (ei_local->block_output)
-#define ei_block_input (ei_local->block_input)
-#define ei_get_8390_hdr (ei_local->get_8390_hdr)
-
-/* use 0 for production, 1 for verification, >2 for debug */
-#ifdef EI_DEBUG
-int ei_debug = EI_DEBUG;
-#else
-int ei_debug = 0;
-#endif
-#ifdef EI_PINGPONG
-static int ei_pingpong = 1;
-#else
-static int ei_pingpong = 0;
-#endif
-
-/* Max number of packets received at one Intr.
- Currently this may only be examined by a kernel debugger. */
-static int high_water_mark = 0;
-
-/* Index to functions. */
-static void ei_tx_intr(struct device *dev);
-static void ei_receive(struct device *dev);
-static void ei_rx_overrun(struct device *dev);
-
-/* Routines generic to NS8390-based boards. */
-static void NS8390_trigger_send(struct device *dev, unsigned int length,
- int start_page);
-static void set_multicast_list(struct device *dev);
-
-
-/* Open/initialize the board. This routine goes all-out, setting everything
- up anew at each open, even though many of these registers should only
- need to be set once at boot.
- */
-int ei_open(struct device *dev)
-{
- struct ei_device *ei_local = (struct ei_device *) dev->priv;
-
- /* This can't happen unless somebody forgot to call ethdev_init(). */
- if (ei_local == NULL) {
- printk(KERN_EMERG "%s: ei_open passed a non-existent device!\n", dev->name);
- return -ENXIO;
- }
-
- irq2dev_map[dev->irq] = dev;
- NS8390_init(dev, 1);
- dev->start = 1;
- ei_local->irqlock = 0;
- return 0;
-}
-
-/* Opposite of above. Only used when "ifconfig <devname> down" is done. */
-int ei_close(struct device *dev)
-{
- NS8390_init(dev, 0);
- dev->start = 0;
- return 0;
-}
-
-static int ei_start_xmit(struct sk_buff *skb, struct device *dev)
-{
- int e8390_base = dev->base_addr;
- struct ei_device *ei_local = (struct ei_device *) dev->priv;
- int length, send_length;
-
-/*
- * We normally shouldn't be called if dev->tbusy is set, but the
- * existing code does anyway. If it has been too long since the
- * last Tx, we assume the board has died and kick it.
- */
-
- if (dev->tbusy) { /* Do timeouts, just like the 8003 driver. */
- int txsr = inb(e8390_base+EN0_TSR), isr;
- int tickssofar = jiffies - dev->trans_start;
- if (tickssofar < TX_TIMEOUT || (tickssofar < (TX_TIMEOUT+5) && ! (txsr & ENTSR_PTX))) {
- return 1;
- }
- isr = inb(e8390_base+EN0_ISR);
- if (dev->start == 0) {
- printk("%s: xmit on stopped card\n", dev->name);
- return 1;
- }
-
- printk(KERN_DEBUG "%s: Tx timed out, %s TSR=%#2x, ISR=%#2x, t=%d.\n",
- dev->name, (txsr & ENTSR_ABT) ? "excess collisions." :
- (isr) ? "lost interrupt?" : "cable problem?", txsr, isr, tickssofar);
-
- if (!isr && !ei_local->stat.tx_packets) {
- /* The 8390 probably hasn't gotten on the cable yet. */
- ei_local->interface_num ^= 1; /* Try a different xcvr. */
- }
-
- /* Try to restart the card. Perhaps the user has fixed something. */
- ei_reset_8390(dev);
- NS8390_init(dev, 1);
- dev->trans_start = jiffies;
- }
-
- /* Sending a NULL skb means some higher layer thinks we've missed an
- tx-done interrupt. Caution: dev_tint() handles the cli()/sti()
- itself. */
- if (skb == NULL) {
- dev_tint(dev);
- return 0;
- }
-
- length = skb->len;
- if (skb->len <= 0)
- return 0;
-
- /* Mask interrupts from the ethercard. */
- outb_p(0x00, e8390_base + EN0_IMR);
- if (dev->interrupt) {
- printk("%s: Tx request while isr active.\n",dev->name);
- outb_p(ENISR_ALL, e8390_base + EN0_IMR);
- return 1;
- }
- ei_local->irqlock = 1;
-
- send_length = ETH_ZLEN < length ? length : ETH_ZLEN;
-
- if (ei_local->pingpong) {
- int output_page;
- if (ei_local->tx1 == 0) {
- output_page = ei_local->tx_start_page;
- ei_local->tx1 = send_length;
- if (ei_debug && ei_local->tx2 > 0)
- printk("%s: idle transmitter tx2=%d, lasttx=%d, txing=%d.\n",
- dev->name, ei_local->tx2, ei_local->lasttx,
- ei_local->txing);
- } else if (ei_local->tx2 == 0) {
- output_page = ei_local->tx_start_page + 6;
- ei_local->tx2 = send_length;
- if (ei_debug && ei_local->tx1 > 0)
- printk("%s: idle transmitter, tx1=%d, lasttx=%d, txing=%d.\n",
- dev->name, ei_local->tx1, ei_local->lasttx,
- ei_local->txing);
- } else { /* We should never get here. */
- if (ei_debug)
- printk("%s: No Tx buffers free. irq=%d tx1=%d tx2=%d last=%d\n",
- dev->name, dev->interrupt, ei_local->tx1,
- ei_local->tx2, ei_local->lasttx);
- ei_local->irqlock = 0;
- dev->tbusy = 1;
- outb_p(ENISR_ALL, e8390_base + EN0_IMR);
- return 1;
- }
- ei_block_output(dev, length, skb->data, output_page);
- if (! ei_local->txing) {
- ei_local->txing = 1;
- NS8390_trigger_send(dev, send_length, output_page);
- dev->trans_start = jiffies;
- if (output_page == ei_local->tx_start_page)
- ei_local->tx1 = -1, ei_local->lasttx = -1;
- else
- ei_local->tx2 = -1, ei_local->lasttx = -2;
- } else
- ei_local->txqueue++;
-
- dev->tbusy = (ei_local->tx1 && ei_local->tx2);
- } else { /* No pingpong, just a single Tx buffer. */
- ei_block_output(dev, length, skb->data, ei_local->tx_start_page);
- ei_local->txing = 1;
- NS8390_trigger_send(dev, send_length, ei_local->tx_start_page);
- dev->trans_start = jiffies;
- dev->tbusy = 1;
- }
-
- /* Turn 8390 interrupts back on. */
- ei_local->irqlock = 0;
- outb_p(ENISR_ALL, e8390_base + EN0_IMR);
-
- dev_kfree_skb (skb, FREE_WRITE);
-
- return 0;
-}
-
-/* The typical workload of the driver:
- Handle the ether interface interrupts. */
-void ei_interrupt(int irq, struct pt_regs * regs)
-{
- struct device *dev = (struct device *)(irq2dev_map[irq]);
- int e8390_base;
- int interrupts, nr_serviced = 0;
- struct ei_device *ei_local;
-
- if (dev == NULL) {
- printk ("net_interrupt(): irq %d for unknown device.\n", irq);
- return;
- }
- e8390_base = dev->base_addr;
- ei_local = (struct ei_device *) dev->priv;
- if (dev->interrupt || ei_local->irqlock) {
- /* The "irqlock" check is only for testing. */
- printk(ei_local->irqlock
- ? "%s: Interrupted while interrupts are masked! isr=%#2x imr=%#2x.\n"
- : "%s: Reentering the interrupt handler! isr=%#2x imr=%#2x.\n",
- dev->name, inb_p(e8390_base + EN0_ISR),
- inb_p(e8390_base + EN0_IMR));
- return;
- }
-
- dev->interrupt = 1;
-
- /* Change to page 0 and read the intr status reg. */
- outb_p(E8390_NODMA+E8390_PAGE0, e8390_base + E8390_CMD);
- if (ei_debug > 3)
- printk("%s: interrupt(isr=%#2.2x).\n", dev->name,
- inb_p(e8390_base + EN0_ISR));
-
- /* !!Assumption!! -- we stay in page 0. Don't break this. */
- while ((interrupts = inb_p(e8390_base + EN0_ISR)) != 0
- && ++nr_serviced < MAX_SERVICE) {
- if (dev->start == 0) {
- printk("%s: interrupt from stopped card\n", dev->name);
- interrupts = 0;
- break;
- }
- if (interrupts & ENISR_OVER) {
- ei_rx_overrun(dev);
- } else if (interrupts & (ENISR_RX+ENISR_RX_ERR)) {
- /* Got a good (?) packet. */
- ei_receive(dev);
- }
- /* Push the next to-transmit packet through. */
- if (interrupts & ENISR_TX) {
- ei_tx_intr(dev);
- } else if (interrupts & ENISR_COUNTERS) {
- ei_local->stat.rx_frame_errors += inb_p(e8390_base + EN0_COUNTER0);
- ei_local->stat.rx_crc_errors += inb_p(e8390_base + EN0_COUNTER1);
- ei_local->stat.rx_missed_errors+= inb_p(e8390_base + EN0_COUNTER2);
- outb_p(ENISR_COUNTERS, e8390_base + EN0_ISR); /* Ack intr. */
- }
-
- /* Ignore the transmit errs and reset intr for now. */
- if (interrupts & ENISR_TX_ERR) {
- outb_p(ENISR_TX_ERR, e8390_base + EN0_ISR); /* Ack intr. */
- }
-
- /* Ignore any RDC interrupts that make it back to here. */
- if (interrupts & ENISR_RDC) {
- outb_p(ENISR_RDC, e8390_base + EN0_ISR);
- }
-
- outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, e8390_base + E8390_CMD);
- }
-
- if (interrupts && ei_debug) {
- outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, e8390_base + E8390_CMD);
- if (nr_serviced >= MAX_SERVICE) {
- printk("%s: Too much work at interrupt, status %#2.2x\n",
- dev->name, interrupts);
- outb_p(ENISR_ALL, e8390_base + EN0_ISR); /* Ack. most intrs. */
- } else {
- printk("%s: unknown interrupt %#2x\n", dev->name, interrupts);
- outb_p(0xff, e8390_base + EN0_ISR); /* Ack. all intrs. */
- }
- }
- dev->interrupt = 0;
- return;
-}
-
-/* We have finished a transmit: check for errors and then trigger the next
- packet to be sent. */
-static void ei_tx_intr(struct device *dev)
-{
- int e8390_base = dev->base_addr;
- int status = inb(e8390_base + EN0_TSR);
- struct ei_device *ei_local = (struct ei_device *) dev->priv;
-
- outb_p(ENISR_TX, e8390_base + EN0_ISR); /* Ack intr. */
-
- if (ei_local->pingpong) {
- ei_local->txqueue--;
- if (ei_local->tx1 < 0) {
- if (ei_local->lasttx != 1 && ei_local->lasttx != -1)
- printk("%s: bogus last_tx_buffer %d, tx1=%d.\n",
- ei_local->name, ei_local->lasttx, ei_local->tx1);
- ei_local->tx1 = 0;
- dev->tbusy = 0;
- if (ei_local->tx2 > 0) {
- ei_local->txing = 1;
- NS8390_trigger_send(dev, ei_local->tx2, ei_local->tx_start_page + 6);
- dev->trans_start = jiffies;
- ei_local->tx2 = -1,
- ei_local->lasttx = 2;
- } else
- ei_local->lasttx = 20, ei_local->txing = 0;
- } else if (ei_local->tx2 < 0) {
- if (ei_local->lasttx != 2 && ei_local->lasttx != -2)
- printk("%s: bogus last_tx_buffer %d, tx2=%d.\n",
- ei_local->name, ei_local->lasttx, ei_local->tx2);
- ei_local->tx2 = 0;
- dev->tbusy = 0;
- if (ei_local->tx1 > 0) {
- ei_local->txing = 1;
- NS8390_trigger_send(dev, ei_local->tx1, ei_local->tx_start_page);
- dev->trans_start = jiffies;
- ei_local->tx1 = -1;
- ei_local->lasttx = 1;
- } else
- ei_local->lasttx = 10, ei_local->txing = 0;
- } else
- printk("%s: unexpected TX-done interrupt, lasttx=%d.\n",
- dev->name, ei_local->lasttx);
- } else {
- ei_local->txing = 0;
- dev->tbusy = 0;
- }
-
- /* Minimize Tx latency: update the statistics after we restart TXing. */
- if (status & ENTSR_COL) ei_local->stat.collisions++;
- if (status & ENTSR_PTX)
- ei_local->stat.tx_packets++;
- else {
- ei_local->stat.tx_errors++;
- if (status & ENTSR_ABT) ei_local->stat.tx_aborted_errors++;
- if (status & ENTSR_CRS) ei_local->stat.tx_carrier_errors++;
- if (status & ENTSR_FU) ei_local->stat.tx_fifo_errors++;
- if (status & ENTSR_CDH) ei_local->stat.tx_heartbeat_errors++;
- if (status & ENTSR_OWC) ei_local->stat.tx_window_errors++;
- }
-
- mark_bh (NET_BH);
-}
-
-/* We have a good packet(s), get it/them out of the buffers. */
-
-static void ei_receive(struct device *dev)
-{
- int e8390_base = dev->base_addr;
- struct ei_device *ei_local = (struct ei_device *) dev->priv;
- int rxing_page, this_frame, next_frame, current_offset;
- int rx_pkt_count = 0;
- struct e8390_pkt_hdr rx_frame;
- int num_rx_pages = ei_local->stop_page-ei_local->rx_start_page;
-
- while (++rx_pkt_count < 10) {
- int pkt_len;
-
- /* Get the rx page (incoming packet pointer). */
- outb_p(E8390_NODMA+E8390_PAGE1, e8390_base + E8390_CMD);
- rxing_page = inb_p(e8390_base + EN1_CURPAG);
- outb_p(E8390_NODMA+E8390_PAGE0, e8390_base + E8390_CMD);
-
- /* Remove one frame from the ring. Boundary is always a page behind. */
- this_frame = inb_p(e8390_base + EN0_BOUNDARY) + 1;
- if (this_frame >= ei_local->stop_page)
- this_frame = ei_local->rx_start_page;
-
- /* Someday we'll omit the previous, iff we never get this message.
- (There is at least one clone claimed to have a problem.) */
- if (ei_debug > 0 && this_frame != ei_local->current_page)
- printk("%s: mismatched read page pointers %2x vs %2x.\n",
- dev->name, this_frame, ei_local->current_page);
-
- if (this_frame == rxing_page) /* Read all the frames? */
- break; /* Done for now */
-
- current_offset = this_frame << 8;
- ei_get_8390_hdr(dev, &rx_frame, this_frame);
-
- pkt_len = rx_frame.count - sizeof(struct e8390_pkt_hdr);
-
- next_frame = this_frame + 1 + ((pkt_len+4)>>8);
-
- /* Check for bogosity warned by 3c503 book: the status byte is never
- written. This happened a lot during testing! This code should be
- cleaned up someday. */
- if (rx_frame.next != next_frame
- && rx_frame.next != next_frame + 1
- && rx_frame.next != next_frame - num_rx_pages
- && rx_frame.next != next_frame + 1 - num_rx_pages) {
- ei_local->current_page = rxing_page;
- outb(ei_local->current_page-1, e8390_base+EN0_BOUNDARY);
- ei_local->stat.rx_errors++;
- continue;
- }
-
- if (pkt_len < 60 || pkt_len > 1518) {
- if (ei_debug)
- printk("%s: bogus packet size: %d, status=%#2x nxpg=%#2x.\n",
- dev->name, rx_frame.count, rx_frame.status,
- rx_frame.next);
- ei_local->stat.rx_errors++;
- } else if ((rx_frame.status & 0x0F) == ENRSR_RXOK) {
- struct sk_buff *skb;
-
- skb = dev_alloc_skb(pkt_len+2);
- if (skb == NULL) {
- if (ei_debug > 1)
- printk("%s: Couldn't allocate a sk_buff of size %d.\n",
- dev->name, pkt_len);
- ei_local->stat.rx_dropped++;
- break;
- } else {
- skb_reserve(skb,2); /* IP headers on 16 byte boundaries */
- skb->dev = dev;
- skb_put(skb, pkt_len); /* Make room */
- ei_block_input(dev, pkt_len, skb, current_offset + sizeof(rx_frame));
- skb->protocol=eth_type_trans(skb,dev);
- netif_rx(skb);
- ei_local->stat.rx_packets++;
- }
- } else {
- int errs = rx_frame.status;
- if (ei_debug)
- printk("%s: bogus packet: status=%#2x nxpg=%#2x size=%d\n",
- dev->name, rx_frame.status, rx_frame.next,
- rx_frame.count);
- if (errs & ENRSR_FO)
- ei_local->stat.rx_fifo_errors++;
- }
- next_frame = rx_frame.next;
-
- /* This _should_ never happen: it's here for avoiding bad clones. */
- if (next_frame >= ei_local->stop_page) {
- printk("%s: next frame inconsistency, %#2x\n", dev->name,
- next_frame);
- next_frame = ei_local->rx_start_page;
- }
- ei_local->current_page = next_frame;
- outb_p(next_frame-1, e8390_base+EN0_BOUNDARY);
- }
- /* If any worth-while packets have been received, netif_rx()
- has done a mark_bh(NET_BH) for us and will work on them
- when we get to the bottom-half routine. */
-
- /* Record the maximum Rx packet queue. */
- if (rx_pkt_count > high_water_mark)
- high_water_mark = rx_pkt_count;
-
- /* We used to also ack ENISR_OVER here, but that would sometimes mask
- a real overrun, leaving the 8390 in a stopped state with rec'vr off. */
- outb_p(ENISR_RX+ENISR_RX_ERR, e8390_base+EN0_ISR);
- return;
-}
-
-/* We have a receiver overrun: we have to kick the 8390 to get it started
- again.*/
-static void ei_rx_overrun(struct device *dev)
-{
- int e8390_base = dev->base_addr;
- int reset_start_time = jiffies;
- struct ei_device *ei_local = (struct ei_device *) dev->priv;
-
- /* We should already be stopped and in page0. Remove after testing. */
- outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base+E8390_CMD);
-
- if (ei_debug > 1)
- printk("%s: Receiver overrun.\n", dev->name);
- ei_local->stat.rx_over_errors++;
-
- /* The old Biro driver does dummy = inb_p( RBCR[01] ); at this point.
- It might mean something -- magic to speed up a reset? A 8390 bug?*/
-
- /* Wait for the reset to complete. This should happen almost instantly,
- but could take up to 1.5msec in certain rare instances. There is no
- easy way of timing something in that range, so we use 'jiffies' as
- a sanity check. */
- while ((inb_p(e8390_base+EN0_ISR) & ENISR_RESET) == 0)
- if (jiffies - reset_start_time > 2*HZ/100) {
- printk("%s: reset did not complete at ei_rx_overrun.\n",
- dev->name);
- NS8390_init(dev, 1);
- return;
- }
-
- /* Remove packets right away. */
- ei_receive(dev);
-
- outb_p(ENISR_OVER, e8390_base+EN0_ISR);
- /* Generic 8390 insns to start up again, same as in open_8390(). */
- outb_p(E8390_NODMA + E8390_PAGE0 + E8390_START, e8390_base + E8390_CMD);
- outb_p(E8390_TXCONFIG, e8390_base + EN0_TXCR); /* xmit on. */
-}
-
-static struct enet_statistics *get_stats(struct device *dev)
-{
- short ioaddr = dev->base_addr;
- struct ei_device *ei_local = (struct ei_device *) dev->priv;
-
- /* If the card is stopped, just return the present stats. */
- if (dev->start == 0) return &ei_local->stat;
-
- /* Read the counter registers, assuming we are in page 0. */
- ei_local->stat.rx_frame_errors += inb_p(ioaddr + EN0_COUNTER0);
- ei_local->stat.rx_crc_errors += inb_p(ioaddr + EN0_COUNTER1);
- ei_local->stat.rx_missed_errors+= inb_p(ioaddr + EN0_COUNTER2);
-
- return &ei_local->stat;
-}
-
-/*
- * Set or clear the multicast filter for this adaptor.
- */
-
-static void set_multicast_list(struct device *dev)
-{
- short ioaddr = dev->base_addr;
-
- if(dev->flags&IFF_PROMISC)
- {
- outb_p(E8390_RXCONFIG | 0x18, ioaddr + EN0_RXCR);
- }
- else if((dev->flags&IFF_ALLMULTI)||dev->mc_list)
- {
- /* The multicast-accept list is initialized to accept-all, and we
- rely on higher-level filtering for now. */
- outb_p(E8390_RXCONFIG | 0x08, ioaddr + EN0_RXCR);
- }
- else
- outb_p(E8390_RXCONFIG, ioaddr + EN0_RXCR);
-}
-
-/* Initialize the rest of the 8390 device structure. */
-int ethdev_init(struct device *dev)
-{
- if (ei_debug > 1)
- printk(version);
-
- if (dev->priv == NULL) {
- struct ei_device *ei_local;
-
- dev->priv = kmalloc(sizeof(struct ei_device), GFP_KERNEL);
- if (dev->priv == NULL)
- return -ENOMEM;
- memset(dev->priv, 0, sizeof(struct ei_device));
- ei_local = (struct ei_device *)dev->priv;
- ei_local->pingpong = ei_pingpong;
- }
-
- dev->hard_start_xmit = &ei_start_xmit;
- dev->get_stats = get_stats;
- dev->set_multicast_list = &set_multicast_list;
-
- ether_setup(dev);
-
- return 0;
-}
-
-
-/* This page of functions should be 8390 generic */
-/* Follow National Semi's recommendations for initializing the "NIC". */
-void NS8390_init(struct device *dev, int startp)
-{
- int e8390_base = dev->base_addr;
- struct ei_device *ei_local = (struct ei_device *) dev->priv;
- int i;
- int endcfg = ei_local->word16 ? (0x48 | ENDCFG_WTS) : 0x48;
- unsigned long flags;
-
- /* Follow National Semi's recommendations for initing the DP83902. */
- outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base); /* 0x21 */
- outb_p(endcfg, e8390_base + EN0_DCFG); /* 0x48 or 0x49 */
- /* Clear the remote byte count registers. */
- outb_p(0x00, e8390_base + EN0_RCNTLO);
- outb_p(0x00, e8390_base + EN0_RCNTHI);
- /* Set to monitor and loopback mode -- this is vital!. */
- outb_p(E8390_RXOFF, e8390_base + EN0_RXCR); /* 0x20 */
- outb_p(E8390_TXOFF, e8390_base + EN0_TXCR); /* 0x02 */
- /* Set the transmit page and receive ring. */
- outb_p(ei_local->tx_start_page, e8390_base + EN0_TPSR);
- ei_local->tx1 = ei_local->tx2 = 0;
- outb_p(ei_local->rx_start_page, e8390_base + EN0_STARTPG);
- outb_p(ei_local->stop_page-1, e8390_base + EN0_BOUNDARY); /* 3c503 says 0x3f,NS0x26*/
- ei_local->current_page = ei_local->rx_start_page; /* assert boundary+1 */
- outb_p(ei_local->stop_page, e8390_base + EN0_STOPPG);
- /* Clear the pending interrupts and mask. */
- outb_p(0xFF, e8390_base + EN0_ISR);
- outb_p(0x00, e8390_base + EN0_IMR);
-
- /* Copy the station address into the DS8390 registers,
- and set the multicast hash bitmap to receive all multicasts. */
- save_flags(flags);
- cli();
- outb_p(E8390_NODMA + E8390_PAGE1 + E8390_STOP, e8390_base); /* 0x61 */
- for(i = 0; i < 6; i++) {
- outb_p(dev->dev_addr[i], e8390_base + EN1_PHYS + i);
- }
- /* Initialize the multicast list to accept-all. If we enable multicast
- the higher levels can do the filtering. */
- for(i = 0; i < 8; i++)
- outb_p(0xff, e8390_base + EN1_MULT + i);
-
- outb_p(ei_local->rx_start_page, e8390_base + EN1_CURPAG);
- outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base);
- restore_flags(flags);
- dev->tbusy = 0;
- dev->interrupt = 0;
- ei_local->tx1 = ei_local->tx2 = 0;
- ei_local->txing = 0;
- if (startp) {
- outb_p(0xff, e8390_base + EN0_ISR);
- outb_p(ENISR_ALL, e8390_base + EN0_IMR);
- outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, e8390_base);
- outb_p(E8390_TXCONFIG, e8390_base + EN0_TXCR); /* xmit on. */
- /* 3c503 TechMan says rxconfig only after the NIC is started. */
- outb_p(E8390_RXCONFIG, e8390_base + EN0_RXCR); /* rx on, */
- dev->set_multicast_list(dev); /* Get the multicast status right if this
- was a reset. */
- }
- return;
-}
-
-/* Trigger a transmit start, assuming the length is valid. */
-static void NS8390_trigger_send(struct device *dev, unsigned int length,
- int start_page)
-{
- int e8390_base = dev->base_addr;
-
- outb_p(E8390_NODMA+E8390_PAGE0, e8390_base);
-
- if (inb_p(e8390_base) & E8390_TRANS) {
- printk("%s: trigger_send() called with the transmitter busy.\n",
- dev->name);
- return;
- }
- outb_p(length & 0xff, e8390_base + EN0_TCNTLO);
- outb_p(length >> 8, e8390_base + EN0_TCNTHI);
- outb_p(start_page, e8390_base + EN0_TPSR);
- outb_p(E8390_NODMA+E8390_TRANS+E8390_START, e8390_base);
- return;
-}
-
-#ifdef MODULE
-
-int init_module(void)
-{
- return 0;
-}
-
-void
-cleanup_module(void)
-{
-}
-#endif /* MODULE */
-
-/*
- * Local variables:
- * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c 8390.c"
- * version-control: t
- * kept-new-versions: 5
- * c-indent-level: 4
- * tab-width: 4
- * End:
- */
diff --git a/i386/i386at/gpl/linux/net/8390.h b/i386/i386at/gpl/linux/net/8390.h
deleted file mode 100644
index 17b8cdb5..00000000
--- a/i386/i386at/gpl/linux/net/8390.h
+++ /dev/null
@@ -1,168 +0,0 @@
-/* Generic NS8390 register definitions. */
-/* This file is part of Donald Becker's 8390 drivers, and is distributed
- under the same license.
- Some of these names and comments originated from the Crynwr
- packet drivers, which are distributed under the GPL. */
-
-#ifndef _8390_h
-#define _8390_h
-
-#include <linux/if_ether.h>
-#include <linux/ioport.h>
-#include <linux/skbuff.h>
-
-#define TX_2X_PAGES 12
-#define TX_1X_PAGES 6
-#define TX_PAGES (ei_status.pingpong ? TX_2X_PAGES : TX_1X_PAGES)
-
-#define ETHER_ADDR_LEN 6
-
-/* The 8390 specific per-packet-header format. */
-struct e8390_pkt_hdr {
- unsigned char status; /* status */
- unsigned char next; /* pointer to next packet. */
- unsigned short count; /* header + packet length in bytes */
-};
-
-/* From 8390.c */
-extern int ei_debug;
-extern struct sigaction ei_sigaction;
-
-extern int ethif_init(struct device *dev);
-extern int ethdev_init(struct device *dev);
-extern void NS8390_init(struct device *dev, int startp);
-extern int ei_open(struct device *dev);
-extern int ei_close(struct device *dev);
-extern void ei_interrupt(int irq, struct pt_regs *regs);
-
-#ifndef HAVE_AUTOIRQ
-/* From auto_irq.c */
-extern struct device *irq2dev_map[16];
-extern int autoirq_setup(int waittime);
-extern int autoirq_report(int waittime);
-#endif
-
-/* Most of these entries should be in 'struct device' (or most of the
- things in there should be here!) */
-/* You have one of these per-board */
-struct ei_device {
- const char *name;
- void (*reset_8390)(struct device *);
- void (*get_8390_hdr)(struct device *, struct e8390_pkt_hdr *, int);
- void (*block_output)(struct device *, int, const unsigned char *, int);
- void (*block_input)(struct device *, int, struct sk_buff *, int);
- unsigned open:1;
- unsigned word16:1; /* We have the 16-bit (vs 8-bit) version of the card. */
- unsigned txing:1; /* Transmit Active */
- unsigned irqlock:1; /* 8390's intrs disabled when '1'. */
- unsigned dmaing:1; /* Remote DMA Active */
- unsigned pingpong:1; /* Using the ping-pong driver */
- unsigned char tx_start_page, rx_start_page, stop_page;
- unsigned char current_page; /* Read pointer in buffer */
- unsigned char interface_num; /* Net port (AUI, 10bT.) to use. */
- unsigned char txqueue; /* Tx Packet buffer queue length. */
- short tx1, tx2; /* Packet lengths for ping-pong tx. */
- short lasttx; /* Alpha version consistency check. */
- unsigned char reg0; /* Register '0' in a WD8013 */
- unsigned char reg5; /* Register '5' in a WD8013 */
- unsigned char saved_irq; /* Original dev->irq value. */
- /* The new statistics table. */
- struct enet_statistics stat;
-};
-
-/* The maximum number of 8390 interrupt service routines called per IRQ. */
-#define MAX_SERVICE 12
-
-/* The maximum time waited (in jiffies) before assuming a Tx failed. (20ms) */
-#define TX_TIMEOUT (20*HZ/100)
-
-#define ei_status (*(struct ei_device *)(dev->priv))
-
-/* Some generic ethernet register configurations. */
-#define E8390_TX_IRQ_MASK 0xa /* For register EN0_ISR */
-#define E8390_RX_IRQ_MASK 0x5
-#define E8390_RXCONFIG 0x4 /* EN0_RXCR: broadcasts, no multicast,errors */
-#define E8390_RXOFF 0x20 /* EN0_RXCR: Accept no packets */
-#define E8390_TXCONFIG 0x00 /* EN0_TXCR: Normal transmit mode */
-#define E8390_TXOFF 0x02 /* EN0_TXCR: Transmitter off */
-
-/* Register accessed at EN_CMD, the 8390 base addr. */
-#define E8390_STOP 0x01 /* Stop and reset the chip */
-#define E8390_START 0x02 /* Start the chip, clear reset */
-#define E8390_TRANS 0x04 /* Transmit a frame */
-#define E8390_RREAD 0x08 /* Remote read */
-#define E8390_RWRITE 0x10 /* Remote write */
-#define E8390_NODMA 0x20 /* Remote DMA */
-#define E8390_PAGE0 0x00 /* Select page chip registers */
-#define E8390_PAGE1 0x40 /* using the two high-order bits */
-#define E8390_PAGE2 0x80 /* Page 3 is invalid. */
-
-#define E8390_CMD 0x00 /* The command register (for all pages) */
-/* Page 0 register offsets. */
-#define EN0_CLDALO 0x01 /* Low byte of current local dma addr RD */
-#define EN0_STARTPG 0x01 /* Starting page of ring bfr WR */
-#define EN0_CLDAHI 0x02 /* High byte of current local dma addr RD */
-#define EN0_STOPPG 0x02 /* Ending page +1 of ring bfr WR */
-#define EN0_BOUNDARY 0x03 /* Boundary page of ring bfr RD WR */
-#define EN0_TSR 0x04 /* Transmit status reg RD */
-#define EN0_TPSR 0x04 /* Transmit starting page WR */
-#define EN0_NCR 0x05 /* Number of collision reg RD */
-#define EN0_TCNTLO 0x05 /* Low byte of tx byte count WR */
-#define EN0_FIFO 0x06 /* FIFO RD */
-#define EN0_TCNTHI 0x06 /* High byte of tx byte count WR */
-#define EN0_ISR 0x07 /* Interrupt status reg RD WR */
-#define EN0_CRDALO 0x08 /* low byte of current remote dma address RD */
-#define EN0_RSARLO 0x08 /* Remote start address reg 0 */
-#define EN0_CRDAHI 0x09 /* high byte, current remote dma address RD */
-#define EN0_RSARHI 0x09 /* Remote start address reg 1 */
-#define EN0_RCNTLO 0x0a /* Remote byte count reg WR */
-#define EN0_RCNTHI 0x0b /* Remote byte count reg WR */
-#define EN0_RSR 0x0c /* rx status reg RD */
-#define EN0_RXCR 0x0c /* RX configuration reg WR */
-#define EN0_TXCR 0x0d /* TX configuration reg WR */
-#define EN0_COUNTER0 0x0d /* Rcv alignment error counter RD */
-#define EN0_DCFG 0x0e /* Data configuration reg WR */
-#define EN0_COUNTER1 0x0e /* Rcv CRC error counter RD */
-#define EN0_IMR 0x0f /* Interrupt mask reg WR */
-#define EN0_COUNTER2 0x0f /* Rcv missed frame error counter RD */
-
-/* Bits in EN0_ISR - Interrupt status register */
-#define ENISR_RX 0x01 /* Receiver, no error */
-#define ENISR_TX 0x02 /* Transmitter, no error */
-#define ENISR_RX_ERR 0x04 /* Receiver, with error */
-#define ENISR_TX_ERR 0x08 /* Transmitter, with error */
-#define ENISR_OVER 0x10 /* Receiver overwrote the ring */
-#define ENISR_COUNTERS 0x20 /* Counters need emptying */
-#define ENISR_RDC 0x40 /* remote dma complete */
-#define ENISR_RESET 0x80 /* Reset completed */
-#define ENISR_ALL 0x3f /* Interrupts we will enable */
-
-/* Bits in EN0_DCFG - Data config register */
-#define ENDCFG_WTS 0x01 /* word transfer mode selection */
-
-/* Page 1 register offsets. */
-#define EN1_PHYS 0x01 /* This board's physical enet addr RD WR */
-#define EN1_CURPAG 0x07 /* Current memory page RD WR */
-#define EN1_MULT 0x08 /* Multicast filter mask array (8 bytes) RD WR */
-
-/* Bits in received packet status byte and EN0_RSR*/
-#define ENRSR_RXOK 0x01 /* Received a good packet */
-#define ENRSR_CRC 0x02 /* CRC error */
-#define ENRSR_FAE 0x04 /* frame alignment error */
-#define ENRSR_FO 0x08 /* FIFO overrun */
-#define ENRSR_MPA 0x10 /* missed pkt */
-#define ENRSR_PHY 0x20 /* physical/multicase address */
-#define ENRSR_DIS 0x40 /* receiver disable. set in monitor mode */
-#define ENRSR_DEF 0x80 /* deferring */
-
-/* Transmitted packet status, EN0_TSR. */
-#define ENTSR_PTX 0x01 /* Packet transmitted without error */
-#define ENTSR_ND 0x02 /* The transmit wasn't deferred. */
-#define ENTSR_COL 0x04 /* The transmit collided at least once. */
-#define ENTSR_ABT 0x08 /* The transmit collided 16 times, and was deferred. */
-#define ENTSR_CRS 0x10 /* The carrier sense was lost. */
-#define ENTSR_FU 0x20 /* A "FIFO underrun" occurred during transmit. */
-#define ENTSR_CDH 0x40 /* The collision detect "heartbeat" signal was lost. */
-#define ENTSR_OWC 0x80 /* There was an out-of-window collision. */
-
-#endif /* _8390_h */
diff --git a/i386/i386at/gpl/linux/net/Space.c b/i386/i386at/gpl/linux/net/Space.c
deleted file mode 100644
index a05507d3..00000000
--- a/i386/i386at/gpl/linux/net/Space.c
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
- * INET An implementation of the TCP/IP protocol suite for the LINUX
- * operating system. INET is implemented using the BSD Socket
- * interface as the means of communication with the user level.
- *
- * Holds initial configuration information for devices.
- *
- * NOTE: This file is a nice idea, but its current format does not work
- * well for drivers that support multiple units, like the SLIP
- * driver. We should actually have only one pointer to a driver
- * here, with the driver knowing how many units it supports.
- * Currently, the SLIP driver abuses the "base_addr" integer
- * field of the 'device' structure to store the unit number...
- * -FvK
- *
- * Version: @(#)Space.c 1.0.7 08/12/93
- *
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
- * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- * Donald J. Becker, <becker@super.org>
- *
- * FIXME:
- * Sort the device chain fastest first.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#include <linux/config.h>
-#include <linux/netdevice.h>
-#include <linux/errno.h>
-
-#define NEXT_DEV NULL
-
-
-/* A unified ethernet device probe. This is the easiest way to have every
- ethernet adaptor have the name "eth[0123...]".
- */
-
-extern int hp100_probe(struct device *dev);
-extern int ultra_probe(struct device *dev);
-extern int wd_probe(struct device *dev);
-extern int el2_probe(struct device *dev);
-extern int ne_probe(struct device *dev);
-extern int hp_probe(struct device *dev);
-extern int hp_plus_probe(struct device *dev);
-extern int znet_probe(struct device *);
-extern int express_probe(struct device *);
-extern int eepro_probe(struct device *);
-extern int el3_probe(struct device *);
-extern int at1500_probe(struct device *);
-extern int at1700_probe(struct device *);
-extern int eth16i_probe(struct device *);
-extern int depca_probe(struct device *);
-extern int apricot_probe(struct device *);
-extern int ewrk3_probe(struct device *);
-extern int de4x5_probe(struct device *);
-extern int el1_probe(struct device *);
-#if defined(CONFIG_WAVELAN)
-extern int wavelan_probe(struct device *);
-#endif /* defined(CONFIG_WAVELAN) */
-extern int el16_probe(struct device *);
-extern int elplus_probe(struct device *);
-extern int ac3200_probe(struct device *);
-extern int e2100_probe(struct device *);
-extern int ni52_probe(struct device *);
-extern int ni65_probe(struct device *);
-extern int SK_init(struct device *);
-extern int seeq8005_probe(struct device *);
-extern int tc59x_probe(struct device *);
-
-/* Detachable devices ("pocket adaptors") */
-extern int atp_init(struct device *);
-extern int de600_probe(struct device *);
-extern int de620_probe(struct device *);
-
-static int
-ethif_probe(struct device *dev)
-{
- u_long base_addr = dev->base_addr;
-
- if ((base_addr == 0xffe0) || (base_addr == 1))
- return 1; /* ENXIO */
-
- if (1
-#if defined(CONFIG_VORTEX)
- && tc59x_probe(dev)
-#endif
-#if defined(CONFIG_SEEQ8005)
- && seeq8005_probe(dev)
-#endif
-#if defined(CONFIG_HP100)
- && hp100_probe(dev)
-#endif
-#if defined(CONFIG_ULTRA)
- && ultra_probe(dev)
-#endif
-#if defined(CONFIG_WD80x3) || defined(WD80x3)
-
- && wd_probe(dev)
-#endif
-#if defined(CONFIG_EL2) || defined(EL2) /* 3c503 */
- && el2_probe(dev)
-#endif
-#if defined(CONFIG_HPLAN) || defined(HPLAN)
- && hp_probe(dev)
-#endif
-#if 0
-#if defined(CONFIG_HPLAN_PLUS)
- && hp_plus_probe(dev)
-#endif
-#endif
-#ifdef CONFIG_AC3200 /* Ansel Communications EISA 3200. */
- && ac3200_probe(dev)
-#endif
-#ifdef CONFIG_E2100 /* Cabletron E21xx series. */
- && e2100_probe(dev)
-#endif
-#if defined(CONFIG_NE2000) || defined(NE2000)
- && ne_probe(dev)
-#endif
-#ifdef CONFIG_AT1500
- && at1500_probe(dev)
-#endif
-#ifdef CONFIG_AT1700
- && at1700_probe(dev)
-#endif
-#ifdef CONFIG_ETH16I
- && eth16i_probe(dev) /* ICL EtherTeam 16i/32 */
-#endif
-#ifdef CONFIG_EL3 /* 3c509 */
- && el3_probe(dev)
-#endif
-#ifdef CONFIG_ZNET /* Zenith Z-Note and some IBM Thinkpads. */
- && znet_probe(dev)
-#endif
-#ifdef CONFIG_EEXPRESS /* Intel EtherExpress */
- && express_probe(dev)
-#endif
-#ifdef CONFIG_EEXPRESS_PRO /* Intel EtherExpress Pro/10 */
- && eepro_probe(dev)
-#endif
-#ifdef CONFIG_DEPCA /* DEC DEPCA */
- && depca_probe(dev)
-#endif
-#ifdef CONFIG_EWRK3 /* DEC EtherWORKS 3 */
- && ewrk3_probe(dev)
-#endif
-#ifdef CONFIG_DE4X5 /* DEC DE425, DE434, DE435 adapters */
- && de4x5_probe(dev)
-#endif
-#ifdef CONFIG_APRICOT /* Apricot I82596 */
- && apricot_probe(dev)
-#endif
-#ifdef CONFIG_EL1 /* 3c501 */
- && el1_probe(dev)
-#endif
-#if defined(CONFIG_WAVELAN) /* WaveLAN */
- && wavelan_probe(dev)
-#endif /* defined(CONFIG_WAVELAN) */
-#ifdef CONFIG_EL16 /* 3c507 */
- && el16_probe(dev)
-#endif
-#ifdef CONFIG_ELPLUS /* 3c505 */
- && elplus_probe(dev)
-#endif
-#ifdef CONFIG_DE600 /* D-Link DE-600 adapter */
- && de600_probe(dev)
-#endif
-#ifdef CONFIG_DE620 /* D-Link DE-620 adapter */
- && de620_probe(dev)
-#endif
-#if defined(CONFIG_SK_G16)
- && SK_init(dev)
-#endif
-#ifdef CONFIG_NI52
- && ni52_probe(dev)
-#endif
-#ifdef CONFIG_NI65
- && ni65_probe(dev)
-#endif
- && 1 ) {
- return 1; /* -ENODEV or -EAGAIN would be more accurate. */
- }
- return 0;
-}
-
-
-#ifdef CONFIG_NETROM
- extern int nr_init(struct device *);
-
- static struct device nr3_dev = { "nr3", 0, 0, 0, 0, 0, 0, 0, 0, 0, NEXT_DEV, nr_init, };
- static struct device nr2_dev = { "nr2", 0, 0, 0, 0, 0, 0, 0, 0, 0, &nr3_dev, nr_init, };
- static struct device nr1_dev = { "nr1", 0, 0, 0, 0, 0, 0, 0, 0, 0, &nr2_dev, nr_init, };
- static struct device nr0_dev = { "nr0", 0, 0, 0, 0, 0, 0, 0, 0, 0, &nr1_dev, nr_init, };
-
-# undef NEXT_DEV
-# define NEXT_DEV (&nr0_dev)
-#endif
-
-/* Run-time ATtachable (Pocket) devices have a different (not "eth#") name. */
-#ifdef CONFIG_ATP /* AT-LAN-TEC (RealTek) pocket adaptor. */
-static struct device atp_dev = {
- "atp0", 0, 0, 0, 0, 0, 0, 0, 0, 0, NEXT_DEV, atp_init, /* ... */ };
-# undef NEXT_DEV
-# define NEXT_DEV (&atp_dev)
-#endif
-
-#ifdef CONFIG_ARCNET
- extern int arcnet_probe(struct device *dev);
- static struct device arcnet_dev = {
- "arc0", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NEXT_DEV, arcnet_probe, };
-# undef NEXT_DEV
-# define NEXT_DEV (&arcnet_dev)
-#endif
-
-/* In Mach, by default allow at least 2 interfaces. */
-#ifdef MACH
-#ifndef ETH1_ADDR
-# define ETH1_ADDR 0
-#endif
-#ifndef ETH1_IRQ
-# define ETH1_IRQ 0
-#endif
-#endif
-
-/* The first device defaults to I/O base '0', which means autoprobe. */
-#ifndef ETH0_ADDR
-# define ETH0_ADDR 0
-#endif
-#ifndef ETH0_IRQ
-# define ETH0_IRQ 0
-#endif
-/* "eth0" defaults to autoprobe (== 0), other use a base of 0xffe0 (== -0x20),
- which means "don't probe". These entries exist to only to provide empty
- slots which may be enabled at boot-time. */
-
-static struct device eth3_dev = {
- "eth3", 0,0,0,0,0xffe0 /* I/O base*/, 0,0,0,0, NEXT_DEV, ethif_probe };
-static struct device eth2_dev = {
- "eth2", 0,0,0,0,0xffe0 /* I/O base*/, 0,0,0,0, &eth3_dev, ethif_probe };
-#ifdef MACH
-static struct device eth1_dev = {
- "eth1", 0,0,0,0,ETH1_ADDR, ETH1_IRQ,0,0,0, &eth2_dev, ethif_probe };
-#else
-static struct device eth1_dev = {
- "eth1", 0,0,0,0,0xffe0 /* I/O base*/, 0,0,0,0, &eth2_dev, ethif_probe };
-#endif
-static struct device eth0_dev = {
- "eth0", 0, 0, 0, 0, ETH0_ADDR, ETH0_IRQ, 0, 0, 0, &eth1_dev, ethif_probe };
-
-# undef NEXT_DEV
-# define NEXT_DEV (&eth0_dev)
-
-#if defined(PLIP) || defined(CONFIG_PLIP)
- extern int plip_init(struct device *);
- static struct device plip2_dev = {
- "plip2", 0, 0, 0, 0, 0x278, 2, 0, 0, 0, NEXT_DEV, plip_init, };
- static struct device plip1_dev = {
- "plip1", 0, 0, 0, 0, 0x378, 7, 0, 0, 0, &plip2_dev, plip_init, };
- static struct device plip0_dev = {
- "plip0", 0, 0, 0, 0, 0x3BC, 5, 0, 0, 0, &plip1_dev, plip_init, };
-# undef NEXT_DEV
-# define NEXT_DEV (&plip0_dev)
-#endif /* PLIP */
-
-#if defined(SLIP) || defined(CONFIG_SLIP)
- /* To be exact, this node just hooks the initialization
- routines to the device structures. */
-extern int slip_init_ctrl_dev(struct device *);
-static struct device slip_bootstrap = {
- "slip_proto", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NEXT_DEV, slip_init_ctrl_dev, };
-#undef NEXT_DEV
-#define NEXT_DEV (&slip_bootstrap)
-#endif /* SLIP */
-
-#if defined(CONFIG_PPP)
-extern int ppp_init(struct device *);
-static struct device ppp_bootstrap = {
- "ppp_proto", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NEXT_DEV, ppp_init, };
-#undef NEXT_DEV
-#define NEXT_DEV (&ppp_bootstrap)
-#endif /* PPP */
-
-#ifdef CONFIG_DUMMY
- extern int dummy_init(struct device *dev);
- static struct device dummy_dev = {
- "dummy", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NEXT_DEV, dummy_init, };
-# undef NEXT_DEV
-# define NEXT_DEV (&dummy_dev)
-#endif
-
-#ifdef CONFIG_EQUALIZER
-extern int eql_init(struct device *dev);
-struct device eql_dev = {
- "eql", /* Master device for IP traffic load
- balancing */
- 0x0, 0x0, 0x0, 0x0, /* recv end/start; mem end/start */
- 0, /* base I/O address */
- 0, /* IRQ */
- 0, 0, 0, /* flags */
- NEXT_DEV, /* next device */
- eql_init /* set up the rest */
-};
-# undef NEXT_DEV
-# define NEXT_DEV (&eql_dev)
-#endif
-
-#ifdef CONFIG_IBMTR
-
- extern int tok_probe(struct device *dev);
- static struct device ibmtr_dev1 = {
- "tr1", /* IBM Token Ring (Non-DMA) Interface */
- 0x0, /* recv memory end */
- 0x0, /* recv memory start */
- 0x0, /* memory end */
- 0x0, /* memory start */
- 0xa24, /* base I/O address */
- 0, /* IRQ */
- 0, 0, 0, /* flags */
- NEXT_DEV, /* next device */
- tok_probe /* ??? Token_init should set up the rest */
- };
-# undef NEXT_DEV
-# define NEXT_DEV (&ibmtr_dev1)
-
-
- static struct device ibmtr_dev0 = {
- "tr0", /* IBM Token Ring (Non-DMA) Interface */
- 0x0, /* recv memory end */
- 0x0, /* recv memory start */
- 0x0, /* memory end */
- 0x0, /* memory start */
- 0xa20, /* base I/O address */
- 0, /* IRQ */
- 0, 0, 0, /* flags */
- NEXT_DEV, /* next device */
- tok_probe /* ??? Token_init should set up the rest */
- };
-# undef NEXT_DEV
-# define NEXT_DEV (&ibmtr_dev0)
-
-#endif
-#ifdef CONFIG_NET_IPIP
-#ifdef CONFIG_IP_FORWARD
- extern int tunnel_init(struct device *);
-
- static struct device tunnel_dev1 =
- {
- "tunl1", /* IPIP tunnel */
- 0x0, /* recv memory end */
- 0x0, /* recv memory start */
- 0x0, /* memory end */
- 0x0, /* memory start */
- 0x0, /* base I/O address */
- 0, /* IRQ */
- 0, 0, 0, /* flags */
- NEXT_DEV, /* next device */
- tunnel_init /* Fill in the details */
- };
-
- static struct device tunnel_dev0 =
- {
- "tunl0", /* IPIP tunnel */
- 0x0, /* recv memory end */
- 0x0, /* recv memory start */
- 0x0, /* memory end */
- 0x0, /* memory start */
- 0x0, /* base I/O address */
- 0, /* IRQ */
- 0, 0, 0, /* flags */
- &tunnel_dev1, /* next device */
- tunnel_init /* Fill in the details */
- };
-# undef NEXT_DEV
-# define NEXT_DEV (&tunnel_dev0)
-
-#endif
-#endif
-
-#ifdef MACH
-struct device *dev_base = &eth0_dev;
-#else
-extern int loopback_init(struct device *dev);
-struct device loopback_dev = {
- "lo", /* Software Loopback interface */
- 0x0, /* recv memory end */
- 0x0, /* recv memory start */
- 0x0, /* memory end */
- 0x0, /* memory start */
- 0, /* base I/O address */
- 0, /* IRQ */
- 0, 0, 0, /* flags */
- NEXT_DEV, /* next device */
- loopback_init /* loopback_init should set up the rest */
-};
-
-struct device *dev_base = &loopback_dev;
-#endif
diff --git a/i386/i386at/gpl/linux/net/ac3200.c b/i386/i386at/gpl/linux/net/ac3200.c
deleted file mode 100644
index 054af13a..00000000
--- a/i386/i386at/gpl/linux/net/ac3200.c
+++ /dev/null
@@ -1,385 +0,0 @@
-/* ac3200.c: A driver for the Ansel Communications EISA ethernet adaptor. */
-/*
- Written 1993, 1994 by Donald Becker.
- Copyright 1993 United States Government as represented by the Director,
- National Security Agency. This software may only be used and distributed
- according to the terms of the GNU Public License as modified by SRC,
- incorporated herein by reference.
-
- The author may be reached as becker@cesdis.gsfc.nasa.gov, or
- C/O Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
-
- This is driver for the Ansel Communications Model 3200 EISA Ethernet LAN
- Adapter. The programming information is from the users manual, as related
- by glee@ardnassak.math.clemson.edu.
- */
-
-static const char *version =
- "ac3200.c:v1.01 7/1/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-
-#include "8390.h"
-
-/* Offsets from the base address. */
-#define AC_NIC_BASE 0x00
-#define AC_SA_PROM 0x16 /* The station address PROM. */
-#define AC_ADDR0 0x00 /* Prefix station address values. */
-#define AC_ADDR1 0x40 /* !!!!These are just guesses!!!! */
-#define AC_ADDR2 0x90
-#define AC_ID_PORT 0xC80
-#define AC_EISA_ID 0x0110d305
-#define AC_RESET_PORT 0xC84
-#define AC_RESET 0x00
-#define AC_ENABLE 0x01
-#define AC_CONFIG 0xC90 /* The configuration port. */
-
-#define AC_IO_EXTENT 0x10 /* IS THIS REALLY TRUE ??? */
- /* Actually accessed is:
- * AC_NIC_BASE (0-15)
- * AC_SA_PROM (0-5)
- * AC_ID_PORT (0-3)
- * AC_RESET_PORT
- * AC_CONFIG
- */
-
-/* Decoding of the configuration register. */
-static unsigned char config2irqmap[8] = {15, 12, 11, 10, 9, 7, 5, 3};
-static int addrmap[8] =
-{0xFF0000, 0xFE0000, 0xFD0000, 0xFFF0000, 0xFFE0000, 0xFFC0000, 0xD0000, 0 };
-static const char *port_name[4] = { "10baseT", "invalid", "AUI", "10base2"};
-
-#define config2irq(configval) config2irqmap[((configval) >> 3) & 7]
-#define config2mem(configval) addrmap[(configval) & 7]
-#define config2name(configval) port_name[((configval) >> 6) & 3]
-
-/* First and last 8390 pages. */
-#define AC_START_PG 0x00 /* First page of 8390 TX buffer */
-#define AC_STOP_PG 0x80 /* Last page +1 of the 8390 RX ring */
-
-int ac3200_probe(struct device *dev);
-static int ac_probe1(int ioaddr, struct device *dev);
-
-static int ac_open(struct device *dev);
-static void ac_reset_8390(struct device *dev);
-static void ac_block_input(struct device *dev, int count,
- struct sk_buff *skb, int ring_offset);
-static void ac_block_output(struct device *dev, const int count,
- const unsigned char *buf, const int start_page);
-static void ac_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr,
- int ring_page);
-
-static int ac_close_card(struct device *dev);
-
-
-/* Probe for the AC3200.
-
- The AC3200 can be identified by either the EISA configuration registers,
- or the unique value in the station address PROM.
- */
-
-int ac3200_probe(struct device *dev)
-{
- unsigned short ioaddr = dev->base_addr;
-
- if (ioaddr > 0x1ff) /* Check a single specified location. */
- return ac_probe1(ioaddr, dev);
- else if (ioaddr > 0) /* Don't probe at all. */
- return ENXIO;
-
- /* If you have a pre 0.99pl15 machine you should delete this line. */
- if ( ! EISA_bus)
- return ENXIO;
-
- for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) {
- if (check_region(ioaddr, AC_IO_EXTENT))
- continue;
- if (ac_probe1(ioaddr, dev) == 0)
- return 0;
- }
-
- return ENODEV;
-}
-
-static int ac_probe1(int ioaddr, struct device *dev)
-{
- int i;
-
-#ifndef final_version
- printk("AC3200 ethercard probe at %#3x:", ioaddr);
-
- for(i = 0; i < 6; i++)
- printk(" %02x", inb(ioaddr + AC_SA_PROM + i));
-#endif
-
- /* !!!!The values of AC_ADDRn (see above) should be corrected when we
- find out the correct station address prefix!!!! */
- if (inb(ioaddr + AC_SA_PROM + 0) != AC_ADDR0
- || inb(ioaddr + AC_SA_PROM + 1) != AC_ADDR1
- || inb(ioaddr + AC_SA_PROM + 2) != AC_ADDR2 ) {
-#ifndef final_version
- printk(" not found (invalid prefix).\n");
-#endif
- return ENODEV;
- }
-
- /* The correct probe method is to check the EISA ID. */
- for (i = 0; i < 4; i++)
- if (inl(ioaddr + AC_ID_PORT) != AC_EISA_ID) {
- printk("EISA ID mismatch, %8x vs %8x.\n",
- inl(ioaddr + AC_EISA_ID), AC_EISA_ID);
- return ENODEV;
- }
-
-
- /* We should have a "dev" from Space.c or the static module table. */
- if (dev == NULL) {
- printk("ac3200.c: Passed a NULL device.\n");
- dev = init_etherdev(0, 0);
- }
-
- for(i = 0; i < ETHER_ADDR_LEN; i++)
- dev->dev_addr[i] = inb(ioaddr + AC_SA_PROM + i);
-
-#ifndef final_version
- printk("\nAC3200 ethercard configuration register is %#02x,"
- " EISA ID %02x %02x %02x %02x.\n", inb(ioaddr + AC_CONFIG),
- inb(ioaddr + AC_ID_PORT + 0), inb(ioaddr + AC_ID_PORT + 1),
- inb(ioaddr + AC_ID_PORT + 2), inb(ioaddr + AC_ID_PORT + 3));
-#endif
-
- /* Assign and allocate the interrupt now. */
- if (dev->irq == 0)
- dev->irq = config2irq(inb(ioaddr + AC_CONFIG));
- else if (dev->irq == 2)
- dev->irq = 9;
-
- if (request_irq(dev->irq, ei_interrupt, 0, "ac3200")) {
- printk (" unable to get IRQ %d.\n", dev->irq);
- return EAGAIN;
- }
-
- /* Allocate dev->priv and fill in 8390 specific dev fields. */
- if (ethdev_init(dev)) {
- printk (" unable to allocate memory for dev->priv.\n");
- free_irq(dev->irq);
- return -ENOMEM;
- }
-
- request_region(ioaddr, AC_IO_EXTENT, "ac3200");
-
- dev->base_addr = ioaddr;
-
-#ifdef notyet
- if (dev->mem_start) { /* Override the value from the board. */
- for (i = 0; i < 7; i++)
- if (addrmap[i] == dev->mem_start)
- break;
- if (i >= 7)
- i = 0;
- outb((inb(ioaddr + AC_CONFIG) & ~7) | i, ioaddr + AC_CONFIG);
- }
-#endif
-
- dev->if_port = inb(ioaddr + AC_CONFIG) >> 6;
- dev->mem_start = config2mem(inb(ioaddr + AC_CONFIG));
- dev->rmem_start = dev->mem_start + TX_PAGES*256;
- dev->mem_end = dev->rmem_end = dev->mem_start
- + (AC_STOP_PG - AC_START_PG)*256;
-
- ei_status.name = "AC3200";
- ei_status.tx_start_page = AC_START_PG;
- ei_status.rx_start_page = AC_START_PG + TX_PAGES;
- ei_status.stop_page = AC_STOP_PG;
- ei_status.word16 = 1;
-
- printk("\n%s: AC3200 at %#x, IRQ %d, %s port, shared memory %#lx-%#lx.\n",
- dev->name, ioaddr, dev->irq, port_name[dev->if_port],
- dev->mem_start, dev->mem_end-1);
-
- if (ei_debug > 0)
- printk(version);
-
- ei_status.reset_8390 = &ac_reset_8390;
- ei_status.block_input = &ac_block_input;
- ei_status.block_output = &ac_block_output;
- ei_status.get_8390_hdr = &ac_get_8390_hdr;
-
- dev->open = &ac_open;
- dev->stop = &ac_close_card;
- NS8390_init(dev, 0);
- return 0;
-}
-
-static int ac_open(struct device *dev)
-{
-#ifdef notyet
- /* Someday we may enable the IRQ and shared memory here. */
- int ioaddr = dev->base_addr;
-
- if (request_irq(dev->irq, ei_interrupt, 0, "ac3200"))
- return -EAGAIN;
-#endif
-
- ei_open(dev);
-
- MOD_INC_USE_COUNT;
-
- return 0;
-}
-
-static void ac_reset_8390(struct device *dev)
-{
- ushort ioaddr = dev->base_addr;
-
- outb(AC_RESET, ioaddr + AC_RESET_PORT);
- if (ei_debug > 1) printk("resetting AC3200, t=%ld...", jiffies);
-
- ei_status.txing = 0;
- outb(AC_ENABLE, ioaddr + AC_RESET_PORT);
- if (ei_debug > 1) printk("reset done\n");
-
- return;
-}
-
-/* Grab the 8390 specific header. Similar to the block_input routine, but
- we don't need to be concerned with ring wrap as the header will be at
- the start of a page, so we optimize accordingly. */
-
-static void
-ac_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
-{
- unsigned long hdr_start = dev->mem_start + ((ring_page - AC_START_PG)<<8);
- memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
-}
-
-/* Block input and output are easy on shared memory ethercards, the only
- complication is when the ring buffer wraps. */
-
-static void ac_block_input(struct device *dev, int count, struct sk_buff *skb,
- int ring_offset)
-{
- unsigned long xfer_start = dev->mem_start + ring_offset - (AC_START_PG<<8);
-
- if (xfer_start + count > dev->rmem_end) {
- /* We must wrap the input move. */
- int semi_count = dev->rmem_end - xfer_start;
- memcpy_fromio(skb->data, xfer_start, semi_count);
- count -= semi_count;
- memcpy_fromio(skb->data + semi_count, dev->rmem_start, count);
- } else {
- /* Packet is in one chunk -- we can copy + cksum. */
- eth_io_copy_and_sum(skb, xfer_start, count, 0);
- }
-}
-
-static void ac_block_output(struct device *dev, int count,
- const unsigned char *buf, int start_page)
-{
- unsigned long shmem = dev->mem_start + ((start_page - AC_START_PG)<<8);
-
- memcpy_toio(shmem, buf, count);
-}
-
-static int ac_close_card(struct device *dev)
-{
- dev->start = 0;
- dev->tbusy = 1;
-
- if (ei_debug > 1)
- printk("%s: Shutting down ethercard.\n", dev->name);
-
-#ifdef notyet
- /* We should someday disable shared memory and interrupts. */
- outb(0x00, ioaddr + 6); /* Disable interrupts. */
- free_irq(dev->irq);
- irq2dev_map[dev->irq] = 0;
-#endif
-
- ei_close(dev);
-
- MOD_DEC_USE_COUNT;
-
- return 0;
-}
-
-#ifdef MODULE
-#define MAX_AC32_CARDS 4 /* Max number of AC32 cards per module */
-#define NAMELEN 8 /* # of chars for storing dev->name */
-static char namelist[NAMELEN * MAX_AC32_CARDS] = { 0, };
-static struct device dev_ac32[MAX_AC32_CARDS] = {
- {
- NULL, /* assign a chunk of namelist[] below */
- 0, 0, 0, 0,
- 0, 0,
- 0, 0, 0, NULL, NULL
- },
-};
-
-static int io[MAX_AC32_CARDS] = { 0, };
-static int irq[MAX_AC32_CARDS] = { 0, };
-static int mem[MAX_AC32_CARDS] = { 0, };
-
-int
-init_module(void)
-{
- int this_dev, found = 0;
-
- for (this_dev = 0; this_dev < MAX_AC32_CARDS; this_dev++) {
- struct device *dev = &dev_ac32[this_dev];
- dev->name = namelist+(NAMELEN*this_dev);
- dev->irq = irq[this_dev];
- dev->base_addr = io[this_dev];
- dev->mem_start = mem[this_dev]; /* Currently ignored by driver */
- dev->init = ac3200_probe;
- /* Default is to only install one card. */
- if (io[this_dev] == 0 && this_dev != 0) break;
- if (register_netdev(dev) != 0) {
- printk(KERN_WARNING "ac3200.c: No ac3200 card found (i/o = 0x%x).\n", io[this_dev]);
- if (found != 0) return 0; /* Got at least one. */
- return -ENXIO;
- }
- found++;
- }
-
- return 0;
-}
-
-void
-cleanup_module(void)
-{
- int this_dev;
-
- for (this_dev = 0; this_dev < MAX_AC32_CARDS; this_dev++) {
- struct device *dev = &dev_ac32[this_dev];
- if (dev->priv != NULL) {
- kfree(dev->priv);
- dev->priv = NULL;
- /* Someday free_irq + irq2dev may be in ac_close_card() */
- free_irq(dev->irq);
- irq2dev_map[dev->irq] = NULL;
- release_region(dev->base_addr, AC_IO_EXTENT);
- unregister_netdev(dev);
- }
- }
-}
-#endif /* MODULE */
-
-/*
- * Local variables:
- * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c ac3200.c"
- * version-control: t
- * kept-new-versions: 5
- * tab-width: 4
- * End:
- */
diff --git a/i386/i386at/gpl/linux/net/apricot.c b/i386/i386at/gpl/linux/net/apricot.c
deleted file mode 100644
index 130d7759..00000000
--- a/i386/i386at/gpl/linux/net/apricot.c
+++ /dev/null
@@ -1,1046 +0,0 @@
-/* apricot.c: An Apricot 82596 ethernet driver for linux. */
-/*
- Apricot
- Written 1994 by Mark Evans.
- This driver is for the Apricot 82596 bus-master interface
-
- Modularised 12/94 Mark Evans
-
- Driver skeleton
- Written 1993 by Donald Becker.
- Copyright 1993 United States Government as represented by the Director,
- National Security Agency. This software may only be used and distributed
- according to the terms of the GNU Public License as modified by SRC,
- incorporated herein by reference.
-
- The author may be reached as becker@super.org or
- C/O Supercomputing Research Ctr., 17100 Science Dr., Bowie MD 20715
-
-
-*/
-
-static const char *version = "apricot.c:v0.2 05/12/94\n";
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/ptrace.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/malloc.h>
-#include <linux/interrupt.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-
-#include <asm/bitops.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-
-#ifndef HAVE_PORTRESERVE
-#define check_region(addr, size) 0
-#define request_region(addr, size,name) do ; while(0)
-#endif
-
-#ifndef HAVE_ALLOC_SKB
-#define alloc_skb(size, priority) (struct sk_buff *) kmalloc(size,priority)
-#define kfree_skbmem(buff, size) kfree_s(buff,size)
-#endif
-
-#define APRICOT_DEBUG 1
-
-#ifdef APRICOT_DEBUG
-int i596_debug = APRICOT_DEBUG;
-#else
-int i596_debug = 1;
-#endif
-
-#define APRICOT_TOTAL_SIZE 17
-
-#define I596_NULL -1
-
-#define CMD_EOL 0x8000 /* The last command of the list, stop. */
-#define CMD_SUSP 0x4000 /* Suspend after doing cmd. */
-#define CMD_INTR 0x2000 /* Interrupt after doing cmd. */
-
-#define CMD_FLEX 0x0008 /* Enable flexible memory model */
-
-enum commands {
- CmdNOp = 0, CmdSASetup = 1, CmdConfigure = 2, CmdMulticastList = 3,
- CmdTx = 4, CmdTDR = 5, CmdDump = 6, CmdDiagnose = 7};
-
-#define STAT_C 0x8000 /* Set to 0 after execution */
-#define STAT_B 0x4000 /* Command being executed */
-#define STAT_OK 0x2000 /* Command executed ok */
-#define STAT_A 0x1000 /* Command aborted */
-
-#define CUC_START 0x0100
-#define CUC_RESUME 0x0200
-#define CUC_SUSPEND 0x0300
-#define CUC_ABORT 0x0400
-#define RX_START 0x0010
-#define RX_RESUME 0x0020
-#define RX_SUSPEND 0x0030
-#define RX_ABORT 0x0040
-
-struct i596_cmd {
- unsigned short status;
- unsigned short command;
- struct i596_cmd *next;
-};
-
-#define EOF 0x8000
-#define SIZE_MASK 0x3fff
-
-struct i596_tbd {
- unsigned short size;
- unsigned short pad;
- struct i596_tbd *next;
- char *data;
-};
-
-struct tx_cmd {
- struct i596_cmd cmd;
- struct i596_tbd *tbd;
- unsigned short size;
- unsigned short pad;
-};
-
-struct i596_rfd {
- unsigned short stat;
- unsigned short cmd;
- struct i596_rfd *next;
- long rbd;
- unsigned short count;
- unsigned short size;
- char data[1532];
-};
-
-#define RX_RING_SIZE 8
-
-struct i596_scb {
- unsigned short status;
- unsigned short command;
- struct i596_cmd *cmd;
- struct i596_rfd *rfd;
- unsigned long crc_err;
- unsigned long align_err;
- unsigned long resource_err;
- unsigned long over_err;
- unsigned long rcvdt_err;
- unsigned long short_err;
- unsigned short t_on;
- unsigned short t_off;
-};
-
-struct i596_iscp {
- unsigned long stat;
- struct i596_scb *scb;
-};
-
-struct i596_scp {
- unsigned long sysbus;
- unsigned long pad;
- struct i596_iscp *iscp;
-};
-
-struct i596_private {
- struct i596_scp scp;
- struct i596_iscp iscp;
- struct i596_scb scb;
- struct i596_cmd set_add;
- char eth_addr[8];
- struct i596_cmd set_conf;
- char i596_config[16];
- struct i596_cmd tdr;
- unsigned long stat;
- int last_restart;
- struct i596_rfd *rx_tail;
- struct i596_cmd *cmd_tail;
- struct i596_cmd *cmd_head;
- int cmd_backlog;
- unsigned long last_cmd;
- struct enet_statistics stats;
-};
-
-char init_setup[] = {
- 0x8E, /* length, prefetch on */
- 0xC8, /* fifo to 8, monitor off */
- 0x80, /* don't save bad frames */
- 0x2E, /* No source address insertion, 8 byte preamble */
- 0x00, /* priority and backoff defaults */
- 0x60, /* interframe spacing */
- 0x00, /* slot time LSB */
- 0xf2, /* slot time and retries */
- 0x00, /* promiscuous mode */
- 0x00, /* collision detect */
- 0x40, /* minimum frame length */
- 0xff,
- 0x00,
- 0x7f /* *multi IA */ };
-
-static int i596_open(struct device *dev);
-static int i596_start_xmit(struct sk_buff *skb, struct device *dev);
-static void i596_interrupt(int irq, struct pt_regs *regs);
-static int i596_close(struct device *dev);
-static struct enet_statistics *i596_get_stats(struct device *dev);
-static void i596_add_cmd(struct device *dev, struct i596_cmd *cmd);
-static void print_eth(char *);
-static void set_multicast_list(struct device *dev);
-
-
-static inline int
-init_rx_bufs(struct device *dev, int num)
-{
- struct i596_private *lp = (struct i596_private *)dev->priv;
- int i;
- struct i596_rfd *rfd;
-
- lp->scb.rfd = (struct i596_rfd *)I596_NULL;
-
- if (i596_debug > 1) printk ("%s: init_rx_bufs %d.\n", dev->name, num);
-
- for (i = 0; i < num; i++)
- {
- if (!(rfd = (struct i596_rfd *)kmalloc(sizeof(struct i596_rfd), GFP_KERNEL)))
- break;
-
- rfd->stat = 0x0000;
- rfd->rbd = I596_NULL;
- rfd->count = 0;
- rfd->size = 1532;
- if (i == 0)
- {
- rfd->cmd = CMD_EOL;
- lp->rx_tail = rfd;
- }
- else
- rfd->cmd = 0x0000;
-
- rfd->next = lp->scb.rfd;
- lp->scb.rfd = rfd;
- }
-
- if (i != 0)
- lp->rx_tail->next = lp->scb.rfd;
-
- return (i);
-}
-
-static inline void
-remove_rx_bufs(struct device *dev)
-{
- struct i596_private *lp = (struct i596_private *)dev->priv;
- struct i596_rfd *rfd = lp->scb.rfd;
-
- lp->rx_tail->next = (struct i596_rfd *)I596_NULL;
-
- do
- {
- lp->scb.rfd = rfd->next;
- kfree_s(rfd, sizeof(struct i596_rfd));
- rfd = lp->scb.rfd;
- }
- while (rfd != lp->rx_tail);
-}
-
-static inline void
-init_i596_mem(struct device *dev)
-{
- struct i596_private *lp = (struct i596_private *)dev->priv;
- short ioaddr = dev->base_addr;
- int boguscnt = 100;
-
- /* change the scp address */
- outw(0, ioaddr);
- outw(0, ioaddr);
- outb(4, ioaddr+0xf);
- outw(((((int)&lp->scp) & 0xffff) | 2), ioaddr);
- outw((((int)&lp->scp)>>16) & 0xffff, ioaddr);
-
- lp->last_cmd = jiffies;
-
- lp->scp.sysbus = 0x00440000;
- lp->scp.iscp = &(lp->iscp);
- lp->iscp.scb = &(lp->scb);
- lp->iscp.stat = 0x0001;
- lp->cmd_backlog = 0;
-
- lp->cmd_head = lp->scb.cmd = (struct i596_cmd *) I596_NULL;
-
- if (i596_debug > 2) printk("%s: starting i82596.\n", dev->name);
-
- (void) inb (ioaddr+0x10);
- outb(4, ioaddr+0xf);
- outw(0, ioaddr+4);
-
- while (lp->iscp.stat)
- if (--boguscnt == 0)
- {
- printk("%s: i82596 initialization timed out with status %4.4x, cmd %4.4x.\n",
- dev->name, lp->scb.status, lp->scb.command);
- break;
- }
-
- lp->scb.command = 0;
-
- memcpy (lp->i596_config, init_setup, 14);
- lp->set_conf.command = CmdConfigure;
- i596_add_cmd(dev, &lp->set_conf);
-
- memcpy (lp->eth_addr, dev->dev_addr, 6);
- lp->set_add.command = CmdSASetup;
- i596_add_cmd(dev, &lp->set_add);
-
- lp->tdr.command = CmdTDR;
- i596_add_cmd(dev, &lp->tdr);
-
- boguscnt = 200;
- while (lp->scb.status, lp->scb.command)
- if (--boguscnt == 0)
- {
- printk("%s: receive unit start timed out with status %4.4x, cmd %4.4x.\n",
- dev->name, lp->scb.status, lp->scb.command);
- break;
- }
-
- lp->scb.command = RX_START;
- outw(0, ioaddr+4);
-
- boguscnt = 200;
- while (lp->scb.status, lp->scb.command)
- if (--boguscnt == 0)
- {
- printk("i82596 init timed out with status %4.4x, cmd %4.4x.\n",
- lp->scb.status, lp->scb.command);
- break;
- }
-
- return;
-}
-
-static inline int
-i596_rx(struct device *dev)
-{
- struct i596_private *lp = (struct i596_private *)dev->priv;
- int frames = 0;
-
- if (i596_debug > 3) printk ("i596_rx()\n");
-
- while ((lp->scb.rfd->stat) & STAT_C)
- {
- if (i596_debug >2) print_eth(lp->scb.rfd->data);
-
- if ((lp->scb.rfd->stat) & STAT_OK)
- {
- /* a good frame */
- int pkt_len = lp->scb.rfd->count & 0x3fff;
- struct sk_buff *skb = dev_alloc_skb(pkt_len);
-
- frames++;
-
- if (skb == NULL)
- {
- printk ("%s: i596_rx Memory squeeze, dropping packet.\n", dev->name);
- lp->stats.rx_dropped++;
- break;
- }
-
- skb->dev = dev;
- memcpy(skb_put(skb,pkt_len), lp->scb.rfd->data, pkt_len);
-
- skb->protocol=eth_type_trans(skb,dev);
- netif_rx(skb);
- lp->stats.rx_packets++;
-
- if (i596_debug > 4) print_eth(skb->data);
- }
- else
- {
- lp->stats.rx_errors++;
- if ((lp->scb.rfd->stat) & 0x0001) lp->stats.collisions++;
- if ((lp->scb.rfd->stat) & 0x0080) lp->stats.rx_length_errors++;
- if ((lp->scb.rfd->stat) & 0x0100) lp->stats.rx_over_errors++;
- if ((lp->scb.rfd->stat) & 0x0200) lp->stats.rx_fifo_errors++;
- if ((lp->scb.rfd->stat) & 0x0400) lp->stats.rx_frame_errors++;
- if ((lp->scb.rfd->stat) & 0x0800) lp->stats.rx_crc_errors++;
- if ((lp->scb.rfd->stat) & 0x1000) lp->stats.rx_length_errors++;
- }
-
- lp->scb.rfd->stat = 0;
- lp->rx_tail->cmd = 0;
- lp->rx_tail = lp->scb.rfd;
- lp->scb.rfd = lp->scb.rfd->next;
- lp->rx_tail->count = 0;
- lp->rx_tail->cmd = CMD_EOL;
-
- }
-
- if (i596_debug > 3) printk ("frames %d\n", frames);
-
- return 0;
-}
-
-static inline void
-i596_cleanup_cmd(struct i596_private *lp)
-{
- struct i596_cmd *ptr;
- int boguscnt = 100;
-
- if (i596_debug > 4) printk ("i596_cleanup_cmd\n");
-
- while (lp->cmd_head != (struct i596_cmd *) I596_NULL)
- {
- ptr = lp->cmd_head;
-
- lp->cmd_head = lp->cmd_head->next;
- lp->cmd_backlog--;
-
- switch ((ptr->command) & 0x7)
- {
- case CmdTx:
- {
- struct tx_cmd *tx_cmd = (struct tx_cmd *) ptr;
- struct sk_buff *skb = ((struct sk_buff *)(tx_cmd->tbd->data)) -1;
-
- dev_kfree_skb(skb, FREE_WRITE);
-
- lp->stats.tx_errors++;
- lp->stats.tx_aborted_errors++;
-
- ptr->next = (struct i596_cmd * ) I596_NULL;
- kfree_s((unsigned char *)tx_cmd, (sizeof (struct tx_cmd) + sizeof (struct i596_tbd)));
- break;
- }
- case CmdMulticastList:
- {
- unsigned short count = *((unsigned short *) (ptr + 1));
-
- ptr->next = (struct i596_cmd * ) I596_NULL;
- kfree_s((unsigned char *)ptr, (sizeof (struct i596_cmd) + count + 2));
- break;
- }
- default:
- ptr->next = (struct i596_cmd * ) I596_NULL;
- }
- }
-
- while (lp->scb.status, lp->scb.command)
- if (--boguscnt == 0)
- {
- printk("i596_cleanup_cmd timed out with status %4.4x, cmd %4.4x.\n",
- lp->scb.status, lp->scb.command);
- break;
- }
-
- lp->scb.cmd = lp->cmd_head;
-}
-
-static inline void
-i596_reset(struct device *dev, struct i596_private *lp, int ioaddr)
-{
- int boguscnt = 100;
-
- if (i596_debug > 4) printk ("i596_reset\n");
-
- while (lp->scb.status, lp->scb.command)
- if (--boguscnt == 0)
- {
- printk("i596_reset timed out with status %4.4x, cmd %4.4x.\n",
- lp->scb.status, lp->scb.command);
- break;
- }
-
- dev->start = 0;
- dev->tbusy = 1;
-
- lp->scb.command = CUC_ABORT|RX_ABORT;
- outw(0, ioaddr+4);
-
- /* wait for shutdown */
- boguscnt = 400;
-
- while ((lp->scb.status, lp->scb.command) || lp->scb.command)
- if (--boguscnt == 0)
- {
- printk("i596_reset 2 timed out with status %4.4x, cmd %4.4x.\n",
- lp->scb.status, lp->scb.command);
- break;
- }
-
- i596_cleanup_cmd(lp);
- i596_rx(dev);
-
- dev->start = 1;
- dev->tbusy = 0;
- dev->interrupt = 0;
- init_i596_mem(dev);
-}
-
-static void i596_add_cmd(struct device *dev, struct i596_cmd *cmd)
-{
- struct i596_private *lp = (struct i596_private *)dev->priv;
- int ioaddr = dev->base_addr;
- unsigned long flags;
- int boguscnt = 100;
-
- if (i596_debug > 4) printk ("i596_add_cmd\n");
-
- cmd->status = 0;
- cmd->command |= (CMD_EOL|CMD_INTR);
- cmd->next = (struct i596_cmd *) I596_NULL;
-
- save_flags(flags);
- cli();
- if (lp->cmd_head != (struct i596_cmd *) I596_NULL)
- lp->cmd_tail->next = cmd;
- else
- {
- lp->cmd_head = cmd;
- while (lp->scb.status, lp->scb.command)
- if (--boguscnt == 0)
- {
- printk("i596_add_cmd timed out with status %4.4x, cmd %4.4x.\n",
- lp->scb.status, lp->scb.command);
- break;
- }
-
- lp->scb.cmd = cmd;
- lp->scb.command = CUC_START;
- outw (0, ioaddr+4);
- }
- lp->cmd_tail = cmd;
- lp->cmd_backlog++;
-
- lp->cmd_head = lp->scb.cmd;
- restore_flags(flags);
-
- if (lp->cmd_backlog > 16)
- {
- int tickssofar = jiffies - lp->last_cmd;
-
- if (tickssofar < 25) return;
-
- printk("%s: command unit timed out, status resetting.\n", dev->name);
-
- i596_reset(dev, lp, ioaddr);
- }
-}
-
-static int
-i596_open(struct device *dev)
-{
- int i;
-
- if (i596_debug > 1)
- printk("%s: i596_open() irq %d.\n", dev->name, dev->irq);
-
- if (request_irq(dev->irq, &i596_interrupt, 0, "apricot"))
- return -EAGAIN;
-
- irq2dev_map[dev->irq] = dev;
-
- i = init_rx_bufs(dev, RX_RING_SIZE);
-
- if ((i = init_rx_bufs(dev, RX_RING_SIZE)) < RX_RING_SIZE)
- printk("%s: only able to allocate %d receive buffers\n", dev->name, i);
-
- if (i < 4)
- {
- free_irq(dev->irq);
- irq2dev_map[dev->irq] = 0;
- return -EAGAIN;
- }
-
- dev->tbusy = 0;
- dev->interrupt = 0;
- dev->start = 1;
- MOD_INC_USE_COUNT;
-
- /* Initialize the 82596 memory */
- init_i596_mem(dev);
-
- return 0; /* Always succeed */
-}
-
-static int
-i596_start_xmit(struct sk_buff *skb, struct device *dev)
-{
- struct i596_private *lp = (struct i596_private *)dev->priv;
- int ioaddr = dev->base_addr;
- struct tx_cmd *tx_cmd;
-
- if (i596_debug > 2) printk ("%s: Apricot start xmit\n", dev->name);
-
- /* Transmitter timeout, serious problems. */
- if (dev->tbusy) {
- int tickssofar = jiffies - dev->trans_start;
- if (tickssofar < 5)
- return 1;
- printk("%s: transmit timed out, status resetting.\n",
- dev->name);
- lp->stats.tx_errors++;
- /* Try to restart the adaptor */
- if (lp->last_restart == lp->stats.tx_packets) {
- if (i596_debug > 1) printk ("Resetting board.\n");
-
- /* Shutdown and restart */
- i596_reset(dev,lp, ioaddr);
- } else {
- /* Issue a channel attention signal */
- if (i596_debug > 1) printk ("Kicking board.\n");
-
- lp->scb.command = CUC_START|RX_START;
- outw(0, ioaddr+4);
-
- lp->last_restart = lp->stats.tx_packets;
- }
- dev->tbusy = 0;
- dev->trans_start = jiffies;
- }
-
- /* If some higher level thinks we've misses a tx-done interrupt
- we are passed NULL. n.b. dev_tint handles the cli()/sti()
- itself. */
- if (skb == NULL) {
- dev_tint(dev);
- return 0;
- }
-
- /* shouldn't happen */
- if (skb->len <= 0) return 0;
-
- if (i596_debug > 3) printk("%s: i596_start_xmit() called\n", dev->name);
-
- /* Block a timer-based transmit from overlapping. This could better be
- done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
- if (set_bit(0, (void*)&dev->tbusy) != 0)
- printk("%s: Transmitter access conflict.\n", dev->name);
- else
- {
- short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
- dev->trans_start = jiffies;
-
- tx_cmd = (struct tx_cmd *) kmalloc ((sizeof (struct tx_cmd) + sizeof (struct i596_tbd)), GFP_ATOMIC);
- if (tx_cmd == NULL)
- {
- printk ("%s: i596_xmit Memory squeeze, dropping packet.\n", dev->name);
- lp->stats.tx_dropped++;
-
- dev_kfree_skb(skb, FREE_WRITE);
- }
- else
- {
- tx_cmd->tbd = (struct i596_tbd *) (tx_cmd + 1);
- tx_cmd->tbd->next = (struct i596_tbd *) I596_NULL;
-
- tx_cmd->cmd.command = CMD_FLEX|CmdTx;
-
- tx_cmd->pad = 0;
- tx_cmd->size = 0;
- tx_cmd->tbd->pad = 0;
- tx_cmd->tbd->size = EOF | length;
-
- tx_cmd->tbd->data = skb->data;
-
- if (i596_debug > 3) print_eth(skb->data);
-
- i596_add_cmd(dev, (struct i596_cmd *)tx_cmd);
-
- lp->stats.tx_packets++;
- }
- }
-
- dev->tbusy = 0;
-
- return 0;
-}
-
-
-static void print_eth(char *add)
-{
- int i;
-
- printk ("Dest ");
- for (i = 0; i < 6; i++)
- printk(" %2.2X", (unsigned char)add[i]);
- printk ("\n");
-
- printk ("Source");
- for (i = 0; i < 6; i++)
- printk(" %2.2X", (unsigned char)add[i+6]);
- printk ("\n");
- printk ("type %2.2X%2.2X\n", (unsigned char)add[12], (unsigned char)add[13]);
-}
-
-int apricot_probe(struct device *dev)
-{
- int i;
- struct i596_private *lp;
- int checksum = 0;
- int ioaddr = 0x300;
- char eth_addr[6];
-
- /* this is easy the ethernet interface can only be at 0x300 */
- /* first check nothing is already registered here */
-
- if (check_region(ioaddr, APRICOT_TOTAL_SIZE))
- return ENODEV;
-
- for (i = 0; i < 8; i++)
- {
- eth_addr[i] = inb(ioaddr+8+i);
- checksum += eth_addr[i];
- }
-
- /* checksum is a multiple of 0x100, got this wrong first time
- some machines have 0x100, some 0x200. The DOS driver doesn't
- even bother with the checksum */
-
- if (checksum % 0x100) return ENODEV;
-
- /* Some other boards trip the checksum.. but then appear as ether
- address 0. Trap these - AC */
-
- if(memcmp(eth_addr,"\x00\x00\x49",3)!= 0)
- return ENODEV;
-
- request_region(ioaddr, APRICOT_TOTAL_SIZE, "apricot");
-
- dev->base_addr = ioaddr;
- ether_setup(dev);
- printk("%s: Apricot 82596 at %#3x,", dev->name, ioaddr);
-
- for (i = 0; i < 6; i++)
- printk(" %2.2X", dev->dev_addr[i] = eth_addr[i]);
-
- dev->base_addr = ioaddr;
- dev->irq = 10;
- printk(" IRQ %d.\n", dev->irq);
-
- if (i596_debug > 0) printk(version);
-
- /* The APRICOT-specific entries in the device structure. */
- dev->open = &i596_open;
- dev->stop = &i596_close;
- dev->hard_start_xmit = &i596_start_xmit;
- dev->get_stats = &i596_get_stats;
- dev->set_multicast_list = &set_multicast_list;
-
- dev->mem_start = (int)kmalloc(sizeof(struct i596_private)+ 0x0f, GFP_KERNEL);
- /* align for scp */
- dev->priv = (void *)((dev->mem_start + 0xf) & 0xfffffff0);
-
- lp = (struct i596_private *)dev->priv;
- memset((void *)lp, 0, sizeof(struct i596_private));
- lp->scb.command = 0;
- lp->scb.cmd = (struct i596_cmd *) I596_NULL;
- lp->scb.rfd = (struct i596_rfd *)I596_NULL;
-
- return 0;
-}
-
-static void
-i596_interrupt(int irq, struct pt_regs *regs)
-{
- struct device *dev = (struct device *)(irq2dev_map[irq]);
- struct i596_private *lp;
- short ioaddr;
- int boguscnt = 200;
- unsigned short status, ack_cmd = 0;
-
- if (dev == NULL) {
- printk ("i596_interrupt(): irq %d for unknown device.\n", irq);
- return;
- }
-
- if (i596_debug > 3) printk ("%s: i596_interrupt(): irq %d\n",dev->name, irq);
-
- if (dev->interrupt)
- printk("%s: Re-entering the interrupt handler.\n", dev->name);
-
- dev->interrupt = 1;
-
- ioaddr = dev->base_addr;
-
- lp = (struct i596_private *)dev->priv;
-
- while (lp->scb.status, lp->scb.command)
- if (--boguscnt == 0)
- {
- printk("%s: i596 interrupt, timeout status %4.4x command %4.4x.\n", dev->name, lp->scb.status, lp->scb.command);
- break;
- }
- status = lp->scb.status;
-
- if (i596_debug > 4)
- printk("%s: i596 interrupt, status %4.4x.\n", dev->name, status);
-
- ack_cmd = status & 0xf000;
-
- if ((status & 0x8000) || (status & 0x2000))
- {
- struct i596_cmd *ptr;
-
- if ((i596_debug > 4) && (status & 0x8000))
- printk("%s: i596 interrupt completed command.\n", dev->name);
- if ((i596_debug > 4) && (status & 0x2000))
- printk("%s: i596 interrupt command unit inactive %x.\n", dev->name, status & 0x0700);
-
- while ((lp->cmd_head != (struct i596_cmd *) I596_NULL) && (lp->cmd_head->status & STAT_C))
- {
- ptr = lp->cmd_head;
-
- lp->cmd_head = lp->cmd_head->next;
- lp->cmd_backlog--;
-
- switch ((ptr->command) & 0x7)
- {
- case CmdTx:
- {
- struct tx_cmd *tx_cmd = (struct tx_cmd *) ptr;
- struct sk_buff *skb = ((struct sk_buff *)(tx_cmd->tbd->data)) -1;
-
- dev_kfree_skb(skb, FREE_WRITE);
-
- if ((ptr->status) & STAT_OK)
- {
- if (i596_debug >2) print_eth(skb->data);
- }
- else
- {
- lp->stats.tx_errors++;
- if ((ptr->status) & 0x0020) lp->stats.collisions++;
- if (!((ptr->status) & 0x0040)) lp->stats.tx_heartbeat_errors++;
- if ((ptr->status) & 0x0400) lp->stats.tx_carrier_errors++;
- if ((ptr->status) & 0x0800) lp->stats.collisions++;
- if ((ptr->status) & 0x1000) lp->stats.tx_aborted_errors++;
- }
-
-
- ptr->next = (struct i596_cmd * ) I596_NULL;
- kfree_s((unsigned char *)tx_cmd, (sizeof (struct tx_cmd) + sizeof (struct i596_tbd)));
- break;
- }
- case CmdMulticastList:
- {
- unsigned short count = *((unsigned short *) (ptr + 1));
-
- ptr->next = (struct i596_cmd * ) I596_NULL;
- kfree_s((unsigned char *)ptr, (sizeof (struct i596_cmd) + count + 2));
- break;
- }
- case CmdTDR:
- {
- unsigned long status = *((unsigned long *) (ptr + 1));
-
- if (status & 0x8000)
- {
- if (i596_debug > 3)
- printk("%s: link ok.\n", dev->name);
- }
- else
- {
- if (status & 0x4000)
- printk("%s: Transceiver problem.\n", dev->name);
- if (status & 0x2000)
- printk("%s: Termination problem.\n", dev->name);
- if (status & 0x1000)
- printk("%s: Short circuit.\n", dev->name);
-
- printk("%s: Time %ld.\n", dev->name, status & 0x07ff);
- }
- }
- default:
- ptr->next = (struct i596_cmd * ) I596_NULL;
-
- lp->last_cmd = jiffies;
- }
- }
-
- ptr = lp->cmd_head;
- while ((ptr != (struct i596_cmd *) I596_NULL) && (ptr != lp->cmd_tail))
- {
- ptr->command &= 0x1fff;
- ptr = ptr->next;
- }
-
- if ((lp->cmd_head != (struct i596_cmd *) I596_NULL) && (dev->start)) ack_cmd |= CUC_START;
- lp->scb.cmd = lp->cmd_head;
- }
-
- if ((status & 0x1000) || (status & 0x4000))
- {
- if ((i596_debug > 4) && (status & 0x4000))
- printk("%s: i596 interrupt received a frame.\n", dev->name);
- if ((i596_debug > 4) && (status & 0x1000))
- printk("%s: i596 interrupt receive unit inactive %x.\n", dev->name, status & 0x0070);
-
- i596_rx(dev);
-
- if (dev->start) ack_cmd |= RX_START;
- }
-
- /* acknowledge the interrupt */
-
-/*
- if ((lp->scb.cmd != (struct i596_cmd *) I596_NULL) && (dev->start)) ack_cmd | = CUC_START;
-*/
- boguscnt = 100;
- while (lp->scb.status, lp->scb.command)
- if (--boguscnt == 0)
- {
- printk("%s: i596 interrupt, timeout status %4.4x command %4.4x.\n", dev->name, lp->scb.status, lp->scb.command);
- break;
- }
- lp->scb.command = ack_cmd;
-
- (void) inb (ioaddr+0x10);
- outb (4, ioaddr+0xf);
- outw (0, ioaddr+4);
-
- if (i596_debug > 4)
- printk("%s: exiting interrupt.\n", dev->name);
-
- dev->interrupt = 0;
- return;
-}
-
-static int
-i596_close(struct device *dev)
-{
- int ioaddr = dev->base_addr;
- struct i596_private *lp = (struct i596_private *)dev->priv;
- int boguscnt = 200;
-
- dev->start = 0;
- dev->tbusy = 1;
-
- if (i596_debug > 1)
- printk("%s: Shutting down ethercard, status was %4.4x.\n",
- dev->name, lp->scb.status);
-
- lp->scb.command = CUC_ABORT|RX_ABORT;
- outw(0, ioaddr+4);
-
- i596_cleanup_cmd(lp);
-
- while (lp->scb.status, lp->scb.command)
- if (--boguscnt == 0)
- {
- printk("%s: close timed timed out with status %4.4x, cmd %4.4x.\n",
- dev->name, lp->scb.status, lp->scb.command);
- break;
- }
- free_irq(dev->irq);
- irq2dev_map[dev->irq] = 0;
- remove_rx_bufs(dev);
- MOD_DEC_USE_COUNT;
-
- return 0;
-}
-
-static struct enet_statistics *
-i596_get_stats(struct device *dev)
-{
- struct i596_private *lp = (struct i596_private *)dev->priv;
-
- return &lp->stats;
-}
-
-/*
- * Set or clear the multicast filter for this adaptor.
- */
-
-static void set_multicast_list(struct device *dev)
-{
- struct i596_private *lp = (struct i596_private *)dev->priv;
- struct i596_cmd *cmd;
-
- if (i596_debug > 1)
- printk ("%s: set multicast list %d\n", dev->name, dev->mc_count);
-
- if (dev->mc_count > 0)
- {
- struct dev_mc_list *dmi;
- char *cp;
- cmd = (struct i596_cmd *) kmalloc(sizeof(struct i596_cmd)+2+dev->mc_count*6, GFP_ATOMIC);
- if (cmd == NULL)
- {
- printk ("%s: set_multicast Memory squeeze.\n", dev->name);
- return;
- }
- cmd->command = CmdMulticastList;
- *((unsigned short *) (cmd + 1)) = dev->mc_count * 6;
- cp=((char *)(cmd + 1))+2;
- for(dmi=dev->mc_list;dmi!=NULL;dmi=dmi->next)
- {
- memcpy(cp, dmi,6);
- cp+=6;
- }
- print_eth (((char *)(cmd + 1)) + 2);
- i596_add_cmd(dev, cmd);
- }
- else
- {
- if (lp->set_conf.next != (struct i596_cmd * ) I596_NULL)
- return;
- if (dev->mc_count == 0 && !(dev->flags&(IFF_PROMISC|IFF_ALLMULTI)))
- {
- if(dev->flags&IFF_ALLMULTI)
- dev->flags|=IFF_PROMISC;
- lp->i596_config[8] &= ~0x01;
- }
- else
- lp->i596_config[8] |= 0x01;
-
- i596_add_cmd(dev, &lp->set_conf);
- }
-}
-
-#ifdef HAVE_DEVLIST
-static unsigned int apricot_portlist[] = {0x300, 0};
-struct netdev_entry apricot_drv =
-{"apricot", apricot_probe, APRICOT_TOTAL_SIZE, apricot_portlist};
-#endif
-
-#ifdef MODULE
-static char devicename[9] = { 0, };
-static struct device dev_apricot = {
- devicename, /* device name inserted by /linux/drivers/net/net_init.c */
- 0, 0, 0, 0,
- 0x300, 10,
- 0, 0, 0, NULL, apricot_probe };
-
-static int io = 0x300;
-static int irq = 10;
-
-int
-init_module(void)
-{
- dev_apricot.base_addr = io;
- dev_apricot.irq = irq;
- if (register_netdev(&dev_apricot) != 0)
- return -EIO;
- return 0;
-}
-
-void
-cleanup_module(void)
-{
- unregister_netdev(&dev_apricot);
- kfree_s((void *)dev_apricot.mem_start, sizeof(struct i596_private) + 0xf);
- dev_apricot.priv = NULL;
-
- /* If we don't do this, we can't re-insmod it later. */
- release_region(dev_apricot.base_addr, APRICOT_TOTAL_SIZE);
-}
-#endif /* MODULE */
-
-/*
- * Local variables:
- * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c apricot.c"
- * End:
- */
diff --git a/i386/i386at/gpl/linux/net/at1700.c b/i386/i386at/gpl/linux/net/at1700.c
deleted file mode 100644
index 3d684c0a..00000000
--- a/i386/i386at/gpl/linux/net/at1700.c
+++ /dev/null
@@ -1,677 +0,0 @@
-/* at1700.c: A network device driver for the Allied Telesis AT1700.
-
- Written 1993-94 by Donald Becker.
-
- Copyright 1993 United States Government as represented by the
- Director, National Security Agency.
-
- This software may be used and distributed according to the terms
- of the GNU Public License, incorporated herein by reference.
-
- The author may be reached as becker@CESDIS.gsfc.nasa.gov, or C/O
- Center of Excellence in Space Data and Information Sciences
- Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
-
- This is a device driver for the Allied Telesis AT1700, which is a
- straight-forward Fujitsu MB86965 implementation.
-
- Sources:
- The Fujitsu MB86965 datasheet.
-
- After the initial version of this driver was written Gerry Sawkins of
- ATI provided their EEPROM configuration code header file.
- Thanks to NIIBE Yutaka <gniibe@mri.co.jp> for bug fixes.
-
- Bugs:
- The MB86965 has a design flaw that makes all probes unreliable. Not
- only is it difficult to detect, it also moves around in I/O space in
- response to inb()s from other device probes!
-*/
-
-static const char *version =
- "at1700.c:v1.12 1/18/95 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ptrace.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/malloc.h>
-#include <linux/string.h>
-#include <asm/system.h>
-#include <asm/bitops.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <linux/errno.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-
-/* This unusual address order is used to verify the CONFIG register. */
-static int at1700_probe_list[] =
-{0x260, 0x280, 0x2a0, 0x240, 0x340, 0x320, 0x380, 0x300, 0};
-
-/* use 0 for production, 1 for verification, >2 for debug */
-#ifndef NET_DEBUG
-#define NET_DEBUG 1
-#endif
-static unsigned int net_debug = NET_DEBUG;
-
-typedef unsigned char uchar;
-
-/* Information that need to be kept for each board. */
-struct net_local {
- struct enet_statistics stats;
- uint tx_started:1; /* Number of packet on the Tx queue. */
- uchar tx_queue; /* Number of packet on the Tx queue. */
- ushort tx_queue_len; /* Current length of the Tx queue. */
-};
-
-
-/* Offsets from the base address. */
-#define STATUS 0
-#define TX_STATUS 0
-#define RX_STATUS 1
-#define TX_INTR 2 /* Bit-mapped interrupt enable registers. */
-#define RX_INTR 3
-#define TX_MODE 4
-#define RX_MODE 5
-#define CONFIG_0 6 /* Misc. configuration settings. */
-#define CONFIG_1 7
-/* Run-time register bank 2 definitions. */
-#define DATAPORT 8 /* Word-wide DMA or programmed-I/O dataport. */
-#define TX_START 10
-#define MODE13 13
-#define EEPROM_Ctrl 16
-#define EEPROM_Data 17
-#define IOCONFIG 19
-#define RESET 31 /* Write to reset some parts of the chip. */
-#define AT1700_IO_EXTENT 32
-
-/* EEPROM_Ctrl bits. */
-#define EE_SHIFT_CLK 0x40 /* EEPROM shift clock, in reg. 16. */
-#define EE_CS 0x20 /* EEPROM chip select, in reg. 16. */
-#define EE_DATA_WRITE 0x80 /* EEPROM chip data in, in reg. 17. */
-#define EE_DATA_READ 0x80 /* EEPROM chip data out, in reg. 17. */
-
-/* Delay between EEPROM clock transitions. */
-#define eeprom_delay() do { int _i = 40; while (--_i > 0) { __SLOW_DOWN_IO; }} while (0)
-
-/* The EEPROM commands include the alway-set leading bit. */
-#define EE_WRITE_CMD (5 << 6)
-#define EE_READ_CMD (6 << 6)
-#define EE_ERASE_CMD (7 << 6)
-
-
-/* Index to functions, as function prototypes. */
-
-extern int at1700_probe(struct device *dev);
-
-static int at1700_probe1(struct device *dev, short ioaddr);
-static int read_eeprom(int ioaddr, int location);
-static int net_open(struct device *dev);
-static int net_send_packet(struct sk_buff *skb, struct device *dev);
-static void net_interrupt(int irq, struct pt_regs *regs);
-static void net_rx(struct device *dev);
-static int net_close(struct device *dev);
-static struct enet_statistics *net_get_stats(struct device *dev);
-static void set_multicast_list(struct device *dev);
-
-
-/* Check for a network adaptor of this type, and return '0' iff one exists.
- If dev->base_addr == 0, probe all likely locations.
- If dev->base_addr == 1, always return failure.
- If dev->base_addr == 2, allocate space for the device and return success
- (detachable devices only).
- */
-#ifdef HAVE_DEVLIST
-/* Support for a alternate probe manager, which will eliminate the
- boilerplate below. */
-struct netdev_entry at1700_drv =
-{"at1700", at1700_probe1, AT1700_IO_EXTENT, at1700_probe_list};
-#else
-int
-at1700_probe(struct device *dev)
-{
- int i;
- int base_addr = dev ? dev->base_addr : 0;
-
- if (base_addr > 0x1ff) /* Check a single specified location. */
- return at1700_probe1(dev, base_addr);
- else if (base_addr != 0) /* Don't probe at all. */
- return ENXIO;
-
- for (i = 0; at1700_probe_list[i]; i++) {
- int ioaddr = at1700_probe_list[i];
- if (check_region(ioaddr, AT1700_IO_EXTENT))
- continue;
- if (at1700_probe1(dev, ioaddr) == 0)
- return 0;
- }
-
- return ENODEV;
-}
-#endif
-
-/* The Fujitsu datasheet suggests that the NIC be probed for by checking its
- "signature", the default bit pattern after a reset. This *doesn't* work --
- there is no way to reset the bus interface without a complete power-cycle!
-
- It turns out that ATI came to the same conclusion I did: the only thing
- that can be done is checking a few bits and then diving right into an
- EEPROM read. */
-
-int at1700_probe1(struct device *dev, short ioaddr)
-{
- char irqmap[8] = {3, 4, 5, 9, 10, 11, 14, 15};
- unsigned int i, irq;
-
- /* Resetting the chip doesn't reset the ISA interface, so don't bother.
- That means we have to be careful with the register values we probe for.
- */
-#ifdef notdef
- printk("at1700 probe at %#x, eeprom is %4.4x %4.4x %4.4x ctrl %4.4x.\n",
- ioaddr, read_eeprom(ioaddr, 4), read_eeprom(ioaddr, 5),
- read_eeprom(ioaddr, 6), inw(ioaddr + EEPROM_Ctrl));
-#endif
- if (at1700_probe_list[inb(ioaddr + IOCONFIG) & 0x07] != ioaddr
- || read_eeprom(ioaddr, 4) != 0x0000
- || (read_eeprom(ioaddr, 5) & 0xff00) != 0xF400)
- return -ENODEV;
-
- /* Reset the internal state machines. */
- outb(0, ioaddr + RESET);
-
- irq = irqmap[(read_eeprom(ioaddr, 12)&0x04)
- | (read_eeprom(ioaddr, 0)>>14)];
-
- /* Snarf the interrupt vector now. */
- if (request_irq(irq, &net_interrupt, 0, "at1700")) {
- printk ("AT1700 found at %#3x, but it's unusable due to a conflict on"
- "IRQ %d.\n", ioaddr, irq);
- return EAGAIN;
- }
-
- /* Allocate a new 'dev' if needed. */
- if (dev == NULL)
- dev = init_etherdev(0, sizeof(struct net_local));
-
- /* Grab the region so that we can find another board if the IRQ request
- fails. */
- request_region(ioaddr, AT1700_IO_EXTENT, "at1700");
-
- printk("%s: AT1700 found at %#3x, IRQ %d, address ", dev->name,
- ioaddr, irq);
-
- dev->base_addr = ioaddr;
- dev->irq = irq;
- irq2dev_map[irq] = dev;
-
- for(i = 0; i < 3; i++) {
- unsigned short eeprom_val = read_eeprom(ioaddr, 4+i);
- printk("%04x", eeprom_val);
- ((unsigned short *)dev->dev_addr)[i] = ntohs(eeprom_val);
- }
-
- /* The EEPROM word 12 bit 0x0400 means use regular 100 ohm 10baseT signals,
- rather than 150 ohm shielded twisted pair compensation.
- 0x0000 == auto-sense the interface
- 0x0800 == use TP interface
- 0x1800 == use coax interface
- */
- {
- const char *porttype[] = {"auto-sense", "10baseT", "auto-sense", "10base2"};
- ushort setup_value = read_eeprom(ioaddr, 12);
-
- dev->if_port = setup_value >> 8;
- printk(" %s interface.\n", porttype[(dev->if_port>>3) & 3]);
- }
-
- /* Set the station address in bank zero. */
- outb(0xe0, ioaddr + 7);
- for (i = 0; i < 6; i++)
- outb(dev->dev_addr[i], ioaddr + 8 + i);
-
- /* Switch to bank 1 and set the multicast table to accept none. */
- outb(0xe4, ioaddr + 7);
- for (i = 0; i < 8; i++)
- outb(0x00, ioaddr + 8 + i);
-
- /* Set the configuration register 0 to 32K 100ns. byte-wide memory, 16 bit
- bus access, two 4K Tx queues, and disabled Tx and Rx. */
- outb(0xda, ioaddr + CONFIG_0);
-
- /* Switch to bank 2 and lock our I/O address. */
- outb(0xe8, ioaddr + 7);
- outb(dev->if_port, MODE13);
-
- /* Power-down the chip. Aren't we green! */
- outb(0x00, ioaddr + CONFIG_1);
-
- if (net_debug)
- printk(version);
-
- /* Initialize the device structure. */
- dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
- if (dev->priv == NULL)
- return -ENOMEM;
- memset(dev->priv, 0, sizeof(struct net_local));
-
- dev->open = net_open;
- dev->stop = net_close;
- dev->hard_start_xmit = net_send_packet;
- dev->get_stats = net_get_stats;
- dev->set_multicast_list = &set_multicast_list;
-
- /* Fill in the fields of 'dev' with ethernet-generic values. */
-
- ether_setup(dev);
- return 0;
-}
-
-static int read_eeprom(int ioaddr, int location)
-{
- int i;
- unsigned short retval = 0;
- short ee_addr = ioaddr + EEPROM_Ctrl;
- short ee_daddr = ioaddr + EEPROM_Data;
- int read_cmd = location | EE_READ_CMD;
- short ctrl_val = EE_CS;
-
- outb(ctrl_val, ee_addr);
-
- /* Shift the read command bits out. */
- for (i = 9; i >= 0; i--) {
- short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
- outb(dataval, ee_daddr);
- outb(EE_CS | EE_SHIFT_CLK, ee_addr); /* EEPROM clock tick. */
- eeprom_delay();
- outb(EE_CS, ee_addr); /* Finish EEPROM a clock tick. */
- eeprom_delay();
- }
- outb(EE_CS, ee_addr);
-
- for (i = 16; i > 0; i--) {
- outb(EE_CS | EE_SHIFT_CLK, ee_addr);
- eeprom_delay();
- retval = (retval << 1) | ((inb(ee_daddr) & EE_DATA_READ) ? 1 : 0);
- outb(EE_CS, ee_addr);
- eeprom_delay();
- }
-
- /* Terminate the EEPROM access. */
- ctrl_val &= ~EE_CS;
- outb(ctrl_val | EE_SHIFT_CLK, ee_addr);
- eeprom_delay();
- outb(ctrl_val, ee_addr);
- eeprom_delay();
- return retval;
-}
-
-
-
-static int net_open(struct device *dev)
-{
- struct net_local *lp = (struct net_local *)dev->priv;
- int ioaddr = dev->base_addr;
- int i;
-
- /* Powerup the chip, initialize config register 1, and select bank 0. */
- outb(0xe0, ioaddr + CONFIG_1);
-
- /* Set the station address in bank zero. */
- for (i = 0; i < 6; i++)
- outb(dev->dev_addr[i], ioaddr + 8 + i);
-
- /* Switch to bank 1 and set the multicast table to accept none. */
- outb(0xe4, ioaddr + 7);
- for (i = 0; i < 8; i++)
- outb(0x00, ioaddr + 8 + i);
-
- /* Set the configuration register 0 to 32K 100ns. byte-wide memory, 16 bit
- bus access, and two 4K Tx queues. */
- outb(0xda, ioaddr + CONFIG_0);
-
- /* Same config 0, except enable the Rx and Tx. */
- outb(0x5a, ioaddr + CONFIG_0);
- /* Switch to register bank 2 for the run-time registers. */
- outb(0xe8, ioaddr + CONFIG_1);
-
- lp->tx_started = 0;
- lp->tx_queue = 0;
- lp->tx_queue_len = 0;
-
- /* Turn on Rx interrupts, leave Tx interrupts off until packet Tx. */
- outb(0x00, ioaddr + TX_INTR);
- outb(0x81, ioaddr + RX_INTR);
-
- dev->tbusy = 0;
- dev->interrupt = 0;
- dev->start = 1;
-
- MOD_INC_USE_COUNT;
-
- return 0;
-}
-
-static int
-net_send_packet(struct sk_buff *skb, struct device *dev)
-{
- struct net_local *lp = (struct net_local *)dev->priv;
- int ioaddr = dev->base_addr;
-
- if (dev->tbusy) {
- /* If we get here, some higher level has decided we are broken.
- There should really be a "kick me" function call instead. */
- int tickssofar = jiffies - dev->trans_start;
- if (tickssofar < 10)
- return 1;
- printk("%s: transmit timed out with status %04x, %s?\n", dev->name,
- inw(ioaddr + STATUS), inb(ioaddr + TX_STATUS) & 0x80
- ? "IRQ conflict" : "network cable problem");
- printk("%s: timeout registers: %04x %04x %04x %04x %04x %04x %04x %04x.\n",
- dev->name, inw(ioaddr + 0), inw(ioaddr + 2), inw(ioaddr + 4),
- inw(ioaddr + 6), inw(ioaddr + 8), inw(ioaddr + 10),
- inw(ioaddr + 12), inw(ioaddr + 14));
- lp->stats.tx_errors++;
- /* ToDo: We should try to restart the adaptor... */
- outw(0xffff, ioaddr + 24);
- outw(0xffff, ioaddr + TX_STATUS);
- outw(0xe85a, ioaddr + CONFIG_0);
- outw(0x8100, ioaddr + TX_INTR);
- dev->tbusy=0;
- dev->trans_start = jiffies;
- lp->tx_started = 0;
- lp->tx_queue = 0;
- lp->tx_queue_len = 0;
- }
-
- /* If some higher layer thinks we've missed an tx-done interrupt
- we are passed NULL. Caution: dev_tint() handles the cli()/sti()
- itself. */
- if (skb == NULL) {
- dev_tint(dev);
- return 0;
- }
-
- /* Block a timer-based transmit from overlapping. This could better be
- done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
- if (set_bit(0, (void*)&dev->tbusy) != 0)
- printk("%s: Transmitter access conflict.\n", dev->name);
- else {
- short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
- unsigned char *buf = skb->data;
-
- /* Turn off the possible Tx interrupts. */
- outb(0x00, ioaddr + TX_INTR);
-
- outw(length, ioaddr + DATAPORT);
- outsw(ioaddr + DATAPORT, buf, (length + 1) >> 1);
-
- lp->tx_queue++;
- lp->tx_queue_len += length + 2;
-
- if (lp->tx_started == 0) {
- /* If the Tx is idle, always trigger a transmit. */
- outb(0x80 | lp->tx_queue, ioaddr + TX_START);
- lp->tx_queue = 0;
- lp->tx_queue_len = 0;
- dev->trans_start = jiffies;
- lp->tx_started = 1;
- dev->tbusy = 0;
- } else if (lp->tx_queue_len < 4096 - 1502)
- /* Yes, there is room for one more packet. */
- dev->tbusy = 0;
-
- /* Turn on Tx interrupts back on. */
- outb(0x82, ioaddr + TX_INTR);
- }
- dev_kfree_skb (skb, FREE_WRITE);
-
- return 0;
-}
-
-/* The typical workload of the driver:
- Handle the network interface interrupts. */
-static void
-net_interrupt(int irq, struct pt_regs *regs)
-{
- struct device *dev = (struct device *)(irq2dev_map[irq]);
- struct net_local *lp;
- int ioaddr, status;
-
- if (dev == NULL) {
- printk ("at1700_interrupt(): irq %d for unknown device.\n", irq);
- return;
- }
- dev->interrupt = 1;
-
- ioaddr = dev->base_addr;
- lp = (struct net_local *)dev->priv;
- status = inw(ioaddr + TX_STATUS);
- outw(status, ioaddr + TX_STATUS);
-
- if (net_debug > 4)
- printk("%s: Interrupt with status %04x.\n", dev->name, status);
- if (status & 0xff00
- || (inb(ioaddr + RX_MODE) & 0x40) == 0) { /* Got a packet(s). */
- net_rx(dev);
- }
- if (status & 0x00ff) {
- if (status & 0x80) {
- lp->stats.tx_packets++;
- if (lp->tx_queue) {
- outb(0x80 | lp->tx_queue, ioaddr + TX_START);
- lp->tx_queue = 0;
- lp->tx_queue_len = 0;
- dev->trans_start = jiffies;
- dev->tbusy = 0;
- mark_bh(NET_BH); /* Inform upper layers. */
- } else {
- lp->tx_started = 0;
- /* Turn on Tx interrupts off. */
- outb(0x00, ioaddr + TX_INTR);
- dev->tbusy = 0;
- mark_bh(NET_BH); /* Inform upper layers. */
- }
- }
- }
-
- dev->interrupt = 0;
- return;
-}
-
-/* We have a good packet(s), get it/them out of the buffers. */
-static void
-net_rx(struct device *dev)
-{
- struct net_local *lp = (struct net_local *)dev->priv;
- int ioaddr = dev->base_addr;
- int boguscount = 5;
-
- while ((inb(ioaddr + RX_MODE) & 0x40) == 0) {
- ushort status = inw(ioaddr + DATAPORT);
- ushort pkt_len = inw(ioaddr + DATAPORT);
-
- if (net_debug > 4)
- printk("%s: Rxing packet mode %02x status %04x.\n",
- dev->name, inb(ioaddr + RX_MODE), status);
-#ifndef final_version
- if (status == 0) {
- outb(0x05, ioaddr + 14);
- break;
- }
-#endif
-
- if ((status & 0xF0) != 0x20) { /* There was an error. */
- lp->stats.rx_errors++;
- if (status & 0x08) lp->stats.rx_length_errors++;
- if (status & 0x04) lp->stats.rx_frame_errors++;
- if (status & 0x02) lp->stats.rx_crc_errors++;
- if (status & 0x01) lp->stats.rx_over_errors++;
- } else {
- /* Malloc up new buffer. */
- struct sk_buff *skb;
-
- if (pkt_len > 1550) {
- printk("%s: The AT1700 claimed a very large packet, size %d.\n",
- dev->name, pkt_len);
- /* Prime the FIFO and then flush the packet. */
- inw(ioaddr + DATAPORT); inw(ioaddr + DATAPORT);
- outb(0x05, ioaddr + 14);
- lp->stats.rx_errors++;
- break;
- }
- skb = dev_alloc_skb(pkt_len+3);
- if (skb == NULL) {
- printk("%s: Memory squeeze, dropping packet (len %d).\n",
- dev->name, pkt_len);
- /* Prime the FIFO and then flush the packet. */
- inw(ioaddr + DATAPORT); inw(ioaddr + DATAPORT);
- outb(0x05, ioaddr + 14);
- lp->stats.rx_dropped++;
- break;
- }
- skb->dev = dev;
- skb_reserve(skb,2);
-
- insw(ioaddr + DATAPORT, skb_put(skb,pkt_len), (pkt_len + 1) >> 1);
- skb->protocol=eth_type_trans(skb, dev);
- netif_rx(skb);
- lp->stats.rx_packets++;
- }
- if (--boguscount <= 0)
- break;
- }
-
- /* If any worth-while packets have been received, dev_rint()
- has done a mark_bh(NET_BH) for us and will work on them
- when we get to the bottom-half routine. */
- {
- int i;
- for (i = 0; i < 20; i++) {
- if ((inb(ioaddr + RX_MODE) & 0x40) == 0x40)
- break;
- inw(ioaddr + DATAPORT); /* dummy status read */
- outb(0x05, ioaddr + 14);
- }
-
- if (net_debug > 5)
- printk("%s: Exint Rx packet with mode %02x after %d ticks.\n",
- dev->name, inb(ioaddr + RX_MODE), i);
- }
- return;
-}
-
-/* The inverse routine to net_open(). */
-static int net_close(struct device *dev)
-{
- int ioaddr = dev->base_addr;
-
- dev->tbusy = 1;
- dev->start = 0;
-
- /* Set configuration register 0 to disable Tx and Rx. */
- outb(0xda, ioaddr + CONFIG_0);
-
- /* Update the statistics -- ToDo. */
-
- /* Power-down the chip. Green, green, green! */
- outb(0x00, ioaddr + CONFIG_1);
-
- MOD_DEC_USE_COUNT;
-
- return 0;
-}
-
-/* Get the current statistics. This may be called with the card open or
- closed. */
-static struct enet_statistics *
-net_get_stats(struct device *dev)
-{
- struct net_local *lp = (struct net_local *)dev->priv;
-
- cli();
- /* ToDo: Update the statistics from the device registers. */
- sti();
-
- return &lp->stats;
-}
-
-/* Set or clear the multicast filter for this adaptor.
- num_addrs == -1 Promiscuous mode, receive all packets
- num_addrs == 0 Normal mode, clear multicast list
- num_addrs > 0 Multicast mode, receive normal and MC packets, and do
- best-effort filtering.
- */
-static void
-set_multicast_list(struct device *dev)
-{
- short ioaddr = dev->base_addr;
- if (dev->mc_count || dev->flags&(IFF_PROMISC|IFF_ALLMULTI))
- {
- /*
- * We must make the kernel realise we had to move
- * into promisc mode or we start all out war on
- * the cable. - AC
- */
- dev->flags|=IFF_PROMISC;
-
- outb(3, ioaddr + RX_MODE); /* Enable promiscuous mode */
- }
- else
- outb(2, ioaddr + RX_MODE); /* Disable promiscuous, use normal mode */
-}
-#ifdef MODULE
-static char devicename[9] = { 0, };
-static struct device dev_at1700 = {
- devicename, /* device name is inserted by linux/drivers/net/net_init.c */
- 0, 0, 0, 0,
- 0, 0,
- 0, 0, 0, NULL, at1700_probe };
-
-static int io = 0x260;
-static int irq = 0;
-
-int init_module(void)
-{
- if (io == 0)
- printk("at1700: You should not use auto-probing with insmod!\n");
- dev_at1700.base_addr = io;
- dev_at1700.irq = irq;
- if (register_netdev(&dev_at1700) != 0) {
- printk("at1700: register_netdev() returned non-zero.\n");
- return -EIO;
- }
- return 0;
-}
-
-void
-cleanup_module(void)
-{
- unregister_netdev(&dev_at1700);
- kfree(dev_at1700.priv);
- dev_at1700.priv = NULL;
-
- /* If we don't do this, we can't re-insmod it later. */
- free_irq(dev_at1700.irq);
- irq2dev_map[dev_at1700.irq] = NULL;
- release_region(dev_at1700.base_addr, AT1700_IO_EXTENT);
-}
-#endif /* MODULE */
-
-/*
- * Local variables:
- * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c at1700.c"
- * version-control: t
- * kept-new-versions: 5
- * tab-width: 4
- * c-indent-level: 4
- * End:
- */
diff --git a/i386/i386at/gpl/linux/net/atp.c b/i386/i386at/gpl/linux/net/atp.c
deleted file mode 100644
index 62aa04ef..00000000
--- a/i386/i386at/gpl/linux/net/atp.c
+++ /dev/null
@@ -1,787 +0,0 @@
-/* atp.c: Attached (pocket) ethernet adapter driver for linux. */
-/*
- This is a driver for a commonly OEMed pocket (parallel port)
- ethernet adapter.
-
- Written 1993,1994,1995 by Donald Becker.
-
- Copyright 1993 United States Government as represented by the
- Director, National Security Agency.
-
- This software may be used and distributed according to the terms
- of the GNU Public License, incorporated herein by reference.
-
- The author may be reached as becker@CESDIS.gsfc.nasa.gov, or C/O
- Center of Excellence in Space Data and Information Sciences
- Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
-
- The timer-based reset code was written by Bill Carlson, wwc@super.org.
-*/
-
-static const char *version =
- "atp.c:v1.01 1/18/95 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
-
-/*
- This file is a device driver for the RealTek (aka AT-Lan-Tec) pocket
- ethernet adapter. This is a common low-cost OEM pocket ethernet
- adapter, sold under many names.
-
- Sources:
- This driver was written from the packet driver assembly code provided by
- Vincent Bono of AT-Lan-Tec. Ever try to figure out how a complicated
- device works just from the assembly code? It ain't pretty. The following
- description is written based on guesses and writing lots of special-purpose
- code to test my theorized operation.
-
- Theory of Operation
-
- The RTL8002 adapter seems to be built around a custom spin of the SEEQ
- controller core. It probably has a 16K or 64K internal packet buffer, of
- which the first 4K is devoted to transmit and the rest to receive.
- The controller maintains the queue of received packet and the packet buffer
- access pointer internally, with only 'reset to beginning' and 'skip to next
- packet' commands visible. The transmit packet queue holds two (or more?)
- packets: both 'retransmit this packet' (due to collision) and 'transmit next
- packet' commands must be started by hand.
-
- The station address is stored in a standard bit-serial EEPROM which must be
- read (ughh) by the device driver. (Provisions have been made for
- substituting a 74S288 PROM, but I haven't gotten reports of any models
- using it.) Unlike built-in devices, a pocket adapter can temporarily lose
- power without indication to the device driver. The major effect is that
- the station address, receive filter (promiscuous, etc.) and transceiver
- must be reset.
-
- The controller itself has 16 registers, some of which use only the lower
- bits. The registers are read and written 4 bits at a time. The four bit
- register address is presented on the data lines along with a few additional
- timing and control bits. The data is then read from status port or written
- to the data port.
-
- Since the bulk data transfer of the actual packets through the slow
- parallel port dominates the driver's running time, four distinct data
- (non-register) transfer modes are provided by the adapter, two in each
- direction. In the first mode timing for the nibble transfers is
- provided through the data port. In the second mode the same timing is
- provided through the control port. In either case the data is read from
- the status port and written to the data port, just as it is accessing
- registers.
-
- In addition to the basic data transfer methods, several more are modes are
- created by adding some delay by doing multiple reads of the data to allow
- it to stabilize. This delay seems to be needed on most machines.
-
- The data transfer mode is stored in the 'dev->if_port' field. Its default
- value is '4'. It may be overridden at boot-time using the third parameter
- to the "ether=..." initialization.
-
- The header file <atp.h> provides inline functions that encapsulate the
- register and data access methods. These functions are hand-tuned to
- generate reasonable object code. This header file also documents my
- interpretations of the device registers.
-*/
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ptrace.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/malloc.h>
-#include <linux/string.h>
-#include <asm/system.h>
-#include <asm/bitops.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <linux/errno.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-
-#include "atp.h"
-
-/* use 0 for production, 1 for verification, >2 for debug */
-#ifndef NET_DEBUG
-#define NET_DEBUG 1
-#endif
-static unsigned int net_debug = NET_DEBUG;
-
-/* The number of low I/O ports used by the ethercard. */
-#define ETHERCARD_TOTAL_SIZE 3
-
-/* This code, written by wwc@super.org, resets the adapter every
- TIMED_CHECKER ticks. This recovers from an unknown error which
- hangs the device. */
-#define TIMED_CHECKER (HZ/4)
-#ifdef TIMED_CHECKER
-#include <linux/timer.h>
-static void atp_timed_checker(unsigned long ignored);
-static struct device *atp_timed_dev;
-static struct timer_list atp_timer = {NULL, NULL, 0, 0, atp_timed_checker};
-#endif
-
-/* Index to functions, as function prototypes. */
-
-extern int atp_probe(struct device *dev);
-
-static int atp_probe1(struct device *dev, short ioaddr);
-static void get_node_ID(struct device *dev);
-static unsigned short eeprom_op(short ioaddr, unsigned int cmd);
-static int net_open(struct device *dev);
-static void hardware_init(struct device *dev);
-static void write_packet(short ioaddr, int length, unsigned char *packet, int mode);
-static void trigger_send(short ioaddr, int length);
-static int net_send_packet(struct sk_buff *skb, struct device *dev);
-static void net_interrupt(int irq, struct pt_regs *regs);
-static void net_rx(struct device *dev);
-static void read_block(short ioaddr, int length, unsigned char *buffer, int data_mode);
-static int net_close(struct device *dev);
-static struct enet_statistics *net_get_stats(struct device *dev);
-static void set_multicast_list(struct device *dev);
-
-
-/* Check for a network adapter of this type, and return '0' iff one exists.
- If dev->base_addr == 0, probe all likely locations.
- If dev->base_addr == 1, always return failure.
- If dev->base_addr == 2, allocate space for the device and return success
- (detachable devices only).
- */
-int
-atp_init(struct device *dev)
-{
- int *port, ports[] = {0x378, 0x278, 0x3bc, 0};
- int base_addr = dev->base_addr;
-
- if (base_addr > 0x1ff) /* Check a single specified location. */
- return atp_probe1(dev, base_addr);
- else if (base_addr == 1) /* Don't probe at all. */
- return ENXIO;
-
- for (port = ports; *port; port++) {
- int ioaddr = *port;
- outb(0x57, ioaddr + PAR_DATA);
- if (inb(ioaddr + PAR_DATA) != 0x57)
- continue;
- if (atp_probe1(dev, ioaddr) == 0)
- return 0;
- }
-
- return ENODEV;
-}
-
-static int atp_probe1(struct device *dev, short ioaddr)
-{
- int saved_ctrl_reg, status;
-
- outb(0xff, ioaddr + PAR_DATA);
- /* Save the original value of the Control register, in case we guessed
- wrong. */
- saved_ctrl_reg = inb(ioaddr + PAR_CONTROL);
- /* IRQEN=0, SLCTB=high INITB=high, AUTOFDB=high, STBB=high. */
- outb(0x04, ioaddr + PAR_CONTROL);
- write_reg_high(ioaddr, CMR1, CMR1h_RESET);
- eeprom_delay(2048);
- status = read_nibble(ioaddr, CMR1);
-
- if ((status & 0x78) != 0x08) {
- /* The pocket adapter probe failed, restore the control register. */
- outb(saved_ctrl_reg, ioaddr + PAR_CONTROL);
- return 1;
- }
- status = read_nibble(ioaddr, CMR2_h);
- if ((status & 0x78) != 0x10) {
- outb(saved_ctrl_reg, ioaddr + PAR_CONTROL);
- return 1;
- }
- /* Find the IRQ used by triggering an interrupt. */
- write_reg_byte(ioaddr, CMR2, 0x01); /* No accept mode, IRQ out. */
- write_reg_high(ioaddr, CMR1, CMR1h_RxENABLE | CMR1h_TxENABLE); /* Enable Tx and Rx. */
-
- /* Omit autoIRQ routine for now. Use "table lookup" instead. Uhgggh. */
- if (ioaddr == 0x378)
- dev->irq = 7;
- else
- dev->irq = 5;
- write_reg_high(ioaddr, CMR1, CMR1h_TxRxOFF); /* Disable Tx and Rx units. */
- write_reg(ioaddr, CMR2, CMR2_NULL);
-
- dev->base_addr = ioaddr;
-
- /* Read the station address PROM. */
- get_node_ID(dev);
-
- printk("%s: Pocket adapter found at %#3lx, IRQ %d, SAPROM "
- "%02X:%02X:%02X:%02X:%02X:%02X.\n", dev->name, dev->base_addr,
- dev->irq, dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
- dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
-
- /* Leave the hardware in a reset state. */
- write_reg_high(ioaddr, CMR1, CMR1h_RESET);
-
- if (net_debug)
- printk(version);
-
- /* Initialize the device structure. */
- ether_setup(dev);
- dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
- if (dev->priv == NULL)
- return -ENOMEM;
- memset(dev->priv, 0, sizeof(struct net_local));
-
-
- {
- struct net_local *lp = (struct net_local *)dev->priv;
- lp->addr_mode = CMR2h_Normal;
- }
-
- /* For the ATP adapter the "if_port" is really the data transfer mode. */
- dev->if_port = (dev->mem_start & 0xf) ? dev->mem_start & 0x7 : 4;
- if (dev->mem_end & 0xf)
- net_debug = dev->mem_end & 7;
-
- dev->open = net_open;
- dev->stop = net_close;
- dev->hard_start_xmit = net_send_packet;
- dev->get_stats = net_get_stats;
- dev->set_multicast_list = &set_multicast_list;
-
-#ifdef TIMED_CHECKER
- del_timer(&atp_timer);
- atp_timer.expires = jiffies + TIMED_CHECKER;
- atp_timed_dev = dev;
- add_timer(&atp_timer);
-#endif
- return 0;
-}
-
-/* Read the station address PROM, usually a word-wide EEPROM. */
-static void get_node_ID(struct device *dev)
-{
- short ioaddr = dev->base_addr;
- int sa_offset = 0;
- int i;
-
- write_reg(ioaddr, CMR2, CMR2_EEPROM); /* Point to the EEPROM control registers. */
-
- /* Some adapters have the station address at offset 15 instead of offset
- zero. Check for it, and fix it if needed. */
- if (eeprom_op(ioaddr, EE_READ(0)) == 0xffff)
- sa_offset = 15;
-
- for (i = 0; i < 3; i++)
- ((unsigned short *)dev->dev_addr)[i] =
- ntohs(eeprom_op(ioaddr, EE_READ(sa_offset + i)));
-
- write_reg(ioaddr, CMR2, CMR2_NULL);
-}
-
-/*
- An EEPROM read command starts by shifting out 0x60+address, and then
- shifting in the serial data. See the NatSemi databook for details.
- * ________________
- * CS : __|
- * ___ ___
- * CLK: ______| |___| |
- * __ _______ _______
- * DI : __X_______X_______X
- * DO : _________X_______X
- */
-
-static unsigned short eeprom_op(short ioaddr, unsigned int cmd)
-{
- unsigned eedata_out = 0;
- int num_bits = EE_CMD_SIZE;
-
- while (--num_bits >= 0) {
- char outval = test_bit(num_bits, &cmd) ? EE_DATA_WRITE : 0;
- write_reg_high(ioaddr, PROM_CMD, outval | EE_CLK_LOW);
- eeprom_delay(5);
- write_reg_high(ioaddr, PROM_CMD, outval | EE_CLK_HIGH);
- eedata_out <<= 1;
- if (read_nibble(ioaddr, PROM_DATA) & EE_DATA_READ)
- eedata_out++;
- eeprom_delay(5);
- }
- write_reg_high(ioaddr, PROM_CMD, EE_CLK_LOW & ~EE_CS);
- return eedata_out;
-}
-
-
-/* Open/initialize the board. This is called (in the current kernel)
- sometime after booting when the 'ifconfig' program is run.
-
- This routine sets everything up anew at each open, even
- registers that "should" only need to be set once at boot, so that
- there is non-reboot way to recover if something goes wrong.
-
- This is an attachable device: if there is no dev->priv entry then it wasn't
- probed for at boot-time, and we need to probe for it again.
- */
-static int net_open(struct device *dev)
-{
-
- /* The interrupt line is turned off (tri-stated) when the device isn't in
- use. That's especially important for "attached" interfaces where the
- port or interrupt may be shared. */
- if (irq2dev_map[dev->irq] != 0
- || (irq2dev_map[dev->irq] = dev) == 0
- || request_irq(dev->irq, &net_interrupt, 0, "ATP")) {
- return -EAGAIN;
- }
-
- hardware_init(dev);
- dev->start = 1;
- return 0;
-}
-
-/* This routine resets the hardware. We initialize everything, assuming that
- the hardware may have been temporarily detached. */
-static void hardware_init(struct device *dev)
-{
- struct net_local *lp = (struct net_local *)dev->priv;
- int ioaddr = dev->base_addr;
- int i;
-
- write_reg_high(ioaddr, CMR1, CMR1h_RESET);
-
- for (i = 0; i < 6; i++)
- write_reg_byte(ioaddr, PAR0 + i, dev->dev_addr[i]);
-
- write_reg_high(ioaddr, CMR2, lp->addr_mode);
-
- if (net_debug > 2) {
- printk("%s: Reset: current Rx mode %d.\n", dev->name,
- (read_nibble(ioaddr, CMR2_h) >> 3) & 0x0f);
- }
-
- write_reg(ioaddr, CMR2, CMR2_IRQOUT);
- write_reg_high(ioaddr, CMR1, CMR1h_RxENABLE | CMR1h_TxENABLE);
-
- /* Enable the interrupt line from the serial port. */
- outb(Ctrl_SelData + Ctrl_IRQEN, ioaddr + PAR_CONTROL);
-
- /* Unmask the interesting interrupts. */
- write_reg(ioaddr, IMR, ISR_RxOK | ISR_TxErr | ISR_TxOK);
- write_reg_high(ioaddr, IMR, ISRh_RxErr);
-
- lp->tx_unit_busy = 0;
- lp->pac_cnt_in_tx_buf = 0;
- lp->saved_tx_size = 0;
-
- dev->tbusy = 0;
- dev->interrupt = 0;
-}
-
-static void trigger_send(short ioaddr, int length)
-{
- write_reg_byte(ioaddr, TxCNT0, length & 0xff);
- write_reg(ioaddr, TxCNT1, length >> 8);
- write_reg(ioaddr, CMR1, CMR1_Xmit);
-}
-
-static void write_packet(short ioaddr, int length, unsigned char *packet, int data_mode)
-{
- length = (length + 1) & ~1; /* Round up to word length. */
- outb(EOC+MAR, ioaddr + PAR_DATA);
- if ((data_mode & 1) == 0) {
- /* Write the packet out, starting with the write addr. */
- outb(WrAddr+MAR, ioaddr + PAR_DATA);
- do {
- write_byte_mode0(ioaddr, *packet++);
- } while (--length > 0) ;
- } else {
- /* Write the packet out in slow mode. */
- unsigned char outbyte = *packet++;
-
- outb(Ctrl_LNibWrite + Ctrl_IRQEN, ioaddr + PAR_CONTROL);
- outb(WrAddr+MAR, ioaddr + PAR_DATA);
-
- outb((outbyte & 0x0f)|0x40, ioaddr + PAR_DATA);
- outb(outbyte & 0x0f, ioaddr + PAR_DATA);
- outbyte >>= 4;
- outb(outbyte & 0x0f, ioaddr + PAR_DATA);
- outb(Ctrl_HNibWrite + Ctrl_IRQEN, ioaddr + PAR_CONTROL);
- while (--length > 0)
- write_byte_mode1(ioaddr, *packet++);
- }
- /* Terminate the Tx frame. End of write: ECB. */
- outb(0xff, ioaddr + PAR_DATA);
- outb(Ctrl_HNibWrite | Ctrl_SelData | Ctrl_IRQEN, ioaddr + PAR_CONTROL);
-}
-
-static int
-net_send_packet(struct sk_buff *skb, struct device *dev)
-{
- struct net_local *lp = (struct net_local *)dev->priv;
- int ioaddr = dev->base_addr;
-
- if (dev->tbusy) {
- /* If we get here, some higher level has decided we are broken.
- There should really be a "kick me" function call instead. */
- int tickssofar = jiffies - dev->trans_start;
- if (tickssofar < 5)
- return 1;
- printk("%s: transmit timed out, %s?\n", dev->name,
- inb(ioaddr + PAR_CONTROL) & 0x10 ? "network cable problem"
- : "IRQ conflict");
- lp->stats.tx_errors++;
- /* Try to restart the adapter. */
- hardware_init(dev);
- dev->tbusy=0;
- dev->trans_start = jiffies;
- }
-
- /* If some higher layer thinks we've missed an tx-done interrupt
- we are passed NULL. Caution: dev_tint() handles the cli()/sti()
- itself. */
- if (skb == NULL) {
- dev_tint(dev);
- return 0;
- }
-
- /* Block a timer-based transmit from overlapping. This could better be
- done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
- if (set_bit(0, (void*)&dev->tbusy) != 0)
- printk("%s: Transmitter access conflict.\n", dev->name);
- else {
- short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
- unsigned char *buf = skb->data;
- int flags;
-
- /* Disable interrupts by writing 0x00 to the Interrupt Mask Register.
- This sequence must not be interrupted by an incoming packet. */
- save_flags(flags);
- cli();
- write_reg(ioaddr, IMR, 0);
- write_reg_high(ioaddr, IMR, 0);
- restore_flags(flags);
-
- write_packet(ioaddr, length, buf, dev->if_port);
-
- lp->pac_cnt_in_tx_buf++;
- if (lp->tx_unit_busy == 0) {
- trigger_send(ioaddr, length);
- lp->saved_tx_size = 0; /* Redundant */
- lp->re_tx = 0;
- lp->tx_unit_busy = 1;
- } else
- lp->saved_tx_size = length;
-
- dev->trans_start = jiffies;
- /* Re-enable the LPT interrupts. */
- write_reg(ioaddr, IMR, ISR_RxOK | ISR_TxErr | ISR_TxOK);
- write_reg_high(ioaddr, IMR, ISRh_RxErr);
- }
-
- dev_kfree_skb (skb, FREE_WRITE);
-
- return 0;
-}
-
-/* The typical workload of the driver:
- Handle the network interface interrupts. */
-static void
-net_interrupt(int irq, struct pt_regs * regs)
-{
- struct device *dev = (struct device *)(irq2dev_map[irq]);
- struct net_local *lp;
- int ioaddr, status, boguscount = 20;
- static int num_tx_since_rx = 0;
-
- if (dev == NULL) {
- printk ("ATP_interrupt(): irq %d for unknown device.\n", irq);
- return;
- }
- dev->interrupt = 1;
-
- ioaddr = dev->base_addr;
- lp = (struct net_local *)dev->priv;
-
- /* Disable additional spurious interrupts. */
- outb(Ctrl_SelData, ioaddr + PAR_CONTROL);
-
- /* The adapter's output is currently the IRQ line, switch it to data. */
- write_reg(ioaddr, CMR2, CMR2_NULL);
- write_reg(ioaddr, IMR, 0);
-
- if (net_debug > 5) printk("%s: In interrupt ", dev->name);
- while (--boguscount > 0) {
- status = read_nibble(ioaddr, ISR);
- if (net_debug > 5) printk("loop status %02x..", status);
-
- if (status & (ISR_RxOK<<3)) {
- write_reg(ioaddr, ISR, ISR_RxOK); /* Clear the Rx interrupt. */
- do {
- int read_status = read_nibble(ioaddr, CMR1);
- if (net_debug > 6)
- printk("handling Rx packet %02x..", read_status);
- /* We acknowledged the normal Rx interrupt, so if the interrupt
- is still outstanding we must have a Rx error. */
- if (read_status & (CMR1_IRQ << 3)) { /* Overrun. */
- lp->stats.rx_over_errors++;
- /* Set to no-accept mode long enough to remove a packet. */
- write_reg_high(ioaddr, CMR2, CMR2h_OFF);
- net_rx(dev);
- /* Clear the interrupt and return to normal Rx mode. */
- write_reg_high(ioaddr, ISR, ISRh_RxErr);
- write_reg_high(ioaddr, CMR2, lp->addr_mode);
- } else if ((read_status & (CMR1_BufEnb << 3)) == 0) {
- net_rx(dev);
- dev->last_rx = jiffies;
- num_tx_since_rx = 0;
- } else
- break;
- } while (--boguscount > 0);
- } else if (status & ((ISR_TxErr + ISR_TxOK)<<3)) {
- if (net_debug > 6) printk("handling Tx done..");
- /* Clear the Tx interrupt. We should check for too many failures
- and reinitialize the adapter. */
- write_reg(ioaddr, ISR, ISR_TxErr + ISR_TxOK);
- if (status & (ISR_TxErr<<3)) {
- lp->stats.collisions++;
- if (++lp->re_tx > 15) {
- lp->stats.tx_aborted_errors++;
- hardware_init(dev);
- break;
- }
- /* Attempt to retransmit. */
- if (net_debug > 6) printk("attempting to ReTx");
- write_reg(ioaddr, CMR1, CMR1_ReXmit + CMR1_Xmit);
- } else {
- /* Finish up the transmit. */
- lp->stats.tx_packets++;
- lp->pac_cnt_in_tx_buf--;
- if ( lp->saved_tx_size) {
- trigger_send(ioaddr, lp->saved_tx_size);
- lp->saved_tx_size = 0;
- lp->re_tx = 0;
- } else
- lp->tx_unit_busy = 0;
- dev->tbusy = 0;
- mark_bh(NET_BH); /* Inform upper layers. */
- }
- num_tx_since_rx++;
- } else if (num_tx_since_rx > 8
- && jiffies > dev->last_rx + 100) {
- if (net_debug > 2)
- printk("%s: Missed packet? No Rx after %d Tx and %ld jiffies"
- " status %02x CMR1 %02x.\n", dev->name,
- num_tx_since_rx, jiffies - dev->last_rx, status,
- (read_nibble(ioaddr, CMR1) >> 3) & 15);
- lp->stats.rx_missed_errors++;
- hardware_init(dev);
- num_tx_since_rx = 0;
- break;
- } else
- break;
- }
-
- /* This following code fixes a rare (and very difficult to track down)
- problem where the adapter forgets its ethernet address. */
- {
- int i;
- for (i = 0; i < 6; i++)
- write_reg_byte(ioaddr, PAR0 + i, dev->dev_addr[i]);
-#ifdef TIMED_CHECKER
- del_timer(&atp_timer);
- atp_timer.expires = jiffies + TIMED_CHECKER;
- add_timer(&atp_timer);
-#endif
- }
-
- /* Tell the adapter that it can go back to using the output line as IRQ. */
- write_reg(ioaddr, CMR2, CMR2_IRQOUT);
- /* Enable the physical interrupt line, which is sure to be low until.. */
- outb(Ctrl_SelData + Ctrl_IRQEN, ioaddr + PAR_CONTROL);
- /* .. we enable the interrupt sources. */
- write_reg(ioaddr, IMR, ISR_RxOK | ISR_TxErr | ISR_TxOK);
- write_reg_high(ioaddr, IMR, ISRh_RxErr); /* Hmmm, really needed? */
-
- if (net_debug > 5) printk("exiting interrupt.\n");
-
- dev->interrupt = 0;
-
- return;
-}
-
-#ifdef TIMED_CHECKER
-/* This following code fixes a rare (and very difficult to track down)
- problem where the adapter forgets its ethernet address. */
-static void atp_timed_checker(unsigned long ignored)
-{
- int i;
- int ioaddr = atp_timed_dev->base_addr;
-
- if (!atp_timed_dev->interrupt)
- {
- for (i = 0; i < 6; i++)
-#if 0
- if (read_cmd_byte(ioaddr, PAR0 + i) != atp_timed_dev->dev_addr[i])
- {
- struct net_local *lp = (struct net_local *)atp_timed_dev->priv;
- write_reg_byte(ioaddr, PAR0 + i, atp_timed_dev->dev_addr[i]);
- if (i == 2)
- lp->stats.tx_errors++;
- else if (i == 3)
- lp->stats.tx_dropped++;
- else if (i == 4)
- lp->stats.collisions++;
- else
- lp->stats.rx_errors++;
- }
-#else
- write_reg_byte(ioaddr, PAR0 + i, atp_timed_dev->dev_addr[i]);
-#endif
- }
- del_timer(&atp_timer);
- atp_timer.expires = jiffies + TIMED_CHECKER;
- add_timer(&atp_timer);
-}
-#endif
-
-/* We have a good packet(s), get it/them out of the buffers. */
-static void net_rx(struct device *dev)
-{
- struct net_local *lp = (struct net_local *)dev->priv;
- int ioaddr = dev->base_addr;
-#ifdef notdef
- ushort header[4];
-#else
- struct rx_header rx_head;
-#endif
-
- /* Process the received packet. */
- outb(EOC+MAR, ioaddr + PAR_DATA);
- read_block(ioaddr, 8, (unsigned char*)&rx_head, dev->if_port);
- if (net_debug > 5)
- printk(" rx_count %04x %04x %04x %04x..", rx_head.pad,
- rx_head.rx_count, rx_head.rx_status, rx_head.cur_addr);
- if ((rx_head.rx_status & 0x77) != 0x01) {
- lp->stats.rx_errors++;
- /* Ackkk! I don't have any documentation on what the error bits mean!
- The best I can do is slap the device around a bit. */
- if (net_debug > 3) printk("%s: Unknown ATP Rx error %04x.\n",
- dev->name, rx_head.rx_status);
- hardware_init(dev);
- return;
- } else {
- /* Malloc up new buffer. */
- int pkt_len = (rx_head.rx_count & 0x7ff) - 4; /* The "-4" is omits the FCS (CRC). */
- struct sk_buff *skb;
-
- skb = dev_alloc_skb(pkt_len);
- if (skb == NULL) {
- printk("%s: Memory squeeze, dropping packet.\n", dev->name);
- lp->stats.rx_dropped++;
- goto done;
- }
- skb->dev = dev;
-
- read_block(ioaddr, pkt_len, skb_put(skb,pkt_len), dev->if_port);
-
- if (net_debug > 6) {
- unsigned char *data = skb->data;
- printk(" data %02x%02x%02x %02x%02x%02x %02x%02x%02x"
- "%02x%02x%02x %02x%02x..",
- data[0], data[1], data[2], data[3], data[4], data[5],
- data[6], data[7], data[8], data[9], data[10], data[11],
- data[12], data[13]);
- }
-
- skb->protocol=eth_type_trans(skb,dev);
- netif_rx(skb);
- lp->stats.rx_packets++;
- }
- done:
- write_reg(ioaddr, CMR1, CMR1_NextPkt);
- return;
-}
-
-static void read_block(short ioaddr, int length, unsigned char *p, int data_mode)
-{
-
- if (data_mode <= 3) { /* Mode 0 or 1 */
- outb(Ctrl_LNibRead, ioaddr + PAR_CONTROL);
- outb(length == 8 ? RdAddr | HNib | MAR : RdAddr | MAR,
- ioaddr + PAR_DATA);
- if (data_mode <= 1) { /* Mode 0 or 1 */
- do *p++ = read_byte_mode0(ioaddr); while (--length > 0);
- } else /* Mode 2 or 3 */
- do *p++ = read_byte_mode2(ioaddr); while (--length > 0);
- } else if (data_mode <= 5)
- do *p++ = read_byte_mode4(ioaddr); while (--length > 0);
- else
- do *p++ = read_byte_mode6(ioaddr); while (--length > 0);
-
- outb(EOC+HNib+MAR, ioaddr + PAR_DATA);
- outb(Ctrl_SelData, ioaddr + PAR_CONTROL);
-}
-
-/* The inverse routine to net_open(). */
-static int
-net_close(struct device *dev)
-{
- struct net_local *lp = (struct net_local *)dev->priv;
- int ioaddr = dev->base_addr;
-
- dev->tbusy = 1;
- dev->start = 0;
-
- /* Flush the Tx and disable Rx here. */
- lp->addr_mode = CMR2h_OFF;
- write_reg_high(ioaddr, CMR2, CMR2h_OFF);
-
- /* Free the IRQ line. */
- outb(0x00, ioaddr + PAR_CONTROL);
- free_irq(dev->irq);
- irq2dev_map[dev->irq] = 0;
-
- /* Leave the hardware in a reset state. */
- write_reg_high(ioaddr, CMR1, CMR1h_RESET);
-
- return 0;
-}
-
-/* Get the current statistics. This may be called with the card open or
- closed. */
-static struct enet_statistics *
-net_get_stats(struct device *dev)
-{
- struct net_local *lp = (struct net_local *)dev->priv;
- return &lp->stats;
-}
-
-/*
- * Set or clear the multicast filter for this adapter.
- */
-
-static void set_multicast_list(struct device *dev)
-{
- struct net_local *lp = (struct net_local *)dev->priv;
- short ioaddr = dev->base_addr;
- int num_addrs=dev->mc_list;
-
- if(dev->flags&(IFF_ALLMULTI|IFF_PROMISC))
- num_addrs=1;
- /*
- * We must make the kernel realise we had to move
- * into promisc mode or we start all out war on
- * the cable. - AC
- */
- if(num_addrs)
- dev->flags|=IFF_PROMISC;
- lp->addr_mode = num_addrs ? CMR2h_PROMISC : CMR2h_Normal;
- write_reg_high(ioaddr, CMR2, lp->addr_mode);
-}
-
-/*
- * Local variables:
- * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c atp.c"
- * version-control: t
- * kept-new-versions: 5
- * tab-width: 4
- * End:
- */
diff --git a/i386/i386at/gpl/linux/net/atp.h b/i386/i386at/gpl/linux/net/atp.h
deleted file mode 100644
index e58f8c10..00000000
--- a/i386/i386at/gpl/linux/net/atp.h
+++ /dev/null
@@ -1,264 +0,0 @@
-#include <linux/if_ether.h>
-#include <linux/types.h>
-#include <asm/io.h>
-
-struct net_local {
-#ifdef __KERNEL__
- struct enet_statistics stats;
-#endif
- ushort saved_tx_size;
- unsigned char
- re_tx, /* Number of packet retransmissions. */
- tx_unit_busy,
- addr_mode, /* Current Rx filter e.g. promiscuous, etc. */
- pac_cnt_in_tx_buf;
-};
-
-struct rx_header {
- ushort pad; /* The first read is always corrupted. */
- ushort rx_count;
- ushort rx_status; /* Unknown bit assignments :-<. */
- ushort cur_addr; /* Apparently the current buffer address(?) */
-};
-
-#define PAR_DATA 0
-#define PAR_STATUS 1
-#define PAR_CONTROL 2
-
-#define Ctrl_LNibRead 0x08 /* LP_PSELECP */
-#define Ctrl_HNibRead 0
-#define Ctrl_LNibWrite 0x08 /* LP_PSELECP */
-#define Ctrl_HNibWrite 0
-#define Ctrl_SelData 0x04 /* LP_PINITP */
-#define Ctrl_IRQEN 0x10 /* LP_PINTEN */
-
-#define EOW 0xE0
-#define EOC 0xE0
-#define WrAddr 0x40 /* Set address of EPLC read, write register. */
-#define RdAddr 0xC0
-#define HNib 0x10
-
-enum page0_regs
-{
- /* The first six registers hold the ethernet physical station address. */
- PAR0 = 0, PAR1 = 1, PAR2 = 2, PAR3 = 3, PAR4 = 4, PAR5 = 5,
- TxCNT0 = 6, TxCNT1 = 7, /* The transmit byte count. */
- TxSTAT = 8, RxSTAT = 9, /* Tx and Rx status. */
- ISR = 10, IMR = 11, /* Interrupt status and mask. */
- CMR1 = 12, /* Command register 1. */
- CMR2 = 13, /* Command register 2. */
- MAR = 14, /* Memory address register. */
- CMR2_h = 0x1d, };
-
-enum eepage_regs
-{ PROM_CMD = 6, PROM_DATA = 7 }; /* Note that PROM_CMD is in the "high" bits. */
-
-
-#define ISR_TxOK 0x01
-#define ISR_RxOK 0x04
-#define ISR_TxErr 0x02
-#define ISRh_RxErr 0x11 /* ISR, high nibble */
-
-#define CMR1h_RESET 0x04 /* Reset. */
-#define CMR1h_RxENABLE 0x02 /* Rx unit enable. */
-#define CMR1h_TxENABLE 0x01 /* Tx unit enable. */
-#define CMR1h_TxRxOFF 0x00
-#define CMR1_ReXmit 0x08 /* Trigger a retransmit. */
-#define CMR1_Xmit 0x04 /* Trigger a transmit. */
-#define CMR1_IRQ 0x02 /* Interrupt active. */
-#define CMR1_BufEnb 0x01 /* Enable the buffer(?). */
-#define CMR1_NextPkt 0x01 /* Enable the buffer(?). */
-
-#define CMR2_NULL 8
-#define CMR2_IRQOUT 9
-#define CMR2_RAMTEST 10
-#define CMR2_EEPROM 12 /* Set to page 1, for reading the EEPROM. */
-
-#define CMR2h_OFF 0 /* No accept mode. */
-#define CMR2h_Physical 1 /* Accept a physical address match only. */
-#define CMR2h_Normal 2 /* Accept physical and broadcast address. */
-#define CMR2h_PROMISC 3 /* Promiscuous mode. */
-
-/* An inline function used below: it differs from inb() by explicitly return an unsigned
- char, saving a truncation. */
-extern inline unsigned char inbyte(unsigned short port)
-{
- unsigned char _v;
- __asm__ __volatile__ ("inb %w1,%b0" :"=a" (_v):"d" (port));
- return _v;
-}
-
-/* Read register OFFSET.
- This command should always be terminated with read_end(). */
-extern inline unsigned char read_nibble(short port, unsigned char offset)
-{
- unsigned char retval;
- outb(EOC+offset, port + PAR_DATA);
- outb(RdAddr+offset, port + PAR_DATA);
- inbyte(port + PAR_STATUS); /* Settling time delay */
- retval = inbyte(port + PAR_STATUS);
- outb(EOC+offset, port + PAR_DATA);
-
- return retval;
-}
-
-/* Functions for bulk data read. The interrupt line is always disabled. */
-/* Get a byte using read mode 0, reading data from the control lines. */
-extern inline unsigned char read_byte_mode0(short ioaddr)
-{
- unsigned char low_nib;
-
- outb(Ctrl_LNibRead, ioaddr + PAR_CONTROL);
- inbyte(ioaddr + PAR_STATUS);
- low_nib = (inbyte(ioaddr + PAR_STATUS) >> 3) & 0x0f;
- outb(Ctrl_HNibRead, ioaddr + PAR_CONTROL);
- inbyte(ioaddr + PAR_STATUS); /* Settling time delay -- needed! */
- inbyte(ioaddr + PAR_STATUS); /* Settling time delay -- needed! */
- return low_nib | ((inbyte(ioaddr + PAR_STATUS) << 1) & 0xf0);
-}
-
-/* The same as read_byte_mode0(), but does multiple inb()s for stability. */
-extern inline unsigned char read_byte_mode2(short ioaddr)
-{
- unsigned char low_nib;
-
- outb(Ctrl_LNibRead, ioaddr + PAR_CONTROL);
- inbyte(ioaddr + PAR_STATUS);
- low_nib = (inbyte(ioaddr + PAR_STATUS) >> 3) & 0x0f;
- outb(Ctrl_HNibRead, ioaddr + PAR_CONTROL);
- inbyte(ioaddr + PAR_STATUS); /* Settling time delay -- needed! */
- return low_nib | ((inbyte(ioaddr + PAR_STATUS) << 1) & 0xf0);
-}
-
-/* Read a byte through the data register. */
-extern inline unsigned char read_byte_mode4(short ioaddr)
-{
- unsigned char low_nib;
-
- outb(RdAddr | MAR, ioaddr + PAR_DATA);
- low_nib = (inbyte(ioaddr + PAR_STATUS) >> 3) & 0x0f;
- outb(RdAddr | HNib | MAR, ioaddr + PAR_DATA);
- return low_nib | ((inbyte(ioaddr + PAR_STATUS) << 1) & 0xf0);
-}
-
-/* Read a byte through the data register, double reading to allow settling. */
-extern inline unsigned char read_byte_mode6(short ioaddr)
-{
- unsigned char low_nib;
-
- outb(RdAddr | MAR, ioaddr + PAR_DATA);
- inbyte(ioaddr + PAR_STATUS);
- low_nib = (inbyte(ioaddr + PAR_STATUS) >> 3) & 0x0f;
- outb(RdAddr | HNib | MAR, ioaddr + PAR_DATA);
- inbyte(ioaddr + PAR_STATUS);
- return low_nib | ((inbyte(ioaddr + PAR_STATUS) << 1) & 0xf0);
-}
-
-extern inline void
-write_reg(short port, unsigned char reg, unsigned char value)
-{
- unsigned char outval;
- outb(EOC | reg, port + PAR_DATA);
- outval = WrAddr | reg;
- outb(outval, port + PAR_DATA);
- outb(outval, port + PAR_DATA); /* Double write for PS/2. */
-
- outval &= 0xf0;
- outval |= value;
- outb(outval, port + PAR_DATA);
- outval &= 0x1f;
- outb(outval, port + PAR_DATA);
- outb(outval, port + PAR_DATA);
-
- outb(EOC | outval, port + PAR_DATA);
-}
-
-extern inline void
-write_reg_high(short port, unsigned char reg, unsigned char value)
-{
- unsigned char outval = EOC | HNib | reg;
-
- outb(outval, port + PAR_DATA);
- outval &= WrAddr | HNib | 0x0f;
- outb(outval, port + PAR_DATA);
- outb(outval, port + PAR_DATA); /* Double write for PS/2. */
-
- outval = WrAddr | HNib | value;
- outb(outval, port + PAR_DATA);
- outval &= HNib | 0x0f; /* HNib | value */
- outb(outval, port + PAR_DATA);
- outb(outval, port + PAR_DATA);
-
- outb(EOC | HNib | outval, port + PAR_DATA);
-}
-
-/* Write a byte out using nibble mode. The low nibble is written first. */
-extern inline void
-write_reg_byte(short port, unsigned char reg, unsigned char value)
-{
- unsigned char outval;
- outb(EOC | reg, port + PAR_DATA); /* Reset the address register. */
- outval = WrAddr | reg;
- outb(outval, port + PAR_DATA);
- outb(outval, port + PAR_DATA); /* Double write for PS/2. */
-
- outb((outval & 0xf0) | (value & 0x0f), port + PAR_DATA);
- outb(value & 0x0f, port + PAR_DATA);
- value >>= 4;
- outb(value, port + PAR_DATA);
- outb(0x10 | value, port + PAR_DATA);
- outb(0x10 | value, port + PAR_DATA);
-
- outb(EOC | value, port + PAR_DATA); /* Reset the address register. */
-}
-
-/*
- * Bulk data writes to the packet buffer. The interrupt line remains enabled.
- * The first, faster method uses only the dataport (data modes 0, 2 & 4).
- * The second (backup) method uses data and control regs (modes 1, 3 & 5).
- * It should only be needed when there is skew between the individual data
- * lines.
- */
-extern inline void write_byte_mode0(short ioaddr, unsigned char value)
-{
- outb(value & 0x0f, ioaddr + PAR_DATA);
- outb((value>>4) | 0x10, ioaddr + PAR_DATA);
-}
-
-extern inline void write_byte_mode1(short ioaddr, unsigned char value)
-{
- outb(value & 0x0f, ioaddr + PAR_DATA);
- outb(Ctrl_IRQEN | Ctrl_LNibWrite, ioaddr + PAR_CONTROL);
- outb((value>>4) | 0x10, ioaddr + PAR_DATA);
- outb(Ctrl_IRQEN | Ctrl_HNibWrite, ioaddr + PAR_CONTROL);
-}
-
-/* Write 16bit VALUE to the packet buffer: the same as above just doubled. */
-extern inline void write_word_mode0(short ioaddr, unsigned short value)
-{
- outb(value & 0x0f, ioaddr + PAR_DATA);
- value >>= 4;
- outb((value & 0x0f) | 0x10, ioaddr + PAR_DATA);
- value >>= 4;
- outb(value & 0x0f, ioaddr + PAR_DATA);
- value >>= 4;
- outb((value & 0x0f) | 0x10, ioaddr + PAR_DATA);
-}
-
-/* EEPROM_Ctrl bits. */
-#define EE_SHIFT_CLK 0x04 /* EEPROM shift clock. */
-#define EE_CS 0x02 /* EEPROM chip select. */
-#define EE_CLK_HIGH 0x12
-#define EE_CLK_LOW 0x16
-#define EE_DATA_WRITE 0x01 /* EEPROM chip data in. */
-#define EE_DATA_READ 0x08 /* EEPROM chip data out. */
-
-/* Delay between EEPROM clock transitions. */
-#define eeprom_delay(ticks) \
-do { int _i = 40; while (--_i > 0) { __SLOW_DOWN_IO; }} while (0)
-
-/* The EEPROM commands include the alway-set leading bit. */
-#define EE_WRITE_CMD(offset) (((5 << 6) + (offset)) << 17)
-#define EE_READ(offset) (((6 << 6) + (offset)) << 17)
-#define EE_ERASE(offset) (((7 << 6) + (offset)) << 17)
-#define EE_CMD_SIZE 27 /* The command+address+data size. */
diff --git a/i386/i386at/gpl/linux/net/de4x5.c b/i386/i386at/gpl/linux/net/de4x5.c
deleted file mode 100644
index 249887a6..00000000
--- a/i386/i386at/gpl/linux/net/de4x5.c
+++ /dev/null
@@ -1,2788 +0,0 @@
-/* de4x5.c: A DIGITAL DE425/DE434/DE435/DE500 ethernet driver for Linux.
-
- Copyright 1994, 1995 Digital Equipment Corporation.
-
- This software may be used and distributed according to the terms of
- the GNU Public License, incorporated herein by reference.
-
- This driver is written for the Digital Equipment Corporation series
- of EtherWORKS ethernet cards:
-
- DE425 TP/COAX EISA
- DE434 TP PCI
- DE435 TP/COAX/AUI PCI
- DE500 10/100 PCI Fasternet
-
- The driver has been tested on a relatively busy network using the DE425,
- DE434, DE435 and DE500 cards and benchmarked with 'ttcp': it transferred
- 16M of data to a DECstation 5000/200 as follows:
-
- TCP UDP
- TX RX TX RX
- DE425 1030k 997k 1170k 1128k
- DE434 1063k 995k 1170k 1125k
- DE435 1063k 995k 1170k 1125k
- DE500 1063k 998k 1170k 1125k in 10Mb/s mode
-
- All values are typical (in kBytes/sec) from a sample of 4 for each
- measurement. Their error is +/-20k on a quiet (private) network and also
- depend on what load the CPU has.
-
- The author may be reached as davies@wanton.lkg.dec.com or Digital
- Equipment Corporation, 550 King Street, Littleton MA 01460.
-
- =========================================================================
- This driver has been written substantially from scratch, although its
- inheritance of style and stack interface from 'ewrk3.c' and in turn from
- Donald Becker's 'lance.c' should be obvious.
-
- Upto 15 EISA cards can be supported under this driver, limited primarily
- by the available IRQ lines. I have checked different configurations of
- multiple depca, EtherWORKS 3 cards and de4x5 cards and have not found a
- problem yet (provided you have at least depca.c v0.38) ...
-
- PCI support has been added to allow the driver to work with the DE434
- and DE435 cards. The I/O accesses are a bit of a kludge due to the
- differences in the EISA and PCI CSR address offsets from the base
- address.
-
- The ability to load this driver as a loadable module has been included
- and used extensively during the driver development (to save those long
- reboot sequences). Loadable module support under PCI has been achieved
- by letting any I/O address less than 0x1000 be assigned as:
-
- 0xghh
-
- where g is the bus number (usually 0 until the BIOS's get fixed)
- hh is the device number (max is 32 per bus).
-
- Essentially, the I/O address and IRQ information are ignored and filled
- in later by the PCI BIOS during the PCI probe. Note that the board
- should be in the system at boot time so that its I/O address and IRQ are
- allocated by the PCI BIOS automatically. The special case of device 0 on
- bus 0 is not allowed as the probe will think you're autoprobing a
- module.
-
- To utilise this ability, you have to do 8 things:
-
- 0) have a copy of the loadable modules code installed on your system.
- 1) copy de4x5.c from the /linux/drivers/net directory to your favourite
- temporary directory.
- 2) edit the source code near line 2762 to reflect the I/O address and
- IRQ you're using, or assign these when loading by:
-
- insmod de4x5.o irq=x io=y
-
- 3) compile de4x5.c, but include -DMODULE in the command line to ensure
- that the correct bits are compiled (see end of source code).
- 4) if you are wanting to add a new card, goto 5. Otherwise, recompile a
- kernel with the de4x5 configuration turned off and reboot.
- 5) insmod de4x5.o
- 6) run the net startup bits for your new eth?? interface manually
- (usually /etc/rc.inet[12] at boot time).
- 7) enjoy!
-
- Note that autoprobing is not allowed in loadable modules - the system is
- already up and running and you're messing with interrupts.
-
- To unload a module, turn off the associated interface
- 'ifconfig eth?? down' then 'rmmod de4x5'.
-
- Automedia detection is included so that in principal you can disconnect
- from, e.g. TP, reconnect to BNC and things will still work (after a
- pause whilst the driver figures out where its media went). My tests
- using ping showed that it appears to work....
-
- A compile time switch to allow Znyx recognition has been added. This
- "feature" is in no way supported nor tested in this driver and the user
- may use it at his/her sole discretion. I have had 2 conflicting reports
- that my driver will or won't work with Znyx. Try Donald Becker's
- 'tulip.c' if this driver doesn't work for you. I will not be supporting
- Znyx cards since I have no information on them and can't test them in a
- system.
-
- TO DO:
- ------
-
-
- Revision History
- ----------------
-
- Version Date Description
-
- 0.1 17-Nov-94 Initial writing. ALPHA code release.
- 0.2 13-Jan-95 Added PCI support for DE435's.
- 0.21 19-Jan-95 Added auto media detection.
- 0.22 10-Feb-95 Fix interrupt handler call <chris@cosy.sbg.ac.at>.
- Fix recognition bug reported by <bkm@star.rl.ac.uk>.
- Add request/release_region code.
- Add loadable modules support for PCI.
- Clean up loadable modules support.
- 0.23 28-Feb-95 Added DC21041 and DC21140 support.
- Fix missed frame counter value and initialisation.
- Fixed EISA probe.
- 0.24 11-Apr-95 Change delay routine to use <linux/udelay>.
- Change TX_BUFFS_AVAIL macro.
- Change media autodetection to allow manual setting.
- Completed DE500 (DC21140) support.
- 0.241 18-Apr-95 Interim release without DE500 Autosense Algorithm.
- 0.242 10-May-95 Minor changes
- 0.30 12-Jun-95 Timer fix for DC21140
- Portability changes.
- Add ALPHA changes from <jestabro@ant.tay1.dec.com>.
- Add DE500 semi automatic autosense.
- Add Link Fail interrupt TP failure detection.
- Add timer based link change detection.
- Plugged a memory leak in de4x5_queue_pkt().
- 0.31 13-Jun-95 Fixed PCI stuff for 1.3.1
- 0.32 26-Jun-95 Added verify_area() calls in de4x5_ioctl() from
- suggestion by <heiko@colossus.escape.de>
-
- =========================================================================
-*/
-
-static const char *version = "de4x5.c:v0.32 6/26/95 davies@wanton.lkg.dec.com\n";
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/interrupt.h>
-#include <linux/ptrace.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/malloc.h>
-#include <linux/bios32.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <asm/bitops.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <asm/segment.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-
-#include <linux/time.h>
-#include <linux/types.h>
-#include <linux/unistd.h>
-
-#include "de4x5.h"
-
-#ifdef DE4X5_DEBUG
-static int de4x5_debug = DE4X5_DEBUG;
-#else
-static int de4x5_debug = 1;
-#endif
-
-#ifdef DE4X5_AUTOSENSE /* Should be done on a per adapter basis */
-static int de4x5_autosense = DE4X5_AUTOSENSE;
-#else
-static int de4x5_autosense = AUTO; /* Do auto media/mode sensing */
-#endif
-
-#ifdef DE4X5_FULL_DUPLEX /* Should be done on a per adapter basis */
-static s32 de4x5_full_duplex = 1;
-#else
-static s32 de4x5_full_duplex = 0;
-#endif
-
-#define DE4X5_NDA 0xffe0 /* No Device (I/O) Address */
-
-/*
-** Ethernet PROM defines
-*/
-#define PROBE_LENGTH 32
-#define ETH_PROM_SIG 0xAA5500FFUL
-
-/*
-** Ethernet Info
-*/
-#define PKT_BUF_SZ 1536 /* Buffer size for each Tx/Rx buffer */
-#define MAX_PKT_SZ 1514 /* Maximum ethernet packet length */
-#define MAX_DAT_SZ 1500 /* Maximum ethernet data length */
-#define MIN_DAT_SZ 1 /* Minimum ethernet data length */
-#define PKT_HDR_LEN 14 /* Addresses and data length info */
-#define FAKE_FRAME_LEN (MAX_PKT_SZ + 1)
-#define QUEUE_PKT_TIMEOUT (3*HZ) /* 3 second timeout */
-
-
-#define CRC_POLYNOMIAL_BE 0x04c11db7UL /* Ethernet CRC, big endian */
-#define CRC_POLYNOMIAL_LE 0xedb88320UL /* Ethernet CRC, little endian */
-
-/*
-** EISA bus defines
-*/
-#define DE4X5_EISA_IO_PORTS 0x0c00 /* I/O port base address, slot 0 */
-#define DE4X5_EISA_TOTAL_SIZE 0xfff /* I/O address extent */
-
-#define MAX_EISA_SLOTS 16
-#define EISA_SLOT_INC 0x1000
-
-#define DE4X5_SIGNATURE {"DE425",""}
-#define DE4X5_NAME_LENGTH 8
-
-/*
-** PCI Bus defines
-*/
-#define PCI_MAX_BUS_NUM 8
-#define DE4X5_PCI_TOTAL_SIZE 0x80 /* I/O address extent */
-#define DE4X5_CLASS_CODE 0x00020000 /* Network controller, Ethernet */
-
-/*
-** Memory Alignment. Each descriptor is 4 longwords long. To force a
-** particular alignment on the TX descriptor, adjust DESC_SKIP_LEN and
-** DESC_ALIGN. ALIGN aligns the start address of the private memory area
-** and hence the RX descriptor ring's first entry.
-*/
-#define ALIGN4 ((u_long)4 - 1) /* 1 longword align */
-#define ALIGN8 ((u_long)8 - 1) /* 2 longword align */
-#define ALIGN16 ((u_long)16 - 1) /* 4 longword align */
-#define ALIGN32 ((u_long)32 - 1) /* 8 longword align */
-#define ALIGN64 ((u_long)64 - 1) /* 16 longword align */
-#define ALIGN128 ((u_long)128 - 1) /* 32 longword align */
-
-#define ALIGN ALIGN32 /* Keep the DC21040 happy... */
-#define CACHE_ALIGN CAL_16LONG
-#define DESC_SKIP_LEN DSL_0 /* Must agree with DESC_ALIGN */
-/*#define DESC_ALIGN u32 dummy[4]; / * Must agree with DESC_SKIP_LEN */
-#define DESC_ALIGN
-
-#ifdef MACH
-#define IS_NOT_DEC
-#endif
-
-#ifndef IS_NOT_DEC /* See README.de4x5 for using this */
-static int is_not_dec = 0;
-#else
-static int is_not_dec = 1;
-#endif
-
-/*
-** DE4X5 IRQ ENABLE/DISABLE
-*/
-#define ENABLE_IRQs { \
- imr |= lp->irq_en;\
- outl(imr, DE4X5_IMR); /* Enable the IRQs */\
-}
-
-#define DISABLE_IRQs {\
- imr = inl(DE4X5_IMR);\
- imr &= ~lp->irq_en;\
- outl(imr, DE4X5_IMR); /* Disable the IRQs */\
-}
-
-#define UNMASK_IRQs {\
- imr |= lp->irq_mask;\
- outl(imr, DE4X5_IMR); /* Unmask the IRQs */\
-}
-
-#define MASK_IRQs {\
- imr = inl(DE4X5_IMR);\
- imr &= ~lp->irq_mask;\
- outl(imr, DE4X5_IMR); /* Mask the IRQs */\
-}
-
-/*
-** DE4X5 START/STOP
-*/
-#define START_DE4X5 {\
- omr = inl(DE4X5_OMR);\
- omr |= OMR_ST | OMR_SR;\
- outl(omr, DE4X5_OMR); /* Enable the TX and/or RX */\
-}
-
-#define STOP_DE4X5 {\
- omr = inl(DE4X5_OMR);\
- omr &= ~(OMR_ST|OMR_SR);\
- outl(omr, DE4X5_OMR); /* Disable the TX and/or RX */ \
-}
-
-/*
-** DE4X5 SIA RESET
-*/
-#define RESET_SIA outl(0, DE4X5_SICR); /* Reset SIA connectivity regs */
-
-/*
-** DE500 AUTOSENSE TIMER INTERVAL (MILLISECS)
-*/
-#define DE4X5_AUTOSENSE_MS 250
-
-/*
-** SROM Structure
-*/
-struct de4x5_srom {
- char reserved[18];
- char version;
- char num_adapters;
- char ieee_addr[6];
- char info[100];
- short chksum;
-};
-
-/*
-** DE4X5 Descriptors. Make sure that all the RX buffers are contiguous
-** and have sizes of both a power of 2 and a multiple of 4.
-** A size of 256 bytes for each buffer could be chosen because over 90% of
-** all packets in our network are <256 bytes long and 64 longword alignment
-** is possible. 1536 showed better 'ttcp' performance. Take your pick. 32 TX
-** descriptors are needed for machines with an ALPHA CPU.
-*/
-#define NUM_RX_DESC 8 /* Number of RX descriptors */
-#define NUM_TX_DESC 32 /* Number of TX descriptors */
-#define BUFF_ALLOC_RETRIES 10 /* In case of memory shortage */
-#define RX_BUFF_SZ 1536 /* Power of 2 for kmalloc and */
- /* Multiple of 4 for DC21040 */
-struct de4x5_desc {
- volatile s32 status;
- u32 des1;
- u32 buf;
- u32 next;
- DESC_ALIGN
-};
-
-/*
-** The DE4X5 private structure
-*/
-#define DE4X5_PKT_STAT_SZ 16
-#define DE4X5_PKT_BIN_SZ 128 /* Should be >=100 unless you
- increase DE4X5_PKT_STAT_SZ */
-
-struct de4x5_private {
- char adapter_name[80]; /* Adapter name */
- struct de4x5_desc rx_ring[NUM_RX_DESC]; /* RX descriptor ring */
- struct de4x5_desc tx_ring[NUM_TX_DESC]; /* TX descriptor ring */
- struct sk_buff *skb[NUM_TX_DESC]; /* TX skb for freeing when sent */
- int rx_new, rx_old; /* RX descriptor ring pointers */
- int tx_new, tx_old; /* TX descriptor ring pointers */
- char setup_frame[SETUP_FRAME_LEN]; /* Holds MCA and PA info. */
- struct enet_statistics stats; /* Public stats */
- struct {
- u_int bins[DE4X5_PKT_STAT_SZ]; /* Private stats counters */
- u_int unicast;
- u_int multicast;
- u_int broadcast;
- u_int excessive_collisions;
- u_int tx_underruns;
- u_int excessive_underruns;
- } pktStats;
- char rxRingSize;
- char txRingSize;
- int bus; /* EISA or PCI */
- int bus_num; /* PCI Bus number */
- int chipset; /* DC21040, DC21041 or DC21140 */
- s32 irq_mask; /* Interrupt Mask (Enable) bits */
- s32 irq_en; /* Summary interrupt bits */
- int media; /* Media (eg TP), mode (eg 100B)*/
- int linkProb; /* Possible Link Problem */
- int autosense; /* Allow/disallow autosensing */
- int tx_enable; /* Enable descriptor polling */
- int lostMedia; /* Possibly lost media */
- int setup_f; /* Setup frame filtering type */
-};
-
-
-/*
-** The transmit ring full condition is described by the tx_old and tx_new
-** pointers by:
-** tx_old = tx_new Empty ring
-** tx_old = tx_new+1 Full ring
-** tx_old+txRingSize = tx_new+1 Full ring (wrapped condition)
-*/
-#define TX_BUFFS_AVAIL ((lp->tx_old<=lp->tx_new)?\
- lp->tx_old+lp->txRingSize-lp->tx_new-1:\
- lp->tx_old -lp->tx_new-1)
-
-/*
-** Public Functions
-*/
-static int de4x5_open(struct device *dev);
-static int de4x5_queue_pkt(struct sk_buff *skb, struct device *dev);
-static void de4x5_interrupt(int irq, struct pt_regs *regs);
-static int de4x5_close(struct device *dev);
-static struct enet_statistics *de4x5_get_stats(struct device *dev);
-static void set_multicast_list(struct device *dev);
-static int de4x5_ioctl(struct device *dev, struct ifreq *rq, int cmd);
-
-/*
-** Private functions
-*/
-static int de4x5_hw_init(struct device *dev, u_long iobase);
-static int de4x5_init(struct device *dev);
-static int de4x5_rx(struct device *dev);
-static int de4x5_tx(struct device *dev);
-static int de4x5_ast(struct device *dev);
-
-static int autoconf_media(struct device *dev);
-static void create_packet(struct device *dev, char *frame, int len);
-static void dce_us_delay(u32 usec);
-static void dce_ms_delay(u32 msec);
-static void load_packet(struct device *dev, char *buf, u32 flags, struct sk_buff *skb);
-static void dc21040_autoconf(struct device *dev);
-static void dc21041_autoconf(struct device *dev);
-static void dc21140_autoconf(struct device *dev);
-static int test_media(struct device *dev, s32 irqs, s32 irq_mask, s32 csr13, s32 csr14, s32 csr15, s32 msec);
-/*static int test_sym_link(struct device *dev, u32 msec);*/
-static int ping_media(struct device *dev);
-static void reset_init_sia(struct device *dev, s32 sicr, s32 strr, s32 sigr);
-static int test_ans(struct device *dev, s32 irqs, s32 irq_mask, s32 msec);
-static void load_ms_timer(struct device *dev, u32 msec);
-static int EISA_signature(char *name, s32 eisa_id);
-static int DevicePresent(u_long iobase);
-static short srom_rd(u_long address, u_char offset);
-static void srom_latch(u_int command, u_long address);
-static void srom_command(u_int command, u_long address);
-static void srom_address(u_int command, u_long address, u_char offset);
-static short srom_data(u_int command, u_long address);
-/*static void srom_busy(u_int command, u_long address);*/
-static void sendto_srom(u_int command, u_long addr);
-static int getfrom_srom(u_long addr);
-static void SetMulticastFilter(struct device *dev);
-static int get_hw_addr(struct device *dev);
-
-static void eisa_probe(struct device *dev, u_long iobase);
-static void pci_probe(struct device *dev, u_long iobase);
-static struct device *alloc_device(struct device *dev, u_long iobase);
-static char *build_setup_frame(struct device *dev, int mode);
-static void disable_ast(struct device *dev);
-static void enable_ast(struct device *dev, u32 time_out);
-static void kick_tx(struct device *dev);
-
-#ifdef MODULE
-int init_module(void);
-void cleanup_module(void);
-static int autoprobed = 1, loading_module = 1;
-# else
-static unsigned char de4x5_irq[] = {5,9,10,11};
-static int autoprobed = 0, loading_module = 0;
-#endif /* MODULE */
-
-static char name[DE4X5_NAME_LENGTH + 1];
-static int num_de4x5s = 0, num_eth = 0;
-
-/*
-** Kludge to get around the fact that the CSR addresses have different
-** offsets in the PCI and EISA boards. Also note that the ethernet address
-** PROM is accessed differently.
-*/
-static struct bus_type {
- int bus;
- int bus_num;
- int device;
- int chipset;
- struct de4x5_srom srom;
- int autosense;
-} bus;
-
-/*
-** Miscellaneous defines...
-*/
-#define RESET_DE4X5 {\
- int i;\
- i=inl(DE4X5_BMR);\
- dce_ms_delay(1);\
- outl(i | BMR_SWR, DE4X5_BMR);\
- dce_ms_delay(1);\
- outl(i, DE4X5_BMR);\
- dce_ms_delay(1);\
- for (i=0;i<5;i++) {inl(DE4X5_BMR); dce_ms_delay(1);}\
- dce_ms_delay(1);\
-}
-
-
-
-int de4x5_probe(struct device *dev)
-{
- int tmp = num_de4x5s, status = -ENODEV;
- u_long iobase = dev->base_addr;
-
- if ((iobase == 0) && loading_module){
- printk("Autoprobing is not supported when loading a module based driver.\n");
- status = -EIO;
- } else {
- eisa_probe(dev, iobase);
- pci_probe(dev, iobase);
-
- if ((tmp == num_de4x5s) && (iobase != 0) && loading_module) {
- printk("%s: de4x5_probe() cannot find device at 0x%04lx.\n", dev->name,
- iobase);
- }
-
- /*
- ** Walk the device list to check that at least one device
- ** initialised OK
- */
- for (; (dev->priv == NULL) && (dev->next != NULL); dev = dev->next);
-
- if (dev->priv) status = 0;
- if (iobase == 0) autoprobed = 1;
- }
-
- return status;
-}
-
-static int
-de4x5_hw_init(struct device *dev, u_long iobase)
-{
- struct bus_type *lp = &bus;
- int tmpbus, tmpchs, i, j, status=0;
- char *tmp;
-
- /* Ensure we're not sleeping */
- if (lp->chipset == DC21041) {
- outl(0, PCI_CFDA);
- dce_ms_delay(10);
- }
-
- RESET_DE4X5;
-
- if ((inl(DE4X5_STS) & (STS_TS | STS_RS)) == 0) {
- /*
- ** Now find out what kind of DC21040/DC21041/DC21140 board we have.
- */
- if (lp->bus == PCI) {
- if (!is_not_dec) {
- if ((lp->chipset == DC21040) || (lp->chipset == DC21041)) {
- strcpy(name, "DE435");
- } else if (lp->chipset == DC21140) {
- strcpy(name, "DE500"); /* Must read the SROM here! */
- }
- } else {
- strcpy(name, "UNKNOWN");
- }
- } else {
- EISA_signature(name, EISA_ID0);
- }
-
- if (*name != '\0') { /* found a board signature */
- dev->base_addr = iobase;
- if (lp->bus == EISA) {
- printk("%s: %s at %04lx (EISA slot %ld)",
- dev->name, name, iobase, ((iobase>>12)&0x0f));
- } else { /* PCI port address */
- printk("%s: %s at %04lx (PCI bus %d, device %d)", dev->name, name,
- iobase, lp->bus_num, lp->device);
- }
-
- printk(", h/w address ");
- status = get_hw_addr(dev);
- for (i = 0; i < ETH_ALEN - 1; i++) { /* get the ethernet addr. */
- printk("%2.2x:", dev->dev_addr[i]);
- }
- printk("%2.2x,\n", dev->dev_addr[i]);
-
- tmpbus = lp->bus;
- tmpchs = lp->chipset;
-
- if (status == 0) {
- struct de4x5_private *lp;
-
- /*
- ** Reserve a section of kernel memory for the adapter
- ** private area and the TX/RX descriptor rings.
- */
- dev->priv = (void *) kmalloc(sizeof(struct de4x5_private) + ALIGN,
- GFP_KERNEL);
- if (dev->priv == NULL)
- return -ENOMEM;
- /*
- ** Align to a longword boundary
- */
- dev->priv = (void *)(((u_long)dev->priv + ALIGN) & ~ALIGN);
- lp = (struct de4x5_private *)dev->priv;
- memset(dev->priv, 0, sizeof(struct de4x5_private));
- lp->bus = tmpbus;
- lp->chipset = tmpchs;
-
- /*
- ** Choose autosensing
- */
- if (de4x5_autosense & AUTO) {
- lp->autosense = AUTO;
- } else {
- if (lp->chipset != DC21140) {
- if ((lp->chipset == DC21040) && (de4x5_autosense & TP_NW)) {
- de4x5_autosense = TP;
- }
- if ((lp->chipset == DC21041) && (de4x5_autosense & BNC_AUI)) {
- de4x5_autosense = BNC;
- }
- lp->autosense = de4x5_autosense & 0x001f;
- } else {
- lp->autosense = de4x5_autosense & 0x00c0;
- }
- }
-
- sprintf(lp->adapter_name,"%s (%s)", name, dev->name);
- request_region(iobase, (lp->bus == PCI ? DE4X5_PCI_TOTAL_SIZE :
- DE4X5_EISA_TOTAL_SIZE),
- lp->adapter_name);
-
- /*
- ** Allocate contiguous receive buffers, long word aligned.
- ** This could be a possible memory leak if the private area
- ** is ever hosed.
- */
- for (tmp=NULL, j=0; (j<BUFF_ALLOC_RETRIES) && (tmp==NULL); j++) {
- if ((tmp = (void *)kmalloc(RX_BUFF_SZ * NUM_RX_DESC + ALIGN,
- GFP_KERNEL)) != NULL) {
- tmp = (char *)(((u_long) tmp + ALIGN) & ~ALIGN);
- for (i=0; i<NUM_RX_DESC; i++) {
- lp->rx_ring[i].status = 0;
- lp->rx_ring[i].des1 = RX_BUFF_SZ;
- lp->rx_ring[i].buf = virt_to_bus(tmp + i * RX_BUFF_SZ);
- lp->rx_ring[i].next = (u32)NULL;
- }
- barrier();
- }
- }
-
- if (tmp != NULL) {
- lp->rxRingSize = NUM_RX_DESC;
- lp->txRingSize = NUM_TX_DESC;
-
- /* Write the end of list marker to the descriptor lists */
- lp->rx_ring[lp->rxRingSize - 1].des1 |= RD_RER;
- lp->tx_ring[lp->txRingSize - 1].des1 |= TD_TER;
-
- /* Tell the adapter where the TX/RX rings are located. */
- outl(virt_to_bus(lp->rx_ring), DE4X5_RRBA);
- outl(virt_to_bus(lp->tx_ring), DE4X5_TRBA);
-
- /* Initialise the IRQ mask and Enable/Disable */
- lp->irq_mask = IMR_RIM | IMR_TIM | IMR_TUM ;
- lp->irq_en = IMR_NIM | IMR_AIM;
-
- lp->tx_enable = TRUE;
-
- if (dev->irq < 2) {
-#ifndef MODULE
- unsigned char irqnum;
- s32 omr;
- autoirq_setup(0);
-
- omr = inl(DE4X5_OMR);
- outl(IMR_AIM|IMR_RUM, DE4X5_IMR); /* Unmask RUM interrupt */
- outl(OMR_SR | omr, DE4X5_OMR); /* Start RX w/no descriptors */
-
- irqnum = autoirq_report(1);
- if (!irqnum) {
- printk(" and failed to detect IRQ line.\n");
- status = -ENXIO;
- } else {
- for (dev->irq=0,i=0; (i<sizeof(de4x5_irq)) && (!dev->irq); i++) {
- if (irqnum == de4x5_irq[i]) {
- dev->irq = irqnum;
- printk(" and uses IRQ%d.\n", dev->irq);
- }
- }
-
- if (!dev->irq) {
- printk(" but incorrect IRQ line detected.\n");
- status = -ENXIO;
- }
- }
-
- outl(0, DE4X5_IMR); /* Re-mask RUM interrupt */
-
-#endif /* MODULE */
- } else {
- printk(" and requires IRQ%d (not probed).\n", dev->irq);
- }
- } else {
- printk("%s: Kernel could not allocate RX buffer memory.\n",
- dev->name);
- status = -ENXIO;
- }
- if (status) release_region(iobase, (lp->bus == PCI ?
- DE4X5_PCI_TOTAL_SIZE :
- DE4X5_EISA_TOTAL_SIZE));
- } else {
- printk(" which has an Ethernet PROM CRC error.\n");
- status = -ENXIO;
- }
- } else {
- status = -ENXIO;
- }
- } else {
- status = -ENXIO;
- }
-
- if (!status) {
- if (de4x5_debug > 0) {
- printk(version);
- }
-
- /* The DE4X5-specific entries in the device structure. */
- dev->open = &de4x5_open;
- dev->hard_start_xmit = &de4x5_queue_pkt;
- dev->stop = &de4x5_close;
- dev->get_stats = &de4x5_get_stats;
- dev->set_multicast_list = &set_multicast_list;
- dev->do_ioctl = &de4x5_ioctl;
-
- dev->mem_start = 0;
-
- /* Fill in the generic field of the device structure. */
- ether_setup(dev);
-
- /* Let the adapter sleep to save power */
- if (lp->chipset == DC21041) {
- outl(0, DE4X5_SICR);
- outl(CFDA_PSM, PCI_CFDA);
- }
- } else { /* Incorrectly initialised hardware */
- struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
- if (lp) {
- kfree_s(bus_to_virt(lp->rx_ring[0].buf),
- RX_BUFF_SZ * NUM_RX_DESC + ALIGN);
- }
- if (dev->priv) {
- kfree_s(dev->priv, sizeof(struct de4x5_private) + ALIGN);
- dev->priv = NULL;
- }
- }
-
- return status;
-}
-
-
-static int
-de4x5_open(struct device *dev)
-{
- struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
- u_long iobase = dev->base_addr;
- int i, status = 0;
- s32 imr, omr, sts;
-
- /*
- ** Wake up the adapter
- */
- if (lp->chipset == DC21041) {
- outl(0, PCI_CFDA);
- dce_ms_delay(10);
- }
-
- if (request_irq(dev->irq, (void *)de4x5_interrupt, 0, lp->adapter_name)) {
- printk("de4x5_open(): Requested IRQ%d is busy\n",dev->irq);
- status = -EAGAIN;
- } else {
-
- irq2dev_map[dev->irq] = dev;
- /*
- ** Re-initialize the DE4X5...
- */
- status = de4x5_init(dev);
-
- if (de4x5_debug > 1){
- printk("%s: de4x5 open with irq %d\n",dev->name,dev->irq);
- printk("\tphysical address: ");
- for (i=0;i<6;i++){
- printk("%2.2x:",(short)dev->dev_addr[i]);
- }
- printk("\n");
- printk("Descriptor head addresses:\n");
- printk("\t0x%8.8lx 0x%8.8lx\n",(u_long)lp->rx_ring,(u_long)lp->tx_ring);
- printk("Descriptor addresses:\nRX: ");
- for (i=0;i<lp->rxRingSize-1;i++){
- if (i < 3) {
- printk("0x%8.8lx ",(u_long)&lp->rx_ring[i].status);
- }
- }
- printk("...0x%8.8lx\n",(u_long)&lp->rx_ring[i].status);
- printk("TX: ");
- for (i=0;i<lp->txRingSize-1;i++){
- if (i < 3) {
- printk("0x%8.8lx ", (u_long)&lp->tx_ring[i].status);
- }
- }
- printk("...0x%8.8lx\n", (u_long)&lp->tx_ring[i].status);
- printk("Descriptor buffers:\nRX: ");
- for (i=0;i<lp->rxRingSize-1;i++){
- if (i < 3) {
- printk("0x%8.8x ",lp->rx_ring[i].buf);
- }
- }
- printk("...0x%8.8x\n",lp->rx_ring[i].buf);
- printk("TX: ");
- for (i=0;i<lp->txRingSize-1;i++){
- if (i < 3) {
- printk("0x%8.8x ", lp->tx_ring[i].buf);
- }
- }
- printk("...0x%8.8x\n", lp->tx_ring[i].buf);
- printk("Ring size: \nRX: %d\nTX: %d\n",
- (short)lp->rxRingSize,
- (short)lp->txRingSize);
- printk("\tstatus: %d\n", status);
- }
-
- if (!status) {
- dev->tbusy = 0;
- dev->start = 1;
- dev->interrupt = UNMASK_INTERRUPTS;
- dev->trans_start = jiffies;
-
- START_DE4X5;
-
- /* Unmask and enable DE4X5 board interrupts */
- imr = 0;
- UNMASK_IRQs;
-
- /* Reset any pending (stale) interrupts */
- sts = inl(DE4X5_STS);
- outl(sts, DE4X5_STS);
-
- ENABLE_IRQs;
- }
- if (de4x5_debug > 1) {
- printk("\tsts: 0x%08x\n", inl(DE4X5_STS));
- printk("\tbmr: 0x%08x\n", inl(DE4X5_BMR));
- printk("\timr: 0x%08x\n", inl(DE4X5_IMR));
- printk("\tomr: 0x%08x\n", inl(DE4X5_OMR));
- printk("\tsisr: 0x%08x\n", inl(DE4X5_SISR));
- printk("\tsicr: 0x%08x\n", inl(DE4X5_SICR));
- printk("\tstrr: 0x%08x\n", inl(DE4X5_STRR));
- printk("\tsigr: 0x%08x\n", inl(DE4X5_SIGR));
- }
- }
-
- MOD_INC_USE_COUNT;
-
- return status;
-}
-
-/*
-** Initialize the DE4X5 operating conditions. NB: a chip problem with the
-** DC21140 requires using perfect filtering mode for that chip. Since I can't
-** see why I'd want > 14 multicast addresses, I may change all chips to use
-** the perfect filtering mode. Keep the DMA burst length at 8: there seems
-** to be data corruption problems if it is larger (UDP errors seen from a
-** ttcp source).
-*/
-static int
-de4x5_init(struct device *dev)
-{
- struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
- u_long iobase = dev->base_addr;
- int i, j, status = 0;
- s32 bmr, omr;
-
- /* Lock out other processes whilst setting up the hardware */
- set_bit(0, (void *)&dev->tbusy);
-
- RESET_DE4X5;
-
- bmr = inl(DE4X5_BMR);
- bmr |= PBL_8 | DESC_SKIP_LEN | CACHE_ALIGN;
- outl(bmr, DE4X5_BMR);
-
- if (lp->chipset != DC21140) {
- omr = TR_96;
- lp->setup_f = HASH_PERF;
- } else {
- omr = OMR_SDP | OMR_SF;
- lp->setup_f = PERFECT;
- }
- outl(virt_to_bus(lp->rx_ring), DE4X5_RRBA);
- outl(virt_to_bus(lp->tx_ring), DE4X5_TRBA);
-
- lp->rx_new = lp->rx_old = 0;
- lp->tx_new = lp->tx_old = 0;
-
- for (i = 0; i < lp->rxRingSize; i++) {
- lp->rx_ring[i].status = R_OWN;
- }
-
- for (i = 0; i < lp->txRingSize; i++) {
- lp->tx_ring[i].status = 0;
- }
-
- barrier();
-
- /* Build the setup frame depending on filtering mode */
- SetMulticastFilter(dev);
-
- if (lp->chipset != DC21140) {
- load_packet(dev, lp->setup_frame, HASH_F|TD_SET|SETUP_FRAME_LEN, NULL);
- } else {
- load_packet(dev, lp->setup_frame, PERFECT_F|TD_SET|SETUP_FRAME_LEN, NULL);
- }
- outl(omr|OMR_ST, DE4X5_OMR);
-
- /* Poll for completion of setup frame (interrupts are disabled for now) */
- for (j=0, i=jiffies;(i<=jiffies+HZ/100) && (j==0);) {
- if (lp->tx_ring[lp->tx_new].status >= 0) j=1;
- }
- outl(omr, DE4X5_OMR); /* Stop everything! */
-
- if (j == 0) {
- printk("%s: Setup frame timed out, status %08x\n", dev->name,
- inl(DE4X5_STS));
- status = -EIO;
- }
-
- lp->tx_new = (++lp->tx_new) % lp->txRingSize;
- lp->tx_old = lp->tx_new;
-
- /* Autoconfigure the connected port */
- if (autoconf_media(dev) == 0) {
- status = -EIO;
- }
-
- return 0;
-}
-
-/*
-** Writes a socket buffer address to the next available transmit descriptor
-*/
-static int
-de4x5_queue_pkt(struct sk_buff *skb, struct device *dev)
-{
- struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
- u_long iobase = dev->base_addr;
- int i, status = 0;
- s32 imr, omr, sts;
-
- /*
- ** Clean out the TX ring asynchronously to interrupts - sometimes the
- ** interrupts are lost by delayed descriptor status updates relative to
- ** the irq assertion, especially with a busy PCI bus.
- */
- if (set_bit(0, (void*)&dev->tbusy) == 0) {
- cli();
- de4x5_tx(dev);
- dev->tbusy = 0;
- sti();
- }
-
- /*
- ** Transmitter timeout, possibly serious problems.
- ** The 'lostMedia' threshold accounts for transient errors that
- ** were noticed when switching media.
- */
- if (dev->tbusy || (lp->lostMedia > LOST_MEDIA_THRESHOLD)) {
- u_long tickssofar = jiffies - dev->trans_start;
- if ((tickssofar < QUEUE_PKT_TIMEOUT) &&
- (lp->lostMedia <= LOST_MEDIA_THRESHOLD)) {
- status = -1;
- } else {
- if (de4x5_debug >= 1) {
- printk("%s: transmit timed out, status %08x, tbusy:%ld, lostMedia:%d tickssofar:%ld, resetting.\n",dev->name, inl(DE4X5_STS), dev->tbusy, lp->lostMedia, tickssofar);
- }
-
- /* Stop and reset the TX and RX... */
- STOP_DE4X5;
-
- /* Re-queue any skb's. */
- for (i=lp->tx_old; i!=lp->tx_new; i=(++i)%lp->txRingSize) {
- if (lp->skb[i] != NULL) {
- if (lp->skb[i]->len != FAKE_FRAME_LEN) {
- if (lp->tx_ring[i].status == T_OWN) {
- dev_queue_xmit(lp->skb[i], dev, SOPRI_NORMAL);
- } else { /* already sent */
- dev_kfree_skb(lp->skb[i], FREE_WRITE);
- }
- } else {
- dev_kfree_skb(lp->skb[i], FREE_WRITE);
- }
- lp->skb[i] = NULL;
- }
- }
- if (skb->len != FAKE_FRAME_LEN) {
- dev_queue_xmit(skb, dev, SOPRI_NORMAL);
- } else {
- dev_kfree_skb(skb, FREE_WRITE);
- }
-
- /* Initialise the hardware */
- status = de4x5_init(dev);
-
- /* Unmask DE4X5 board interrupts */
- if (!status) {
- /* Start here to clean stale interrupts later */
- dev->interrupt = UNMASK_INTERRUPTS;
- dev->start = 1;
- dev->tbusy = 0;
- dev->trans_start = jiffies;
-
- START_DE4X5;
-
- /* Unmask DE4X5 board interrupts */
- imr = 0;
- UNMASK_IRQs;
-
- /* Clear any pending (stale) interrupts */
- sts = inl(DE4X5_STS);
- outl(sts, DE4X5_STS);
-
- ENABLE_IRQs;
- } else {
- printk("%s: hardware initialisation failure, status %08x.\n",
- dev->name, inl(DE4X5_STS));
- }
- }
- } else if (skb == NULL) {
- dev_tint(dev);
- } else if (skb->len == FAKE_FRAME_LEN) { /* Don't TX a fake frame! */
- dev_kfree_skb(skb, FREE_WRITE);
- } else if (skb->len > 0) {
- /* Enforce 1 process per h/w access */
- if (set_bit(0, (void*)&dev->tbusy) != 0) {
- printk("%s: Transmitter access conflict.\n", dev->name);
- status = -1; /* Re-queue packet */
- } else {
- cli();
- if (TX_BUFFS_AVAIL) { /* Fill in a Tx ring entry */
- load_packet(dev, skb->data, TD_IC | TD_LS | TD_FS | skb->len, skb);
- if (lp->tx_enable) {
- outl(POLL_DEMAND, DE4X5_TPD); /* Start the TX */
- }
-
- lp->tx_new = (++lp->tx_new) % lp->txRingSize; /* Ensure a wrap */
- dev->trans_start = jiffies;
-
- if (TX_BUFFS_AVAIL) {
- dev->tbusy = 0; /* Another pkt may be queued */
- }
- } else { /* Ring full - re-queue */
- status = -1;
- }
- sti();
- }
- }
-
- return status;
-}
-
-/*
-** The DE4X5 interrupt handler.
-**
-** I/O Read/Writes through intermediate PCI bridges are never 'posted',
-** so that the asserted interrupt always has some real data to work with -
-** if these I/O accesses are ever changed to memory accesses, ensure the
-** STS write is read immediately to complete the transaction if the adapter
-** is not on bus 0. Lost interrupts can still occur when the PCI bus load
-** is high and descriptor status bits cannot be set before the associated
-** interrupt is asserted and this routine entered.
-*/
-static void
-de4x5_interrupt(int irq, struct pt_regs *regs)
-{
- struct device *dev = (struct device *)(irq2dev_map[irq]);
- struct de4x5_private *lp;
- s32 imr, omr, sts;
- u_long iobase;
-
- if (dev == NULL) {
- printk ("de4x5_interrupt(): irq %d for unknown device.\n", irq);
- } else {
- lp = (struct de4x5_private *)dev->priv;
- iobase = dev->base_addr;
-
- if (dev->interrupt)
- printk("%s: Re-entering the interrupt handler.\n", dev->name);
-
- DISABLE_IRQs; /* Ensure non re-entrancy */
- dev->interrupt = MASK_INTERRUPTS;
-
- while ((sts = inl(DE4X5_STS)) & lp->irq_mask) { /* Read IRQ status */
- outl(sts, DE4X5_STS); /* Reset the board interrupts */
-
- if (sts & (STS_RI | STS_RU)) /* Rx interrupt (packet[s] arrived) */
- de4x5_rx(dev);
-
- if (sts & (STS_TI | STS_TU)) /* Tx interrupt (packet sent) */
- de4x5_tx(dev);
-
- if (sts & STS_TM) /* Autosense tick */
- de4x5_ast(dev);
-
- if (sts & STS_LNF) { /* TP Link has failed */
- lp->lostMedia = LOST_MEDIA_THRESHOLD + 1;
- lp->irq_mask &= ~IMR_LFM;
- kick_tx(dev);
- }
-
- if (sts & STS_SE) { /* Bus Error */
- STOP_DE4X5;
- printk("%s: Fatal bus error occured, sts=%#8x, device stopped.\n",
- dev->name, sts);
- }
- }
-
- if (TX_BUFFS_AVAIL && dev->tbusy) {/* Any resources available? */
- dev->tbusy = 0; /* Clear TX busy flag */
- mark_bh(NET_BH);
- }
-
- dev->interrupt = UNMASK_INTERRUPTS;
- ENABLE_IRQs;
- }
-
- return;
-}
-
-static int
-de4x5_rx(struct device *dev)
-{
- struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
- int i, entry;
- s32 status;
- char *buf;
-
- for (entry = lp->rx_new; lp->rx_ring[entry].status >= 0;entry = lp->rx_new) {
- status = lp->rx_ring[entry].status;
-
- if (status & RD_FS) { /* Remember the start of frame */
- lp->rx_old = entry;
- }
-
- if (status & RD_LS) { /* Valid frame status */
- if (status & RD_ES) { /* There was an error. */
- lp->stats.rx_errors++; /* Update the error stats. */
- if (status & (RD_RF | RD_TL)) lp->stats.rx_frame_errors++;
- if (status & RD_CE) lp->stats.rx_crc_errors++;
- if (status & RD_OF) lp->stats.rx_fifo_errors++;
- } else { /* A valid frame received */
- struct sk_buff *skb;
- short pkt_len = (short)(lp->rx_ring[entry].status >> 16) - 4;
-
- if ((skb = dev_alloc_skb(pkt_len+2)) != NULL) {
- skb->dev = dev;
-
- skb_reserve(skb,2); /* Align */
- if (entry < lp->rx_old) { /* Wrapped buffer */
- short len = (lp->rxRingSize - lp->rx_old) * RX_BUFF_SZ;
- memcpy(skb_put(skb,len), bus_to_virt(lp->rx_ring[lp->rx_old].buf), len);
- memcpy(skb_put(skb,pkt_len-len), bus_to_virt(lp->rx_ring[0].buf), pkt_len - len);
- } else { /* Linear buffer */
- memcpy(skb_put(skb,pkt_len), bus_to_virt(lp->rx_ring[lp->rx_old].buf), pkt_len);
- }
-
- /* Push up the protocol stack */
- skb->protocol=eth_type_trans(skb,dev);
- netif_rx(skb);
-
- /* Update stats */
- lp->stats.rx_packets++;
- for (i=1; i<DE4X5_PKT_STAT_SZ-1; i++) {
- if (pkt_len < (i*DE4X5_PKT_BIN_SZ)) {
- lp->pktStats.bins[i]++;
- i = DE4X5_PKT_STAT_SZ;
- }
- }
- buf = skb->data; /* Look at the dest addr */
- if (buf[0] & 0x01) { /* Multicast/Broadcast */
- if ((*(s32 *)&buf[0] == -1) && (*(s16 *)&buf[4] == -1)) {
- lp->pktStats.broadcast++;
- } else {
- lp->pktStats.multicast++;
- }
- } else if ((*(s32 *)&buf[0] == *(s32 *)&dev->dev_addr[0]) &&
- (*(s16 *)&buf[4] == *(s16 *)&dev->dev_addr[4])) {
- lp->pktStats.unicast++;
- }
-
- lp->pktStats.bins[0]++; /* Duplicates stats.rx_packets */
- if (lp->pktStats.bins[0] == 0) { /* Reset counters */
- memset((char *)&lp->pktStats, 0, sizeof(lp->pktStats));
- }
- } else {
- printk("%s: Insufficient memory; nuking packet.\n", dev->name);
- lp->stats.rx_dropped++; /* Really, deferred. */
- break;
- }
- }
-
- /* Change buffer ownership for this last frame, back to the adapter */
- for (; lp->rx_old!=entry; lp->rx_old=(++lp->rx_old)%lp->rxRingSize) {
- lp->rx_ring[lp->rx_old].status = R_OWN;
- barrier();
- }
- lp->rx_ring[entry].status = R_OWN;
- barrier();
- }
-
- /*
- ** Update entry information
- */
- lp->rx_new = (++lp->rx_new) % lp->rxRingSize;
- }
-
- return 0;
-}
-
-/*
-** Buffer sent - check for TX buffer errors.
-*/
-static int
-de4x5_tx(struct device *dev)
-{
- struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
- u_long iobase = dev->base_addr;
- int entry;
- s32 status;
-
- for (entry = lp->tx_old; entry != lp->tx_new; entry = lp->tx_old) {
- status = lp->tx_ring[entry].status;
- if (status < 0) { /* Buffer not sent yet */
- break;
- } else if (status & TD_ES) { /* An error happened */
- lp->stats.tx_errors++;
- if (status & TD_NC) lp->stats.tx_carrier_errors++;
- if (status & TD_LC) lp->stats.tx_window_errors++;
- if (status & TD_UF) lp->stats.tx_fifo_errors++;
- if (status & TD_LC) lp->stats.collisions++;
- if (status & TD_EC) lp->pktStats.excessive_collisions++;
- if (status & TD_DE) lp->stats.tx_aborted_errors++;
-
- if ((status != 0x7fffffff) && /* Not setup frame */
- (status & (TD_LO | TD_NC | TD_EC | TD_LF))) {
- lp->lostMedia++;
- if (lp->lostMedia > LOST_MEDIA_THRESHOLD) { /* Trip autosense */
- kick_tx(dev);
- }
- } else {
- outl(POLL_DEMAND, DE4X5_TPD); /* Restart a stalled TX */
- }
- } else { /* Packet sent */
- lp->stats.tx_packets++;
- lp->lostMedia = 0; /* Remove transient problem */
- }
- /* Free the buffer if it's not a setup frame. */
- if (lp->skb[entry] != NULL) {
- dev_kfree_skb(lp->skb[entry], FREE_WRITE);
- lp->skb[entry] = NULL;
- }
-
- /* Update all the pointers */
- lp->tx_old = (++lp->tx_old) % lp->txRingSize;
- }
-
- return 0;
-}
-
-static int
-de4x5_ast(struct device *dev)
-{
- struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
- u_long iobase = dev->base_addr;
- s32 gep;
-
- disable_ast(dev);
-
- if (lp->chipset == DC21140) {
- gep = inl(DE4X5_GEP);
- if (((lp->media == _100Mb) && (gep & GEP_SLNK)) ||
- ((lp->media == _10Mb) && (gep & GEP_LNP)) ||
- ((lp->media == _10Mb) && !(gep & GEP_SLNK)) ||
- (lp->media == NC)) {
- if (lp->linkProb || ((lp->media == NC) && (!(gep & GEP_LNP)))) {
- lp->lostMedia = LOST_MEDIA_THRESHOLD + 1;
- lp->linkProb = 0;
- kick_tx(dev);
- } else {
- switch(lp->media) {
- case NC:
- lp->linkProb = 0;
- enable_ast(dev, DE4X5_AUTOSENSE_MS);
- break;
-
- case _10Mb:
- lp->linkProb = 1; /* Flag a potential problem */
- enable_ast(dev, 1500);
- break;
-
- case _100Mb:
- lp->linkProb = 1; /* Flag a potential problem */
- enable_ast(dev, 4000);
- break;
- }
- }
- } else {
- lp->linkProb = 0; /* Link OK */
- enable_ast(dev, DE4X5_AUTOSENSE_MS);
- }
- }
-
- return 0;
-}
-
-static int
-de4x5_close(struct device *dev)
-{
- struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
- u_long iobase = dev->base_addr;
- s32 imr, omr;
-
- dev->start = 0;
- dev->tbusy = 1;
-
- if (de4x5_debug > 1) {
- printk("%s: Shutting down ethercard, status was %8.8x.\n",
- dev->name, inl(DE4X5_STS));
- }
-
- /*
- ** We stop the DE4X5 here... mask interrupts and stop TX & RX
- */
- DISABLE_IRQs;
-
- STOP_DE4X5;
-
- /*
- ** Free the associated irq
- */
- free_irq(dev->irq);
- irq2dev_map[dev->irq] = 0;
-
- MOD_DEC_USE_COUNT;
-
- /* Put the adapter to sleep to save power */
- if (lp->chipset == DC21041) {
- outl(0, DE4X5_SICR);
- outl(CFDA_PSM, PCI_CFDA);
- }
-
- return 0;
-}
-
-static struct enet_statistics *
-de4x5_get_stats(struct device *dev)
-{
- struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
- u_long iobase = dev->base_addr;
-
- lp->stats.rx_missed_errors = (int) (inl(DE4X5_MFC) & (MFC_OVFL | MFC_CNTR));
-
- return &lp->stats;
-}
-
-static void load_packet(struct device *dev, char *buf, u32 flags, struct sk_buff *skb)
-{
- struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
-
- lp->tx_ring[lp->tx_new].buf = virt_to_bus(buf);
- lp->tx_ring[lp->tx_new].des1 &= TD_TER;
- lp->tx_ring[lp->tx_new].des1 |= flags;
- lp->skb[lp->tx_new] = skb;
- barrier();
- lp->tx_ring[lp->tx_new].status = T_OWN;
- barrier();
-
- return;
-}
-/*
-** Set or clear the multicast filter for this adaptor.
-** num_addrs == -1 Promiscuous mode, receive all packets - now supported.
-** Can also use the ioctls.
-** num_addrs == 0 Normal mode, clear multicast list
-** num_addrs > 0 Multicast mode, receive normal and MC packets, and do
-** best-effort filtering.
-** num_addrs == HASH_TABLE_LEN
-** Set all multicast bits (pass all multicasts).
-*/
-static void
-set_multicast_list(struct device *dev)
-{
- struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
- u_long iobase = dev->base_addr;
-
- /* First, double check that the adapter is open */
- if (irq2dev_map[dev->irq] != NULL) {
- if (dev->flags & IFF_PROMISC) { /* set promiscuous mode */
- u32 omr;
- omr = inl(DE4X5_OMR);
- omr |= OMR_PR;
- outl(omr, DE4X5_OMR);
- } else {
- SetMulticastFilter(dev);
- if (lp->setup_f == HASH_PERF) {
- load_packet(dev, lp->setup_frame, TD_IC | HASH_F | TD_SET |
- SETUP_FRAME_LEN, NULL);
- } else {
- load_packet(dev, lp->setup_frame, TD_IC | PERFECT_F | TD_SET |
- SETUP_FRAME_LEN, NULL);
- }
-
- lp->tx_new = (++lp->tx_new) % lp->txRingSize;
- outl(POLL_DEMAND, DE4X5_TPD); /* Start the TX */
- dev->trans_start = jiffies;
- }
- }
-
- return;
-}
-
-/*
-** Calculate the hash code and update the logical address filter
-** from a list of ethernet multicast addresses.
-** Little endian crc one liner from Matt Thomas, DEC.
-*/
-static void SetMulticastFilter(struct device *dev)
-{
- struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
- struct dev_mc_list *dmi=dev->mc_list;
- u_long iobase = dev->base_addr;
- int i, j, bit, byte;
- u16 hashcode;
- u32 omr, crc, poly = CRC_POLYNOMIAL_LE;
- char *pa;
- unsigned char *addrs;
-
- omr = inl(DE4X5_OMR);
- omr &= ~OMR_PR;
- pa = build_setup_frame(dev, ALL); /* Build the basic frame */
-
- if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 14)) {
- omr |= OMR_PM; /* Pass all multicasts */
- } else if (lp->setup_f == HASH_PERF) {
- /* Now update the MCA table */
- for (i=0;i<dev->mc_count;i++) { /* for each address in the list */
- addrs=dmi->dmi_addr;
- dmi=dmi->next;
- if ((*addrs & 0x01) == 1) { /* multicast address? */
- crc = 0xffffffff; /* init CRC for each address */
- for (byte=0;byte<ETH_ALEN;byte++) { /* for each address byte */
- /* process each address bit */
- for (bit = *addrs++,j=0;j<8;j++, bit>>=1) {
- crc = (crc >> 1) ^ (((crc ^ bit) & 0x01) ? poly : 0);
- }
- }
- hashcode = crc & HASH_BITS; /* hashcode is 9 LSb of CRC */
-
- byte = hashcode >> 3; /* bit[3-8] -> byte in filter */
- bit = 1 << (hashcode & 0x07); /* bit[0-2] -> bit in byte */
-
- byte <<= 1; /* calc offset into setup frame */
- if (byte & 0x02) {
- byte -= 1;
- }
- lp->setup_frame[byte] |= bit;
- }
- }
- } else { /* Perfect filtering */
- for (j=0; j<dev->mc_count; j++) {
- addrs=dmi->dmi_addr;
- dmi=dmi->next;
- for (i=0; i<ETH_ALEN; i++) {
- *(pa + (i&1)) = *addrs++;
- if (i & 0x01) pa += 4;
- }
- }
- }
- outl(omr, DE4X5_OMR);
-
- return;
-}
-
-/*
-** EISA bus I/O device probe. Probe from slot 1 since slot 0 is usually
-** the motherboard. Upto 15 EISA devices are supported.
-*/
-static void eisa_probe(struct device *dev, u_long ioaddr)
-{
- int i, maxSlots, status;
- u_short vendor, device;
- s32 cfid;
- u_long iobase;
- struct bus_type *lp = &bus;
- char name[DE4X5_STRLEN];
-
- if (!ioaddr && autoprobed) return ; /* Been here before ! */
- if ((ioaddr < 0x1000) && (ioaddr > 0)) return; /* PCI MODULE special */
-
- lp->bus = EISA;
-
- if (ioaddr == 0) { /* Autoprobing */
- iobase = EISA_SLOT_INC; /* Get the first slot address */
- i = 1;
- maxSlots = MAX_EISA_SLOTS;
- } else { /* Probe a specific location */
- iobase = ioaddr;
- i = (ioaddr >> 12);
- maxSlots = i + 1;
- }
-
- for (status = -ENODEV; (i<maxSlots) && (dev!=NULL); i++, iobase+=EISA_SLOT_INC) {
- if (EISA_signature(name, EISA_ID)) {
- cfid = inl(PCI_CFID);
- device = (u_short)(cfid >> 16);
- vendor = (u_short) cfid;
-
- lp->bus = EISA;
- lp->chipset = device;
- if (DevicePresent(EISA_APROM) == 0) {
- /* Write the PCI Configuration Registers */
- outl(PCI_COMMAND_IO | PCI_COMMAND_MASTER, PCI_CFCS);
- outl(0x00004000, PCI_CFLT);
- outl(iobase, PCI_CBIO);
-
- if (check_region(iobase, DE4X5_EISA_TOTAL_SIZE) == 0) {
- if ((dev = alloc_device(dev, iobase)) != NULL) {
- if ((status = de4x5_hw_init(dev, iobase)) == 0) {
- num_de4x5s++;
- }
- num_eth++;
- }
- } else if (autoprobed) {
- printk("%s: region already allocated at 0x%04lx.\n", dev->name, iobase);
- }
- }
- }
- }
-
- return;
-}
-
-/*
-** PCI bus I/O device probe
-** NB: PCI I/O accesses and Bus Mastering are enabled by the PCI BIOS, not
-** the driver. Some PCI BIOS's, pre V2.1, need the slot + features to be
-** enabled by the user first in the set up utility. Hence we just check for
-** enabled features and silently ignore the card if they're not.
-**
-** STOP PRESS: Some BIOS's __require__ the driver to enable the bus mastering
-** bit. Here, check for I/O accesses and then set BM. If you put the card in
-** a non BM slot, you're on your own (and complain to the PC vendor that your
-** PC doesn't conform to the PCI standard)!
-*/
-#define PCI_DEVICE (dev_num << 3)
-#define PCI_LAST_DEV 32
-
-static void pci_probe(struct device *dev, u_long ioaddr)
-{
- u_char irq;
- u_char pb, pbus, dev_num, dnum, dev_fn;
- u_short vendor, device, index, status;
- u_int class = DE4X5_CLASS_CODE;
- u_int iobase;
- struct bus_type *lp = &bus;
-
- if (!ioaddr && autoprobed) return ; /* Been here before ! */
-
- if (pcibios_present()) {
- lp->bus = PCI;
-
- if (ioaddr < 0x1000) {
- pbus = (u_short)(ioaddr >> 8);
- dnum = (u_short)(ioaddr & 0xff);
- } else {
- pbus = 0;
- dnum = 0;
- }
-
- for (index=0;
- (pcibios_find_class(class, index, &pb, &dev_fn)!= PCIBIOS_DEVICE_NOT_FOUND);
- index++) {
- dev_num = PCI_SLOT(dev_fn);
-
- if ((!pbus && !dnum) || ((pbus == pb) && (dnum == dev_num))) {
- pcibios_read_config_word(pb, PCI_DEVICE, PCI_VENDOR_ID, &vendor);
- pcibios_read_config_word(pb, PCI_DEVICE, PCI_DEVICE_ID, &device);
- if (is_DC21040 || is_DC21041 || is_DC21140) {
- /* Set the device number information */
- lp->device = dev_num;
- lp->bus_num = pb;
-
- /* Set the chipset information */
- lp->chipset = device;
-
- /* Get the board I/O address */
- pcibios_read_config_dword(pb, PCI_DEVICE, PCI_BASE_ADDRESS_0, &iobase);
- iobase &= CBIO_MASK;
-
- /* Fetch the IRQ to be used */
- pcibios_read_config_byte(pb, PCI_DEVICE, PCI_INTERRUPT_LINE, &irq);
-
- /* Check if I/O accesses and Bus Mastering are enabled */
- pcibios_read_config_word(pb, PCI_DEVICE, PCI_COMMAND, &status);
- if (status & PCI_COMMAND_IO) {
- if (!(status & PCI_COMMAND_MASTER)) {
- status |= PCI_COMMAND_MASTER;
- pcibios_write_config_word(pb, PCI_DEVICE, PCI_COMMAND, status);
- pcibios_read_config_word(pb, PCI_DEVICE, PCI_COMMAND, &status);
- }
- if (status & PCI_COMMAND_MASTER) {
- if ((DevicePresent(DE4X5_APROM) == 0) || is_not_dec) {
- if (check_region(iobase, DE4X5_PCI_TOTAL_SIZE) == 0) {
- if ((dev = alloc_device(dev, iobase)) != NULL) {
- dev->irq = irq;
- if ((status = de4x5_hw_init(dev, iobase)) == 0) {
- num_de4x5s++;
- }
- num_eth++;
- }
- } else if (autoprobed) {
- printk("%s: region already allocated at 0x%04x.\n", dev->name, (u_short)iobase);
- }
- }
- }
- }
- }
- }
- }
- }
-
- return;
-}
-
-/*
-** Allocate the device by pointing to the next available space in the
-** device structure. Should one not be available, it is created.
-*/
-static struct device *alloc_device(struct device *dev, u_long iobase)
-{
- int addAutoProbe = 0;
- struct device *tmp = NULL, *ret;
- int (*init)(struct device *) = NULL;
-
- /*
- ** Check the device structures for an end of list or unused device
- */
- if (!loading_module) {
- while (dev->next != NULL) {
- if ((dev->base_addr == DE4X5_NDA) || (dev->base_addr == 0)) break;
- dev = dev->next; /* walk through eth device list */
- num_eth++; /* increment eth device number */
- }
-
- /*
- ** If an autoprobe is requested for another device, we must re-insert
- ** the request later in the list. Remember the current position first.
- */
- if ((dev->base_addr == 0) && (num_de4x5s > 0)) {
- addAutoProbe++;
- tmp = dev->next; /* point to the next device */
- init = dev->init; /* remember the probe function */
- }
-
- /*
- ** If at end of list and can't use current entry, malloc one up.
- ** If memory could not be allocated, print an error message.
- */
- if ((dev->next == NULL) &&
- !((dev->base_addr == DE4X5_NDA) || (dev->base_addr == 0))){
- dev->next = (struct device *)kmalloc(sizeof(struct device) + 8,
- GFP_KERNEL);
-
- dev = dev->next; /* point to the new device */
- if (dev == NULL) {
- printk("eth%d: Device not initialised, insufficient memory\n",
- num_eth);
- } else {
- /*
- ** If the memory was allocated, point to the new memory area
- ** and initialize it (name, I/O address, next device (NULL) and
- ** initialisation probe routine).
- */
- dev->name = (char *)(dev + sizeof(struct device));
- if (num_eth > 9999) {
- sprintf(dev->name,"eth????"); /* New device name */
- } else {
- sprintf(dev->name,"eth%d", num_eth);/* New device name */
- }
- dev->base_addr = iobase; /* assign the io address */
- dev->next = NULL; /* mark the end of list */
- dev->init = &de4x5_probe; /* initialisation routine */
- num_de4x5s++;
- }
- }
- ret = dev; /* return current struct, or NULL */
-
- /*
- ** Now figure out what to do with the autoprobe that has to be inserted.
- ** Firstly, search the (possibly altered) list for an empty space.
- */
- if (ret != NULL) {
- if (addAutoProbe) {
- for (; (tmp->next!=NULL) && (tmp->base_addr!=DE4X5_NDA); tmp=tmp->next);
-
- /*
- ** If no more device structures and can't use the current one, malloc
- ** one up. If memory could not be allocated, print an error message.
- */
- if ((tmp->next == NULL) && !(tmp->base_addr == DE4X5_NDA)) {
- tmp->next = (struct device *)kmalloc(sizeof(struct device) + 8,
- GFP_KERNEL);
- tmp = tmp->next; /* point to the new device */
- if (tmp == NULL) {
- printk("%s: Insufficient memory to extend the device list.\n",
- dev->name);
- } else {
- /*
- ** If the memory was allocated, point to the new memory area
- ** and initialize it (name, I/O address, next device (NULL) and
- ** initialisation probe routine).
- */
- tmp->name = (char *)(tmp + sizeof(struct device));
- if (num_eth > 9999) {
- sprintf(tmp->name,"eth????"); /* New device name */
- } else {
- sprintf(tmp->name,"eth%d", num_eth);/* New device name */
- }
- tmp->base_addr = 0; /* re-insert the io address */
- tmp->next = NULL; /* mark the end of list */
- tmp->init = init; /* initialisation routine */
- }
- } else { /* structure already exists */
- tmp->base_addr = 0; /* re-insert the io address */
- }
- }
- }
- } else {
- ret = dev;
- }
-
- return ret;
-}
-
-/*
-** Auto configure the media here rather than setting the port at compile
-** time. This routine is called by de4x5_init() when a loss of media is
-** detected (excessive collisions, loss of carrier, no carrier or link fail
-** [TP]) to check whether the user has been sneaky and changed the port on us.
-*/
-static int autoconf_media(struct device *dev)
-{
- struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
- u_long iobase = dev->base_addr;
-
- lp->tx_enable = YES;
- if (de4x5_debug > 0 ) {
- if (lp->chipset != DC21140) {
- printk("%s: Searching for media... ",dev->name);
- } else {
- printk("%s: Searching for mode... ",dev->name);
- }
- }
-
- if (lp->chipset == DC21040) {
- lp->media = (lp->autosense == AUTO ? TP : lp->autosense);
- dc21040_autoconf(dev);
- } else if (lp->chipset == DC21041) {
- lp->media = (lp->autosense == AUTO ? TP_NW : lp->autosense);
- dc21041_autoconf(dev);
- } else if (lp->chipset == DC21140) {
- disable_ast(dev);
- lp->media = (lp->autosense == AUTO ? _10Mb : lp->autosense);
- dc21140_autoconf(dev);
- }
-
- if (de4x5_debug > 0 ) {
- if (lp->chipset != DC21140) {
- printk("media is %s\n", (lp->media == NC ? "unconnected!" :
- (lp->media == TP ? "TP." :
- (lp->media == ANS ? "TP/Nway." :
- (lp->media == BNC ? "BNC." :
- (lp->media == AUI ? "AUI." :
- "BNC/AUI."
- ))))));
- } else {
- printk("mode is %s\n",(lp->media == NC ? "link down.":
- (lp->media == _100Mb ? "100Mb/s." :
- (lp->media == _10Mb ? "10Mb/s." :
- "\?\?\?"
- ))));
- }
- }
-
- if (lp->media) {
- lp->lostMedia = 0;
- inl(DE4X5_MFC); /* Zero the lost frames counter */
- if ((lp->media == TP) || (lp->media == ANS)) {
- lp->irq_mask |= IMR_LFM;
- }
- }
- dce_ms_delay(10);
-
- return (lp->media);
-}
-
-static void dc21040_autoconf(struct device *dev)
-{
- struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
- u_long iobase = dev->base_addr;
- int i, linkBad;
- s32 sisr = 0, t_3s = 3000;
-
- switch (lp->media) {
- case TP:
- reset_init_sia(dev, 0x8f01, 0xffff, 0x0000);
- for (linkBad=1,i=0;(i<t_3s) && linkBad && !(sisr & SISR_NCR);i++) {
- if (((sisr = inl(DE4X5_SISR)) & SISR_LKF) == 0) linkBad = 0;
- dce_ms_delay(1);
- }
- if (linkBad && (lp->autosense == AUTO)) {
- lp->media = BNC_AUI;
- dc21040_autoconf(dev);
- }
- break;
-
- case BNC:
- case AUI:
- case BNC_AUI:
- reset_init_sia(dev, 0x8f09, 0x0705, 0x0006);
- dce_ms_delay(500);
- linkBad = ping_media(dev);
- if (linkBad && (lp->autosense == AUTO)) {
- lp->media = EXT_SIA;
- dc21040_autoconf(dev);
- }
- break;
-
- case EXT_SIA:
- reset_init_sia(dev, 0x3041, 0x0000, 0x0006);
- dce_ms_delay(500);
- linkBad = ping_media(dev);
- if (linkBad && (lp->autosense == AUTO)) {
- lp->media = NC;
- dc21040_autoconf(dev);
- }
- break;
-
- case NC:
-#ifndef __alpha__
- reset_init_sia(dev, 0x8f01, 0xffff, 0x0000);
- break;
-#else
- /* JAE: for Alpha, default to BNC/AUI, *not* TP */
- reset_init_sia(dev, 0x8f09, 0x0705, 0x0006);
-#endif /* i386 */
- }
-
- return;
-}
-
-/*
-** Autoconfigure the media when using the DC21041. AUI needs to be tested
-** before BNC, because the BNC port will indicate activity if it's not
-** terminated correctly. The only way to test for that is to place a loopback
-** packet onto the network and watch for errors.
-*/
-static void dc21041_autoconf(struct device *dev)
-{
- struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
- u_long iobase = dev->base_addr;
- s32 sts, irqs, irq_mask, omr;
-
- switch (lp->media) {
- case TP_NW:
- omr = inl(DE4X5_OMR); /* Set up full duplex for the autonegotiate */
- outl(omr | OMR_FD, DE4X5_OMR);
- irqs = STS_LNF | STS_LNP;
- irq_mask = IMR_LFM | IMR_LPM;
- sts = test_media(dev, irqs, irq_mask, 0xef01, 0xffff, 0x0008, 2400);
- if (sts & STS_LNP) {
- lp->media = ANS;
- } else {
- lp->media = AUI;
- }
- dc21041_autoconf(dev);
- break;
-
- case ANS:
- irqs = STS_LNP;
- irq_mask = IMR_LPM;
- sts = test_ans(dev, irqs, irq_mask, 3000);
- if (!(sts & STS_LNP) && (lp->autosense == AUTO)) {
- lp->media = TP;
- dc21041_autoconf(dev);
- }
- break;
-
- case TP:
- omr = inl(DE4X5_OMR); /* Set up half duplex for TP */
- outl(omr & ~OMR_FD, DE4X5_OMR);
- irqs = STS_LNF | STS_LNP;
- irq_mask = IMR_LFM | IMR_LPM;
- sts = test_media(dev, irqs, irq_mask, 0xef01, 0xff3f, 0x0008, 2400);
- if (!(sts & STS_LNP) && (lp->autosense == AUTO)) {
- if (inl(DE4X5_SISR) & SISR_NRA) { /* Non selected port activity */
- lp->media = AUI;
- } else {
- lp->media = BNC;
- }
- dc21041_autoconf(dev);
- }
- break;
-
- case AUI:
- omr = inl(DE4X5_OMR); /* Set up half duplex for AUI */
- outl(omr & ~OMR_FD, DE4X5_OMR);
- irqs = 0;
- irq_mask = 0;
- sts = test_media(dev, irqs, irq_mask, 0xef09, 0xf7fd, 0x000e, 1000);
- if (!(inl(DE4X5_SISR) & SISR_SRA) && (lp->autosense == AUTO)) {
- lp->media = BNC;
- dc21041_autoconf(dev);
- }
- break;
-
- case BNC:
- omr = inl(DE4X5_OMR); /* Set up half duplex for BNC */
- outl(omr & ~OMR_FD, DE4X5_OMR);
- irqs = 0;
- irq_mask = 0;
- sts = test_media(dev, irqs, irq_mask, 0xef09, 0xf7fd, 0x0006, 1000);
- if (!(inl(DE4X5_SISR) & SISR_SRA) && (lp->autosense == AUTO)) {
- lp->media = NC;
- } else { /* Ensure media connected */
- if (ping_media(dev)) lp->media = NC;
- }
- break;
-
- case NC:
- omr = inl(DE4X5_OMR); /* Set up full duplex for the autonegotiate */
- outl(omr | OMR_FD, DE4X5_OMR);
- reset_init_sia(dev, 0xef01, 0xffff, 0x0008);/* Initialise the SIA */
- break;
- }
-
- return;
-}
-
-/*
-** Reduced feature version (temporary I hope)
-*/
-static void dc21140_autoconf(struct device *dev)
-{
- struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
- u_long iobase = dev->base_addr;
- s32 omr;
-
- switch(lp->media) {
- case _100Mb: /* Set 100Mb/s, MII Port with PCS Function and Scrambler */
- omr = (inl(DE4X5_OMR) & ~(OMR_PS | OMR_HBD | OMR_TTM | OMR_PCS | OMR_SCR));
- omr |= (de4x5_full_duplex ? OMR_FD : 0); /* Set up Full Duplex */
- outl(omr | OMR_PS | OMR_HBD | OMR_PCS | OMR_SCR, DE4X5_OMR);
- outl(GEP_FDXD | GEP_MODE, DE4X5_GEP);
- break;
-
- case _10Mb: /* Set conventional 10Mb/s ENDEC interface */
- omr = (inl(DE4X5_OMR) & ~(OMR_PS | OMR_HBD | OMR_TTM | OMR_PCS | OMR_SCR));
- omr |= (de4x5_full_duplex ? OMR_FD : 0); /* Set up Full Duplex */
- outl(omr | OMR_TTM, DE4X5_OMR);
- outl(GEP_FDXD, DE4X5_GEP);
- break;
- }
-
- return;
-}
-
-static int
-test_media(struct device *dev, s32 irqs, s32 irq_mask, s32 csr13, s32 csr14, s32 csr15, s32 msec)
-{
- struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
- u_long iobase = dev->base_addr;
- s32 sts, time, csr12;
-
- reset_init_sia(dev, csr13, csr14, csr15);
-
- /* Set link_fail_inhibit_timer */
- load_ms_timer(dev, msec);
-
- /* clear all pending interrupts */
- sts = inl(DE4X5_STS);
- outl(sts, DE4X5_STS);
-
- /* clear csr12 NRA and SRA bits */
- csr12 = inl(DE4X5_SISR);
- outl(csr12, DE4X5_SISR);
-
- /* Poll for timeout - timer interrupt doesn't work correctly */
- do {
- time = inl(DE4X5_GPT) & GPT_VAL;
- sts = inl(DE4X5_STS);
- } while ((time != 0) && !(sts & irqs));
-
- sts = inl(DE4X5_STS);
-
- return sts;
-}
-/*
-static int test_sym_link(struct device *dev, u32 msec)
-{
- struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
- u_long iobase = dev->base_addr;
- u32 gep, time;
-
- / * Set link_fail_inhibit_timer * /
- load_ms_timer(dev, msec);
-
- / * Poll for timeout or SYM_LINK=0 * /
- do {
- time = inl(DE4X5_GPT) & GPT_VAL;
- gep = inl(DE4X5_GEP) & (GEP_SLNK | GEP_LNP);
- } while ((time > 0) && (gep & GEP_SLNK));
-
- return gep;
-}
-*/
-/*
-** Send a packet onto the media and watch for send errors that indicate the
-** media is bad or unconnected.
-*/
-static int ping_media(struct device *dev)
-{
- struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
- u_long iobase = dev->base_addr;
- int i, entry, linkBad;
- s32 omr, t_3s = 4000;
- char frame[64];
-
- create_packet(dev, frame, sizeof(frame));
-
- entry = lp->tx_new; /* Remember the ring position */
- load_packet(dev, frame, TD_LS | TD_FS | sizeof(frame),NULL);
-
- omr = inl(DE4X5_OMR);
- outl(omr|OMR_ST, DE4X5_OMR);
-
- lp->tx_new = (++lp->tx_new) % lp->txRingSize;
- lp->tx_old = lp->tx_new;
-
- /* Poll for completion of frame (interrupts are disabled for now)... */
- for (linkBad=1,i=0;(i<t_3s) && linkBad;i++) {
- if ((inl(DE4X5_SISR) & SISR_NCR) == 1) break;
- if (lp->tx_ring[entry].status >= 0) linkBad=0;
- dce_ms_delay(1);
- }
- outl(omr, DE4X5_OMR);
-
- return ((linkBad || (lp->tx_ring[entry].status & TD_ES)) ? 1 : 0);
-}
-
-/*
-** Check the Auto Negotiation State. Return OK when a link pass interrupt
-** is received and the auto-negotiation status is NWAY OK.
-*/
-static int test_ans(struct device *dev, s32 irqs, s32 irq_mask, s32 msec)
-{
- struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
- u_long iobase = dev->base_addr;
- s32 sts, ans;
-
- outl(irq_mask, DE4X5_IMR);
-
- /* Set timeout limit */
- load_ms_timer(dev, msec);
-
- /* clear all pending interrupts */
- sts = inl(DE4X5_STS);
- outl(sts, DE4X5_STS);
-
- /* Poll for interrupts */
- do {
- ans = inl(DE4X5_SISR) & SISR_ANS;
- sts = inl(DE4X5_STS);
- } while (!(sts & irqs) && (ans ^ ANS_NWOK) != 0);
-
- return ((sts & STS_LNP) && ((ans ^ ANS_NWOK) == 0) ? STS_LNP : 0);
-}
-
-/*
-**
-*/
-static void reset_init_sia(struct device *dev, s32 sicr, s32 strr, s32 sigr)
-{
- struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
- u_long iobase = dev->base_addr;
-
- RESET_SIA;
- outl(sigr, DE4X5_SIGR);
- outl(strr, DE4X5_STRR);
- outl(sicr, DE4X5_SICR);
-
- return;
-}
-
-/*
-** Load the timer on the DC21041 and 21140. Max time is 13.42 secs.
-*/
-static void load_ms_timer(struct device *dev, u32 msec)
-{
- struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
- u_long iobase = dev->base_addr;
- s32 i = 2048, j;
-
- if (lp->chipset == DC21140) {
- j = inl(DE4X5_OMR);
- if ((j & OMR_TTM) && (j & OMR_PS)) { /* 10Mb/s MII */
- i = 8192;
- } else if ((~j & OMR_TTM) && (j & OMR_PS)) { /* 100Mb/s MII */
- i = 819;
- }
- }
-
- outl((s32)(msec * 10000)/i, DE4X5_GPT);
-
- return;
-}
-
-/*
-** Create an Ethernet packet with an invalid CRC
-*/
-static void create_packet(struct device *dev, char *frame, int len)
-{
- int i;
- char *buf = frame;
-
- for (i=0; i<ETH_ALEN; i++) { /* Use this source address */
- *buf++ = dev->dev_addr[i];
- }
- for (i=0; i<ETH_ALEN; i++) { /* Use this destination address */
- *buf++ = dev->dev_addr[i];
- }
-
- *buf++ = 0; /* Packet length (2 bytes) */
- *buf++ = 1;
-
- return;
-}
-
-/*
-** Known delay in microseconds
-*/
-static void dce_us_delay(u32 usec)
-{
- udelay(usec);
-
- return;
-}
-
-/*
-** Known delay in milliseconds, in millisecond steps.
-*/
-static void dce_ms_delay(u32 msec)
-{
- u_int i;
-
- for (i=0; i<msec; i++) {
- dce_us_delay(1000);
- }
-
- return;
-}
-
-
-/*
-** Look for a particular board name in the EISA configuration space
-*/
-static int EISA_signature(char *name, s32 eisa_id)
-{
- u_int i;
- const char *signatures[] = DE4X5_SIGNATURE;
- char ManCode[DE4X5_STRLEN];
- union {
- s32 ID;
- char Id[4];
- } Eisa;
- int status = 0;
-
- *name = '\0';
- Eisa.ID = inl(eisa_id);
-
- ManCode[0]=(((Eisa.Id[0]>>2)&0x1f)+0x40);
- ManCode[1]=(((Eisa.Id[1]&0xe0)>>5)+((Eisa.Id[0]&0x03)<<3)+0x40);
- ManCode[2]=(((Eisa.Id[2]>>4)&0x0f)+0x30);
- ManCode[3]=((Eisa.Id[2]&0x0f)+0x30);
- ManCode[4]=(((Eisa.Id[3]>>4)&0x0f)+0x30);
- ManCode[5]='\0';
-
- for (i=0;(*signatures[i] != '\0') && (*name == '\0');i++) {
- if (strstr(ManCode, signatures[i]) != NULL) {
- strcpy(name,ManCode);
- status = 1;
- }
- }
-
- return status; /* return the device name string */
-}
-
-/*
-** Look for a special sequence in the Ethernet station address PROM that
-** is common across all DIGITAL network adapter products.
-**
-** Search the Ethernet address ROM for the signature. Since the ROM address
-** counter can start at an arbitrary point, the search must include the entire
-** probe sequence length plus the (length_of_the_signature - 1).
-** Stop the search IMMEDIATELY after the signature is found so that the
-** PROM address counter is correctly positioned at the start of the
-** ethernet address for later read out.
-*/
-
-static int DevicePresent(u_long aprom_addr)
-{
- union {
- struct {
- u32 a;
- u32 b;
- } llsig;
- char Sig[sizeof(u32) << 1];
- } dev;
- char data;
- int i, j, tmp, status = 0;
- short sigLength;
- struct bus_type *lp = &bus;
-
- dev.llsig.a = ETH_PROM_SIG;
- dev.llsig.b = ETH_PROM_SIG;
- sigLength = sizeof(u32) << 1;
-
- if (lp->chipset == DC21040) {
- for (i=0,j=0;(j<sigLength) && (i<PROBE_LENGTH+sigLength-1);i++) {
- if (lp->bus == PCI) {
- while ((tmp = inl(aprom_addr)) < 0);
- data = (char)tmp;
- } else {
- data = inb(aprom_addr);
- }
- if (dev.Sig[j] == data) { /* track signature */
- j++;
- } else { /* lost signature; begin search again */
- if (data == dev.Sig[0]) {
- j=1;
- } else {
- j=0;
- }
- }
- }
-
- if (j!=sigLength) {
- status = -ENODEV; /* search failed */
- }
-
- } else { /* use new srom */
- short *p = (short *)&lp->srom;
- for (i=0; i<(sizeof(struct de4x5_srom)>>1); i++) {
- *p++ = srom_rd(aprom_addr, i);
- }
- }
-
- return status;
-}
-
-static int get_hw_addr(struct device *dev)
-{
- u_long iobase = dev->base_addr;
- int i, k, tmp, status = 0;
- u_short j,chksum;
- struct bus_type *lp = &bus;
-
- for (i=0,k=0,j=0;j<3;j++) {
- k <<= 1 ;
- if (k > 0xffff) k-=0xffff;
-
- if (lp->bus == PCI) {
- if (lp->chipset == DC21040) {
- while ((tmp = inl(DE4X5_APROM)) < 0);
- k += (u_char) tmp;
- dev->dev_addr[i++] = (u_char) tmp;
- while ((tmp = inl(DE4X5_APROM)) < 0);
- k += (u_short) (tmp << 8);
- dev->dev_addr[i++] = (u_char) tmp;
- } else {
- dev->dev_addr[i] = (u_char) lp->srom.ieee_addr[i]; i++;
- dev->dev_addr[i] = (u_char) lp->srom.ieee_addr[i]; i++;
- }
- } else {
- k += (u_char) (tmp = inb(EISA_APROM));
- dev->dev_addr[i++] = (u_char) tmp;
- k += (u_short) ((tmp = inb(EISA_APROM)) << 8);
- dev->dev_addr[i++] = (u_char) tmp;
- }
-
- if (k > 0xffff) k-=0xffff;
- }
- if (k == 0xffff) k=0;
-
- if (lp->bus == PCI) {
- if (lp->chipset == DC21040) {
- while ((tmp = inl(DE4X5_APROM)) < 0);
- chksum = (u_char) tmp;
- while ((tmp = inl(DE4X5_APROM)) < 0);
- chksum |= (u_short) (tmp << 8);
- if (k != chksum) status = -1;
- }
- } else {
- chksum = (u_char) inb(EISA_APROM);
- chksum |= (u_short) (inb(EISA_APROM) << 8);
- if (k != chksum) status = -1;
- }
-
-
- return status;
-}
-
-/*
-** SROM Read
-*/
-static short srom_rd(u_long addr, u_char offset)
-{
- sendto_srom(SROM_RD | SROM_SR, addr);
-
- srom_latch(SROM_RD | SROM_SR | DT_CS, addr);
- srom_command(SROM_RD | SROM_SR | DT_IN | DT_CS, addr);
- srom_address(SROM_RD | SROM_SR | DT_CS, addr, offset);
-
- return srom_data(SROM_RD | SROM_SR | DT_CS, addr);
-}
-
-static void srom_latch(u_int command, u_long addr)
-{
- sendto_srom(command, addr);
- sendto_srom(command | DT_CLK, addr);
- sendto_srom(command, addr);
-
- return;
-}
-
-static void srom_command(u_int command, u_long addr)
-{
- srom_latch(command, addr);
- srom_latch(command, addr);
- srom_latch((command & 0x0000ff00) | DT_CS, addr);
-
- return;
-}
-
-static void srom_address(u_int command, u_long addr, u_char offset)
-{
- int i;
- char a;
-
- a = (char)(offset << 2);
- for (i=0; i<6; i++, a <<= 1) {
- srom_latch(command | ((a < 0) ? DT_IN : 0), addr);
- }
- dce_us_delay(1);
-
- i = (getfrom_srom(addr) >> 3) & 0x01;
- if (i != 0) {
- printk("Bad SROM address phase.....\n");
-/* printk(".");*/
- }
-
- return;
-}
-
-static short srom_data(u_int command, u_long addr)
-{
- int i;
- short word = 0;
- s32 tmp;
-
- for (i=0; i<16; i++) {
- sendto_srom(command | DT_CLK, addr);
- tmp = getfrom_srom(addr);
- sendto_srom(command, addr);
-
- word = (word << 1) | ((tmp >> 3) & 0x01);
- }
-
- sendto_srom(command & 0x0000ff00, addr);
-
- return word;
-}
-
-/*
-static void srom_busy(u_int command, u_long addr)
-{
- sendto_srom((command & 0x0000ff00) | DT_CS, addr);
-
- while (!((getfrom_srom(addr) >> 3) & 0x01)) {
- dce_ms_delay(1);
- }
-
- sendto_srom(command & 0x0000ff00, addr);
-
- return;
-}
-*/
-
-static void sendto_srom(u_int command, u_long addr)
-{
- outl(command, addr);
- dce_us_delay(1);
-
- return;
-}
-
-static int getfrom_srom(u_long addr)
-{
- s32 tmp;
-
- tmp = inl(addr);
- dce_us_delay(1);
-
- return tmp;
-}
-
-static char *build_setup_frame(struct device *dev, int mode)
-{
- struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
- int i;
- char *pa = lp->setup_frame;
-
- /* Initialise the setup frame */
- if (mode == ALL) {
- memset(lp->setup_frame, 0, SETUP_FRAME_LEN);
- }
-
- if (lp->setup_f == HASH_PERF) {
- for (pa=lp->setup_frame+IMPERF_PA_OFFSET, i=0; i<ETH_ALEN; i++) {
- *(pa + i) = dev->dev_addr[i]; /* Host address */
- if (i & 0x01) pa += 2;
- }
- *(lp->setup_frame + (HASH_TABLE_LEN >> 3) - 3) = 0x80; /* B'cast address */
- } else {
- for (i=0; i<ETH_ALEN; i++) { /* Host address */
- *(pa + (i&1)) = dev->dev_addr[i];
- if (i & 0x01) pa += 4;
- }
- for (i=0; i<ETH_ALEN; i++) { /* Broadcast address */
- *(pa + (i&1)) = (char) 0xff;
- if (i & 0x01) pa += 4;
- }
- }
-
- return pa; /* Points to the next entry */
-}
-
-static void enable_ast(struct device *dev, u32 time_out)
-{
- struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
- u_long iobase = dev->base_addr;
-
- lp->irq_mask |= IMR_TMM;
- outl(lp->irq_mask, DE4X5_IMR);
- load_ms_timer(dev, time_out);
-
- return;
-}
-
-static void disable_ast(struct device *dev)
-{
- struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
- u_long iobase = dev->base_addr;
-
- lp->irq_mask &= ~IMR_TMM;
- outl(lp->irq_mask, DE4X5_IMR);
- load_ms_timer(dev, 0);
-
- return;
-}
-
-static void kick_tx(struct device *dev)
-{
- struct sk_buff *skb;
-
- if ((skb = alloc_skb(0, GFP_ATOMIC)) != NULL) {
- skb->len= FAKE_FRAME_LEN;
- skb->arp=1;
- skb->dev=dev;
- dev_queue_xmit(skb, dev, SOPRI_NORMAL);
- }
-
- return;
-}
-
-/*
-** Perform IOCTL call functions here. Some are privileged operations and the
-** effective uid is checked in those cases.
-*/
-static int de4x5_ioctl(struct device *dev, struct ifreq *rq, int cmd)
-{
- struct de4x5_private *lp = (struct de4x5_private *)dev->priv;
- struct de4x5_ioctl *ioc = (struct de4x5_ioctl *) &rq->ifr_data;
- u_long iobase = dev->base_addr;
- int i, j, status = 0;
- s32 omr;
- union {
- u8 addr[(HASH_TABLE_LEN * ETH_ALEN)];
- u16 sval[(HASH_TABLE_LEN * ETH_ALEN) >> 1];
- u32 lval[(HASH_TABLE_LEN * ETH_ALEN) >> 2];
- } tmp;
-
- switch(ioc->cmd) {
- case DE4X5_GET_HWADDR: /* Get the hardware address */
- ioc->len = ETH_ALEN;
- status = verify_area(VERIFY_WRITE, (void *)ioc->data, ioc->len);
- if (status)
- break;
- for (i=0; i<ETH_ALEN; i++) {
- tmp.addr[i] = dev->dev_addr[i];
- }
- memcpy_tofs(ioc->data, tmp.addr, ioc->len);
-
- break;
- case DE4X5_SET_HWADDR: /* Set the hardware address */
- status = verify_area(VERIFY_READ, (void *)ioc->data, ETH_ALEN);
- if (status)
- break;
- status = -EPERM;
- if (!suser())
- break;
- status = 0;
- memcpy_fromfs(tmp.addr, ioc->data, ETH_ALEN);
- for (i=0; i<ETH_ALEN; i++) {
- dev->dev_addr[i] = tmp.addr[i];
- }
- build_setup_frame(dev, PHYS_ADDR_ONLY);
- /* Set up the descriptor and give ownership to the card */
- while (set_bit(0, (void *)&dev->tbusy) != 0);/* Wait for lock to free*/
- if (lp->setup_f == HASH_PERF) {
- load_packet(dev, lp->setup_frame, TD_IC | HASH_F | TD_SET |
- SETUP_FRAME_LEN, NULL);
- } else {
- load_packet(dev, lp->setup_frame, TD_IC | PERFECT_F | TD_SET |
- SETUP_FRAME_LEN, NULL);
- }
- lp->tx_new = (++lp->tx_new) % lp->txRingSize;
- outl(POLL_DEMAND, DE4X5_TPD); /* Start the TX */
- dev->tbusy = 0; /* Unlock the TX ring */
-
- break;
- case DE4X5_SET_PROM: /* Set Promiscuous Mode */
- if (suser()) {
- omr = inl(DE4X5_OMR);
- omr |= OMR_PR;
- outl(omr, DE4X5_OMR);
- } else {
- status = -EPERM;
- }
-
- break;
- case DE4X5_CLR_PROM: /* Clear Promiscuous Mode */
- if (suser()) {
- omr = inl(DE4X5_OMR);
- omr &= ~OMR_PR;
- outb(omr, DE4X5_OMR);
- } else {
- status = -EPERM;
- }
-
- break;
- case DE4X5_SAY_BOO: /* Say "Boo!" to the kernel log file */
- printk("%s: Boo!\n", dev->name);
-
- break;
- case DE4X5_GET_MCA: /* Get the multicast address table */
- ioc->len = (HASH_TABLE_LEN >> 3);
- status = verify_area(VERIFY_WRITE, ioc->data, ioc->len);
- if (status)
- break;
- memcpy_tofs(ioc->data, lp->setup_frame, ioc->len);
-
- break;
- case DE4X5_SET_MCA: /* Set a multicast address */
- if (suser()) {
- if (ioc->len != HASH_TABLE_LEN) { /* MCA changes */
- if (!(status = verify_area(VERIFY_READ, (void *)ioc->data, ETH_ALEN * ioc->len))) {
- memcpy_fromfs(tmp.addr, ioc->data, ETH_ALEN * ioc->len);
- set_multicast_list(dev);
- }
- } else {
- set_multicast_list(dev);
- }
- } else {
- status = -EPERM;
- }
-
- break;
- case DE4X5_CLR_MCA: /* Clear all multicast addresses */
- if (suser()) {
- set_multicast_list(dev);
- } else {
- status = -EPERM;
- }
-
- break;
- case DE4X5_MCA_EN: /* Enable pass all multicast addressing */
- if (suser()) {
- omr = inl(DE4X5_OMR);
- omr |= OMR_PM;
- outl(omr, DE4X5_OMR);
- } else {
- status = -EPERM;
- }
-
- break;
- case DE4X5_GET_STATS: /* Get the driver statistics */
- ioc->len = sizeof(lp->pktStats);
- status = verify_area(VERIFY_WRITE, (void *)ioc->data, ioc->len);
- if (status)
- break;
-
- cli();
- memcpy_tofs(ioc->data, &lp->pktStats, ioc->len);
- sti();
-
- break;
- case DE4X5_CLR_STATS: /* Zero out the driver statistics */
- if (suser()) {
- cli();
- memset(&lp->pktStats, 0, sizeof(lp->pktStats));
- sti();
- } else {
- status = -EPERM;
- }
-
- break;
- case DE4X5_GET_OMR: /* Get the OMR Register contents */
- tmp.addr[0] = inl(DE4X5_OMR);
- if (!(status = verify_area(VERIFY_WRITE, (void *)ioc->data, 1))) {
- memcpy_tofs(ioc->data, tmp.addr, 1);
- }
-
- break;
- case DE4X5_SET_OMR: /* Set the OMR Register contents */
- if (suser()) {
- if (!(status = verify_area(VERIFY_READ, (void *)ioc->data, 1))) {
- memcpy_fromfs(tmp.addr, ioc->data, 1);
- outl(tmp.addr[0], DE4X5_OMR);
- }
- } else {
- status = -EPERM;
- }
-
- break;
- case DE4X5_GET_REG: /* Get the DE4X5 Registers */
- j = 0;
- tmp.lval[0] = inl(DE4X5_STS); j+=4;
- tmp.lval[1] = inl(DE4X5_BMR); j+=4;
- tmp.lval[2] = inl(DE4X5_IMR); j+=4;
- tmp.lval[3] = inl(DE4X5_OMR); j+=4;
- tmp.lval[4] = inl(DE4X5_SISR); j+=4;
- tmp.lval[5] = inl(DE4X5_SICR); j+=4;
- tmp.lval[6] = inl(DE4X5_STRR); j+=4;
- tmp.lval[7] = inl(DE4X5_SIGR); j+=4;
- ioc->len = j;
- if (!(status = verify_area(VERIFY_WRITE, (void *)ioc->data, ioc->len))) {
- memcpy_tofs(ioc->data, tmp.addr, ioc->len);
- }
- break;
-
-#define DE4X5_DUMP 0x0f /* Dump the DE4X5 Status */
-
- case DE4X5_DUMP:
- j = 0;
- tmp.addr[j++] = dev->irq;
- for (i=0; i<ETH_ALEN; i++) {
- tmp.addr[j++] = dev->dev_addr[i];
- }
- tmp.addr[j++] = lp->rxRingSize;
- tmp.lval[j>>2] = (long)lp->rx_ring; j+=4;
- tmp.lval[j>>2] = (long)lp->tx_ring; j+=4;
-
- for (i=0;i<lp->rxRingSize-1;i++){
- if (i < 3) {
- tmp.lval[j>>2] = (long)&lp->rx_ring[i].status; j+=4;
- }
- }
- tmp.lval[j>>2] = (long)&lp->rx_ring[i].status; j+=4;
- for (i=0;i<lp->txRingSize-1;i++){
- if (i < 3) {
- tmp.lval[j>>2] = (long)&lp->tx_ring[i].status; j+=4;
- }
- }
- tmp.lval[j>>2] = (long)&lp->tx_ring[i].status; j+=4;
-
- for (i=0;i<lp->rxRingSize-1;i++){
- if (i < 3) {
- tmp.lval[j>>2] = (s32)lp->rx_ring[i].buf; j+=4;
- }
- }
- tmp.lval[j>>2] = (s32)lp->rx_ring[i].buf; j+=4;
- for (i=0;i<lp->txRingSize-1;i++){
- if (i < 3) {
- tmp.lval[j>>2] = (s32)lp->tx_ring[i].buf; j+=4;
- }
- }
- tmp.lval[j>>2] = (s32)lp->tx_ring[i].buf; j+=4;
-
- for (i=0;i<lp->rxRingSize;i++){
- tmp.lval[j>>2] = lp->rx_ring[i].status; j+=4;
- }
- for (i=0;i<lp->txRingSize;i++){
- tmp.lval[j>>2] = lp->tx_ring[i].status; j+=4;
- }
-
- tmp.lval[j>>2] = inl(DE4X5_STS); j+=4;
- tmp.lval[j>>2] = inl(DE4X5_BMR); j+=4;
- tmp.lval[j>>2] = inl(DE4X5_IMR); j+=4;
- tmp.lval[j>>2] = inl(DE4X5_OMR); j+=4;
- tmp.lval[j>>2] = inl(DE4X5_SISR); j+=4;
- tmp.lval[j>>2] = inl(DE4X5_SICR); j+=4;
- tmp.lval[j>>2] = inl(DE4X5_STRR); j+=4;
- tmp.lval[j>>2] = inl(DE4X5_SIGR); j+=4;
-
- tmp.addr[j++] = lp->txRingSize;
- tmp.addr[j++] = dev->tbusy;
-
- ioc->len = j;
- if (!(status = verify_area(VERIFY_WRITE, (void *)ioc->data, ioc->len))) {
- memcpy_tofs(ioc->data, tmp.addr, ioc->len);
- }
-
- break;
- default:
- status = -EOPNOTSUPP;
- }
-
- return status;
-}
-
-#ifdef MODULE
-static char devicename[9] = { 0, };
-static struct device thisDE4X5 = {
- devicename, /* device name is inserted by linux/drivers/net/net_init.c */
- 0, 0, 0, 0,
- 0x2000, 10, /* I/O address, IRQ */
- 0, 0, 0, NULL, de4x5_probe };
-
-static int io=0x000b; /* EDIT THESE LINES FOR YOUR CONFIGURATION */
-static int irq=10; /* or use the insmod io= irq= options */
-
-int
-init_module(void)
-{
- thisDE4X5.base_addr=io;
- thisDE4X5.irq=irq;
- if (register_netdev(&thisDE4X5) != 0)
- return -EIO;
- return 0;
-}
-
-void
-cleanup_module(void)
-{
- struct de4x5_private *lp = (struct de4x5_private *) thisDE4X5.priv;
-
- if (lp) {
- kfree_s(bus_to_virt(lp->rx_ring[0].buf), RX_BUFF_SZ * NUM_RX_DESC + ALIGN);
- }
- kfree_s(thisDE4X5.priv, sizeof(struct de4x5_private) + ALIGN);
- thisDE4X5.priv = NULL;
-
- release_region(thisDE4X5.base_addr, (lp->bus == PCI ?
- DE4X5_PCI_TOTAL_SIZE :
- DE4X5_EISA_TOTAL_SIZE));
- unregister_netdev(&thisDE4X5);
-}
-#endif /* MODULE */
-
-
-/*
- * Local variables:
- * kernel-compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de4x5.c"
- *
- * module-compile-command: "gcc -D__KERNEL__ -DMODULE -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de4x5.c"
- * End:
- */
-
-
diff --git a/i386/i386at/gpl/linux/net/de4x5.h b/i386/i386at/gpl/linux/net/de4x5.h
deleted file mode 100644
index b0ee43ea..00000000
--- a/i386/i386at/gpl/linux/net/de4x5.h
+++ /dev/null
@@ -1,645 +0,0 @@
-/*
- Copyright 1994 Digital Equipment Corporation.
-
- This software may be used and distributed according to the terms of the
- GNU Public License, incorporated herein by reference.
-
- The author may be reached as davies@wanton.lkg.dec.com or Digital
- Equipment Corporation, 550 King Street, Littleton MA 01460.
-
- =========================================================================
-*/
-
-/*
-** DC21040 CSR<1..15> Register Address Map
-*/
-#define DE4X5_BMR iobase+(0x000 << lp->bus) /* Bus Mode Register */
-#define DE4X5_TPD iobase+(0x008 << lp->bus) /* Transmit Poll Demand Reg */
-#define DE4X5_RPD iobase+(0x010 << lp->bus) /* Receive Poll Demand Reg */
-#define DE4X5_RRBA iobase+(0x018 << lp->bus) /* RX Ring Base Address Reg */
-#define DE4X5_TRBA iobase+(0x020 << lp->bus) /* TX Ring Base Address Reg */
-#define DE4X5_STS iobase+(0x028 << lp->bus) /* Status Register */
-#define DE4X5_OMR iobase+(0x030 << lp->bus) /* Operation Mode Register */
-#define DE4X5_IMR iobase+(0x038 << lp->bus) /* Interrupt Mask Register */
-#define DE4X5_MFC iobase+(0x040 << lp->bus) /* Missed Frame Counter */
-#define DE4X5_APROM iobase+(0x048 << lp->bus) /* Ethernet Address PROM */
-#define DE4X5_BROM iobase+(0x048 << lp->bus) /* Boot ROM Register */
-#define DE4X5_SROM iobase+(0x048 << lp->bus) /* Serial ROM Register */
-#define DE4X5_DDR iobase+(0x050 << lp->bus) /* Data Diagnostic Register */
-#define DE4X5_FDR iobase+(0x058 << lp->bus) /* Full Duplex Register */
-#define DE4X5_GPT iobase+(0x058 << lp->bus) /* General Purpose Timer Reg.*/
-#define DE4X5_GEP iobase+(0x060 << lp->bus) /* General Purpose Register */
-#define DE4X5_SISR iobase+(0x060 << lp->bus) /* SIA Status Register */
-#define DE4X5_SICR iobase+(0x068 << lp->bus) /* SIA Connectivity Register */
-#define DE4X5_STRR iobase+(0x070 << lp->bus) /* SIA TX/RX Register */
-#define DE4X5_SIGR iobase+(0x078 << lp->bus) /* SIA General Register */
-
-/*
-** EISA Register Address Map
-*/
-#define EISA_ID iobase+0x0c80 /* EISA ID Registers */
-#define EISA_ID0 iobase+0x0c80 /* EISA ID Register 0 */
-#define EISA_ID1 iobase+0x0c81 /* EISA ID Register 1 */
-#define EISA_ID2 iobase+0x0c82 /* EISA ID Register 2 */
-#define EISA_ID3 iobase+0x0c83 /* EISA ID Register 3 */
-#define EISA_CR iobase+0x0c84 /* EISA Control Register */
-#define EISA_REG0 iobase+0x0c88 /* EISA Configuration Register 0 */
-#define EISA_REG1 iobase+0x0c89 /* EISA Configuration Register 1 */
-#define EISA_REG2 iobase+0x0c8a /* EISA Configuration Register 2 */
-#define EISA_REG3 iobase+0x0c8f /* EISA Configuration Register 3 */
-#define EISA_APROM iobase+0x0c90 /* Ethernet Address PROM */
-
-/*
-** PCI/EISA Configuration Registers Address Map
-*/
-#define PCI_CFID iobase+0x0008 /* PCI Configuration ID Register */
-#define PCI_CFCS iobase+0x000c /* PCI Command/Status Register */
-#define PCI_CFRV iobase+0x0018 /* PCI Revision Register */
-#define PCI_CFLT iobase+0x001c /* PCI Latency Timer Register */
-#define PCI_CBIO iobase+0x0028 /* PCI Base I/O Register */
-#define PCI_CBMA iobase+0x002c /* PCI Base Memory Address Register */
-#define PCI_CBER iobase+0x0030 /* PCI Expansion ROM Base Address Reg. */
-#define PCI_CFIT iobase+0x003c /* PCI Configuration Interrupt Register */
-#define PCI_CFDA iobase+0x0040 /* PCI Driver Area Register */
-
-/*
-** EISA Configuration Register 0 bit definitions
-*/
-#define ER0_BSW 0x80 /* EISA Bus Slave Width, 1: 32 bits */
-#define ER0_BMW 0x40 /* EISA Bus Master Width, 1: 32 bits */
-#define ER0_EPT 0x20 /* EISA PREEMPT Time, 0: 23 BCLKs */
-#define ER0_ISTS 0x10 /* Interrupt Status (X) */
-#define ER0_LI 0x08 /* Latch Interrupts */
-#define ER0_INTL 0x06 /* INTerrupt Level */
-#define ER0_INTT 0x01 /* INTerrupt Type, 0: Level, 1: Edge */
-
-/*
-** EISA Configuration Register 1 bit definitions
-*/
-#define ER1_IAM 0xe0 /* ISA Address Mode */
-#define ER1_IAE 0x10 /* ISA Addressing Enable */
-#define ER1_UPIN 0x0f /* User Pins */
-
-/*
-** EISA Configuration Register 2 bit definitions
-*/
-#define ER2_BRS 0xc0 /* Boot ROM Size */
-#define ER2_BRA 0x3c /* Boot ROM Address <16:13> */
-
-/*
-** EISA Configuration Register 3 bit definitions
-*/
-#define ER3_BWE 0x40 /* Burst Write Enable */
-#define ER3_BRE 0x04 /* Burst Read Enable */
-#define ER3_LSR 0x02 /* Local Software Reset */
-
-/*
-** PCI Configuration ID Register (PCI_CFID)
-*/
-#define CFID_DID 0xff00 /* Device ID */
-#define CFID_VID 0x00ff /* Vendor ID */
-#define DC21040_DID 0x0002 /* Unique Device ID # */
-#define DC21040_VID 0x1011 /* DC21040 Manufacturer */
-#define DC21041_DID 0x0014 /* Unique Device ID # */
-#define DC21041_VID 0x1011 /* DC21041 Manufacturer */
-#define DC21140_DID 0x0009 /* Unique Device ID # */
-#define DC21140_VID 0x1011 /* DC21140 Manufacturer */
-
-/*
-** Chipset defines
-*/
-#define DC21040 DC21040_DID
-#define DC21041 DC21041_DID
-#define DC21140 DC21140_DID
-
-#define is_DC21040 ((vendor == DC21040_VID) && (device == DC21040_DID))
-#define is_DC21041 ((vendor == DC21041_VID) && (device == DC21041_DID))
-#define is_DC21140 ((vendor == DC21140_VID) && (device == DC21140_DID))
-
-/*
-** PCI Configuration Command/Status Register (PCI_CFCS)
-*/
-#define CFCS_DPE 0x80000000 /* Detected Parity Error (S) */
-#define CFCS_SSE 0x40000000 /* Signal System Error (S) */
-#define CFCS_RMA 0x20000000 /* Receive Master Abort (S) */
-#define CFCS_RTA 0x10000000 /* Receive Target Abort (S) */
-#define CFCS_DST 0x06000000 /* DEVSEL Timing (S) */
-#define CFCS_DPR 0x01000000 /* Data Parity Report (S) */
-#define CFCS_FBB 0x00800000 /* Fast Back-To-Back (S) */
-#define CFCS_SLE 0x00000100 /* System Error Enable (C) */
-#define CFCS_PER 0x00000040 /* Parity Error Response (C) */
-#define CFCS_MO 0x00000004 /* Master Operation (C) */
-#define CFCS_MSA 0x00000002 /* Memory Space Access (C) */
-#define CFCS_IOSA 0x00000001 /* I/O Space Access (C) */
-
-/*
-** PCI Configuration Revision Register (PCI_CFRV)
-*/
-#define CFRV_BC 0xff000000 /* Base Class */
-#define CFRV_SC 0x00ff0000 /* Subclass */
-#define CFRV_SN 0x000000f0 /* Step Number */
-#define CFRV_RN 0x0000000f /* Revision Number */
-#define BASE_CLASS 0x02000000 /* Indicates Network Controller */
-#define SUB_CLASS 0x00000000 /* Indicates Ethernet Controller */
-#define STEP_NUMBER 0x00000020 /* Increments for future chips */
-#define REV_NUMBER 0x00000003 /* 0x00, 0x01, 0x02, 0x03: Rev in Step */
-#define CFRV_MASK 0xffff0000 /* Register mask */
-
-/*
-** PCI Configuration Latency Timer Register (PCI_CFLT)
-*/
-#define CFLT_BC 0x0000ff00 /* Latency Timer bits */
-
-/*
-** PCI Configuration Base I/O Address Register (PCI_CBIO)
-*/
-#define CBIO_MASK 0xffffff80 /* Base I/O Address Mask */
-#define CBIO_IOSI 0x00000001 /* I/O Space Indicator (RO, value is 1) */
-
-/*
-** PCI Configuration Expansion ROM Base Address Register (PCI_CBER)
-*/
-#define CBER_MASK 0xfffffc00 /* Expansion ROM Base Address Mask */
-#define CBER_ROME 0x00000001 /* ROM Enable */
-
-/*
-** PCI Configuration Driver Area Register (PCI_CFDA)
-*/
-#define CFDA_PSM 0x80000000 /* Power Saving Mode */
-
-/*
-** DC21040 Bus Mode Register (DE4X5_BMR)
-*/
-#define BMR_DBO 0x00100000 /* Descriptor Byte Ordering (Endian) */
-#define BMR_TAP 0x000e0000 /* Transmit Automatic Polling */
-#define BMR_DAS 0x00010000 /* Diagnostic Address Space */
-#define BMR_CAL 0x0000c000 /* Cache Alignment */
-#define BMR_PBL 0x00003f00 /* Programmable Burst Length */
-#define BMR_BLE 0x00000080 /* Big/Little Endian */
-#define BMR_DSL 0x0000007c /* Descriptor Skip Length */
-#define BMR_BAR 0x00000002 /* Bus ARbitration */
-#define BMR_SWR 0x00000001 /* Software Reset */
-
-#define TAP_NOPOLL 0x00000000 /* No automatic polling */
-#define TAP_200US 0x00020000 /* TX automatic polling every 200us */
-#define TAP_800US 0x00040000 /* TX automatic polling every 800us */
-#define TAP_1_6MS 0x00060000 /* TX automatic polling every 1.6ms */
-#define TAP_12_8US 0x00080000 /* TX automatic polling every 12.8us */
-#define TAP_25_6US 0x000a0000 /* TX automatic polling every 25.6us */
-#define TAP_51_2US 0x000c0000 /* TX automatic polling every 51.2us */
-#define TAP_102_4US 0x000e0000 /* TX automatic polling every 102.4us */
-
-#define CAL_NOUSE 0x00000000 /* Not used */
-#define CAL_8LONG 0x00004000 /* 8-longword alignment */
-#define CAL_16LONG 0x00008000 /* 16-longword alignment */
-#define CAL_32LONG 0x0000c000 /* 32-longword alignment */
-
-#define PBL_0 0x00000000 /* DMA burst length = amount in RX FIFO */
-#define PBL_1 0x00000100 /* 1 longword DMA burst length */
-#define PBL_2 0x00000200 /* 2 longwords DMA burst length */
-#define PBL_4 0x00000400 /* 4 longwords DMA burst length */
-#define PBL_8 0x00000800 /* 8 longwords DMA burst length */
-#define PBL_16 0x00001000 /* 16 longwords DMA burst length */
-#define PBL_32 0x00002000 /* 32 longwords DMA burst length */
-
-#define DSL_0 0x00000000 /* 0 longword / descriptor */
-#define DSL_1 0x00000004 /* 1 longword / descriptor */
-#define DSL_2 0x00000008 /* 2 longwords / descriptor */
-#define DSL_4 0x00000010 /* 4 longwords / descriptor */
-#define DSL_8 0x00000020 /* 8 longwords / descriptor */
-#define DSL_16 0x00000040 /* 16 longwords / descriptor */
-#define DSL_32 0x00000080 /* 32 longwords / descriptor */
-
-/*
-** DC21040 Transmit Poll Demand Register (DE4X5_TPD)
-*/
-#define TPD 0x00000001 /* Transmit Poll Demand */
-
-/*
-** DC21040 Receive Poll Demand Register (DE4X5_RPD)
-*/
-#define RPD 0x00000001 /* Receive Poll Demand */
-
-/*
-** DC21040 Receive Ring Base Address Register (DE4X5_RRBA)
-*/
-#define RRBA 0xfffffffc /* RX Descriptor List Start Address */
-
-/*
-** DC21040 Transmit Ring Base Address Register (DE4X5_TRBA)
-*/
-#define TRBA 0xfffffffc /* TX Descriptor List Start Address */
-
-/*
-** DC21040 Status Register (DE4X5_STS)
-*/
-#define STS_BE 0x03800000 /* Bus Error Bits */
-#define STS_TS 0x00700000 /* Transmit Process State */
-#define STS_RS 0x000e0000 /* Receive Process State */
-#define STS_NIS 0x00010000 /* Normal Interrupt Summary */
-#define STS_AIS 0x00008000 /* Abnormal Interrupt Summary */
-#define STS_ER 0x00004000 /* Early Receive */
-#define STS_SE 0x00002000 /* System Error */
-#define STS_LNF 0x00001000 /* Link Fail */
-#define STS_FD 0x00000800 /* Full-Duplex Short Frame Received */
-#define STS_TM 0x00000800 /* Timer Expired (DC21041) */
-#define STS_AT 0x00000400 /* AUI/TP Pin */
-#define STS_RWT 0x00000200 /* Receive Watchdog Time-Out */
-#define STS_RPS 0x00000100 /* Receive Process Stopped */
-#define STS_RU 0x00000080 /* Receive Buffer Unavailable */
-#define STS_RI 0x00000040 /* Receive Interrupt */
-#define STS_UNF 0x00000020 /* Transmit Underflow */
-#define STS_LNP 0x00000010 /* Link Pass */
-#define STS_TJT 0x00000008 /* Transmit Jabber Time-Out */
-#define STS_TU 0x00000004 /* Transmit Buffer Unavailable */
-#define STS_TPS 0x00000002 /* Transmit Process Stopped */
-#define STS_TI 0x00000001 /* Transmit Interrupt */
-
-#define EB_PAR 0x00000000 /* Parity Error */
-#define EB_MA 0x00800000 /* Master Abort */
-#define EB_TA 0x01000000 /* Target Abort */
-#define EB_RES0 0x01800000 /* Reserved */
-#define EB_RES1 0x02000000 /* Reserved */
-
-#define TS_STOP 0x00000000 /* Stopped */
-#define TS_FTD 0x00100000 /* Fetch Transmit Descriptor */
-#define TS_WEOT 0x00200000 /* Wait for End Of Transmission */
-#define TS_QDAT 0x00300000 /* Queue skb data into TX FIFO */
-#define TS_RES 0x00400000 /* Reserved */
-#define TS_SPKT 0x00500000 /* Setup Packet */
-#define TS_SUSP 0x00600000 /* Suspended */
-#define TS_CLTD 0x00700000 /* Close Transmit Descriptor */
-
-#define RS_STOP 0x00000000 /* Stopped */
-#define RS_FRD 0x00020000 /* Fetch Receive Descriptor */
-#define RS_CEOR 0x00040000 /* Check for End of Receive Packet */
-#define RS_WFRP 0x00060000 /* Wait for Receive Packet */
-#define RS_SUSP 0x00080000 /* Suspended */
-#define RS_CLRD 0x000a0000 /* Close Receive Descriptor */
-#define RS_FLUSH 0x000c0000 /* Flush RX FIFO */
-#define RS_QRFS 0x000e0000 /* Queue RX FIFO into RX Skb */
-
-#define INT_CANCEL 0x0001ffff /* For zeroing all interrupt sources */
-
-/*
-** DC21040 Operation Mode Register (DE4X5_OMR)
-*/
-#define OMR_SDP 0x02000000 /* SD Polarity - MUST BE ASSERTED */
-#define OMR_SCR 0x01000000 /* Scrambler Mode */
-#define OMR_PCS 0x00800000 /* PCS Function */
-#define OMR_TTM 0x00400000 /* Transmit Threshold Mode */
-#define OMR_SF 0x00200000 /* Store and Forward */
-#define OMR_HBD 0x00080000 /* HeartBeat Disable */
-#define OMR_PS 0x00040000 /* Port Select */
-#define OMR_CA 0x00020000 /* Capture Effect Enable */
-#define OMR_BP 0x00010000 /* Back Pressure */
-#define OMR_TR 0x0000c000 /* Threshold Control Bits */
-#define OMR_ST 0x00002000 /* Start/Stop Transmission Command */
-#define OMR_FC 0x00001000 /* Force Collision Mode */
-#define OMR_OM 0x00000c00 /* Operating Mode */
-#define OMR_FD 0x00000200 /* Full Duplex Mode */
-#define OMR_FKD 0x00000100 /* Flaky Oscillator Disable */
-#define OMR_PM 0x00000080 /* Pass All Multicast */
-#define OMR_PR 0x00000040 /* Promiscuous Mode */
-#define OMR_SB 0x00000020 /* Start/Stop Backoff Counter */
-#define OMR_IF 0x00000010 /* Inverse Filtering */
-#define OMR_PB 0x00000008 /* Pass Bad Frames */
-#define OMR_HO 0x00000004 /* Hash Only Filtering Mode */
-#define OMR_SR 0x00000002 /* Start/Stop Receive */
-#define OMR_HP 0x00000001 /* Hash/Perfect Receive Filtering Mode */
-
-#define TR_72 0x00000000 /* Threshold set to 72 bytes */
-#define TR_96 0x00004000 /* Threshold set to 96 bytes */
-#define TR_128 0x00008000 /* Threshold set to 128 bytes */
-#define TR_160 0x0000c000 /* Threshold set to 160 bytes */
-
-/*
-** DC21040 Interrupt Mask Register (DE4X5_IMR)
-*/
-#define IMR_NIM 0x00010000 /* Normal Interrupt Summary Mask */
-#define IMR_AIM 0x00008000 /* Abnormal Interrupt Summary Mask */
-#define IMR_ERM 0x00004000 /* Early Receive Mask */
-#define IMR_SEM 0x00002000 /* System Error Mask */
-#define IMR_LFM 0x00001000 /* Link Fail Mask */
-#define IMR_FDM 0x00000800 /* Full-Duplex (Short Frame) Mask */
-#define IMR_TMM 0x00000800 /* Timer Expired Mask (DC21041) */
-#define IMR_ATM 0x00000400 /* AUI/TP Switch Mask */
-#define IMR_RWM 0x00000200 /* Receive Watchdog Time-Out Mask */
-#define IMR_RSM 0x00000100 /* Receive Stopped Mask */
-#define IMR_RUM 0x00000080 /* Receive Buffer Unavailable Mask */
-#define IMR_RIM 0x00000040 /* Receive Interrupt Mask */
-#define IMR_UNM 0x00000020 /* Underflow Interrupt Mask */
-#define IMR_LPM 0x00000010 /* Link Pass */
-#define IMR_TJM 0x00000008 /* Transmit Time-Out Jabber Mask */
-#define IMR_TUM 0x00000004 /* Transmit Buffer Unavailable Mask */
-#define IMR_TSM 0x00000002 /* Transmission Stopped Mask */
-#define IMR_TIM 0x00000001 /* Transmit Interrupt Mask */
-
-/*
-** DC21040 Missed Frame Counter (DE4X5_MFC)
-*/
-#define MFC_OVFL 0x00010000 /* Counter Overflow Bit */
-#define MFC_CNTR 0x0000ffff /* Counter Bits */
-
-/*
-** DC21040 Ethernet Address PROM (DE4X5_APROM)
-*/
-#define APROM_DN 0x80000000 /* Data Not Valid */
-#define APROM_DT 0x000000ff /* Address Byte */
-
-/*
-** DC21041 Boot/Ethernet Address ROM (DE4X5_BROM)
-*/
-#define BROM_MODE 0x00008000 /* MODE_1: 0, MODE_0: 1 (read only) */
-#define BROM_RD 0x00004000 /* Read from Boot ROM */
-#define BROM_WR 0x00002000 /* Write to Boot ROM */
-#define BROM_BR 0x00001000 /* Select Boot ROM when set */
-#define BROM_SR 0x00000800 /* Select Serial ROM when set */
-#define BROM_REG 0x00000400 /* External Register Select */
-#define BROM_DT 0x000000ff /* Data Byte */
-
-/*
-** DC21041 Serial/Ethernet Address ROM (DE4X5_SROM)
-*/
-#define SROM_MODE 0x00008000 /* MODE_1: 0, MODE_0: 1 (read only) */
-#define SROM_RD 0x00004000 /* Read from Boot ROM */
-#define SROM_WR 0x00002000 /* Write to Boot ROM */
-#define SROM_BR 0x00001000 /* Select Boot ROM when set */
-#define SROM_SR 0x00000800 /* Select Serial ROM when set */
-#define SROM_REG 0x00000400 /* External Register Select */
-#define SROM_DT 0x000000ff /* Data Byte */
-
-#define DT_OUT 0x00000008 /* Serial Data Out */
-#define DT_IN 0x00000004 /* Serial Data In */
-#define DT_CLK 0x00000002 /* Serial ROM Clock */
-#define DT_CS 0x00000001 /* Serial ROM Chip Select */
-
-/*
-** DC21040 Full Duplex Register (DE4X5_FDR)
-*/
-#define FDR_FDACV 0x0000ffff /* Full Duplex Auto Configuration Value */
-
-/*
-** DC21041 General Purpose Timer Register (DE4X5_GPT)
-*/
-#define GPT_CON 0x00010000 /* One shot: 0, Continuous: 1 */
-#define GPT_VAL 0x0000ffff /* Timer Value */
-
-/*
-** DC21140 General Purpose Register (DE4X5_GEP) (hardware dependent bits)
-*/
-/* Valid ONLY for DE500 hardware */
-#define GEP_LNP 0x00000080 /* Link Pass (input) */
-#define GEP_SLNK 0x00000040 /* SYM LINK (input) */
-#define GEP_SDET 0x00000020 /* Signal Detect (input) */
-#define GEP_FDXD 0x00000008 /* Full Duplex Disable (output) */
-#define GEP_PHYL 0x00000004 /* PHY Loopback (output) */
-#define GEP_FLED 0x00000002 /* Force Activity LED on (output) */
-#define GEP_MODE 0x00000001 /* 0: 10Mb/s, 1: 100Mb/s */
-#define GEP_INIT 0x0000010f /* Setup inputs (0) and outputs (1) */
-
-
-/*
-** DC21040 SIA Status Register (DE4X5_SISR)
-*/
-#define SISR_LPC 0xffff0000 /* Link Partner's Code Word */
-#define SISR_LPN 0x00008000 /* Link Partner Negotiable */
-#define SISR_ANS 0x00007000 /* Auto Negotiation Arbitration State */
-#define SISR_NSN 0x00000800 /* Non Stable NLPs Detected */
-#define SISR_ANR_FDS 0x00000400 /* Auto Negotiate Restart/Full Duplex Sel.*/
-#define SISR_NRA 0x00000200 /* Non Selected Port Receive Activity */
-#define SISR_SRA 0x00000100 /* Selected Port Receive Activity */
-#define SISR_DAO 0x00000080 /* PLL All One */
-#define SISR_DAZ 0x00000040 /* PLL All Zero */
-#define SISR_DSP 0x00000020 /* PLL Self-Test Pass */
-#define SISR_DSD 0x00000010 /* PLL Self-Test Done */
-#define SISR_APS 0x00000008 /* Auto Polarity State */
-#define SISR_LKF 0x00000004 /* Link Fail Status */
-#define SISR_NCR 0x00000002 /* Network Connection Error */
-#define SISR_PAUI 0x00000001 /* AUI_TP Indication */
-#define SIA_RESET 0x00000000 /* SIA Reset */
-
-#define ANS_NDIS 0x00000000 /* Nway disable */
-#define ANS_TDIS 0x00001000 /* Transmit Disable */
-#define ANS_ADET 0x00002000 /* Ability Detect */
-#define ANS_ACK 0x00003000 /* Acknowledge */
-#define ANS_CACK 0x00004000 /* Complete Acknowledge */
-#define ANS_NWOK 0x00005000 /* Nway OK - FLP Link Good */
-#define ANS_LCHK 0x00006000 /* Link Check */
-
-/*
-** DC21040 SIA Connectivity Register (DE4X5_SICR)
-*/
-#define SICR_SDM 0xffff0000 /* SIA Diagnostics Mode */
-#define SICR_OE57 0x00008000 /* Output Enable 5 6 7 */
-#define SICR_OE24 0x00004000 /* Output Enable 2 4 */
-#define SICR_OE13 0x00002000 /* Output Enable 1 3 */
-#define SICR_IE 0x00001000 /* Input Enable */
-#define SICR_EXT 0x00000000 /* SIA MUX Select External SIA Mode */
-#define SICR_D_SIA 0x00000400 /* SIA MUX Select Diagnostics - SIA Sigs */
-#define SICR_DPLL 0x00000800 /* SIA MUX Select Diagnostics - DPLL Sigs*/
-#define SICR_APLL 0x00000a00 /* SIA MUX Select Diagnostics - DPLL Sigs*/
-#define SICR_D_RxM 0x00000c00 /* SIA MUX Select Diagnostics - RxM Sigs */
-#define SICR_M_RxM 0x00000d00 /* SIA MUX Select Diagnostics - RxM Sigs */
-#define SICR_LNKT 0x00000e00 /* SIA MUX Select Diagnostics - Link Test*/
-#define SICR_SEL 0x00000f00 /* SIA MUX Select AUI or TP with LEDs */
-#define SICR_ASE 0x00000080 /* APLL Start Enable*/
-#define SICR_SIM 0x00000040 /* Serial Interface Input Multiplexer */
-#define SICR_ENI 0x00000020 /* Encoder Input Multiplexer */
-#define SICR_EDP 0x00000010 /* SIA PLL External Input Enable */
-#define SICR_AUI 0x00000008 /* 10Base-T or AUI */
-#define SICR_CAC 0x00000004 /* CSR Auto Configuration */
-#define SICR_PS 0x00000002 /* Pin AUI/TP Selection */
-#define SICR_SRL 0x00000001 /* SIA Reset */
-#define SICR_RESET 0xffff0000 /* Reset value for SICR */
-
-/*
-** DC21040 SIA Transmit and Receive Register (DE4X5_STRR)
-*/
-#define STRR_TAS 0x00008000 /* 10Base-T/AUI Autosensing Enable */
-#define STRR_SPP 0x00004000 /* Set Polarity Plus */
-#define STRR_APE 0x00002000 /* Auto Polarity Enable */
-#define STRR_LTE 0x00001000 /* Link Test Enable */
-#define STRR_SQE 0x00000800 /* Signal Quality Enable */
-#define STRR_CLD 0x00000400 /* Collision Detect Enable */
-#define STRR_CSQ 0x00000200 /* Collision Squelch Enable */
-#define STRR_RSQ 0x00000100 /* Receive Squelch Enable */
-#define STRR_ANE 0x00000080 /* Auto Negotiate Enable */
-#define STRR_HDE 0x00000040 /* Half Duplex Enable */
-#define STRR_CPEN 0x00000030 /* Compensation Enable */
-#define STRR_LSE 0x00000008 /* Link Pulse Send Enable */
-#define STRR_DREN 0x00000004 /* Driver Enable */
-#define STRR_LBK 0x00000002 /* Loopback Enable */
-#define STRR_ECEN 0x00000001 /* Encoder Enable */
-#define STRR_RESET 0xffffffff /* Reset value for STRR */
-
-/*
-** DC21040 SIA General Register (DE4X5_SIGR)
-*/
-#define SIGR_LV2 0x00008000 /* General Purpose LED2 value */
-#define SIGR_LE2 0x00004000 /* General Purpose LED2 enable */
-#define SIGR_FRL 0x00002000 /* Force Receiver Low */
-#define SIGR_DPST 0x00001000 /* PLL Self Test Start */
-#define SIGR_LSD 0x00000800 /* LED Stretch Disable */
-#define SIGR_FLF 0x00000400 /* Force Link Fail */
-#define SIGR_FUSQ 0x00000200 /* Force Unsquelch */
-#define SIGR_TSCK 0x00000100 /* Test Clock */
-#define SIGR_LV1 0x00000080 /* General Purpose LED1 value */
-#define SIGR_LE1 0x00000040 /* General Purpose LED1 enable */
-#define SIGR_RWR 0x00000020 /* Receive Watchdog Release */
-#define SIGR_RWD 0x00000010 /* Receive Watchdog Disable */
-#define SIGR_ABM 0x00000008 /* BNC: 0, AUI:1 */
-#define SIGR_JCK 0x00000004 /* Jabber Clock */
-#define SIGR_HUJ 0x00000002 /* Host Unjab */
-#define SIGR_JBD 0x00000001 /* Jabber Disable */
-#define SIGR_RESET 0xffff0000 /* Reset value for SIGR */
-
-/*
-** Receive Descriptor Bit Summary
-*/
-#define R_OWN 0x80000000 /* Own Bit */
-#define RD_FL 0x7fff0000 /* Frame Length */
-#define RD_ES 0x00008000 /* Error Summary */
-#define RD_LE 0x00004000 /* Length Error */
-#define RD_DT 0x00003000 /* Data Type */
-#define RD_RF 0x00000800 /* Runt Frame */
-#define RD_MF 0x00000400 /* Multicast Frame */
-#define RD_FS 0x00000200 /* First Descriptor */
-#define RD_LS 0x00000100 /* Last Descriptor */
-#define RD_TL 0x00000080 /* Frame Too Long */
-#define RD_CS 0x00000040 /* Collision Seen */
-#define RD_FT 0x00000020 /* Frame Type */
-#define RD_RJ 0x00000010 /* Receive Watchdog */
-#define RD_DB 0x00000004 /* Dribbling Bit */
-#define RD_CE 0x00000002 /* CRC Error */
-#define RD_OF 0x00000001 /* Overflow */
-
-#define RD_RER 0x02000000 /* Receive End Of Ring */
-#define RD_RCH 0x01000000 /* Second Address Chained */
-#define RD_RBS2 0x003ff800 /* Buffer 2 Size */
-#define RD_RBS1 0x000007ff /* Buffer 1 Size */
-
-/*
-** Transmit Descriptor Bit Summary
-*/
-#define T_OWN 0x80000000 /* Own Bit */
-#define TD_ES 0x00008000 /* Error Summary */
-#define TD_TO 0x00004000 /* Transmit Jabber Time-Out */
-#define TD_LO 0x00000800 /* Loss Of Carrier */
-#define TD_NC 0x00000400 /* No Carrier */
-#define TD_LC 0x00000200 /* Late Collision */
-#define TD_EC 0x00000100 /* Excessive Collisions */
-#define TD_HF 0x00000080 /* Heartbeat Fail */
-#define TD_CC 0x00000078 /* Collision Counter */
-#define TD_LF 0x00000004 /* Link Fail */
-#define TD_UF 0x00000002 /* Underflow Error */
-#define TD_DE 0x00000001 /* Deferred */
-
-#define TD_IC 0x80000000 /* Interrupt On Completion */
-#define TD_LS 0x40000000 /* Last Segment */
-#define TD_FS 0x20000000 /* First Segment */
-#define TD_FT1 0x10000000 /* Filtering Type */
-#define TD_SET 0x08000000 /* Setup Packet */
-#define TD_AC 0x04000000 /* Add CRC Disable */
-#define TD_TER 0x02000000 /* Transmit End Of Ring */
-#define TD_TCH 0x01000000 /* Second Address Chained */
-#define TD_DPD 0x00800000 /* Disabled Padding */
-#define TD_FT0 0x00400000 /* Filtering Type */
-#define TD_RBS2 0x003ff800 /* Buffer 2 Size */
-#define TD_RBS1 0x000007ff /* Buffer 1 Size */
-
-#define PERFECT_F 0x00000000
-#define HASH_F TD_FT0
-#define INVERSE_F TD_FT1
-#define HASH_O_F TD_FT1| TD_F0
-
-/*
-** Media / mode state machine definitions
-*/
-#define NC 0x0000 /* No Connection */
-#define TP 0x0001 /* 10Base-T */
-#define TP_NW 0x0002 /* 10Base-T with Nway */
-#define BNC 0x0004 /* Thinwire */
-#define AUI 0x0008 /* Thickwire */
-#define BNC_AUI 0x0010 /* BNC/AUI on DC21040 indistinguishable */
-#define ANS 0x0020 /* Intermediate AutoNegotiation State */
-#define EXT_SIA 0x0400 /* external SIA (as on DEC MULTIA) */
-
-#define _10Mb 0x0040 /* 10Mb/s Ethernet */
-#define _100Mb 0x0080 /* 100Mb/s Ethernet */
-#define SYM_WAIT 0x0100 /* Wait for SYM_LINK */
-#define INIT 0x0200 /* Initial state */
-
-#define AUTO 0x4000 /* Auto sense the media or speed */
-
-/*
-** Miscellaneous
-*/
-#define PCI 0
-#define EISA 1
-
-#define HASH_TABLE_LEN 512 /* Bits */
-#define HASH_BITS 0x01ff /* 9 LS bits */
-
-#define SETUP_FRAME_LEN 192 /* Bytes */
-#define IMPERF_PA_OFFSET 156 /* Bytes */
-
-#define POLL_DEMAND 1
-
-#define LOST_MEDIA_THRESHOLD 3
-
-#define MASK_INTERRUPTS 1
-#define UNMASK_INTERRUPTS 0
-
-#define DE4X5_STRLEN 8
-
-/*
-** Address Filtering Modes
-*/
-#define PERFECT 0 /* 16 perfect physical addresses */
-#define HASH_PERF 1 /* 1 perfect, 512 multicast addresses */
-#define PERFECT_REJ 2 /* Reject 16 perfect physical addresses */
-#define ALL_HASH 3 /* Hashes all physical & multicast addrs */
-
-#define ALL 0 /* Clear out all the setup frame */
-#define PHYS_ADDR_ONLY 1 /* Update the physical address only */
-
-/*
-** Booleans
-*/
-#define NO 0
-#define FALSE 0
-
-#define YES !0
-#define TRUE !0
-
-/*
-** Include the IOCTL stuff
-*/
-#include <linux/sockios.h>
-
-#define DE4X5IOCTL SIOCDEVPRIVATE
-
-struct de4x5_ioctl {
- unsigned short cmd; /* Command to run */
- unsigned short len; /* Length of the data buffer */
- unsigned char *data; /* Pointer to the data buffer */
-};
-
-/*
-** Recognised commands for the driver
-*/
-#define DE4X5_GET_HWADDR 0x01 /* Get the hardware address */
-#define DE4X5_SET_HWADDR 0x02 /* Get the hardware address */
-#define DE4X5_SET_PROM 0x03 /* Set Promiscuous Mode */
-#define DE4X5_CLR_PROM 0x04 /* Clear Promiscuous Mode */
-#define DE4X5_SAY_BOO 0x05 /* Say "Boo!" to the kernel log file */
-#define DE4X5_GET_MCA 0x06 /* Get a multicast address */
-#define DE4X5_SET_MCA 0x07 /* Set a multicast address */
-#define DE4X5_CLR_MCA 0x08 /* Clear a multicast address */
-#define DE4X5_MCA_EN 0x09 /* Enable a multicast address group */
-#define DE4X5_GET_STATS 0x0a /* Get the driver statistics */
-#define DE4X5_CLR_STATS 0x0b /* Zero out the driver statistics */
-#define DE4X5_GET_OMR 0x0c /* Get the OMR Register contents */
-#define DE4X5_SET_OMR 0x0d /* Set the OMR Register contents */
-#define DE4X5_GET_REG 0x0e /* Get the DE4X5 Registers */
diff --git a/i386/i386at/gpl/linux/net/de600.c b/i386/i386at/gpl/linux/net/de600.c
deleted file mode 100644
index 256759df..00000000
--- a/i386/i386at/gpl/linux/net/de600.c
+++ /dev/null
@@ -1,853 +0,0 @@
-static const char *version =
- "de600.c: $Revision: 1.1.1.1 $, Bjorn Ekwall (bj0rn@blox.se)\n";
-/*
- * de600.c
- *
- * Linux driver for the D-Link DE-600 Ethernet pocket adapter.
- *
- * Portions (C) Copyright 1993, 1994 by Bjorn Ekwall
- * The Author may be reached as bj0rn@blox.se
- *
- * Based on adapter information gathered from DE600.ASM by D-Link Inc.,
- * as included on disk C in the v.2.11 of PC/TCP from FTP Software.
- * For DE600.asm:
- * Portions (C) Copyright 1990 D-Link, Inc.
- * Copyright, 1988-1992, Russell Nelson, Crynwr Software
- *
- * Adapted to the sample network driver core for linux,
- * written by: Donald Becker <becker@super.org>
- * C/O Supercomputing Research Ctr., 17100 Science Dr., Bowie MD 20715
- *
- * compile-command:
- * "gcc -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer \
- * -m486 -c de600.c
- *
- **************************************************************/
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- **************************************************************/
-/* Add another "; SLOW_DOWN_IO" here if your adapter won't work OK: */
-#define DE600_SLOW_DOWN SLOW_DOWN_IO; SLOW_DOWN_IO; SLOW_DOWN_IO
-
- /*
- * If you still have trouble reading/writing to the adapter,
- * modify the following "#define": (see <asm/io.h> for more info)
-#define REALLY_SLOW_IO
- */
-#define SLOW_IO_BY_JUMPING /* Looks "better" than dummy write to port 0x80 :-) */
-
-/*
- * If you want to enable automatic continuous checking for the DE600,
- * keep this #define enabled.
- * It doesn't cost much per packet, so I think it is worth it!
- * If you disagree, comment away the #define, and live with it...
- *
- */
-#define CHECK_LOST_DE600
-
-/*
- * Enable this #define if you want the adapter to do a "ifconfig down" on
- * itself when we have detected that something is possibly wrong with it.
- * The default behaviour is to retry with "adapter_init()" until success.
- * This should be used for debugging purposes only.
- * (Depends on the CHECK_LOST_DE600 above)
- *
- */
-#define SHUTDOWN_WHEN_LOST
-
-/*
- * See comment at "de600_rspace()"!
- * This is an *ugly* hack, but for now it achieves its goal of
- * faking a TCP flow-control that will not flood the poor DE600.
- *
- * Tricks TCP to announce a small max window (max 2 fast packets please :-)
- *
- * Comment away at your own risk!
- *
- * Update: Use the more general per-device maxwindow parameter instead.
- */
-#undef FAKE_SMALL_MAX
-
-/* use 0 for production, 1 for verification, >2 for debug */
-#ifdef DE600_DEBUG
-#define PRINTK(x) if (de600_debug >= 2) printk x
-#else
-#define DE600_DEBUG 0
-#define PRINTK(x) /**/
-#endif
-unsigned int de600_debug = DE600_DEBUG;
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/string.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <asm/io.h>
-#include <linux/in.h>
-#include <linux/ptrace.h>
-#include <asm/system.h>
-#include <linux/errno.h>
-
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-
-#ifdef FAKE_SMALL_MAX
-static unsigned long de600_rspace(struct sock *sk);
-#include <net/sock.h>
-#endif
-
-#define netstats enet_statistics
-typedef unsigned char byte;
-
-/**************************************************
- * *
- * Definition of D-Link Ethernet Pocket adapter *
- * *
- **************************************************/
-/*
- * D-Link Ethernet pocket adapter ports
- */
-/*
- * OK, so I'm cheating, but there are an awful lot of
- * reads and writes in order to get anything in and out
- * of the DE-600 with 4 bits at a time in the parallel port,
- * so every saved instruction really helps :-)
- *
- * That is, I don't care what the device struct says
- * but hope that Space.c will keep the rest of the drivers happy.
- */
-#ifndef DE600_IO
-#define DE600_IO 0x378
-#endif
-
-#define DATA_PORT (DE600_IO)
-#define STATUS_PORT (DE600_IO + 1)
-#define COMMAND_PORT (DE600_IO + 2)
-
-#ifndef DE600_IRQ
-#define DE600_IRQ 7
-#endif
-/*
- * It really should look like this, and autoprobing as well...
- *
-#define DATA_PORT (dev->base_addr + 0)
-#define STATUS_PORT (dev->base_addr + 1)
-#define COMMAND_PORT (dev->base_addr + 2)
-#define DE600_IRQ dev->irq
- */
-
-/*
- * D-Link COMMAND_PORT commands
- */
-#define SELECT_NIC 0x04 /* select Network Interface Card */
-#define SELECT_PRN 0x1c /* select Printer */
-#define NML_PRN 0xec /* normal Printer situation */
-#define IRQEN 0x10 /* enable IRQ line */
-
-/*
- * D-Link STATUS_PORT
- */
-#define RX_BUSY 0x80
-#define RX_GOOD 0x40
-#define TX_FAILED16 0x10
-#define TX_BUSY 0x08
-
-/*
- * D-Link DATA_PORT commands
- * command in low 4 bits
- * data in high 4 bits
- * select current data nibble with HI_NIBBLE bit
- */
-#define WRITE_DATA 0x00 /* write memory */
-#define READ_DATA 0x01 /* read memory */
-#define STATUS 0x02 /* read status register */
-#define COMMAND 0x03 /* write command register (see COMMAND below) */
-#define NULL_COMMAND 0x04 /* null command */
-#define RX_LEN 0x05 /* read received packet length */
-#define TX_ADDR 0x06 /* set adapter transmit memory address */
-#define RW_ADDR 0x07 /* set adapter read/write memory address */
-#define HI_NIBBLE 0x08 /* read/write the high nibble of data,
- or-ed with rest of command */
-
-/*
- * command register, accessed through DATA_PORT with low bits = COMMAND
- */
-#define RX_ALL 0x01 /* PROMISCUOUS */
-#define RX_BP 0x02 /* default: BROADCAST & PHYSICAL ADDRESS */
-#define RX_MBP 0x03 /* MULTICAST, BROADCAST & PHYSICAL ADDRESS */
-
-#define TX_ENABLE 0x04 /* bit 2 */
-#define RX_ENABLE 0x08 /* bit 3 */
-
-#define RESET 0x80 /* set bit 7 high */
-#define STOP_RESET 0x00 /* set bit 7 low */
-
-/*
- * data to command register
- * (high 4 bits in write to DATA_PORT)
- */
-#define RX_PAGE2_SELECT 0x10 /* bit 4, only 2 pages to select */
-#define RX_BASE_PAGE 0x20 /* bit 5, always set when specifying RX_ADDR */
-#define FLIP_IRQ 0x40 /* bit 6 */
-
-/*
- * D-Link adapter internal memory:
- *
- * 0-2K 1:st transmit page (send from pointer up to 2K)
- * 2-4K 2:nd transmit page (send from pointer up to 4K)
- *
- * 4-6K 1:st receive page (data from 4K upwards)
- * 6-8K 2:nd receive page (data from 6K upwards)
- *
- * 8K+ Adapter ROM (contains magic code and last 3 bytes of Ethernet address)
- */
-#define MEM_2K 0x0800 /* 2048 */
-#define MEM_4K 0x1000 /* 4096 */
-#define MEM_6K 0x1800 /* 6144 */
-#define NODE_ADDRESS 0x2000 /* 8192 */
-
-#define RUNT 60 /* Too small Ethernet packet */
-
-/**************************************************
- * *
- * End of definition *
- * *
- **************************************************/
-
-/*
- * Index to functions, as function prototypes.
- */
-/* Routines used internally. (See "convenience macros") */
-static byte de600_read_status(struct device *dev);
-static byte de600_read_byte(unsigned char type, struct device *dev);
-
-/* Put in the device structure. */
-static int de600_open(struct device *dev);
-static int de600_close(struct device *dev);
-static struct netstats *get_stats(struct device *dev);
-static int de600_start_xmit(struct sk_buff *skb, struct device *dev);
-
-/* Dispatch from interrupts. */
-static void de600_interrupt(int irq, struct pt_regs *regs);
-static int de600_tx_intr(struct device *dev, int irq_status);
-static void de600_rx_intr(struct device *dev);
-
-/* Initialization */
-static void trigger_interrupt(struct device *dev);
-int de600_probe(struct device *dev);
-static int adapter_init(struct device *dev);
-
-/*
- * D-Link driver variables:
- */
-static volatile int rx_page = 0;
-
-#define TX_PAGES 2
-static volatile int tx_fifo[TX_PAGES];
-static volatile int tx_fifo_in = 0;
-static volatile int tx_fifo_out = 0;
-static volatile int free_tx_pages = TX_PAGES;
-static int was_down = 0;
-
-/*
- * Convenience macros/functions for D-Link adapter
- */
-
-#define select_prn() outb_p(SELECT_PRN, COMMAND_PORT); DE600_SLOW_DOWN
-#define select_nic() outb_p(SELECT_NIC, COMMAND_PORT); DE600_SLOW_DOWN
-
-/* Thanks for hints from Mark Burton <markb@ordern.demon.co.uk> */
-#define de600_put_byte(data) ( \
- outb_p(((data) << 4) | WRITE_DATA , DATA_PORT), \
- outb_p(((data) & 0xf0) | WRITE_DATA | HI_NIBBLE, DATA_PORT))
-
-/*
- * The first two outb_p()'s below could perhaps be deleted if there
- * would be more delay in the last two. Not certain about it yet...
- */
-#define de600_put_command(cmd) ( \
- outb_p(( rx_page << 4) | COMMAND , DATA_PORT), \
- outb_p(( rx_page & 0xf0) | COMMAND | HI_NIBBLE, DATA_PORT), \
- outb_p(((rx_page | cmd) << 4) | COMMAND , DATA_PORT), \
- outb_p(((rx_page | cmd) & 0xf0) | COMMAND | HI_NIBBLE, DATA_PORT))
-
-#define de600_setup_address(addr,type) ( \
- outb_p((((addr) << 4) & 0xf0) | type , DATA_PORT), \
- outb_p(( (addr) & 0xf0) | type | HI_NIBBLE, DATA_PORT), \
- outb_p((((addr) >> 4) & 0xf0) | type , DATA_PORT), \
- outb_p((((addr) >> 8) & 0xf0) | type | HI_NIBBLE, DATA_PORT))
-
-#define rx_page_adr() ((rx_page & RX_PAGE2_SELECT)?(MEM_6K):(MEM_4K))
-
-/* Flip bit, only 2 pages */
-#define next_rx_page() (rx_page ^= RX_PAGE2_SELECT)
-
-#define tx_page_adr(a) (((a) + 1) * MEM_2K)
-
-static inline byte
-de600_read_status(struct device *dev)
-{
- byte status;
-
- outb_p(STATUS, DATA_PORT);
- status = inb(STATUS_PORT);
- outb_p(NULL_COMMAND | HI_NIBBLE, DATA_PORT);
-
- return status;
-}
-
-static inline byte
-de600_read_byte(unsigned char type, struct device *dev) { /* dev used by macros */
- byte lo;
-
- (void)outb_p((type), DATA_PORT);
- lo = ((unsigned char)inb(STATUS_PORT)) >> 4;
- (void)outb_p((type) | HI_NIBBLE, DATA_PORT);
- return ((unsigned char)inb(STATUS_PORT) & (unsigned char)0xf0) | lo;
-}
-
-/*
- * Open/initialize the board. This is called (in the current kernel)
- * after booting when 'ifconfig <dev->name> $IP_ADDR' is run (in rc.inet1).
- *
- * This routine should set everything up anew at each open, even
- * registers that "should" only need to be set once at boot, so that
- * there is a non-reboot way to recover if something goes wrong.
- */
-static int
-de600_open(struct device *dev)
-{
- if (request_irq(DE600_IRQ, de600_interrupt, 0, "de600")) {
- printk ("%s: unable to get IRQ %d\n", dev->name, DE600_IRQ);
- return 1;
- }
- irq2dev_map[DE600_IRQ] = dev;
-
- MOD_INC_USE_COUNT;
- dev->start = 1;
- if (adapter_init(dev)) {
- return 1;
- }
-
- return 0;
-}
-
-/*
- * The inverse routine to de600_open().
- */
-static int
-de600_close(struct device *dev)
-{
- select_nic();
- rx_page = 0;
- de600_put_command(RESET);
- de600_put_command(STOP_RESET);
- de600_put_command(0);
- select_prn();
-
- if (dev->start) {
- free_irq(DE600_IRQ);
- irq2dev_map[DE600_IRQ] = NULL;
- dev->start = 0;
- MOD_DEC_USE_COUNT;
- }
- return 0;
-}
-
-static struct netstats *
-get_stats(struct device *dev)
-{
- return (struct netstats *)(dev->priv);
-}
-
-static inline void
-trigger_interrupt(struct device *dev)
-{
- de600_put_command(FLIP_IRQ);
- select_prn();
- DE600_SLOW_DOWN;
- select_nic();
- de600_put_command(0);
-}
-
-/*
- * Copy a buffer to the adapter transmit page memory.
- * Start sending.
- */
-static int
-de600_start_xmit(struct sk_buff *skb, struct device *dev)
-{
- int transmit_from;
- int len;
- int tickssofar;
- byte *buffer = skb->data;
-
- /*
- * If some higher layer thinks we've missed a
- * tx-done interrupt we are passed NULL.
- * Caution: dev_tint() handles the cli()/sti() itself.
- */
-
- if (skb == NULL) {
- dev_tint(dev);
- return 0;
- }
-
- if (free_tx_pages <= 0) { /* Do timeouts, to avoid hangs. */
- tickssofar = jiffies - dev->trans_start;
-
- if (tickssofar < 5)
- return 1;
-
- /* else */
- printk("%s: transmit timed out (%d), %s?\n",
- dev->name,
- tickssofar,
- "network cable problem"
- );
- /* Restart the adapter. */
- if (adapter_init(dev)) {
- return 1;
- }
- }
-
- /* Start real output */
- PRINTK(("de600_start_xmit:len=%d, page %d/%d\n", skb->len, tx_fifo_in, free_tx_pages));
-
- if ((len = skb->len) < RUNT)
- len = RUNT;
-
- cli();
- select_nic();
- tx_fifo[tx_fifo_in] = transmit_from = tx_page_adr(tx_fifo_in) - len;
- tx_fifo_in = (tx_fifo_in + 1) % TX_PAGES; /* Next free tx page */
-
-#ifdef CHECK_LOST_DE600
- /* This costs about 40 instructions per packet... */
- de600_setup_address(NODE_ADDRESS, RW_ADDR);
- de600_read_byte(READ_DATA, dev);
- if (was_down || (de600_read_byte(READ_DATA, dev) != 0xde)) {
- if (adapter_init(dev)) {
- sti();
- return 1;
- }
- }
-#endif
-
- de600_setup_address(transmit_from, RW_ADDR);
- for ( ; len > 0; --len, ++buffer)
- de600_put_byte(*buffer);
-
- if (free_tx_pages-- == TX_PAGES) { /* No transmission going on */
- dev->trans_start = jiffies;
- dev->tbusy = 0; /* allow more packets into adapter */
- /* Send page and generate a faked interrupt */
- de600_setup_address(transmit_from, TX_ADDR);
- de600_put_command(TX_ENABLE);
- }
- else {
- dev->tbusy = !free_tx_pages;
- select_prn();
- }
-
- sti(); /* interrupts back on */
-
-#ifdef FAKE_SMALL_MAX
- /* This will "patch" the socket TCP proto at an early moment */
- if (skb->sk && (skb->sk->protocol == IPPROTO_TCP) &&
- (skb->sk->prot->rspace != &de600_rspace))
- skb->sk->prot->rspace = de600_rspace; /* Ugh! */
-#endif
-
- dev_kfree_skb (skb, FREE_WRITE);
-
- return 0;
-}
-
-/*
- * The typical workload of the driver:
- * Handle the network interface interrupts.
- */
-static void
-de600_interrupt(int irq, struct pt_regs * regs)
-{
- struct device *dev = irq2dev_map[irq];
- byte irq_status;
- int retrig = 0;
- int boguscount = 0;
-
- /* This might just as well be deleted now, no crummy drivers present :-) */
- if ((dev == NULL) || (dev->start == 0) || (DE600_IRQ != irq)) {
- printk("%s: bogus interrupt %d\n", dev?dev->name:"DE-600", irq);
- return;
- }
-
- dev->interrupt = 1;
- select_nic();
- irq_status = de600_read_status(dev);
-
- do {
- PRINTK(("de600_interrupt (%02X)\n", irq_status));
-
- if (irq_status & RX_GOOD)
- de600_rx_intr(dev);
- else if (!(irq_status & RX_BUSY))
- de600_put_command(RX_ENABLE);
-
- /* Any transmission in progress? */
- if (free_tx_pages < TX_PAGES)
- retrig = de600_tx_intr(dev, irq_status);
- else
- retrig = 0;
-
- irq_status = de600_read_status(dev);
- } while ( (irq_status & RX_GOOD) || ((++boguscount < 100) && retrig) );
- /*
- * Yeah, it _looks_ like busy waiting, smells like busy waiting
- * and I know it's not PC, but please, it will only occur once
- * in a while and then only for a loop or so (< 1ms for sure!)
- */
-
- /* Enable adapter interrupts */
- dev->interrupt = 0;
- select_prn();
-
- if (retrig)
- trigger_interrupt(dev);
-
- sti();
- return;
-}
-
-static int
-de600_tx_intr(struct device *dev, int irq_status)
-{
- /*
- * Returns 1 if tx still not done
- */
-
- mark_bh(NET_BH);
- /* Check if current transmission is done yet */
- if (irq_status & TX_BUSY)
- return 1; /* tx not done, try again */
-
- /* else */
- /* If last transmission OK then bump fifo index */
- if (!(irq_status & TX_FAILED16)) {
- tx_fifo_out = (tx_fifo_out + 1) % TX_PAGES;
- ++free_tx_pages;
- ((struct netstats *)(dev->priv))->tx_packets++;
- dev->tbusy = 0;
- }
-
- /* More to send, or resend last packet? */
- if ((free_tx_pages < TX_PAGES) || (irq_status & TX_FAILED16)) {
- dev->trans_start = jiffies;
- de600_setup_address(tx_fifo[tx_fifo_out], TX_ADDR);
- de600_put_command(TX_ENABLE);
- return 1;
- }
- /* else */
-
- return 0;
-}
-
-/*
- * We have a good packet, get it out of the adapter.
- */
-static void
-de600_rx_intr(struct device *dev)
-{
- struct sk_buff *skb;
- int i;
- int read_from;
- int size;
- register unsigned char *buffer;
-
- cli();
- /* Get size of received packet */
- size = de600_read_byte(RX_LEN, dev); /* low byte */
- size += (de600_read_byte(RX_LEN, dev) << 8); /* high byte */
- size -= 4; /* Ignore trailing 4 CRC-bytes */
-
- /* Tell adapter where to store next incoming packet, enable receiver */
- read_from = rx_page_adr();
- next_rx_page();
- de600_put_command(RX_ENABLE);
- sti();
-
- if ((size < 32) || (size > 1535)) {
- printk("%s: Bogus packet size %d.\n", dev->name, size);
- if (size > 10000)
- adapter_init(dev);
- return;
- }
-
- skb = dev_alloc_skb(size+2);
- sti();
- if (skb == NULL) {
- printk("%s: Couldn't allocate a sk_buff of size %d.\n",
- dev->name, size);
- return;
- }
- /* else */
-
- skb->dev = dev;
- skb_reserve(skb,2); /* Align */
-
- /* 'skb->data' points to the start of sk_buff data area. */
- buffer = skb_put(skb,size);
-
- /* copy the packet into the buffer */
- de600_setup_address(read_from, RW_ADDR);
- for (i = size; i > 0; --i, ++buffer)
- *buffer = de600_read_byte(READ_DATA, dev);
-
- ((struct netstats *)(dev->priv))->rx_packets++; /* count all receives */
-
- skb->protocol=eth_type_trans(skb,dev);
-
- netif_rx(skb);
- /*
- * If any worth-while packets have been received, netif_rx()
- * has done a mark_bh(INET_BH) for us and will work on them
- * when we get to the bottom-half routine.
- */
-}
-
-int
-de600_probe(struct device *dev)
-{
- int i;
- static struct netstats de600_netstats;
- /*dev->priv = kmalloc(sizeof(struct netstats), GFP_KERNEL);*/
-
- printk("%s: D-Link DE-600 pocket adapter", dev->name);
- /* Alpha testers must have the version number to report bugs. */
- if (de600_debug > 1)
- printk(version);
-
- /* probe for adapter */
- rx_page = 0;
- select_nic();
- (void)de600_read_status(dev);
- de600_put_command(RESET);
- de600_put_command(STOP_RESET);
- if (de600_read_status(dev) & 0xf0) {
- printk(": not at I/O %#3x.\n", DATA_PORT);
- return ENODEV;
- }
-
- /*
- * Maybe we found one,
- * have to check if it is a D-Link DE-600 adapter...
- */
-
- /* Get the adapter ethernet address from the ROM */
- de600_setup_address(NODE_ADDRESS, RW_ADDR);
- for (i = 0; i < ETH_ALEN; i++) {
- dev->dev_addr[i] = de600_read_byte(READ_DATA, dev);
- dev->broadcast[i] = 0xff;
- }
-
- /* Check magic code */
- if ((dev->dev_addr[1] == 0xde) && (dev->dev_addr[2] == 0x15)) {
- /* OK, install real address */
- dev->dev_addr[0] = 0x00;
- dev->dev_addr[1] = 0x80;
- dev->dev_addr[2] = 0xc8;
- dev->dev_addr[3] &= 0x0f;
- dev->dev_addr[3] |= 0x70;
- } else {
- printk(" not identified in the printer port\n");
- return ENODEV;
- }
-
-#if 0 /* Not yet */
- if (check_region(DE600_IO, 3)) {
- printk(", port 0x%x busy\n", DE600_IO);
- return EBUSY;
- }
-#endif
- request_region(DE600_IO, 3, "de600");
-
- printk(", Ethernet Address: %02X", dev->dev_addr[0]);
- for (i = 1; i < ETH_ALEN; i++)
- printk(":%02X",dev->dev_addr[i]);
- printk("\n");
-
- /* Initialize the device structure. */
- /*dev->priv = kmalloc(sizeof(struct netstats), GFP_KERNEL);*/
- dev->priv = &de600_netstats;
-
- memset(dev->priv, 0, sizeof(struct netstats));
- dev->get_stats = get_stats;
-
- dev->open = de600_open;
- dev->stop = de600_close;
- dev->hard_start_xmit = &de600_start_xmit;
-
- ether_setup(dev);
-
- dev->flags&=~IFF_MULTICAST;
-
- select_prn();
- return 0;
-}
-
-static int
-adapter_init(struct device *dev)
-{
- int i;
- long flags;
-
- save_flags(flags);
- cli();
-
- select_nic();
- rx_page = 0; /* used by RESET */
- de600_put_command(RESET);
- de600_put_command(STOP_RESET);
-#ifdef CHECK_LOST_DE600
- /* Check if it is still there... */
- /* Get the some bytes of the adapter ethernet address from the ROM */
- de600_setup_address(NODE_ADDRESS, RW_ADDR);
- de600_read_byte(READ_DATA, dev);
- if ((de600_read_byte(READ_DATA, dev) != 0xde) ||
- (de600_read_byte(READ_DATA, dev) != 0x15)) {
- /* was: if (de600_read_status(dev) & 0xf0) { */
- printk("Something has happened to the DE-600! Please check it"
-#ifdef SHUTDOWN_WHEN_LOST
- " and do a new ifconfig"
-#endif /* SHUTDOWN_WHEN_LOST */
- "!\n");
-#ifdef SHUTDOWN_WHEN_LOST
- /* Goodbye, cruel world... */
- dev->flags &= ~IFF_UP;
- de600_close(dev);
-#endif /* SHUTDOWN_WHEN_LOST */
- was_down = 1;
- dev->tbusy = 1; /* Transmit busy... */
- restore_flags(flags);
- return 1; /* failed */
- }
-#endif /* CHECK_LOST_DE600 */
- if (was_down) {
- printk("Thanks, I feel much better now!\n");
- was_down = 0;
- }
-
- dev->tbusy = 0; /* Transmit busy... */
- dev->interrupt = 0;
- tx_fifo_in = 0;
- tx_fifo_out = 0;
- free_tx_pages = TX_PAGES;
-
- /* set the ether address. */
- de600_setup_address(NODE_ADDRESS, RW_ADDR);
- for (i = 0; i < ETH_ALEN; i++)
- de600_put_byte(dev->dev_addr[i]);
-
- /* where to start saving incoming packets */
- rx_page = RX_BP | RX_BASE_PAGE;
- de600_setup_address(MEM_4K, RW_ADDR);
- /* Enable receiver */
- de600_put_command(RX_ENABLE);
- select_prn();
- restore_flags(flags);
-
- return 0; /* OK */
-}
-
-#ifdef FAKE_SMALL_MAX
-/*
- * The new router code (coming soon 8-) ) will fix this properly.
- */
-#define DE600_MIN_WINDOW 1024
-#define DE600_MAX_WINDOW 2048
-#define DE600_TCP_WINDOW_DIFF 1024
-/*
- * Copied from "net/inet/sock.c"
- *
- * Sets a lower max receive window in order to achieve <= 2
- * packets arriving at the adapter in fast succession.
- * (No way that a DE-600 can keep up with a net saturated
- * with packets homing in on it :-( )
- *
- * Since there are only 2 receive buffers in the DE-600
- * and it takes some time to copy from the adapter,
- * this is absolutely necessary for any TCP performance whatsoever!
- *
- * Note that the returned window info will never be smaller than
- * DE600_MIN_WINDOW, i.e. 1024
- * This differs from the standard function, that can return an
- * arbitrarily small window!
- */
-#define min(a,b) ((a)<(b)?(a):(b))
-static unsigned long
-de600_rspace(struct sock *sk)
-{
- int amt;
-
- if (sk != NULL) {
-/*
- * Hack! You might want to play with commenting away the following line,
- * if you know what you do!
- sk->max_unacked = DE600_MAX_WINDOW - DE600_TCP_WINDOW_DIFF;
- */
-
- if (sk->rmem_alloc >= sk->rcvbuf-2*DE600_MIN_WINDOW) return(0);
- amt = min((sk->rcvbuf-sk->rmem_alloc)/2/*-DE600_MIN_WINDOW*/, DE600_MAX_WINDOW);
- if (amt < 0) return(0);
- return(amt);
- }
- return(0);
-}
-#endif
-
-#ifdef MODULE
-static char nullname[8];
-static struct device de600_dev = {
- nullname, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, de600_probe };
-
-int
-init_module(void)
-{
- if (register_netdev(&de600_dev) != 0)
- return -EIO;
- return 0;
-}
-
-void
-cleanup_module(void)
-{
- unregister_netdev(&de600_dev);
- release_region(DE600_IO, 3);
-}
-#endif /* MODULE */
-/*
- * Local variables:
- * kernel-compile-command: "gcc -D__KERNEL__ -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de600.c"
- * module-compile-command: "gcc -D__KERNEL__ -DMODULE -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de600.c"
- * compile-command: "gcc -D__KERNEL__ -DMODULE -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de600.c"
- * End:
- */
diff --git a/i386/i386at/gpl/linux/net/de620.c b/i386/i386at/gpl/linux/net/de620.c
deleted file mode 100644
index 2b17c390..00000000
--- a/i386/i386at/gpl/linux/net/de620.c
+++ /dev/null
@@ -1,1045 +0,0 @@
-/*
- * de620.c $Revision: 1.1.1.1 $ BETA
- *
- *
- * Linux driver for the D-Link DE-620 Ethernet pocket adapter.
- *
- * Portions (C) Copyright 1993, 1994 by Bjorn Ekwall <bj0rn@blox.se>
- *
- * Based on adapter information gathered from DOS packetdriver
- * sources from D-Link Inc: (Special thanks to Henry Ngai of D-Link.)
- * Portions (C) Copyright D-Link SYSTEM Inc. 1991, 1992
- * Copyright, 1988, Russell Nelson, Crynwr Software
- *
- * Adapted to the sample network driver core for linux,
- * written by: Donald Becker <becker@super.org>
- * (Now at <becker@cesdis.gsfc.nasa.gov>
- *
- * Valuable assistance from:
- * J. Joshua Kopper <kopper@rtsg.mot.com>
- * Olav Kvittem <Olav.Kvittem@uninett.no>
- * Germano Caronni <caronni@nessie.cs.id.ethz.ch>
- * Jeremy Fitzhardinge <jeremy@suite.sw.oz.au>
- *
- *****************************************************************************/
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *****************************************************************************/
-static const char *version =
- "de620.c: $Revision: 1.1.1.1 $, Bjorn Ekwall <bj0rn@blox.se>\n";
-
-/***********************************************************************
- *
- * "Tuning" section.
- *
- * Compile-time options: (see below for descriptions)
- * -DDE620_IO=0x378 (lpt1)
- * -DDE620_IRQ=7 (lpt1)
- * -DDE602_DEBUG=...
- * -DSHUTDOWN_WHEN_LOST
- * -DCOUNT_LOOPS
- * -DLOWSPEED
- * -DREAD_DELAY
- * -DWRITE_DELAY
- */
-
-/*
- * This driver assumes that the printer port is a "normal",
- * dumb, uni-directional port!
- * If your port is "fancy" in any way, please try to set it to "normal"
- * with your BIOS setup. I have no access to machines with bi-directional
- * ports, so I can't test such a driver :-(
- * (Yes, I _know_ it is possible to use DE620 with bidirectional ports...)
- *
- * There are some clones of DE620 out there, with different names.
- * If the current driver does not recognize a clone, try to change
- * the following #define to:
- *
- * #define DE620_CLONE 1
- */
-#define DE620_CLONE 0
-
-/*
- * If the adapter has problems with high speeds, enable this #define
- * otherwise full printerport speed will be attempted.
- *
- * You can tune the READ_DELAY/WRITE_DELAY below if you enable LOWSPEED
- *
-#define LOWSPEED
- */
-
-#ifndef READ_DELAY
-#define READ_DELAY 100 /* adapter internal read delay in 100ns units */
-#endif
-
-#ifndef WRITE_DELAY
-#define WRITE_DELAY 100 /* adapter internal write delay in 100ns units */
-#endif
-
-/*
- * Enable this #define if you want the adapter to do a "ifconfig down" on
- * itself when we have detected that something is possibly wrong with it.
- * The default behaviour is to retry with "adapter_init()" until success.
- * This should be used for debugging purposes only.
- *
-#define SHUTDOWN_WHEN_LOST
- */
-
-/*
- * Enable debugging by "-DDE620_DEBUG=3" when compiling,
- * OR in "./CONFIG"
- * OR by enabling the following #define
- *
- * use 0 for production, 1 for verification, >2 for debug
- *
-#define DE620_DEBUG 3
- */
-
-#ifdef LOWSPEED
-/*
- * Enable this #define if you want to see debugging output that show how long
- * we have to wait before the DE-620 is ready for the next read/write/command.
- *
-#define COUNT_LOOPS
- */
-#endif
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/string.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <asm/io.h>
-#include <linux/in.h>
-#include <linux/ptrace.h>
-#include <asm/system.h>
-#include <linux/errno.h>
-
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-
-/* Constant definitions for the DE-620 registers, commands and bits */
-#include "de620.h"
-
-#define netstats enet_statistics
-typedef unsigned char byte;
-
-/*******************************************************
- * *
- * Definition of D-Link DE-620 Ethernet Pocket adapter *
- * See also "de620.h" *
- * *
- *******************************************************/
-#ifndef DE620_IO /* Compile-time configurable */
-#define DE620_IO 0x378
-#endif
-
-#ifndef DE620_IRQ /* Compile-time configurable */
-#define DE620_IRQ 7
-#endif
-
-#define DATA_PORT (dev->base_addr)
-#define STATUS_PORT (dev->base_addr + 1)
-#define COMMAND_PORT (dev->base_addr + 2)
-
-#define RUNT 60 /* Too small Ethernet packet */
-#define GIANT 1514 /* largest legal size packet, no fcs */
-
-#ifdef DE620_DEBUG /* Compile-time configurable */
-#define PRINTK(x) if (de620_debug >= 2) printk x
-#else
-#define DE620_DEBUG 0
-#define PRINTK(x) /**/
-#endif
-
-
-/*
- * Force media with insmod:
- * insmod de620.o bnc=1
- * or
- * insmod de620.o utp=1
- *
- * Force io and/or irq with insmod:
- * insmod de620.o io=0x378 irq=7
- *
- * Make a clone skip the Ethernet-address range check:
- * insmod de620.o clone=1
- */
-static int bnc = 0;
-static int utp = 0;
-static int io = DE620_IO;
-static int irq = DE620_IRQ;
-static int clone = DE620_CLONE;
-
-static unsigned int de620_debug = DE620_DEBUG;
-
-/***********************************************
- * *
- * Index to functions, as function prototypes. *
- * *
- ***********************************************/
-
-/*
- * Routines used internally. (See also "convenience macros.. below")
- */
-
-/* Put in the device structure. */
-static int de620_open(struct device *);
-static int de620_close(struct device *);
-static struct netstats *get_stats(struct device *);
-static void de620_set_multicast_list(struct device *);
-static int de620_start_xmit(struct sk_buff *, struct device *);
-
-/* Dispatch from interrupts. */
-static void de620_interrupt(int, struct pt_regs *);
-static int de620_rx_intr(struct device *);
-
-/* Initialization */
-static int adapter_init(struct device *);
-int de620_probe(struct device *);
-static int read_eeprom(struct device *);
-
-
-/*
- * D-Link driver variables:
- */
-#define SCR_DEF NIBBLEMODE |INTON | SLEEP | AUTOTX
-#define TCR_DEF RXPB /* not used: | TXSUCINT | T16INT */
-#define DE620_RX_START_PAGE 12 /* 12 pages (=3k) reserved for tx */
-#define DEF_NIC_CMD IRQEN | ICEN | DS1
-
-static volatile byte NIC_Cmd;
-static volatile byte next_rx_page;
-static byte first_rx_page;
-static byte last_rx_page;
-static byte EIPRegister;
-
-static struct nic {
- byte NodeID[6];
- byte RAM_Size;
- byte Model;
- byte Media;
- byte SCR;
-} nic_data;
-
-/**********************************************************
- * *
- * Convenience macros/functions for D-Link DE-620 adapter *
- * *
- **********************************************************/
-#define de620_tx_buffs(dd) (inb(STATUS_PORT) & (TXBF0 | TXBF1))
-#define de620_flip_ds(dd) NIC_Cmd ^= DS0 | DS1; outb(NIC_Cmd, COMMAND_PORT);
-
-/* Check for ready-status, and return a nibble (high 4 bits) for data input */
-#ifdef COUNT_LOOPS
-static int tot_cnt;
-#endif
-static inline byte
-de620_ready(struct device *dev)
-{
- byte value;
- register short int cnt = 0;
-
- while ((((value = inb(STATUS_PORT)) & READY) == 0) && (cnt <= 1000))
- ++cnt;
-
-#ifdef COUNT_LOOPS
- tot_cnt += cnt;
-#endif
- return value & 0xf0; /* nibble */
-}
-
-static inline void
-de620_send_command(struct device *dev, byte cmd)
-{
- de620_ready(dev);
- if (cmd == W_DUMMY)
- outb(NIC_Cmd, COMMAND_PORT);
-
- outb(cmd, DATA_PORT);
-
- outb(NIC_Cmd ^ CS0, COMMAND_PORT);
- de620_ready(dev);
- outb(NIC_Cmd, COMMAND_PORT);
-}
-
-static inline void
-de620_put_byte(struct device *dev, byte value)
-{
- /* The de620_ready() makes 7 loops, on the average, on a DX2/66 */
- de620_ready(dev);
- outb(value, DATA_PORT);
- de620_flip_ds(dev);
-}
-
-static inline byte
-de620_read_byte(struct device *dev)
-{
- byte value;
-
- /* The de620_ready() makes 7 loops, on the average, on a DX2/66 */
- value = de620_ready(dev); /* High nibble */
- de620_flip_ds(dev);
- value |= de620_ready(dev) >> 4; /* Low nibble */
- return value;
-}
-
-static inline void
-de620_write_block(struct device *dev, byte *buffer, int count)
-{
-#ifndef LOWSPEED
- byte uflip = NIC_Cmd ^ (DS0 | DS1);
- byte dflip = NIC_Cmd;
-#else /* LOWSPEED */
-#ifdef COUNT_LOOPS
- int bytes = count;
-#endif /* COUNT_LOOPS */
-#endif /* LOWSPEED */
-
-#ifdef LOWSPEED
-#ifdef COUNT_LOOPS
- tot_cnt = 0;
-#endif /* COUNT_LOOPS */
- /* No further optimization useful, the limit is in the adapter. */
- for ( ; count > 0; --count, ++buffer) {
- de620_put_byte(dev,*buffer);
- }
- de620_send_command(dev,W_DUMMY);
-#ifdef COUNT_LOOPS
- /* trial debug output: loops per byte in de620_ready() */
- printk("WRITE(%d)\n", tot_cnt/((bytes?bytes:1)));
-#endif /* COUNT_LOOPS */
-#else /* not LOWSPEED */
- for ( ; count > 0; count -=2) {
- outb(*buffer++, DATA_PORT);
- outb(uflip, COMMAND_PORT);
- outb(*buffer++, DATA_PORT);
- outb(dflip, COMMAND_PORT);
- }
- de620_send_command(dev,W_DUMMY);
-#endif /* LOWSPEED */
-}
-
-static inline void
-de620_read_block(struct device *dev, byte *data, int count)
-{
-#ifndef LOWSPEED
- byte value;
- byte uflip = NIC_Cmd ^ (DS0 | DS1);
- byte dflip = NIC_Cmd;
-#else /* LOWSPEED */
-#ifdef COUNT_LOOPS
- int bytes = count;
-
- tot_cnt = 0;
-#endif /* COUNT_LOOPS */
-#endif /* LOWSPEED */
-
-#ifdef LOWSPEED
- /* No further optimization useful, the limit is in the adapter. */
- while (count-- > 0) {
- *data++ = de620_read_byte(dev);
- de620_flip_ds(dev);
- }
-#ifdef COUNT_LOOPS
- /* trial debug output: loops per byte in de620_ready() */
- printk("READ(%d)\n", tot_cnt/(2*(bytes?bytes:1)));
-#endif /* COUNT_LOOPS */
-#else /* not LOWSPEED */
- while (count-- > 0) {
- value = inb(STATUS_PORT) & 0xf0; /* High nibble */
- outb(uflip, COMMAND_PORT);
- *data++ = value | inb(STATUS_PORT) >> 4; /* Low nibble */
- outb(dflip , COMMAND_PORT);
- }
-#endif /* LOWSPEED */
-}
-
-static inline void
-de620_set_delay(struct device *dev)
-{
- de620_ready(dev);
- outb(W_DFR, DATA_PORT);
- outb(NIC_Cmd ^ CS0, COMMAND_PORT);
-
- de620_ready(dev);
-#ifdef LOWSPEED
- outb(WRITE_DELAY, DATA_PORT);
-#else
- outb(0, DATA_PORT);
-#endif
- de620_flip_ds(dev);
-
- de620_ready(dev);
-#ifdef LOWSPEED
- outb(READ_DELAY, DATA_PORT);
-#else
- outb(0, DATA_PORT);
-#endif
- de620_flip_ds(dev);
-}
-
-static inline void
-de620_set_register(struct device *dev, byte reg, byte value)
-{
- de620_ready(dev);
- outb(reg, DATA_PORT);
- outb(NIC_Cmd ^ CS0, COMMAND_PORT);
-
- de620_put_byte(dev, value);
-}
-
-static inline byte
-de620_get_register(struct device *dev, byte reg)
-{
- byte value;
-
- de620_send_command(dev,reg);
- value = de620_read_byte(dev);
- de620_send_command(dev,W_DUMMY);
-
- return value;
-}
-
-/*********************************************************************
- *
- * Open/initialize the board.
- *
- * This routine should set everything up anew at each open, even
- * registers that "should" only need to be set once at boot, so that
- * there is a non-reboot way to recover if something goes wrong.
- *
- */
-static int
-de620_open(struct device *dev)
-{
- if (request_irq(dev->irq, de620_interrupt, 0, "de620")) {
- printk ("%s: unable to get IRQ %d\n", dev->name, dev->irq);
- return 1;
- }
- irq2dev_map[dev->irq] = dev;
-
- MOD_INC_USE_COUNT;
- if (adapter_init(dev)) {
- return 1;
- }
- dev->start = 1;
- return 0;
-}
-
-/************************************************
- *
- * The inverse routine to de620_open().
- *
- */
-static int
-de620_close(struct device *dev)
-{
- /* disable recv */
- de620_set_register(dev, W_TCR, RXOFF);
-
- free_irq(dev->irq);
- irq2dev_map[dev->irq] = NULL;
-
- dev->start = 0;
- MOD_DEC_USE_COUNT;
- return 0;
-}
-
-/*********************************************
- *
- * Return current statistics
- *
- */
-static struct netstats *
-get_stats(struct device *dev)
-{
- return (struct netstats *)(dev->priv);
-}
-
-/*********************************************
- *
- * Set or clear the multicast filter for this adaptor.
- * (no real multicast implemented for the DE-620, but she can be promiscuous...)
- *
- */
-
-static void de620_set_multicast_list(struct device *dev)
-{
- if (dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC))
- { /* Enable promiscuous mode */
- /*
- * We must make the kernel realise we had to move
- * into promisc mode or we start all out war on
- * the cable. - AC
- */
- dev->flags|=IFF_PROMISC;
-
- de620_set_register(dev, W_TCR, (TCR_DEF & ~RXPBM) | RXALL);
- }
- else
- { /* Disable promiscuous mode, use normal mode */
- de620_set_register(dev, W_TCR, TCR_DEF);
- }
-}
-
-/*******************************************************
- *
- * Copy a buffer to the adapter transmit page memory.
- * Start sending.
- */
-static int
-de620_start_xmit(struct sk_buff *skb, struct device *dev)
-{
- unsigned long flags;
- int len;
- int tickssofar;
- byte *buffer = skb->data;
- byte using_txbuf;
-
- /*
- * If some higher layer thinks we've missed a
- * tx-done interrupt we are passed NULL.
- * Caution: dev_tint() handles the cli()/sti() itself.
- */
-
- if (skb == NULL) {
- dev_tint(dev);
- return 0;
- }
-
- using_txbuf = de620_tx_buffs(dev); /* Peek at the adapter */
- dev->tbusy = (using_txbuf == (TXBF0 | TXBF1)); /* Boolean! */
-
- if (dev->tbusy) { /* Do timeouts, to avoid hangs. */
- tickssofar = jiffies - dev->trans_start;
-
- if (tickssofar < 5)
- return 1;
-
- /* else */
- printk("%s: transmit timed out (%d), %s?\n",
- dev->name,
- tickssofar,
- "network cable problem"
- );
- /* Restart the adapter. */
- if (adapter_init(dev)) /* maybe close it */
- return 1;
- }
-
- if ((len = skb->len) < RUNT)
- len = RUNT;
- if (len & 1) /* send an even number of bytes */
- ++len;
-
- /* Start real output */
- save_flags(flags);
- cli();
-
- PRINTK(("de620_start_xmit: len=%d, bufs 0x%02x\n",
- (int)skb->len, using_txbuf));
-
- /* select a free tx buffer. if there is one... */
- switch (using_txbuf) {
- default: /* both are free: use TXBF0 */
- case TXBF1: /* use TXBF0 */
- de620_send_command(dev,W_CR | RW0);
- using_txbuf |= TXBF0;
- break;
-
- case TXBF0: /* use TXBF1 */
- de620_send_command(dev,W_CR | RW1);
- using_txbuf |= TXBF1;
- break;
-
- case (TXBF0 | TXBF1): /* NONE!!! */
- printk("de620: Ouch! No tx-buffer available!\n");
- restore_flags(flags);
- return 1;
- break;
- }
- de620_write_block(dev, buffer, len);
-
- dev->trans_start = jiffies;
- dev->tbusy = (using_txbuf == (TXBF0 | TXBF1)); /* Boolean! */
-
- ((struct netstats *)(dev->priv))->tx_packets++;
-
- restore_flags(flags); /* interrupts maybe back on */
-
- dev_kfree_skb (skb, FREE_WRITE);
-
- return 0;
-}
-
-/*****************************************************
- *
- * Handle the network interface interrupts.
- *
- */
-static void
-de620_interrupt(int irq_in, struct pt_regs *regs)
-{
- struct device *dev = irq2dev_map[irq_in];
- byte irq_status;
- int bogus_count = 0;
- int again = 0;
-
- /* This might be deleted now, no crummy drivers present :-) Or..? */
- if ((dev == NULL) || (irq != irq_in)) {
- printk("%s: bogus interrupt %d\n", dev?dev->name:"de620", irq_in);
- return;
- }
-
- cli();
- dev->interrupt = 1;
-
- /* Read the status register (_not_ the status port) */
- irq_status = de620_get_register(dev, R_STS);
-
- PRINTK(("de620_interrupt (%2.2X)\n", irq_status));
-
- if (irq_status & RXGOOD) {
- do {
- again = de620_rx_intr(dev);
- PRINTK(("again=%d\n", again));
- }
- while (again && (++bogus_count < 100));
- }
-
- dev->tbusy = (de620_tx_buffs(dev) == (TXBF0 | TXBF1)); /* Boolean! */
-
- dev->interrupt = 0;
- sti();
- return;
-}
-
-/**************************************
- *
- * Get a packet from the adapter
- *
- * Send it "upstairs"
- *
- */
-static int
-de620_rx_intr(struct device *dev)
-{
- struct header_buf {
- byte status;
- byte Rx_NextPage;
- unsigned short Rx_ByteCount;
- } header_buf;
- struct sk_buff *skb;
- int size;
- byte *buffer;
- byte pagelink;
- byte curr_page;
-
- PRINTK(("de620_rx_intr: next_rx_page = %d\n", next_rx_page));
-
- /* Tell the adapter that we are going to read data, and from where */
- de620_send_command(dev, W_CR | RRN);
- de620_set_register(dev, W_RSA1, next_rx_page);
- de620_set_register(dev, W_RSA0, 0);
-
- /* Deep breath, and away we goooooo */
- de620_read_block(dev, (byte *)&header_buf, sizeof(struct header_buf));
- PRINTK(("page status=0x%02x, nextpage=%d, packetsize=%d\n",
- header_buf.status, header_buf.Rx_NextPage, header_buf.Rx_ByteCount));
-
- /* Plausible page header? */
- pagelink = header_buf.Rx_NextPage;
- if ((pagelink < first_rx_page) || (last_rx_page < pagelink)) {
- /* Ouch... Forget it! Skip all and start afresh... */
- printk("%s: Ring overrun? Restoring...\n", dev->name);
- /* You win some, you loose some. And sometimes plenty... */
- adapter_init(dev);
- ((struct netstats *)(dev->priv))->rx_over_errors++;
- return 0;
- }
-
- /* OK, this look good, so far. Let's see if it's consistent... */
- /* Let's compute the start of the next packet, based on where we are */
- pagelink = next_rx_page +
- ((header_buf.Rx_ByteCount + (4 - 1 + 0x100)) >> 8);
-
- /* Are we going to wrap around the page counter? */
- if (pagelink > last_rx_page)
- pagelink -= (last_rx_page - first_rx_page + 1);
-
- /* Is the _computed_ next page number equal to what the adapter says? */
- if (pagelink != header_buf.Rx_NextPage) {
- /* Naah, we'll skip this packet. Probably bogus data as well */
- printk("%s: Page link out of sync! Restoring...\n", dev->name);
- next_rx_page = header_buf.Rx_NextPage; /* at least a try... */
- de620_send_command(dev, W_DUMMY);
- de620_set_register(dev, W_NPRF, next_rx_page);
- ((struct netstats *)(dev->priv))->rx_over_errors++;
- return 0;
- }
- next_rx_page = pagelink;
-
- size = header_buf.Rx_ByteCount - 4;
- if ((size < RUNT) || (GIANT < size)) {
- printk("%s: Illegal packet size: %d!\n", dev->name, size);
- }
- else { /* Good packet? */
- skb = dev_alloc_skb(size+2);
- if (skb == NULL) { /* Yeah, but no place to put it... */
- printk("%s: Couldn't allocate a sk_buff of size %d.\n",
- dev->name, size);
- ((struct netstats *)(dev->priv))->rx_dropped++;
- }
- else { /* Yep! Go get it! */
- skb_reserve(skb,2); /* Align */
- skb->dev = dev;
- skb->free = 1;
- /* skb->data points to the start of sk_buff data area */
- buffer = skb_put(skb,size);
- /* copy the packet into the buffer */
- de620_read_block(dev, buffer, size);
- PRINTK(("Read %d bytes\n", size));
- skb->protocol=eth_type_trans(skb,dev);
- netif_rx(skb); /* deliver it "upstairs" */
- /* count all receives */
- ((struct netstats *)(dev->priv))->rx_packets++;
- }
- }
-
- /* Let's peek ahead to see if we have read the last current packet */
- /* NOTE! We're _not_ checking the 'EMPTY'-flag! This seems better... */
- curr_page = de620_get_register(dev, R_CPR);
- de620_set_register(dev, W_NPRF, next_rx_page);
- PRINTK(("next_rx_page=%d CPR=%d\n", next_rx_page, curr_page));
-
- return (next_rx_page != curr_page); /* That was slightly tricky... */
-}
-
-/*********************************************
- *
- * Reset the adapter to a known state
- *
- */
-static int
-adapter_init(struct device *dev)
-{
- int i;
- static int was_down = 0;
-
- if ((nic_data.Model == 3) || (nic_data.Model == 0)) { /* CT */
- EIPRegister = NCTL0;
- if (nic_data.Media != 1)
- EIPRegister |= NIS0; /* not BNC */
- }
- else if (nic_data.Model == 2) { /* UTP */
- EIPRegister = NCTL0 | NIS0;
- }
-
- if (utp)
- EIPRegister = NCTL0 | NIS0;
- if (bnc)
- EIPRegister = NCTL0;
-
- de620_send_command(dev, W_CR | RNOP | CLEAR);
- de620_send_command(dev, W_CR | RNOP);
-
- de620_set_register(dev, W_SCR, SCR_DEF);
- /* disable recv to wait init */
- de620_set_register(dev, W_TCR, RXOFF);
-
- /* Set the node ID in the adapter */
- for (i = 0; i < 6; ++i) { /* W_PARn = 0xaa + n */
- de620_set_register(dev, W_PAR0 + i, dev->dev_addr[i]);
- }
-
- de620_set_register(dev, W_EIP, EIPRegister);
-
- next_rx_page = first_rx_page = DE620_RX_START_PAGE;
- if (nic_data.RAM_Size)
- last_rx_page = nic_data.RAM_Size - 1;
- else /* 64k RAM */
- last_rx_page = 255;
-
- de620_set_register(dev, W_SPR, first_rx_page); /* Start Page Register*/
- de620_set_register(dev, W_EPR, last_rx_page); /* End Page Register */
- de620_set_register(dev, W_CPR, first_rx_page);/*Current Page Register*/
- de620_send_command(dev, W_NPR | first_rx_page); /* Next Page Register*/
- de620_send_command(dev, W_DUMMY);
- de620_set_delay(dev);
-
- /* Final sanity check: Anybody out there? */
- /* Let's hope some bits from the statusregister make a good check */
-#define CHECK_MASK ( 0 | TXSUC | T16 | 0 | RXCRC | RXSHORT | 0 | 0 )
-#define CHECK_OK ( 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 )
- /* success: X 0 0 X 0 0 X X */
- /* ignore: EEDI RXGOOD COLS LNKS*/
-
- if (((i = de620_get_register(dev, R_STS)) & CHECK_MASK) != CHECK_OK) {
- printk("Something has happened to the DE-620! Please check it"
-#ifdef SHUTDOWN_WHEN_LOST
- " and do a new ifconfig"
-#endif
- "! (%02x)\n", i);
-#ifdef SHUTDOWN_WHEN_LOST
- /* Goodbye, cruel world... */
- dev->flags &= ~IFF_UP;
- de620_close(dev);
-#endif
- was_down = 1;
- return 1; /* failed */
- }
- if (was_down) {
- printk("Thanks, I feel much better now!\n");
- was_down = 0;
- }
-
- /* All OK, go ahead... */
- de620_set_register(dev, W_TCR, TCR_DEF);
-
- return 0; /* all ok */
-}
-
-/******************************************************************************
- *
- * Only start-up code below
- *
- */
-/****************************************
- *
- * Check if there is a DE-620 connected
- */
-int
-de620_probe(struct device *dev)
-{
- static struct netstats de620_netstats;
- int i;
- byte checkbyte = 0xa5;
-
- /*
- * This is where the base_addr and irq gets set.
- * Tunable at compile-time and insmod-time
- */
- dev->base_addr = io;
- dev->irq = irq;
-
- if (de620_debug)
- printk(version);
-
- printk("D-Link DE-620 pocket adapter");
-
- /* Initially, configure basic nibble mode, so we can read the EEPROM */
- NIC_Cmd = DEF_NIC_CMD;
- de620_set_register(dev, W_EIP, EIPRegister);
-
- /* Anybody out there? */
- de620_set_register(dev, W_CPR, checkbyte);
- checkbyte = de620_get_register(dev, R_CPR);
-
- if ((checkbyte != 0xa5) || (read_eeprom(dev) != 0)) {
- printk(" not identified in the printer port\n");
- return ENODEV;
- }
-
-#if 0 /* Not yet */
- if (check_region(dev->base_addr, 3)) {
- printk(", port 0x%x busy\n", dev->base_addr);
- return EBUSY;
- }
-#endif
- request_region(dev->base_addr, 3, "de620");
-
- /* else, got it! */
- printk(", Ethernet Address: %2.2X",
- dev->dev_addr[0] = nic_data.NodeID[0]);
- for (i = 1; i < ETH_ALEN; i++) {
- printk(":%2.2X", dev->dev_addr[i] = nic_data.NodeID[i]);
- dev->broadcast[i] = 0xff;
- }
-
- printk(" (%dk RAM,",
- (nic_data.RAM_Size) ? (nic_data.RAM_Size >> 2) : 64);
-
- if (nic_data.Media == 1)
- printk(" BNC)\n");
- else
- printk(" UTP)\n");
-
- /* Initialize the device structure. */
- /*dev->priv = kmalloc(sizeof(struct netstats), GFP_KERNEL);*/
- dev->priv = &de620_netstats;
-
- memset(dev->priv, 0, sizeof(struct netstats));
- dev->get_stats = get_stats;
- dev->open = de620_open;
- dev->stop = de620_close;
- dev->hard_start_xmit = &de620_start_xmit;
- dev->set_multicast_list = &de620_set_multicast_list;
- /* base_addr and irq are already set, see above! */
-
- ether_setup(dev);
-
- /* dump eeprom */
- if (de620_debug) {
- printk("\nEEPROM contents:\n");
- printk("RAM_Size = 0x%02X\n", nic_data.RAM_Size);
- printk("NodeID = %02X:%02X:%02X:%02X:%02X:%02X\n",
- nic_data.NodeID[0], nic_data.NodeID[1],
- nic_data.NodeID[2], nic_data.NodeID[3],
- nic_data.NodeID[4], nic_data.NodeID[5]);
- printk("Model = %d\n", nic_data.Model);
- printk("Media = %d\n", nic_data.Media);
- printk("SCR = 0x%02x\n", nic_data.SCR);
- }
-
- return 0;
-}
-
-/**********************************
- *
- * Read info from on-board EEPROM
- *
- * Note: Bitwise serial I/O to/from the EEPROM vi the status _register_!
- */
-#define sendit(dev,data) de620_set_register(dev, W_EIP, data | EIPRegister);
-
-static unsigned short
-ReadAWord(struct device *dev, int from)
-{
- unsigned short data;
- int nbits;
-
- /* cs [__~~] SET SEND STATE */
- /* di [____] */
- /* sck [_~~_] */
- sendit(dev, 0); sendit(dev, 1); sendit(dev, 5); sendit(dev, 4);
-
- /* Send the 9-bit address from where we want to read the 16-bit word */
- for (nbits = 9; nbits > 0; --nbits, from <<= 1) {
- if (from & 0x0100) { /* bit set? */
- /* cs [~~~~] SEND 1 */
- /* di [~~~~] */
- /* sck [_~~_] */
- sendit(dev, 6); sendit(dev, 7); sendit(dev, 7); sendit(dev, 6);
- }
- else {
- /* cs [~~~~] SEND 0 */
- /* di [____] */
- /* sck [_~~_] */
- sendit(dev, 4); sendit(dev, 5); sendit(dev, 5); sendit(dev, 4);
- }
- }
-
- /* Shift in the 16-bit word. The bits appear serially in EEDI (=0x80) */
- for (data = 0, nbits = 16; nbits > 0; --nbits) {
- /* cs [~~~~] SEND 0 */
- /* di [____] */
- /* sck [_~~_] */
- sendit(dev, 4); sendit(dev, 5); sendit(dev, 5); sendit(dev, 4);
- data = (data << 1) | ((de620_get_register(dev, R_STS) & EEDI) >> 7);
- }
- /* cs [____] RESET SEND STATE */
- /* di [____] */
- /* sck [_~~_] */
- sendit(dev, 0); sendit(dev, 1); sendit(dev, 1); sendit(dev, 0);
-
- return data;
-}
-
-static int
-read_eeprom(struct device *dev)
-{
- unsigned short wrd;
-
- /* D-Link Ethernet addresses are in the series 00:80:c8:7X:XX:XX:XX */
- wrd = ReadAWord(dev, 0x1aa); /* bytes 0 + 1 of NodeID */
- if (!clone && (wrd != htons(0x0080))) /* Valid D-Link ether sequence? */
- return -1; /* Nope, not a DE-620 */
- nic_data.NodeID[0] = wrd & 0xff;
- nic_data.NodeID[1] = wrd >> 8;
-
- wrd = ReadAWord(dev, 0x1ab); /* bytes 2 + 3 of NodeID */
- if (!clone && ((wrd & 0xff) != 0xc8)) /* Valid D-Link ether sequence? */
- return -1; /* Nope, not a DE-620 */
- nic_data.NodeID[2] = wrd & 0xff;
- nic_data.NodeID[3] = wrd >> 8;
-
- wrd = ReadAWord(dev, 0x1ac); /* bytes 4 + 5 of NodeID */
- nic_data.NodeID[4] = wrd & 0xff;
- nic_data.NodeID[5] = wrd >> 8;
-
- wrd = ReadAWord(dev, 0x1ad); /* RAM size in pages (256 bytes). 0 = 64k */
- nic_data.RAM_Size = (wrd >> 8);
-
- wrd = ReadAWord(dev, 0x1ae); /* hardware model (CT = 3) */
- nic_data.Model = (wrd & 0xff);
-
- wrd = ReadAWord(dev, 0x1af); /* media (indicates BNC/UTP) */
- nic_data.Media = (wrd & 0xff);
-
- wrd = ReadAWord(dev, 0x1a8); /* System Configuration Register */
- nic_data.SCR = (wrd >> 8);
-
- return 0; /* no errors */
-}
-
-/******************************************************************************
- *
- * Loadable module skeleton
- *
- */
-#ifdef MODULE
-static char nullname[8] = "";
-static struct device de620_dev = {
- nullname, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, de620_probe };
-
-int
-init_module(void)
-{
- if (register_netdev(&de620_dev) != 0)
- return -EIO;
- return 0;
-}
-
-void
-cleanup_module(void)
-{
- unregister_netdev(&de620_dev);
- release_region(de620_dev.base_addr, 3);
-}
-#endif /* MODULE */
-
-/*
- * (add '-DMODULE' when compiling as loadable module)
- *
- * compile-command:
- * gcc -D__KERNEL__ -Wall -Wstrict-prototypes -O2 \
- * -fomit-frame-pointer -m486 \
- * -I/usr/src/linux/include -I../../net/inet -c de620.c
-*/
-/*
- * Local variables:
- * kernel-compile-command: "gcc -D__KERNEL__ -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de620.c"
- * module-compile-command: "gcc -D__KERNEL__ -DMODULE -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de620.c"
- * compile-command: "gcc -D__KERNEL__ -DMODULE -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de620.c"
- * End:
- */
diff --git a/i386/i386at/gpl/linux/net/de620.h b/i386/i386at/gpl/linux/net/de620.h
deleted file mode 100644
index e8d9a88f..00000000
--- a/i386/i386at/gpl/linux/net/de620.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*********************************************************
- * *
- * Definition of D-Link DE-620 Ethernet Pocket adapter *
- * *
- *********************************************************/
-
-/* DE-620's CMD port Command */
-#define CS0 0x08 /* 1->0 command strobe */
-#define ICEN 0x04 /* 0=enable DL3520 host interface */
-#define DS0 0x02 /* 1->0 data strobe 0 */
-#define DS1 0x01 /* 1->0 data strobe 1 */
-
-#define WDIR 0x20 /* general 0=read 1=write */
-#define RDIR 0x00 /* (not 100% confirm ) */
-#define PS2WDIR 0x00 /* ps/2 mode 1=read, 0=write */
-#define PS2RDIR 0x20
-
-#define IRQEN 0x10 /* 1 = enable printer IRQ line */
-#define SELECTIN 0x08 /* 1 = select printer */
-#define INITP 0x04 /* 0 = initial printer */
-#define AUTOFEED 0x02 /* 1 = printer auto form feed */
-#define STROBE 0x01 /* 0->1 data strobe */
-
-#define RESET 0x08
-#define NIS0 0x20 /* 0 = BNC, 1 = UTP */
-#define NCTL0 0x10
-
-/* DE-620 DIC Command */
-#define W_DUMMY 0x00 /* DIC reserved command */
-#define W_CR 0x20 /* DIC write command register */
-#define W_NPR 0x40 /* DIC write Next Page Register */
-#define W_TBR 0x60 /* DIC write Tx Byte Count 1 reg */
-#define W_RSA 0x80 /* DIC write Remote Start Addr 1 */
-
-/* DE-620's STAT port bits 7-4 */
-#define EMPTY 0x80 /* 1 = receive buffer empty */
-#define INTLEVEL 0x40 /* 1 = interrupt level is high */
-#define TXBF1 0x20 /* 1 = transmit buffer 1 is in use */
-#define TXBF0 0x10 /* 1 = transmit buffer 0 is in use */
-#define READY 0x08 /* 1 = h/w ready to accept cmd/data */
-
-/* IDC 1 Command */
-#define W_RSA1 0xa0 /* write remote start address 1 */
-#define W_RSA0 0xa1 /* write remote start address 0 */
-#define W_NPRF 0xa2 /* write next page register NPR15-NPR8 */
-#define W_DFR 0xa3 /* write delay factor register */
-#define W_CPR 0xa4 /* write current page register */
-#define W_SPR 0xa5 /* write start page register */
-#define W_EPR 0xa6 /* write end page register */
-#define W_SCR 0xa7 /* write system configuration register */
-#define W_TCR 0xa8 /* write Transceiver Configuration reg */
-#define W_EIP 0xa9 /* write EEPM Interface port */
-#define W_PAR0 0xaa /* write physical address register 0 */
-#define W_PAR1 0xab /* write physical address register 1 */
-#define W_PAR2 0xac /* write physical address register 2 */
-#define W_PAR3 0xad /* write physical address register 3 */
-#define W_PAR4 0xae /* write physical address register 4 */
-#define W_PAR5 0xaf /* write physical address register 5 */
-
-/* IDC 2 Command */
-#define R_STS 0xc0 /* read status register */
-#define R_CPR 0xc1 /* read current page register */
-#define R_BPR 0xc2 /* read boundary page register */
-#define R_TDR 0xc3 /* read time domain reflectometry reg */
-
-/* STATUS Register */
-#define EEDI 0x80 /* EEPM DO pin */
-#define TXSUC 0x40 /* tx success */
-#define T16 0x20 /* tx fail 16 times */
-#define TS1 0x40 /* 0=Tx success, 1=T16 */
-#define TS0 0x20 /* 0=Tx success, 1=T16 */
-#define RXGOOD 0x10 /* rx a good packet */
-#define RXCRC 0x08 /* rx a CRC error packet */
-#define RXSHORT 0x04 /* rx a short packet */
-#define COLS 0x02 /* coaxial collision status */
-#define LNKS 0x01 /* UTP link status */
-
-/* Command Register */
-#define CLEAR 0x10 /* reset part of hardware */
-#define NOPER 0x08 /* No Operation */
-#define RNOP 0x08
-#define RRA 0x06 /* After RR then auto-advance NPR & BPR(=NPR-1) */
-#define RRN 0x04 /* Normal Remote Read mode */
-#define RW1 0x02 /* Remote Write tx buffer 1 ( page 6 - 11 ) */
-#define RW0 0x00 /* Remote Write tx buffer 0 ( page 0 - 5 ) */
-#define TXEN 0x01 /* 0->1 tx enable */
-
-/* System Configuration Register */
-#define TESTON 0x80 /* test host data transfer reliability */
-#define SLEEP 0x40 /* sleep mode */
-#if 0
-#define FASTMODE 0x04 /* fast mode for intel 82360SL fast mode */
-#define BYTEMODE 0x02 /* byte mode */
-#else
-#define FASTMODE 0x20 /* fast mode for intel 82360SL fast mode */
-#define BYTEMODE 0x10 /* byte mode */
-#endif
-#define NIBBLEMODE 0x00 /* nibble mode */
-#define IRQINV 0x08 /* turn off IRQ line inverter */
-#define IRQNML 0x00 /* turn on IRQ line inverter */
-#define INTON 0x04
-#define AUTOFFSET 0x02 /* auto shift address to TPR+12 */
-#define AUTOTX 0x01 /* auto tx when leave RW mode */
-
-/* Transceiver Configuration Register */
-#define JABBER 0x80 /* generate jabber condition */
-#define TXSUCINT 0x40 /* enable tx success interrupt */
-#define T16INT 0x20 /* enable T16 interrupt */
-#define RXERRPKT 0x10 /* accept CRC error or short packet */
-#define EXTERNALB2 0x0C /* external loopback 2 */
-#define EXTERNALB1 0x08 /* external loopback 1 */
-#define INTERNALB 0x04 /* internal loopback */
-#define NMLOPERATE 0x00 /* normal operation */
-#define RXPBM 0x03 /* rx physical, broadcast, multicast */
-#define RXPB 0x02 /* rx physical, broadcast */
-#define RXALL 0x01 /* rx all packet */
-#define RXOFF 0x00 /* rx disable */
diff --git a/i386/i386at/gpl/linux/net/depca.c b/i386/i386at/gpl/linux/net/depca.c
deleted file mode 100644
index ae9a8ca3..00000000
--- a/i386/i386at/gpl/linux/net/depca.c
+++ /dev/null
@@ -1,1901 +0,0 @@
-/* depca.c: A DIGITAL DEPCA & EtherWORKS ethernet driver for linux.
-
- Written 1994, 1995 by David C. Davies.
-
-
- Copyright 1994 David C. Davies
- and
- United States Government
- (as represented by the Director, National Security Agency).
-
- Copyright 1995 Digital Equipment Corporation.
-
-
- This software may be used and distributed according to the terms of
- the GNU Public License, incorporated herein by reference.
-
- This driver is written for the Digital Equipment Corporation series
- of DEPCA and EtherWORKS ethernet cards:
-
- DEPCA (the original)
- DE100
- DE101
- DE200 Turbo
- DE201 Turbo
- DE202 Turbo (TP BNC)
- DE210
- DE422 (EISA)
-
- The driver has been tested on DE100, DE200 and DE202 cards in a
- relatively busy network. The DE422 has been tested a little.
-
- This driver will NOT work for the DE203, DE204 and DE205 series of
- cards, since they have a new custom ASIC in place of the AMD LANCE
- chip. See the 'ewrk3.c' driver in the Linux source tree for running
- those cards.
-
- I have benchmarked the driver with a DE100 at 595kB/s to (542kB/s from)
- a DECstation 5000/200.
-
- The author may be reached at davies@wanton.lkg.dec.com or
- davies@maniac.ultranet.com or Digital Equipment Corporation, 550 King
- Street, Littleton MA 01460.
-
- =========================================================================
-
- The driver was originally based on the 'lance.c' driver from Donald
- Becker which is included with the standard driver distribution for
- linux. V0.4 is a complete re-write with only the kernel interface
- remaining from the original code.
-
- 1) Lance.c code in /linux/drivers/net/
- 2) "Ethernet/IEEE 802.3 Family. 1992 World Network Data Book/Handbook",
- AMD, 1992 [(800) 222-9323].
- 3) "Am79C90 CMOS Local Area Network Controller for Ethernet (C-LANCE)",
- AMD, Pub. #17881, May 1993.
- 4) "Am79C960 PCnet-ISA(tm), Single-Chip Ethernet Controller for ISA",
- AMD, Pub. #16907, May 1992
- 5) "DEC EtherWORKS LC Ethernet Controller Owners Manual",
- Digital Equipment corporation, 1990, Pub. #EK-DE100-OM.003
- 6) "DEC EtherWORKS Turbo Ethernet Controller Owners Manual",
- Digital Equipment corporation, 1990, Pub. #EK-DE200-OM.003
- 7) "DEPCA Hardware Reference Manual", Pub. #EK-DEPCA-PR
- Digital Equipment Corporation, 1989
- 8) "DEC EtherWORKS Turbo_(TP BNC) Ethernet Controller Owners Manual",
- Digital Equipment corporation, 1991, Pub. #EK-DE202-OM.001
-
-
- Peter Bauer's depca.c (V0.5) was referred to when debugging V0.1 of this
- driver.
-
- The original DEPCA card requires that the ethernet ROM address counter
- be enabled to count and has an 8 bit NICSR. The ROM counter enabling is
- only done when a 0x08 is read as the first address octet (to minimise
- the chances of writing over some other hardware's I/O register). The
- NICSR accesses have been changed to byte accesses for all the cards
- supported by this driver, since there is only one useful bit in the MSB
- (remote boot timeout) and it is not used. Also, there is a maximum of
- only 48kB network RAM for this card. My thanks to Torbjorn Lindh for
- help debugging all this (and holding my feet to the fire until I got it
- right).
-
- The DE200 series boards have on-board 64kB RAM for use as a shared
- memory network buffer. Only the DE100 cards make use of a 2kB buffer
- mode which has not been implemented in this driver (only the 32kB and
- 64kB modes are supported [16kB/48kB for the original DEPCA]).
-
- At the most only 2 DEPCA cards can be supported on the ISA bus because
- there is only provision for two I/O base addresses on each card (0x300
- and 0x200). The I/O address is detected by searching for a byte sequence
- in the Ethernet station address PROM at the expected I/O address for the
- Ethernet PROM. The shared memory base address is 'autoprobed' by
- looking for the self test PROM and detecting the card name. When a
- second DEPCA is detected, information is placed in the base_addr
- variable of the next device structure (which is created if necessary),
- thus enabling ethif_probe initialization for the device. More than 2
- EISA cards can be supported, but care will be needed assigning the
- shared memory to ensure that each slot has the correct IRQ, I/O address
- and shared memory address assigned.
-
- ************************************************************************
-
- NOTE: If you are using two ISA DEPCAs, it is important that you assign
- the base memory addresses correctly. The driver autoprobes I/O 0x300
- then 0x200. The base memory address for the first device must be less
- than that of the second so that the auto probe will correctly assign the
- I/O and memory addresses on the same card. I can't think of a way to do
- this unambiguously at the moment, since there is nothing on the cards to
- tie I/O and memory information together.
-
- I am unable to test 2 cards together for now, so this code is
- unchecked. All reports, good or bad, are welcome.
-
- ************************************************************************
-
- The board IRQ setting must be at an unused IRQ which is auto-probed
- using Donald Becker's autoprobe routines. DEPCA and DE100 board IRQs are
- {2,3,4,5,7}, whereas the DE200 is at {5,9,10,11,15}. Note that IRQ2 is
- really IRQ9 in machines with 16 IRQ lines.
-
- No 16MB memory limitation should exist with this driver as DMA is not
- used and the common memory area is in low memory on the network card (my
- current system has 20MB and I've not had problems yet).
-
- The ability to load this driver as a loadable module has been added. To
- utilise this ability, you have to do <8 things:
-
- 0) have a copy of the loadable modules code installed on your system.
- 1) copy depca.c from the /linux/drivers/net directory to your favourite
- temporary directory.
- 2) if you wish, edit the source code near line 1530 to reflect the I/O
- address and IRQ you're using (see also 5).
- 3) compile depca.c, but include -DMODULE in the command line to ensure
- that the correct bits are compiled (see end of source code).
- 4) if you are wanting to add a new card, goto 5. Otherwise, recompile a
- kernel with the depca configuration turned off and reboot.
- 5) insmod depca.o [irq=7] [io=0x200] [mem=0xd0000] [adapter_name=DE100]
- [Alan Cox: Changed the code to allow command line irq/io assignments]
- [Dave Davies: Changed the code to allow command line mem/name
- assignments]
- 6) run the net startup bits for your eth?? interface manually
- (usually /etc/rc.inet[12] at boot time).
- 7) enjoy!
-
- Note that autoprobing is not allowed in loadable modules - the system is
- already up and running and you're messing with interrupts.
-
- To unload a module, turn off the associated interface
- 'ifconfig eth?? down' then 'rmmod depca'.
-
- To assign a base memory address for the shared memory when running as a
- loadable module, see 5 above. To include the adapter name (if you have
- no PROM but know the card name) also see 5 above. Note that this last
- option will not work with kernel built-in depca's.
-
- The shared memory assignment for a loadable module makes sense to avoid
- the 'memory autoprobe' picking the wrong shared memory (for the case of
- 2 depca's in a PC).
-
-
- TO DO:
- ------
-
-
- Revision History
- ----------------
-
- Version Date Description
-
- 0.1 25-jan-94 Initial writing.
- 0.2 27-jan-94 Added LANCE TX hardware buffer chaining.
- 0.3 1-feb-94 Added multiple DEPCA support.
- 0.31 4-feb-94 Added DE202 recognition.
- 0.32 19-feb-94 Tidy up. Improve multi-DEPCA support.
- 0.33 25-feb-94 Fix DEPCA ethernet ROM counter enable.
- Add jabber packet fix from murf@perftech.com
- and becker@super.org
- 0.34 7-mar-94 Fix DEPCA max network memory RAM & NICSR access.
- 0.35 8-mar-94 Added DE201 recognition. Tidied up.
- 0.351 30-apr-94 Added EISA support. Added DE422 recognition.
- 0.36 16-may-94 DE422 fix released.
- 0.37 22-jul-94 Added MODULE support
- 0.38 15-aug-94 Added DBR ROM switch in depca_close().
- Multi DEPCA bug fix.
- 0.38axp 15-sep-94 Special version for Alpha AXP Linux V1.0.
- 0.381 12-dec-94 Added DE101 recognition, fix multicast bug.
- 0.382 9-feb-95 Fix recognition bug reported by <bkm@star.rl.ac.uk>.
- 0.383 22-feb-95 Fix for conflict with VESA SCSI reported by
- <stromain@alf.dec.com>
- 0.384 17-mar-95 Fix a ring full bug reported by <bkm@star.rl.ac.uk>
- 0.385 3-apr-95 Fix a recognition bug reported by
- <ryan.niemi@lastfrontier.com>
- 0.386 21-apr-95 Fix the last fix...sorry, must be galloping senility
- 0.40 25-May-95 Rewrite for portability & updated.
- ALPHA support from <jestabro@amt.tay1.dec.com>
- 0.41 26-Jun-95 Added verify_area() calls in depca_ioctl() from
- suggestion by <heiko@colossus.escape.de>
- 0.42 27-Dec-95 Add 'mem' shared memory assigment for loadable
- modules.
- Add 'adapter_name' for loadable modules when no PROM.
- Both above from a suggestion by
- <pchen@woodruffs121.residence.gatech.edu>.
- Add new multicasting code.
-
- =========================================================================
-*/
-
-static const char *version = "depca.c:v0.42 95/12/27 davies@wanton.lkg.dec.com\n";
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/ptrace.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/malloc.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <asm/segment.h>
-#include <asm/bitops.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-
-#include <linux/time.h>
-#include <linux/types.h>
-#include <linux/unistd.h>
-
-#include "depca.h"
-
-#ifdef DEPCA_DEBUG
-static int depca_debug = DEPCA_DEBUG;
-#else
-static int depca_debug = 1;
-#endif
-
-#define DEPCA_NDA 0xffe0 /* No Device Address */
-
-/*
-** Ethernet PROM defines
-*/
-#define PROBE_LENGTH 32
-#define ETH_PROM_SIG 0xAA5500FFUL
-
-/*
-** Set the number of Tx and Rx buffers. Ensure that the memory requested
-** here is <= to the amount of shared memory set up by the board switches.
-** The number of descriptors MUST BE A POWER OF 2.
-**
-** total_memory = NUM_RX_DESC*(8+RX_BUFF_SZ) + NUM_TX_DESC*(8+TX_BUFF_SZ)
-*/
-#define NUM_RX_DESC 8 /* Number of RX descriptors */
-#define NUM_TX_DESC 8 /* Number of TX descriptors */
-#define RX_BUFF_SZ 1536 /* Buffer size for each Rx buffer */
-#define TX_BUFF_SZ 1536 /* Buffer size for each Tx buffer */
-
-#define CRC_POLYNOMIAL_BE 0x04c11db7UL /* Ethernet CRC, big endian */
-#define CRC_POLYNOMIAL_LE 0xedb88320UL /* Ethernet CRC, little endian */
-
-/*
-** EISA bus defines
-*/
-#define DEPCA_EISA_IO_PORTS 0x0c00 /* I/O port base address, slot 0 */
-#define MAX_EISA_SLOTS 16
-#define EISA_SLOT_INC 0x1000
-
-/*
-** ISA Bus defines
-*/
-#define DEPCA_RAM_BASE_ADDRESSES {0xc0000,0xd0000,0xe0000,0x00000}
-#define DEPCA_IO_PORTS {0x300, 0x200, 0}
-#define DEPCA_TOTAL_SIZE 0x10
-static short mem_chkd = 0;
-
-/*
-** Name <-> Adapter mapping
-*/
-#define DEPCA_SIGNATURE {"DEPCA",\
- "DE100","DE101",\
- "DE200","DE201","DE202",\
- "DE210",\
- "DE422",\
- ""}
-static enum {DEPCA, de100, de101, de200, de201, de202, de210, de422, unknown} adapter;
-
-/*
-** Miscellaneous info...
-*/
-#define DEPCA_STRLEN 16
-#define MAX_NUM_DEPCAS 2
-
-/*
-** Memory Alignment. Each descriptor is 4 longwords long. To force a
-** particular alignment on the TX descriptor, adjust DESC_SKIP_LEN and
-** DESC_ALIGN. ALIGN aligns the start address of the private memory area
-** and hence the RX descriptor ring's first entry.
-*/
-#define ALIGN4 ((u_long)4 - 1) /* 1 longword align */
-#define ALIGN8 ((u_long)8 - 1) /* 2 longword (quadword) align */
-#define ALIGN ALIGN8 /* Keep the LANCE happy... */
-
-/*
-** The DEPCA Rx and Tx ring descriptors.
-*/
-struct depca_rx_desc {
- volatile s32 base;
- s16 buf_length; /* This length is negative 2's complement! */
- s16 msg_length; /* This length is "normal". */
-};
-
-struct depca_tx_desc {
- volatile s32 base;
- s16 length; /* This length is negative 2's complement! */
- s16 misc; /* Errors and TDR info */
-};
-
-#define LA_MASK 0x0000ffff /* LANCE address mask for mapping network RAM
- to LANCE memory address space */
-
-/*
-** The Lance initialization block, described in databook, in common memory.
-*/
-struct depca_init {
- u16 mode; /* Mode register */
- u8 phys_addr[ETH_ALEN]; /* Physical ethernet address */
- u8 mcast_table[8]; /* Multicast Hash Table. */
- u32 rx_ring; /* Rx ring base pointer & ring length */
- u32 tx_ring; /* Tx ring base pointer & ring length */
-};
-
-#define DEPCA_PKT_STAT_SZ 16
-#define DEPCA_PKT_BIN_SZ 128 /* Should be >=100 unless you
- increase DEPCA_PKT_STAT_SZ */
-struct depca_private {
- char devname[DEPCA_STRLEN]; /* Device Product String */
- char adapter_name[DEPCA_STRLEN];/* /proc/ioports string */
- char adapter; /* Adapter type */
- struct depca_rx_desc *rx_ring; /* Pointer to start of RX descriptor ring */
- struct depca_tx_desc *tx_ring; /* Pointer to start of TX descriptor ring */
- struct depca_init init_block;/* Shadow Initialization block */
- char *rx_memcpy[NUM_RX_DESC]; /* CPU virt address of sh'd memory buffs */
- char *tx_memcpy[NUM_TX_DESC]; /* CPU virt address of sh'd memory buffs */
- u_long bus_offset; /* (E)ISA bus address offset vs LANCE */
- u_long sh_mem; /* Physical start addr of shared mem area */
- u_long dma_buffs; /* LANCE Rx and Tx buffers start address. */
- int rx_new, tx_new; /* The next free ring entry */
- int rx_old, tx_old; /* The ring entries to be free()ed. */
- struct enet_statistics stats;
- struct { /* Private stats counters */
- u32 bins[DEPCA_PKT_STAT_SZ];
- u32 unicast;
- u32 multicast;
- u32 broadcast;
- u32 excessive_collisions;
- u32 tx_underruns;
- u32 excessive_underruns;
- } pktStats;
- int txRingMask; /* TX ring mask */
- int rxRingMask; /* RX ring mask */
- s32 rx_rlen; /* log2(rxRingMask+1) for the descriptors */
- s32 tx_rlen; /* log2(txRingMask+1) for the descriptors */
-};
-
-/*
-** The transmit ring full condition is described by the tx_old and tx_new
-** pointers by:
-** tx_old = tx_new Empty ring
-** tx_old = tx_new+1 Full ring
-** tx_old+txRingMask = tx_new Full ring (wrapped condition)
-*/
-#define TX_BUFFS_AVAIL ((lp->tx_old<=lp->tx_new)?\
- lp->tx_old+lp->txRingMask-lp->tx_new:\
- lp->tx_old -lp->tx_new-1)
-
-/*
-** Public Functions
-*/
-static int depca_open(struct device *dev);
-static int depca_start_xmit(struct sk_buff *skb, struct device *dev);
-static void depca_interrupt(int irq, struct pt_regs * regs);
-static int depca_close(struct device *dev);
-static int depca_ioctl(struct device *dev, struct ifreq *rq, int cmd);
-static struct enet_statistics *depca_get_stats(struct device *dev);
-static void set_multicast_list(struct device *dev);
-
-/*
-** Private functions
-*/
-static int depca_hw_init(struct device *dev, u_long ioaddr);
-static void depca_init_ring(struct device *dev);
-static int depca_rx(struct device *dev);
-static int depca_tx(struct device *dev);
-
-static void LoadCSRs(struct device *dev);
-static int InitRestartDepca(struct device *dev);
-static void DepcaSignature(char *name, u_long paddr);
-static int DevicePresent(u_long ioaddr);
-static int get_hw_addr(struct device *dev);
-static int EISA_signature(char *name, s32 eisa_id);
-static void SetMulticastFilter(struct device *dev);
-static void isa_probe(struct device *dev, u_long iobase);
-static void eisa_probe(struct device *dev, u_long iobase);
-static struct device *alloc_device(struct device *dev, u_long iobase);
-static int load_packet(struct device *dev, struct sk_buff *skb);
-static void depca_dbg_open(struct device *dev);
-
-#ifdef MODULE
-int init_module(void);
-void cleanup_module(void);
-static int autoprobed = 1, loading_module = 1;
-# else
-static u_char de1xx_irq[] = {2,3,4,5,7,0};
-static u_char de2xx_irq[] = {5,9,10,11,15,0};
-static u_char de422_irq[] = {5,9,10,11,0};
-static u_char *depca_irq;
-static int autoprobed = 0, loading_module = 0;
-#endif /* MODULE */
-
-static char name[DEPCA_STRLEN];
-static int num_depcas = 0, num_eth = 0;
-static int mem=0; /* For loadable module assignment
- use insmod mem=0x????? .... */
-static char *adapter_name = '\0'; /* If no PROM when loadable module
- use insmod adapter_name=DE??? ...
- */
-/*
-** Miscellaneous defines...
-*/
-#define STOP_DEPCA \
- outw(CSR0, DEPCA_ADDR);\
- outw(STOP, DEPCA_DATA)
-
-
-
-int depca_probe(struct device *dev)
-{
- int tmp = num_depcas, status = -ENODEV;
- u_long iobase = dev->base_addr;
-
- if ((iobase == 0) && loading_module){
- printk("Autoprobing is not supported when loading a module based driver.\n");
- status = -EIO;
- } else {
- isa_probe(dev, iobase);
- eisa_probe(dev, iobase);
-
- if ((tmp == num_depcas) && (iobase != 0) && loading_module) {
- printk("%s: depca_probe() cannot find device at 0x%04lx.\n", dev->name,
- iobase);
- }
-
- /*
- ** Walk the device list to check that at least one device
- ** initialised OK
- */
- for (; (dev->priv == NULL) && (dev->next != NULL); dev = dev->next);
-
- if (dev->priv) status = 0;
- if (iobase == 0) autoprobed = 1;
- }
-
- return status;
-}
-
-static int
-depca_hw_init(struct device *dev, u_long ioaddr)
-{
- struct depca_private *lp;
- int i, j, offset, netRAM, mem_len, status=0;
- s16 nicsr;
- u_long mem_start=0, mem_base[] = DEPCA_RAM_BASE_ADDRESSES;
-
- STOP_DEPCA;
-
- nicsr = inb(DEPCA_NICSR);
- nicsr = ((nicsr & ~SHE & ~RBE & ~IEN) | IM);
- outb(nicsr, DEPCA_NICSR);
-
- if (inw(DEPCA_DATA) == STOP) {
- if (mem == 0) {
- for (; mem_base[mem_chkd]; mem_chkd++) {
- mem_start = mem_base[mem_chkd];
- DepcaSignature(name, mem_start);
- if (*name != '\0') break;
- }
- } else {
- mem_start = mem;
- if (adapter_name) {
- strcpy(name, adapter_name);
- } else{
- DepcaSignature(name, mem_start);
- }
- }
-
- if ((*name != '\0') && mem_start) { /* found a DEPCA device */
- dev->base_addr = ioaddr;
-
- if ((ioaddr&0x0fff)==DEPCA_EISA_IO_PORTS) {/* EISA slot address */
- printk("%s: %s at 0x%04lx (EISA slot %d)",
- dev->name, name, ioaddr, (int)((ioaddr>>12)&0x0f));
- } else { /* ISA port address */
- printk("%s: %s at 0x%04lx", dev->name, name, ioaddr);
- }
-
- printk(", h/w address ");
- status = get_hw_addr(dev);
- for (i=0; i<ETH_ALEN - 1; i++) { /* get the ethernet address */
- printk("%2.2x:", dev->dev_addr[i]);
- }
- printk("%2.2x", dev->dev_addr[i]);
-
- if (status == 0) {
- /* Set up the maximum amount of network RAM(kB) */
- netRAM = ((adapter != DEPCA) ? 64 : 48);
- if ((nicsr & _128KB) && (adapter == de422)) netRAM = 128;
- offset = 0x0000;
-
- /* Shared Memory Base Address */
- if (nicsr & BUF) {
- offset = 0x8000; /* 32kbyte RAM offset*/
- nicsr &= ~BS; /* DEPCA RAM in top 32k */
- netRAM -= 32;
- }
- mem_start += offset; /* (E)ISA start address */
- if ((mem_len = (NUM_RX_DESC*(sizeof(struct depca_rx_desc)+RX_BUFF_SZ) +
- NUM_TX_DESC*(sizeof(struct depca_tx_desc)+TX_BUFF_SZ) +
- sizeof(struct depca_init))) <=
- (netRAM<<10)) {
- printk(",\n has %dkB RAM at 0x%.5lx", netRAM, mem_start);
-
- /* Enable the shadow RAM. */
- if (adapter != DEPCA) {
- nicsr |= SHE;
- outb(nicsr, DEPCA_NICSR);
- }
-
- /* Define the device private memory */
- dev->priv = (void *) kmalloc(sizeof(struct depca_private), GFP_KERNEL);
- if (dev->priv == NULL)
- return -ENOMEM;
- lp = (struct depca_private *)dev->priv;
- memset((char *)dev->priv, 0, sizeof(struct depca_private));
- lp->adapter = adapter;
- sprintf(lp->adapter_name,"%s (%s)", name, dev->name);
- request_region(ioaddr, DEPCA_TOTAL_SIZE, lp->adapter_name);
-
- /* Initialisation Block */
- lp->sh_mem = mem_start;
- mem_start += sizeof(struct depca_init);
-
- /* Tx & Rx descriptors (aligned to a quadword boundary) */
- mem_start = (mem_start + ALIGN) & ~ALIGN;
- lp->rx_ring = (struct depca_rx_desc *)mem_start;
-
- mem_start += (sizeof(struct depca_rx_desc) * NUM_RX_DESC);
- lp->tx_ring = (struct depca_tx_desc *)mem_start;
-
- mem_start += (sizeof(struct depca_tx_desc) * NUM_TX_DESC);
- lp->bus_offset = mem_start & 0x00ff0000;
- mem_start &= LA_MASK; /* LANCE re-mapped start address */
-
- lp->dma_buffs = mem_start;
-
- /* Finish initialising the ring information. */
- lp->rxRingMask = NUM_RX_DESC - 1;
- lp->txRingMask = NUM_TX_DESC - 1;
-
- /* Calculate Tx/Rx RLEN size for the descriptors. */
- for (i=0, j = lp->rxRingMask; j>0; i++) {
- j >>= 1;
- }
- lp->rx_rlen = (s32)(i << 29);
- for (i=0, j = lp->txRingMask; j>0; i++) {
- j >>= 1;
- }
- lp->tx_rlen = (s32)(i << 29);
-
- /* Load the initialisation block */
- depca_init_ring(dev);
-
- /* Initialise the control and status registers */
- LoadCSRs(dev);
-
- /* Enable DEPCA board interrupts for autoprobing */
- nicsr = ((nicsr & ~IM)|IEN);
- outb(nicsr, DEPCA_NICSR);
-
- /* To auto-IRQ we enable the initialization-done and DMA err,
- interrupts. For now we will always get a DMA error. */
- if (dev->irq < 2) {
-#ifndef MODULE
- unsigned char irqnum;
- autoirq_setup(0);
-
- /* Assign the correct irq list */
- switch (lp->adapter) {
- case DEPCA:
- case de100:
- case de101:
- depca_irq = de1xx_irq;
- break;
- case de200:
- case de201:
- case de202:
- case de210:
- depca_irq = de2xx_irq;
- break;
- case de422:
- depca_irq = de422_irq;
- break;
- }
-
- /* Trigger an initialization just for the interrupt. */
- outw(INEA | INIT, DEPCA_DATA);
-
- irqnum = autoirq_report(1);
- if (!irqnum) {
- printk(" and failed to detect IRQ line.\n");
- status = -ENXIO;
- } else {
- for (dev->irq=0,i=0; (depca_irq[i]) && (!dev->irq); i++) {
- if (irqnum == depca_irq[i]) {
- dev->irq = irqnum;
- printk(" and uses IRQ%d.\n", dev->irq);
- }
- }
-
- if (!dev->irq) {
- printk(" but incorrect IRQ line detected.\n");
- status = -ENXIO;
- }
- }
-#endif /* MODULE */
- } else {
- printk(" and assigned IRQ%d.\n", dev->irq);
- }
- if (status) release_region(ioaddr, DEPCA_TOTAL_SIZE);
- } else {
- printk(",\n requests %dkB RAM: only %dkB is available!\n",
- (mem_len>>10), netRAM);
- status = -ENXIO;
- }
- } else {
- printk(" which has an Ethernet PROM CRC error.\n");
- status = -ENXIO;
- }
- }
- if (!status) {
- if (depca_debug > 0) {
- printk(version);
- }
-
- /* The DEPCA-specific entries in the device structure. */
- dev->open = &depca_open;
- dev->hard_start_xmit = &depca_start_xmit;
- dev->stop = &depca_close;
- dev->get_stats = &depca_get_stats;
- dev->set_multicast_list = &set_multicast_list;
- dev->do_ioctl = &depca_ioctl;
-
- dev->mem_start = 0;
-
- /* Fill in the generic field of the device structure. */
- ether_setup(dev);
- } else { /* Incorrectly initialised hardware */
- if (dev->priv) {
- kfree_s(dev->priv, sizeof(struct depca_private));
- dev->priv = NULL;
- }
- }
- } else {
- status = -ENXIO;
- }
-
- return status;
-}
-
-
-static int
-depca_open(struct device *dev)
-{
- struct depca_private *lp = (struct depca_private *)dev->priv;
- u_long ioaddr = dev->base_addr;
- s16 nicsr;
- int status = 0;
-
- irq2dev_map[dev->irq] = dev;
- STOP_DEPCA;
- nicsr = inb(DEPCA_NICSR);
-
- /* Make sure the shadow RAM is enabled */
- if (adapter != DEPCA) {
- nicsr |= SHE;
- outb(nicsr, DEPCA_NICSR);
- }
-
- /* Re-initialize the DEPCA... */
- depca_init_ring(dev);
- LoadCSRs(dev);
-
- depca_dbg_open(dev);
-
- if (request_irq(dev->irq, &depca_interrupt, 0, lp->adapter_name)) {
- printk("depca_open(): Requested IRQ%d is busy\n",dev->irq);
- status = -EAGAIN;
- } else {
-
- /* Enable DEPCA board interrupts and turn off LED */
- nicsr = ((nicsr & ~IM & ~LED)|IEN);
- outb(nicsr, DEPCA_NICSR);
- outw(CSR0,DEPCA_ADDR);
-
- dev->tbusy = 0;
- dev->interrupt = 0;
- dev->start = 1;
-
- status = InitRestartDepca(dev);
-
- if (depca_debug > 1){
- printk("CSR0: 0x%4.4x\n",inw(DEPCA_DATA));
- printk("nicsr: 0x%02x\n",inb(DEPCA_NICSR));
- }
- }
-
- MOD_INC_USE_COUNT;
-
- return status;
-}
-
-/* Initialize the lance Rx and Tx descriptor rings. */
-static void
-depca_init_ring(struct device *dev)
-{
- struct depca_private *lp = (struct depca_private *)dev->priv;
- u_int i;
- u_long p;
-
- /* Lock out other processes whilst setting up the hardware */
- set_bit(0, (void *)&dev->tbusy);
-
- lp->rx_new = lp->tx_new = 0;
- lp->rx_old = lp->tx_old = 0;
-
- /* Initialize the base addresses and length of each buffer in the ring */
- for (i = 0; i <= lp->rxRingMask; i++) {
- writel((p=lp->dma_buffs+i*RX_BUFF_SZ) | R_OWN, &lp->rx_ring[i].base);
- writew(-RX_BUFF_SZ, &lp->rx_ring[i].buf_length);
- lp->rx_memcpy[i]=(char *)(p+lp->bus_offset);
- }
- for (i = 0; i <= lp->txRingMask; i++) {
- writel((p=lp->dma_buffs+(i+lp->txRingMask+1)*TX_BUFF_SZ) & 0x00ffffff,
- &lp->tx_ring[i].base);
- lp->tx_memcpy[i]=(char *)(p+lp->bus_offset);
- }
-
- /* Set up the initialization block */
- lp->init_block.rx_ring = ((u32)((u_long)lp->rx_ring)&LA_MASK) | lp->rx_rlen;
- lp->init_block.tx_ring = ((u32)((u_long)lp->tx_ring)&LA_MASK) | lp->tx_rlen;
-
- SetMulticastFilter(dev);
-
- for (i = 0; i < ETH_ALEN; i++) {
- lp->init_block.phys_addr[i] = dev->dev_addr[i];
- }
-
- lp->init_block.mode = 0x0000; /* Enable the Tx and Rx */
-
- return;
-}
-
-/*
-** Writes a socket buffer to TX descriptor ring and starts transmission
-*/
-static int
-depca_start_xmit(struct sk_buff *skb, struct device *dev)
-{
- struct depca_private *lp = (struct depca_private *)dev->priv;
- u_long ioaddr = dev->base_addr;
- int status = 0;
-
- /* Transmitter timeout, serious problems. */
- if (dev->tbusy) {
- int tickssofar = jiffies - dev->trans_start;
- if (tickssofar < 1*HZ) {
- status = -1;
- } else {
- printk("%s: transmit timed out, status %04x, resetting.\n",
- dev->name, inw(DEPCA_DATA));
-
- STOP_DEPCA;
- depca_init_ring(dev);
- LoadCSRs(dev);
- dev->interrupt = UNMASK_INTERRUPTS;
- dev->start = 1;
- dev->tbusy=0;
- dev->trans_start = jiffies;
- InitRestartDepca(dev);
- }
- return status;
- } else if (skb == NULL) {
- dev_tint(dev);
- } else if (skb->len > 0) {
- /* Enforce 1 process per h/w access */
- if (set_bit(0, (void*)&dev->tbusy) != 0) {
- printk("%s: Transmitter access conflict.\n", dev->name);
- status = -1;
- } else {
- if (TX_BUFFS_AVAIL) { /* Fill in a Tx ring entry */
- status = load_packet(dev, skb);
-
- if (!status) {
- /* Trigger an immediate send demand. */
- outw(CSR0, DEPCA_ADDR);
- outw(INEA | TDMD, DEPCA_DATA);
-
- dev->trans_start = jiffies;
- dev_kfree_skb(skb, FREE_WRITE);
- }
- if (TX_BUFFS_AVAIL) {
- dev->tbusy=0;
- }
- } else {
- status = -1;
- }
- }
- }
-
- return status;
-}
-
-/*
-** The DEPCA interrupt handler.
-*/
-static void
-depca_interrupt(int irq, struct pt_regs * regs)
-{
- struct device *dev = (struct device *)(irq2dev_map[irq]);
- struct depca_private *lp;
- s16 csr0, nicsr;
- u_long ioaddr;
-
- if (dev == NULL) {
- printk ("depca_interrupt(): irq %d for unknown device.\n", irq);
- } else {
- lp = (struct depca_private *)dev->priv;
- ioaddr = dev->base_addr;
-
- if (dev->interrupt)
- printk("%s: Re-entering the interrupt handler.\n", dev->name);
-
- dev->interrupt = MASK_INTERRUPTS;
-
- /* mask the DEPCA board interrupts and turn on the LED */
- nicsr = inb(DEPCA_NICSR);
- nicsr |= (IM|LED);
- outb(nicsr, DEPCA_NICSR);
-
- outw(CSR0, DEPCA_ADDR);
- csr0 = inw(DEPCA_DATA);
-
- /* Acknowledge all of the current interrupt sources ASAP. */
- outw(csr0 & INTE, DEPCA_DATA);
-
- if (csr0 & RINT) /* Rx interrupt (packet arrived) */
- depca_rx(dev);
-
- if (csr0 & TINT) /* Tx interrupt (packet sent) */
- depca_tx(dev);
-
- if ((TX_BUFFS_AVAIL >= 0) && dev->tbusy) { /* any resources available? */
- dev->tbusy = 0; /* clear TX busy flag */
- mark_bh(NET_BH);
- }
-
- /* Unmask the DEPCA board interrupts and turn off the LED */
- nicsr = (nicsr & ~IM & ~LED);
- outb(nicsr, DEPCA_NICSR);
-
- dev->interrupt = UNMASK_INTERRUPTS;
- }
-
- return;
-}
-
-static int
-depca_rx(struct device *dev)
-{
- struct depca_private *lp = (struct depca_private *)dev->priv;
- int i, entry;
- s32 status;
-
- for (entry=lp->rx_new;
- !(readl(&lp->rx_ring[entry].base) & R_OWN);
- entry=lp->rx_new){
- status = readl(&lp->rx_ring[entry].base) >> 16 ;
- if (status & R_STP) { /* Remember start of frame */
- lp->rx_old = entry;
- }
- if (status & R_ENP) { /* Valid frame status */
- if (status & R_ERR) { /* There was an error. */
- lp->stats.rx_errors++; /* Update the error stats. */
- if (status & R_FRAM) lp->stats.rx_frame_errors++;
- if (status & R_OFLO) lp->stats.rx_over_errors++;
- if (status & R_CRC) lp->stats.rx_crc_errors++;
- if (status & R_BUFF) lp->stats.rx_fifo_errors++;
- } else {
- short len, pkt_len = readw(&lp->rx_ring[entry].msg_length);
- struct sk_buff *skb;
-
- skb = dev_alloc_skb(pkt_len+2);
- if (skb != NULL) {
- unsigned char *buf;
- skb_reserve(skb,2); /* 16 byte align the IP header */
- buf = skb_put(skb,pkt_len);
- skb->dev = dev;
- if (entry < lp->rx_old) { /* Wrapped buffer */
- len = (lp->rxRingMask - lp->rx_old + 1) * RX_BUFF_SZ;
- memcpy_fromio(buf, lp->rx_memcpy[lp->rx_old], len);
- memcpy_fromio(buf + len, lp->rx_memcpy[0], pkt_len-len);
- } else { /* Linear buffer */
- memcpy_fromio(buf, lp->rx_memcpy[lp->rx_old], pkt_len);
- }
-
- /*
- ** Notify the upper protocol layers that there is another
- ** packet to handle
- */
- skb->protocol=eth_type_trans(skb,dev);
- netif_rx(skb);
-
- /*
- ** Update stats
- */
- lp->stats.rx_packets++;
- for (i=1; i<DEPCA_PKT_STAT_SZ-1; i++) {
- if (pkt_len < (i*DEPCA_PKT_BIN_SZ)) {
- lp->pktStats.bins[i]++;
- i = DEPCA_PKT_STAT_SZ;
- }
- }
- if (buf[0] & 0x01) { /* Multicast/Broadcast */
- if ((*(s16 *)&buf[0] == -1) &&
- (*(s16 *)&buf[2] == -1) &&
- (*(s16 *)&buf[4] == -1)) {
- lp->pktStats.broadcast++;
- } else {
- lp->pktStats.multicast++;
- }
- } else if ((*(s16 *)&buf[0] == *(s16 *)&dev->dev_addr[0]) &&
- (*(s16 *)&buf[2] == *(s16 *)&dev->dev_addr[2]) &&
- (*(s16 *)&buf[4] == *(s16 *)&dev->dev_addr[4])) {
- lp->pktStats.unicast++;
- }
-
- lp->pktStats.bins[0]++; /* Duplicates stats.rx_packets */
- if (lp->pktStats.bins[0] == 0) { /* Reset counters */
- memset((char *)&lp->pktStats, 0, sizeof(lp->pktStats));
- }
- } else {
- printk("%s: Memory squeeze, deferring packet.\n", dev->name);
- lp->stats.rx_dropped++; /* Really, deferred. */
- break;
- }
- }
- /* Change buffer ownership for this last frame, back to the adapter */
- for (; lp->rx_old!=entry; lp->rx_old=(++lp->rx_old)&lp->rxRingMask) {
- writel(readl(&lp->rx_ring[lp->rx_old].base) | R_OWN,
- &lp->rx_ring[lp->rx_old].base);
- }
- writel(readl(&lp->rx_ring[entry].base) | R_OWN, &lp->rx_ring[entry].base);
- }
-
- /*
- ** Update entry information
- */
- lp->rx_new = (++lp->rx_new) & lp->rxRingMask;
- }
-
- return 0;
-}
-
-/*
-** Buffer sent - check for buffer errors.
-*/
-static int
-depca_tx(struct device *dev)
-{
- struct depca_private *lp = (struct depca_private *)dev->priv;
- int entry;
- s32 status;
- u_long ioaddr = dev->base_addr;
-
- for (entry = lp->tx_old; entry != lp->tx_new; entry = lp->tx_old) {
- status = readl(&lp->tx_ring[entry].base) >> 16 ;
-
- if (status < 0) { /* Packet not yet sent! */
- break;
- } else if (status & T_ERR) { /* An error occured. */
- status = readl(&lp->tx_ring[entry].misc);
- lp->stats.tx_errors++;
- if (status & TMD3_RTRY) lp->stats.tx_aborted_errors++;
- if (status & TMD3_LCAR) lp->stats.tx_carrier_errors++;
- if (status & TMD3_LCOL) lp->stats.tx_window_errors++;
- if (status & TMD3_UFLO) lp->stats.tx_fifo_errors++;
- if (status & (TMD3_BUFF | TMD3_UFLO)) {
- /* Trigger an immediate send demand. */
- outw(CSR0, DEPCA_ADDR);
- outw(INEA | TDMD, DEPCA_DATA);
- }
- } else if (status & (T_MORE | T_ONE)) {
- lp->stats.collisions++;
- } else {
- lp->stats.tx_packets++;
- }
-
- /* Update all the pointers */
- lp->tx_old = (++lp->tx_old) & lp->txRingMask;
- }
-
- return 0;
-}
-
-static int
-depca_close(struct device *dev)
-{
- struct depca_private *lp = (struct depca_private *)dev->priv;
- s16 nicsr;
- u_long ioaddr = dev->base_addr;
-
- dev->start = 0;
- dev->tbusy = 1;
-
- outw(CSR0, DEPCA_ADDR);
-
- if (depca_debug > 1) {
- printk("%s: Shutting down ethercard, status was %2.2x.\n",
- dev->name, inw(DEPCA_DATA));
- }
-
- /*
- ** We stop the DEPCA here -- it occasionally polls
- ** memory if we don't.
- */
- outw(STOP, DEPCA_DATA);
-
- /*
- ** Give back the ROM in case the user wants to go to DOS
- */
- if (lp->adapter != DEPCA) {
- nicsr = inb(DEPCA_NICSR);
- nicsr &= ~SHE;
- outb(nicsr, DEPCA_NICSR);
- }
-
- /*
- ** Free the associated irq
- */
- free_irq(dev->irq);
- irq2dev_map[dev->irq] = NULL;
-
- MOD_DEC_USE_COUNT;
-
- return 0;
-}
-
-static void LoadCSRs(struct device *dev)
-{
- struct depca_private *lp = (struct depca_private *)dev->priv;
- u_long ioaddr = dev->base_addr;
-
- outw(CSR1, DEPCA_ADDR); /* initialisation block address LSW */
- outw((u16)(lp->sh_mem & LA_MASK), DEPCA_DATA);
- outw(CSR2, DEPCA_ADDR); /* initialisation block address MSW */
- outw((u16)((lp->sh_mem & LA_MASK) >> 16), DEPCA_DATA);
- outw(CSR3, DEPCA_ADDR); /* ALE control */
- outw(ACON, DEPCA_DATA);
-
- outw(CSR0, DEPCA_ADDR); /* Point back to CSR0 */
-
- return;
-}
-
-static int InitRestartDepca(struct device *dev)
-{
- struct depca_private *lp = (struct depca_private *)dev->priv;
- u_long ioaddr = dev->base_addr;
- int i, status=0;
-
- /* Copy the shadow init_block to shared memory */
- memcpy_toio((char *)lp->sh_mem, &lp->init_block, sizeof(struct depca_init));
-
- outw(CSR0, DEPCA_ADDR); /* point back to CSR0 */
- outw(INIT, DEPCA_DATA); /* initialize DEPCA */
-
- /* wait for lance to complete initialisation */
- for (i=0;(i<100) && !(inw(DEPCA_DATA) & IDON); i++);
-
- if (i!=100) {
- /* clear IDON by writing a "1", enable interrupts and start lance */
- outw(IDON | INEA | STRT, DEPCA_DATA);
- if (depca_debug > 2) {
- printk("%s: DEPCA open after %d ticks, init block 0x%08lx csr0 %4.4x.\n",
- dev->name, i, lp->sh_mem, inw(DEPCA_DATA));
- }
- } else {
- printk("%s: DEPCA unopen after %d ticks, init block 0x%08lx csr0 %4.4x.\n",
- dev->name, i, lp->sh_mem, inw(DEPCA_DATA));
- status = -1;
- }
-
- return status;
-}
-
-static struct enet_statistics *
-depca_get_stats(struct device *dev)
-{
- struct depca_private *lp = (struct depca_private *)dev->priv;
-
- /* Null body since there is no framing error counter */
-
- return &lp->stats;
-}
-
-/*
-** Set or clear the multicast filter for this adaptor.
-*/
-static void
-set_multicast_list(struct device *dev)
-{
- struct depca_private *lp = (struct depca_private *)dev->priv;
- u_long ioaddr = dev->base_addr;
-
- if (irq2dev_map[dev->irq] != NULL) {
- while(dev->tbusy); /* Stop ring access */
- set_bit(0, (void*)&dev->tbusy);
- while(lp->tx_old != lp->tx_new); /* Wait for the ring to empty */
-
- STOP_DEPCA; /* Temporarily stop the depca. */
- depca_init_ring(dev); /* Initialize the descriptor rings */
-
- if (dev->flags & IFF_PROMISC) { /* Set promiscuous mode */
- lp->init_block.mode |= PROM;
- } else {
- SetMulticastFilter(dev);
- lp->init_block.mode &= ~PROM; /* Unset promiscuous mode */
- }
-
- LoadCSRs(dev); /* Reload CSR3 */
- InitRestartDepca(dev); /* Resume normal operation. */
- dev->tbusy = 0; /* Unlock the TX ring */
- }
-}
-
-/*
-** Calculate the hash code and update the logical address filter
-** from a list of ethernet multicast addresses.
-** Big endian crc one liner is mine, all mine, ha ha ha ha!
-** LANCE calculates its hash codes big endian.
-*/
-static void SetMulticastFilter(struct device *dev)
-{
- struct depca_private *lp = (struct depca_private *)dev->priv;
- struct dev_mc_list *dmi=dev->mc_list;
- char *addrs;
- int i, j, bit, byte;
- u16 hashcode;
- s32 crc, poly = CRC_POLYNOMIAL_BE;
-
- if (dev->flags & IFF_ALLMULTI) { /* Set all multicast bits */
- for (i=0; i<(HASH_TABLE_LEN>>3); i++) {
- lp->init_block.mcast_table[i] = (char)0xff;
- }
- } else {
- for (i=0; i<(HASH_TABLE_LEN>>3); i++){ /* Clear the multicast table */
- lp->init_block.mcast_table[i]=0;
- }
- /* Add multicast addresses */
- for (i=0;i<dev->mc_count;i++) { /* for each address in the list */
- addrs=dmi->dmi_addr;
- dmi=dmi->next;
- if ((*addrs & 0x01) == 1) { /* multicast address? */
- crc = 0xffffffff; /* init CRC for each address */
- for (byte=0;byte<ETH_ALEN;byte++) {/* for each address byte */
- /* process each address bit */
- for (bit = *addrs++,j=0;j<8;j++, bit>>=1) {
- crc = (crc << 1) ^ ((((crc<0?1:0) ^ bit) & 0x01) ? poly : 0);
- }
- }
- hashcode = (crc & 1); /* hashcode is 6 LSb of CRC ... */
- for (j=0;j<5;j++) { /* ... in reverse order. */
- hashcode = (hashcode << 1) | ((crc>>=1) & 1);
- }
-
-
- byte = hashcode >> 3; /* bit[3-5] -> byte in filter */
- bit = 1 << (hashcode & 0x07); /* bit[0-2] -> bit in byte */
- lp->init_block.mcast_table[byte] |= bit;
- }
- }
- }
-
- return;
-}
-
-/*
-** ISA bus I/O device probe
-*/
-static void isa_probe(struct device *dev, u_long ioaddr)
-{
- int i = num_depcas, maxSlots;
- s32 ports[] = DEPCA_IO_PORTS;
-
- if (!ioaddr && autoprobed) return ; /* Been here before ! */
- if (ioaddr > 0x400) return; /* EISA Address */
- if (i >= MAX_NUM_DEPCAS) return; /* Too many ISA adapters */
-
- if (ioaddr == 0) { /* Autoprobing */
- maxSlots = MAX_NUM_DEPCAS;
- } else { /* Probe a specific location */
- ports[i] = ioaddr;
- maxSlots = i + 1;
- }
-
- for (; (i<maxSlots) && (dev!=NULL) && ports[i]; i++) {
- if (DevicePresent(ports[i]) == 0) {
- if (check_region(ports[i], DEPCA_TOTAL_SIZE) == 0) {
- if ((dev = alloc_device(dev, ports[i])) != NULL) {
- if (depca_hw_init(dev, ports[i]) == 0) {
- num_depcas++;
- }
- num_eth++;
- }
- } else if (autoprobed) {
- printk("%s: region already allocated at 0x%04x.\n", dev->name,ports[i]);
- }
- }
- }
-
- return;
-}
-
-/*
-** EISA bus I/O device probe. Probe from slot 1 since slot 0 is usually
-** the motherboard. Upto 15 EISA devices are supported.
-*/
-static void eisa_probe(struct device *dev, u_long ioaddr)
-{
- int i, maxSlots;
- u_long iobase;
- char name[DEPCA_STRLEN];
-
- if (!ioaddr && autoprobed) return ; /* Been here before ! */
- if ((ioaddr < 0x400) && (ioaddr > 0)) return; /* ISA Address */
-
- if (ioaddr == 0) { /* Autoprobing */
- iobase = EISA_SLOT_INC; /* Get the first slot address */
- i = 1;
- maxSlots = MAX_EISA_SLOTS;
- } else { /* Probe a specific location */
- iobase = ioaddr;
- i = (ioaddr >> 12);
- maxSlots = i + 1;
- }
- if ((iobase & 0x0fff) == 0) iobase += DEPCA_EISA_IO_PORTS;
-
- for (; (i<maxSlots) && (dev!=NULL); i++, iobase+=EISA_SLOT_INC) {
- if (EISA_signature(name, EISA_ID)) {
- if (DevicePresent(iobase) == 0) {
- if (check_region(iobase, DEPCA_TOTAL_SIZE) == 0) {
- if ((dev = alloc_device(dev, iobase)) != NULL) {
- if (depca_hw_init(dev, iobase) == 0) {
- num_depcas++;
- }
- num_eth++;
- }
- } else if (autoprobed) {
- printk("%s: region already allocated at 0x%04lx.\n",dev->name,iobase);
- }
- }
- }
- }
-
- return;
-}
-
-/*
-** Allocate the device by pointing to the next available space in the
-** device structure. Should one not be available, it is created.
-*/
-static struct device *alloc_device(struct device *dev, u_long iobase)
-{
- int addAutoProbe = 0;
- struct device *tmp = NULL, *ret;
- int (*init)(struct device *) = NULL;
-
- /*
- ** Check the device structures for an end of list or unused device
- */
- if (!loading_module) {
- while (dev->next != NULL) {
- if ((dev->base_addr == DEPCA_NDA) || (dev->base_addr == 0)) break;
- dev = dev->next; /* walk through eth device list */
- num_eth++; /* increment eth device number */
- }
-
- /*
- ** If an autoprobe is requested for another device, we must re-insert
- ** the request later in the list. Remember the current information.
- */
- if ((dev->base_addr == 0) && (num_depcas > 0)) {
- addAutoProbe++;
- tmp = dev->next; /* point to the next device */
- init = dev->init; /* remember the probe function */
- }
-
- /*
- ** If at end of list and can't use current entry, malloc one up.
- ** If memory could not be allocated, print an error message.
- */
- if ((dev->next == NULL) &&
- !((dev->base_addr == DEPCA_NDA) || (dev->base_addr == 0))){
- dev->next = (struct device *)kmalloc(sizeof(struct device) + 8,
- GFP_KERNEL);
-
- dev = dev->next; /* point to the new device */
- if (dev == NULL) {
- printk("eth%d: Device not initialised, insufficient memory\n",
- num_eth);
- } else {
- /*
- ** If the memory was allocated, point to the new memory area
- ** and initialize it (name, I/O address, next device (NULL) and
- ** initialisation probe routine).
- */
- dev->name = (char *)(dev + sizeof(struct device));
- if (num_eth > 9999) {
- sprintf(dev->name,"eth????"); /* New device name */
- } else {
- sprintf(dev->name,"eth%d", num_eth);/* New device name */
- }
- dev->base_addr = iobase; /* assign the io address */
- dev->next = NULL; /* mark the end of list */
- dev->init = &depca_probe; /* initialisation routine */
- num_depcas++;
- }
- }
- ret = dev; /* return current struct, or NULL */
-
- /*
- ** Now figure out what to do with the autoprobe that has to be inserted.
- ** Firstly, search the (possibly altered) list for an empty space.
- */
- if (ret != NULL) {
- if (addAutoProbe) {
- for (;(tmp->next!=NULL) && (tmp->base_addr!=DEPCA_NDA); tmp=tmp->next);
-
- /*
- ** If no more device structures and can't use the current one, malloc
- ** one up. If memory could not be allocated, print an error message.
- */
- if ((tmp->next == NULL) && !(tmp->base_addr == DEPCA_NDA)) {
- tmp->next = (struct device *)kmalloc(sizeof(struct device) + 8,
- GFP_KERNEL);
- tmp = tmp->next; /* point to the new device */
- if (tmp == NULL) {
- printk("%s: Insufficient memory to extend the device list.\n",
- dev->name);
- } else {
- /*
- ** If the memory was allocated, point to the new memory area
- ** and initialize it (name, I/O address, next device (NULL) and
- ** initialisation probe routine).
- */
- tmp->name = (char *)(tmp + sizeof(struct device));
- if (num_eth > 9999) {
- sprintf(tmp->name,"eth????"); /* New device name */
- } else {
- sprintf(tmp->name,"eth%d", num_eth);/* New device name */
- }
- tmp->base_addr = 0; /* re-insert the io address */
- tmp->next = NULL; /* mark the end of list */
- tmp->init = init; /* initialisation routine */
- }
- } else { /* structure already exists */
- tmp->base_addr = 0; /* re-insert the io address */
- }
- }
- }
- } else {
- ret = dev;
- }
-
- return ret;
-}
-
-/*
-** Look for a particular board name in the on-board Remote Diagnostics
-** and Boot (readb) ROM. This will also give us a clue to the network RAM
-** base address.
-*/
-static void DepcaSignature(char *name, u_long paddr)
-{
- u_int i,j,k;
- const char *signatures[] = DEPCA_SIGNATURE;
- char tmpstr[16];
-
- for (i=0;i<16;i++) { /* copy the first 16 bytes of ROM to */
- tmpstr[i] = readb(paddr+0xc000+i); /* a temporary string */
- }
-
- strcpy(name,"");
- for (i=0;*signatures[i]!='\0' && *name=='\0';i++) {
- for (j=0,k=0;j<16 && k<strlen(signatures[i]);j++) {
- if (signatures[i][k] == tmpstr[j]) { /* track signature */
- k++;
- } else { /* lost signature; begin search again */
- k=0;
- }
- }
- if (k == strlen(signatures[i])) {
- strcpy(name,signatures[i]);
- }
- }
-
- adapter = i - 1;
-
- return;
-}
-
-/*
-** Look for a special sequence in the Ethernet station address PROM that
-** is common across all DEPCA products. Note that the original DEPCA needs
-** its ROM address counter to be initialized and enabled. Only enable
-** if the first address octet is a 0x08 - this minimises the chances of
-** messing around with some other hardware, but it assumes that this DEPCA
-** card initialized itself correctly.
-**
-** Search the Ethernet address ROM for the signature. Since the ROM address
-** counter can start at an arbitrary point, the search must include the entire
-** probe sequence length plus the (length_of_the_signature - 1).
-** Stop the search IMMEDIATELY after the signature is found so that the
-** PROM address counter is correctly positioned at the start of the
-** ethernet address for later read out.
-*/
-static int DevicePresent(u_long ioaddr)
-{
- union {
- struct {
- u32 a;
- u32 b;
- } llsig;
- char Sig[sizeof(u32) << 1];
- } dev;
- short sigLength=0;
- s8 data;
- s16 nicsr;
- int i, j, status = 0;
-
- data = inb(DEPCA_PROM); /* clear counter on DEPCA */
- data = inb(DEPCA_PROM); /* read data */
-
- if (data == 0x08) { /* Enable counter on DEPCA */
- nicsr = inb(DEPCA_NICSR);
- nicsr |= AAC;
- outb(nicsr, DEPCA_NICSR);
- }
-
- dev.llsig.a = ETH_PROM_SIG;
- dev.llsig.b = ETH_PROM_SIG;
- sigLength = sizeof(u32) << 1;
-
- for (i=0,j=0;j<sigLength && i<PROBE_LENGTH+sigLength-1;i++) {
- data = inb(DEPCA_PROM);
- if (dev.Sig[j] == data) { /* track signature */
- j++;
- } else { /* lost signature; begin search again */
- if (data == dev.Sig[0]) { /* rare case.... */
- j=1;
- } else {
- j=0;
- }
- }
- }
-
- if (j!=sigLength) {
- status = -ENODEV; /* search failed */
- }
-
- return status;
-}
-
-/*
-** The DE100 and DE101 PROM accesses were made non-standard for some bizarre
-** reason: access the upper half of the PROM with x=0; access the lower half
-** with x=1.
-*/
-static int get_hw_addr(struct device *dev)
-{
- u_long ioaddr = dev->base_addr;
- int i, k, tmp, status = 0;
- u_short j, x, chksum;
-
- x = (((adapter == de100) || (adapter == de101)) ? 1 : 0);
-
- for (i=0,k=0,j=0;j<3;j++) {
- k <<= 1 ;
- if (k > 0xffff) k-=0xffff;
-
- k += (u_char) (tmp = inb(DEPCA_PROM + x));
- dev->dev_addr[i++] = (u_char) tmp;
- k += (u_short) ((tmp = inb(DEPCA_PROM + x)) << 8);
- dev->dev_addr[i++] = (u_char) tmp;
-
- if (k > 0xffff) k-=0xffff;
- }
- if (k == 0xffff) k=0;
-
- chksum = (u_char) inb(DEPCA_PROM + x);
- chksum |= (u_short) (inb(DEPCA_PROM + x) << 8);
- if (k != chksum) status = -1;
-
- return status;
-}
-
-/*
-** Load a packet into the shared memory
-*/
-static int load_packet(struct device *dev, struct sk_buff *skb)
-{
- struct depca_private *lp = (struct depca_private *)dev->priv;
- int i, entry, end, len, status = 0;
-
- entry = lp->tx_new; /* Ring around buffer number. */
- end = (entry + (skb->len - 1) / TX_BUFF_SZ) & lp->txRingMask;
- if (!(readl(&lp->tx_ring[end].base) & T_OWN)) {/* Enough room? */
- /*
- ** Caution: the write order is important here... don't set up the
- ** ownership rights until all the other information is in place.
- */
- if (end < entry) { /* wrapped buffer */
- len = (lp->txRingMask - entry + 1) * TX_BUFF_SZ;
- memcpy_toio(lp->tx_memcpy[entry], skb->data, len);
- memcpy_toio(lp->tx_memcpy[0], skb->data + len, skb->len - len);
- } else { /* linear buffer */
- memcpy_toio(lp->tx_memcpy[entry], skb->data, skb->len);
- }
-
- /* set up the buffer descriptors */
- len = (skb->len < ETH_ZLEN) ? ETH_ZLEN : skb->len;
- for (i = entry; i != end; i = (++i) & lp->txRingMask) {
- /* clean out flags */
- writel(readl(&lp->tx_ring[i].base) & ~T_FLAGS, &lp->tx_ring[i].base);
- writew(0x0000, &lp->tx_ring[i].misc); /* clears other error flags */
- writew(-TX_BUFF_SZ, &lp->tx_ring[i].length);/* packet length in buffer */
- len -= TX_BUFF_SZ;
- }
- /* clean out flags */
- writel(readl(&lp->tx_ring[end].base) & ~T_FLAGS, &lp->tx_ring[end].base);
- writew(0x0000, &lp->tx_ring[end].misc); /* clears other error flags */
- writew(-len, &lp->tx_ring[end].length); /* packet length in last buff */
-
- /* start of packet */
- writel(readl(&lp->tx_ring[entry].base) | T_STP, &lp->tx_ring[entry].base);
- /* end of packet */
- writel(readl(&lp->tx_ring[end].base) | T_ENP, &lp->tx_ring[end].base);
-
- for (i=end; i!=entry; --i) {
- /* ownership of packet */
- writel(readl(&lp->tx_ring[i].base) | T_OWN, &lp->tx_ring[i].base);
- if (i == 0) i=lp->txRingMask+1;
- }
- writel(readl(&lp->tx_ring[entry].base) | T_OWN, &lp->tx_ring[entry].base);
-
- lp->tx_new = (++end) & lp->txRingMask; /* update current pointers */
- } else {
- status = -1;
- }
-
- return status;
-}
-
-/*
-** Look for a particular board name in the EISA configuration space
-*/
-static int EISA_signature(char *name, s32 eisa_id)
-{
- u_int i;
- const char *signatures[] = DEPCA_SIGNATURE;
- char ManCode[DEPCA_STRLEN];
- union {
- s32 ID;
- char Id[4];
- } Eisa;
- int status = 0;
-
- *name = '\0';
- Eisa.ID = inl(eisa_id);
-
- ManCode[0]=(((Eisa.Id[0]>>2)&0x1f)+0x40);
- ManCode[1]=(((Eisa.Id[1]&0xe0)>>5)+((Eisa.Id[0]&0x03)<<3)+0x40);
- ManCode[2]=(((Eisa.Id[2]>>4)&0x0f)+0x30);
- ManCode[3]=(( Eisa.Id[2]&0x0f)+0x30);
- ManCode[4]=(((Eisa.Id[3]>>4)&0x0f)+0x30);
- ManCode[5]='\0';
-
- for (i=0;(*signatures[i] != '\0') && (*name == '\0');i++) {
- if (strstr(ManCode, signatures[i]) != NULL) {
- strcpy(name,ManCode);
- status = 1;
- }
- }
-
- return status;
-}
-
-static void depca_dbg_open(struct device *dev)
-{
- struct depca_private *lp = (struct depca_private *)dev->priv;
- u_long ioaddr = dev->base_addr;
- struct depca_init *p = (struct depca_init *)lp->sh_mem;
- int i;
-
- if (depca_debug > 1){
- /* Copy the shadow init_block to shared memory */
- memcpy_toio((char *)lp->sh_mem,&lp->init_block,sizeof(struct depca_init));
-
- printk("%s: depca open with irq %d\n",dev->name,dev->irq);
- printk("Descriptor head addresses:\n");
- printk("\t0x%lx 0x%lx\n",(u_long)lp->rx_ring, (u_long)lp->tx_ring);
- printk("Descriptor addresses:\nRX: ");
- for (i=0;i<lp->rxRingMask;i++){
- if (i < 3) {
- printk("0x%8.8lx ", (long) &lp->rx_ring[i].base);
- }
- }
- printk("...0x%8.8lx\n", (long) &lp->rx_ring[i].base);
- printk("TX: ");
- for (i=0;i<lp->txRingMask;i++){
- if (i < 3) {
- printk("0x%8.8lx ", (long) &lp->tx_ring[i].base);
- }
- }
- printk("...0x%8.8lx\n", (long) &lp->tx_ring[i].base);
- printk("\nDescriptor buffers:\nRX: ");
- for (i=0;i<lp->rxRingMask;i++){
- if (i < 3) {
- printk("0x%8.8x ", (u32) readl(&lp->rx_ring[i].base));
- }
- }
- printk("...0x%8.8x\n", (u32) readl(&lp->rx_ring[i].base));
- printk("TX: ");
- for (i=0;i<lp->txRingMask;i++){
- if (i < 3) {
- printk("0x%8.8x ", (u32) readl(&lp->tx_ring[i].base));
- }
- }
- printk("...0x%8.8x\n", (u32) readl(&lp->tx_ring[i].base));
- printk("Initialisation block at 0x%8.8lx\n",lp->sh_mem);
- printk("\tmode: 0x%4.4x\n", (u16) readw(&p->mode));
- printk("\tphysical address: ");
- for (i=0;i<ETH_ALEN-1;i++){
- printk("%2.2x:",(u_char)readb(&p->phys_addr[i]));
- }
- printk("%2.2x\n",(u_char)readb(&p->phys_addr[i]));
- printk("\tmulticast hash table: ");
- for (i=0;i<(HASH_TABLE_LEN >> 3)-1;i++){
- printk("%2.2x:",(u_char)readb(&p->mcast_table[i]));
- }
- printk("%2.2x\n",(u_char)readb(&p->mcast_table[i]));
- printk("\trx_ring at: 0x%8.8x\n", (u32) readl(&p->rx_ring));
- printk("\ttx_ring at: 0x%8.8x\n", (u32) readl(&p->tx_ring));
- printk("dma_buffs: 0x%8.8lx\n",lp->dma_buffs);
- printk("Ring size:\nRX: %d Log2(rxRingMask): 0x%8.8x\n",
- (int)lp->rxRingMask + 1,
- lp->rx_rlen);
- printk("TX: %d Log2(txRingMask): 0x%8.8x\n",
- (int)lp->txRingMask + 1,
- lp->tx_rlen);
- outw(CSR2,DEPCA_ADDR);
- printk("CSR2&1: 0x%4.4x",inw(DEPCA_DATA));
- outw(CSR1,DEPCA_ADDR);
- printk("%4.4x\n",inw(DEPCA_DATA));
- outw(CSR3,DEPCA_ADDR);
- printk("CSR3: 0x%4.4x\n",inw(DEPCA_DATA));
- }
-
- return;
-}
-
-/*
-** Perform IOCTL call functions here. Some are privileged operations and the
-** effective uid is checked in those cases.
-** All MCA IOCTLs will not work here and are for testing purposes only.
-*/
-static int depca_ioctl(struct device *dev, struct ifreq *rq, int cmd)
-{
- struct depca_private *lp = (struct depca_private *)dev->priv;
- struct depca_ioctl *ioc = (struct depca_ioctl *) &rq->ifr_data;
- int i, status = 0;
- u_long ioaddr = dev->base_addr;
- union {
- u8 addr[(HASH_TABLE_LEN * ETH_ALEN)];
- u16 sval[(HASH_TABLE_LEN * ETH_ALEN) >> 1];
- u32 lval[(HASH_TABLE_LEN * ETH_ALEN) >> 2];
- } tmp;
-
- switch(ioc->cmd) {
- case DEPCA_GET_HWADDR: /* Get the hardware address */
- for (i=0; i<ETH_ALEN; i++) {
- tmp.addr[i] = dev->dev_addr[i];
- }
- ioc->len = ETH_ALEN;
- if (!(status = verify_area(VERIFY_WRITE, (void *)ioc->data, ioc->len))) {
- memcpy_tofs(ioc->data, tmp.addr, ioc->len);
- }
-
- break;
- case DEPCA_SET_HWADDR: /* Set the hardware address */
- if (suser()) {
- if (!(status = verify_area(VERIFY_READ, (void *)ioc->data, ETH_ALEN))) {
- memcpy_fromfs(tmp.addr,ioc->data,ETH_ALEN);
- for (i=0; i<ETH_ALEN; i++) {
- dev->dev_addr[i] = tmp.addr[i];
- }
- while(dev->tbusy); /* Stop ring access */
- set_bit(0, (void*)&dev->tbusy);
- while(lp->tx_old != lp->tx_new);/* Wait for the ring to empty */
-
- STOP_DEPCA; /* Temporarily stop the depca. */
- depca_init_ring(dev); /* Initialize the descriptor rings */
- LoadCSRs(dev); /* Reload CSR3 */
- InitRestartDepca(dev); /* Resume normal operation. */
- dev->tbusy = 0; /* Unlock the TX ring */
- }
- } else {
- status = -EPERM;
- }
-
- break;
- case DEPCA_SET_PROM: /* Set Promiscuous Mode */
- if (suser()) {
- while(dev->tbusy); /* Stop ring access */
- set_bit(0, (void*)&dev->tbusy);
- while(lp->tx_old != lp->tx_new); /* Wait for the ring to empty */
-
- STOP_DEPCA; /* Temporarily stop the depca. */
- depca_init_ring(dev); /* Initialize the descriptor rings */
- lp->init_block.mode |= PROM; /* Set promiscuous mode */
-
- LoadCSRs(dev); /* Reload CSR3 */
- InitRestartDepca(dev); /* Resume normal operation. */
- dev->tbusy = 0; /* Unlock the TX ring */
- } else {
- status = -EPERM;
- }
-
- break;
- case DEPCA_CLR_PROM: /* Clear Promiscuous Mode */
- if (suser()) {
- while(dev->tbusy); /* Stop ring access */
- set_bit(0, (void*)&dev->tbusy);
- while(lp->tx_old != lp->tx_new); /* Wait for the ring to empty */
-
- STOP_DEPCA; /* Temporarily stop the depca. */
- depca_init_ring(dev); /* Initialize the descriptor rings */
- lp->init_block.mode &= ~PROM; /* Clear promiscuous mode */
-
- LoadCSRs(dev); /* Reload CSR3 */
- InitRestartDepca(dev); /* Resume normal operation. */
- dev->tbusy = 0; /* Unlock the TX ring */
- } else {
- status = -EPERM;
- }
-
- break;
- case DEPCA_SAY_BOO: /* Say "Boo!" to the kernel log file */
- printk("%s: Boo!\n", dev->name);
-
- break;
- case DEPCA_GET_MCA: /* Get the multicast address table */
- ioc->len = (HASH_TABLE_LEN >> 3);
- if (!(status = verify_area(VERIFY_WRITE, ioc->data, ioc->len))) {
- memcpy_tofs(ioc->data, lp->init_block.mcast_table, ioc->len);
- }
-
- break;
- case DEPCA_SET_MCA: /* Set a multicast address */
- if (suser()) {
- if (!(status=verify_area(VERIFY_READ, ioc->data, ETH_ALEN*ioc->len))) {
- memcpy_fromfs(tmp.addr, ioc->data, ETH_ALEN * ioc->len);
- set_multicast_list(dev);
- }
- } else {
- status = -EPERM;
- }
-
- break;
- case DEPCA_CLR_MCA: /* Clear all multicast addresses */
- if (suser()) {
- set_multicast_list(dev);
- } else {
- status = -EPERM;
- }
-
- break;
- case DEPCA_MCA_EN: /* Enable pass all multicast addressing */
- if (suser()) {
- set_multicast_list(dev);
- } else {
- status = -EPERM;
- }
-
- break;
- case DEPCA_GET_STATS: /* Get the driver statistics */
- cli();
- ioc->len = sizeof(lp->pktStats);
- if (!(status=verify_area(VERIFY_WRITE, ioc->data, ioc->len))) {
- memcpy_tofs(ioc->data, &lp->pktStats, ioc->len);
- }
- sti();
-
- break;
- case DEPCA_CLR_STATS: /* Zero out the driver statistics */
- if (suser()) {
- cli();
- memset(&lp->pktStats, 0, sizeof(lp->pktStats));
- sti();
- } else {
- status = -EPERM;
- }
-
- break;
- case DEPCA_GET_REG: /* Get the DEPCA Registers */
- i=0;
- tmp.sval[i++] = inw(DEPCA_NICSR);
- outw(CSR0, DEPCA_ADDR); /* status register */
- tmp.sval[i++] = inw(DEPCA_DATA);
- memcpy(&tmp.sval[i], &lp->init_block, sizeof(struct depca_init));
- ioc->len = i+sizeof(struct depca_init);
- if (!(status=verify_area(VERIFY_WRITE, ioc->data, ioc->len))) {
- memcpy_tofs(ioc->data, tmp.addr, ioc->len);
- }
-
- break;
- default:
- status = -EOPNOTSUPP;
- }
-
- return status;
-}
-
-#ifdef MODULE
-static char devicename[9] = { 0, };
-static struct device thisDepca = {
- devicename, /* device name is inserted by /linux/drivers/net/net_init.c */
- 0, 0, 0, 0,
- 0x200, 7, /* I/O address, IRQ */
- 0, 0, 0, NULL, depca_probe };
-
-static int irq=7; /* EDIT THESE LINE FOR YOUR CONFIGURATION */
-static int io=0x200; /* Or use the irq= io= options to insmod */
-
-/* See depca_probe() for autoprobe messages when a module */
-int
-init_module(void)
-{
- thisDepca.irq=irq;
- thisDepca.base_addr=io;
-
- if (register_netdev(&thisDepca) != 0)
- return -EIO;
-
- return 0;
-}
-
-void
-cleanup_module(void)
-{
- release_region(thisDepca.base_addr, DEPCA_TOTAL_SIZE);
- if (thisDepca.priv) {
- kfree(thisDepca.priv);
- thisDepca.priv = NULL;
- }
- thisDepca.irq=0;
-
- unregister_netdev(&thisDepca);
-}
-#endif /* MODULE */
-
-
-/*
- * Local variables:
- * kernel-compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O2 -m486 -c depca.c"
- *
- * module-compile-command: "gcc -D__KERNEL__ -DMODULE -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O2 -m486 -c depca.c"
- * End:
- */
diff --git a/i386/i386at/gpl/linux/net/depca.h b/i386/i386at/gpl/linux/net/depca.h
deleted file mode 100644
index 012f7399..00000000
--- a/i386/i386at/gpl/linux/net/depca.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- Written 1994 by David C. Davies.
-
- Copyright 1994 David C. Davies. This software may be used and distributed
- according to the terms of the GNU Public License, incorporated herein by
- reference.
-*/
-
-/*
-** I/O addresses. Note that the 2k buffer option is not supported in
-** this driver.
-*/
-#define DEPCA_NICSR ioaddr+0x00 /* Network interface CSR */
-#define DEPCA_RBI ioaddr+0x02 /* RAM buffer index (2k buffer mode) */
-#define DEPCA_DATA ioaddr+0x04 /* LANCE registers' data port */
-#define DEPCA_ADDR ioaddr+0x06 /* LANCE registers' address port */
-#define DEPCA_HBASE ioaddr+0x08 /* EISA high memory base address reg. */
-#define DEPCA_PROM ioaddr+0x0c /* Ethernet address ROM data port */
-#define DEPCA_CNFG ioaddr+0x0c /* EISA Configuration port */
-#define DEPCA_RBSA ioaddr+0x0e /* RAM buffer starting address (2k buff.) */
-
-/*
-** These are LANCE registers addressable through DEPCA_ADDR
-*/
-#define CSR0 0
-#define CSR1 1
-#define CSR2 2
-#define CSR3 3
-
-/*
-** NETWORK INTERFACE CSR (NI_CSR) bit definitions
-*/
-
-#define TO 0x0100 /* Time Out for remote boot */
-#define SHE 0x0080 /* SHadow memory Enable */
-#define BS 0x0040 /* Bank Select */
-#define BUF 0x0020 /* BUFfer size (1->32k, 0->64k) */
-#define RBE 0x0010 /* Remote Boot Enable (1->net boot) */
-#define AAC 0x0008 /* Address ROM Address Counter (1->enable) */
-#define _128KB 0x0008 /* 128kB Network RAM (1->enable) */
-#define IM 0x0004 /* Interrupt Mask (1->mask) */
-#define IEN 0x0002 /* Interrupt tristate ENable (1->enable) */
-#define LED 0x0001 /* LED control */
-
-/*
-** Control and Status Register 0 (CSR0) bit definitions
-*/
-
-#define ERR 0x8000 /* Error summary */
-#define BABL 0x4000 /* Babble transmitter timeout error */
-#define CERR 0x2000 /* Collision Error */
-#define MISS 0x1000 /* Missed packet */
-#define MERR 0x0800 /* Memory Error */
-#define RINT 0x0400 /* Receiver Interrupt */
-#define TINT 0x0200 /* Transmit Interrupt */
-#define IDON 0x0100 /* Initialization Done */
-#define INTR 0x0080 /* Interrupt Flag */
-#define INEA 0x0040 /* Interrupt Enable */
-#define RXON 0x0020 /* Receiver on */
-#define TXON 0x0010 /* Transmitter on */
-#define TDMD 0x0008 /* Transmit Demand */
-#define STOP 0x0004 /* Stop */
-#define STRT 0x0002 /* Start */
-#define INIT 0x0001 /* Initialize */
-#define INTM 0xff00 /* Interrupt Mask */
-#define INTE 0xfff0 /* Interrupt Enable */
-
-/*
-** CONTROL AND STATUS REGISTER 3 (CSR3)
-*/
-
-#define BSWP 0x0004 /* Byte SWaP */
-#define ACON 0x0002 /* ALE control */
-#define BCON 0x0001 /* Byte CONtrol */
-
-/*
-** Initialization Block Mode Register
-*/
-
-#define PROM 0x8000 /* Promiscuous Mode */
-#define EMBA 0x0080 /* Enable Modified Back-off Algorithm */
-#define INTL 0x0040 /* Internal Loopback */
-#define DRTY 0x0020 /* Disable Retry */
-#define COLL 0x0010 /* Force Collision */
-#define DTCR 0x0008 /* Disable Transmit CRC */
-#define LOOP 0x0004 /* Loopback */
-#define DTX 0x0002 /* Disable the Transmitter */
-#define DRX 0x0001 /* Disable the Receiver */
-
-/*
-** Receive Message Descriptor 1 (RMD1) bit definitions.
-*/
-
-#define R_OWN 0x80000000 /* Owner bit 0 = host, 1 = lance */
-#define R_ERR 0x4000 /* Error Summary */
-#define R_FRAM 0x2000 /* Framing Error */
-#define R_OFLO 0x1000 /* Overflow Error */
-#define R_CRC 0x0800 /* CRC Error */
-#define R_BUFF 0x0400 /* Buffer Error */
-#define R_STP 0x0200 /* Start of Packet */
-#define R_ENP 0x0100 /* End of Packet */
-
-/*
-** Transmit Message Descriptor 1 (TMD1) bit definitions.
-*/
-
-#define T_OWN 0x80000000 /* Owner bit 0 = host, 1 = lance */
-#define T_ERR 0x4000 /* Error Summary */
-#define T_ADD_FCS 0x2000 /* More the 1 retry needed to Xmit */
-#define T_MORE 0x1000 /* >1 retry to transmit packet */
-#define T_ONE 0x0800 /* 1 try needed to transmit the packet */
-#define T_DEF 0x0400 /* Deferred */
-#define T_STP 0x02000000 /* Start of Packet */
-#define T_ENP 0x01000000 /* End of Packet */
-#define T_FLAGS 0xff000000 /* TX Flags Field */
-
-/*
-** Transmit Message Descriptor 3 (TMD3) bit definitions.
-*/
-
-#define TMD3_BUFF 0x8000 /* BUFFer error */
-#define TMD3_UFLO 0x4000 /* UnderFLOw error */
-#define TMD3_RES 0x2000 /* REServed */
-#define TMD3_LCOL 0x1000 /* Late COLlision */
-#define TMD3_LCAR 0x0800 /* Loss of CARrier */
-#define TMD3_RTRY 0x0400 /* ReTRY error */
-
-/*
-** EISA configuration Register (CNFG) bit definitions
-*/
-
-#define TIMEOUT 0x0100 /* 0:2.5 mins, 1: 30 secs */
-#define REMOTE 0x0080 /* Remote Boot Enable -> 1 */
-#define IRQ11 0x0040 /* Enable -> 1 */
-#define IRQ10 0x0020 /* Enable -> 1 */
-#define IRQ9 0x0010 /* Enable -> 1 */
-#define IRQ5 0x0008 /* Enable -> 1 */
-#define BUFF 0x0004 /* 0: 64kB or 128kB, 1: 32kB */
-#define PADR16 0x0002 /* RAM on 64kB boundary */
-#define PADR17 0x0001 /* RAM on 128kB boundary */
-
-/*
-** Miscellaneous
-*/
-#define HASH_TABLE_LEN 64 /* Bits */
-#define HASH_BITS 0x003f /* 6 LS bits */
-
-#define MASK_INTERRUPTS 1
-#define UNMASK_INTERRUPTS 0
-
-#define EISA_EN 0x0001 /* Enable EISA bus buffers */
-#define EISA_ID iobase+0x0080 /* ID long word for EISA card */
-#define EISA_CTRL iobase+0x0084 /* Control word for EISA card */
-
-/*
-** Include the IOCTL stuff
-*/
-#include <linux/sockios.h>
-
-#define DEPCAIOCTL SIOCDEVPRIVATE
-
-struct depca_ioctl {
- unsigned short cmd; /* Command to run */
- unsigned short len; /* Length of the data buffer */
- unsigned char *data; /* Pointer to the data buffer */
-};
-
-/*
-** Recognised commands for the driver
-*/
-#define DEPCA_GET_HWADDR 0x01 /* Get the hardware address */
-#define DEPCA_SET_HWADDR 0x02 /* Get the hardware address */
-#define DEPCA_SET_PROM 0x03 /* Set Promiscuous Mode */
-#define DEPCA_CLR_PROM 0x04 /* Clear Promiscuous Mode */
-#define DEPCA_SAY_BOO 0x05 /* Say "Boo!" to the kernel log file */
-#define DEPCA_GET_MCA 0x06 /* Get a multicast address */
-#define DEPCA_SET_MCA 0x07 /* Set a multicast address */
-#define DEPCA_CLR_MCA 0x08 /* Clear a multicast address */
-#define DEPCA_MCA_EN 0x09 /* Enable a multicast address group */
-#define DEPCA_GET_STATS 0x0a /* Get the driver statistics */
-#define DEPCA_CLR_STATS 0x0b /* Zero out the driver statistics */
-#define DEPCA_GET_REG 0x0c /* Get the Register contents */
-#define DEPCA_SET_REG 0x0d /* Set the Register contents */
-#define DEPCA_DUMP 0x0f /* Dump the DEPCA Status */
-
diff --git a/i386/i386at/gpl/linux/net/dev.c b/i386/i386at/gpl/linux/net/dev.c
deleted file mode 100644
index 69d576ff..00000000
--- a/i386/i386at/gpl/linux/net/dev.c
+++ /dev/null
@@ -1,1413 +0,0 @@
-/*
- * NET3 Protocol independent device support routines.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- * Derived from the non IP parts of dev.c 1.0.19
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
- * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- * Mark Evans, <evansmp@uhura.aston.ac.uk>
- *
- * Additional Authors:
- * Florian la Roche <rzsfl@rz.uni-sb.de>
- * Alan Cox <gw4pts@gw4pts.ampr.org>
- * David Hinds <dhinds@allegro.stanford.edu>
- *
- * Changes:
- * Alan Cox : device private ioctl copies fields back.
- * Alan Cox : Transmit queue code does relevant stunts to
- * keep the queue safe.
- * Alan Cox : Fixed double lock.
- * Alan Cox : Fixed promisc NULL pointer trap
- * ???????? : Support the full private ioctl range
- * Alan Cox : Moved ioctl permission check into drivers
- * Tim Kordas : SIOCADDMULTI/SIOCDELMULTI
- * Alan Cox : 100 backlog just doesn't cut it when
- * you start doing multicast video 8)
- * Alan Cox : Rewrote net_bh and list manager.
- * Alan Cox : Fix ETH_P_ALL echoback lengths.
- * Alan Cox : Took out transmit every packet pass
- * Saved a few bytes in the ioctl handler
- * Alan Cox : Network driver sets packet type before calling netif_rx. Saves
- * a function call a packet.
- * Alan Cox : Hashed net_bh()
- * Richard Kooijman: Timestamp fixes.
- * Alan Cox : Wrong field in SIOCGIFDSTADDR
- * Alan Cox : Device lock protection.
- * Alan Cox : Fixed nasty side effect of device close changes.
- * Rudi Cilibrasi : Pass the right thing to set_mac_address()
- * Dave Miller : 32bit quantity for the device lock to make it work out
- * on a Sparc.
- * Bjorn Ekwall : Added KERNELD hack.
- * Alan Cox : Cleaned up the backlog initialise.
- * Craig Metz : SIOCGIFCONF fix if space for under
- * 1 device.
- *
- */
-
-#include <asm/segment.h>
-#include <asm/system.h>
-#include <asm/bitops.h>
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/if_ether.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/notifier.h>
-#include <net/ip.h>
-#include <net/route.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <net/arp.h>
-#include <net/slhc.h>
-#include <linux/proc_fs.h>
-#include <linux/stat.h>
-#ifdef CONFIG_NET_ALIAS
-#include <linux/net_alias.h>
-#endif
-#ifdef CONFIG_KERNELD
-#include <linux/kerneld.h>
-#endif
-
-#ifndef MACH
-/*
- * The list of packet types we will receive (as opposed to discard)
- * and the routines to invoke.
- */
-
-struct packet_type *ptype_base[16];
-struct packet_type *ptype_all = NULL; /* Taps */
-
-/*
- * Device list lock
- */
-
-int dev_lockct=0;
-
-/*
- * Our notifier list
- */
-
-struct notifier_block *netdev_chain=NULL;
-
-/*
- * Device drivers call our routines to queue packets here. We empty the
- * queue in the bottom half handler.
- */
-
-static struct sk_buff_head backlog;
-
-/*
- * We don't overdo the queue or we will thrash memory badly.
- */
-
-static int backlog_size = 0;
-
-/*
- * Return the lesser of the two values.
- */
-
-static __inline__ unsigned long min(unsigned long a, unsigned long b)
-{
- return (a < b)? a : b;
-}
-
-
-/******************************************************************************************
-
- Protocol management and registration routines
-
-*******************************************************************************************/
-
-/*
- * For efficiency
- */
-
-static int dev_nit=0;
-
-/*
- * Add a protocol ID to the list. Now that the input handler is
- * smarter we can dispense with all the messy stuff that used to be
- * here.
- */
-
-void dev_add_pack(struct packet_type *pt)
-{
- int hash;
- if(pt->type==htons(ETH_P_ALL))
- {
- dev_nit++;
- pt->next=ptype_all;
- ptype_all=pt;
- }
- else
- {
- hash=ntohs(pt->type)&15;
- pt->next = ptype_base[hash];
- ptype_base[hash] = pt;
- }
-}
-
-
-/*
- * Remove a protocol ID from the list.
- */
-
-void dev_remove_pack(struct packet_type *pt)
-{
- struct packet_type **pt1;
- if(pt->type==htons(ETH_P_ALL))
- {
- dev_nit--;
- pt1=&ptype_all;
- }
- else
- pt1=&ptype_base[ntohs(pt->type)&15];
- for(; (*pt1)!=NULL; pt1=&((*pt1)->next))
- {
- if(pt==(*pt1))
- {
- *pt1=pt->next;
- return;
- }
- }
- printk("dev_remove_pack: %p not found.\n", pt);
-}
-
-/*****************************************************************************************
-
- Device Interface Subroutines
-
-******************************************************************************************/
-
-/*
- * Find an interface by name.
- */
-
-struct device *dev_get(const char *name)
-{
- struct device *dev;
-
- for (dev = dev_base; dev != NULL; dev = dev->next)
- {
- if (strcmp(dev->name, name) == 0)
- return(dev);
- }
- return NULL;
-}
-
-/*
- * Find and possibly load an interface.
- */
-
-#ifdef CONFIG_KERNELD
-
-extern __inline__ void dev_load(const char *name)
-{
- char *sptr;
-
- if(!dev_get(name)) {
-#ifdef CONFIG_NET_ALIAS
- for (sptr=name ; *sptr ; sptr++) if(*sptr==':') break;
- if (!(*sptr && *(sptr+1)))
-#endif
- request_module(name);
- }
-}
-
-#endif
-
-/*
- * Prepare an interface for use.
- */
-
-int dev_open(struct device *dev)
-{
- int ret = 0;
-
- /*
- * Call device private open method
- */
- if (dev->open)
- ret = dev->open(dev);
-
- /*
- * If it went open OK then set the flags
- */
-
- if (ret == 0)
- {
- dev->flags |= (IFF_UP | IFF_RUNNING);
- /*
- * Initialise multicasting status
- */
- dev_mc_upload(dev);
- notifier_call_chain(&netdev_chain, NETDEV_UP, dev);
- }
- return(ret);
-}
-
-
-/*
- * Completely shutdown an interface.
- */
-
-int dev_close(struct device *dev)
-{
- int ct=0;
-
- /*
- * Call the device specific close. This cannot fail.
- * Only if device is UP
- */
-
- if ((dev->flags & IFF_UP) && dev->stop)
- dev->stop(dev);
-
- /*
- * Device is now down.
- */
-
- dev->flags&=~(IFF_UP|IFF_RUNNING);
-
- /*
- * Tell people we are going down
- */
- notifier_call_chain(&netdev_chain, NETDEV_DOWN, dev);
- /*
- * Flush the multicast chain
- */
- dev_mc_discard(dev);
- /*
- * Blank the IP addresses
- */
- dev->pa_addr = 0;
- dev->pa_dstaddr = 0;
- dev->pa_brdaddr = 0;
- dev->pa_mask = 0;
- /*
- * Purge any queued packets when we down the link
- */
- while(ct<DEV_NUMBUFFS)
- {
- struct sk_buff *skb;
- while((skb=skb_dequeue(&dev->buffs[ct]))!=NULL)
- if(skb->free)
- kfree_skb(skb,FREE_WRITE);
- ct++;
- }
- return(0);
-}
-
-
-/*
- * Device change register/unregister. These are not inline or static
- * as we export them to the world.
- */
-
-int register_netdevice_notifier(struct notifier_block *nb)
-{
- return notifier_chain_register(&netdev_chain, nb);
-}
-
-int unregister_netdevice_notifier(struct notifier_block *nb)
-{
- return notifier_chain_unregister(&netdev_chain,nb);
-}
-
-/*
- * Send (or queue for sending) a packet.
- *
- * IMPORTANT: When this is called to resend frames. The caller MUST
- * already have locked the sk_buff. Apart from that we do the
- * rest of the magic.
- */
-
-void dev_queue_xmit(struct sk_buff *skb, struct device *dev, int pri)
-{
- unsigned long flags;
- struct sk_buff_head *list;
- int retransmission = 0; /* used to say if the packet should go */
- /* at the front or the back of the */
- /* queue - front is a retransmit try */
-
- if(pri>=0 && !skb_device_locked(skb))
- skb_device_lock(skb); /* Shove a lock on the frame */
-#if CONFIG_SKB_CHECK
- IS_SKB(skb);
-#endif
- skb->dev = dev;
-
- /*
- * Negative priority is used to flag a frame that is being pulled from the
- * queue front as a retransmit attempt. It therefore goes back on the queue
- * start on a failure.
- */
-
- if (pri < 0)
- {
- pri = -pri-1;
- retransmission = 1;
- }
-
-#ifdef CONFIG_NET_DEBUG
- if (pri >= DEV_NUMBUFFS)
- {
- printk("bad priority in dev_queue_xmit.\n");
- pri = 1;
- }
-#endif
-
- /*
- * If the address has not been resolved. Call the device header rebuilder.
- * This can cover all protocols and technically not just ARP either.
- */
-
- if (!skb->arp && dev->rebuild_header(skb->data, dev, skb->raddr, skb)) {
- return;
- }
-
- /*
- *
- * If dev is an alias, switch to its main device.
- * "arp" resolution has been made with alias device, so
- * arp entries refer to alias, not main.
- *
- */
-
-#ifdef CONFIG_NET_ALIAS
- if (net_alias_is(dev))
- skb->dev = dev = net_alias_main_dev(dev);
-#endif
- list = dev->buffs + pri;
-
- save_flags(flags);
- /* if this isn't a retransmission, use the first packet instead... */
- if (!retransmission) {
- if (skb_queue_len(list)) {
- /* avoid overrunning the device queue.. */
- if (skb_queue_len(list) > dev->tx_queue_len) {
- dev_kfree_skb(skb, FREE_WRITE);
- return;
- }
- cli();
- skb_device_unlock(skb); /* Buffer is on the device queue and can be freed safely */
- __skb_queue_tail(list, skb);
- skb = __skb_dequeue(list);
- skb_device_lock(skb); /* New buffer needs locking down */
- restore_flags(flags);
- }
-
- /* copy outgoing packets to any sniffer packet handlers */
- if (dev_nit) {
- struct packet_type *ptype;
- skb->stamp=xtime;
- for (ptype = ptype_all; ptype!=NULL; ptype = ptype->next)
- {
- /* Never send packets back to the socket
- * they originated from - MvS (miquels@drinkel.ow.org)
- */
- if ((ptype->dev == dev || !ptype->dev) &&
- ((struct sock *)ptype->data != skb->sk))
- {
- struct sk_buff *skb2;
- if ((skb2 = skb_clone(skb, GFP_ATOMIC)) == NULL)
- break;
- skb2->h.raw = skb2->data + dev->hard_header_len;
- skb2->mac.raw = skb2->data;
- ptype->func(skb2, skb->dev, ptype);
- }
- }
- }
- }
- start_bh_atomic();
- if (dev->hard_start_xmit(skb, dev) == 0) {
- /*
- * Packet is now solely the responsibility of the driver
- */
- end_bh_atomic();
- return;
- }
- end_bh_atomic();
-
- /*
- * Transmission failed, put skb back into a list. Once on the list it's safe and
- * no longer device locked (it can be freed safely from the device queue)
- */
- cli();
- skb_device_unlock(skb);
- __skb_queue_head(list,skb);
- restore_flags(flags);
-}
-
-/*
- * Receive a packet from a device driver and queue it for the upper
- * (protocol) levels. It always succeeds. This is the recommended
- * interface to use.
- */
-
-void netif_rx(struct sk_buff *skb)
-{
- static int dropping = 0;
-
- /*
- * Any received buffers are un-owned and should be discarded
- * when freed. These will be updated later as the frames get
- * owners.
- */
-
- skb->sk = NULL;
- skb->free = 1;
- if(skb->stamp.tv_sec==0)
- skb->stamp = xtime;
-
- /*
- * Check that we aren't overdoing things.
- */
-
- if (!backlog_size)
- dropping = 0;
- else if (backlog_size > 300)
- dropping = 1;
-
- if (dropping)
- {
- kfree_skb(skb, FREE_READ);
- return;
- }
-
- /*
- * Add it to the "backlog" queue.
- */
-#if CONFIG_SKB_CHECK
- IS_SKB(skb);
-#endif
- skb_queue_tail(&backlog,skb);
- backlog_size++;
-
- /*
- * If any packet arrived, mark it for processing after the
- * hardware interrupt returns.
- */
-
-#ifdef CONFIG_NET_RUNONIRQ /* Dont enable yet, needs some driver mods */
- net_bh();
-#else
- mark_bh(NET_BH);
-#endif
- return;
-}
-
-/*
- * This routine causes all interfaces to try to send some data.
- */
-
-void dev_transmit(void)
-{
- struct device *dev;
-
- for (dev = dev_base; dev != NULL; dev = dev->next)
- {
- if (dev->flags != 0 && !dev->tbusy) {
- /*
- * Kick the device
- */
- dev_tint(dev);
- }
- }
-}
-
-
-/**********************************************************************************
-
- Receive Queue Processor
-
-***********************************************************************************/
-
-/*
- * This is a single non-reentrant routine which takes the received packet
- * queue and throws it at the networking layers in the hope that something
- * useful will emerge.
- */
-
-volatile unsigned long in_bh = 0; /* Non-reentrant remember */
-
-int in_net_bh() /* Used by timer.c */
-{
- return(in_bh==0?0:1);
-}
-
-/*
- * When we are called the queue is ready to grab, the interrupts are
- * on and hardware can interrupt and queue to the receive queue a we
- * run with no problems.
- * This is run as a bottom half after an interrupt handler that does
- * mark_bh(NET_BH);
- */
-
-void net_bh(void *tmp)
-{
- struct sk_buff *skb;
- struct packet_type *ptype;
- struct packet_type *pt_prev;
- unsigned short type;
-
- /*
- * Atomically check and mark our BUSY state.
- */
-
- if (set_bit(1, (void*)&in_bh))
- return;
-
- /*
- * Can we send anything now? We want to clear the
- * decks for any more sends that get done as we
- * process the input. This also minimises the
- * latency on a transmit interrupt bh.
- */
-
- dev_transmit();
-
- /*
- * Any data left to process. This may occur because a
- * mark_bh() is done after we empty the queue including
- * that from the device which does a mark_bh() just after
- */
-
- cli();
-
- /*
- * While the queue is not empty
- */
-
- while((skb=__skb_dequeue(&backlog))!=NULL)
- {
- /*
- * We have a packet. Therefore the queue has shrunk
- */
- backlog_size--;
-
- sti();
-
- /*
- * Bump the pointer to the next structure.
- *
- * On entry to the protocol layer. skb->data and
- * skb->h.raw point to the MAC and encapsulated data
- */
-
- skb->h.raw = skb->data;
-
- /*
- * Fetch the packet protocol ID.
- */
-
- type = skb->protocol;
-
- /*
- * We got a packet ID. Now loop over the "known protocols"
- * list. There are two lists. The ptype_all list of taps (normally empty)
- * and the main protocol list which is hashed perfectly for normal protocols.
- */
- pt_prev = NULL;
- for (ptype = ptype_all; ptype!=NULL; ptype=ptype->next)
- {
- if(pt_prev)
- {
- struct sk_buff *skb2=skb_clone(skb, GFP_ATOMIC);
- if(skb2)
- pt_prev->func(skb2,skb->dev, pt_prev);
- }
- pt_prev=ptype;
- }
-
- for (ptype = ptype_base[ntohs(type)&15]; ptype != NULL; ptype = ptype->next)
- {
- if (ptype->type == type && (!ptype->dev || ptype->dev==skb->dev))
- {
- /*
- * We already have a match queued. Deliver
- * to it and then remember the new match
- */
- if(pt_prev)
- {
- struct sk_buff *skb2;
-
- skb2=skb_clone(skb, GFP_ATOMIC);
-
- /*
- * Kick the protocol handler. This should be fast
- * and efficient code.
- */
-
- if(skb2)
- pt_prev->func(skb2, skb->dev, pt_prev);
- }
- /* Remember the current last to do */
- pt_prev=ptype;
- }
- } /* End of protocol list loop */
-
- /*
- * Is there a last item to send to ?
- */
-
- if(pt_prev)
- pt_prev->func(skb, skb->dev, pt_prev);
- /*
- * Has an unknown packet has been received ?
- */
-
- else
- kfree_skb(skb, FREE_WRITE);
-
- /*
- * Again, see if we can transmit anything now.
- * [Ought to take this out judging by tests it slows
- * us down not speeds us up]
- */
-#ifdef XMIT_EVERY
- dev_transmit();
-#endif
- cli();
- } /* End of queue loop */
-
- /*
- * We have emptied the queue
- */
-
- in_bh = 0;
- sti();
-
- /*
- * One last output flush.
- */
-
-#ifdef XMIT_AFTER
- dev_transmit();
-#endif
-}
-
-
-/*
- * This routine is called when an device driver (i.e. an
- * interface) is ready to transmit a packet.
- */
-
-void dev_tint(struct device *dev)
-{
- int i;
- unsigned long flags;
- struct sk_buff_head * head;
-
- /*
- * aliases do not transmit (for now :) )
- */
-
-#ifdef CONFIG_NET_ALIAS
- if (net_alias_is(dev)) return;
-#endif
- head = dev->buffs;
- save_flags(flags);
- cli();
-
- /*
- * Work the queues in priority order
- */
- for(i = 0;i < DEV_NUMBUFFS; i++,head++)
- {
- struct sk_buff *skb = skb_peek(head);
-
- if (skb) {
- __skb_unlink(skb, head);
- /*
- * Stop anyone freeing the buffer while we retransmit it
- */
- skb_device_lock(skb);
- restore_flags(flags);
- /*
- * Feed them to the output stage and if it fails
- * indicate they re-queue at the front.
- */
- dev_queue_xmit(skb,dev,-i - 1);
- /*
- * If we can take no more then stop here.
- */
- if (dev->tbusy)
- return;
- cli();
- }
- }
- restore_flags(flags);
-}
-
-
-/*
- * Perform a SIOCGIFCONF call. This structure will change
- * size shortly, and there is nothing I can do about it.
- * Thus we will need a 'compatibility mode'.
- */
-
-static int dev_ifconf(char *arg)
-{
- struct ifconf ifc;
- struct ifreq ifr;
- struct device *dev;
- char *pos;
- int len;
- int err;
-
- /*
- * Fetch the caller's info block.
- */
-
- err=verify_area(VERIFY_WRITE, arg, sizeof(struct ifconf));
- if(err)
- return err;
- memcpy_fromfs(&ifc, arg, sizeof(struct ifconf));
- len = ifc.ifc_len;
- pos = ifc.ifc_buf;
-
- /*
- * We now walk the device list filling each active device
- * into the array.
- */
-
- err=verify_area(VERIFY_WRITE,pos,len);
- if(err)
- return err;
-
- /*
- * Loop over the interfaces, and write an info block for each.
- */
-
- for (dev = dev_base; dev != NULL; dev = dev->next)
- {
- if(!(dev->flags & IFF_UP)) /* Downed devices don't count */
- continue;
- /*
- * Have we run out of space here ?
- */
-
- if (len < sizeof(struct ifreq))
- break;
-
- memset(&ifr, 0, sizeof(struct ifreq));
- strcpy(ifr.ifr_name, dev->name);
- (*(struct sockaddr_in *) &ifr.ifr_addr).sin_family = dev->family;
- (*(struct sockaddr_in *) &ifr.ifr_addr).sin_addr.s_addr = dev->pa_addr;
-
-
- /*
- * Write this block to the caller's space.
- */
-
- memcpy_tofs(pos, &ifr, sizeof(struct ifreq));
- pos += sizeof(struct ifreq);
- len -= sizeof(struct ifreq);
- }
-
- /*
- * All done. Write the updated control block back to the caller.
- */
-
- ifc.ifc_len = (pos - ifc.ifc_buf);
- ifc.ifc_req = (struct ifreq *) ifc.ifc_buf;
- memcpy_tofs(arg, &ifc, sizeof(struct ifconf));
-
- /*
- * Report how much was filled in
- */
-
- return(pos - arg);
-}
-
-
-/*
- * This is invoked by the /proc filesystem handler to display a device
- * in detail.
- */
-
-#ifdef CONFIG_PROC_FS
-static int sprintf_stats(char *buffer, struct device *dev)
-{
- struct enet_statistics *stats = (dev->get_stats ? dev->get_stats(dev): NULL);
- int size;
-
- if (stats)
- size = sprintf(buffer, "%6s:%7d %4d %4d %4d %4d %8d %4d %4d %4d %5d %4d\n",
- dev->name,
- stats->rx_packets, stats->rx_errors,
- stats->rx_dropped + stats->rx_missed_errors,
- stats->rx_fifo_errors,
- stats->rx_length_errors + stats->rx_over_errors
- + stats->rx_crc_errors + stats->rx_frame_errors,
- stats->tx_packets, stats->tx_errors, stats->tx_dropped,
- stats->tx_fifo_errors, stats->collisions,
- stats->tx_carrier_errors + stats->tx_aborted_errors
- + stats->tx_window_errors + stats->tx_heartbeat_errors);
- else
- size = sprintf(buffer, "%6s: No statistics available.\n", dev->name);
-
- return size;
-}
-
-/*
- * Called from the PROCfs module. This now uses the new arbitrary sized /proc/net interface
- * to create /proc/net/dev
- */
-
-int dev_get_info(char *buffer, char **start, off_t offset, int length, int dummy)
-{
- int len=0;
- off_t begin=0;
- off_t pos=0;
- int size;
-
- struct device *dev;
-
-
- size = sprintf(buffer, "Inter-| Receive | Transmit\n"
- " face |packets errs drop fifo frame|packets errs drop fifo colls carrier\n");
-
- pos+=size;
- len+=size;
-
-
- for (dev = dev_base; dev != NULL; dev = dev->next)
- {
- size = sprintf_stats(buffer+len, dev);
- len+=size;
- pos=begin+len;
-
- if(pos<offset)
- {
- len=0;
- begin=pos;
- }
- if(pos>offset+length)
- break;
- }
-
- *start=buffer+(offset-begin); /* Start of wanted data */
- len-=(offset-begin); /* Start slop */
- if(len>length)
- len=length; /* Ending slop */
- return len;
-}
-#endif /* CONFIG_PROC_FS */
-
-
-/*
- * This checks bitmasks for the ioctl calls for devices.
- */
-
-static inline int bad_mask(unsigned long mask, unsigned long addr)
-{
- if (addr & (mask = ~mask))
- return 1;
- mask = ntohl(mask);
- if (mask & (mask+1))
- return 1;
- return 0;
-}
-
-/*
- * Perform the SIOCxIFxxx calls.
- *
- * The socket layer has seen an ioctl the address family thinks is
- * for the device. At this point we get invoked to make a decision
- */
-
-static int dev_ifsioc(void *arg, unsigned int getset)
-{
- struct ifreq ifr;
- struct device *dev;
- int ret;
-
- /*
- * Fetch the caller's info block into kernel space
- */
-
- int err=verify_area(VERIFY_WRITE, arg, sizeof(struct ifreq));
- if(err)
- return err;
-
- memcpy_fromfs(&ifr, arg, sizeof(struct ifreq));
-
- /*
- * See which interface the caller is talking about.
- */
-
- /*
- *
- * net_alias_dev_get(): dev_get() with added alias naming magic.
- * only allow alias creation/deletion if (getset==SIOCSIFADDR)
- *
- */
-
-#ifdef CONFIG_KERNELD
- dev_load(ifr.ifr_name);
-#endif
-
-#ifdef CONFIG_NET_ALIAS
- if ((dev = net_alias_dev_get(ifr.ifr_name, getset == SIOCSIFADDR, &err, NULL, NULL)) == NULL)
- return(err);
-#else
- if ((dev = dev_get(ifr.ifr_name)) == NULL)
- return(-ENODEV);
-#endif
- switch(getset)
- {
- case SIOCGIFFLAGS: /* Get interface flags */
- ifr.ifr_flags = dev->flags;
- goto rarok;
-
- case SIOCSIFFLAGS: /* Set interface flags */
- {
- int old_flags = dev->flags;
-
- /*
- * We are not allowed to potentially close/unload
- * a device until we get this lock.
- */
-
- dev_lock_wait();
-
- /*
- * Set the flags on our device.
- */
-
- dev->flags = (ifr.ifr_flags & (
- IFF_BROADCAST | IFF_DEBUG | IFF_LOOPBACK |
- IFF_POINTOPOINT | IFF_NOTRAILERS | IFF_RUNNING |
- IFF_NOARP | IFF_PROMISC | IFF_ALLMULTI | IFF_SLAVE | IFF_MASTER
- | IFF_MULTICAST)) | (dev->flags & IFF_UP);
- /*
- * Load in the correct multicast list now the flags have changed.
- */
-
- dev_mc_upload(dev);
-
- /*
- * Have we downed the interface. We handle IFF_UP ourselves
- * according to user attempts to set it, rather than blindly
- * setting it.
- */
-
- if ((old_flags^ifr.ifr_flags)&IFF_UP) /* Bit is different ? */
- {
- if(old_flags&IFF_UP) /* Gone down */
- ret=dev_close(dev);
- else /* Come up */
- {
- ret=dev_open(dev);
- if(ret<0)
- dev->flags&=~IFF_UP; /* Open failed */
- }
- }
- else
- ret=0;
- /*
- * Load in the correct multicast list now the flags have changed.
- */
-
- dev_mc_upload(dev);
- }
- break;
-
- case SIOCGIFADDR: /* Get interface address (and family) */
- if(ifr.ifr_addr.sa_family==AF_UNSPEC)
- {
- memcpy(ifr.ifr_hwaddr.sa_data,dev->dev_addr, MAX_ADDR_LEN);
- ifr.ifr_hwaddr.sa_family=dev->type;
- goto rarok;
- }
- else
- {
- (*(struct sockaddr_in *)
- &ifr.ifr_addr).sin_addr.s_addr = dev->pa_addr;
- (*(struct sockaddr_in *)
- &ifr.ifr_addr).sin_family = dev->family;
- (*(struct sockaddr_in *)
- &ifr.ifr_addr).sin_port = 0;
- }
- goto rarok;
-
- case SIOCSIFADDR: /* Set interface address (and family) */
-
- /*
- * BSDism. SIOCSIFADDR family=AF_UNSPEC sets the
- * physical address. We can cope with this now.
- */
-
- if(ifr.ifr_addr.sa_family==AF_UNSPEC)
- {
- if(dev->set_mac_address==NULL)
- return -EOPNOTSUPP;
- ret=dev->set_mac_address(dev,&ifr.ifr_addr);
- }
- else
- {
-
- /*
- * if dev is an alias, must rehash to update
- * address change
- */
-
-#ifdef CONFIG_NET_ALIAS
- if (net_alias_is(dev))
- net_alias_dev_rehash(dev ,&ifr.ifr_addr);
-#endif
- dev->pa_addr = (*(struct sockaddr_in *)
- &ifr.ifr_addr).sin_addr.s_addr;
- dev->family = ifr.ifr_addr.sa_family;
-
-#ifdef CONFIG_INET
- /* This is naughty. When net-032e comes out It wants moving into the net032
- code not the kernel. Till then it can sit here (SIGH) */
- dev->pa_mask = ip_get_mask(dev->pa_addr);
-#endif
- dev->pa_brdaddr = dev->pa_addr | ~dev->pa_mask;
- ret = 0;
- }
- break;
-
- case SIOCGIFBRDADDR: /* Get the broadcast address */
- (*(struct sockaddr_in *)
- &ifr.ifr_broadaddr).sin_addr.s_addr = dev->pa_brdaddr;
- (*(struct sockaddr_in *)
- &ifr.ifr_broadaddr).sin_family = dev->family;
- (*(struct sockaddr_in *)
- &ifr.ifr_broadaddr).sin_port = 0;
- goto rarok;
-
- case SIOCSIFBRDADDR: /* Set the broadcast address */
- dev->pa_brdaddr = (*(struct sockaddr_in *)
- &ifr.ifr_broadaddr).sin_addr.s_addr;
- ret = 0;
- break;
-
- case SIOCGIFDSTADDR: /* Get the destination address (for point-to-point links) */
- (*(struct sockaddr_in *)
- &ifr.ifr_dstaddr).sin_addr.s_addr = dev->pa_dstaddr;
- (*(struct sockaddr_in *)
- &ifr.ifr_dstaddr).sin_family = dev->family;
- (*(struct sockaddr_in *)
- &ifr.ifr_dstaddr).sin_port = 0;
- goto rarok;
-
- case SIOCSIFDSTADDR: /* Set the destination address (for point-to-point links) */
- dev->pa_dstaddr = (*(struct sockaddr_in *)
- &ifr.ifr_dstaddr).sin_addr.s_addr;
- ret = 0;
- break;
-
- case SIOCGIFNETMASK: /* Get the netmask for the interface */
- (*(struct sockaddr_in *)
- &ifr.ifr_netmask).sin_addr.s_addr = dev->pa_mask;
- (*(struct sockaddr_in *)
- &ifr.ifr_netmask).sin_family = dev->family;
- (*(struct sockaddr_in *)
- &ifr.ifr_netmask).sin_port = 0;
- goto rarok;
-
- case SIOCSIFNETMASK: /* Set the netmask for the interface */
- {
- unsigned long mask = (*(struct sockaddr_in *)
- &ifr.ifr_netmask).sin_addr.s_addr;
- ret = -EINVAL;
- /*
- * The mask we set must be legal.
- */
- if (bad_mask(mask,0))
- break;
- dev->pa_mask = mask;
- ret = 0;
- }
- break;
-
- case SIOCGIFMETRIC: /* Get the metric on the interface (currently unused) */
-
- ifr.ifr_metric = dev->metric;
- goto rarok;
-
- case SIOCSIFMETRIC: /* Set the metric on the interface (currently unused) */
- dev->metric = ifr.ifr_metric;
- ret=0;
- break;
-
- case SIOCGIFMTU: /* Get the MTU of a device */
- ifr.ifr_mtu = dev->mtu;
- goto rarok;
-
- case SIOCSIFMTU: /* Set the MTU of a device */
-
- /*
- * MTU must be positive.
- */
-
- if(ifr.ifr_mtu<68)
- return -EINVAL;
- dev->mtu = ifr.ifr_mtu;
- ret = 0;
- break;
-
- case SIOCGIFMEM: /* Get the per device memory space. We can add this but currently
- do not support it */
- ret = -EINVAL;
- break;
-
- case SIOCSIFMEM: /* Set the per device memory buffer space. Not applicable in our case */
- ret = -EINVAL;
- break;
-
- case SIOCGIFHWADDR:
- memcpy(ifr.ifr_hwaddr.sa_data,dev->dev_addr, MAX_ADDR_LEN);
- ifr.ifr_hwaddr.sa_family=dev->type;
- goto rarok;
-
- case SIOCSIFHWADDR:
- if(dev->set_mac_address==NULL)
- return -EOPNOTSUPP;
- if(ifr.ifr_hwaddr.sa_family!=dev->type)
- return -EINVAL;
- ret=dev->set_mac_address(dev,&ifr.ifr_hwaddr);
- break;
-
- case SIOCGIFMAP:
- ifr.ifr_map.mem_start=dev->mem_start;
- ifr.ifr_map.mem_end=dev->mem_end;
- ifr.ifr_map.base_addr=dev->base_addr;
- ifr.ifr_map.irq=dev->irq;
- ifr.ifr_map.dma=dev->dma;
- ifr.ifr_map.port=dev->if_port;
- goto rarok;
-
- case SIOCSIFMAP:
- if(dev->set_config==NULL)
- return -EOPNOTSUPP;
- return dev->set_config(dev,&ifr.ifr_map);
-
- case SIOCADDMULTI:
- if(dev->set_multicast_list==NULL)
- return -EINVAL;
- if(ifr.ifr_hwaddr.sa_family!=AF_UNSPEC)
- return -EINVAL;
- dev_mc_add(dev,ifr.ifr_hwaddr.sa_data, dev->addr_len, 1);
- return 0;
-
- case SIOCDELMULTI:
- if(dev->set_multicast_list==NULL)
- return -EINVAL;
- if(ifr.ifr_hwaddr.sa_family!=AF_UNSPEC)
- return -EINVAL;
- dev_mc_delete(dev,ifr.ifr_hwaddr.sa_data,dev->addr_len, 1);
- return 0;
- /*
- * Unknown or private ioctl
- */
-
- default:
- if((getset >= SIOCDEVPRIVATE) &&
- (getset <= (SIOCDEVPRIVATE + 15))) {
- if(dev->do_ioctl==NULL)
- return -EOPNOTSUPP;
- ret=dev->do_ioctl(dev, &ifr, getset);
- memcpy_tofs(arg,&ifr,sizeof(struct ifreq));
- break;
- }
-
- ret = -EINVAL;
- }
- return(ret);
-/*
- * The load of calls that return an ifreq and ok (saves memory).
- */
-rarok:
- memcpy_tofs(arg, &ifr, sizeof(struct ifreq));
- return 0;
-}
-
-
-/*
- * This function handles all "interface"-type I/O control requests. The actual
- * 'doing' part of this is dev_ifsioc above.
- */
-
-int dev_ioctl(unsigned int cmd, void *arg)
-{
- switch(cmd)
- {
- case SIOCGIFCONF:
- (void) dev_ifconf((char *) arg);
- return 0;
-
- /*
- * Ioctl calls that can be done by all.
- */
-
- case SIOCGIFFLAGS:
- case SIOCGIFADDR:
- case SIOCGIFDSTADDR:
- case SIOCGIFBRDADDR:
- case SIOCGIFNETMASK:
- case SIOCGIFMETRIC:
- case SIOCGIFMTU:
- case SIOCGIFMEM:
- case SIOCGIFHWADDR:
- case SIOCSIFHWADDR:
- case SIOCGIFSLAVE:
- case SIOCGIFMAP:
- return dev_ifsioc(arg, cmd);
-
- /*
- * Ioctl calls requiring the power of a superuser
- */
-
- case SIOCSIFFLAGS:
- case SIOCSIFADDR:
- case SIOCSIFDSTADDR:
- case SIOCSIFBRDADDR:
- case SIOCSIFNETMASK:
- case SIOCSIFMETRIC:
- case SIOCSIFMTU:
- case SIOCSIFMEM:
- case SIOCSIFMAP:
- case SIOCSIFSLAVE:
- case SIOCADDMULTI:
- case SIOCDELMULTI:
- if (!suser())
- return -EPERM;
- return dev_ifsioc(arg, cmd);
-
- case SIOCSIFLINK:
- return -EINVAL;
-
- /*
- * Unknown or private ioctl.
- */
-
- default:
- if((cmd >= SIOCDEVPRIVATE) &&
- (cmd <= (SIOCDEVPRIVATE + 15))) {
- return dev_ifsioc(arg, cmd);
- }
- return -EINVAL;
- }
-}
-#endif /* ! MACH */
-
-/*
- * Initialize the DEV module. At boot time this walks the device list and
- * unhooks any devices that fail to initialise (normally hardware not
- * present) and leaves us with a valid list of present and active devices.
- *
- */
-extern int lance_init(void);
-extern int pi_init(void);
-extern int dec21040_init(void);
-
-int net_dev_init(void)
-{
- struct device *dev, **dp;
-
-#ifndef MACH
- /*
- * Initialise the packet receive queue.
- */
-
- skb_queue_head_init(&backlog);
-#endif
-
- /*
- * This is VeryUgly(tm).
- *
- * Some devices want to be initialized eary..
- */
-#if defined(CONFIG_LANCE)
- lance_init();
-#endif
-#if defined(CONFIG_PI)
- pi_init();
-#endif
-#if defined(CONFIG_PT)
- pt_init();
-#endif
-#if defined(CONFIG_DEC_ELCP)
- dec21040_init();
-#endif
- /*
- * SLHC if present needs attaching so other people see it
- * even if not opened.
- */
-#if (defined(CONFIG_SLIP_COMPRESSED) || defined(CONFIG_PPP)) && defined(CONFIG_SLHC_BUILTIN)
- slhc_install();
-#endif
-
- /*
- * Add the devices.
- * If the call to dev->init fails, the dev is removed
- * from the chain disconnecting the device until the
- * next reboot.
- */
-
- dp = &dev_base;
- while ((dev = *dp) != NULL)
- {
- int i;
- for (i = 0; i < DEV_NUMBUFFS; i++) {
- skb_queue_head_init(dev->buffs + i);
- }
-
- if (dev->init && dev->init(dev))
- {
- /*
- * It failed to come up. Unhook it.
- */
- *dp = dev->next;
- }
- else
- {
- dp = &dev->next;
- }
- }
-
-#ifdef CONFIG_PROC_FS
- proc_net_register(&(struct proc_dir_entry) {
- PROC_NET_DEV, 3, "dev",
- S_IFREG | S_IRUGO, 1, 0, 0,
- 0, &proc_net_inode_operations,
- dev_get_info
- });
-#endif
-
- /*
- * Initialise net_alias engine
- *
- * - register net_alias device notifier
- * - register proc entries: /proc/net/alias_types
- * /proc/net/aliases
- */
-
-#ifdef CONFIG_NET_ALIAS
- net_alias_init();
-#endif
-
- bh_base[NET_BH].routine = net_bh;
- enable_bh(NET_BH);
- return 0;
-}
diff --git a/i386/i386at/gpl/linux/net/e2100.c b/i386/i386at/gpl/linux/net/e2100.c
deleted file mode 100644
index fb0f1de6..00000000
--- a/i386/i386at/gpl/linux/net/e2100.c
+++ /dev/null
@@ -1,456 +0,0 @@
-/* e2100.c: A Cabletron E2100 series ethernet driver for linux. */
-/*
- Written 1993-1994 by Donald Becker.
-
- Copyright 1994 by Donald Becker.
- Copyright 1993 United States Government as represented by the
- Director, National Security Agency. This software may be used and
- distributed according to the terms of the GNU Public License,
- incorporated herein by reference.
-
- This is a driver for the Cabletron E2100 series ethercards.
-
- The Author may be reached as becker@cesdis.gsfc.nasa.gov, or
- C/O Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
-
- The E2100 series ethercard is a fairly generic shared memory 8390
- implementation. The only unusual aspect is the way the shared memory
- registers are set: first you do an inb() in what is normally the
- station address region, and the low three bits of next outb() *address*
- is used as the write value for that register. Either someone wasn't
- too used to dem bit en bites, or they were trying to obfuscate the
- programming interface.
-
- There is an additional complication when setting the window on the packet
- buffer. You must first do a read into the packet buffer region with the
- low 8 address bits the address setting the page for the start of the packet
- buffer window, and then do the above operation. See mem_on() for details.
-
- One bug on the chip is that even a hard reset won't disable the memory
- window, usually resulting in a hung machine if mem_off() isn't called.
- If this happens, you must power down the machine for about 30 seconds.
-*/
-
-static const char *version =
- "e2100.c:v1.01 7/21/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-
-#include <asm/io.h>
-#include <asm/system.h>
-
-#include "8390.h"
-
-static int e21_probe_list[] = {0x300, 0x280, 0x380, 0x220, 0};
-
-/* Offsets from the base_addr.
- Read from the ASIC register, and the low three bits of the next outb()
- address is used to set the corresponding register. */
-#define E21_NIC_OFFSET 0 /* Offset to the 8390 NIC. */
-#define E21_ASIC 0x10
-#define E21_MEM_ENABLE 0x10
-#define E21_MEM_ON 0x05 /* Enable memory in 16 bit mode. */
-#define E21_MEM_ON_8 0x07 /* Enable memory in 8 bit mode. */
-#define E21_MEM_BASE 0x11
-#define E21_IRQ_LOW 0x12 /* The low three bits of the IRQ number. */
-#define E21_IRQ_HIGH 0x14 /* The high IRQ bit and media select ... */
-#define E21_MEDIA 0x14 /* (alias). */
-#define E21_ALT_IFPORT 0x02 /* Set to use the other (BNC,AUI) port. */
-#define E21_BIG_MEM 0x04 /* Use a bigger (64K) buffer (we don't) */
-#define E21_SAPROM 0x10 /* Offset to station address data. */
-#define E21_IO_EXTENT 0x20
-
-extern inline void mem_on(short port, volatile char *mem_base,
- unsigned char start_page )
-{
- /* This is a little weird: set the shared memory window by doing a
- read. The low address bits specify the starting page. */
- mem_base[start_page];
- inb(port + E21_MEM_ENABLE);
- outb(E21_MEM_ON, port + E21_MEM_ENABLE + E21_MEM_ON);
-}
-
-extern inline void mem_off(short port)
-{
- inb(port + E21_MEM_ENABLE);
- outb(0x00, port + E21_MEM_ENABLE);
-}
-
-/* In other drivers I put the TX pages first, but the E2100 window circuitry
- is designed to have a 4K Tx region last. The windowing circuitry wraps the
- window at 0x2fff->0x0000 so that the packets at e.g. 0x2f00 in the RX ring
- appear contiguously in the window. */
-#define E21_RX_START_PG 0x00 /* First page of RX buffer */
-#define E21_RX_STOP_PG 0x30 /* Last page +1 of RX ring */
-#define E21_BIG_RX_STOP_PG 0xF0 /* Last page +1 of RX ring */
-#define E21_TX_START_PG E21_RX_STOP_PG /* First page of TX buffer */
-
-int e2100_probe(struct device *dev);
-int e21_probe1(struct device *dev, int ioaddr);
-
-static int e21_open(struct device *dev);
-static void e21_reset_8390(struct device *dev);
-static void e21_block_input(struct device *dev, int count,
- struct sk_buff *skb, int ring_offset);
-static void e21_block_output(struct device *dev, int count,
- const unsigned char *buf, const start_page);
-static void e21_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr,
- int ring_page);
-
-static int e21_close(struct device *dev);
-
-
-/* Probe for the E2100 series ethercards. These cards have an 8390 at the
- base address and the station address at both offset 0x10 and 0x18. I read
- the station address from offset 0x18 to avoid the dataport of NE2000
- ethercards, and look for Ctron's unique ID (first three octets of the
- station address).
- */
-
-int e2100_probe(struct device *dev)
-{
- int *port;
- int base_addr = dev->base_addr;
-
- if (base_addr > 0x1ff) /* Check a single specified location. */
- return e21_probe1(dev, base_addr);
- else if (base_addr != 0) /* Don't probe at all. */
- return ENXIO;
-
- for (port = e21_probe_list; *port; port++) {
- if (check_region(*port, E21_IO_EXTENT))
- continue;
- if (e21_probe1(dev, *port) == 0)
- return 0;
- }
-
- return ENODEV;
-}
-
-int e21_probe1(struct device *dev, int ioaddr)
-{
- int i, status;
- unsigned char *station_addr = dev->dev_addr;
- static unsigned version_printed = 0;
-
- /* First check the station address for the Ctron prefix. */
- if (inb(ioaddr + E21_SAPROM + 0) != 0x00
- || inb(ioaddr + E21_SAPROM + 1) != 0x00
- || inb(ioaddr + E21_SAPROM + 2) != 0x1d)
- return ENODEV;
-
- /* Verify by making certain that there is a 8390 at there. */
- outb(E8390_NODMA + E8390_STOP, ioaddr);
- SLOW_DOWN_IO;
- status = inb(ioaddr);
- if (status != 0x21 && status != 0x23)
- return ENODEV;
-
- /* Read the station address PROM. */
- for (i = 0; i < 6; i++)
- station_addr[i] = inb(ioaddr + E21_SAPROM + i);
-
- inb(ioaddr + E21_MEDIA); /* Point to media selection. */
- outb(0, ioaddr + E21_ASIC); /* and disable the secondary interface. */
-
- if (ei_debug && version_printed++ == 0)
- printk(version);
-
- /* We should have a "dev" from Space.c or the static module table. */
- if (dev == NULL) {
- printk("e2100.c: Passed a NULL device.\n");
- dev = init_etherdev(0, 0);
- }
-
- printk("%s: E21** at %#3x,", dev->name, ioaddr);
- for (i = 0; i < 6; i++)
- printk(" %02X", station_addr[i]);
-
- if (dev->irq < 2) {
- int irqlist[] = {15,11,10,12,5,9,3,4}, i;
- for (i = 0; i < 8; i++)
- if (request_irq (irqlist[i], NULL, 0, "bogus") != -EBUSY) {
- dev->irq = irqlist[i];
- break;
- }
- if (i >= 8) {
- printk(" unable to get IRQ %d.\n", dev->irq);
- return EAGAIN;
- }
- } else if (dev->irq == 2) /* Fixup luser bogosity: IRQ2 is really IRQ9 */
- dev->irq = 9;
-
- /* Allocate dev->priv and fill in 8390 specific dev fields. */
- if (ethdev_init(dev)) {
- printk (" unable to get memory for dev->priv.\n");
- return -ENOMEM;
- }
-
- /* Grab the region so we can find a different board if IRQ select fails. */
- request_region(ioaddr, E21_IO_EXTENT, "e2100");
-
- /* The 8390 is at the base address. */
- dev->base_addr = ioaddr;
-
- ei_status.name = "E2100";
- ei_status.word16 = 1;
- ei_status.tx_start_page = E21_TX_START_PG;
- ei_status.rx_start_page = E21_RX_START_PG;
- ei_status.stop_page = E21_RX_STOP_PG;
- ei_status.saved_irq = dev->irq;
-
- /* Check the media port used. The port can be passed in on the
- low mem_end bits. */
- if (dev->mem_end & 15)
- dev->if_port = dev->mem_end & 7;
- else {
- dev->if_port = 0;
- inb(ioaddr + E21_MEDIA); /* Turn automatic media detection on. */
- for(i = 0; i < 6; i++)
- if (station_addr[i] != inb(ioaddr + E21_SAPROM + 8 + i)) {
- dev->if_port = 1;
- break;
- }
- }
-
- /* Never map in the E21 shared memory unless you are actively using it.
- Also, the shared memory has effective only one setting -- spread all
- over the 128K region! */
- if (dev->mem_start == 0)
- dev->mem_start = 0xd0000;
-
-#ifdef notdef
- /* These values are unused. The E2100 has a 2K window into the packet
- buffer. The window can be set to start on any page boundary. */
- dev->rmem_start = dev->mem_start + TX_PAGES*256;
- dev->mem_end = dev->rmem_end = dev->mem_start + 2*1024;
-#endif
-
- printk(", IRQ %d, %s media, memory @ %#lx.\n", dev->irq,
- dev->if_port ? "secondary" : "primary", dev->mem_start);
-
- ei_status.reset_8390 = &e21_reset_8390;
- ei_status.block_input = &e21_block_input;
- ei_status.block_output = &e21_block_output;
- ei_status.get_8390_hdr = &e21_get_8390_hdr;
- dev->open = &e21_open;
- dev->stop = &e21_close;
- NS8390_init(dev, 0);
-
- return 0;
-}
-
-static int
-e21_open(struct device *dev)
-{
- short ioaddr = dev->base_addr;
-
- if (request_irq(dev->irq, ei_interrupt, 0, "e2100")) {
- return EBUSY;
- }
- irq2dev_map[dev->irq] = dev;
-
- /* Set the interrupt line and memory base on the hardware. */
- inb(ioaddr + E21_IRQ_LOW);
- outb(0, ioaddr + E21_ASIC + (dev->irq & 7));
- inb(ioaddr + E21_IRQ_HIGH); /* High IRQ bit, and if_port. */
- outb(0, ioaddr + E21_ASIC + (dev->irq > 7 ? 1:0)
- + (dev->if_port ? E21_ALT_IFPORT : 0));
- inb(ioaddr + E21_MEM_BASE);
- outb(0, ioaddr + E21_ASIC + ((dev->mem_start >> 17) & 7));
-
- ei_open(dev);
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-static void
-e21_reset_8390(struct device *dev)
-{
- short ioaddr = dev->base_addr;
-
- outb(0x01, ioaddr);
- if (ei_debug > 1) printk("resetting the E2180x3 t=%ld...", jiffies);
- ei_status.txing = 0;
-
- /* Set up the ASIC registers, just in case something changed them. */
-
- if (ei_debug > 1) printk("reset done\n");
- return;
-}
-
-/* Grab the 8390 specific header. We put the 2k window so the header page
- appears at the start of the shared memory. */
-
-static void
-e21_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
-{
-
- short ioaddr = dev->base_addr;
- char *shared_mem = (char *)dev->mem_start;
-
- mem_on(ioaddr, shared_mem, ring_page);
-
-#ifdef notdef
- /* Officially this is what we are doing, but the readl() is faster */
- memcpy_fromio(hdr, shared_mem, sizeof(struct e8390_pkt_hdr));
-#else
- ((unsigned int*)hdr)[0] = readl(shared_mem);
-#endif
-
- /* Turn off memory access: we would need to reprogram the window anyway. */
- mem_off(ioaddr);
-
-}
-
-/* Block input and output are easy on shared memory ethercards.
- The E21xx makes block_input() especially easy by wrapping the top
- ring buffer to the bottom automatically. */
-static void
-e21_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset)
-{
- short ioaddr = dev->base_addr;
- char *shared_mem = (char *)dev->mem_start;
-
- mem_on(ioaddr, shared_mem, (ring_offset>>8));
-
- /* Packet is always in one chunk -- we can copy + cksum. */
- eth_io_copy_and_sum(skb, dev->mem_start + (ring_offset & 0xff), count, 0);
-
- mem_off(ioaddr);
-}
-
-static void
-e21_block_output(struct device *dev, int count, const unsigned char *buf,
- int start_page)
-{
- short ioaddr = dev->base_addr;
- volatile char *shared_mem = (char *)dev->mem_start;
-
- /* Set the shared memory window start by doing a read, with the low address
- bits specifying the starting page. */
- readb(shared_mem + start_page);
- mem_on(ioaddr, shared_mem, start_page);
-
- memcpy_toio(shared_mem, buf, count);
- mem_off(ioaddr);
-}
-
-static int
-e21_close(struct device *dev)
-{
- short ioaddr = dev->base_addr;
-
- if (ei_debug > 1)
- printk("%s: Shutting down ethercard.\n", dev->name);
-
- free_irq(dev->irq);
- dev->irq = ei_status.saved_irq;
-
- /* Shut off the interrupt line and secondary interface. */
- inb(ioaddr + E21_IRQ_LOW);
- outb(0, ioaddr + E21_ASIC);
- inb(ioaddr + E21_IRQ_HIGH); /* High IRQ bit, and if_port. */
- outb(0, ioaddr + E21_ASIC);
-
- irq2dev_map[dev->irq] = NULL;
-
- ei_close(dev);
-
- /* Double-check that the memory has been turned off, because really
- really bad things happen if it isn't. */
- mem_off(ioaddr);
-
- MOD_DEC_USE_COUNT;
-
- return 0;
-}
-
-#ifdef HAVE_DEVLIST
-struct netdev_entry e21_drv =
-{"e21", e21_probe1, E21_IO_EXTENT, e21_probe_list};
-#endif
-
-
-#ifdef MODULE
-#define MAX_E21_CARDS 4 /* Max number of E21 cards per module */
-#define NAMELEN 8 /* # of chars for storing dev->name */
-static char namelist[NAMELEN * MAX_E21_CARDS] = { 0, };
-static struct device dev_e21[MAX_E21_CARDS] = {
- {
- NULL, /* assign a chunk of namelist[] below */
- 0, 0, 0, 0,
- 0, 0,
- 0, 0, 0, NULL, NULL
- },
-};
-
-static int io[MAX_E21_CARDS] = { 0, };
-static int irq[MAX_E21_CARDS] = { 0, };
-static int mem[MAX_E21_CARDS] = { 0, };
-static int xcvr[MAX_E21_CARDS] = { 0, }; /* choose int. or ext. xcvr */
-
-/* This is set up so that only a single autoprobe takes place per call.
-ISA device autoprobes on a running machine are not recommended. */
-int
-init_module(void)
-{
- int this_dev, found = 0;
-
- for (this_dev = 0; this_dev < MAX_E21_CARDS; this_dev++) {
- struct device *dev = &dev_e21[this_dev];
- dev->name = namelist+(NAMELEN*this_dev);
- dev->irq = irq[this_dev];
- dev->base_addr = io[this_dev];
- dev->mem_start = mem[this_dev];
- dev->mem_end = xcvr[this_dev]; /* low 4bits = xcvr sel. */
- dev->init = e2100_probe;
- if (io[this_dev] == 0) {
- if (this_dev != 0) break; /* only autoprobe 1st one */
- printk(KERN_NOTICE "e2100.c: Presently autoprobing (not recommended) for a single card.\n");
- }
- if (register_netdev(dev) != 0) {
- printk(KERN_WARNING "e2100.c: No E2100 card found (i/o = 0x%x).\n", io[this_dev]);
- if (found != 0) return 0; /* Got at least one. */
- return -ENXIO;
- }
- found++;
- }
-
- return 0;
-}
-
-void
-cleanup_module(void)
-{
- int this_dev;
-
- for (this_dev = 0; this_dev < MAX_E21_CARDS; this_dev++) {
- struct device *dev = &dev_e21[this_dev];
- if (dev->priv != NULL) {
- /* NB: e21_close() handles free_irq + irq2dev map */
- kfree(dev->priv);
- dev->priv = NULL;
- release_region(dev->base_addr, E21_IO_EXTENT);
- unregister_netdev(dev);
- }
- }
-}
-#endif /* MODULE */
-
-/*
- * Local variables:
- * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c e2100.c"
- * version-control: t
- * tab-width: 4
- * kept-new-versions: 5
- * End:
- */
diff --git a/i386/i386at/gpl/linux/net/eepro.c b/i386/i386at/gpl/linux/net/eepro.c
deleted file mode 100644
index 2aa2bd14..00000000
--- a/i386/i386at/gpl/linux/net/eepro.c
+++ /dev/null
@@ -1,1169 +0,0 @@
-/* eepro.c: Intel EtherExpress Pro/10 device driver for Linux. */
-/*
- Written 1994, 1995 by Bao C. Ha.
-
- Copyright (C) 1994, 1995 by Bao C. Ha.
-
- This software may be used and distributed
- according to the terms of the GNU Public License,
- incorporated herein by reference.
-
- The author may be reached at bao@saigon.async.com
- or 418 Hastings Place, Martinez, GA 30907.
-
- Things remaining to do:
- Better record keeping of errors.
- Eliminate transmit interrupt to reduce overhead.
- Implement "concurrent processing". I won't be doing it!
- Allow changes to the partition of the transmit and receive
- buffers, currently the ratio is 3:1 of receive to transmit
- buffer ratio.
-
- Bugs:
-
- If you have a problem of not detecting the 82595 during a
- reboot (warm reset), disable the FLASH memory should fix it.
- This is a compatibility hardware problem.
-
- Versions:
-
- 0.07a Fix a stat report which counts every packet as a
- heart-beat failure. (BCH, 6/3/95)
-
- 0.07 Modified to support all other 82595-based lan cards.
- The IRQ vector of the EtherExpress Pro will be set
- according to the value saved in the EEPROM. For other
- cards, I will do autoirq_request() to grab the next
- available interrupt vector. (BCH, 3/17/95)
-
- 0.06a,b Interim released. Minor changes in the comments and
- print out format. (BCH, 3/9/95 and 3/14/95)
-
- 0.06 First stable release that I am comfortable with. (BCH,
- 3/2/95)
-
- 0.05 Complete testing of multicast. (BCH, 2/23/95)
-
- 0.04 Adding multicast support. (BCH, 2/14/95)
-
- 0.03 First widely alpha release for public testing.
- (BCH, 2/14/95)
-
-*/
-
-static const char *version =
- "eepro.c: v0.07a 6/5/95 Bao C. Ha (bao@saigon.async.com)\n";
-
-#include <linux/module.h>
-
-/*
- Sources:
-
- This driver wouldn't have been written without the availability
- of the Crynwr's Lan595 driver source code. It helps me to
- familiarize with the 82595 chipset while waiting for the Intel
- documentation. I also learned how to detect the 82595 using
- the packet driver's technique.
-
- This driver is written by cutting and pasting the skeleton.c driver
- provided by Donald Becker. I also borrowed the EEPROM routine from
- Donald Becker's 82586 driver.
-
- Datasheet for the Intel 82595. It provides just enough info that
- the casual reader might think that it documents the i82595.
-
- The User Manual for the 82595. It provides a lot of the missing
- information.
-
-*/
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ptrace.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/malloc.h>
-#include <linux/string.h>
-#include <asm/system.h>
-#include <asm/bitops.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <linux/errno.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-
-
-/* First, a few definitions that the brave might change. */
-/* A zero-terminated list of I/O addresses to be probed. */
-static unsigned int eepro_portlist[] =
- { 0x200, 0x240, 0x280, 0x2C0, 0x300, 0x320, 0x340, 0x360, 0};
-
-/* use 0 for production, 1 for verification, >2 for debug */
-#ifndef NET_DEBUG
-#define NET_DEBUG 2
-#endif
-static unsigned int net_debug = NET_DEBUG;
-
-/* The number of low I/O ports used by the ethercard. */
-#define EEPRO_IO_EXTENT 16
-
-/* Information that need to be kept for each board. */
-struct eepro_local {
- struct enet_statistics stats;
- unsigned rx_start;
- unsigned tx_start; /* start of the transmit chain */
- int tx_last; /* pointer to last packet in the transmit chain */
- unsigned tx_end; /* end of the transmit chain (plus 1) */
- int eepro; /* a flag, TRUE=1 for the EtherExpress Pro/10,
- FALSE = 0 for other 82595-based lan cards. */
-};
-
-/* The station (ethernet) address prefix, used for IDing the board. */
-#define SA_ADDR0 0x00
-#define SA_ADDR1 0xaa
-#define SA_ADDR2 0x00
-
-/* Index to functions, as function prototypes. */
-
-extern int eepro_probe(struct device *dev);
-
-static int eepro_probe1(struct device *dev, short ioaddr);
-static int eepro_open(struct device *dev);
-static int eepro_send_packet(struct sk_buff *skb, struct device *dev);
-static void eepro_interrupt(int irq, struct pt_regs *regs);
-static void eepro_rx(struct device *dev);
-static void eepro_transmit_interrupt(struct device *dev);
-static int eepro_close(struct device *dev);
-static struct enet_statistics *eepro_get_stats(struct device *dev);
-static void set_multicast_list(struct device *dev);
-
-static int read_eeprom(int ioaddr, int location);
-static void hardware_send_packet(struct device *dev, void *buf, short length);
-static int eepro_grab_irq(struct device *dev);
-
-/*
- Details of the i82595.
-
-You will need either the datasheet or the user manual to understand what
-is going on here. The 82595 is very different from the 82586, 82593.
-
-The receive algorithm in eepro_rx() is just an implementation of the
-RCV ring structure that the Intel 82595 imposes at the hardware level.
-The receive buffer is set at 24K, and the transmit buffer is 8K. I
-am assuming that the total buffer memory is 32K, which is true for the
-Intel EtherExpress Pro/10. If it is less than that on a generic card,
-the driver will be broken.
-
-The transmit algorithm in the hardware_send_packet() is similar to the
-one in the eepro_rx(). The transmit buffer is a ring linked list.
-I just queue the next available packet to the end of the list. In my
-system, the 82595 is so fast that the list seems to always contain a
-single packet. In other systems with faster computers and more congested
-network traffics, the ring linked list should improve performance by
-allowing up to 8K worth of packets to be queued.
-
-*/
-#define RAM_SIZE 0x8000
-#define RCV_HEADER 8
-#define RCV_RAM 0x6000 /* 24KB for RCV buffer */
-#define RCV_LOWER_LIMIT 0x00 /* 0x0000 */
-#define RCV_UPPER_LIMIT ((RCV_RAM - 2) >> 8) /* 0x5ffe */
-#define XMT_RAM (RAM_SIZE - RCV_RAM) /* 8KB for XMT buffer */
-#define XMT_LOWER_LIMIT (RCV_RAM >> 8) /* 0x6000 */
-#define XMT_UPPER_LIMIT ((RAM_SIZE - 2) >> 8) /* 0x7ffe */
-#define XMT_HEADER 8
-
-#define RCV_DONE 0x0008
-#define RX_OK 0x2000
-#define RX_ERROR 0x0d81
-
-#define TX_DONE_BIT 0x0080
-#define CHAIN_BIT 0x8000
-#define XMT_STATUS 0x02
-#define XMT_CHAIN 0x04
-#define XMT_COUNT 0x06
-
-#define BANK0_SELECT 0x00
-#define BANK1_SELECT 0x40
-#define BANK2_SELECT 0x80
-
-/* Bank 0 registers */
-#define COMMAND_REG 0x00 /* Register 0 */
-#define MC_SETUP 0x03
-#define XMT_CMD 0x04
-#define DIAGNOSE_CMD 0x07
-#define RCV_ENABLE_CMD 0x08
-#define RCV_DISABLE_CMD 0x0a
-#define STOP_RCV_CMD 0x0b
-#define RESET_CMD 0x0e
-#define POWER_DOWN_CMD 0x18
-#define RESUME_XMT_CMD 0x1c
-#define SEL_RESET_CMD 0x1e
-#define STATUS_REG 0x01 /* Register 1 */
-#define RX_INT 0x02
-#define TX_INT 0x04
-#define EXEC_STATUS 0x30
-#define ID_REG 0x02 /* Register 2 */
-#define R_ROBIN_BITS 0xc0 /* round robin counter */
-#define ID_REG_MASK 0x2c
-#define ID_REG_SIG 0x24
-#define AUTO_ENABLE 0x10
-#define INT_MASK_REG 0x03 /* Register 3 */
-#define RX_STOP_MASK 0x01
-#define RX_MASK 0x02
-#define TX_MASK 0x04
-#define EXEC_MASK 0x08
-#define ALL_MASK 0x0f
-#define RCV_BAR 0x04 /* The following are word (16-bit) registers */
-#define RCV_STOP 0x06
-#define XMT_BAR 0x0a
-#define HOST_ADDRESS_REG 0x0c
-#define IO_PORT 0x0e
-
-/* Bank 1 registers */
-#define REG1 0x01
-#define WORD_WIDTH 0x02
-#define INT_ENABLE 0x80
-#define INT_NO_REG 0x02
-#define RCV_LOWER_LIMIT_REG 0x08
-#define RCV_UPPER_LIMIT_REG 0x09
-#define XMT_LOWER_LIMIT_REG 0x0a
-#define XMT_UPPER_LIMIT_REG 0x0b
-
-/* Bank 2 registers */
-#define XMT_Chain_Int 0x20 /* Interrupt at the end of the transmit chain */
-#define XMT_Chain_ErrStop 0x40 /* Interrupt at the end of the chain even if there are errors */
-#define RCV_Discard_BadFrame 0x80 /* Throw bad frames away, and continue to receive others */
-#define REG2 0x02
-#define PRMSC_Mode 0x01
-#define Multi_IA 0x20
-#define REG3 0x03
-#define TPE_BIT 0x04
-#define BNC_BIT 0x20
-
-#define I_ADD_REG0 0x04
-#define I_ADD_REG1 0x05
-#define I_ADD_REG2 0x06
-#define I_ADD_REG3 0x07
-#define I_ADD_REG4 0x08
-#define I_ADD_REG5 0x09
-
-#define EEPROM_REG 0x0a
-#define EESK 0x01
-#define EECS 0x02
-#define EEDI 0x04
-#define EEDO 0x08
-
-
-/* Check for a network adaptor of this type, and return '0' iff one exists.
- If dev->base_addr == 0, probe all likely locations.
- If dev->base_addr == 1, always return failure.
- If dev->base_addr == 2, allocate space for the device and return success
- (detachable devices only).
- */
-#ifdef HAVE_DEVLIST
-/* Support for a alternate probe manager, which will eliminate the
- boilerplate below. */
-struct netdev_entry netcard_drv =
-{"eepro", eepro_probe1, EEPRO_IO_EXTENT, eepro_portlist};
-#else
-int
-eepro_probe(struct device *dev)
-{
- int i;
- int base_addr = dev ? dev->base_addr : 0;
-
- if (base_addr > 0x1ff) /* Check a single specified location. */
- return eepro_probe1(dev, base_addr);
- else if (base_addr != 0) /* Don't probe at all. */
- return ENXIO;
-
- for (i = 0; eepro_portlist[i]; i++) {
- int ioaddr = eepro_portlist[i];
- if (check_region(ioaddr, EEPRO_IO_EXTENT))
- continue;
- if (eepro_probe1(dev, ioaddr) == 0)
- return 0;
- }
-
- return ENODEV;
-}
-#endif
-
-/* This is the real probe routine. Linux has a history of friendly device
- probes on the ISA bus. A good device probes avoids doing writes, and
- verifies that the correct device exists and functions. */
-
-int eepro_probe1(struct device *dev, short ioaddr)
-{
- unsigned short station_addr[6], id, counter;
- int i;
- int eepro; /* a flag, TRUE=1 for the EtherExpress Pro/10,
- FALSE = 0 for other 82595-based lan cards. */
- const char *ifmap[] = {"AUI", "10Base2", "10BaseT"};
- enum iftype { AUI=0, BNC=1, TPE=2 };
-
- /* Now, we are going to check for the signature of the
- ID_REG (register 2 of bank 0) */
-
- if (((id=inb(ioaddr + ID_REG)) & ID_REG_MASK) == ID_REG_SIG) {
-
- /* We seem to have the 82595 signature, let's
- play with its counter (last 2 bits of
- register 2 of bank 0) to be sure. */
-
- counter = (id & R_ROBIN_BITS);
- if (((id=inb(ioaddr+ID_REG)) & R_ROBIN_BITS) ==
- (counter + 0x40)) {
-
- /* Yes, the 82595 has been found */
-
- /* Now, get the ethernet hardware address from
- the EEPROM */
-
- station_addr[0] = read_eeprom(ioaddr, 2);
- station_addr[1] = read_eeprom(ioaddr, 3);
- station_addr[2] = read_eeprom(ioaddr, 4);
-
- /* Check the station address for the manufacturer's code */
-
- if (station_addr[2] != 0x00aa || (station_addr[1] & 0xff00) != 0x0000) {
- eepro = 0;
- printk("%s: Intel 82595-based lan card at %#x,",
- dev->name, ioaddr);
- }
- else {
- eepro = 1;
- printk("%s: Intel EtherExpress Pro/10 at %#x,",
- dev->name, ioaddr);
- }
-
- /* Fill in the 'dev' fields. */
- dev->base_addr = ioaddr;
-
- for (i=0; i < 6; i++) {
- dev->dev_addr[i] = ((unsigned char *) station_addr)[5-i];
- printk("%c%02x", i ? ':' : ' ', dev->dev_addr[i]);
- }
-
- outb(BANK2_SELECT, ioaddr); /* be CAREFUL, BANK 2 now */
- id = inb(ioaddr + REG3);
- if (id & TPE_BIT)
- dev->if_port = TPE;
- else dev->if_port = BNC;
-
- if (dev->irq < 2 && eepro) {
- i = read_eeprom(ioaddr, 1);
- switch (i & 0x07) {
- case 0: dev->irq = 9; break;
- case 1: dev->irq = 3; break;
- case 2: dev->irq = 5; break;
- case 3: dev->irq = 10; break;
- case 4: dev->irq = 11; break;
- default: /* should never get here !!!!! */
- printk(" illegal interrupt vector stored in EEPROM.\n");
- return ENODEV;
- }
- }
- else if (dev->irq == 2)
- dev->irq = 9;
-
- if (dev->irq > 2) {
- printk(", IRQ %d, %s.\n", dev->irq,
- ifmap[dev->if_port]);
- if (request_irq(dev->irq, &eepro_interrupt, 0, "eepro")) {
- printk("%s: unable to get IRQ %d.\n", dev->name, dev->irq);
- return -EAGAIN;
- }
- }
- else printk(", %s.\n", ifmap[dev->if_port]);
-
- if ((dev->mem_start & 0xf) > 0)
- net_debug = dev->mem_start & 7;
-
- if (net_debug > 3) {
- i = read_eeprom(ioaddr, 5);
- if (i & 0x2000) /* bit 13 of EEPROM word 5 */
- printk("%s: Concurrent Processing is enabled but not used!\n",
- dev->name);
- }
-
- if (net_debug)
- printk(version);
-
- /* Grab the region so we can find another board if autoIRQ fails. */
- request_region(ioaddr, EEPRO_IO_EXTENT, "eepro");
-
- /* Initialize the device structure */
- dev->priv = kmalloc(sizeof(struct eepro_local), GFP_KERNEL);
- if (dev->priv == NULL)
- return -ENOMEM;
- memset(dev->priv, 0, sizeof(struct eepro_local));
-
- dev->open = eepro_open;
- dev->stop = eepro_close;
- dev->hard_start_xmit = eepro_send_packet;
- dev->get_stats = eepro_get_stats;
- dev->set_multicast_list = &set_multicast_list;
-
- /* Fill in the fields of the device structure with
- ethernet generic values */
-
- ether_setup(dev);
-
- outb(RESET_CMD, ioaddr); /* RESET the 82595 */
-
- return 0;
- }
- else return ENODEV;
- }
- else if (net_debug > 3)
- printk ("EtherExpress Pro probed failed!\n");
- return ENODEV;
-}
-
-/* Open/initialize the board. This is called (in the current kernel)
- sometime after booting when the 'ifconfig' program is run.
-
- This routine should set everything up anew at each open, even
- registers that "should" only need to be set once at boot, so that
- there is non-reboot way to recover if something goes wrong.
- */
-
-static char irqrmap[] = {-1,-1,0,1,-1,2,-1,-1,-1,0,3,4,-1,-1,-1,-1};
-static int eepro_grab_irq(struct device *dev)
-{
- int irqlist[] = { 5, 9, 10, 11, 4, 3, 0};
- int *irqp = irqlist, temp_reg, ioaddr = dev->base_addr;
-
- outb(BANK1_SELECT, ioaddr); /* be CAREFUL, BANK 1 now */
-
- /* Enable the interrupt line. */
- temp_reg = inb(ioaddr + REG1);
- outb(temp_reg | INT_ENABLE, ioaddr + REG1);
-
- outb(BANK0_SELECT, ioaddr); /* be CAREFUL, BANK 0 now */
-
- /* clear all interrupts */
- outb(ALL_MASK, ioaddr + STATUS_REG);
- /* Let EXEC event to interrupt */
- outb(ALL_MASK & ~(EXEC_MASK), ioaddr + INT_MASK_REG);
-
- do {
- outb(BANK1_SELECT, ioaddr); /* be CAREFUL, BANK 1 now */
-
- temp_reg = inb(ioaddr + INT_NO_REG);
- outb((temp_reg & 0xf8) | irqrmap[*irqp], ioaddr + INT_NO_REG);
-
- outb(BANK0_SELECT, ioaddr); /* Switch back to Bank 0 */
-
- if (request_irq (*irqp, NULL, 0, "bogus") != EBUSY) {
- /* Twinkle the interrupt, and check if it's seen */
- autoirq_setup(0);
-
- outb(DIAGNOSE_CMD, ioaddr); /* RESET the 82595 */
-
- if (*irqp == autoirq_report(2) && /* It's a good IRQ line */
- (request_irq(dev->irq = *irqp, &eepro_interrupt, 0, "eepro") == 0))
- break;
-
- /* clear all interrupts */
- outb(ALL_MASK, ioaddr + STATUS_REG);
- }
- } while (*++irqp);
-
- outb(BANK1_SELECT, ioaddr); /* Switch back to Bank 1 */
-
- /* Disable the physical interrupt line. */
- temp_reg = inb(ioaddr + REG1);
- outb(temp_reg & 0x7f, ioaddr + REG1);
-
- outb(BANK0_SELECT, ioaddr); /* Switch back to Bank 0 */
-
- /* Mask all the interrupts. */
- outb(ALL_MASK, ioaddr + INT_MASK_REG);
-
- /* clear all interrupts */
- outb(ALL_MASK, ioaddr + STATUS_REG);
-
- return dev->irq;
-}
-
-static int
-eepro_open(struct device *dev)
-{
- unsigned short temp_reg;
- int i, ioaddr = dev->base_addr;
- struct eepro_local *lp = (struct eepro_local *)dev->priv;
-
- if (net_debug > 3)
- printk("eepro: entering eepro_open routine.\n");
-
- if (dev->dev_addr[0] == SA_ADDR0 &&
- dev->dev_addr[1] == SA_ADDR1 &&
- dev->dev_addr[2] == SA_ADDR2)
- lp->eepro = 1; /* Yes, an Intel EtherExpress Pro/10 */
- else lp->eepro = 0; /* No, it is a generic 82585 lan card */
-
- /* Get the interrupt vector for the 82595 */
- if (dev->irq < 2 && eepro_grab_irq(dev) == 0) {
- printk("%s: unable to get IRQ %d.\n", dev->name, dev->irq);
- return -EAGAIN;
- }
-
- if (irq2dev_map[dev->irq] != 0
- || (irq2dev_map[dev->irq] = dev) == 0)
- return -EAGAIN;
-
- /* Initialize the 82595. */
-
- outb(BANK2_SELECT, ioaddr); /* be CAREFUL, BANK 2 now */
- temp_reg = inb(ioaddr + EEPROM_REG);
- if (temp_reg & 0x10) /* Check the TurnOff Enable bit */
- outb(temp_reg & 0xef, ioaddr + EEPROM_REG);
- for (i=0; i < 6; i++)
- outb(dev->dev_addr[i] , ioaddr + I_ADD_REG0 + i);
-
- temp_reg = inb(ioaddr + REG1); /* Setup Transmit Chaining */
- outb(temp_reg | XMT_Chain_Int | XMT_Chain_ErrStop /* and discard bad RCV frames */
- | RCV_Discard_BadFrame, ioaddr + REG1);
-
- temp_reg = inb(ioaddr + REG2); /* Match broadcast */
- outb(temp_reg | 0x14, ioaddr + REG2);
-
- temp_reg = inb(ioaddr + REG3);
- outb(temp_reg & 0x3f, ioaddr + REG3); /* clear test mode */
-
- /* Set the receiving mode */
- outb(BANK1_SELECT, ioaddr); /* be CAREFUL, BANK 1 now */
-
- temp_reg = inb(ioaddr + INT_NO_REG);
- outb((temp_reg & 0xf8) | irqrmap[dev->irq], ioaddr + INT_NO_REG);
-
- /* Initialize the RCV and XMT upper and lower limits */
- outb(RCV_LOWER_LIMIT, ioaddr + RCV_LOWER_LIMIT_REG);
- outb(RCV_UPPER_LIMIT, ioaddr + RCV_UPPER_LIMIT_REG);
- outb(XMT_LOWER_LIMIT, ioaddr + XMT_LOWER_LIMIT_REG);
- outb(XMT_UPPER_LIMIT, ioaddr + XMT_UPPER_LIMIT_REG);
-
- /* Enable the interrupt line. */
- temp_reg = inb(ioaddr + REG1);
- outb(temp_reg | INT_ENABLE, ioaddr + REG1);
-
- outb(BANK0_SELECT, ioaddr); /* Switch back to Bank 0 */
-
- /* Let RX and TX events to interrupt */
- outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG);
- /* clear all interrupts */
- outb(ALL_MASK, ioaddr + STATUS_REG);
-
- /* Initialize RCV */
- outw(RCV_LOWER_LIMIT << 8, ioaddr + RCV_BAR);
- lp->rx_start = (RCV_LOWER_LIMIT << 8) ;
- outw((RCV_UPPER_LIMIT << 8) | 0xfe, ioaddr + RCV_STOP);
-
- /* Initialize XMT */
- outw(XMT_LOWER_LIMIT << 8, ioaddr + XMT_BAR);
-
- outb(SEL_RESET_CMD, ioaddr);
- /* We are supposed to wait for 2 us after a SEL_RESET */
- SLOW_DOWN_IO;
- SLOW_DOWN_IO;
-
- lp->tx_start = lp->tx_end = XMT_LOWER_LIMIT << 8; /* or = RCV_RAM */
- lp->tx_last = 0;
-
- dev->tbusy = 0;
- dev->interrupt = 0;
- dev->start = 1;
-
- if (net_debug > 3)
- printk("eepro: exiting eepro_open routine.\n");
-
- outb(RCV_ENABLE_CMD, ioaddr);
-
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-static int
-eepro_send_packet(struct sk_buff *skb, struct device *dev)
-{
- struct eepro_local *lp = (struct eepro_local *)dev->priv;
- int ioaddr = dev->base_addr;
-
- if (net_debug > 5)
- printk("eepro: entering eepro_send_packet routine.\n");
-
- if (dev->tbusy) {
- /* If we get here, some higher level has decided we are broken.
- There should really be a "kick me" function call instead. */
- int tickssofar = jiffies - dev->trans_start;
- if (tickssofar < 5)
- return 1;
- if (net_debug > 1)
- printk("%s: transmit timed out, %s?\n", dev->name,
- "network cable problem");
- lp->stats.tx_errors++;
- /* Try to restart the adaptor. */
- outb(SEL_RESET_CMD, ioaddr);
- /* We are supposed to wait for 2 us after a SEL_RESET */
- SLOW_DOWN_IO;
- SLOW_DOWN_IO;
-
- /* Do I also need to flush the transmit buffers here? YES? */
- lp->tx_start = lp->tx_end = RCV_RAM;
- lp->tx_last = 0;
-
- dev->tbusy=0;
- dev->trans_start = jiffies;
-
- outb(RCV_ENABLE_CMD, ioaddr);
-
- }
-
- /* If some higher layer thinks we've missed an tx-done interrupt
- we are passed NULL. Caution: dev_tint() handles the cli()/sti()
- itself. */
- if (skb == NULL) {
- dev_tint(dev);
- return 0;
- }
-
- /* Block a timer-based transmit from overlapping. */
- if (set_bit(0, (void*)&dev->tbusy) != 0)
- printk("%s: Transmitter access conflict.\n", dev->name);
- else {
- short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
- unsigned char *buf = skb->data;
-
- hardware_send_packet(dev, buf, length);
- dev->trans_start = jiffies;
- }
-
- dev_kfree_skb (skb, FREE_WRITE);
-
- /* You might need to clean up and record Tx statistics here. */
- /* lp->stats.tx_aborted_errors++; */
-
- if (net_debug > 5)
- printk("eepro: exiting eepro_send_packet routine.\n");
-
- return 0;
-}
-
-
-/* The typical workload of the driver:
- Handle the network interface interrupts. */
-static void
-eepro_interrupt(int irq, struct pt_regs * regs)
-{
- struct device *dev = (struct device *)(irq2dev_map[irq]);
- int ioaddr, status, boguscount = 0;
-
- if (net_debug > 5)
- printk("eepro: entering eepro_interrupt routine.\n");
-
- if (dev == NULL) {
- printk ("eepro_interrupt(): irq %d for unknown device.\n", irq);
- return;
- }
- dev->interrupt = 1;
-
- ioaddr = dev->base_addr;
-
- do {
- status = inb(ioaddr + STATUS_REG);
-
- if (status & RX_INT) {
- if (net_debug > 4)
- printk("eepro: packet received interrupt.\n");
-
- /* Acknowledge the RX_INT */
- outb(RX_INT, ioaddr + STATUS_REG);
-
- /* Get the received packets */
- eepro_rx(dev);
- }
- else if (status & TX_INT) {
- if (net_debug > 4)
- printk("eepro: packet transmit interrupt.\n");
-
- /* Acknowledge the TX_INT */
- outb(TX_INT, ioaddr + STATUS_REG);
-
- /* Process the status of transmitted packets */
- eepro_transmit_interrupt(dev);
- dev->tbusy = 0;
- mark_bh(NET_BH);
- }
- } while ((++boguscount < 10) && (status & 0x06));
-
- dev->interrupt = 0;
- if (net_debug > 5)
- printk("eepro: exiting eepro_interrupt routine.\n");
-
- return;
-}
-
-static int
-eepro_close(struct device *dev)
-{
- struct eepro_local *lp = (struct eepro_local *)dev->priv;
- int ioaddr = dev->base_addr;
- short temp_reg;
-
- dev->tbusy = 1;
- dev->start = 0;
-
- outb(BANK1_SELECT, ioaddr); /* Switch back to Bank 1 */
-
- /* Disable the physical interrupt line. */
- temp_reg = inb(ioaddr + REG1);
- outb(temp_reg & 0x7f, ioaddr + REG1);
-
- outb(BANK0_SELECT, ioaddr); /* Switch back to Bank 0 */
-
- /* Flush the Tx and disable Rx. */
- outb(STOP_RCV_CMD, ioaddr);
- lp->tx_start = lp->tx_end = RCV_RAM ;
- lp->tx_last = 0;
-
- /* Mask all the interrupts. */
- outb(ALL_MASK, ioaddr + INT_MASK_REG);
-
- /* clear all interrupts */
- outb(ALL_MASK, ioaddr + STATUS_REG);
-
- /* Reset the 82595 */
- outb(RESET_CMD, ioaddr);
-
- /* release the interrupt */
- free_irq(dev->irq);
-
- irq2dev_map[dev->irq] = 0;
-
- /* Update the statistics here. What statistics? */
-
- /* We are supposed to wait for 200 us after a RESET */
- SLOW_DOWN_IO;
- SLOW_DOWN_IO; /* May not be enough? */
-
- MOD_DEC_USE_COUNT;
- return 0;
-}
-
-/* Get the current statistics. This may be called with the card open or
- closed. */
-static struct enet_statistics *
-eepro_get_stats(struct device *dev)
-{
- struct eepro_local *lp = (struct eepro_local *)dev->priv;
-
- return &lp->stats;
-}
-
-/* Set or clear the multicast filter for this adaptor.
- */
-static void
-set_multicast_list(struct device *dev)
-{
- struct eepro_local *lp = (struct eepro_local *)dev->priv;
- short ioaddr = dev->base_addr;
- unsigned short mode;
- struct dev_mc_list *dmi=dev->mc_list;
-
- if (dev->flags&(IFF_ALLMULTI|IFF_PROMISC) || dev->mc_count > 63)
- {
- /*
- * We must make the kernel realise we had to move
- * into promisc mode or we start all out war on
- * the cable. If it was a promisc rewquest the
- * flag is already set. If not we assert it.
- */
- dev->flags|=IFF_PROMISC;
-
- outb(BANK2_SELECT, ioaddr); /* be CAREFUL, BANK 2 now */
- mode = inb(ioaddr + REG2);
- outb(mode | PRMSC_Mode, ioaddr + REG2);
- mode = inb(ioaddr + REG3);
- outb(mode, ioaddr + REG3); /* writing reg. 3 to complete the update */
- outb(BANK0_SELECT, ioaddr); /* Return to BANK 0 now */
- printk("%s: promiscuous mode enabled.\n", dev->name);
- }
- else if (dev->mc_count==0 )
- {
- outb(BANK2_SELECT, ioaddr); /* be CAREFUL, BANK 2 now */
- mode = inb(ioaddr + REG2);
- outb(mode & 0xd6, ioaddr + REG2); /* Turn off Multi-IA and PRMSC_Mode bits */
- mode = inb(ioaddr + REG3);
- outb(mode, ioaddr + REG3); /* writing reg. 3 to complete the update */
- outb(BANK0_SELECT, ioaddr); /* Return to BANK 0 now */
- }
- else
- {
- unsigned short status, *eaddrs;
- int i, boguscount = 0;
-
- /* Disable RX and TX interrupts. Neccessary to avoid
- corruption of the HOST_ADDRESS_REG by interrupt
- service routines. */
- outb(ALL_MASK, ioaddr + INT_MASK_REG);
-
- outb(BANK2_SELECT, ioaddr); /* be CAREFUL, BANK 2 now */
- mode = inb(ioaddr + REG2);
- outb(mode | Multi_IA, ioaddr + REG2);
- mode = inb(ioaddr + REG3);
- outb(mode, ioaddr + REG3); /* writing reg. 3 to complete the update */
- outb(BANK0_SELECT, ioaddr); /* Return to BANK 0 now */
- outw(lp->tx_end, ioaddr + HOST_ADDRESS_REG);
- outw(MC_SETUP, ioaddr + IO_PORT);
- outw(0, ioaddr + IO_PORT);
- outw(0, ioaddr + IO_PORT);
- outw(6*(dev->mc_count + 1), ioaddr + IO_PORT);
- for (i = 0; i < dev->mc_count; i++)
- {
- eaddrs=(unsigned short *)dmi->dmi_addr;
- dmi=dmi->next;
- outw(*eaddrs++, ioaddr + IO_PORT);
- outw(*eaddrs++, ioaddr + IO_PORT);
- outw(*eaddrs++, ioaddr + IO_PORT);
- }
- eaddrs = (unsigned short *) dev->dev_addr;
- outw(eaddrs[0], ioaddr + IO_PORT);
- outw(eaddrs[1], ioaddr + IO_PORT);
- outw(eaddrs[2], ioaddr + IO_PORT);
- outw(lp->tx_end, ioaddr + XMT_BAR);
- outb(MC_SETUP, ioaddr);
-
- /* Update the transmit queue */
- i = lp->tx_end + XMT_HEADER + 6*(dev->mc_count + 1);
- if (lp->tx_start != lp->tx_end)
- {
- /* update the next address and the chain bit in the
- last packet */
- outw(lp->tx_last + XMT_CHAIN, ioaddr + HOST_ADDRESS_REG);
- outw(i, ioaddr + IO_PORT);
- outw(lp->tx_last + XMT_COUNT, ioaddr + HOST_ADDRESS_REG);
- status = inw(ioaddr + IO_PORT);
- outw(status | CHAIN_BIT, ioaddr + IO_PORT);
- lp->tx_end = i ;
- }
- else lp->tx_start = lp->tx_end = i ;
-
- /* Acknowledge that the MC setup is done */
- do { /* We should be doing this in the eepro_interrupt()! */
- SLOW_DOWN_IO;
- SLOW_DOWN_IO;
- if (inb(ioaddr + STATUS_REG) & 0x08)
- {
- i = inb(ioaddr);
- outb(0x08, ioaddr + STATUS_REG);
- if (i & 0x20) { /* command ABORTed */
- printk("%s: multicast setup failed.\n",
- dev->name);
- break;
- } else if ((i & 0x0f) == 0x03) { /* MC-Done */
- printk("%s: set Rx mode to %d addresses.\n",
- dev->name, dev->mc_count);
- break;
- }
- }
- } while (++boguscount < 100);
-
- /* Re-enable RX and TX interrupts */
- outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG);
-
- }
- outb(RCV_ENABLE_CMD, ioaddr);
-}
-
-/* The horrible routine to read a word from the serial EEPROM. */
-/* IMPORTANT - the 82595 will be set to Bank 0 after the eeprom is read */
-
-/* The delay between EEPROM clock transitions. */
-#define eeprom_delay() { int _i = 40; while (--_i > 0) { __SLOW_DOWN_IO; }}
-#define EE_READ_CMD (6 << 6)
-
-int
-read_eeprom(int ioaddr, int location)
-{
- int i;
- unsigned short retval = 0;
- short ee_addr = ioaddr + EEPROM_REG;
- int read_cmd = location | EE_READ_CMD;
- short ctrl_val = EECS ;
-
- outb(BANK2_SELECT, ioaddr);
- outb(ctrl_val, ee_addr);
-
- /* Shift the read command bits out. */
- for (i = 8; i >= 0; i--) {
- short outval = (read_cmd & (1 << i)) ? ctrl_val | EEDI
- : ctrl_val;
- outb(outval, ee_addr);
- outb(outval | EESK, ee_addr); /* EEPROM clock tick. */
- eeprom_delay();
- outb(outval, ee_addr); /* Finish EEPROM a clock tick. */
- eeprom_delay();
- }
- outb(ctrl_val, ee_addr);
-
- for (i = 16; i > 0; i--) {
- outb(ctrl_val | EESK, ee_addr); eeprom_delay();
- retval = (retval << 1) | ((inb(ee_addr) & EEDO) ? 1 : 0);
- outb(ctrl_val, ee_addr); eeprom_delay();
- }
-
- /* Terminate the EEPROM access. */
- ctrl_val &= ~EECS;
- outb(ctrl_val | EESK, ee_addr);
- eeprom_delay();
- outb(ctrl_val, ee_addr);
- eeprom_delay();
- outb(BANK0_SELECT, ioaddr);
- return retval;
-}
-
-static void
-hardware_send_packet(struct device *dev, void *buf, short length)
-{
- struct eepro_local *lp = (struct eepro_local *)dev->priv;
- short ioaddr = dev->base_addr;
- unsigned status, tx_available, last, end, boguscount = 10;
-
- if (net_debug > 5)
- printk("eepro: entering hardware_send_packet routine.\n");
-
- while (boguscount-- > 0) {
-
- /* determine how much of the transmit buffer space is available */
- if (lp->tx_end > lp->tx_start)
- tx_available = XMT_RAM - (lp->tx_end - lp->tx_start);
- else if (lp->tx_end < lp->tx_start)
- tx_available = lp->tx_start - lp->tx_end;
- else tx_available = XMT_RAM;
-
- /* Disable RX and TX interrupts. Neccessary to avoid
- corruption of the HOST_ADDRESS_REG by interrupt
- service routines. */
- outb(ALL_MASK, ioaddr + INT_MASK_REG);
-
- if (((((length + 1) >> 1) << 1) + 2*XMT_HEADER)
- >= tx_available) /* No space available ??? */
- continue;
-
- last = lp->tx_end;
- end = last + (((length + 1) >> 1) << 1) + XMT_HEADER;
-
- if (end >= RAM_SIZE) { /* the transmit buffer is wrapped around */
- if ((RAM_SIZE - last) <= XMT_HEADER) {
- /* Arrrr!!!, must keep the xmt header together,
- several days were lost to chase this one down. */
- last = RCV_RAM;
- end = last + (((length + 1) >> 1) << 1) + XMT_HEADER;
- }
- else end = RCV_RAM + (end - RAM_SIZE);
- }
-
- outw(last, ioaddr + HOST_ADDRESS_REG);
- outw(XMT_CMD, ioaddr + IO_PORT);
- outw(0, ioaddr + IO_PORT);
- outw(end, ioaddr + IO_PORT);
- outw(length, ioaddr + IO_PORT);
- outsw(ioaddr + IO_PORT, buf, (length + 1) >> 1);
-
- if (lp->tx_start != lp->tx_end) {
- /* update the next address and the chain bit in the
- last packet */
- if (lp->tx_end != last) {
- outw(lp->tx_last + XMT_CHAIN, ioaddr + HOST_ADDRESS_REG);
- outw(last, ioaddr + IO_PORT);
- }
- outw(lp->tx_last + XMT_COUNT, ioaddr + HOST_ADDRESS_REG);
- status = inw(ioaddr + IO_PORT);
- outw(status | CHAIN_BIT, ioaddr + IO_PORT);
- }
-
- /* A dummy read to flush the DRAM write pipeline */
- status = inw(ioaddr + IO_PORT);
-
- /* Enable RX and TX interrupts */
- outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG);
-
- if (lp->tx_start == lp->tx_end) {
- outw(last, ioaddr + XMT_BAR);
- outb(XMT_CMD, ioaddr);
- lp->tx_start = last; /* I don't like to change tx_start here */
- }
- else outb(RESUME_XMT_CMD, ioaddr);
-
- lp->tx_last = last;
- lp->tx_end = end;
-
- if (dev->tbusy) {
- dev->tbusy = 0;
- mark_bh(NET_BH);
- }
-
- if (net_debug > 5)
- printk("eepro: exiting hardware_send_packet routine.\n");
- return;
- }
- dev->tbusy = 1;
- if (net_debug > 5)
- printk("eepro: exiting hardware_send_packet routine.\n");
-}
-
-static void
-eepro_rx(struct device *dev)
-{
- struct eepro_local *lp = (struct eepro_local *)dev->priv;
- short ioaddr = dev->base_addr;
- short boguscount = 20;
- short rcv_car = lp->rx_start;
- unsigned rcv_event, rcv_status, rcv_next_frame, rcv_size;
-
- if (net_debug > 5)
- printk("eepro: entering eepro_rx routine.\n");
-
- /* Set the read pointer to the start of the RCV */
- outw(rcv_car, ioaddr + HOST_ADDRESS_REG);
- rcv_event = inw(ioaddr + IO_PORT);
-
- while (rcv_event == RCV_DONE) {
- rcv_status = inw(ioaddr + IO_PORT);
- rcv_next_frame = inw(ioaddr + IO_PORT);
- rcv_size = inw(ioaddr + IO_PORT);
-
- if ((rcv_status & (RX_OK | RX_ERROR)) == RX_OK) {
- /* Malloc up new buffer. */
- struct sk_buff *skb;
-
- rcv_size &= 0x3fff;
- skb = dev_alloc_skb(rcv_size+2);
- if (skb == NULL) {
- printk("%s: Memory squeeze, dropping packet.\n", dev->name);
- lp->stats.rx_dropped++;
- break;
- }
- skb->dev = dev;
- skb_reserve(skb,2);
-
- insw(ioaddr+IO_PORT, skb_put(skb,rcv_size), (rcv_size + 1) >> 1);
-
- skb->protocol = eth_type_trans(skb,dev);
- netif_rx(skb);
- lp->stats.rx_packets++;
- }
- else { /* Not sure will ever reach here,
- I set the 595 to discard bad received frames */
- lp->stats.rx_errors++;
- if (rcv_status & 0x0100)
- lp->stats.rx_over_errors++;
- else if (rcv_status & 0x0400)
- lp->stats.rx_frame_errors++;
- else if (rcv_status & 0x0800)
- lp->stats.rx_crc_errors++;
- printk("%s: event = %#x, status = %#x, next = %#x, size = %#x\n",
- dev->name, rcv_event, rcv_status, rcv_next_frame, rcv_size);
- }
- if (rcv_status & 0x1000)
- lp->stats.rx_length_errors++;
- if (--boguscount == 0)
- break;
-
- rcv_car = lp->rx_start + RCV_HEADER + rcv_size;
- lp->rx_start = rcv_next_frame;
- outw(rcv_next_frame, ioaddr + HOST_ADDRESS_REG);
- rcv_event = inw(ioaddr + IO_PORT);
-
- }
- if (rcv_car == 0)
- rcv_car = (RCV_UPPER_LIMIT << 8) | 0xff;
- outw(rcv_car - 1, ioaddr + RCV_STOP);
-
- if (net_debug > 5)
- printk("eepro: exiting eepro_rx routine.\n");
-}
-
-static void
-eepro_transmit_interrupt(struct device *dev)
-{
- struct eepro_local *lp = (struct eepro_local *)dev->priv;
- short ioaddr = dev->base_addr;
- short boguscount = 10;
- short xmt_status;
-
- while (lp->tx_start != lp->tx_end) {
-
- outw(lp->tx_start, ioaddr + HOST_ADDRESS_REG);
- xmt_status = inw(ioaddr+IO_PORT);
- if ((xmt_status & TX_DONE_BIT) == 0) break;
- xmt_status = inw(ioaddr+IO_PORT);
- lp->tx_start = inw(ioaddr+IO_PORT);
-
- if (dev->tbusy) {
- dev->tbusy = 0;
- mark_bh(NET_BH);
- }
-
- if (xmt_status & 0x2000)
- lp->stats.tx_packets++;
- else {
- lp->stats.tx_errors++;
- if (xmt_status & 0x0400)
- lp->stats.tx_carrier_errors++;
- printk("%s: XMT status = %#x\n",
- dev->name, xmt_status);
- }
- if (xmt_status & 0x000f)
- lp->stats.collisions += (xmt_status & 0x000f);
- if ((xmt_status & 0x0040) == 0x0)
- lp->stats.tx_heartbeat_errors++;
-
- if (--boguscount == 0)
- break;
- }
-}
-
-#ifdef MODULE
-static char devicename[9] = { 0, };
-static struct device dev_eepro = {
- devicename, /* device name is inserted by linux/drivers/net/net_init.c */
- 0, 0, 0, 0,
- 0, 0,
- 0, 0, 0, NULL, eepro_probe };
-
-static int io = 0x200;
-static int irq = 0;
-
-int
-init_module(void)
-{
- if (io == 0)
- printk("eepro: You should not use auto-probing with insmod!\n");
- dev_eepro.base_addr = io;
- dev_eepro.irq = irq;
-
- if (register_netdev(&dev_eepro) != 0)
- return -EIO;
- return 0;
-}
-
-void
-cleanup_module(void)
-{
- unregister_netdev(&dev_eepro);
- kfree_s(dev_eepro.priv,sizeof(struct eepro_local));
- dev_eepro.priv=NULL;
-
- /* If we don't do this, we can't re-insmod it later. */
- release_region(dev_eepro.base_addr, EEPRO_IO_EXTENT);
-}
-#endif /* MODULE */
diff --git a/i386/i386at/gpl/linux/net/eexpress.c b/i386/i386at/gpl/linux/net/eexpress.c
deleted file mode 100644
index 2f641d68..00000000
--- a/i386/i386at/gpl/linux/net/eexpress.c
+++ /dev/null
@@ -1,1034 +0,0 @@
-/* eexpress.c: Intel EtherExpress device driver for Linux. */
-/*
- Written 1993 by Donald Becker.
- Copyright 1993 United States Government as represented by the Director,
- National Security Agency. This software may only be used and distributed
- according to the terms of the GNU Public License as modified by SRC,
- incorporated herein by reference.
-
- The author may be reached as becker@super.org or
- C/O Supercomputing Research Ctr., 17100 Science Dr., Bowie MD 20715
-
- Things remaining to do:
- Check that the 586 and ASIC are reset/unreset at the right times.
- Check tx and rx buffer setup.
- The current Tx is single-buffer-only.
- Move the theory of operation and memory map documentation.
- Rework the board error reset
- The statistics need to be updated correctly.
-
- Modularized by Pauline Middelink <middelin@polyware.iaf.nl>
- Changed to support io= irq= by Alan Cox <Alan.Cox@linux.org>
-*/
-
-static const char *version =
- "eexpress.c:v0.07 1/19/94 Donald Becker (becker@super.org)\n";
-
-/*
- Sources:
- This driver wouldn't have been written with the availability of the
- Crynwr driver source code. It provided a known-working implementation
- that filled in the gaping holes of the Intel documentation. Three cheers
- for Russ Nelson.
-
- Intel Microcommunications Databook, Vol. 1, 1990. It provides just enough
- info that the casual reader might think that it documents the i82586.
-*/
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ptrace.h>
-#include <linux/ioport.h>
-#include <linux/string.h>
-#include <linux/in.h>
-#include <asm/system.h>
-#include <asm/bitops.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <linux/errno.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/malloc.h>
-
-/* use 0 for production, 1 for verification, 2..7 for debug */
-#ifndef NET_DEBUG
-#define NET_DEBUG 2
-#endif
-static unsigned int net_debug = NET_DEBUG;
-
-/*
- Details of the i82586.
-
- You'll really need the databook to understand the details of this part,
- but the outline is that the i82586 has two separate processing units.
-
- The Rx unit uses a list of frame descriptors and a list of data buffer
- descriptors. We use full-sized (1518 byte) data buffers, so there is
- a one-to-one pairing of frame descriptors to buffer descriptors.
-
- The Tx ("command") unit executes a list of commands that look like:
- Status word Written by the 82586 when the command is done.
- Command word Command in lower 3 bits, post-command action in upper 3
- Link word The address of the next command.
- Parameters (as needed).
-
- Some definitions related to the Command Word are:
- */
-#define CMD_EOL 0x8000 /* The last command of the list, stop. */
-#define CMD_SUSP 0x4000 /* Suspend after doing cmd. */
-#define CMD_INTR 0x2000 /* Interrupt after doing cmd. */
-
-enum commands {
- CmdNOp = 0, CmdSASetup = 1, CmdConfigure = 2, CmdMulticastList = 3,
- CmdTx = 4, CmdTDR = 5, CmdDump = 6, CmdDiagnose = 7};
-
-/* Information that need to be kept for each board. */
-struct net_local {
- struct enet_statistics stats;
- int last_restart;
- short rx_head;
- short rx_tail;
- short tx_head;
- short tx_cmd_link;
- short tx_reap;
-};
-
-/*
- Details of the EtherExpress Implementation
- The EtherExpress takes an unusual approach to host access to packet buffer
- memory. The host can use either the Dataport, with independent
- autoincrementing read and write pointers, or it can I/O map 32 bytes of the
- memory using the "Shadow Memory Pointer" (SMB) as follows:
- ioaddr Normal EtherExpress registers
- ioaddr+0x4000...0x400f Buffer Memory at SMB...SMB+15
- ioaddr+0x8000...0x800f Buffer Memory at SMB+16...SMB+31
- ioaddr+0xC000...0xC007 "" SMB+16...SMB+23 (hardware flaw?)
- ioaddr+0xC008...0xC00f Buffer Memory at 0x0008...0x000f
- The last I/O map set is useful if you put the i82586 System Command Block
- (the command mailbox) exactly at 0x0008. (There seems to be some
- undocumented init structure at 0x0000-7, so I had to use the Crywnr memory
- setup verbatim for those four words anyway.)
-
- A problem with using either one of these mechanisms is that you must run
- single-threaded, or the interrupt handler must restore a changed value of
- the read, write, or SMB pointers.
-
- Unlike the Crynwr driver, my driver mostly ignores the I/O mapped "feature"
- and relies heavily on the dataport for buffer memory access. To minimize
- switching, the read_pointer is dedicated to the Rx interrupt handler, and
- the write_pointer is used by the send_packet() routine (it's carefully saved
- and restored when it's needed by the interrupt handler).
- */
-
-/* Offsets from the base I/O address. */
-#define DATAPORT 0 /* Data Transfer Register. */
-#define WRITE_PTR 2 /* Write Address Pointer. */
-#define READ_PTR 4 /* Read Address Pointer. */
-#define SIGNAL_CA 6 /* Frob the 82586 Channel Attention line. */
-#define SET_IRQ 7 /* IRQ Select. */
-#define SHADOW_PTR 8 /* Shadow Memory Bank Pointer. */
-#define MEM_Ctrl 11
-#define MEM_Page_Ctrl 12
-#define Config 13
-#define EEPROM_Ctrl 14
-#define ID_PORT 15
-
-#define EEXPRESS_IO_EXTENT 16
-
-/* EEPROM_Ctrl bits. */
-
-#define EE_SHIFT_CLK 0x01 /* EEPROM shift clock. */
-#define EE_CS 0x02 /* EEPROM chip select. */
-#define EE_DATA_WRITE 0x04 /* EEPROM chip data in. */
-#define EE_DATA_READ 0x08 /* EEPROM chip data out. */
-#define EE_CTRL_BITS (EE_SHIFT_CLK | EE_CS | EE_DATA_WRITE | EE_DATA_READ)
-#define ASIC_RESET 0x40
-#define _586_RESET 0x80
-
-/* Offsets to elements of the System Control Block structure. */
-#define SCB_STATUS 0xc008
-#define SCB_CMD 0xc00A
-#define CUC_START 0x0100
-#define CUC_RESUME 0x0200
-#define CUC_SUSPEND 0x0300
-#define RX_START 0x0010
-#define RX_RESUME 0x0020
-#define RX_SUSPEND 0x0030
-#define SCB_CBL 0xc00C /* Command BLock offset. */
-#define SCB_RFA 0xc00E /* Rx Frame Area offset. */
-
-/*
- What follows in 'init_words[]' is the "program" that is downloaded to the
- 82586 memory. It's mostly tables and command blocks, and starts at the
- reset address 0xfffff6.
-
- Even with the additional "don't care" values, doing it this way takes less
- program space than initializing the individual tables, and I feel it's much
- cleaner.
-
- The databook is particularly useless for the first two structures; they are
- completely undocumented. I had to use the Crynwr driver as an example.
-
- The memory setup is as follows:
- */
-
-#define CONFIG_CMD 0x0018
-#define SET_SA_CMD 0x0024
-#define SA_OFFSET 0x002A
-#define IDLELOOP 0x30
-#define TDR_CMD 0x38
-#define TDR_TIME 0x3C
-#define DUMP_CMD 0x40
-#define DIAG_CMD 0x48
-#define SET_MC_CMD 0x4E
-#define DUMP_DATA 0x56 /* A 170 byte buffer for dump and Set-MC into. */
-
-#define TX_BUF_START 0x0100
-#define NUM_TX_BUFS 4
-#define TX_BUF_SIZE 0x0680 /* packet+header+TBD+extra (1518+14+20+16) */
-#define TX_BUF_END 0x2000
-
-#define RX_BUF_START 0x2000
-#define RX_BUF_SIZE (0x640) /* packet+header+RBD+extra */
-#define RX_BUF_END 0x4000
-
-/*
- That's it: only 86 bytes to set up the beast, including every extra
- command available. The 170 byte buffer at DUMP_DATA is shared between the
- Dump command (called only by the diagnostic program) and the SetMulticastList
- command.
-
- To complete the memory setup you only have to write the station address at
- SA_OFFSET and create the Tx & Rx buffer lists.
-
- The Tx command chain and buffer list is setup as follows:
- A Tx command table, with the data buffer pointing to...
- A Tx data buffer descriptor. The packet is in a single buffer, rather than
- chaining together several smaller buffers.
- A NoOp command, which initially points to itself,
- And the packet data.
-
- A transmit is done by filling in the Tx command table and data buffer,
- re-writing the NoOp command, and finally changing the offset of the last
- command to point to the current Tx command. When the Tx command is finished,
- it jumps to the NoOp, when it loops until the next Tx command changes the
- "link offset" in the NoOp. This way the 82586 never has to go through the
- slow restart sequence.
-
- The Rx buffer list is set up in the obvious ring structure. We have enough
- memory (and low enough interrupt latency) that we can avoid the complicated
- Rx buffer linked lists by alway associating a full-size Rx data buffer with
- each Rx data frame.
-
- I current use four transmit buffers starting at TX_BUF_START (0x0100), and
- use the rest of memory, from RX_BUF_START to RX_BUF_END, for Rx buffers.
-
- */
-
-static short init_words[] = {
- 0x0000, /* Set bus size to 16 bits. */
- 0x0000,0x0000, /* Set control mailbox (SCB) addr. */
- 0,0, /* pad to 0x000000. */
- 0x0001, /* Status word that's cleared when init is done. */
- 0x0008,0,0, /* SCB offset, (skip, skip) */
-
- 0,0xf000|RX_START|CUC_START, /* SCB status and cmd. */
- CONFIG_CMD, /* Command list pointer, points to Configure. */
- RX_BUF_START, /* Rx block list. */
- 0,0,0,0, /* Error count: CRC, align, buffer, overrun. */
-
- /* 0x0018: Configure command. Change to put MAC data with packet. */
- 0, CmdConfigure, /* Status, command. */
- SET_SA_CMD, /* Next command is Set Station Addr. */
- 0x0804, /* "4" bytes of config data, 8 byte FIFO. */
- 0x2e40, /* Magic values, including MAC data location. */
- 0, /* Unused pad word. */
-
- /* 0x0024: Setup station address command. */
- 0, CmdSASetup,
- SET_MC_CMD, /* Next command. */
- 0xaa00,0xb000,0x0bad, /* Station address (to be filled in) */
-
- /* 0x0030: NOP, looping back to itself. Point to first Tx buffer to Tx. */
- 0, CmdNOp, IDLELOOP, 0 /* pad */,
-
- /* 0x0038: A unused Time-Domain Reflectometer command. */
- 0, CmdTDR, IDLELOOP, 0,
-
- /* 0x0040: An unused Dump State command. */
- 0, CmdDump, IDLELOOP, DUMP_DATA,
-
- /* 0x0048: An unused Diagnose command. */
- 0, CmdDiagnose, IDLELOOP,
-
- /* 0x004E: An empty set-multicast-list command. */
-#ifdef initial_text_tx
- 0, CmdMulticastList, DUMP_DATA, 0,
-#else
- 0, CmdMulticastList, IDLELOOP, 0,
-#endif
-
- /* 0x0056: A continuous transmit command, only here for testing. */
- 0, CmdTx, DUMP_DATA, DUMP_DATA+8, 0x83ff, -1, DUMP_DATA, 0,
-};
-
-/* Index to functions, as function prototypes. */
-
-extern int express_probe(struct device *dev); /* Called from Space.c */
-
-static int eexp_probe1(struct device *dev, short ioaddr);
-static int eexp_open(struct device *dev);
-static int eexp_send_packet(struct sk_buff *skb, struct device *dev);
-static void eexp_interrupt(int irq, struct pt_regs *regs);
-static void eexp_rx(struct device *dev);
-static int eexp_close(struct device *dev);
-static struct enet_statistics *eexp_get_stats(struct device *dev);
-static void set_multicast_list(struct device *dev);
-
-static int read_eeprom(int ioaddr, int location);
-static void hardware_send_packet(struct device *dev, void *buf, short length);
-static void init_82586_mem(struct device *dev);
-static void init_rx_bufs(struct device *dev);
-
-
-/* Check for a network adaptor of this type, and return '0' iff one exists.
- If dev->base_addr == 0, probe all likely locations.
- If dev->base_addr == 1, always return failure.
- If dev->base_addr == 2, (detachable devices only) allocate space for the
- device and return success.
- */
-int
-express_probe(struct device *dev)
-{
- /* Don't probe all settable addresses, 0x[23][0-7]0, just common ones. */
- int *port, ports[] = {0x300, 0x270, 0x320, 0x340, 0};
- int base_addr = dev->base_addr;
-
- if (base_addr > 0x1ff) /* Check a single specified location. */
- return eexp_probe1(dev, base_addr);
- else if (base_addr > 0)
- return ENXIO; /* Don't probe at all. */
-
- for (port = &ports[0]; *port; port++) {
- short id_addr = *port + ID_PORT;
- unsigned short sum = 0;
- int i;
-#ifdef notdef
- for (i = 16; i > 0; i--)
- sum += inb(id_addr);
- printk("EtherExpress ID checksum is %04x.\n", sum);
-#else
- for (i = 4; i > 0; i--) {
- short id_val = inb(id_addr);
- sum |= (id_val >> 4) << ((id_val & 3) << 2);
- }
-#endif
- if (sum == 0xbaba
- && eexp_probe1(dev, *port) == 0)
- return 0;
- }
-
- return ENODEV;
-}
-
-int eexp_probe1(struct device *dev, short ioaddr)
-{
- unsigned short station_addr[3];
- int i;
-
- printk("%s: EtherExpress at %#x,", dev->name, ioaddr);
-
- /* The station address is stored !backwards! in the EEPROM, reverse
- after reading. (Hmmm, a little brain-damage there at Intel, eh?) */
- station_addr[0] = read_eeprom(ioaddr, 2);
- station_addr[1] = read_eeprom(ioaddr, 3);
- station_addr[2] = read_eeprom(ioaddr, 4);
-
- /* Check the first three octets of the S.A. for the manufacturer's code. */
- if (station_addr[2] != 0x00aa || (station_addr[1] & 0xff00) != 0x0000) {
- printk(" rejected (invalid address %04x%04x%04x).\n",
- station_addr[2], station_addr[1], station_addr[0]);
- return ENODEV;
- }
-
- /* We've committed to using the board, and can start filling in *dev. */
- request_region(ioaddr, EEXPRESS_IO_EXTENT, "eexpress");
- dev->base_addr = ioaddr;
-
- for (i = 0; i < 6; i++) {
- dev->dev_addr[i] = ((unsigned char*)station_addr)[5-i];
- printk(" %02x", dev->dev_addr[i]);
- }
-
- /* There is no reason for the driver to care, but I print out the
- interface to minimize bogus bug reports. */
- {
- char irqmap[] = {0, 9, 3, 4, 5, 10, 11, 0};
- const char *ifmap[] = {"AUI", "BNC", "10baseT"};
- enum iftype {AUI=0, BNC=1, TP=2};
- unsigned short setupval = read_eeprom(ioaddr, 0);
-
- dev->irq = irqmap[setupval >> 13];
- dev->if_port = (setupval & 0x1000) == 0 ? AUI :
- read_eeprom(ioaddr, 5) & 0x1 ? TP : BNC;
- printk(", IRQ %d, Interface %s.\n", dev->irq, ifmap[dev->if_port]);
- /* Release the IRQ line so that it can be shared if we don't use the
- ethercard. */
- outb(0x00, ioaddr + SET_IRQ);
- }
-
- /* It's now OK to leave the board in reset, pending the open(). */
- outb(ASIC_RESET, ioaddr + EEPROM_Ctrl);
-
- if ((dev->mem_start & 0xf) > 0)
- net_debug = dev->mem_start & 7;
-
- if (net_debug)
- printk(version);
-
- /* Initialize the device structure. */
- dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
- if (dev->priv == NULL)
- return -ENOMEM;
- memset(dev->priv, 0, sizeof(struct net_local));
-
- dev->open = eexp_open;
- dev->stop = eexp_close;
- dev->hard_start_xmit = eexp_send_packet;
- dev->get_stats = eexp_get_stats;
- dev->set_multicast_list = &set_multicast_list;
-
- /* Fill in the fields of the device structure with ethernet-generic values. */
-
- ether_setup(dev);
-
- dev->flags&=~IFF_MULTICAST;
-
- return 0;
-}
-
-
-/* Reverse IRQ map: the value to put in the SET_IRQ reg. for IRQ<index>. */
-static char irqrmap[]={0,0,1,2,3,4,0,0,0,1,5,6,0,0,0,0};
-
-static int
-eexp_open(struct device *dev)
-{
- int ioaddr = dev->base_addr;
-
- if (dev->irq == 0 || irqrmap[dev->irq] == 0)
- return -ENXIO;
-
- if (irq2dev_map[dev->irq] != 0
- /* This is always true, but avoid the false IRQ. */
- || (irq2dev_map[dev->irq] = dev) == 0
- || request_irq(dev->irq, &eexp_interrupt, 0, "EExpress")) {
- return -EAGAIN;
- }
-
- /* Initialize the 82586 memory and start it. */
- init_82586_mem(dev);
-
- /* Enable the interrupt line. */
- outb(irqrmap[dev->irq] | 0x08, ioaddr + SET_IRQ);
-
- dev->tbusy = 0;
- dev->interrupt = 0;
- dev->start = 1;
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-static int
-eexp_send_packet(struct sk_buff *skb, struct device *dev)
-{
- struct net_local *lp = (struct net_local *)dev->priv;
- int ioaddr = dev->base_addr;
-
- if (dev->tbusy) {
- /* If we get here, some higher level has decided we are broken.
- There should really be a "kick me" function call instead. */
- int tickssofar = jiffies - dev->trans_start;
- if (tickssofar < 5)
- return 1;
- if (net_debug > 1)
- printk("%s: transmit timed out, %s? ", dev->name,
- inw(ioaddr+SCB_STATUS) & 0x8000 ? "IRQ conflict" :
- "network cable problem");
- lp->stats.tx_errors++;
- /* Try to restart the adaptor. */
- if (lp->last_restart == lp->stats.tx_packets) {
- if (net_debug > 1) printk("Resetting board.\n");
- /* Completely reset the adaptor. */
- init_82586_mem(dev);
- } else {
- /* Issue the channel attention signal and hope it "gets better". */
- if (net_debug > 1) printk("Kicking board.\n");
- outw(0xf000|CUC_START|RX_START, ioaddr + SCB_CMD);
- outb(0, ioaddr + SIGNAL_CA);
- lp->last_restart = lp->stats.tx_packets;
- }
- dev->tbusy=0;
- dev->trans_start = jiffies;
- }
-
- /* If some higher layer thinks we've missed an tx-done interrupt
- we are passed NULL. Caution: dev_tint() handles the cli()/sti()
- itself. */
- if (skb == NULL) {
- dev_tint(dev);
- return 0;
- }
-
- /* Block a timer-based transmit from overlapping. */
- if (set_bit(0, (void*)&dev->tbusy) != 0)
- printk("%s: Transmitter access conflict.\n", dev->name);
- else {
- short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
- unsigned char *buf = skb->data;
-
- /* Disable the 82586's input to the interrupt line. */
- outb(irqrmap[dev->irq], ioaddr + SET_IRQ);
- hardware_send_packet(dev, buf, length);
- dev->trans_start = jiffies;
- /* Enable the 82586 interrupt input. */
- outb(0x08 | irqrmap[dev->irq], ioaddr + SET_IRQ);
- }
-
- dev_kfree_skb (skb, FREE_WRITE);
-
- /* You might need to clean up and record Tx statistics here. */
- lp->stats.tx_aborted_errors++;
-
- return 0;
-}
-
-/* The typical workload of the driver:
- Handle the network interface interrupts. */
-static void
-eexp_interrupt(int irq, struct pt_regs *regs)
-{
- struct device *dev = (struct device *)(irq2dev_map[irq]);
- struct net_local *lp;
- int ioaddr, status, boguscount = 0;
- short ack_cmd;
-
- if (dev == NULL) {
- printk ("net_interrupt(): irq %d for unknown device.\n", irq);
- return;
- }
- dev->interrupt = 1;
-
- ioaddr = dev->base_addr;
- lp = (struct net_local *)dev->priv;
-
- status = inw(ioaddr + SCB_STATUS);
-
- if (net_debug > 4) {
- printk("%s: EExp interrupt, status %4.4x.\n", dev->name, status);
- }
-
- /* Disable the 82586's input to the interrupt line. */
- outb(irqrmap[dev->irq], ioaddr + SET_IRQ);
-
- /* Reap the Tx packet buffers. */
- while (lp->tx_reap != lp->tx_head) { /* if (status & 0x8000) */
- unsigned short tx_status;
- outw(lp->tx_reap, ioaddr + READ_PTR);
- tx_status = inw(ioaddr);
- if (tx_status == 0) {
- if (net_debug > 5) printk("Couldn't reap %#x.\n", lp->tx_reap);
- break;
- }
- if (tx_status & 0x2000) {
- lp->stats.tx_packets++;
- lp->stats.collisions += tx_status & 0xf;
- dev->tbusy = 0;
- mark_bh(NET_BH); /* Inform upper layers. */
- } else {
- lp->stats.tx_errors++;
- if (tx_status & 0x0600) lp->stats.tx_carrier_errors++;
- if (tx_status & 0x0100) lp->stats.tx_fifo_errors++;
- if (!(tx_status & 0x0040)) lp->stats.tx_heartbeat_errors++;
- if (tx_status & 0x0020) lp->stats.tx_aborted_errors++;
- }
- if (net_debug > 5)
- printk("Reaped %x, Tx status %04x.\n" , lp->tx_reap, tx_status);
- lp->tx_reap += TX_BUF_SIZE;
- if (lp->tx_reap > TX_BUF_END - TX_BUF_SIZE)
- lp->tx_reap = TX_BUF_START;
- if (++boguscount > 4)
- break;
- }
-
- if (status & 0x4000) { /* Packet received. */
- if (net_debug > 5)
- printk("Received packet, rx_head %04x.\n", lp->rx_head);
- eexp_rx(dev);
- }
-
- /* Acknowledge the interrupt sources. */
- ack_cmd = status & 0xf000;
-
- if ((status & 0x0700) != 0x0200 && dev->start) {
- short saved_write_ptr = inw(ioaddr + WRITE_PTR);
- if (net_debug > 1)
- printk("%s: Command unit stopped, status %04x, restarting.\n",
- dev->name, status);
- /* If this ever occurs we must re-write the idle loop, reset
- the Tx list, and do a complete restart of the command unit. */
- outw(IDLELOOP, ioaddr + WRITE_PTR);
- outw(0, ioaddr);
- outw(CmdNOp, ioaddr);
- outw(IDLELOOP, ioaddr);
- outw(IDLELOOP, SCB_CBL);
- lp->tx_cmd_link = IDLELOOP + 4;
- lp->tx_head = lp->tx_reap = TX_BUF_START;
- /* Restore the saved write pointer. */
- outw(saved_write_ptr, ioaddr + WRITE_PTR);
- ack_cmd |= CUC_START;
- }
-
- if ((status & 0x0070) != 0x0040 && dev->start) {
- short saved_write_ptr = inw(ioaddr + WRITE_PTR);
- /* The Rx unit is not ready, it must be hung. Restart the receiver by
- initializing the rx buffers, and issuing an Rx start command. */
- lp->stats.rx_errors++;
- if (net_debug > 1) {
- int cur_rxbuf = RX_BUF_START;
- printk("%s: Rx unit stopped status %04x rx head %04x tail %04x.\n",
- dev->name, status, lp->rx_head, lp->rx_tail);
- while (cur_rxbuf <= RX_BUF_END - RX_BUF_SIZE) {
- int i;
- printk(" Rx buf at %04x:", cur_rxbuf);
- outw(cur_rxbuf, ioaddr + READ_PTR);
- for (i = 0; i < 0x20; i += 2)
- printk(" %04x", inw(ioaddr));
- printk(".\n");
- cur_rxbuf += RX_BUF_SIZE;
- }
- }
- init_rx_bufs(dev);
- outw(RX_BUF_START, SCB_RFA);
- outw(saved_write_ptr, ioaddr + WRITE_PTR);
- ack_cmd |= RX_START;
- }
-
- outw(ack_cmd, ioaddr + SCB_CMD);
- outb(0, ioaddr + SIGNAL_CA);
-
- if (net_debug > 5) {
- printk("%s: EExp exiting interrupt, status %4.4x.\n", dev->name,
- inw(ioaddr + SCB_CMD));
- }
- /* Enable the 82586's input to the interrupt line. */
- outb(irqrmap[dev->irq] | 0x08, ioaddr + SET_IRQ);
- return;
-}
-
-static int
-eexp_close(struct device *dev)
-{
- int ioaddr = dev->base_addr;
-
- dev->tbusy = 1;
- dev->start = 0;
-
- /* Flush the Tx and disable Rx. */
- outw(RX_SUSPEND | CUC_SUSPEND, ioaddr + SCB_CMD);
- outb(0, ioaddr + SIGNAL_CA);
-
- /* Disable the physical interrupt line. */
- outb(0, ioaddr + SET_IRQ);
-
- free_irq(dev->irq);
-
- irq2dev_map[dev->irq] = 0;
-
- /* Update the statistics here. */
-
- MOD_DEC_USE_COUNT;
- return 0;
-}
-
-/* Get the current statistics. This may be called with the card open or
- closed. */
-static struct enet_statistics *
-eexp_get_stats(struct device *dev)
-{
- struct net_local *lp = (struct net_local *)dev->priv;
-
- /* ToDo: decide if there are any useful statistics from the SCB. */
-
- return &lp->stats;
-}
-
-/* Set or clear the multicast filter for this adaptor.
- */
-static void
-set_multicast_list(struct device *dev)
-{
-/* This doesn't work yet */
-#if 0
- short ioaddr = dev->base_addr;
- if (num_addrs < 0) {
- /* Not written yet, this requires expanding the init_words config
- cmd. */
- } else if (num_addrs > 0) {
- /* Fill in the SET_MC_CMD with the number of address bytes, followed
- by the list of multicast addresses to be accepted. */
- outw(SET_MC_CMD + 6, ioaddr + WRITE_PTR);
- outw(num_addrs * 6, ioaddr);
- outsw(ioaddr, addrs, num_addrs*3); /* 3 = addr len in words */
- /* We must trigger a whole 586 reset due to a bug. */
- } else {
- /* Not written yet, this requires expanding the init_words config
- cmd. */
- outw(99, ioaddr); /* Disable promiscuous mode, use normal mode */
- }
-#endif
-}
-
-/* The horrible routine to read a word from the serial EEPROM. */
-
-/* The delay between EEPROM clock transitions. */
-#define eeprom_delay() { int _i = 40; while (--_i > 0) { __SLOW_DOWN_IO; }}
-#define EE_READ_CMD (6 << 6)
-
-int
-read_eeprom(int ioaddr, int location)
-{
- int i;
- unsigned short retval = 0;
- short ee_addr = ioaddr + EEPROM_Ctrl;
- int read_cmd = location | EE_READ_CMD;
- short ctrl_val = EE_CS | _586_RESET;
-
- outb(ctrl_val, ee_addr);
-
- /* Shift the read command bits out. */
- for (i = 8; i >= 0; i--) {
- short outval = (read_cmd & (1 << i)) ? ctrl_val | EE_DATA_WRITE
- : ctrl_val;
- outb(outval, ee_addr);
- outb(outval | EE_SHIFT_CLK, ee_addr); /* EEPROM clock tick. */
- eeprom_delay();
- outb(outval, ee_addr); /* Finish EEPROM a clock tick. */
- eeprom_delay();
- }
- outb(ctrl_val, ee_addr);
-
- for (i = 16; i > 0; i--) {
- outb(ctrl_val | EE_SHIFT_CLK, ee_addr); eeprom_delay();
- retval = (retval << 1) | ((inb(ee_addr) & EE_DATA_READ) ? 1 : 0);
- outb(ctrl_val, ee_addr); eeprom_delay();
- }
-
- /* Terminate the EEPROM access. */
- ctrl_val &= ~EE_CS;
- outb(ctrl_val | EE_SHIFT_CLK, ee_addr);
- eeprom_delay();
- outb(ctrl_val, ee_addr);
- eeprom_delay();
- return retval;
-}
-
-static void
-init_82586_mem(struct device *dev)
-{
- struct net_local *lp = (struct net_local *)dev->priv;
- short ioaddr = dev->base_addr;
-
- /* Enable loopback to protect the wire while starting up.
- This is Superstition From Crynwr. */
- outb(inb(ioaddr + Config) | 0x02, ioaddr + Config);
-
- /* Hold the 586 in reset during the memory initialization. */
- outb(_586_RESET, ioaddr + EEPROM_Ctrl);
-
- /* Place the write pointer at 0xfff6 (address-aliased to 0xfffff6). */
- outw(0xfff6, ioaddr + WRITE_PTR);
- outsw(ioaddr, init_words, sizeof(init_words)>>1);
-
- /* Fill in the station address. */
- outw(SA_OFFSET, ioaddr + WRITE_PTR);
- outsw(ioaddr, dev->dev_addr, 3);
-
- /* The Tx-block list is written as needed. We just set up the values. */
-#ifdef initial_text_tx
- lp->tx_cmd_link = DUMP_DATA + 4;
-#else
- lp->tx_cmd_link = IDLELOOP + 4;
-#endif
- lp->tx_head = lp->tx_reap = TX_BUF_START;
-
- init_rx_bufs(dev);
-
- /* Start the 586 by releasing the reset line. */
- outb(0x00, ioaddr + EEPROM_Ctrl);
-
- /* This was time consuming to track down: you need to give two channel
- attention signals to reliably start up the i82586. */
- outb(0, ioaddr + SIGNAL_CA);
-
- {
- int boguscnt = 50;
- while (inw(ioaddr + SCB_STATUS) == 0)
- if (--boguscnt == 0) {
- printk("%s: i82586 initialization timed out with status %04x, cmd %04x.\n",
- dev->name, inw(ioaddr + SCB_STATUS), inw(ioaddr + SCB_CMD));
- break;
- }
- /* Issue channel-attn -- the 82586 won't start without it. */
- outb(0, ioaddr + SIGNAL_CA);
- }
-
- /* Disable loopback. */
- outb(inb(ioaddr + Config) & ~0x02, ioaddr + Config);
- if (net_debug > 4)
- printk("%s: Initialized 82586, status %04x.\n", dev->name,
- inw(ioaddr + SCB_STATUS));
- return;
-}
-
-/* Initialize the Rx-block list. */
-static void init_rx_bufs(struct device *dev)
-{
- struct net_local *lp = (struct net_local *)dev->priv;
- short ioaddr = dev->base_addr;
-
- int cur_rxbuf = lp->rx_head = RX_BUF_START;
-
- /* Initialize each Rx frame + data buffer. */
- do { /* While there is room for one more. */
- outw(cur_rxbuf, ioaddr + WRITE_PTR);
- outw(0x0000, ioaddr); /* Status */
- outw(0x0000, ioaddr); /* Command */
- outw(cur_rxbuf + RX_BUF_SIZE, ioaddr); /* Link */
- outw(cur_rxbuf + 22, ioaddr); /* Buffer offset */
- outw(0xFeed, ioaddr); /* Pad for dest addr. */
- outw(0xF00d, ioaddr);
- outw(0xF001, ioaddr);
- outw(0x0505, ioaddr); /* Pad for source addr. */
- outw(0x2424, ioaddr);
- outw(0x6565, ioaddr);
- outw(0xdeaf, ioaddr); /* Pad for protocol. */
-
- outw(0x0000, ioaddr); /* Buffer: Actual count */
- outw(-1, ioaddr); /* Buffer: Next (none). */
- outw(cur_rxbuf + 0x20, ioaddr); /* Buffer: Address low */
- outw(0x0000, ioaddr);
- /* Finally, the number of bytes in the buffer. */
- outw(0x8000 + RX_BUF_SIZE-0x20, ioaddr);
-
- lp->rx_tail = cur_rxbuf;
- cur_rxbuf += RX_BUF_SIZE;
- } while (cur_rxbuf <= RX_BUF_END - RX_BUF_SIZE);
-
- /* Terminate the list by setting the EOL bit, and wrap the pointer to make
- the list a ring. */
- outw(lp->rx_tail + 2, ioaddr + WRITE_PTR);
- outw(0xC000, ioaddr); /* Command, mark as last. */
- outw(lp->rx_head, ioaddr); /* Link */
-}
-
-static void
-hardware_send_packet(struct device *dev, void *buf, short length)
-{
- struct net_local *lp = (struct net_local *)dev->priv;
- short ioaddr = dev->base_addr;
- short tx_block = lp->tx_head;
-
- /* Set the write pointer to the Tx block, and put out the header. */
- outw(tx_block, ioaddr + WRITE_PTR);
- outw(0x0000, ioaddr); /* Tx status */
- outw(CMD_INTR|CmdTx, ioaddr); /* Tx command */
- outw(tx_block+16, ioaddr); /* Next command is a NoOp. */
- outw(tx_block+8, ioaddr); /* Data Buffer offset. */
-
- /* Output the data buffer descriptor. */
- outw(length | 0x8000, ioaddr); /* Byte count parameter. */
- outw(-1, ioaddr); /* No next data buffer. */
- outw(tx_block+22, ioaddr); /* Buffer follows the NoOp command. */
- outw(0x0000, ioaddr); /* Buffer address high bits (always zero). */
-
- /* Output the Loop-back NoOp command. */
- outw(0x0000, ioaddr); /* Tx status */
- outw(CmdNOp, ioaddr); /* Tx command */
- outw(tx_block+16, ioaddr); /* Next is myself. */
-
- /* Output the packet using the write pointer.
- Hmmm, it feels a little like a 3c501! */
- outsw(ioaddr + DATAPORT, buf, (length + 1) >> 1);
-
- /* Set the old command link pointing to this send packet. */
- outw(lp->tx_cmd_link, ioaddr + WRITE_PTR);
- outw(tx_block, ioaddr);
- lp->tx_cmd_link = tx_block + 20;
-
- /* Set the next free tx region. */
- lp->tx_head = tx_block + TX_BUF_SIZE;
- if (lp->tx_head > TX_BUF_END - TX_BUF_SIZE)
- lp->tx_head = TX_BUF_START;
-
- if (net_debug > 4) {
- printk("%s: EExp @%x send length = %d, tx_block %3x, next %3x, "
- "reap %4x status %4.4x.\n", dev->name, ioaddr, length,
- tx_block, lp->tx_head, lp->tx_reap, inw(ioaddr + SCB_STATUS));
- }
-
- if (lp->tx_head != lp->tx_reap)
- dev->tbusy = 0;
-}
-
-static void
-eexp_rx(struct device *dev)
-{
- struct net_local *lp = (struct net_local *)dev->priv;
- short ioaddr = dev->base_addr;
- short saved_write_ptr = inw(ioaddr + WRITE_PTR);
- short rx_head = lp->rx_head;
- short rx_tail = lp->rx_tail;
- short boguscount = 10;
- short frame_status;
-
- /* Set the read pointer to the Rx frame. */
- outw(rx_head, ioaddr + READ_PTR);
- while ((frame_status = inw(ioaddr)) < 0) { /* Command complete */
- short rfd_cmd = inw(ioaddr);
- short next_rx_frame = inw(ioaddr);
- short data_buffer_addr = inw(ioaddr);
- short pkt_len;
-
- /* Set the read pointer the data buffer. */
- outw(data_buffer_addr, ioaddr + READ_PTR);
- pkt_len = inw(ioaddr);
-
- if (rfd_cmd != 0 || data_buffer_addr != rx_head + 22
- || (pkt_len & 0xC000) != 0xC000) {
- printk("%s: Rx frame at %#x corrupted, status %04x cmd %04x"
- "next %04x data-buf @%04x %04x.\n", dev->name, rx_head,
- frame_status, rfd_cmd, next_rx_frame, data_buffer_addr,
- pkt_len);
- } else if ((frame_status & 0x2000) == 0) {
- /* Frame Rxed, but with error. */
- lp->stats.rx_errors++;
- if (frame_status & 0x0800) lp->stats.rx_crc_errors++;
- if (frame_status & 0x0400) lp->stats.rx_frame_errors++;
- if (frame_status & 0x0200) lp->stats.rx_fifo_errors++;
- if (frame_status & 0x0100) lp->stats.rx_over_errors++;
- if (frame_status & 0x0080) lp->stats.rx_length_errors++;
- } else {
- /* Malloc up new buffer. */
- struct sk_buff *skb;
-
- pkt_len &= 0x3fff;
- skb = dev_alloc_skb(pkt_len+2);
- if (skb == NULL) {
- printk("%s: Memory squeeze, dropping packet.\n", dev->name);
- lp->stats.rx_dropped++;
- break;
- }
- skb->dev = dev;
- skb_reserve(skb,2);
-
- outw(data_buffer_addr + 10, ioaddr + READ_PTR);
-
- insw(ioaddr, skb_put(skb,pkt_len), (pkt_len + 1) >> 1);
-
- skb->protocol=eth_type_trans(skb,dev);
- netif_rx(skb);
- lp->stats.rx_packets++;
- }
-
- /* Clear the status word and set End-of-List on the rx frame. */
- outw(rx_head, ioaddr + WRITE_PTR);
- outw(0x0000, ioaddr);
- outw(0xC000, ioaddr);
-#ifndef final_version
- if (next_rx_frame != rx_head + RX_BUF_SIZE
- && next_rx_frame != RX_BUF_START) {
- printk("%s: Rx next frame at %#x is %#x instead of %#x.\n", dev->name,
- rx_head, next_rx_frame, rx_head + RX_BUF_SIZE);
- next_rx_frame = rx_head + RX_BUF_SIZE;
- if (next_rx_frame >= RX_BUF_END - RX_BUF_SIZE)
- next_rx_frame = RX_BUF_START;
- }
-#endif
- outw(rx_tail+2, ioaddr + WRITE_PTR);
- outw(0x0000, ioaddr); /* Clear the end-of-list on the prev. RFD. */
-
-#ifndef final_version
- outw(rx_tail+4, ioaddr + READ_PTR);
- if (inw(ioaddr) != rx_head) {
- printk("%s: Rx buf link mismatch, at %04x link %04x instead of %04x.\n",
- dev->name, rx_tail, (outw(rx_tail+4, ioaddr + READ_PTR),inw(ioaddr)),
- rx_head);
- outw(rx_head, ioaddr);
- }
-#endif
-
- rx_tail = rx_head;
- rx_head = next_rx_frame;
- if (--boguscount == 0)
- break;
- outw(rx_head, ioaddr + READ_PTR);
- }
-
- lp->rx_head = rx_head;
- lp->rx_tail = rx_tail;
-
- /* Restore the original write pointer. */
- outw(saved_write_ptr, ioaddr + WRITE_PTR);
-}
-
-#ifdef MODULE
-static char devicename[9] = { 0, };
-static struct device dev_eexpress = {
- devicename, /* device name is inserted by linux/drivers/net/net_init.c */
- 0, 0, 0, 0,
- 0, 0,
- 0, 0, 0, NULL, express_probe };
-
-
-static int irq=0x300;
-static int io=0;
-
-int
-init_module(void)
-{
- if (io == 0)
- printk("eexpress: You should not use auto-probing with insmod!\n");
- dev_eexpress.base_addr=io;
- dev_eexpress.irq=irq;
- if (register_netdev(&dev_eexpress) != 0)
- return -EIO;
- return 0;
-}
-
-void
-cleanup_module(void)
-{
- unregister_netdev(&dev_eexpress);
- kfree_s(dev_eexpress.priv,sizeof(struct net_local));
- dev_eexpress.priv=NULL;
-
- /* If we don't do this, we can't re-insmod it later. */
- release_region(dev_eexpress.base_addr, EEXPRESS_IO_EXTENT);
-}
-#endif /* MODULE */
-/*
- * Local variables:
- * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -I/usr/src/linux/drivers/net -Wall -Wstrict-prototypes -O6 -m486 -c eexpress.c"
- * version-control: t
- * kept-new-versions: 5
- * tab-width: 4
- * End:
- */
diff --git a/i386/i386at/gpl/linux/net/eth16i.c b/i386/i386at/gpl/linux/net/eth16i.c
deleted file mode 100644
index b21e4f33..00000000
--- a/i386/i386at/gpl/linux/net/eth16i.c
+++ /dev/null
@@ -1,1214 +0,0 @@
-/* eth16i.c An ICL EtherTeam 16i and 32 EISA ethernet driver for Linux
-
- Written 1994-95 by Mika Kuoppala
-
- Copyright (C) 1994, 1995 by Mika Kuoppala
- Based on skeleton.c and at1700.c by Donald Becker
-
- This software may be used and distributed according to the terms
- of the GNU Public Licence, incorporated herein by reference.
-
- The author may be reached as miku@elt.icl.fi
-
- This driver supports following cards :
- - ICL EtherTeam 16i
- - ICL EtherTeam 32 EISA
-
- Sources:
- - skeleton.c a sample network driver core for linux,
- written by Donald Becker <becker@CESDIS.gsfc.nasa.gov>
- - at1700.c a driver for Allied Telesis AT1700, written
- by Donald Becker.
- - e16iSRV.asm a Netware 3.X Server Driver for ICL EtherTeam16i
- written by Markku Viima
- - The Fujitsu MB86965 databook.
-
- Valuable assistance from:
- Markku Viima (ICL)
- Ari Valve (ICL)
-
- Revision history:
-
- Version Date Description
-
- 0.01 15.12-94 Initial version (card detection)
- 0.02 23.01-95 Interrupt is now hooked correctly
- 0.03 01.02-95 Rewrote initialization part
- 0.04 07.02-95 Base skeleton done...
- Made a few changes to signature checking
- to make it a bit reliable.
- - fixed bug in tx_buf mapping
- - fixed bug in initialization (DLC_EN
- wasn't enabled when initialization
- was done.)
- 0.05 08.02-95 If there were more than one packet to send,
- transmit was jammed due to invalid
- register write...now fixed
- 0.06 19.02-95 Rewrote interrupt handling
- 0.07 13.04-95 Wrote EEPROM read routines
- Card configuration now set according to
- data read from EEPROM
- 0.08 23.06-95 Wrote part that tries to probe used interface
- port if AUTO is selected
-
- 0.09 01.09-95 Added module support
-
- 0.10 04.09-95 Fixed receive packet allocation to work
- with kernels > 1.3.x
-
- 0.20 20.09-95 Added support for EtherTeam32 EISA
-
- 0.21 17.10-95 Removed the unnecessary extern
- init_etherdev() declaration. Some
- other cleanups.
- Bugs:
- In some cases the interface autoprobing code doesn't find
- the correct interface type. In this case you can
- manually choose the interface type in DOS with E16IC.EXE which is
- configuration software for EtherTeam16i and EtherTeam32 cards.
-
- To do:
- - Real multicast support
-*/
-
-static char *version =
- "eth16i.c: v0.21 17-10-95 Mika Kuoppala (miku@elt.icl.fi)\n";
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ptrace.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/malloc.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-
-#include <asm/system.h>
-#include <asm/bitops.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-
-/* Few macros */
-#define BIT(a) ( (1 << (a)) )
-#define BITSET(ioaddr, bnum) ((outb(((inb(ioaddr)) | (bnum)), ioaddr)))
-#define BITCLR(ioaddr, bnum) ((outb(((inb(ioaddr)) & (~(bnum))), ioaddr)))
-
-/* This is the I/O address space for Etherteam 16i adapter. */
-#define ETH16I_IO_EXTENT 32
-
-/* Ticks before deciding that transmit has timed out */
-#define TIMEOUT_TICKS 30
-
-/* Maximum loop count when receiving packets */
-#define MAX_RX_LOOP 40
-
-/* Some interrupt masks */
-#define ETH16I_INTR_ON 0x8f82
-#define ETH16I_INTR_OFF 0x0000
-
-/* Buffers header status byte meanings */
-#define PKT_GOOD BIT(5)
-#define PKT_GOOD_RMT BIT(4)
-#define PKT_SHORT BIT(3)
-#define PKT_ALIGN_ERR BIT(2)
-#define PKT_CRC_ERR BIT(1)
-#define PKT_RX_BUF_OVERFLOW BIT(0)
-
-/* Transmit status register (DLCR0) */
-#define TX_STATUS_REG 0
-#define TX_DONE BIT(7)
-#define NET_BUSY BIT(6)
-#define TX_PKT_RCD BIT(5)
-#define CR_LOST BIT(4)
-#define COLLISION BIT(2)
-#define COLLISIONS_16 BIT(1)
-
-/* Receive status register (DLCR1) */
-#define RX_STATUS_REG 1
-#define RX_PKT BIT(7) /* Packet received */
-#define BUS_RD_ERR BIT(6)
-#define SHORT_PKT_ERR BIT(3)
-#define ALIGN_ERR BIT(2)
-#define CRC_ERR BIT(1)
-#define RX_BUF_OVERFLOW BIT(0)
-
-/* Transmit Interrupt Enable Register (DLCR2) */
-#define TX_INTR_REG 2
-#define TX_INTR_DONE BIT(7)
-#define TX_INTR_COL BIT(2)
-#define TX_INTR_16_COL BIT(1)
-
-/* Receive Interrupt Enable Register (DLCR3) */
-#define RX_INTR_REG 3
-#define RX_INTR_RECEIVE BIT(7)
-#define RX_INTR_SHORT_PKT BIT(3)
-#define RX_INTR_CRC_ERR BIT(1)
-#define RX_INTR_BUF_OVERFLOW BIT(0)
-
-/* Transmit Mode Register (DLCR4) */
-#define TRANSMIT_MODE_REG 4
-#define LOOPBACK_CONTROL BIT(1)
-#define CONTROL_OUTPUT BIT(2)
-
-/* Receive Mode Register (DLCR5) */
-#define RECEIVE_MODE_REG 5
-#define RX_BUFFER_EMPTY BIT(6)
-#define ACCEPT_BAD_PACKETS BIT(5)
-#define RECEIVE_SHORT_ADDR BIT(4)
-#define ACCEPT_SHORT_PACKETS BIT(3)
-#define REMOTE_RESET BIT(2)
-
-#define ADDRESS_FILTER_MODE BIT(1) | BIT(0)
-#define REJECT_ALL 0
-#define ACCEPT_ALL 3
-#define MODE_1 1 /* NODE ID, BC, MC, 2-24th bit */
-#define MODE_2 2 /* NODE ID, BC, MC, Hash Table */
-
-/* Configuration Register 0 (DLCR6) */
-#define CONFIG_REG_0 6
-#define DLC_EN BIT(7)
-#define SRAM_CYCLE_TIME_100NS BIT(6)
-#define SYSTEM_BUS_WIDTH_8 BIT(5) /* 1 = 8bit, 0 = 16bit */
-#define BUFFER_WIDTH_8 BIT(4) /* 1 = 8bit, 0 = 16bit */
-#define TBS1 BIT(3)
-#define TBS0 BIT(2)
-#define BS1 BIT(1) /* 00=8kb, 01=16kb */
-#define BS0 BIT(0) /* 10=32kb, 11=64kb */
-
-#ifndef ETH16I_TX_BUF_SIZE /* 0 = 2kb, 1 = 4kb */
-#define ETH16I_TX_BUF_SIZE 2 /* 2 = 8kb, 3 = 16kb */
-#endif
-#define TX_BUF_1x2048 0
-#define TX_BUF_2x2048 1
-#define TX_BUF_2x4098 2
-#define TX_BUF_2x8192 3
-
-/* Configuration Register 1 (DLCR7) */
-#define CONFIG_REG_1 7
-#define POWERUP BIT(5)
-
-/* Transmit start register */
-#define TRANSMIT_START_REG 10
-#define TRANSMIT_START_RB 2
-#define TX_START BIT(7) /* Rest of register bit indicate*/
- /* number of packets in tx buffer*/
-/* Node ID registers (DLCR8-13) */
-#define NODE_ID_0 8
-#define NODE_ID_RB 0
-
-/* Hash Table registers (HT8-15) */
-#define HASH_TABLE_0 8
-#define HASH_TABLE_RB 1
-
-/* Buffer memory ports */
-#define BUFFER_MEM_PORT_LB 8
-#define DATAPORT BUFFER_MEM_PORT_LB
-#define BUFFER_MEM_PORT_HB 9
-
-/* 16 Collision control register (BMPR11) */
-#define COL_16_REG 11
-#define HALT_ON_16 0x00
-#define RETRANS_AND_HALT_ON_16 0x02
-
-/* DMA Burst and Transceiver Mode Register (BMPR13) */
-#define TRANSCEIVER_MODE_REG 13
-#define TRANSCEIVER_MODE_RB 2
-#define IO_BASE_UNLOCK BIT(7)
-#define LOWER_SQUELCH_TRESH BIT(6)
-#define LINK_TEST_DISABLE BIT(5)
-#define AUI_SELECT BIT(4)
-#define DIS_AUTO_PORT_SEL BIT(3)
-
-/* Filter Self Receive Register (BMPR14) */
-#define FILTER_SELF_RX_REG 14
-#define SKIP_RECEIVE_PACKET BIT(2)
-#define FILTER_SELF_RECEIVE BIT(0)
-#define RX_BUF_SKIP_PACKET SKIP_RECEIVE_PACKET | FILTER_SELF_RECEIVE
-
-/* EEPROM Control Register (BMPR 16) */
-#define EEPROM_CTRL_REG 16
-
-/* EEPROM Data Register (BMPR 17) */
-#define EEPROM_DATA_REG 17
-
-/* NMC93CSx6 EEPROM Control Bits */
-#define CS_0 0x00
-#define CS_1 0x20
-#define SK_0 0x00
-#define SK_1 0x40
-#define DI_0 0x00
-#define DI_1 0x80
-
-/* NMC93CSx6 EEPROM Instructions */
-#define EEPROM_READ 0x80
-
-/* NMC93CSx6 EEPROM Addresses */
-#define E_NODEID_0 0x02
-#define E_NODEID_1 0x03
-#define E_NODEID_2 0x04
-#define E_PORT_SELECT 0x14
- #define E_PORT_BNC 0
- #define E_PORT_DIX 1
- #define E_PORT_TP 2
- #define E_PORT_AUTO 3
-#define E_PRODUCT_CFG 0x30
-
-
-/* Macro to slow down io between EEPROM clock transitions */
-#define eeprom_slow_io() do { int _i = 40; while(--_i > 0) { __SLOW_DOWN_IO; }}while(0)
-
-/* Jumperless Configuration Register (BMPR19) */
-#define JUMPERLESS_CONFIG 19
-
-/* ID ROM registers, writing to them also resets some parts of chip */
-#define ID_ROM_0 24
-#define ID_ROM_7 31
-#define RESET ID_ROM_0
-
-/* This is the I/O address list to be probed when seeking the card */
-static unsigned int eth16i_portlist[] =
- { 0x260, 0x280, 0x2A0, 0x240, 0x340, 0x320, 0x380, 0x300, 0 };
-
-static unsigned int eth32i_portlist[] =
- { 0x1000, 0x2000, 0x3000, 0x4000, 0x5000, 0x6000, 0x7000, 0x8000,
- 0x9000, 0xA000, 0xB000, 0xC000, 0xD000, 0xE000, 0xF000, 0 };
-
-/* This is the Interrupt lookup table for Eth16i card */
-static unsigned int eth16i_irqmap[] = { 9, 10, 5, 15 };
-
-/* This is the Interrupt lookup table for Eth32i card */
-static unsigned int eth32i_irqmap[] = { 3, 5, 7, 9, 10, 11, 12, 15 };
-#define EISA_IRQ_REG 0xc89
-
-static unsigned int eth16i_tx_buf_map[] = { 2048, 2048, 4096, 8192 };
-unsigned int boot = 1;
-
-/* Use 0 for production, 1 for verification, >2 for debug */
-#ifndef ETH16I_DEBUG
-#define ETH16I_DEBUG 0
-#endif
-static unsigned int eth16i_debug = ETH16I_DEBUG;
-
-/* Information for each board */
-struct eth16i_local {
- struct enet_statistics stats;
- unsigned int tx_started:1;
- unsigned char tx_queue; /* Number of packets in transmit buffer */
- unsigned short tx_queue_len;
- unsigned int tx_buf_size;
- unsigned long open_time;
-};
-
-/* Function prototypes */
-
-extern int eth16i_probe(struct device *dev);
-
-static int eth16i_probe1(struct device *dev, short ioaddr);
-static int eth16i_check_signature(short ioaddr);
-static int eth16i_probe_port(short ioaddr);
-static void eth16i_set_port(short ioaddr, int porttype);
-static int eth16i_send_probe_packet(short ioaddr, unsigned char *b, int l);
-static int eth16i_receive_probe_packet(short ioaddr);
-static int eth16i_get_irq(short ioaddr);
-static int eth16i_read_eeprom(int ioaddr, int offset);
-static int eth16i_read_eeprom_word(int ioaddr);
-static void eth16i_eeprom_cmd(int ioaddr, unsigned char command);
-static int eth16i_open(struct device *dev);
-static int eth16i_close(struct device *dev);
-static int eth16i_tx(struct sk_buff *skb, struct device *dev);
-static void eth16i_rx(struct device *dev);
-static void eth16i_interrupt(int irq, struct pt_regs *regs);
-static void eth16i_multicast(struct device *dev, int num_addrs, void *addrs);
-static void eth16i_select_regbank(unsigned char regbank, short ioaddr);
-static void eth16i_initialize(struct device *dev);
-static struct enet_statistics *eth16i_get_stats(struct device *dev);
-
-static char *cardname = "ICL EtherTeam 16i/32";
-
-#ifdef HAVE_DEVLIST
-/* Support for alternate probe manager */
-/struct netdev_entry eth16i_drv =
- {"eth16i", eth16i_probe1, ETH16I_IO_EXTENT, eth16i_probe_list};
-
-#else /* Not HAVE_DEVLIST */
-int eth16i_probe(struct device *dev)
-{
- int i;
- int ioaddr;
- int base_addr = dev ? dev->base_addr : 0;
-
- if(eth16i_debug > 4)
- printk("Probing started for %s\n", cardname);
-
- if(base_addr > 0x1ff) /* Check only single location */
- return eth16i_probe1(dev, base_addr);
- else if(base_addr != 0) /* Don't probe at all */
- return ENXIO;
-
- /* Seek card from the ISA io address space */
- for(i = 0; (ioaddr = eth16i_portlist[i]) ; i++) {
- if(check_region(ioaddr, ETH16I_IO_EXTENT))
- continue;
- if(eth16i_probe1(dev, ioaddr) == 0)
- return 0;
- }
-
- /* Seek card from the EISA io address space */
- for(i = 0; (ioaddr = eth32i_portlist[i]) ; i++) {
- if(check_region(ioaddr, ETH16I_IO_EXTENT))
- continue;
- if(eth16i_probe1(dev, ioaddr) == 0)
- return 0;
- }
-
- return ENODEV;
-}
-#endif /* Not HAVE_DEVLIST */
-
-static int eth16i_probe1(struct device *dev, short ioaddr)
-{
- static unsigned version_printed = 0;
- unsigned int irq = 0;
- boot = 1; /* To inform initilization that we are in boot probe */
-
- /*
- The MB86985 chip has on register which holds information in which
- io address the chip lies. First read this register and compare
- it to our current io address and if match then this could
- be our chip.
- */
-
- if(ioaddr < 0x1000) {
- if(eth16i_portlist[(inb(ioaddr + JUMPERLESS_CONFIG) & 0x07)] != ioaddr)
- return -ENODEV;
- }
-
- /* Now we will go a bit deeper and try to find the chip's signature */
-
- if(eth16i_check_signature(ioaddr) != 0) /* Can we find the signature here */
- return -ENODEV;
-
- /*
- Now it seems that we have found a ethernet chip in this particular
- ioaddr. The MB86985 chip has this feature, that when you read a
- certain register it will increase it's io base address to next
- configurable slot. Now when we have found the chip, first thing is
- to make sure that the chip's ioaddr will hold still here.
- */
-
- eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr);
- outb(0x00, ioaddr + TRANSCEIVER_MODE_REG);
-
- outb(0x00, ioaddr + RESET); /* Will reset some parts of chip */
- BITSET(ioaddr + CONFIG_REG_0, BIT(7)); /* This will disable the data link */
-
- if(dev == NULL)
- dev = init_etherdev(0, sizeof(struct eth16i_local));
-
- if( (eth16i_debug & version_printed++) == 0)
- printk(version);
-
- dev->base_addr = ioaddr;
-
- irq = eth16i_get_irq(ioaddr);
- dev->irq = irq;
-
- /* Try to obtain interrupt vector */
- if(request_irq(dev->irq, &eth16i_interrupt, 0, "eth16i")) {
- printk("%s: %s at %#3x, but is unusable due
- conflict on IRQ %d.\n", dev->name, cardname, ioaddr, irq);
- return EAGAIN;
- }
-
- printk("%s: %s at %#3x, IRQ %d, ",
- dev->name, cardname, ioaddr, dev->irq);
-
- /* Let's grab the region */
- request_region(ioaddr, ETH16I_IO_EXTENT, "eth16i");
-
- /* Now we will have to lock the chip's io address */
- eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr);
- outb(0x38, ioaddr + TRANSCEIVER_MODE_REG);
-
- eth16i_initialize(dev); /* Initialize rest of the chip's registers */
-
- /* Now let's same some energy by shutting down the chip ;) */
- BITCLR(ioaddr + CONFIG_REG_1, POWERUP);
-
- /* Initialize the device structure */
- if(dev->priv == NULL)
- dev->priv = kmalloc(sizeof(struct eth16i_local), GFP_KERNEL);
- memset(dev->priv, 0, sizeof(struct eth16i_local));
-
- dev->open = eth16i_open;
- dev->stop = eth16i_close;
- dev->hard_start_xmit = eth16i_tx;
- dev->get_stats = eth16i_get_stats;
- dev->set_multicast_list = &eth16i_multicast;
-
- /* Fill in the fields of the device structure with ethernet values. */
- ether_setup(dev);
-
- boot = 0;
-
- return 0;
-}
-
-
-static void eth16i_initialize(struct device *dev)
-{
- short ioaddr = dev->base_addr;
- int i, node_w = 0;
- unsigned char node_byte = 0;
-
- /* Setup station address */
- eth16i_select_regbank(NODE_ID_RB, ioaddr);
- for(i = 0 ; i < 3 ; i++) {
- unsigned short node_val = eth16i_read_eeprom(ioaddr, E_NODEID_0 + i);
- ((unsigned short *)dev->dev_addr)[i] = ntohs(node_val);
- }
-
- for(i = 0; i < 6; i++) {
- outb( ((unsigned char *)dev->dev_addr)[i], ioaddr + NODE_ID_0 + i);
- if(boot) {
- printk("%02x", inb(ioaddr + NODE_ID_0 + i));
- if(i != 5)
- printk(":");
- }
- }
-
- /* Now we will set multicast addresses to accept none */
- eth16i_select_regbank(HASH_TABLE_RB, ioaddr);
- for(i = 0; i < 8; i++)
- outb(0x00, ioaddr + HASH_TABLE_0 + i);
-
- /*
- Now let's disable the transmitter and receiver, set the buffer ram
- cycle time, bus width and buffer data path width. Also we shall
- set transmit buffer size and total buffer size.
- */
-
- eth16i_select_regbank(2, ioaddr);
-
- node_byte = 0;
- node_w = eth16i_read_eeprom(ioaddr, E_PRODUCT_CFG);
-
- if( (node_w & 0xFF00) == 0x0800)
- node_byte |= BUFFER_WIDTH_8;
-
- node_byte |= BS1;
-
- if( (node_w & 0x00FF) == 64)
- node_byte |= BS0;
-
- node_byte |= DLC_EN | SRAM_CYCLE_TIME_100NS | (ETH16I_TX_BUF_SIZE << 2);
-
- outb(node_byte, ioaddr + CONFIG_REG_0);
-
- /* We shall halt the transmitting, if 16 collisions are detected */
- outb(RETRANS_AND_HALT_ON_16, ioaddr + COL_16_REG);
-
- if(boot) /* Now set port type */
- {
- char *porttype[] = {"BNC", "DIX", "TP", "AUTO"};
-
- ushort ptype = eth16i_read_eeprom(ioaddr, E_PORT_SELECT);
- dev->if_port = (ptype & 0x00FF);
-
- printk(" %s interface.\n", porttype[dev->if_port]);
-
- if(ptype == E_PORT_AUTO)
- ptype = eth16i_probe_port(ioaddr);
-
- eth16i_set_port(ioaddr, ptype);
- }
-
- /* Set Receive Mode to normal operation */
- outb(MODE_2, ioaddr + RECEIVE_MODE_REG);
-}
-
-static int eth16i_probe_port(short ioaddr)
-{
- int i;
- int retcode;
- unsigned char dummy_packet[64] = { 0 };
-
- /* Powerup the chip */
- outb(0xc0 | POWERUP, ioaddr + CONFIG_REG_1);
-
- BITSET(ioaddr + CONFIG_REG_0, DLC_EN);
-
- eth16i_select_regbank(NODE_ID_RB, ioaddr);
-
- for(i = 0; i < 6; i++) {
- dummy_packet[i] = inb(ioaddr + NODE_ID_0 + i);
- dummy_packet[i+6] = inb(ioaddr + NODE_ID_0 + i);
- }
-
- dummy_packet[12] = 0x00;
- dummy_packet[13] = 0x04;
-
- eth16i_select_regbank(2, ioaddr);
-
- for(i = 0; i < 3; i++) {
- BITSET(ioaddr + CONFIG_REG_0, DLC_EN);
- BITCLR(ioaddr + CONFIG_REG_0, DLC_EN);
- eth16i_set_port(ioaddr, i);
-
- if(eth16i_debug > 1)
- printk("Set port number %d\n", i);
-
- retcode = eth16i_send_probe_packet(ioaddr, dummy_packet, 64);
- if(retcode == 0) {
- retcode = eth16i_receive_probe_packet(ioaddr);
- if(retcode != -1) {
- if(eth16i_debug > 1)
- printk("Eth16i interface port found at %d\n", i);
- return i;
- }
- }
- else {
- if(eth16i_debug > 1)
- printk("TRANSMIT_DONE timeout\n");
- }
- }
-
- if( eth16i_debug > 1)
- printk("Using default port\n");
-
- return E_PORT_BNC;
-}
-
-static void eth16i_set_port(short ioaddr, int porttype)
-{
- unsigned short temp = 0;
-
- eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr);
- outb(LOOPBACK_CONTROL, ioaddr + TRANSMIT_MODE_REG);
-
- temp |= DIS_AUTO_PORT_SEL;
-
- switch(porttype) {
-
- case E_PORT_BNC :
- temp |= AUI_SELECT;
- break;
-
- case E_PORT_TP :
- break;
-
- case E_PORT_DIX :
- temp |= AUI_SELECT;
- BITSET(ioaddr + TRANSMIT_MODE_REG, CONTROL_OUTPUT);
- break;
- }
- outb(temp, ioaddr + TRANSCEIVER_MODE_REG);
-
- if(eth16i_debug > 1) {
- printk("TRANSMIT_MODE_REG = %x\n", inb(ioaddr + TRANSMIT_MODE_REG));
- printk("TRANSCEIVER_MODE_REG = %x\n", inb(ioaddr+TRANSCEIVER_MODE_REG));
- }
-}
-
-static int eth16i_send_probe_packet(short ioaddr, unsigned char *b, int l)
-{
- int starttime;
-
- outb(0xff, ioaddr + TX_STATUS_REG);
-
- outw(l, ioaddr + DATAPORT);
- outsw(ioaddr + DATAPORT, (unsigned short *)b, (l + 1) >> 1);
-
- starttime = jiffies;
- outb(TX_START | 1, ioaddr + TRANSMIT_START_REG);
-
- while( (inb(ioaddr + TX_STATUS_REG) & 0x80) == 0) {
- if( (jiffies - starttime) > TIMEOUT_TICKS) {
- break;
- }
- }
-
- return(0);
-}
-
-static int eth16i_receive_probe_packet(short ioaddr)
-{
- int starttime;
-
- starttime = jiffies;
-
- while((inb(ioaddr + TX_STATUS_REG) & 0x20) == 0) {
- if( (jiffies - starttime) > TIMEOUT_TICKS) {
-
- if(eth16i_debug > 1)
- printk("Timeout occured waiting transmit packet received\n");
- starttime = jiffies;
- while((inb(ioaddr + RX_STATUS_REG) & 0x80) == 0) {
- if( (jiffies - starttime) > TIMEOUT_TICKS) {
- if(eth16i_debug > 1)
- printk("Timeout occured waiting receive packet\n");
- return -1;
- }
- }
-
- if(eth16i_debug > 1)
- printk("RECEIVE_PACKET\n");
- return(0); /* Found receive packet */
- }
- }
-
- if(eth16i_debug > 1) {
- printk("TRANSMIT_PACKET_RECEIVED %x\n", inb(ioaddr + TX_STATUS_REG));
- printk("RX_STATUS_REG = %x\n", inb(ioaddr + RX_STATUS_REG));
- }
-
- return(0); /* Return success */
-}
-
-static int eth16i_get_irq(short ioaddr)
-{
- unsigned char cbyte;
-
- if( ioaddr < 0x1000) {
- cbyte = inb(ioaddr + JUMPERLESS_CONFIG);
- return( eth16i_irqmap[ ((cbyte & 0xC0) >> 6) ] );
- } else { /* Oh..the card is EISA so method getting IRQ different */
- unsigned short index = 0;
- cbyte = inb(ioaddr + EISA_IRQ_REG);
- while( (cbyte & 0x01) == 0) {
- cbyte = cbyte >> 1;
- index++;
- }
- return( eth32i_irqmap[ index ] );
- }
-}
-
-static int eth16i_check_signature(short ioaddr)
-{
- int i;
- unsigned char creg[4] = { 0 };
-
- for(i = 0; i < 4 ; i++) {
-
- creg[i] = inb(ioaddr + TRANSMIT_MODE_REG + i);
-
- if(eth16i_debug > 1)
- printk("eth16i: read signature byte %x at %x\n", creg[i],
- ioaddr + TRANSMIT_MODE_REG + i);
- }
-
- creg[0] &= 0x0F; /* Mask collision cnr */
- creg[2] &= 0x7F; /* Mask DCLEN bit */
-
-#ifdef 0
-/*
- This was removed because the card was sometimes left to state
- from which it couldn't be find anymore. If there is need
- to more strict chech still this have to be fixed.
-*/
- if( !( (creg[0] == 0x06) && (creg[1] == 0x41)) ) {
- if(creg[1] != 0x42)
- return -1;
- }
-#endif
-
- if( !( (creg[2] == 0x36) && (creg[3] == 0xE0)) ) {
- creg[2] &= 0x42;
- creg[3] &= 0x03;
-
- if( !( (creg[2] == 0x42) && (creg[3] == 0x00)) )
- return -1;
- }
-
- if(eth16i_read_eeprom(ioaddr, E_NODEID_0) != 0)
- return -1;
- if((eth16i_read_eeprom(ioaddr, E_NODEID_1) & 0xFF00) != 0x4B00)
- return -1;
-
- return 0;
-}
-
-static int eth16i_read_eeprom(int ioaddr, int offset)
-{
- int data = 0;
-
- eth16i_eeprom_cmd(ioaddr, EEPROM_READ | offset);
- outb(CS_1, ioaddr + EEPROM_CTRL_REG);
- data = eth16i_read_eeprom_word(ioaddr);
- outb(CS_0 | SK_0, ioaddr + EEPROM_CTRL_REG);
-
- return(data);
-}
-
-static int eth16i_read_eeprom_word(int ioaddr)
-{
- int i;
- int data = 0;
-
- for(i = 16; i > 0; i--) {
- outb(CS_1 | SK_0, ioaddr + EEPROM_CTRL_REG);
- eeprom_slow_io();
- outb(CS_1 | SK_1, ioaddr + EEPROM_CTRL_REG);
- eeprom_slow_io();
- data = (data << 1) | ((inb(ioaddr + EEPROM_DATA_REG) & DI_1) ? 1 : 0);
- eeprom_slow_io();
- }
-
- return(data);
-}
-
-static void eth16i_eeprom_cmd(int ioaddr, unsigned char command)
-{
- int i;
-
- outb(CS_0 | SK_0, ioaddr + EEPROM_CTRL_REG);
- outb(DI_0, ioaddr + EEPROM_DATA_REG);
- outb(CS_1 | SK_0, ioaddr + EEPROM_CTRL_REG);
- outb(DI_1, ioaddr + EEPROM_DATA_REG);
- outb(CS_1 | SK_1, ioaddr + EEPROM_CTRL_REG);
-
- for(i = 7; i >= 0; i--) {
- short cmd = ( (command & (1 << i)) ? DI_1 : DI_0 );
- outb(cmd, ioaddr + EEPROM_DATA_REG);
- outb(CS_1 | SK_0, ioaddr + EEPROM_CTRL_REG);
- eeprom_slow_io();
- outb(CS_1 | SK_1, ioaddr + EEPROM_CTRL_REG);
- eeprom_slow_io();
- }
-}
-
-static int eth16i_open(struct device *dev)
-{
- struct eth16i_local *lp = (struct eth16i_local *)dev->priv;
- int ioaddr = dev->base_addr;
-
- irq2dev_map[dev->irq] = dev;
-
- /* Powerup the chip */
- outb(0xc0 | POWERUP, ioaddr + CONFIG_REG_1);
-
- /* Initialize the chip */
- eth16i_initialize(dev);
-
- /* Set the transmit buffer size */
- lp->tx_buf_size = eth16i_tx_buf_map[ETH16I_TX_BUF_SIZE & 0x03];
-
- if(eth16i_debug > 3)
- printk("%s: transmit buffer size %d\n", dev->name, lp->tx_buf_size);
-
- /* Now enable Transmitter and Receiver sections */
- BITCLR(ioaddr + CONFIG_REG_0, DLC_EN);
-
- /* Now switch to register bank 2, for run time operation */
- eth16i_select_regbank(2, ioaddr);
-
- lp->open_time = jiffies;
- lp->tx_started = 0;
- lp->tx_queue = 0;
- lp->tx_queue_len = 0;
-
- /* Turn on interrupts*/
- outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
-
- dev->tbusy = 0;
- dev->interrupt = 0;
- dev->start = 1;
-
-#ifdef MODULE
- MOD_INC_USE_COUNT;
-#endif
-
- return 0;
-}
-
-static int eth16i_close(struct device *dev)
-{
- struct eth16i_local *lp = (struct eth16i_local *)dev->priv;
- int ioaddr = dev->base_addr;
-
- lp->open_time = 0;
-
- dev->tbusy = 1;
- dev->start = 0;
-
- /* Disable transmit and receive */
- BITSET(ioaddr + CONFIG_REG_0, DLC_EN);
-
- /* Reset the chip */
- outb(0xff, ioaddr + RESET);
-
- /* Save some energy by switching off power */
- BITCLR(ioaddr + CONFIG_REG_1, POWERUP);
-
-#ifdef MODULE
- MOD_DEC_USE_COUNT;
-#endif
-
- return 0;
-}
-
-static int eth16i_tx(struct sk_buff *skb, struct device *dev)
-{
- struct eth16i_local *lp = (struct eth16i_local *)dev->priv;
- int ioaddr = dev->base_addr;
-
- if(dev->tbusy) {
- /*
- If we get here, some higher level has decided that we are broken.
- There should really be a "kick me" function call instead.
- */
-
- int tickssofar = jiffies - dev->trans_start;
- if(tickssofar < TIMEOUT_TICKS) /* Let's not rush with our timeout, */
- return 1; /* wait a couple of ticks first */
-
- printk("%s: transmit timed out with status %04x, %s ?\n", dev->name,
- inw(ioaddr + TX_STATUS_REG),
- (inb(ioaddr + TX_STATUS_REG) & TX_DONE) ?
- "IRQ conflict" : "network cable problem");
-
- /* Let's dump all registers */
- if(eth16i_debug > 0) {
- printk("%s: timeout regs: %02x %02x %02x %02x %02x %02x %02x %02x.\n",
- dev->name, inb(ioaddr + 0), inb(ioaddr + 1), inb(ioaddr + 2),
- inb(ioaddr + 3), inb(ioaddr + 4), inb(ioaddr + 5),
- inb(ioaddr + 6), inb(ioaddr + 7));
-
-
- printk("lp->tx_queue = %d\n", lp->tx_queue);
- printk("lp->tx_queue_len = %d\n", lp->tx_queue_len);
- printk("lp->tx_started = %d\n", lp->tx_started);
-
- }
-
- lp->stats.tx_errors++;
-
- /* Now let's try to restart the adaptor */
-
- BITSET(ioaddr + CONFIG_REG_0, DLC_EN);
- outw(0xffff, ioaddr + RESET);
- eth16i_initialize(dev);
- outw(0xffff, ioaddr + TX_STATUS_REG);
- BITCLR(ioaddr + CONFIG_REG_0, DLC_EN);
-
- lp->tx_started = 0;
- lp->tx_queue = 0;
- lp->tx_queue_len = 0;
-
- outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
-
- dev->tbusy = 0;
- dev->trans_start = jiffies;
- }
-
- /*
- If some higher layer thinks we've missed an tx-done interrupt
- we are passed NULL. Caution: dev_tint() handles the cli()/sti()
- itself
- */
- if(skb == NULL) {
- dev_tint(dev);
- return 0;
- }
-
- /* Block a timer based transmitter from overlapping. This could better be
- done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
-
- /* Turn off TX interrupts */
- outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG);
-
- if(set_bit(0, (void *)&dev->tbusy) != 0)
- printk("%s: Transmitter access conflict.\n", dev->name);
- else {
- short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
- unsigned char *buf = skb->data;
-
- outw(length, ioaddr + DATAPORT);
-
- if( ioaddr < 0x1000 )
- outsw(ioaddr + DATAPORT, buf, (length + 1) >> 1);
- else {
- unsigned char frag = length % 4;
-
- outsl(ioaddr + DATAPORT, buf, length >> 2);
-
- if( frag != 0 ) {
- outsw(ioaddr + DATAPORT, (buf + (length & 0xFFFC)), 1);
- if( frag == 3 )
- outsw(ioaddr + DATAPORT, (buf + (length & 0xFFFC) + 2), 1);
- }
- }
-
- lp->tx_queue++;
- lp->tx_queue_len += length + 2;
-
- if(lp->tx_started == 0) {
- /* If the transmitter is idle..always trigger a transmit */
- outb(TX_START | lp->tx_queue, ioaddr + TRANSMIT_START_REG);
- lp->tx_queue = 0;
- lp->tx_queue_len = 0;
- dev->trans_start = jiffies;
- lp->tx_started = 1;
- dev->tbusy = 0;
- }
- else if(lp->tx_queue_len < lp->tx_buf_size - (ETH_FRAME_LEN + 2)) {
- /* There is still more room for one more packet in tx buffer */
- dev->tbusy = 0;
- }
-
- outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
-
- /* Turn TX interrupts back on */
- /* outb(TX_INTR_DONE | TX_INTR_16_COL, ioaddr + TX_INTR_REG); */
- }
- dev_kfree_skb(skb, FREE_WRITE);
-
- return 0;
-}
-
-static void eth16i_rx(struct device *dev)
-{
- struct eth16i_local *lp = (struct eth16i_local *)dev->priv;
- int ioaddr = dev->base_addr;
- int boguscount = MAX_RX_LOOP;
-
- /* Loop until all packets have been read */
- while( (inb(ioaddr + RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == 0) {
-
- /* Read status byte from receive buffer */
- ushort status = inw(ioaddr + DATAPORT);
-
- if(eth16i_debug > 4)
- printk("%s: Receiving packet mode %02x status %04x.\n",
- dev->name, inb(ioaddr + RECEIVE_MODE_REG), status);
-
- if( !(status & PKT_GOOD) ) {
- /* Hmm..something went wrong. Let's check what error occured */
- lp->stats.rx_errors++;
- if( status & PKT_SHORT ) lp->stats.rx_length_errors++;
- if( status & PKT_ALIGN_ERR ) lp->stats.rx_frame_errors++;
- if( status & PKT_CRC_ERR ) lp->stats.rx_crc_errors++;
- if( status & PKT_RX_BUF_OVERFLOW) lp->stats.rx_over_errors++;
- }
- else { /* Ok so now we should have a good packet */
- struct sk_buff *skb;
-
- /* Get the size of the packet from receive buffer */
- ushort pkt_len = inw(ioaddr + DATAPORT);
-
- if(pkt_len > ETH_FRAME_LEN) {
- printk("%s: %s claimed a very large packet, size of %d bytes.\n",
- dev->name, cardname, pkt_len);
- outb(RX_BUF_SKIP_PACKET, ioaddr + FILTER_SELF_RX_REG);
- lp->stats.rx_dropped++;
- break;
- }
-
- skb = dev_alloc_skb(pkt_len + 3);
- if( skb == NULL ) {
- printk("%s: Could'n allocate memory for packet (len %d)\n",
- dev->name, pkt_len);
- outb(RX_BUF_SKIP_PACKET, ioaddr + FILTER_SELF_RX_REG);
- lp->stats.rx_dropped++;
- break;
- }
-
- skb->dev = dev;
- skb_reserve(skb,2);
- /*
- Now let's get the packet out of buffer.
- size is (pkt_len + 1) >> 1, cause we are now reading words
- and it have to be even aligned.
- */
-
- if( ioaddr < 0x1000)
- insw(ioaddr + DATAPORT, skb_put(skb, pkt_len), (pkt_len + 1) >> 1);
- else {
- unsigned char *buf = skb_put(skb, pkt_len);
- unsigned char frag = pkt_len % 4;
-
- insl(ioaddr + DATAPORT, buf, pkt_len >> 2);
-
- if(frag != 0) {
- unsigned short rest[2];
- rest[0] = inw( ioaddr + DATAPORT );
- if(frag == 3)
- rest[1] = inw( ioaddr + DATAPORT );
-
- memcpy(buf + (pkt_len & 0xfffc), (char *)rest, frag);
- }
- }
-
- skb->protocol=eth_type_trans(skb, dev);
- netif_rx(skb);
- lp->stats.rx_packets++;
-
- if( eth16i_debug > 5 ) {
- int i;
- printk("%s: Received packet of length %d.\n", dev->name, pkt_len);
- for(i = 0; i < 14; i++)
- printk(" %02x", skb->data[i]);
- printk(".\n");
- }
-
- } /* else */
-
- if(--boguscount <= 0)
- break;
-
- } /* while */
-
-#if 0
- {
- int i;
-
- for(i = 0; i < 20; i++) {
- if( (inb(ioaddr+RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == RX_BUFFER_EMPTY)
- break;
- inw(ioaddr + DATAPORT);
- outb(RX_BUF_SKIP_PACKET, ioaddr + FILTER_SELF_RX_REG);
- }
-
- if(eth16i_debug > 1)
- printk("%s: Flushed receive buffer.\n", dev->name);
- }
-#endif
-
- return;
-}
-
-static void eth16i_interrupt(int irq, struct pt_regs *regs)
-{
- struct device *dev = (struct device *)(irq2dev_map[irq]);
- struct eth16i_local *lp;
- int ioaddr = 0,
- status;
-
- if(dev == NULL) {
- printk("eth16i_interrupt(): irq %d for unknown device. \n", irq);
- return;
- }
-
- /* Turn off all interrupts from adapter */
- outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG);
-
- dev->interrupt = 1;
-
- ioaddr = dev->base_addr;
- lp = (struct eth16i_local *)dev->priv;
- status = inw(ioaddr + TX_STATUS_REG); /* Get the status */
- outw(status, ioaddr + TX_STATUS_REG); /* Clear status bits */
-
- if(eth16i_debug > 3)
- printk("%s: Interrupt with status %04x.\n", dev->name, status);
-
- if( status & 0x00ff ) { /* Let's check the transmit status reg */
-
- if(status & TX_DONE) { /* The transmit has been done */
- lp->stats.tx_packets++;
-
- if(lp->tx_queue) { /* Is there still packets ? */
- /* There was packet(s) so start transmitting and write also
- how many packets there is to be sended */
- outb(TX_START | lp->tx_queue, ioaddr + TRANSMIT_START_REG);
- lp->tx_queue = 0;
- lp->tx_queue_len = 0;
- dev->trans_start = jiffies;
- dev->tbusy = 0;
- mark_bh(NET_BH);
- }
- else {
- lp->tx_started = 0;
- dev->tbusy = 0;
- mark_bh(NET_BH);
- }
- }
- }
-
- if( ( status & 0xff00 ) ||
- ( (inb(ioaddr + RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == 0) ) {
- eth16i_rx(dev); /* We have packet in receive buffer */
- }
-
- dev->interrupt = 0;
-
- /* Turn interrupts back on */
- outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
-
- return;
-}
-
-static void eth16i_multicast(struct device *dev, int num_addrs, void *addrs)
-{
- short ioaddr = dev->base_addr;
-
- if(dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC))
- {
- dev->flags|=IFF_PROMISC; /* Must do this */
- outb(3, ioaddr + RECEIVE_MODE_REG);
- } else {
- outb(2, ioaddr + RECEIVE_MODE_REG);
- }
-}
-
-static struct enet_statistics *eth16i_get_stats(struct device *dev)
-{
- struct eth16i_local *lp = (struct eth16i_local *)dev->priv;
-
- return &lp->stats;
-}
-
-static void eth16i_select_regbank(unsigned char banknbr, short ioaddr)
-{
- unsigned char data;
-
- data = inb(ioaddr + CONFIG_REG_1);
- outb( ((data & 0xF3) | ( (banknbr & 0x03) << 2)), ioaddr + CONFIG_REG_1);
-}
-
-#ifdef MODULE
-static char devicename[9] = { 0, };
-static struct device dev_eth16i = {
- devicename,
- 0, 0, 0, 0,
- 0, 0,
- 0, 0, 0, NULL, eth16i_probe };
-
-int io = 0x2a0;
-int irq = 0;
-
-int init_module(void)
-{
- if(io == 0)
- printk("eth16i: You should not use auto-probing with insmod!\n");
-
- dev_eth16i.base_addr = io;
- dev_eth16i.irq = irq;
- if( register_netdev( &dev_eth16i ) != 0 ) {
- printk("eth16i: register_netdev() returned non-zero.\n");
- return -EIO;
- }
-
- return 0;
-}
-
-void cleanup_module(void)
-{
- unregister_netdev( &dev_eth16i );
- free_irq( dev_eth16i.irq );
- irq2dev_map[ dev_eth16i.irq ] = NULL;
- release_region( dev_eth16i.base_addr, ETH16I_IO_EXTENT );
-}
-
-#endif /* MODULE */
-
-
diff --git a/i386/i386at/gpl/linux/net/ewrk3.c b/i386/i386at/gpl/linux/net/ewrk3.c
deleted file mode 100644
index 90e3b932..00000000
--- a/i386/i386at/gpl/linux/net/ewrk3.c
+++ /dev/null
@@ -1,1933 +0,0 @@
-/* ewrk3.c: A DIGITAL EtherWORKS 3 ethernet driver for Linux.
-
- Written 1994 by David C. Davies.
-
- Copyright 1994 Digital Equipment Corporation.
-
- This software may be used and distributed according to the terms of
- the GNU Public License, incorporated herein by reference.
-
- This driver is written for the Digital Equipment Corporation series
- of EtherWORKS ethernet cards:
-
- DE203 Turbo (BNC)
- DE204 Turbo (TP)
- DE205 Turbo (TP BNC)
-
- The driver has been tested on a relatively busy network using the DE205
- card and benchmarked with 'ttcp': it transferred 16M of data at 975kB/s
- (7.8Mb/s) to a DECstation 5000/200.
-
- The author may be reached at davies@wanton.lkg.dec.com or
- davies@maniac.ultranet.com or Digital Equipment Corporation, 550 King
- Street, Littleton MA 01460.
-
- =========================================================================
- This driver has been written substantially from scratch, although its
- inheritance of style and stack interface from 'depca.c' and in turn from
- Donald Becker's 'lance.c' should be obvious.
-
- The DE203/4/5 boards all use a new proprietary chip in place of the
- LANCE chip used in prior cards (DEPCA, DE100, DE200/1/2, DE210, DE422).
- Use the depca.c driver in the standard distribution for the LANCE based
- cards from DIGITAL; this driver will not work with them.
-
- The DE203/4/5 cards have 2 main modes: shared memory and I/O only. I/O
- only makes all the card accesses through I/O transactions and no high
- (shared) memory is used. This mode provides a >48% performance penalty
- and is deprecated in this driver, although allowed to provide initial
- setup when hardstrapped.
-
- The shared memory mode comes in 3 flavours: 2kB, 32kB and 64kB. There is
- no point in using any mode other than the 2kB mode - their performances
- are virtually identical, although the driver has been tested in the 2kB
- and 32kB modes. I would suggest you uncomment the line:
-
- FORCE_2K_MODE;
-
- to allow the driver to configure the card as a 2kB card at your current
- base address, thus leaving more room to clutter your system box with
- other memory hungry boards.
-
- As many ISA and EISA cards can be supported under this driver as you
- wish, limited primarily by the available IRQ lines, rather than by the
- available I/O addresses (24 ISA, 16 EISA). I have checked different
- configurations of multiple depca cards and ewrk3 cards and have not
- found a problem yet (provided you have at least depca.c v0.38) ...
-
- The board IRQ setting must be at an unused IRQ which is auto-probed
- using Donald Becker's autoprobe routines. All these cards are at
- {5,10,11,15}.
-
- No 16MB memory limitation should exist with this driver as DMA is not
- used and the common memory area is in low memory on the network card (my
- current system has 20MB and I've not had problems yet).
-
- The ability to load this driver as a loadable module has been included
- and used extensively during the driver development (to save those long
- reboot sequences). To utilise this ability, you have to do 8 things:
-
- 0) have a copy of the loadable modules code installed on your system.
- 1) copy ewrk3.c from the /linux/drivers/net directory to your favourite
- temporary directory.
- 2) edit the source code near line 1880 to reflect the I/O address and
- IRQ you're using.
- 3) compile ewrk3.c, but include -DMODULE in the command line to ensure
- that the correct bits are compiled (see end of source code).
- 4) if you are wanting to add a new card, goto 5. Otherwise, recompile a
- kernel with the ewrk3 configuration turned off and reboot.
- 5) insmod ewrk3.o
- [Alan Cox: Changed this so you can insmod ewrk3.o irq=x io=y]
- 6) run the net startup bits for your new eth?? interface manually
- (usually /etc/rc.inet[12] at boot time).
- 7) enjoy!
-
- Note that autoprobing is not allowed in loadable modules - the system is
- already up and running and you're messing with interrupts.
-
- To unload a module, turn off the associated interface
- 'ifconfig eth?? down' then 'rmmod ewrk3'.
-
- Promiscuous mode has been turned off in this driver, but all the
- multicast address bits have been turned on. This improved the send
- performance on a busy network by about 13%.
-
- Ioctl's have now been provided (primarily because I wanted to grab some
- packet size statistics). They are patterned after 'plipconfig.c' from a
- suggestion by Alan Cox. Using these ioctls, you can enable promiscuous
- mode, add/delete multicast addresses, change the hardware address, get
- packet size distribution statistics and muck around with the control and
- status register. I'll add others if and when the need arises.
-
- TO DO:
- ------
-
-
- Revision History
- ----------------
-
- Version Date Description
-
- 0.1 26-aug-94 Initial writing. ALPHA code release.
- 0.11 31-aug-94 Fixed: 2k mode memory base calc.,
- LeMAC version calc.,
- IRQ vector assignments during autoprobe.
- 0.12 31-aug-94 Tested working on LeMAC2 (DE20[345]-AC) card.
- Fixed up MCA hash table algorithm.
- 0.20 4-sep-94 Added IOCTL functionality.
- 0.21 14-sep-94 Added I/O mode.
- 0.21axp 15-sep-94 Special version for ALPHA AXP Linux V1.0.
- 0.22 16-sep-94 Added more IOCTLs & tidied up.
- 0.23 21-sep-94 Added transmit cut through.
- 0.24 31-oct-94 Added uid checks in some ioctls.
- 0.30 1-nov-94 BETA code release.
- 0.31 5-dec-94 Added check/allocate region code.
- 0.32 16-jan-95 Broadcast packet fix.
- 0.33 10-Feb-95 Fix recognition bug reported by <bkm@star.rl.ac.uk>.
- 0.40 27-Dec-95 Rationalise MODULE and autoprobe code.
- Rewrite for portability & updated.
- ALPHA support from <jestabro@amt.tay1.dec.com>
- Added verify_area() calls in depca_ioctl() from
- suggestion by <heiko@colossus.escape.de>.
- Add new multicasting code.
-
- =========================================================================
-*/
-
-static const char *version = "ewrk3.c:v0.40 95/12/27 davies@wanton.lkg.dec.com\n";
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/ptrace.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/malloc.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <asm/bitops.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <asm/segment.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-
-#include <linux/time.h>
-#include <linux/types.h>
-#include <linux/unistd.h>
-
-#include "ewrk3.h"
-
-#ifdef EWRK3_DEBUG
-static int ewrk3_debug = EWRK3_DEBUG;
-#else
-static int ewrk3_debug = 1;
-#endif
-
-#define EWRK3_NDA 0xffe0 /* No Device Address */
-
-#define PROBE_LENGTH 32
-#define ETH_PROM_SIG 0xAA5500FFUL
-
-#ifndef EWRK3_SIGNATURE
-#define EWRK3_SIGNATURE {"DE203","DE204","DE205",""}
-#define EWRK3_STRLEN 8
-#endif
-
-#ifndef EWRK3_RAM_BASE_ADDRESSES
-#define EWRK3_RAM_BASE_ADDRESSES {0xc0000,0xd0000,0x00000}
-#endif
-
-/*
-** Sets up the I/O area for the autoprobe.
-*/
-#define EWRK3_IO_BASE 0x100 /* Start address for probe search */
-#define EWRK3_IOP_INC 0x20 /* I/O address increment */
-#define EWRK3_TOTAL_SIZE 0x20 /* required I/O address length */
-
-#ifndef MAX_NUM_EWRK3S
-#define MAX_NUM_EWRK3S 21
-#endif
-
-#ifndef EWRK3_EISA_IO_PORTS
-#define EWRK3_EISA_IO_PORTS 0x0c00 /* I/O port base address, slot 0 */
-#endif
-
-#ifndef MAX_EISA_SLOTS
-#define MAX_EISA_SLOTS 16
-#define EISA_SLOT_INC 0x1000
-#endif
-
-#define CRC_POLYNOMIAL_BE 0x04c11db7UL /* Ethernet CRC, big endian */
-#define CRC_POLYNOMIAL_LE 0xedb88320UL /* Ethernet CRC, little endian */
-
-#define QUEUE_PKT_TIMEOUT (100) /* Jiffies */
-
-/*
-** EtherWORKS 3 shared memory window sizes
-*/
-#define IO_ONLY 0x00
-#define SHMEM_2K 0x800
-#define SHMEM_32K 0x8000
-#define SHMEM_64K 0x10000
-
-/*
-** EtherWORKS 3 IRQ ENABLE/DISABLE
-*/
-#define ENABLE_IRQs { \
- icr |= lp->irq_mask;\
- outb(icr, EWRK3_ICR); /* Enable the IRQs */\
-}
-
-#define DISABLE_IRQs { \
- icr = inb(EWRK3_ICR);\
- icr &= ~lp->irq_mask;\
- outb(icr, EWRK3_ICR); /* Disable the IRQs */\
-}
-
-/*
-** EtherWORKS 3 START/STOP
-*/
-#define START_EWRK3 { \
- csr = inb(EWRK3_CSR);\
- csr &= ~(CSR_TXD|CSR_RXD);\
- outb(csr, EWRK3_CSR); /* Enable the TX and/or RX */\
-}
-
-#define STOP_EWRK3 { \
- csr = (CSR_TXD|CSR_RXD);\
- outb(csr, EWRK3_CSR); /* Disable the TX and/or RX */\
-}
-
-/*
-** The EtherWORKS 3 private structure
-*/
-#define EWRK3_PKT_STAT_SZ 16
-#define EWRK3_PKT_BIN_SZ 128 /* Should be >=100 unless you
- increase EWRK3_PKT_STAT_SZ */
-
-struct ewrk3_private {
- char adapter_name[80]; /* Name exported to /proc/ioports */
- u_long shmem_base; /* Shared memory start address */
- u_long shmem_length; /* Shared memory window length */
- struct enet_statistics stats; /* Public stats */
- struct {
- u32 bins[EWRK3_PKT_STAT_SZ]; /* Private stats counters */
- u32 unicast;
- u32 multicast;
- u32 broadcast;
- u32 excessive_collisions;
- u32 tx_underruns;
- u32 excessive_underruns;
- } pktStats;
- u_char irq_mask; /* Adapter IRQ mask bits */
- u_char mPage; /* Maximum 2kB Page number */
- u_char lemac; /* Chip rev. level */
- u_char hard_strapped; /* Don't allow a full open */
- u_char lock; /* Lock the page register */
- u_char txc; /* Transmit cut through */
- u_char *mctbl; /* Pointer to the multicast table */
-};
-
-/*
-** Force the EtherWORKS 3 card to be in 2kB MODE
-*/
-#define FORCE_2K_MODE { \
- shmem_length = SHMEM_2K;\
- outb(((mem_start - 0x80000) >> 11), EWRK3_MBR);\
-}
-
-/*
-** Public Functions
-*/
-static int ewrk3_open(struct device *dev);
-static int ewrk3_queue_pkt(struct sk_buff *skb, struct device *dev);
-static void ewrk3_interrupt(int irq, struct pt_regs *regs);
-static int ewrk3_close(struct device *dev);
-static struct enet_statistics *ewrk3_get_stats(struct device *dev);
-static void set_multicast_list(struct device *dev);
-static int ewrk3_ioctl(struct device *dev, struct ifreq *rq, int cmd);
-
-/*
-** Private functions
-*/
-static int ewrk3_hw_init(struct device *dev, u_long iobase);
-static void ewrk3_init(struct device *dev);
-static int ewrk3_rx(struct device *dev);
-static int ewrk3_tx(struct device *dev);
-
-static void EthwrkSignature(char * name, char *eeprom_image);
-static int DevicePresent(u_long iobase);
-static void SetMulticastFilter(struct device *dev);
-static int EISA_signature(char *name, s32 eisa_id);
-
-static int Read_EEPROM(u_long iobase, u_char eaddr);
-static int Write_EEPROM(short data, u_long iobase, u_char eaddr);
-static u_char get_hw_addr (struct device *dev, u_char *eeprom_image, char chipType);
-
-static void isa_probe(struct device *dev, u_long iobase);
-static void eisa_probe(struct device *dev, u_long iobase);
-static struct device *alloc_device(struct device *dev, u_long iobase);
-
-
-#ifdef MODULE
-int init_module(void);
-void cleanup_module(void);
-static int autoprobed = 1, loading_module = 1;
-
-# else
-static u_char irq[] = {5,0,10,3,11,9,15,12};
-static int autoprobed = 0, loading_module = 0;
-
-#endif /* MODULE */
-
-static char name[EWRK3_STRLEN + 1];
-static int num_ewrk3s = 0, num_eth = 0;
-
-/*
-** Miscellaneous defines...
-*/
-#define INIT_EWRK3 {\
- outb(EEPROM_INIT, EWRK3_IOPR);\
- udelay(1000);\
-}
-
-
-
-
-int ewrk3_probe(struct device *dev)
-{
- int tmp = num_ewrk3s, status = -ENODEV;
- u_long iobase = dev->base_addr;
-
- if ((iobase == 0) && loading_module){
- printk("Autoprobing is not supported when loading a module based driver.\n");
- status = -EIO;
- } else { /* First probe for the Ethernet */
- /* Address PROM pattern */
- isa_probe(dev, iobase);
- eisa_probe(dev, iobase);
-
- if ((tmp == num_ewrk3s) && (iobase != 0) && loading_module) {
- printk("%s: ewrk3_probe() cannot find device at 0x%04lx.\n", dev->name,
- iobase);
- }
-
- /*
- ** Walk the device list to check that at least one device
- ** initialised OK
- */
- for (; (dev->priv == NULL) && (dev->next != NULL); dev = dev->next);
-
- if (dev->priv) status = 0;
- if (iobase == 0) autoprobed = 1;
- }
-
- return status;
-}
-
-static int
-ewrk3_hw_init(struct device *dev, u_long iobase)
-{
- struct ewrk3_private *lp;
- int i, status=0;
- u_long mem_start, shmem_length;
- u_char cr, cmr, icr, nicsr, lemac, hard_strapped = 0;
- u_char eeprom_image[EEPROM_MAX], chksum, eisa_cr = 0;
-
- /*
- ** Stop the EWRK3. Enable the DBR ROM. Disable interrupts and remote boot.
- ** This also disables the EISA_ENABLE bit in the EISA Control Register.
- */
- if (iobase > 0x400) eisa_cr = inb(EISA_CR);
- INIT_EWRK3;
-
- nicsr = inb(EWRK3_CSR);
-
- icr = inb(EWRK3_ICR);
- icr |= 0xf0;
- outb(icr, EWRK3_ICR); /* Disable all the IRQs */
-
- if (nicsr == CSR_TXD|CSR_RXD) {
-
- /* Check that the EEPROM is alive and well and not living on Pluto... */
- for (chksum=0, i=0; i<EEPROM_MAX; i+=2) {
- union {
- short val;
- char c[2];
- } tmp;
-
- tmp.val = (short)Read_EEPROM(iobase, (i>>1));
- eeprom_image[i] = tmp.c[0];
- eeprom_image[i+1] = tmp.c[1];
- chksum += eeprom_image[i] + eeprom_image[i+1];
- }
-
- if (chksum != 0) { /* Bad EEPROM Data! */
- printk("%s: Device has a bad on-board EEPROM.\n", dev->name);
- status = -ENXIO;
- } else {
- EthwrkSignature(name, eeprom_image);
- if (*name != '\0') { /* found a EWRK3 device */
- dev->base_addr = iobase;
-
- if (iobase > 0x400) {
- outb(eisa_cr, EISA_CR); /* Rewrite the EISA CR */
- }
-
- lemac = eeprom_image[EEPROM_CHIPVER];
- cmr = inb(EWRK3_CMR);
-
- if (((lemac == LeMAC) && ((cmr & CMR_NO_EEPROM) != CMR_NO_EEPROM)) ||
- ((lemac == LeMAC2) && !(cmr & CMR_HS))) {
- printk("%s: %s at %#4lx", dev->name, name, iobase);
- hard_strapped = 1;
- } else if ((iobase&0x0fff)==EWRK3_EISA_IO_PORTS) {
- /* EISA slot address */
- printk("%s: %s at %#4lx (EISA slot %ld)",
- dev->name, name, iobase, ((iobase>>12)&0x0f));
- } else { /* ISA port address */
- printk("%s: %s at %#4lx", dev->name, name, iobase);
- }
-
- if (!status) {
- printk(", h/w address ");
- if (lemac!=LeMAC2) DevicePresent(iobase);/* need after EWRK3_INIT */
- status = get_hw_addr(dev, eeprom_image, lemac);
- for (i = 0; i < ETH_ALEN - 1; i++) { /* get the ethernet addr. */
- printk("%2.2x:", dev->dev_addr[i]);
- }
- printk("%2.2x,\n", dev->dev_addr[i]);
-
- if (status) {
- printk(" which has an EEPROM CRC error.\n");
- status = -ENXIO;
- } else {
- if (lemac == LeMAC2) { /* Special LeMAC2 CMR things */
- cmr &= ~(CMR_RA | CMR_WB | CMR_LINK | CMR_POLARITY | CMR_0WS);
- if (eeprom_image[EEPROM_MISC0] & READ_AHEAD) cmr |= CMR_RA;
- if (eeprom_image[EEPROM_MISC0] & WRITE_BEHIND) cmr |= CMR_WB;
- if (eeprom_image[EEPROM_NETMAN0] & NETMAN_POL) cmr |= CMR_POLARITY;
- if (eeprom_image[EEPROM_NETMAN0] & NETMAN_LINK) cmr |= CMR_LINK;
- if (eeprom_image[EEPROM_MISC0] & _0WS_ENA) cmr |= CMR_0WS;
- }
- if (eeprom_image[EEPROM_SETUP] & SETUP_DRAM) cmr |= CMR_DRAM;
- outb(cmr, EWRK3_CMR);
-
- cr = inb(EWRK3_CR); /* Set up the Control Register */
- cr |= eeprom_image[EEPROM_SETUP] & SETUP_APD;
- if (cr & SETUP_APD) cr |= eeprom_image[EEPROM_SETUP] & SETUP_PS;
- cr |= eeprom_image[EEPROM_MISC0] & FAST_BUS;
- cr |= eeprom_image[EEPROM_MISC0] & ENA_16;
- outb(cr, EWRK3_CR);
-
- /*
- ** Determine the base address and window length for the EWRK3
- ** RAM from the memory base register.
- */
- mem_start = inb(EWRK3_MBR);
- shmem_length = 0;
- if (mem_start != 0) {
- if ((mem_start >= 0x0a) && (mem_start <= 0x0f)) {
- mem_start *= SHMEM_64K;
- shmem_length = SHMEM_64K;
- } else if ((mem_start >= 0x14) && (mem_start <= 0x1f)) {
- mem_start *= SHMEM_32K;
- shmem_length = SHMEM_32K;
- } else if ((mem_start >= 0x40) && (mem_start <= 0xff)) {
- mem_start = mem_start * SHMEM_2K + 0x80000;
- shmem_length = SHMEM_2K;
- } else {
- status = -ENXIO;
- }
- }
-
- /*
- ** See the top of this source code for comments about
- ** uncommenting this line.
- */
-/* FORCE_2K_MODE;*/
-
- if (!status) {
- if (hard_strapped) {
- printk(" is hard strapped.\n");
- } else if (mem_start) {
- printk(" has a %dk RAM window", (int)(shmem_length >> 10));
- printk(" at 0x%.5lx", mem_start);
- } else {
- printk(" is in I/O only mode");
- }
-
- /* private area & initialise */
- dev->priv = (void *) kmalloc(sizeof(struct ewrk3_private),
- GFP_KERNEL);
- if (dev->priv == NULL) {
- return -ENOMEM;
- }
- lp = (struct ewrk3_private *)dev->priv;
- memset(dev->priv, 0, sizeof(struct ewrk3_private));
- lp->shmem_base = mem_start;
- lp->shmem_length = shmem_length;
- lp->lemac = lemac;
- lp->hard_strapped = hard_strapped;
-
- lp->mPage = 64;
- if (cmr & CMR_DRAM) lp->mPage <<= 1 ;/* 2 DRAMS on module */
-
- sprintf(lp->adapter_name,"%s (%s)", name, dev->name);
- request_region(iobase, EWRK3_TOTAL_SIZE, lp->adapter_name);
-
- lp->irq_mask = ICR_TNEM|ICR_TXDM|ICR_RNEM|ICR_RXDM;
-
- if (!hard_strapped) {
- /*
- ** Enable EWRK3 board interrupts for autoprobing
- */
- icr |= ICR_IE; /* Enable interrupts */
- outb(icr, EWRK3_ICR);
-
- /* The DMA channel may be passed in on this parameter. */
- dev->dma = 0;
-
- /* To auto-IRQ we enable the initialization-done and DMA err,
- interrupts. For now we will always get a DMA error. */
- if (dev->irq < 2) {
-#ifndef MODULE
- u_char irqnum;
-
- autoirq_setup(0);
-
- /*
- ** Trigger a TNE interrupt.
- */
- icr |=ICR_TNEM;
- outb(1,EWRK3_TDQ); /* Write to the TX done queue */
- outb(icr, EWRK3_ICR); /* Unmask the TXD interrupt */
-
- irqnum = irq[((icr & IRQ_SEL) >> 4)];
-
- dev->irq = autoirq_report(1);
- if ((dev->irq) && (irqnum == dev->irq)) {
- printk(" and uses IRQ%d.\n", dev->irq);
- } else {
- if (!dev->irq) {
- printk(" and failed to detect IRQ line.\n");
- } else if ((irqnum == 1) && (lemac == LeMAC2)) {
- printk(" and an illegal IRQ line detected.\n");
- } else {
- printk(", but incorrect IRQ line detected.\n");
- }
- status = -ENXIO;
- }
-
- DISABLE_IRQs; /* Mask all interrupts */
-
-#endif /* MODULE */
- } else {
- printk(" and requires IRQ%d.\n", dev->irq);
- }
- }
- if (status) release_region(iobase, EWRK3_TOTAL_SIZE);
- } else {
- status = -ENXIO;
- }
- }
- }
- } else {
- status = -ENXIO;
- }
- }
-
- if (!status) {
- if (ewrk3_debug > 0) {
- printk(version);
- }
-
- /* The EWRK3-specific entries in the device structure. */
- dev->open = &ewrk3_open;
- dev->hard_start_xmit = &ewrk3_queue_pkt;
- dev->stop = &ewrk3_close;
- dev->get_stats = &ewrk3_get_stats;
- dev->set_multicast_list = &set_multicast_list;
- dev->do_ioctl = &ewrk3_ioctl;
-
- dev->mem_start = 0;
-
- /* Fill in the generic field of the device structure. */
- ether_setup(dev);
- }
- } else {
- status = -ENXIO;
- }
-
- return status;
-}
-
-
-static int
-ewrk3_open(struct device *dev)
-{
- struct ewrk3_private *lp = (struct ewrk3_private *)dev->priv;
- u_long iobase = dev->base_addr;
- int i, status = 0;
- u_char icr, csr;
-
- /*
- ** Stop the TX and RX...
- */
- STOP_EWRK3;
-
- if (!lp->hard_strapped) {
- irq2dev_map[dev->irq] = dev; /* For latched interrupts */
-
- if (request_irq(dev->irq, (void *)ewrk3_interrupt, 0, "ewrk3")) {
- printk("ewrk3_open(): Requested IRQ%d is busy\n",dev->irq);
- status = -EAGAIN;
- } else {
-
- /*
- ** Re-initialize the EWRK3...
- */
- ewrk3_init(dev);
-
- if (ewrk3_debug > 1){
- printk("%s: ewrk3 open with irq %d\n",dev->name,dev->irq);
- printk(" physical address: ");
- for (i=0;i<5;i++){
- printk("%2.2x:",(u_char)dev->dev_addr[i]);
- }
- printk("%2.2x\n",(u_char)dev->dev_addr[i]);
- if (lp->shmem_length == 0) {
- printk(" no shared memory, I/O only mode\n");
- } else {
- printk(" start of shared memory: 0x%08lx\n",lp->shmem_base);
- printk(" window length: 0x%04lx\n",lp->shmem_length);
- }
- printk(" # of DRAMS: %d\n",((inb(EWRK3_CMR) & 0x02) ? 2 : 1));
- printk(" csr: 0x%02x\n", inb(EWRK3_CSR));
- printk(" cr: 0x%02x\n", inb(EWRK3_CR));
- printk(" icr: 0x%02x\n", inb(EWRK3_ICR));
- printk(" cmr: 0x%02x\n", inb(EWRK3_CMR));
- printk(" fmqc: 0x%02x\n", inb(EWRK3_FMQC));
- }
-
- dev->tbusy = 0;
- dev->start = 1;
- dev->interrupt = UNMASK_INTERRUPTS;
-
- /*
- ** Unmask EWRK3 board interrupts
- */
- icr = inb(EWRK3_ICR);
- ENABLE_IRQs;
-
- }
- } else {
- dev->start = 0;
- dev->tbusy = 1;
- printk("%s: ewrk3 available for hard strapped set up only.\n", dev->name);
- printk(" Run the 'ewrk3setup' utility or remove the hard straps.\n");
- }
-
- MOD_INC_USE_COUNT;
-
- return status;
-}
-
-/*
-** Initialize the EtherWORKS 3 operating conditions
-*/
-static void
-ewrk3_init(struct device *dev)
-{
- struct ewrk3_private *lp = (struct ewrk3_private *)dev->priv;
- u_char csr, page;
- u_long iobase = dev->base_addr;
-
- /*
- ** Enable any multicasts
- */
- set_multicast_list(dev);
-
- /*
- ** Clean out any remaining entries in all the queues here
- */
- while (inb(EWRK3_TQ));
- while (inb(EWRK3_TDQ));
- while (inb(EWRK3_RQ));
- while (inb(EWRK3_FMQ));
-
- /*
- ** Write a clean free memory queue
- */
- for (page=1;page<lp->mPage;page++) { /* Write the free page numbers */
- outb(page, EWRK3_FMQ); /* to the Free Memory Queue */
- }
-
- lp->lock = 0; /* Ensure there are no locks */
-
- START_EWRK3; /* Enable the TX and/or RX */
-}
-
-/*
-** Writes a socket buffer to the free page queue
-*/
-static int
-ewrk3_queue_pkt(struct sk_buff *skb, struct device *dev)
-{
- struct ewrk3_private *lp = (struct ewrk3_private *)dev->priv;
- u_long iobase = dev->base_addr;
- int status = 0;
- u_char icr, csr;
-
- /* Transmitter timeout, serious problems. */
- if (dev->tbusy || lp->lock) {
- int tickssofar = jiffies - dev->trans_start;
- if (tickssofar < QUEUE_PKT_TIMEOUT) {
- status = -1;
- } else if (!lp->hard_strapped) {
- printk("%s: transmit timed/locked out, status %04x, resetting.\n",
- dev->name, inb(EWRK3_CSR));
-
- /*
- ** Mask all board interrupts
- */
- DISABLE_IRQs;
-
- /*
- ** Stop the TX and RX...
- */
- STOP_EWRK3;
-
- ewrk3_init(dev);
-
- /*
- ** Unmask EWRK3 board interrupts
- */
- ENABLE_IRQs;
-
- dev->tbusy=0;
- dev->trans_start = jiffies;
- }
- } else if (skb == NULL) {
- dev_tint(dev);
- } else if (skb->len > 0) {
-
- /*
- ** Block a timer-based transmit from overlapping. This could better be
- ** done with atomic_swap(1, dev->tbusy), but set_bit() works as well.
- */
- if (set_bit(0, (void*)&dev->tbusy) != 0)
- printk("%s: Transmitter access conflict.\n", dev->name);
-
- DISABLE_IRQs; /* So that the page # remains correct */
-
- /*
- ** Get a free page from the FMQ when resources are available
- */
- if (inb(EWRK3_FMQC) > 0) {
- u_long buf = 0;
- u_char page;
-
- if ((page = inb(EWRK3_FMQ)) < lp->mPage) {
- /*
- ** Set up shared memory window and pointer into the window
- */
- while (set_bit(0, (void *)&lp->lock) != 0); /* Wait for lock to free */
- if (lp->shmem_length == IO_ONLY) {
- outb(page, EWRK3_IOPR);
- } else if (lp->shmem_length == SHMEM_2K) {
- buf = lp->shmem_base;
- outb(page, EWRK3_MPR);
- } else if (lp->shmem_length == SHMEM_32K) {
- buf = ((((short)page << 11) & 0x7800) + lp->shmem_base);
- outb((page >> 4), EWRK3_MPR);
- } else if (lp->shmem_length == SHMEM_64K) {
- buf = ((((short)page << 11) & 0xf800) + lp->shmem_base);
- outb((page >> 5), EWRK3_MPR);
- } else {
- status = -1;
- printk("%s: Oops - your private data area is hosed!\n",dev->name);
- }
-
- if (!status) {
-
- /*
- ** Set up the buffer control structures and copy the data from
- ** the socket buffer to the shared memory .
- */
-
- if (lp->shmem_length == IO_ONLY) {
- int i;
- u_char *p = skb->data;
-
- outb((char)(TCR_QMODE | TCR_PAD | TCR_IFC), EWRK3_DATA);
- outb((char)(skb->len & 0xff), EWRK3_DATA);
- outb((char)((skb->len >> 8) & 0xff), EWRK3_DATA);
- outb((char)0x04, EWRK3_DATA);
- for (i=0; i<skb->len; i++) {
- outb(*p++, EWRK3_DATA);
- }
- outb(page, EWRK3_TQ); /* Start sending pkt */
- } else {
- writeb((char)(TCR_QMODE|TCR_PAD|TCR_IFC), (char *)buf);/* ctrl byte*/
- buf+=1;
- writeb((char)(skb->len & 0xff), (char *)buf);/* length (16 bit xfer)*/
- buf+=1;
- if (lp->txc) {
- writeb((char)(((skb->len >> 8) & 0xff) | XCT), (char *)buf);
- buf+=1;
- writeb(0x04, (char *)buf); /* index byte */
- buf+=1;
- writeb(0x00, (char *)(buf + skb->len)); /* Write the XCT flag */
- memcpy_toio(buf, skb->data, PRELOAD);/* Write PRELOAD bytes*/
- outb(page, EWRK3_TQ); /* Start sending pkt */
- memcpy_toio(buf+PRELOAD, skb->data+PRELOAD, skb->len-PRELOAD);
- writeb(0xff, (char *)(buf + skb->len)); /* Write the XCT flag */
- } else {
- writeb((char)((skb->len >> 8) & 0xff), (char *)buf);
- buf+=1;
- writeb(0x04, (char *)buf); /* index byte */
- buf+=1;
- memcpy_toio((char *)buf, skb->data, skb->len);/* Write data bytes */
- outb(page, EWRK3_TQ); /* Start sending pkt */
- }
- }
-
- dev->trans_start = jiffies;
- dev_kfree_skb (skb, FREE_WRITE);
-
- } else { /* return unused page to the free memory queue */
- outb(page, EWRK3_FMQ);
- }
- lp->lock = 0; /* unlock the page register */
- } else {
- printk("ewrk3_queue_pkt(): Invalid free memory page (%d).\n",
- (u_char) page);
- }
- } else {
- printk("ewrk3_queue_pkt(): No free resources...\n");
- printk("ewrk3_queue_pkt(): CSR: %02x ICR: %02x FMQC: %02x\n",inb(EWRK3_CSR),inb(EWRK3_ICR),inb(EWRK3_FMQC));
- }
-
- /* Check for free resources: clear 'tbusy' if there are some */
- if (inb(EWRK3_FMQC) > 0) {
- dev->tbusy = 0;
- }
-
- ENABLE_IRQs;
- }
-
- return status;
-}
-
-/*
-** The EWRK3 interrupt handler.
-*/
-static void
-ewrk3_interrupt(int irq, struct pt_regs * regs)
-{
- struct device *dev = (struct device *)(irq2dev_map[irq]);
- struct ewrk3_private *lp;
- u_long iobase;
- u_char icr, cr, csr;
-
- if (dev == NULL) {
- printk ("ewrk3_interrupt(): irq %d for unknown device.\n", irq);
- } else {
- lp = (struct ewrk3_private *)dev->priv;
- iobase = dev->base_addr;
-
- if (dev->interrupt)
- printk("%s: Re-entering the interrupt handler.\n", dev->name);
-
- dev->interrupt = MASK_INTERRUPTS;
-
- /* get the interrupt information */
- csr = inb(EWRK3_CSR);
-
- /*
- ** Mask the EWRK3 board interrupts and turn on the LED
- */
- DISABLE_IRQs;
-
- cr = inb(EWRK3_CR);
- cr |= CR_LED;
- outb(cr, EWRK3_CR);
-
- if (csr & CSR_RNE) /* Rx interrupt (packet[s] arrived) */
- ewrk3_rx(dev);
-
- if (csr & CSR_TNE) /* Tx interrupt (packet sent) */
- ewrk3_tx(dev);
-
- /*
- ** Now deal with the TX/RX disable flags. These are set when there
- ** are no more resources. If resources free up then enable these
- ** interrupts, otherwise mask them - failure to do this will result
- ** in the system hanging in an interrupt loop.
- */
- if (inb(EWRK3_FMQC)) { /* any resources available? */
- lp->irq_mask |= ICR_TXDM|ICR_RXDM;/* enable the interrupt source */
- csr &= ~(CSR_TXD|CSR_RXD);/* ensure restart of a stalled TX or RX */
- outb(csr, EWRK3_CSR);
- dev->tbusy = 0; /* clear TX busy flag */
- mark_bh(NET_BH);
- } else {
- lp->irq_mask &= ~(ICR_TXDM|ICR_RXDM);/* disable the interrupt source */
- }
-
- /* Unmask the EWRK3 board interrupts and turn off the LED */
- cr &= ~CR_LED;
- outb(cr, EWRK3_CR);
-
- dev->interrupt = UNMASK_INTERRUPTS;
- ENABLE_IRQs;
- }
-
- return;
-}
-
-static int
-ewrk3_rx(struct device *dev)
-{
- struct ewrk3_private *lp = (struct ewrk3_private *)dev->priv;
- u_long iobase = dev->base_addr;
- int i, status = 0;
- u_char page, tmpPage = 0, tmpLock = 0;
- u_long buf = 0;
-
- while (inb(EWRK3_RQC) && !status) { /* Whilst there's incoming data */
- if ((page = inb(EWRK3_RQ)) < lp->mPage) {/* Get next entry's buffer page */
- /*
- ** Preempt any process using the current page register. Check for
- ** an existing lock to reduce time taken in I/O transactions.
- */
- if ((tmpLock = set_bit(0, (void *)&lp->lock)) == 1) { /* Assert lock */
- if (lp->shmem_length == IO_ONLY) { /* Get existing page */
- tmpPage = inb(EWRK3_IOPR);
- } else {
- tmpPage = inb(EWRK3_MPR);
- }
- }
-
- /*
- ** Set up shared memory window and pointer into the window
- */
- if (lp->shmem_length == IO_ONLY) {
- outb(page, EWRK3_IOPR);
- } else if (lp->shmem_length == SHMEM_2K) {
- buf = lp->shmem_base;
- outb(page, EWRK3_MPR);
- } else if (lp->shmem_length == SHMEM_32K) {
- buf = ((((short)page << 11) & 0x7800) + lp->shmem_base);
- outb((page >> 4), EWRK3_MPR);
- } else if (lp->shmem_length == SHMEM_64K) {
- buf = ((((short)page << 11) & 0xf800) + lp->shmem_base);
- outb((page >> 5), EWRK3_MPR);
- } else {
- status = -1;
- printk("%s: Oops - your private data area is hosed!\n",dev->name);
- }
-
- if (!status) {
- char rx_status;
- int pkt_len;
-
- if (lp->shmem_length == IO_ONLY) {
- rx_status = inb(EWRK3_DATA);
- pkt_len = inb(EWRK3_DATA);
- pkt_len |= ((u_short)inb(EWRK3_DATA) << 8);
- } else {
- rx_status = readb(buf);
- buf+=1;
- pkt_len = readw(buf);
- buf+=3;
- }
-
- if (!(rx_status & R_ROK)) { /* There was an error. */
- lp->stats.rx_errors++; /* Update the error stats. */
- if (rx_status & R_DBE) lp->stats.rx_frame_errors++;
- if (rx_status & R_CRC) lp->stats.rx_crc_errors++;
- if (rx_status & R_PLL) lp->stats.rx_fifo_errors++;
- } else {
- struct sk_buff *skb;
-
- if ((skb = dev_alloc_skb(pkt_len+2)) != NULL) {
- unsigned char *p;
- skb->dev = dev;
- skb_reserve(skb,2); /* Align to 16 bytes */
- p = skb_put(skb,pkt_len);
-
- if (lp->shmem_length == IO_ONLY) {
- *p = inb(EWRK3_DATA); /* dummy read */
- for (i=0; i<pkt_len; i++) {
- *p++ = inb(EWRK3_DATA);
- }
- } else {
- memcpy_fromio(p, buf, pkt_len);
- }
-
- /*
- ** Notify the upper protocol layers that there is another
- ** packet to handle
- */
- skb->protocol=eth_type_trans(skb,dev);
- netif_rx(skb);
-
- /*
- ** Update stats
- */
- lp->stats.rx_packets++;
- for (i=1; i<EWRK3_PKT_STAT_SZ-1; i++) {
- if (pkt_len < i*EWRK3_PKT_BIN_SZ) {
- lp->pktStats.bins[i]++;
- i = EWRK3_PKT_STAT_SZ;
- }
- }
- p = skb->data; /* Look at the dest addr */
- if (p[0] & 0x01) { /* Multicast/Broadcast */
- if ((*(s32 *)&p[0] == -1) && (*(s16 *)&p[4] == -1)) {
- lp->pktStats.broadcast++;
- } else {
- lp->pktStats.multicast++;
- }
- } else if ((*(s32 *)&p[0] == *(s32 *)&dev->dev_addr[0]) &&
- (*(s16 *)&p[4] == *(s16 *)&dev->dev_addr[4])) {
- lp->pktStats.unicast++;
- }
-
- lp->pktStats.bins[0]++; /* Duplicates stats.rx_packets */
- if (lp->pktStats.bins[0] == 0) { /* Reset counters */
- memset(&lp->pktStats, 0, sizeof(lp->pktStats));
- }
- } else {
- printk("%s: Insufficient memory; nuking packet.\n", dev->name);
- lp->stats.rx_dropped++; /* Really, deferred. */
- break;
- }
- }
- }
- /*
- ** Return the received buffer to the free memory queue
- */
- outb(page, EWRK3_FMQ);
-
- if (tmpLock) { /* If a lock was preempted */
- if (lp->shmem_length == IO_ONLY) { /* Replace old page */
- outb(tmpPage, EWRK3_IOPR);
- } else {
- outb(tmpPage, EWRK3_MPR);
- }
- }
- lp->lock = 0; /* Unlock the page register */
- } else {
- printk("ewrk3_rx(): Illegal page number, page %d\n",page);
- printk("ewrk3_rx(): CSR: %02x ICR: %02x FMQC: %02x\n",inb(EWRK3_CSR),inb(EWRK3_ICR),inb(EWRK3_FMQC));
- }
- }
- return status;
-}
-
-/*
-** Buffer sent - check for TX buffer errors.
-*/
-static int
-ewrk3_tx(struct device *dev)
-{
- struct ewrk3_private *lp = (struct ewrk3_private *)dev->priv;
- u_long iobase = dev->base_addr;
- u_char tx_status;
-
- while ((tx_status = inb(EWRK3_TDQ)) > 0) { /* Whilst there's old buffers */
- if (tx_status & T_VSTS) { /* The status is valid */
- if (tx_status & T_TXE) {
- lp->stats.tx_errors++;
- if (tx_status & T_NCL) lp->stats.tx_carrier_errors++;
- if (tx_status & T_LCL) lp->stats.tx_window_errors++;
- if (tx_status & T_CTU) {
- if ((tx_status & T_COLL) ^ T_XUR) {
- lp->pktStats.tx_underruns++;
- } else {
- lp->pktStats.excessive_underruns++;
- }
- } else if (tx_status & T_COLL) {
- if ((tx_status & T_COLL) ^ T_XCOLL) {
- lp->stats.collisions++;
- } else {
- lp->pktStats.excessive_collisions++;
- }
- }
- } else {
- lp->stats.tx_packets++;
- }
- }
- }
-
- return 0;
-}
-
-static int
-ewrk3_close(struct device *dev)
-{
- struct ewrk3_private *lp = (struct ewrk3_private *)dev->priv;
- u_long iobase = dev->base_addr;
- u_char icr, csr;
-
- dev->start = 0;
- dev->tbusy = 1;
-
- if (ewrk3_debug > 1) {
- printk("%s: Shutting down ethercard, status was %2.2x.\n",
- dev->name, inb(EWRK3_CSR));
- }
-
- /*
- ** We stop the EWRK3 here... mask interrupts and stop TX & RX
- */
- DISABLE_IRQs;
-
- STOP_EWRK3;
-
- /*
- ** Clean out the TX and RX queues here (note that one entry
- ** may get added to either the TXD or RX queues if the the TX or RX
- ** just starts processing a packet before the STOP_EWRK3 command
- ** is received. This will be flushed in the ewrk3_open() call).
- */
- while (inb(EWRK3_TQ));
- while (inb(EWRK3_TDQ));
- while (inb(EWRK3_RQ));
-
- if (!lp->hard_strapped) {
- free_irq(dev->irq);
-
- irq2dev_map[dev->irq] = 0;
- }
-
- MOD_DEC_USE_COUNT;
-
- return 0;
-}
-
-static struct enet_statistics *
-ewrk3_get_stats(struct device *dev)
-{
- struct ewrk3_private *lp = (struct ewrk3_private *)dev->priv;
-
- /* Null body since there is no framing error counter */
-
- return &lp->stats;
-}
-
-/*
-** Set or clear the multicast filter for this adaptor.
-*/
-static void
-set_multicast_list(struct device *dev)
-{
- struct ewrk3_private *lp = (struct ewrk3_private *)dev->priv;
- u_long iobase = dev->base_addr;
- u_char csr;
-
- if (irq2dev_map[dev->irq] != NULL) {
- csr = inb(EWRK3_CSR);
-
- if (lp->shmem_length == IO_ONLY) {
- lp->mctbl = (char *) PAGE0_HTE;
- } else {
- lp->mctbl = (char *)(lp->shmem_base + PAGE0_HTE);
- }
-
- csr &= ~(CSR_PME | CSR_MCE);
- if (dev->flags & IFF_PROMISC) { /* set promiscuous mode */
- csr |= CSR_PME;
- outb(csr, EWRK3_CSR);
- } else {
- SetMulticastFilter(dev);
- csr |= CSR_MCE;
- outb(csr, EWRK3_CSR);
- }
- }
-}
-
-/*
-** Calculate the hash code and update the logical address filter
-** from a list of ethernet multicast addresses.
-** Little endian crc one liner from Matt Thomas, DEC.
-**
-** Note that when clearing the table, the broadcast bit must remain asserted
-** to receive broadcast messages.
-*/
-static void SetMulticastFilter(struct device *dev)
-{
- struct ewrk3_private *lp = (struct ewrk3_private *)dev->priv;
- struct dev_mc_list *dmi=dev->mc_list;
- u_long iobase = dev->base_addr;
- int i;
- char *addrs, j, bit, byte;
- short *p = (short *) lp->mctbl;
- u16 hashcode;
- s32 crc, poly = CRC_POLYNOMIAL_LE;
-
- while (set_bit(0, (void *)&lp->lock) != 0); /* Wait for lock to free */
-
- if (lp->shmem_length == IO_ONLY) {
- outb(0, EWRK3_IOPR);
- outw(EEPROM_OFFSET(lp->mctbl), EWRK3_PIR1);
- } else {
- outb(0, EWRK3_MPR);
- }
-
- if (dev->flags & IFF_ALLMULTI) {
- for (i=0; i<(HASH_TABLE_LEN >> 3); i++) {
- if (lp->shmem_length == IO_ONLY) {
- outb(0xff, EWRK3_DATA);
- } else { /* memset didn't work here */
- writew(0xffff, p);
- p++; i++;
- }
- }
- } else {
- /* Clear table except for broadcast bit */
- if (lp->shmem_length == IO_ONLY) {
- for (i=0; i<(HASH_TABLE_LEN >> 4) - 1; i++) {
- outb(0x00, EWRK3_DATA);
- }
- outb(0x80, EWRK3_DATA); i++; /* insert the broadcast bit */
- for (; i<(HASH_TABLE_LEN >> 3); i++) {
- outb(0x00, EWRK3_DATA);
- }
- } else {
- memset_io(lp->mctbl, 0, (HASH_TABLE_LEN >> 3));
- writeb(0x80, (char *)(lp->mctbl + (HASH_TABLE_LEN >> 4) - 1));
- }
-
- /* Update table */
- for (i=0;i<dev->mc_count;i++) { /* for each address in the list */
- addrs=dmi->dmi_addr;
- dmi=dmi->next;
- if ((*addrs & 0x01) == 1) { /* multicast address? */
- crc = 0xffffffff; /* init CRC for each address */
- for (byte=0;byte<ETH_ALEN;byte++) { /* for each address byte */
- /* process each address bit */
- for (bit = *addrs++,j=0;j<8;j++, bit>>=1) {
- crc = (crc >> 1) ^ (((crc ^ bit) & 0x01) ? poly : 0);
- }
- }
- hashcode = crc & ((1 << 9) - 1); /* hashcode is 9 LSb of CRC */
-
- byte = hashcode >> 3; /* bit[3-8] -> byte in filter */
- bit = 1 << (hashcode & 0x07); /* bit[0-2] -> bit in byte */
-
- if (lp->shmem_length == IO_ONLY) {
- u_char tmp;
-
- outw((short)((long)lp->mctbl) + byte, EWRK3_PIR1);
- tmp = inb(EWRK3_DATA);
- tmp |= bit;
- outw((short)((long)lp->mctbl) + byte, EWRK3_PIR1);
- outb(tmp, EWRK3_DATA);
- } else {
- writeb(readb(lp->mctbl + byte) | bit, lp->mctbl + byte);
- }
- }
- }
- }
-
- lp->lock = 0; /* Unlock the page register */
-
- return;
-}
-
-/*
-** ISA bus I/O device probe
-*/
-static void isa_probe(struct device *dev, u_long ioaddr)
-{
- int i = num_ewrk3s, maxSlots;
- u_long iobase;
-
- if (!ioaddr && autoprobed) return ; /* Been here before ! */
- if (ioaddr >= 0x400) return; /* Not ISA */
-
- if (ioaddr == 0) { /* Autoprobing */
- iobase = EWRK3_IO_BASE; /* Get the first slot address */
- maxSlots = 24;
- } else { /* Probe a specific location */
- iobase = ioaddr;
- maxSlots = i + 1;
- }
-
- for (; (i<maxSlots) && (dev!=NULL);iobase+=EWRK3_IOP_INC, i++) {
- if (!check_region(iobase, EWRK3_TOTAL_SIZE)) {
- if (DevicePresent(iobase) == 0) {
- if ((dev = alloc_device(dev, iobase)) != NULL) {
- if (ewrk3_hw_init(dev, iobase) == 0) {
- num_ewrk3s++;
- }
- num_eth++;
- }
- }
- } else if (autoprobed) {
- printk("%s: region already allocated at 0x%04lx.\n", dev->name, iobase);
- }
- }
-
- return;
-}
-
-/*
-** EISA bus I/O device probe. Probe from slot 1 since slot 0 is usually
-** the motherboard.
-*/
-static void eisa_probe(struct device *dev, u_long ioaddr)
-{
- int i, maxSlots;
- u_long iobase;
- char name[EWRK3_STRLEN];
-
- if (!ioaddr && autoprobed) return ; /* Been here before ! */
- if (ioaddr < 0x1000) return; /* Not EISA */
-
- if (ioaddr == 0) { /* Autoprobing */
- iobase = EISA_SLOT_INC; /* Get the first slot address */
- i = 1;
- maxSlots = MAX_EISA_SLOTS;
- } else { /* Probe a specific location */
- iobase = ioaddr;
- i = (ioaddr >> 12);
- maxSlots = i + 1;
- }
-
- for (i=1; (i<maxSlots) && (dev!=NULL); i++, iobase+=EISA_SLOT_INC) {
- if (EISA_signature(name, EISA_ID) == 0) {
- if (!check_region(iobase, EWRK3_TOTAL_SIZE)) {
- if (DevicePresent(iobase) == 0) {
- if ((dev = alloc_device(dev, iobase)) != NULL) {
- if (ewrk3_hw_init(dev, iobase) == 0) {
- num_ewrk3s++;
- }
- num_eth++;
- }
- }
- } else if (autoprobed) {
- printk("%s: region already allocated at 0x%04lx.\n", dev->name, iobase);
- }
- }
- }
-
- return;
-}
-
-/*
-** Allocate the device by pointing to the next available space in the
-** device structure. Should one not be available, it is created.
-*/
-static struct device *alloc_device(struct device *dev, u_long iobase)
-{
- int addAutoProbe = 0;
- struct device *tmp = NULL, *ret;
- int (*init)(struct device *) = NULL;
-
- /*
- ** Check the device structures for an end of list or unused device
- */
- if (!loading_module) {
- while (dev->next != NULL) {
- if ((dev->base_addr == EWRK3_NDA) || (dev->base_addr == 0)) break;
- dev = dev->next; /* walk through eth device list */
- num_eth++; /* increment eth device number */
- }
-
- /*
- ** If an autoprobe is requested for another device, we must re-insert
- ** the request later in the list. Remember the current position first.
- */
- if ((dev->base_addr == 0) && (num_ewrk3s > 0)) {
- addAutoProbe++;
- tmp = dev->next; /* point to the next device */
- init = dev->init; /* remember the probe function */
- }
-
- /*
- ** If at end of list and can't use current entry, malloc one up.
- ** If memory could not be allocated, print an error message.
- */
- if ((dev->next == NULL) &&
- !((dev->base_addr == EWRK3_NDA) || (dev->base_addr == 0))){
- dev->next = (struct device *)kmalloc(sizeof(struct device) + 8,
- GFP_KERNEL);
-
- dev = dev->next; /* point to the new device */
- if (dev == NULL) {
- printk("eth%d: Device not initialised, insufficient memory\n",
- num_eth);
- } else {
- /*
- ** If the memory was allocated, point to the new memory area
- ** and initialize it (name, I/O address, next device (NULL) and
- ** initialisation probe routine).
- */
- dev->name = (char *)(dev + sizeof(struct device));
- if (num_eth > 9999) {
- sprintf(dev->name,"eth????"); /* New device name */
- } else {
- sprintf(dev->name,"eth%d", num_eth);/* New device name */
- }
- dev->base_addr = iobase; /* assign the io address */
- dev->next = NULL; /* mark the end of list */
- dev->init = &ewrk3_probe; /* initialisation routine */
- num_ewrk3s++;
- }
- }
- ret = dev; /* return current struct, or NULL */
-
- /*
- ** Now figure out what to do with the autoprobe that has to be inserted.
- ** Firstly, search the (possibly altered) list for an empty space.
- */
- if (ret != NULL) {
- if (addAutoProbe) {
- for (;(tmp->next!=NULL) && (tmp->base_addr!=EWRK3_NDA); tmp=tmp->next);
-
- /*
- ** If no more device structures and can't use the current one, malloc
- ** one up. If memory could not be allocated, print an error message.
- */
- if ((tmp->next == NULL) && !(tmp->base_addr == EWRK3_NDA)) {
- tmp->next = (struct device *)kmalloc(sizeof(struct device) + 8,
- GFP_KERNEL);
- tmp = tmp->next; /* point to the new device */
- if (tmp == NULL) {
- printk("%s: Insufficient memory to extend the device list.\n",
- dev->name);
- } else {
- /*
- ** If the memory was allocated, point to the new memory area
- ** and initialize it (name, I/O address, next device (NULL) and
- ** initialisation probe routine).
- */
- tmp->name = (char *)(tmp + sizeof(struct device));
- if (num_eth > 9999) {
- sprintf(tmp->name,"eth????"); /* New device name */
- } else {
- sprintf(tmp->name,"eth%d", num_eth);/* New device name */
- }
- tmp->base_addr = 0; /* re-insert the io address */
- tmp->next = NULL; /* mark the end of list */
- tmp->init = init; /* initialisation routine */
- }
- } else { /* structure already exists */
- tmp->base_addr = 0; /* re-insert the io address */
- }
- }
- }
- } else {
- ret = dev;
- }
-
- return ret;
-}
-
-/*
-** Read the EWRK3 EEPROM using this routine
-*/
-static int Read_EEPROM(u_long iobase, u_char eaddr)
-{
- int i;
-
- outb((eaddr & 0x3f), EWRK3_PIR1); /* set up 6 bits of address info */
- outb(EEPROM_RD, EWRK3_IOPR); /* issue read command */
- for (i=0;i<5000;i++) inb(EWRK3_CSR); /* wait 1msec */
-
- return inw(EWRK3_EPROM1); /* 16 bits data return */
-}
-
-/*
-** Write the EWRK3 EEPROM using this routine
-*/
-static int Write_EEPROM(short data, u_long iobase, u_char eaddr)
-{
- int i;
-
- outb(EEPROM_WR_EN, EWRK3_IOPR); /* issue write enable command */
- for (i=0;i<5000;i++) inb(EWRK3_CSR); /* wait 1msec */
- outw(data, EWRK3_EPROM1); /* write data to register */
- outb((eaddr & 0x3f), EWRK3_PIR1); /* set up 6 bits of address info */
- outb(EEPROM_WR, EWRK3_IOPR); /* issue write command */
- for (i=0;i<75000;i++) inb(EWRK3_CSR); /* wait 15msec */
- outb(EEPROM_WR_DIS, EWRK3_IOPR); /* issue write disable command */
- for (i=0;i<5000;i++) inb(EWRK3_CSR); /* wait 1msec */
-
- return 0;
-}
-
-/*
-** Look for a particular board name in the on-board EEPROM.
-*/
-static void EthwrkSignature(char *name, char *eeprom_image)
-{
- u_long i,j,k;
- char *signatures[] = EWRK3_SIGNATURE;
-
- strcpy(name, "");
- for (i=0;*signatures[i] != '\0' && *name == '\0';i++) {
- for (j=EEPROM_PNAME7,k=0;j<=EEPROM_PNAME0 && k<strlen(signatures[i]);j++) {
- if (signatures[i][k] == eeprom_image[j]) { /* track signature */
- k++;
- } else { /* lost signature; begin search again */
- k=0;
- }
- }
- if (k == strlen(signatures[i])) {
- for (k=0; k<EWRK3_STRLEN; k++) {
- name[k] = eeprom_image[EEPROM_PNAME7 + k];
- name[EWRK3_STRLEN] = '\0';
- }
- }
- }
-
- return; /* return the device name string */
-}
-
-/*
-** Look for a special sequence in the Ethernet station address PROM that
-** is common across all EWRK3 products.
-**
-** Search the Ethernet address ROM for the signature. Since the ROM address
-** counter can start at an arbitrary point, the search must include the entire
-** probe sequence length plus the (length_of_the_signature - 1).
-** Stop the search IMMEDIATELY after the signature is found so that the
-** PROM address counter is correctly positioned at the start of the
-** ethernet address for later read out.
-*/
-
-static int DevicePresent(u_long iobase)
-{
- union {
- struct {
- u32 a;
- u32 b;
- } llsig;
- char Sig[sizeof(u32) << 1];
- } dev;
- short sigLength;
- char data;
- int i, j, status = 0;
-
- dev.llsig.a = ETH_PROM_SIG;
- dev.llsig.b = ETH_PROM_SIG;
- sigLength = sizeof(u32) << 1;
-
- for (i=0,j=0;j<sigLength && i<PROBE_LENGTH+sigLength-1;i++) {
- data = inb(EWRK3_APROM);
- if (dev.Sig[j] == data) { /* track signature */
- j++;
- } else { /* lost signature; begin search again */
- if (data == dev.Sig[0]) {
- j=1;
- } else {
- j=0;
- }
- }
- }
-
- if (j!=sigLength) {
- status = -ENODEV; /* search failed */
- }
-
- return status;
-}
-
-static u_char get_hw_addr(struct device *dev, u_char *eeprom_image, char chipType)
-{
- int i, j, k;
- u_short chksum;
- u_char crc, lfsr, sd, status = 0;
- u_long iobase = dev->base_addr;
- u16 tmp;
-
- if (chipType == LeMAC2) {
- for (crc=0x6a, j=0; j<ETH_ALEN; j++) {
- sd = dev->dev_addr[j] = eeprom_image[EEPROM_PADDR0 + j];
- outb(dev->dev_addr[j], EWRK3_PAR0 + j);
- for (k=0; k<8; k++, sd >>= 1) {
- lfsr = ((((crc & 0x02) >> 1) ^ (crc & 0x01)) ^ (sd & 0x01)) << 7;
- crc = (crc >> 1) + lfsr;
- }
- }
- if (crc != eeprom_image[EEPROM_PA_CRC]) status = -1;
- } else {
- for (i=0,k=0;i<ETH_ALEN;) {
- k <<= 1 ;
- if (k > 0xffff) k-=0xffff;
-
- k += (u_char) (tmp = inb(EWRK3_APROM));
- dev->dev_addr[i] = (u_char) tmp;
- outb(dev->dev_addr[i], EWRK3_PAR0 + i);
- i++;
- k += (u_short) ((tmp = inb(EWRK3_APROM)) << 8);
- dev->dev_addr[i] = (u_char) tmp;
- outb(dev->dev_addr[i], EWRK3_PAR0 + i);
- i++;
-
- if (k > 0xffff) k-=0xffff;
- }
- if (k == 0xffff) k=0;
- chksum = inb(EWRK3_APROM);
- chksum |= (inb(EWRK3_APROM)<<8);
- if (k != chksum) status = -1;
- }
-
- return status;
-}
-
-/*
-** Look for a particular board name in the EISA configuration space
-*/
-static int EISA_signature(char *name, s32 eisa_id)
-{
- u_long i;
- char *signatures[] = EWRK3_SIGNATURE;
- char ManCode[EWRK3_STRLEN];
- union {
- s32 ID;
- char Id[4];
- } Eisa;
- int status = 0;
-
- *name = '\0';
- for (i=0; i<4; i++) {
- Eisa.Id[i] = inb(eisa_id + i);
- }
-
- ManCode[0]=(((Eisa.Id[0]>>2)&0x1f)+0x40);
- ManCode[1]=(((Eisa.Id[1]&0xe0)>>5)+((Eisa.Id[0]&0x03)<<3)+0x40);
- ManCode[2]=(((Eisa.Id[2]>>4)&0x0f)+0x30);
- ManCode[3]=((Eisa.Id[2]&0x0f)+0x30);
- ManCode[4]=(((Eisa.Id[3]>>4)&0x0f)+0x30);
- ManCode[5]='\0';
-
- for (i=0;(*signatures[i] != '\0') && (*name == '\0');i++) {
- if (strstr(ManCode, signatures[i]) != NULL) {
- strcpy(name,ManCode);
- status = 1;
- }
- }
-
- return status; /* return the device name string */
-}
-
-/*
-** Perform IOCTL call functions here. Some are privileged operations and the
-** effective uid is checked in those cases.
-*/
-static int ewrk3_ioctl(struct device *dev, struct ifreq *rq, int cmd)
-{
- struct ewrk3_private *lp = (struct ewrk3_private *)dev->priv;
- struct ewrk3_ioctl *ioc = (struct ewrk3_ioctl *) &rq->ifr_data;
- u_long iobase = dev->base_addr;
- int i, j, status = 0;
- u_char csr;
- union {
- u_char addr[HASH_TABLE_LEN * ETH_ALEN];
- u_short val[(HASH_TABLE_LEN * ETH_ALEN) >> 1];
- } tmp;
-
- switch(ioc->cmd) {
- case EWRK3_GET_HWADDR: /* Get the hardware address */
- for (i=0; i<ETH_ALEN; i++) {
- tmp.addr[i] = dev->dev_addr[i];
- }
- ioc->len = ETH_ALEN;
- if (!(status = verify_area(VERIFY_WRITE, (void *)ioc->data, ioc->len))) {
- memcpy_tofs(ioc->data, tmp.addr, ioc->len);
- }
-
- break;
- case EWRK3_SET_HWADDR: /* Set the hardware address */
- if (suser()) {
- if (!(status = verify_area(VERIFY_READ, (void *)ioc->data, ETH_ALEN))) {
- csr = inb(EWRK3_CSR);
- csr |= (CSR_TXD|CSR_RXD);
- outb(csr, EWRK3_CSR); /* Disable the TX and RX */
-
- memcpy_fromfs(tmp.addr,ioc->data,ETH_ALEN);
- for (i=0; i<ETH_ALEN; i++) {
- dev->dev_addr[i] = tmp.addr[i];
- outb(tmp.addr[i], EWRK3_PAR0 + i);
- }
-
- csr &= ~(CSR_TXD|CSR_RXD); /* Enable the TX and RX */
- outb(csr, EWRK3_CSR);
- }
- } else {
- status = -EPERM;
- }
-
- break;
- case EWRK3_SET_PROM: /* Set Promiscuous Mode */
- if (suser()) {
- csr = inb(EWRK3_CSR);
- csr |= CSR_PME;
- csr &= ~CSR_MCE;
- outb(csr, EWRK3_CSR);
- } else {
- status = -EPERM;
- }
-
- break;
- case EWRK3_CLR_PROM: /* Clear Promiscuous Mode */
- if (suser()) {
- csr = inb(EWRK3_CSR);
- csr &= ~CSR_PME;
- outb(csr, EWRK3_CSR);
- } else {
- status = -EPERM;
- }
-
- break;
- case EWRK3_SAY_BOO: /* Say "Boo!" to the kernel log file */
- printk("%s: Boo!\n", dev->name);
-
- break;
- case EWRK3_GET_MCA: /* Get the multicast address table */
- if (!(status = verify_area(VERIFY_WRITE, ioc->data, ioc->len))) {
- while (set_bit(0, (void *)&lp->lock) != 0); /* Wait for lock to free */
- if (lp->shmem_length == IO_ONLY) {
- outb(0, EWRK3_IOPR);
- outw(PAGE0_HTE, EWRK3_PIR1);
- for (i=0; i<(HASH_TABLE_LEN >> 3); i++) {
- tmp.addr[i] = inb(EWRK3_DATA);
- }
- } else {
- outb(0, EWRK3_MPR);
- memcpy_fromio(tmp.addr, (char *)(lp->shmem_base + PAGE0_HTE), (HASH_TABLE_LEN >> 3));
- }
- ioc->len = (HASH_TABLE_LEN >> 3);
- memcpy_tofs(ioc->data, tmp.addr, ioc->len);
- }
- lp->lock = 0; /* Unlock the page register */
-
- break;
- case EWRK3_SET_MCA: /* Set a multicast address */
- if (suser()) {
- if (!(status=verify_area(VERIFY_READ, ioc->data, ETH_ALEN*ioc->len))) {
- memcpy_fromfs(tmp.addr, ioc->data, ETH_ALEN * ioc->len);
- set_multicast_list(dev);
- }
- } else {
- status = -EPERM;
- }
-
- break;
- case EWRK3_CLR_MCA: /* Clear all multicast addresses */
- if (suser()) {
- set_multicast_list(dev);
- } else {
- status = -EPERM;
- }
-
- break;
- case EWRK3_MCA_EN: /* Enable multicast addressing */
- if (suser()) {
- csr = inb(EWRK3_CSR);
- csr |= CSR_MCE;
- csr &= ~CSR_PME;
- outb(csr, EWRK3_CSR);
- } else {
- status = -EPERM;
- }
-
- break;
- case EWRK3_GET_STATS: /* Get the driver statistics */
- cli();
- ioc->len = sizeof(lp->pktStats);
- if (!(status=verify_area(VERIFY_WRITE, ioc->data, ioc->len))) {
- memcpy_tofs(ioc->data, &lp->pktStats, ioc->len);
- }
- sti();
-
- break;
- case EWRK3_CLR_STATS: /* Zero out the driver statistics */
- if (suser()) {
- cli();
- memset(&lp->pktStats, 0, sizeof(lp->pktStats));
- sti();
- } else {
- status = -EPERM;
- }
-
- break;
- case EWRK3_GET_CSR: /* Get the CSR Register contents */
- tmp.addr[0] = inb(EWRK3_CSR);
- ioc->len = 1;
- if (!(status=verify_area(VERIFY_WRITE, ioc->data, ioc->len))) {
- memcpy_tofs(ioc->data, tmp.addr, ioc->len);
- }
-
- break;
- case EWRK3_SET_CSR: /* Set the CSR Register contents */
- if (suser()) {
- if (!(status=verify_area(VERIFY_READ, ioc->data, 1))) {
- memcpy_fromfs(tmp.addr, ioc->data, 1);
- outb(tmp.addr[0], EWRK3_CSR);
- }
- } else {
- status = -EPERM;
- }
-
- break;
- case EWRK3_GET_EEPROM: /* Get the EEPROM contents */
- if (suser()) {
- for (i=0; i<(EEPROM_MAX>>1); i++) {
- tmp.val[i] = (short)Read_EEPROM(iobase, i);
- }
- i = EEPROM_MAX;
- tmp.addr[i++] = inb(EWRK3_CMR); /* Config/Management Reg. */
- for (j=0;j<ETH_ALEN;j++) {
- tmp.addr[i++] = inb(EWRK3_PAR0 + j);
- }
- ioc->len = EEPROM_MAX + 1 + ETH_ALEN;
- if (!(status=verify_area(VERIFY_WRITE, ioc->data, ioc->len))) {
- memcpy_tofs(ioc->data, tmp.addr, ioc->len);
- }
- } else {
- status = -EPERM;
- }
-
- break;
- case EWRK3_SET_EEPROM: /* Set the EEPROM contents */
- if (suser()) {
- if (!(status=verify_area(VERIFY_READ, ioc->data, EEPROM_MAX))) {
- memcpy_fromfs(tmp.addr, ioc->data, EEPROM_MAX);
- for (i=0; i<(EEPROM_MAX>>1); i++) {
- Write_EEPROM(tmp.val[i], iobase, i);
- }
- }
- } else {
- status = -EPERM;
- }
-
- break;
- case EWRK3_GET_CMR: /* Get the CMR Register contents */
- tmp.addr[0] = inb(EWRK3_CMR);
- ioc->len = 1;
- if (!(status=verify_area(VERIFY_WRITE, ioc->data, ioc->len))) {
- memcpy_tofs(ioc->data, tmp.addr, ioc->len);
- }
-
- break;
- case EWRK3_SET_TX_CUT_THRU: /* Set TX cut through mode */
- if (suser()) {
- lp->txc = 1;
- } else {
- status = -EPERM;
- }
-
- break;
- case EWRK3_CLR_TX_CUT_THRU: /* Clear TX cut through mode */
- if (suser()) {
- lp->txc = 0;
- } else {
- status = -EPERM;
- }
-
- break;
- default:
- status = -EOPNOTSUPP;
- }
-
- return status;
-}
-
-#ifdef MODULE
-static char devicename[9] = { 0, };
-static struct device thisEthwrk = {
- devicename, /* device name is inserted by /linux/drivers/net/net_init.c */
- 0, 0, 0, 0,
- 0x300, 5, /* I/O address, IRQ */
- 0, 0, 0, NULL, ewrk3_probe };
-
-static int io=0x300; /* <--- EDIT THESE LINES FOR YOUR CONFIGURATION */
-static int irq=5; /* or use the insmod io= irq= options */
-
-int
-init_module(void)
-{
- thisEthwrk.base_addr=io;
- thisEthwrk.irq=irq;
- if (register_netdev(&thisEthwrk) != 0)
- return -EIO;
- return 0;
-}
-
-void
-cleanup_module(void)
-{
- release_region(thisEthwrk.base_addr, EWRK3_TOTAL_SIZE);
-
- if (thisEthwrk.priv) {
- kfree(thisEthwrk.priv);
- thisEthwrk.priv = NULL;
- }
- thisEthwrk.irq = 0;
-
- unregister_netdev(&thisEthwrk);
-}
-#endif /* MODULE */
-
-
-/*
- * Local variables:
- * kernel-compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O2 -m486 -c ewrk3.c"
- *
- * module-compile-command: "gcc -D__KERNEL__ -DMODULE -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O2 -m486 -c ewrk3.c"
- * End:
- */
-
diff --git a/i386/i386at/gpl/linux/net/ewrk3.h b/i386/i386at/gpl/linux/net/ewrk3.h
deleted file mode 100644
index b37abf46..00000000
--- a/i386/i386at/gpl/linux/net/ewrk3.h
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- Written 1994 by David C. Davies.
-
- Copyright 1994 Digital Equipment Corporation.
-
- This software may be used and distributed according to the terms of the
- GNU Public License, incorporated herein by reference.
-
- The author may be reached as davies@wanton.lkg.dec.com or Digital
- Equipment Corporation, 550 King Street, Littleton MA 01460.
-
- =========================================================================
-*/
-
-/*
-** I/O Address Register Map
-*/
-#define EWRK3_CSR iobase+0x00 /* Control and Status Register */
-#define EWRK3_CR iobase+0x01 /* Control Register */
-#define EWRK3_ICR iobase+0x02 /* Interrupt Control Register */
-#define EWRK3_TSR iobase+0x03 /* Transmit Status Register */
-#define EWRK3_RSVD1 iobase+0x04 /* RESERVED */
-#define EWRK3_RSVD2 iobase+0x05 /* RESERVED */
-#define EWRK3_FMQ iobase+0x06 /* Free Memory Queue */
-#define EWRK3_FMQC iobase+0x07 /* Free Memory Queue Counter */
-#define EWRK3_RQ iobase+0x08 /* Receive Queue */
-#define EWRK3_RQC iobase+0x09 /* Receive Queue Counter */
-#define EWRK3_TQ iobase+0x0a /* Transmit Queue */
-#define EWRK3_TQC iobase+0x0b /* Transmit Queue Counter */
-#define EWRK3_TDQ iobase+0x0c /* Transmit Done Queue */
-#define EWRK3_TDQC iobase+0x0d /* Transmit Done Queue Counter */
-#define EWRK3_PIR1 iobase+0x0e /* Page Index Register 1 */
-#define EWRK3_PIR2 iobase+0x0f /* Page Index Register 2 */
-#define EWRK3_DATA iobase+0x10 /* Data Register */
-#define EWRK3_IOPR iobase+0x11 /* I/O Page Register */
-#define EWRK3_IOBR iobase+0x12 /* I/O Base Register */
-#define EWRK3_MPR iobase+0x13 /* Memory Page Register */
-#define EWRK3_MBR iobase+0x14 /* Memory Base Register */
-#define EWRK3_APROM iobase+0x15 /* Address PROM */
-#define EWRK3_EPROM1 iobase+0x16 /* EEPROM Data Register 1 */
-#define EWRK3_EPROM2 iobase+0x17 /* EEPROM Data Register 2 */
-#define EWRK3_PAR0 iobase+0x18 /* Physical Address Register 0 */
-#define EWRK3_PAR1 iobase+0x19 /* Physical Address Register 1 */
-#define EWRK3_PAR2 iobase+0x1a /* Physical Address Register 2 */
-#define EWRK3_PAR3 iobase+0x1b /* Physical Address Register 3 */
-#define EWRK3_PAR4 iobase+0x1c /* Physical Address Register 4 */
-#define EWRK3_PAR5 iobase+0x1d /* Physical Address Register 5 */
-#define EWRK3_CMR iobase+0x1e /* Configuration/Management Register */
-
-/*
-** Control Page Map
-*/
-#define PAGE0_FMQ 0x000 /* Free Memory Queue */
-#define PAGE0_RQ 0x080 /* Receive Queue */
-#define PAGE0_TQ 0x100 /* Transmit Queue */
-#define PAGE0_TDQ 0x180 /* Transmit Done Queue */
-#define PAGE0_HTE 0x200 /* Hash Table Entries */
-#define PAGE0_RSVD 0x240 /* RESERVED */
-#define PAGE0_USRD 0x600 /* User Data */
-
-/*
-** Control and Status Register bit definitions (EWRK3_CSR)
-*/
-#define CSR_RA 0x80 /* Runt Accept */
-#define CSR_PME 0x40 /* Promiscuous Mode Enable */
-#define CSR_MCE 0x20 /* Multicast Enable */
-#define CSR_TNE 0x08 /* TX Done Queue Not Empty */
-#define CSR_RNE 0x04 /* RX Queue Not Empty */
-#define CSR_TXD 0x02 /* TX Disable */
-#define CSR_RXD 0x01 /* RX Disable */
-
-/*
-** Control Register bit definitions (EWRK3_CR)
-*/
-#define CR_APD 0x80 /* Auto Port Disable */
-#define CR_PSEL 0x40 /* Port Select (0->TP port) */
-#define CR_LBCK 0x20 /* LoopBaCK enable */
-#define CR_FDUP 0x10 /* Full DUPlex enable */
-#define CR_FBUS 0x08 /* Fast BUS enable (ISA clk > 8.33MHz) */
-#define CR_EN_16 0x04 /* ENable 16 bit memory accesses */
-#define CR_LED 0x02 /* LED (1-> turn on) */
-
-/*
-** Interrupt Control Register bit definitions (EWRK3_ICR)
-*/
-#define ICR_IE 0x80 /* Interrupt Enable */
-#define ICR_IS 0x60 /* Interrupt Selected */
-#define ICR_TNEM 0x08 /* TNE Mask (0->mask) */
-#define ICR_RNEM 0x04 /* RNE Mask (0->mask) */
-#define ICR_TXDM 0x02 /* TXD Mask (0->mask) */
-#define ICR_RXDM 0x01 /* RXD Mask (0->mask) */
-
-/*
-** Transmit Status Register bit definitions (EWRK3_TSR)
-*/
-#define TSR_NCL 0x80 /* No Carrier Loopback */
-#define TSR_ID 0x40 /* Initially Deferred */
-#define TSR_LCL 0x20 /* Late CoLlision */
-#define TSR_ECL 0x10 /* Excessive CoLlisions */
-#define TSR_RCNTR 0x0f /* Retries CouNTeR */
-
-/*
-** I/O Page Register bit definitions (EWRK3_IOPR)
-*/
-#define EEPROM_INIT 0xc0 /* EEPROM INIT command */
-#define EEPROM_WR_EN 0xc8 /* EEPROM WRITE ENABLE command */
-#define EEPROM_WR 0xd0 /* EEPROM WRITE command */
-#define EEPROM_WR_DIS 0xd8 /* EEPROM WRITE DISABLE command */
-#define EEPROM_RD 0xe0 /* EEPROM READ command */
-
-/*
-** I/O Base Register bit definitions (EWRK3_IOBR)
-*/
-#define EISA_REGS_EN 0x20 /* Enable EISA ID and Control Registers */
-#define EISA_IOB 0x1f /* Compare bits for I/O Base Address */
-
-/*
-** I/O Congiguration/Management Register bit definitions (EWRK3_CMR)
-*/
-#define CMR_RA 0x80 /* Read Ahead */
-#define CMR_WB 0x40 /* Write Behind */
-#define CMR_LINK 0x20 /* 0->TP */
-#define CMR_POLARITY 0x10 /* Informational */
-#define CMR_NO_EEPROM 0x0c /* NO_EEPROM<1:0> pin status */
-#define CMR_HS 0x08 /* Hard Strapped pin status (LeMAC2) */
-#define CMR_PNP 0x04 /* Plug 'n Play */
-#define CMR_DRAM 0x02 /* 0-> 1DRAM, 1-> 2 DRAM on board */
-#define CMR_0WS 0x01 /* Zero Wait State */
-
-/*
-** MAC Receive Status Register bit definitions
-*/
-
-#define R_ROK 0x80 /* Receive OK summary */
-#define R_IAM 0x10 /* Individual Address Match */
-#define R_MCM 0x08 /* MultiCast Match */
-#define R_DBE 0x04 /* Dribble Bit Error */
-#define R_CRC 0x02 /* CRC error */
-#define R_PLL 0x01 /* Phase Lock Lost */
-
-/*
-** MAC Transmit Control Register bit definitions
-*/
-
-#define TCR_SQEE 0x40 /* SQE Enable - look for heartbeat */
-#define TCR_SED 0x20 /* Stop when Error Detected */
-#define TCR_QMODE 0x10 /* Q_MODE */
-#define TCR_LAB 0x08 /* Less Aggressive Backoff */
-#define TCR_PAD 0x04 /* PAD Runt Packets */
-#define TCR_IFC 0x02 /* Insert Frame Check */
-#define TCR_ISA 0x01 /* Insert Source Address */
-
-/*
-** MAC Transmit Status Register bit definitions
-*/
-
-#define T_VSTS 0x80 /* Valid STatuS */
-#define T_CTU 0x40 /* Cut Through Used */
-#define T_SQE 0x20 /* Signal Quality Error */
-#define T_NCL 0x10 /* No Carrier Loopback */
-#define T_LCL 0x08 /* Late Collision */
-#define T_ID 0x04 /* Initially Deferred */
-#define T_COLL 0x03 /* COLLision status */
-#define T_XCOLL 0x03 /* Excessive Collisions */
-#define T_MCOLL 0x02 /* Multiple Collisions */
-#define T_OCOLL 0x01 /* One Collision */
-#define T_NOCOLL 0x00 /* No Collisions */
-#define T_XUR 0x03 /* Excessive Underruns */
-#define T_TXE 0x7f /* TX Errors */
-
-/*
-** EISA Configuration Register bit definitions
-*/
-
-#define EISA_ID iobase + 0x0c80 /* EISA ID Registers */
-#define EISA_ID0 iobase + 0x0c80 /* EISA ID Register 0 */
-#define EISA_ID1 iobase + 0x0c81 /* EISA ID Register 1 */
-#define EISA_ID2 iobase + 0x0c82 /* EISA ID Register 2 */
-#define EISA_ID3 iobase + 0x0c83 /* EISA ID Register 3 */
-#define EISA_CR iobase + 0x0c84 /* EISA Control Register */
-
-/*
-** EEPROM BYTES
-*/
-#define EEPROM_MEMB 0x00
-#define EEPROM_IOB 0x01
-#define EEPROM_EISA_ID0 0x02
-#define EEPROM_EISA_ID1 0x03
-#define EEPROM_EISA_ID2 0x04
-#define EEPROM_EISA_ID3 0x05
-#define EEPROM_MISC0 0x06
-#define EEPROM_MISC1 0x07
-#define EEPROM_PNAME7 0x08
-#define EEPROM_PNAME6 0x09
-#define EEPROM_PNAME5 0x0a
-#define EEPROM_PNAME4 0x0b
-#define EEPROM_PNAME3 0x0c
-#define EEPROM_PNAME2 0x0d
-#define EEPROM_PNAME1 0x0e
-#define EEPROM_PNAME0 0x0f
-#define EEPROM_SWFLAGS 0x10
-#define EEPROM_HWCAT 0x11
-#define EEPROM_NETMAN2 0x12
-#define EEPROM_REVLVL 0x13
-#define EEPROM_NETMAN0 0x14
-#define EEPROM_NETMAN1 0x15
-#define EEPROM_CHIPVER 0x16
-#define EEPROM_SETUP 0x17
-#define EEPROM_PADDR0 0x18
-#define EEPROM_PADDR1 0x19
-#define EEPROM_PADDR2 0x1a
-#define EEPROM_PADDR3 0x1b
-#define EEPROM_PADDR4 0x1c
-#define EEPROM_PADDR5 0x1d
-#define EEPROM_PA_CRC 0x1e
-#define EEPROM_CHKSUM 0x1f
-
-/*
-** EEPROM bytes for checksumming
-*/
-#define EEPROM_MAX 32 /* bytes */
-
-/*
-** EEPROM MISCELLANEOUS FLAGS
-*/
-#define RBE_SHADOW 0x0100 /* Remote Boot Enable Shadow */
-#define READ_AHEAD 0x0080 /* Read Ahead feature */
-#define IRQ_SEL2 0x0070 /* IRQ line selection (LeMAC2) */
-#define IRQ_SEL 0x0060 /* IRQ line selection */
-#define FAST_BUS 0x0008 /* ISA Bus speeds > 8.33MHz */
-#define ENA_16 0x0004 /* Enables 16 bit memory transfers */
-#define WRITE_BEHIND 0x0002 /* Write Behind feature */
-#define _0WS_ENA 0x0001 /* Zero Wait State Enable */
-
-/*
-** EEPROM NETWORK MANAGEMENT FLAGS
-*/
-#define NETMAN_POL 0x04 /* Polarity defeat */
-#define NETMAN_LINK 0x02 /* Link defeat */
-#define NETMAN_CCE 0x01 /* Custom Counters Enable */
-
-/*
-** EEPROM SW FLAGS
-*/
-#define SW_SQE 0x10 /* Signal Quality Error */
-#define SW_LAB 0x08 /* Less Aggressive Backoff */
-#define SW_INIT 0x04 /* Initialized */
-#define SW_TIMEOUT 0x02 /* 0:2.5 mins, 1: 30 secs */
-#define SW_REMOTE 0x01 /* Remote Boot Enable -> 1 */
-
-/*
-** EEPROM SETUP FLAGS
-*/
-#define SETUP_APD 0x80 /* AutoPort Disable */
-#define SETUP_PS 0x40 /* Port Select */
-#define SETUP_MP 0x20 /* MultiPort */
-#define SETUP_1TP 0x10 /* 1 port, TP */
-#define SETUP_1COAX 0x00 /* 1 port, Coax */
-#define SETUP_DRAM 0x02 /* Number of DRAMS on board */
-
-/*
-** EEPROM MANAGEMENT FLAGS
-*/
-#define MGMT_CCE 0x01 /* Custom Counters Enable */
-
-/*
-** EEPROM VERSIONS
-*/
-#define LeMAC 0x11
-#define LeMAC2 0x12
-
-/*
-** Miscellaneous
-*/
-
-#define EEPROM_WAIT_TIME 1000 /* Number of microseconds */
-#define EISA_EN 0x0001 /* Enable EISA bus buffers */
-
-#define HASH_TABLE_LEN 512 /* Bits */
-
-#define XCT 0x80 /* Transmit Cut Through */
-#define PRELOAD 16 /* 4 long words */
-
-#define MASK_INTERRUPTS 1
-#define UNMASK_INTERRUPTS 0
-
-#define EEPROM_OFFSET(a) ((u_short)((u_long)(a)))
-
-/*
-** Include the IOCTL stuff
-*/
-#include <linux/sockios.h>
-
-#define EWRK3IOCTL SIOCDEVPRIVATE
-
-struct ewrk3_ioctl {
- unsigned short cmd; /* Command to run */
- unsigned short len; /* Length of the data buffer */
- unsigned char *data; /* Pointer to the data buffer */
-};
-
-/*
-** Recognised commands for the driver
-*/
-#define EWRK3_GET_HWADDR 0x01 /* Get the hardware address */
-#define EWRK3_SET_HWADDR 0x02 /* Get the hardware address */
-#define EWRK3_SET_PROM 0x03 /* Set Promiscuous Mode */
-#define EWRK3_CLR_PROM 0x04 /* Clear Promiscuous Mode */
-#define EWRK3_SAY_BOO 0x05 /* Say "Boo!" to the kernel log file */
-#define EWRK3_GET_MCA 0x06 /* Get a multicast address */
-#define EWRK3_SET_MCA 0x07 /* Set a multicast address */
-#define EWRK3_CLR_MCA 0x08 /* Clear a multicast address */
-#define EWRK3_MCA_EN 0x09 /* Enable a multicast address group */
-#define EWRK3_GET_STATS 0x0a /* Get the driver statistics */
-#define EWRK3_CLR_STATS 0x0b /* Zero out the driver statistics */
-#define EWRK3_GET_CSR 0x0c /* Get the CSR Register contents */
-#define EWRK3_SET_CSR 0x0d /* Set the CSR Register contents */
-#define EWRK3_GET_EEPROM 0x0e /* Get the EEPROM contents */
-#define EWRK3_SET_EEPROM 0x0f /* Set the EEPROM contents */
-#define EWRK3_GET_CMR 0x10 /* Get the CMR Register contents */
-#define EWRK3_CLR_TX_CUT_THRU 0x11 /* Clear the TX cut through mode */
-#define EWRK3_SET_TX_CUT_THRU 0x12 /* Set the TX cut through mode */
diff --git a/i386/i386at/gpl/linux/net/hp-plus.c b/i386/i386at/gpl/linux/net/hp-plus.c
deleted file mode 100644
index aed7ee01..00000000
--- a/i386/i386at/gpl/linux/net/hp-plus.c
+++ /dev/null
@@ -1,483 +0,0 @@
-/* hp-plus.c: A HP PCLAN/plus ethernet driver for linux. */
-/*
- Written 1994 by Donald Becker.
-
- This driver is for the Hewlett Packard PC LAN (27***) plus ethercards.
- These cards are sold under several model numbers, usually 2724*.
-
- This software may be used and distributed according to the terms
- of the GNU Public License, incorporated herein by reference.
-
- The author may be reached as becker@CESDIS.gsfc.nasa.gov, or C/O
-
- Center of Excellence in Space Data and Information Sciences
- Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
-
- As is often the case, a great deal of credit is owed to Russ Nelson.
- The Crynwr packet driver was my primary source of HP-specific
- programming information.
-*/
-
-static const char *version =
-"hp-plus.c:v1.10 9/24/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
-
-#include <linux/module.h>
-
-#include <linux/string.h> /* Important -- this inlines word moves. */
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-
-
-#include "8390.h"
-
-/* A zero-terminated list of I/O addresses to be probed. */
-static unsigned int hpplus_portlist[] =
-{0x200, 0x240, 0x280, 0x2C0, 0x300, 0x320, 0x340, 0};
-
-/*
- The HP EtherTwist chip implementation is a fairly routine DP8390
- implementation. It allows both shared memory and programmed-I/O buffer
- access, using a custom interface for both. The programmed-I/O mode is
- entirely implemented in the HP EtherTwist chip, bypassing the problem
- ridden built-in 8390 facilities used on NE2000 designs. The shared
- memory mode is likewise special, with an offset register used to make
- packets appear at the shared memory base. Both modes use a base and bounds
- page register to hide the Rx ring buffer wrap -- a packet that spans the
- end of physical buffer memory appears continuous to the driver. (c.f. the
- 3c503 and Cabletron E2100)
-
- A special note: the internal buffer of the board is only 8 bits wide.
- This lays several nasty traps for the unaware:
- - the 8390 must be programmed for byte-wide operations
- - all I/O and memory operations must work on whole words (the access
- latches are serially preloaded and have no byte-swapping ability).
-
- This board is laid out in I/O space much like the earlier HP boards:
- the first 16 locations are for the board registers, and the second 16 are
- for the 8390. The board is easy to identify, with both a dedicated 16 bit
- ID register and a constant 0x530* value in the upper bits of the paging
- register.
-*/
-
-#define HP_ID 0x00 /* ID register, always 0x4850. */
-#define HP_PAGING 0x02 /* Registers visible @ 8-f, see PageName. */
-#define HPP_OPTION 0x04 /* Bitmapped options, see HP_Option. */
-#define HPP_OUT_ADDR 0x08 /* I/O output location in Perf_Page. */
-#define HPP_IN_ADDR 0x0A /* I/O input location in Perf_Page. */
-#define HP_DATAPORT 0x0c /* I/O data transfer in Perf_Page. */
-#define NIC_OFFSET 0x10 /* Offset to the 8390 registers. */
-#define HP_IO_EXTENT 32
-
-#define HP_START_PG 0x00 /* First page of TX buffer */
-#define HP_STOP_PG 0x80 /* Last page +1 of RX ring */
-
-/* The register set selected in HP_PAGING. */
-enum PageName {
- Perf_Page = 0, /* Normal operation. */
- MAC_Page = 1, /* The ethernet address (+checksum). */
- HW_Page = 2, /* EEPROM-loaded hardware parameters. */
- LAN_Page = 4, /* Transceiver selection, testing, etc. */
- ID_Page = 6 };
-
-/* The bit definitions for the HPP_OPTION register. */
-enum HP_Option {
- NICReset = 1, ChipReset = 2, /* Active low, really UNreset. */
- EnableIRQ = 4, FakeIntr = 8, BootROMEnb = 0x10, IOEnb = 0x20,
- MemEnable = 0x40, ZeroWait = 0x80, MemDisable = 0x1000, };
-
-int hp_plus_probe(struct device *dev);
-int hpp_probe1(struct device *dev, int ioaddr);
-
-static void hpp_reset_8390(struct device *dev);
-static int hpp_open(struct device *dev);
-static int hpp_close(struct device *dev);
-static void hpp_mem_block_input(struct device *dev, int count,
- struct sk_buff *skb, int ring_offset);
-static void hpp_mem_block_output(struct device *dev, int count,
- const unsigned char *buf, const start_page);
-static void hpp_mem_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr,
- int ring_page);
-static void hpp_io_block_input(struct device *dev, int count,
- struct sk_buff *skb, int ring_offset);
-static void hpp_io_block_output(struct device *dev, int count,
- const unsigned char *buf, const start_page);
-static void hpp_io_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr,
- int ring_page);
-
-
-/* Probe a list of addresses for an HP LAN+ adaptor.
- This routine is almost boilerplate. */
-#ifdef HAVE_DEVLIST
-/* Support for a alternate probe manager, which will eliminate the
- boilerplate below. */
-struct netdev_entry hpplus_drv =
-{"hpplus", hpp_probe1, HP_IO_EXTENT, hpplus_portlist};
-#else
-
-int hp_plus_probe(struct device *dev)
-{
- int i;
- int base_addr = dev ? dev->base_addr : 0;
-
- if (base_addr > 0x1ff) /* Check a single specified location. */
- return hpp_probe1(dev, base_addr);
- else if (base_addr != 0) /* Don't probe at all. */
- return ENXIO;
-
- for (i = 0; hpplus_portlist[i]; i++) {
- int ioaddr = hpplus_portlist[i];
- if (check_region(ioaddr, HP_IO_EXTENT))
- continue;
- if (hpp_probe1(dev, ioaddr) == 0)
- return 0;
- }
-
- return ENODEV;
-}
-#endif
-
-/* Do the interesting part of the probe at a single address. */
-int hpp_probe1(struct device *dev, int ioaddr)
-{
- int i;
- unsigned char checksum = 0;
- const char *name = "HP-PC-LAN+";
- int mem_start;
- static unsigned version_printed = 0;
-
- /* Check for the HP+ signature, 50 48 0x 53. */
- if (inw(ioaddr + HP_ID) != 0x4850
- || (inw(ioaddr + HP_PAGING) & 0xfff0) != 0x5300)
- return ENODEV;
-
- /* We should have a "dev" from Space.c or the static module table. */
- if (dev == NULL) {
- printk("hp-plus.c: Passed a NULL device.\n");
- dev = init_etherdev(0, 0);
- }
-
- if (ei_debug && version_printed++ == 0)
- printk(version);
-
- printk("%s: %s at %#3x,", dev->name, name, ioaddr);
-
- /* Retrieve and checksum the station address. */
- outw(MAC_Page, ioaddr + HP_PAGING);
-
- for(i = 0; i < ETHER_ADDR_LEN; i++) {
- unsigned char inval = inb(ioaddr + 8 + i);
- dev->dev_addr[i] = inval;
- checksum += inval;
- printk(" %2.2x", inval);
- }
- checksum += inb(ioaddr + 14);
-
- if (checksum != 0xff) {
- printk(" bad checksum %2.2x.\n", checksum);
- return ENODEV;
- } else {
- /* Point at the Software Configuration Flags. */
- outw(ID_Page, ioaddr + HP_PAGING);
- printk(" ID %4.4x", inw(ioaddr + 12));
- }
-
- /* Allocate dev->priv and fill in 8390 specific dev fields. */
- if (ethdev_init(dev)) {
- printk ("hp-plus.c: unable to allocate memory for dev->priv.\n");
- return -ENOMEM;
- }
-
- /* Grab the region so we can find another board if something fails. */
- request_region(ioaddr, HP_IO_EXTENT,"hp-plus");
-
- /* Read the IRQ line. */
- outw(HW_Page, ioaddr + HP_PAGING);
- {
- int irq = inb(ioaddr + 13) & 0x0f;
- int option = inw(ioaddr + HPP_OPTION);
-
- dev->irq = irq;
- if (option & MemEnable) {
- mem_start = inw(ioaddr + 9) << 8;
- printk(", IRQ %d, memory address %#x.\n", irq, mem_start);
- } else {
- mem_start = 0;
- printk(", IRQ %d, programmed-I/O mode.\n", irq);
- }
- }
-
- /* Set the wrap registers for string I/O reads. */
- outw((HP_START_PG + TX_2X_PAGES) | ((HP_STOP_PG - 1) << 8), ioaddr + 14);
-
- /* Set the base address to point to the NIC, not the "real" base! */
- dev->base_addr = ioaddr + NIC_OFFSET;
-
- dev->open = &hpp_open;
- dev->stop = &hpp_close;
-
- ei_status.name = name;
- ei_status.word16 = 0; /* Agggghhhhh! Debug time: 2 days! */
- ei_status.tx_start_page = HP_START_PG;
- ei_status.rx_start_page = HP_START_PG + TX_2X_PAGES;
- ei_status.stop_page = HP_STOP_PG;
-
- ei_status.reset_8390 = &hpp_reset_8390;
- ei_status.block_input = &hpp_io_block_input;
- ei_status.block_output = &hpp_io_block_output;
- ei_status.get_8390_hdr = &hpp_io_get_8390_hdr;
-
- /* Check if the memory_enable flag is set in the option register. */
- if (mem_start) {
- ei_status.block_input = &hpp_mem_block_input;
- ei_status.block_output = &hpp_mem_block_output;
- ei_status.get_8390_hdr = &hpp_mem_get_8390_hdr;
- dev->mem_start = mem_start;
- dev->rmem_start = dev->mem_start + TX_2X_PAGES*256;
- dev->mem_end = dev->rmem_end
- = dev->mem_start + (HP_STOP_PG - HP_START_PG)*256;
- }
-
- outw(Perf_Page, ioaddr + HP_PAGING);
- NS8390_init(dev, 0);
- /* Leave the 8390 and HP chip reset. */
- outw(inw(ioaddr + HPP_OPTION) & ~EnableIRQ, ioaddr + HPP_OPTION);
-
- return 0;
-}
-
-static int
-hpp_open(struct device *dev)
-{
- int ioaddr = dev->base_addr - NIC_OFFSET;
- int option_reg;
-
- if (request_irq(dev->irq, &ei_interrupt, 0, "hp-plus")) {
- return -EAGAIN;
- }
-
- /* Reset the 8390 and HP chip. */
- option_reg = inw(ioaddr + HPP_OPTION);
- outw(option_reg & ~(NICReset + ChipReset), ioaddr + HPP_OPTION);
- SLOW_DOWN_IO; SLOW_DOWN_IO;
- /* Unreset the board and enable interrupts. */
- outw(option_reg | (EnableIRQ + NICReset + ChipReset), ioaddr + HPP_OPTION);
-
- /* Set the wrap registers for programmed-I/O operation. */
- outw(HW_Page, ioaddr + HP_PAGING);
- outw((HP_START_PG + TX_2X_PAGES) | ((HP_STOP_PG - 1) << 8), ioaddr + 14);
-
- /* Select the operational page. */
- outw(Perf_Page, ioaddr + HP_PAGING);
-
- ei_open(dev);
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-static int
-hpp_close(struct device *dev)
-{
- int ioaddr = dev->base_addr - NIC_OFFSET;
- int option_reg = inw(ioaddr + HPP_OPTION);
-
- free_irq(dev->irq);
- irq2dev_map[dev->irq] = NULL;
- ei_close(dev);
- outw((option_reg & ~EnableIRQ) | MemDisable | NICReset | ChipReset,
- ioaddr + HPP_OPTION);
-
- MOD_DEC_USE_COUNT;
- return 0;
-}
-
-static void
-hpp_reset_8390(struct device *dev)
-{
- int ioaddr = dev->base_addr - NIC_OFFSET;
- int option_reg = inw(ioaddr + HPP_OPTION);
-
- if (ei_debug > 1) printk("resetting the 8390 time=%ld...", jiffies);
-
- outw(option_reg & ~(NICReset + ChipReset), ioaddr + HPP_OPTION);
- /* Pause a few cycles for the hardware reset to take place. */
- SLOW_DOWN_IO;
- SLOW_DOWN_IO;
- ei_status.txing = 0;
- outw(option_reg | (EnableIRQ + NICReset + ChipReset), ioaddr + HPP_OPTION);
-
- SLOW_DOWN_IO; SLOW_DOWN_IO;
-
-
- if ((inb_p(ioaddr+NIC_OFFSET+EN0_ISR) & ENISR_RESET) == 0)
- printk("%s: hp_reset_8390() did not complete.\n", dev->name);
-
- if (ei_debug > 1) printk("8390 reset done (%ld).", jiffies);
- return;
-}
-
-/* The programmed-I/O version of reading the 4 byte 8390 specific header.
- Note that transfer with the EtherTwist+ must be on word boundaries. */
-
-static void
-hpp_io_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
-{
- int ioaddr = dev->base_addr - NIC_OFFSET;
-
- outw((ring_page<<8), ioaddr + HPP_IN_ADDR);
- insw(ioaddr + HP_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)>>1);
-}
-
-/* Block input and output, similar to the Crynwr packet driver. */
-
-static void
-hpp_io_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset)
-{
- int ioaddr = dev->base_addr - NIC_OFFSET;
- char *buf = skb->data;
-
- outw(ring_offset, ioaddr + HPP_IN_ADDR);
- insw(ioaddr + HP_DATAPORT, buf, count>>1);
- if (count & 0x01)
- buf[count-1] = inw(ioaddr + HP_DATAPORT);
-}
-
-/* The corresponding shared memory versions of the above 2 functions. */
-
-static void
-hpp_mem_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
-{
- int ioaddr = dev->base_addr - NIC_OFFSET;
- int option_reg = inw(ioaddr + HPP_OPTION);
-
- outw((ring_page<<8), ioaddr + HPP_IN_ADDR);
- outw(option_reg & ~(MemDisable + BootROMEnb), ioaddr + HPP_OPTION);
- memcpy_fromio(hdr, dev->mem_start, sizeof(struct e8390_pkt_hdr));
- outw(option_reg, ioaddr + HPP_OPTION);
- hdr->count = (hdr->count + 3) & ~3; /* Round up allocation. */
-}
-
-static void
-hpp_mem_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset)
-{
- int ioaddr = dev->base_addr - NIC_OFFSET;
- int option_reg = inw(ioaddr + HPP_OPTION);
-
- outw(ring_offset, ioaddr + HPP_IN_ADDR);
-
- outw(option_reg & ~(MemDisable + BootROMEnb), ioaddr + HPP_OPTION);
-
- /* Caution: this relies on get_8390_hdr() rounding up count!
- Also note that we *can't* use eth_io_copy_and_sum() because
- it will not always copy "count" bytes (e.g. padded IP). */
-
- memcpy_fromio(skb->data, dev->mem_start, count);
- outw(option_reg, ioaddr + HPP_OPTION);
-}
-
-/* A special note: we *must* always transfer >=16 bit words.
- It's always safe to round up, so we do. */
-static void
-hpp_io_block_output(struct device *dev, int count,
- const unsigned char *buf, const start_page)
-{
- int ioaddr = dev->base_addr - NIC_OFFSET;
- outw(start_page << 8, ioaddr + HPP_OUT_ADDR);
- outsl(ioaddr + HP_DATAPORT, buf, (count+3)>>2);
- return;
-}
-
-static void
-hpp_mem_block_output(struct device *dev, int count,
- const unsigned char *buf, const start_page)
-{
- int ioaddr = dev->base_addr - NIC_OFFSET;
- int option_reg = inw(ioaddr + HPP_OPTION);
-
- outw(start_page << 8, ioaddr + HPP_OUT_ADDR);
- outw(option_reg & ~(MemDisable + BootROMEnb), ioaddr + HPP_OPTION);
- memcpy_toio(dev->mem_start, buf, (count + 3) & ~3);
- outw(option_reg, ioaddr + HPP_OPTION);
-
- return;
-}
-
-
-#ifdef MODULE
-#define MAX_HPP_CARDS 4 /* Max number of HPP cards per module */
-#define NAMELEN 8 /* # of chars for storing dev->name */
-static char namelist[NAMELEN * MAX_HPP_CARDS] = { 0, };
-static struct device dev_hpp[MAX_HPP_CARDS] = {
- {
- NULL, /* assign a chunk of namelist[] below */
- 0, 0, 0, 0,
- 0, 0,
- 0, 0, 0, NULL, NULL
- },
-};
-
-static int io[MAX_HPP_CARDS] = { 0, };
-static int irq[MAX_HPP_CARDS] = { 0, };
-
-/* This is set up so that only a single autoprobe takes place per call.
-ISA device autoprobes on a running machine are not recommended. */
-int
-init_module(void)
-{
- int this_dev, found = 0;
-
- for (this_dev = 0; this_dev < MAX_HPP_CARDS; this_dev++) {
- struct device *dev = &dev_hpp[this_dev];
- dev->name = namelist+(NAMELEN*this_dev);
- dev->irq = irq[this_dev];
- dev->base_addr = io[this_dev];
- dev->init = hp_plus_probe;
- if (io[this_dev] == 0) {
- if (this_dev != 0) break; /* only autoprobe 1st one */
- printk(KERN_NOTICE "hp-plus.c: Presently autoprobing (not recommended) for a single card.\n");
- }
- if (register_netdev(dev) != 0) {
- printk(KERN_WARNING "hp-plus.c: No HP-Plus card found (i/o = 0x%x).\n", io[this_dev]);
- if (found != 0) return 0; /* Got at least one. */
- return -ENXIO;
- }
- found++;
- }
-
- return 0;
-}
-
-void
-cleanup_module(void)
-{
- int this_dev;
-
- for (this_dev = 0; this_dev < MAX_HPP_CARDS; this_dev++) {
- struct device *dev = &dev_hpp[this_dev];
- if (dev->priv != NULL) {
- /* NB: hpp_close() handles free_irq + irq2dev map */
- int ioaddr = dev->base_addr - NIC_OFFSET;
- kfree(dev->priv);
- dev->priv = NULL;
- release_region(ioaddr, HP_IO_EXTENT);
- unregister_netdev(dev);
- }
- }
-}
-#endif /* MODULE */
-
-/*
- * Local variables:
- * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c hp-plus.c"
- * version-control: t
- * kept-new-versions: 5
- * tab-width: 4
- * c-indent-level: 4
- * End:
- */
diff --git a/i386/i386at/gpl/linux/net/hp.c b/i386/i386at/gpl/linux/net/hp.c
deleted file mode 100644
index d0443a7d..00000000
--- a/i386/i386at/gpl/linux/net/hp.c
+++ /dev/null
@@ -1,451 +0,0 @@
-/* hp.c: A HP LAN ethernet driver for linux. */
-/*
- Written 1993-94 by Donald Becker.
-
- Copyright 1993 United States Government as represented by the
- Director, National Security Agency.
-
- This software may be used and distributed according to the terms
- of the GNU Public License, incorporated herein by reference.
-
- The author may be reached as becker@CESDIS.gsfc.nasa.gov, or C/O
- Center of Excellence in Space Data and Information Sciences
- Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
-
- This is a driver for the HP PC-LAN adaptors.
-
- Sources:
- The Crynwr packet driver.
-*/
-
-static const char *version =
- "hp.c:v1.10 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
-
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-
-#include "8390.h"
-
-/* A zero-terminated list of I/O addresses to be probed. */
-static unsigned int hppclan_portlist[] =
-{ 0x300, 0x320, 0x340, 0x280, 0x2C0, 0x200, 0x240, 0};
-
-#define HP_IO_EXTENT 32
-
-#define HP_DATAPORT 0x0c /* "Remote DMA" data port. */
-#define HP_ID 0x07
-#define HP_CONFIGURE 0x08 /* Configuration register. */
-#define HP_RUN 0x01 /* 1 == Run, 0 == reset. */
-#define HP_IRQ 0x0E /* Mask for software-configured IRQ line. */
-#define HP_DATAON 0x10 /* Turn on dataport */
-#define NIC_OFFSET 0x10 /* Offset the 8390 registers. */
-
-#define HP_START_PG 0x00 /* First page of TX buffer */
-#define HP_8BSTOP_PG 0x80 /* Last page +1 of RX ring */
-#define HP_16BSTOP_PG 0xFF /* Same, for 16 bit cards. */
-
-int hp_probe(struct device *dev);
-int hp_probe1(struct device *dev, int ioaddr);
-
-static int hp_open(struct device *dev);
-static int hp_close(struct device *dev);
-static void hp_reset_8390(struct device *dev);
-static void hp_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr,
- int ring_page);
-static void hp_block_input(struct device *dev, int count,
- struct sk_buff *skb , int ring_offset);
-static void hp_block_output(struct device *dev, int count,
- const unsigned char *buf, const start_page);
-
-static void hp_init_card(struct device *dev);
-
-/* The map from IRQ number to HP_CONFIGURE register setting. */
-/* My default is IRQ5 0 1 2 3 4 5 6 7 8 9 10 11 */
-static char irqmap[16] = { 0, 0, 4, 6, 8,10, 0,14, 0, 4, 2,12,0,0,0,0};
-
-
-/* Probe for an HP LAN adaptor.
- Also initialize the card and fill in STATION_ADDR with the station
- address. */
-#ifdef HAVE_DEVLIST
-struct netdev_entry netcard_drv =
-{"hp", hp_probe1, HP_IO_EXTENT, hppclan_portlist};
-#else
-
-int hp_probe(struct device *dev)
-{
- int i;
- int base_addr = dev ? dev->base_addr : 0;
-
- if (base_addr > 0x1ff) /* Check a single specified location. */
- return hp_probe1(dev, base_addr);
- else if (base_addr != 0) /* Don't probe at all. */
- return ENXIO;
-
- for (i = 0; hppclan_portlist[i]; i++) {
- int ioaddr = hppclan_portlist[i];
- if (check_region(ioaddr, HP_IO_EXTENT))
- continue;
- if (hp_probe1(dev, ioaddr) == 0)
- return 0;
- }
-
- return ENODEV;
-}
-#endif
-
-int hp_probe1(struct device *dev, int ioaddr)
-{
- int i, board_id, wordmode;
- const char *name;
- static unsigned version_printed = 0;
-
- /* Check for the HP physical address, 08 00 09 xx xx xx. */
- /* This really isn't good enough: we may pick up HP LANCE boards
- also! Avoid the lance 0x5757 signature. */
- if (inb(ioaddr) != 0x08
- || inb(ioaddr+1) != 0x00
- || inb(ioaddr+2) != 0x09
- || inb(ioaddr+14) == 0x57)
- return ENODEV;
-
- /* Set up the parameters based on the board ID.
- If you have additional mappings, please mail them to me -djb. */
- if ((board_id = inb(ioaddr + HP_ID)) & 0x80) {
- name = "HP27247";
- wordmode = 1;
- } else {
- name = "HP27250";
- wordmode = 0;
- }
-
- /* We should have a "dev" from Space.c or the static module table. */
- if (dev == NULL) {
- printk("hp.c: Passed a NULL device.\n");
- dev = init_etherdev(0, 0);
- }
-
- if (ei_debug && version_printed++ == 0)
- printk(version);
-
- printk("%s: %s (ID %02x) at %#3x,", dev->name, name, board_id, ioaddr);
-
- for(i = 0; i < ETHER_ADDR_LEN; i++)
- printk(" %2.2x", dev->dev_addr[i] = inb(ioaddr + i));
-
- /* Snarf the interrupt now. Someday this could be moved to open(). */
- if (dev->irq < 2) {
- int irq_16list[] = { 11, 10, 5, 3, 4, 7, 9, 0};
- int irq_8list[] = { 7, 5, 3, 4, 9, 0};
- int *irqp = wordmode ? irq_16list : irq_8list;
- do {
- int irq = *irqp;
- if (request_irq (irq, NULL, 0, "bogus") != -EBUSY) {
- autoirq_setup(0);
- /* Twinkle the interrupt, and check if it's seen. */
- outb_p(irqmap[irq] | HP_RUN, ioaddr + HP_CONFIGURE);
- outb_p( 0x00 | HP_RUN, ioaddr + HP_CONFIGURE);
- if (irq == autoirq_report(0) /* It's a good IRQ line! */
- && request_irq (irq, &ei_interrupt, 0, "hp") == 0) {
- printk(" selecting IRQ %d.\n", irq);
- dev->irq = *irqp;
- break;
- }
- }
- } while (*++irqp);
- if (*irqp == 0) {
- printk(" no free IRQ lines.\n");
- return EBUSY;
- }
- } else {
- if (dev->irq == 2)
- dev->irq = 9;
- if (request_irq(dev->irq, ei_interrupt, 0, "hp")) {
- printk (" unable to get IRQ %d.\n", dev->irq);
- return EBUSY;
- }
- }
-
- /* Allocate dev->priv and fill in 8390 specific dev fields. */
- if (ethdev_init(dev)) {
- printk (" unable to get memory for dev->priv.\n");
- free_irq(dev->irq);
- return -ENOMEM;
- }
-
- /* Grab the region so we can find another board if something fails. */
- request_region(ioaddr, HP_IO_EXTENT,"hp");
-
- /* Set the base address to point to the NIC, not the "real" base! */
- dev->base_addr = ioaddr + NIC_OFFSET;
- dev->open = &hp_open;
- dev->stop = &hp_close;
-
- ei_status.name = name;
- ei_status.word16 = wordmode;
- ei_status.tx_start_page = HP_START_PG;
- ei_status.rx_start_page = HP_START_PG + TX_PAGES;
- ei_status.stop_page = wordmode ? HP_16BSTOP_PG : HP_8BSTOP_PG;
-
- ei_status.reset_8390 = &hp_reset_8390;
- ei_status.get_8390_hdr = &hp_get_8390_hdr;
- ei_status.block_input = &hp_block_input;
- ei_status.block_output = &hp_block_output;
- hp_init_card(dev);
-
- return 0;
-}
-
-static int
-hp_open(struct device *dev)
-{
- ei_open(dev);
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-static int
-hp_close(struct device *dev)
-{
- ei_close(dev);
- MOD_DEC_USE_COUNT;
- return 0;
-}
-
-static void
-hp_reset_8390(struct device *dev)
-{
- int hp_base = dev->base_addr - NIC_OFFSET;
- int saved_config = inb_p(hp_base + HP_CONFIGURE);
-
- if (ei_debug > 1) printk("resetting the 8390 time=%ld...", jiffies);
- outb_p(0x00, hp_base + HP_CONFIGURE);
- ei_status.txing = 0;
- /* Pause just a few cycles for the hardware reset to take place. */
- SLOW_DOWN_IO;
- SLOW_DOWN_IO;
-
- outb_p(saved_config, hp_base + HP_CONFIGURE);
- SLOW_DOWN_IO; SLOW_DOWN_IO;
-
- if ((inb_p(hp_base+NIC_OFFSET+EN0_ISR) & ENISR_RESET) == 0)
- printk("%s: hp_reset_8390() did not complete.\n", dev->name);
-
- if (ei_debug > 1) printk("8390 reset done (%ld).", jiffies);
- return;
-}
-
-static void
-hp_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
-{
- int nic_base = dev->base_addr;
- int saved_config = inb_p(nic_base - NIC_OFFSET + HP_CONFIGURE);
-
- outb_p(saved_config | HP_DATAON, nic_base - NIC_OFFSET + HP_CONFIGURE);
- outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base);
- outb_p(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO);
- outb_p(0, nic_base + EN0_RCNTHI);
- outb_p(0, nic_base + EN0_RSARLO); /* On page boundary */
- outb_p(ring_page, nic_base + EN0_RSARHI);
- outb_p(E8390_RREAD+E8390_START, nic_base);
-
- if (ei_status.word16)
- insw(nic_base - NIC_OFFSET + HP_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)>>1);
- else
- insb(nic_base - NIC_OFFSET + HP_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr));
-
- outb_p(saved_config & (~HP_DATAON), nic_base - NIC_OFFSET + HP_CONFIGURE);
-}
-
-/* Block input and output, similar to the Crynwr packet driver. If you are
- porting to a new ethercard look at the packet driver source for hints.
- The HP LAN doesn't use shared memory -- we put the packet
- out through the "remote DMA" dataport. */
-
-static void
-hp_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset)
-{
- int nic_base = dev->base_addr;
- int saved_config = inb_p(nic_base - NIC_OFFSET + HP_CONFIGURE);
- int xfer_count = count;
- char *buf = skb->data;
-
- outb_p(saved_config | HP_DATAON, nic_base - NIC_OFFSET + HP_CONFIGURE);
- outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base);
- outb_p(count & 0xff, nic_base + EN0_RCNTLO);
- outb_p(count >> 8, nic_base + EN0_RCNTHI);
- outb_p(ring_offset & 0xff, nic_base + EN0_RSARLO);
- outb_p(ring_offset >> 8, nic_base + EN0_RSARHI);
- outb_p(E8390_RREAD+E8390_START, nic_base);
- if (ei_status.word16) {
- insw(nic_base - NIC_OFFSET + HP_DATAPORT,buf,count>>1);
- if (count & 0x01)
- buf[count-1] = inb(nic_base - NIC_OFFSET + HP_DATAPORT), xfer_count++;
- } else {
- insb(nic_base - NIC_OFFSET + HP_DATAPORT, buf, count);
- }
- /* This is for the ALPHA version only, remove for later releases. */
- if (ei_debug > 0) { /* DMA termination address check... */
- int high = inb_p(nic_base + EN0_RSARHI);
- int low = inb_p(nic_base + EN0_RSARLO);
- int addr = (high << 8) + low;
- /* Check only the lower 8 bits so we can ignore ring wrap. */
- if (((ring_offset + xfer_count) & 0xff) != (addr & 0xff))
- printk("%s: RX transfer address mismatch, %#4.4x vs. %#4.4x (actual).\n",
- dev->name, ring_offset + xfer_count, addr);
- }
- outb_p(saved_config & (~HP_DATAON), nic_base - NIC_OFFSET + HP_CONFIGURE);
-}
-
-static void
-hp_block_output(struct device *dev, int count,
- const unsigned char *buf, const start_page)
-{
- int nic_base = dev->base_addr;
- int saved_config = inb_p(nic_base - NIC_OFFSET + HP_CONFIGURE);
-
- outb_p(saved_config | HP_DATAON, nic_base - NIC_OFFSET + HP_CONFIGURE);
- /* Round the count up for word writes. Do we need to do this?
- What effect will an odd byte count have on the 8390?
- I should check someday. */
- if (ei_status.word16 && (count & 0x01))
- count++;
- /* We should already be in page 0, but to be safe... */
- outb_p(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base);
-
-#ifdef NE8390_RW_BUGFIX
- /* Handle the read-before-write bug the same way as the
- Crynwr packet driver -- the NatSemi method doesn't work. */
- outb_p(0x42, nic_base + EN0_RCNTLO);
- outb_p(0, nic_base + EN0_RCNTHI);
- outb_p(0xff, nic_base + EN0_RSARLO);
- outb_p(0x00, nic_base + EN0_RSARHI);
-#define NE_CMD 0x00
- outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD);
- /* Make certain that the dummy read has occurred. */
- inb_p(0x61);
- inb_p(0x61);
-#endif
-
- outb_p(count & 0xff, nic_base + EN0_RCNTLO);
- outb_p(count >> 8, nic_base + EN0_RCNTHI);
- outb_p(0x00, nic_base + EN0_RSARLO);
- outb_p(start_page, nic_base + EN0_RSARHI);
-
- outb_p(E8390_RWRITE+E8390_START, nic_base);
- if (ei_status.word16) {
- /* Use the 'rep' sequence for 16 bit boards. */
- outsw(nic_base - NIC_OFFSET + HP_DATAPORT, buf, count>>1);
- } else {
- outsb(nic_base - NIC_OFFSET + HP_DATAPORT, buf, count);
- }
-
- /* DON'T check for 'inb_p(EN0_ISR) & ENISR_RDC' here -- it's broken! */
-
- /* This is for the ALPHA version only, remove for later releases. */
- if (ei_debug > 0) { /* DMA termination address check... */
- int high = inb_p(nic_base + EN0_RSARHI);
- int low = inb_p(nic_base + EN0_RSARLO);
- int addr = (high << 8) + low;
- if ((start_page << 8) + count != addr)
- printk("%s: TX Transfer address mismatch, %#4.4x vs. %#4.4x.\n",
- dev->name, (start_page << 8) + count, addr);
- }
- outb_p(saved_config & (~HP_DATAON), nic_base - NIC_OFFSET + HP_CONFIGURE);
- return;
-}
-
-/* This function resets the ethercard if something screws up. */
-static void
-hp_init_card(struct device *dev)
-{
- int irq = dev->irq;
- NS8390_init(dev, 0);
- outb_p(irqmap[irq&0x0f] | HP_RUN,
- dev->base_addr - NIC_OFFSET + HP_CONFIGURE);
- return;
-}
-
-#ifdef MODULE
-#define MAX_HP_CARDS 4 /* Max number of HP cards per module */
-#define NAMELEN 8 /* # of chars for storing dev->name */
-static char namelist[NAMELEN * MAX_HP_CARDS] = { 0, };
-static struct device dev_hp[MAX_HP_CARDS] = {
- {
- NULL, /* assign a chunk of namelist[] below */
- 0, 0, 0, 0,
- 0, 0,
- 0, 0, 0, NULL, NULL
- },
-};
-
-static int io[MAX_HP_CARDS] = { 0, };
-static int irq[MAX_HP_CARDS] = { 0, };
-
-/* This is set up so that only a single autoprobe takes place per call.
-ISA device autoprobes on a running machine are not recommended. */
-int
-init_module(void)
-{
- int this_dev, found = 0;
-
- for (this_dev = 0; this_dev < MAX_HP_CARDS; this_dev++) {
- struct device *dev = &dev_hp[this_dev];
- dev->name = namelist+(NAMELEN*this_dev);
- dev->irq = irq[this_dev];
- dev->base_addr = io[this_dev];
- dev->init = hp_probe;
- if (io[this_dev] == 0) {
- if (this_dev != 0) break; /* only autoprobe 1st one */
- printk(KERN_NOTICE "hp.c: Presently autoprobing (not recommended) for a single card.\n");
- }
- if (register_netdev(dev) != 0) {
- printk(KERN_WARNING "hp.c: No HP card found (i/o = 0x%x).\n", io[this_dev]);
- if (found != 0) return 0; /* Got at least one. */
- return -ENXIO;
- }
- found++;
- }
-
- return 0;
-}
-
-void
-cleanup_module(void)
-{
- int this_dev;
-
- for (this_dev = 0; this_dev < MAX_HP_CARDS; this_dev++) {
- struct device *dev = &dev_hp[this_dev];
- if (dev->priv != NULL) {
- int ioaddr = dev->base_addr - NIC_OFFSET;
- kfree(dev->priv);
- dev->priv = NULL;
- free_irq(dev->irq);
- irq2dev_map[dev->irq] = NULL;
- release_region(ioaddr, HP_IO_EXTENT);
- unregister_netdev(dev);
- }
- }
-}
-#endif /* MODULE */
-
-/*
- * Local variables:
- * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c hp.c"
- * version-control: t
- * kept-new-versions: 5
- * tab-width: 4
- * c-indent-level: 4
- * End:
- */
diff --git a/i386/i386at/gpl/linux/net/hp100.c b/i386/i386at/gpl/linux/net/hp100.c
deleted file mode 100644
index d8186bf1..00000000
--- a/i386/i386at/gpl/linux/net/hp100.c
+++ /dev/null
@@ -1,1144 +0,0 @@
-/*
- * hp100.c: Hewlett Packard HP10/100VG ANY LAN ethernet driver for Linux.
- *
- * Author: Jaroslav Kysela, <perex@pf.jcu.cz>
- *
- * Supports only the following Hewlett Packard cards:
- *
- * HP J2577 10/100 EISA card with REVA Cascade chip
- * HP J2573 10/100 ISA card with REVA Cascade chip
- * HP 27248B 10 only EISA card with Cascade chip
- * HP J2577 10/100 EISA card with Cascade chip
- * HP J2573 10/100 ISA card with Cascade chip
- * HP J2585 10/100 PCI card
- *
- * Other ATT2MD01 Chip based boards might be supported in the future
- * (there are some minor changes needed).
- *
- * This driver is based on the 'hpfepkt' crynwr packet driver.
- *
- * This source/code is public free; you can distribute it and/or modify
- * it under terms of the GNU General Public License (published by the
- * Free Software Foundation) either version two of this License, or any
- * later version.
- * ----------------------------------------------------------------------------
- *
- * Note: Some routines (interrupt handling, transmit) assumes that
- * there is the PERFORMANCE page selected...
- *
- * ----------------------------------------------------------------------------
- *
- * If you are going to use the module version of this driver, you may
- * change this values at the "insert time" :
- *
- * Variable Description
- *
- * hp100_rx_ratio Range 1-99 - onboard memory used for RX
- * packets in %.
- * hp100_priority_tx If this variable is nonzero - all outgoing
- * packets will be transmitted as priority.
- * hp100_port Adapter port (for example 0x380).
- *
- * ----------------------------------------------------------------------------
- * MY BEST REGARDS GOING TO:
- *
- * IPEX s.r.o which lend me two HP J2573 cards and
- * the HP AdvanceStack 100VG Hub-15 for debugging.
- *
- * Russel Nellson <nelson@crynwr.com> for help with obtaining sources
- * of the 'hpfepkt' packet driver.
- *
- * Also thanks to Abacus Electric s.r.o which let me to use their
- * motherboard for my second computer.
- *
- * ----------------------------------------------------------------------------
- *
- * TO DO:
- * ======
- * - ioctl handling - some runtime setup things
- * - 100Mb/s Voice Grade AnyLAN network adapter/hub services support
- * - 802.5 frames
- * - promiscuous mode
- * - bridge mode
- * - cascaded repeater mode
- * - 100Mbit MAC
- *
- * Revision history:
- * =================
- *
- * Version Date Description
- *
- * 0.1 14-May-95 Initial writing. ALPHA code was released.
- * Only HP J2573 on 10Mb/s (two machines) tested.
- * 0.11 14-Jun-95 Reset interface bug fixed?
- * Little bug in hp100_close function fixed.
- * 100Mb/s connection debugged.
- * 0.12 14-Jul-95 Link down is now handled better.
- * 0.20 01-Aug-95 Added PCI support for HP J2585A card.
- * Statistics bug fixed.
- * 0.21 04-Aug-95 Memory mapped access support for PCI card.
- * Added priority transmit support for 100Mb/s
- * Voice Grade AnyLAN network.
- *
- */
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/malloc.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/bios32.h>
-#include <asm/bitops.h>
-#include <asm/io.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-
-#include <linux/types.h>
-#include <linux/config.h> /* for CONFIG_PCI */
-
-#include "hp100.h"
-
-/*
- * defines
- */
-
-#define HP100_BUS_ISA 0
-#define HP100_BUS_EISA 1
-#define HP100_BUS_PCI 2
-
-#define HP100_REGION_SIZE 0x20
-
-#define HP100_MAX_PACKET_SIZE (1536+4)
-#define HP100_MIN_PACKET_SIZE 60
-
-#ifndef HP100_DEFAULT_RX_RATIO
-/* default - 65% onboard memory on the card are used for RX packets */
-#define HP100_DEFAULT_RX_RATIO 65
-#endif
-
-#ifndef HP100_DEFAULT_PRIORITY_TX
-/* default - don't enable transmit outgoing packets as priority */
-#define HP100_DEFAULT_PRIORITY_TX 0
-#endif
-
-#ifdef MACH
-#define HP100_IO_MAPPED
-#endif
-
-/*
- * structures
- */
-
-struct hp100_eisa_id {
- u_int id;
- const char *name;
- u_char bus;
-};
-
-struct hp100_private {
- struct hp100_eisa_id *id;
- u_short soft_model;
- u_int memory_size;
- u_short rx_ratio; /* 1 - 99 */
- u_short priority_tx; /* != 0 - priority tx */
- short mem_mapped; /* memory mapped access */
- u_char *mem_ptr_virt; /* virtual memory mapped area, maybe NULL */
- u_char *mem_ptr_phys; /* physical memory mapped area */
- short lan_type; /* 10Mb/s, 100Mb/s or -1 (error) */
- int hub_status; /* login to hub was successfull? */
- u_char mac1_mode;
- u_char mac2_mode;
- struct enet_statistics stats;
-};
-
-/*
- * variables
- */
-
-static struct hp100_eisa_id hp100_eisa_ids[] = {
-
- /* 10/100 EISA card with REVA Cascade chip */
- { 0x080F1F022, "HP J2577 rev A", HP100_BUS_EISA },
-
- /* 10/100 ISA card with REVA Cascade chip */
- { 0x050F1F022, "HP J2573 rev A", HP100_BUS_ISA },
-
- /* 10 only EISA card with Cascade chip */
- { 0x02019F022, "HP 27248B", HP100_BUS_EISA },
-
- /* 10/100 EISA card with Cascade chip */
- { 0x04019F022, "HP J2577", HP100_BUS_EISA },
-
- /* 10/100 ISA card with Cascade chip */
- { 0x05019F022, "HP J2573", HP100_BUS_ISA },
-
- /* 10/100 PCI card */
- /* Note: ID for this card is same as PCI vendor/device numbers. */
- { 0x01030103c, "HP J2585", HP100_BUS_PCI },
-};
-
-int hp100_rx_ratio = HP100_DEFAULT_RX_RATIO;
-int hp100_priority_tx = HP100_DEFAULT_PRIORITY_TX;
-
-/*
- * prototypes
- */
-
-static int hp100_probe1( struct device *dev, int ioaddr, int bus );
-static int hp100_open( struct device *dev );
-static int hp100_close( struct device *dev );
-static int hp100_start_xmit( struct sk_buff *skb, struct device *dev );
-static void hp100_rx( struct device *dev );
-static struct enet_statistics *hp100_get_stats( struct device *dev );
-static void hp100_update_stats( struct device *dev );
-static void hp100_clear_stats( int ioaddr );
-static void hp100_set_multicast_list( struct device *dev);
-static void hp100_interrupt( int irq, struct pt_regs *regs );
-
-static void hp100_start_interface( struct device *dev );
-static void hp100_stop_interface( struct device *dev );
-static void hp100_load_eeprom( struct device *dev );
-static int hp100_sense_lan( struct device *dev );
-static int hp100_login_to_vg_hub( struct device *dev );
-static int hp100_down_vg_link( struct device *dev );
-
-/*
- * probe functions
- */
-
-int hp100_probe( struct device *dev )
-{
- int base_addr = dev ? dev -> base_addr : 0;
- int ioaddr;
-#ifdef CONFIG_PCI
- int pci_start_index = 0;
-#endif
-
- if ( base_addr > 0xff ) /* Check a single specified location. */
- {
- if ( check_region( base_addr, HP100_REGION_SIZE ) ) return -EINVAL;
- if ( base_addr < 0x400 )
- return hp100_probe1( dev, base_addr, HP100_BUS_ISA );
- else
- return hp100_probe1( dev, base_addr, HP100_BUS_EISA );
- }
- else
-#ifdef CONFIG_PCI
- if ( base_addr > 0 && base_addr < 8 + 1 )
- pci_start_index = 0x100 | ( base_addr - 1 );
- else
-#endif
- if ( base_addr != 0 ) return -ENXIO;
-
- /* at first - scan PCI bus(es) */
-
-#ifdef CONFIG_PCI
- if ( pcibios_present() )
- {
- int pci_index;
-
-#ifdef HP100_DEBUG_PCI
- printk( "hp100: PCI BIOS is present, checking for devices..\n" );
-#endif
- for ( pci_index = pci_start_index & 7; pci_index < 8; pci_index++ )
- {
- u_char pci_bus, pci_device_fn;
- u_short pci_command;
-
- if ( pcibios_find_device( PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2585A,
- pci_index, &pci_bus,
- &pci_device_fn ) != 0 ) break;
- pcibios_read_config_dword( pci_bus, pci_device_fn,
- PCI_BASE_ADDRESS_0, &ioaddr );
-
- ioaddr &= ~3; /* remove I/O space marker in bit 0. */
-
- if ( check_region( ioaddr, HP100_REGION_SIZE ) ) continue;
-
- pcibios_read_config_word( pci_bus, pci_device_fn,
- PCI_COMMAND, &pci_command );
- if ( !( pci_command & PCI_COMMAND_MASTER ) )
- {
-#ifdef HP100_DEBUG_PCI
- printk( "hp100: PCI Master Bit has not been set. Setting...\n" );
-#endif
- pci_command |= PCI_COMMAND_MASTER;
- pcibios_write_config_word( pci_bus, pci_device_fn,
- PCI_COMMAND, pci_command );
- }
-#ifdef HP100_DEBUG_PCI
- printk( "hp100: PCI adapter found at 0x%x\n", ioaddr );
-#endif
- if ( hp100_probe1( dev, ioaddr, HP100_BUS_PCI ) == 0 ) return 0;
- }
- }
- if ( pci_start_index > 0 ) return -ENODEV;
-#endif /* CONFIG_PCI */
-
- /* at second - probe all EISA possible port regions (if EISA bus present) */
-
- for ( ioaddr = 0x1c38; EISA_bus && ioaddr < 0x10000; ioaddr += 0x400 )
- {
- if ( check_region( ioaddr, HP100_REGION_SIZE ) ) continue;
- if ( hp100_probe1( dev, ioaddr, HP100_BUS_EISA ) == 0 ) return 0;
- }
-
- /* at third - probe all ISA possible port regions */
-
- for ( ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x20 )
- {
- if ( check_region( ioaddr, HP100_REGION_SIZE ) ) continue;
- if ( hp100_probe1( dev, ioaddr, HP100_BUS_ISA ) == 0 ) return 0;
- }
-
- return -ENODEV;
-}
-
-static int hp100_probe1( struct device *dev, int ioaddr, int bus )
-{
- int i;
- u_char uc, uc_1;
- u_int eisa_id;
- short mem_mapped;
- u_char *mem_ptr_phys, *mem_ptr_virt;
- struct hp100_private *lp;
- struct hp100_eisa_id *eid;
-
- if ( dev == NULL )
- {
-#ifdef HP100_DEBUG
- printk( "hp100_probe1: dev == NULL ?\n" );
-#endif
- return EIO;
- }
-
- if ( bus != HP100_BUS_PCI ) /* don't check PCI cards again */
- if ( inb( ioaddr + 0 ) != HP100_HW_ID_0 ||
- inb( ioaddr + 1 ) != HP100_HW_ID_1 ||
- ( inb( ioaddr + 2 ) & 0xf0 ) != HP100_HW_ID_2_REVA ||
- inb( ioaddr + 3 ) != HP100_HW_ID_3 )
- return -ENODEV;
-
- dev -> base_addr = ioaddr;
-
-#ifdef HP100_DEBUG_PROBE1
- printk( "hp100_probe1: card found at port 0x%x\n", ioaddr );
-#endif
-
- hp100_page( ID_MAC_ADDR );
- for ( i = uc = eisa_id = 0; i < 4; i++ )
- {
- eisa_id >>= 8;
- uc_1 = hp100_inb( BOARD_ID + i );
- eisa_id |= uc_1 << 24;
- uc += uc_1;
- }
- uc += hp100_inb( BOARD_ID + 4 );
-
-#ifdef HP100_DEBUG_PROBE1
- printk( "hp100_probe1: EISA ID = 0x%08x checksum = 0x%02x\n", eisa_id, uc );
-#endif
-
- if ( uc != 0xff ) /* bad checksum? */
- {
- printk( "hp100_probe: bad EISA ID checksum at base port 0x%x\n", ioaddr );
- return -ENODEV;
- }
-
- for ( i = 0; i < sizeof( hp100_eisa_ids ) / sizeof( struct hp100_eisa_id ); i++ )
- if ( ( hp100_eisa_ids[ i ].id & 0xf0ffffff ) == ( eisa_id & 0xf0ffffff ) )
- break;
- if ( i >= sizeof( hp100_eisa_ids ) / sizeof( struct hp100_eisa_id ) )
- {
- printk( "hp100_probe1: card at port 0x%x isn't known (id = 0x%x)\n", ioaddr, eisa_id );
- return -ENODEV;
- }
- eid = &hp100_eisa_ids[ i ];
- if ( ( eid -> id & 0x0f000000 ) < ( eisa_id & 0x0f000000 ) )
- {
- printk( "hp100_probe1: newer version of card %s at port 0x%x - unsupported\n",
- eid -> name, ioaddr );
- return -ENODEV;
- }
-
- for ( i = uc = 0; i < 7; i++ )
- uc += hp100_inb( LAN_ADDR + i );
- if ( uc != 0xff )
- {
- printk( "hp100_probe1: bad lan address checksum (card %s at port 0x%x)\n",
- eid -> name, ioaddr );
- return -EIO;
- }
-
-#ifndef HP100_IO_MAPPED
- hp100_page( HW_MAP );
- mem_mapped = ( hp100_inw( OPTION_LSW ) &
- ( HP100_MEM_EN | HP100_BM_WRITE | HP100_BM_READ ) ) != 0;
- mem_ptr_phys = mem_ptr_virt = NULL;
- if ( mem_mapped )
- {
- mem_ptr_phys = (u_char *)( hp100_inw( MEM_MAP_LSW ) |
- ( hp100_inw( MEM_MAP_MSW ) << 16 ) );
- (u_int)mem_ptr_phys &= ~0x1fff; /* 8k aligment */
- if ( bus == HP100_BUS_ISA && ( (u_long)mem_ptr_phys & ~0xfffff ) != 0 )
- {
- mem_ptr_phys = NULL;
- mem_mapped = 0;
- }
- if ( mem_mapped && bus == HP100_BUS_PCI )
- {
- if ( ( mem_ptr_virt = vremap( (u_long)mem_ptr_phys, 0x2000 ) ) == NULL )
- {
- printk( "hp100: vremap for high PCI memory at 0x%lx failed\n", (u_long)mem_ptr_phys );
- mem_ptr_phys = NULL;
- mem_mapped = 0;
- }
- }
- }
-#else
- mem_mapped = 0;
- mem_ptr_phys = mem_ptr_virt = NULL;
-#endif
-
- if ( ( dev -> priv = kmalloc( sizeof( struct hp100_private ), GFP_KERNEL ) ) == NULL )
- return -ENOMEM;
- memset( dev -> priv, 0, sizeof( struct hp100_private ) );
-
- lp = (struct hp100_private *)dev -> priv;
- lp -> id = eid;
- lp -> mem_mapped = mem_mapped;
- lp -> mem_ptr_phys = mem_ptr_phys;
- lp -> mem_ptr_virt = mem_ptr_virt;
- hp100_page( ID_MAC_ADDR );
- lp -> soft_model = hp100_inb( SOFT_MODEL );
- lp -> mac1_mode = HP100_MAC1MODE3;
- lp -> mac2_mode = HP100_MAC2MODE3;
-
- dev -> base_addr = ioaddr;
- hp100_page( HW_MAP );
- dev -> irq = hp100_inb( IRQ_CHANNEL ) & HP100_IRQ_MASK;
- if ( dev -> irq == 2 ) dev -> irq = 9;
- lp -> memory_size = 0x200 << ( ( hp100_inb( SRAM ) & 0xe0 ) >> 5 );
- lp -> rx_ratio = hp100_rx_ratio;
-
- dev -> open = hp100_open;
- dev -> stop = hp100_close;
- dev -> hard_start_xmit = hp100_start_xmit;
- dev -> get_stats = hp100_get_stats;
- dev -> set_multicast_list = &hp100_set_multicast_list;
-
- request_region( dev -> base_addr, HP100_REGION_SIZE, eid -> name );
-
- hp100_page( ID_MAC_ADDR );
- for ( i = uc = 0; i < 6; i++ )
- dev -> dev_addr[ i ] = hp100_inb( LAN_ADDR + i );
-
- hp100_clear_stats( ioaddr );
-
- ether_setup( dev );
-
- lp -> lan_type = hp100_sense_lan( dev );
-
- printk( "%s: %s at 0x%x, IRQ %d, ",
- dev -> name, lp -> id -> name, ioaddr, dev -> irq );
- switch ( bus ) {
- case HP100_BUS_EISA: printk( "EISA" ); break;
- case HP100_BUS_PCI: printk( "PCI" ); break;
- default: printk( "ISA" ); break;
- }
- printk( " bus, %dk SRAM (rx/tx %d%%).\n",
- lp -> memory_size >> ( 10 - 4 ), lp -> rx_ratio );
- if ( mem_mapped )
- {
- printk( "%s: Memory area at 0x%lx-0x%lx",
- dev -> name, (u_long)mem_ptr_phys, (u_long)mem_ptr_phys + 0x1fff );
- if ( mem_ptr_virt )
- printk( " (virtual base 0x%lx)", (u_long)mem_ptr_virt );
- printk( ".\n" );
- }
- printk( "%s: ", dev -> name );
- if ( lp -> lan_type != HP100_LAN_ERR )
- printk( "Adapter is attached to " );
- switch ( lp -> lan_type ) {
- case HP100_LAN_100:
- printk( "100Mb/s Voice Grade AnyLAN network.\n" );
- break;
- case HP100_LAN_10:
- printk( "10Mb/s network.\n" );
- break;
- default:
- printk( "Warning! Link down.\n" );
- }
-
- hp100_stop_interface( dev );
-
- return 0;
-}
-
-/*
- * open/close functions
- */
-
-static int hp100_open( struct device *dev )
-{
- int i;
- int ioaddr = dev -> base_addr;
- struct hp100_private *lp = (struct hp100_private *)dev -> priv;
-
- if ( request_irq( dev -> irq, hp100_interrupt, SA_INTERRUPT, lp -> id -> name ) )
- {
- printk( "%s: unable to get IRQ %d\n", dev -> name, dev -> irq );
- return -EAGAIN;
- }
- irq2dev_map[ dev -> irq ] = dev;
-
- MOD_INC_USE_COUNT;
-
- dev -> tbusy = 0;
- dev -> trans_start = jiffies;
- dev -> interrupt = 0;
- dev -> start = 1;
-
- lp -> lan_type = hp100_sense_lan( dev );
- lp -> mac1_mode = HP100_MAC1MODE3;
- lp -> mac2_mode = HP100_MAC2MODE3;
-
- hp100_page( MAC_CTRL );
- hp100_orw( HP100_LINK_BEAT_DIS | HP100_RESET_LB, LAN_CFG_10 );
-
- hp100_stop_interface( dev );
- hp100_load_eeprom( dev );
-
- hp100_outw( HP100_MMAP_DIS | HP100_SET_HB |
- HP100_IO_EN | HP100_SET_LB, OPTION_LSW );
- hp100_outw( HP100_DEBUG_EN | HP100_RX_HDR | HP100_EE_EN | HP100_RESET_HB |
- HP100_FAKE_INT | HP100_RESET_LB, OPTION_LSW );
- hp100_outw( HP100_ADV_NXT_PKT | HP100_TX_CMD | HP100_RESET_LB |
- HP100_PRIORITY_TX | ( hp100_priority_tx ? HP100_SET_HB : HP100_RESET_HB ),
- OPTION_MSW );
-
- hp100_page( MAC_ADDRESS );
- for ( i = 0; i < 6; i++ )
- hp100_outb( dev -> dev_addr[ i ], MAC_ADDR + i );
- for ( i = 0; i < 8; i++ ) /* setup multicast filter to receive all */
- hp100_outb( 0xff, HASH_BYTE0 + i );
- hp100_page( PERFORMANCE );
- hp100_outw( 0xfefe, IRQ_MASK ); /* mask off all ints */
- hp100_outw( 0xffff, IRQ_STATUS ); /* ack IRQ */
- hp100_outw( (HP100_RX_PACKET | HP100_RX_ERROR | HP100_SET_HB) |
- (HP100_TX_ERROR | HP100_SET_LB ), IRQ_MASK );
- /* and enable few */
- hp100_reset_card();
- hp100_page( MMU_CFG );
- hp100_outw( ( lp -> memory_size * lp -> rx_ratio ) / 100, RX_MEM_STOP );
- hp100_outw( lp -> memory_size - 1, TX_MEM_STOP );
- hp100_unreset_card();
-
- if ( lp -> lan_type == HP100_LAN_100 )
- lp -> hub_status = hp100_login_to_vg_hub( dev );
-
- hp100_start_interface( dev );
-
- return 0;
-}
-
-static int hp100_close( struct device *dev )
-{
- int ioaddr = dev -> base_addr;
- struct hp100_private *lp = (struct hp100_private *)dev -> priv;
-
- hp100_page( PERFORMANCE );
- hp100_outw( 0xfefe, IRQ_MASK ); /* mask off all IRQs */
-
- hp100_stop_interface( dev );
-
- if ( lp -> lan_type == HP100_LAN_100 ) /* relogin */
- hp100_login_to_vg_hub( dev );
-
- dev -> tbusy = 1;
- dev -> start = 0;
-
- free_irq( dev -> irq );
- irq2dev_map[ dev -> irq ] = NULL;
- MOD_DEC_USE_COUNT;
- return 0;
-}
-
-/*
- * transmit
- */
-
-static int hp100_start_xmit( struct sk_buff *skb, struct device *dev )
-{
- int i, ok_flag;
- int ioaddr = dev -> base_addr;
- u_short val;
- struct hp100_private *lp = (struct hp100_private *)dev -> priv;
-
- if ( lp -> lan_type < 0 )
- {
- hp100_stop_interface( dev );
- if ( ( lp -> lan_type = hp100_sense_lan( dev ) ) < 0 )
- {
- printk( "%s: no connection found - check wire\n", dev -> name );
- hp100_start_interface( dev ); /* 10Mb/s RX packets maybe handled */
- return -EIO;
- }
- if ( lp -> lan_type == HP100_LAN_100 )
- lp -> hub_status = hp100_login_to_vg_hub( dev );
- hp100_start_interface( dev );
- }
-
- if ( ( i = ( hp100_inl( TX_MEM_FREE ) & ~0x7fffffff ) ) < skb -> len + 16 )
- {
-#ifdef HP100_DEBUG
- printk( "hp100_start_xmit: rx free mem = 0x%x\n", i );
-#endif
- if ( jiffies - dev -> trans_start < 2 * HZ ) return -EAGAIN;
- if ( lp -> lan_type == HP100_LAN_100 && lp -> hub_status < 0 )
- /* 100Mb/s adapter isn't connected to hub */
- {
- printk( "%s: login to 100Mb/s hub retry\n", dev -> name );
- hp100_stop_interface( dev );
- lp -> hub_status = hp100_login_to_vg_hub( dev );
- hp100_start_interface( dev );
- }
- else
- {
- hp100_ints_off();
- i = hp100_sense_lan( dev );
- hp100_page( PERFORMANCE );
- hp100_ints_on();
- if ( i == HP100_LAN_ERR )
- printk( "%s: link down detected\n", dev -> name );
- else
- if ( lp -> lan_type != i )
- {
- /* it's very heavy - all network setting must be changed!!! */
- printk( "%s: cable change 10Mb/s <-> 100Mb/s detected\n", dev -> name );
- lp -> lan_type = i;
- hp100_stop_interface( dev );
- if ( lp -> lan_type == HP100_LAN_100 )
- lp -> hub_status = hp100_login_to_vg_hub( dev );
- hp100_start_interface( dev );
- }
- else
- {
- printk( "%s: interface reset\n", dev -> name );
- hp100_stop_interface( dev );
- hp100_start_interface( dev );
- }
- }
- dev -> trans_start = jiffies;
- return -EAGAIN;
- }
-
- if ( skb == NULL )
- {
- dev_tint( dev );
- return 0;
- }
-
- if ( skb -> len <= 0 ) return 0;
-
- for ( i = 0; i < 6000 && ( hp100_inw( OPTION_MSW ) & HP100_TX_CMD ); i++ )
- {
-#ifdef HP100_DEBUG_TX
- printk( "hp100_start_xmit: busy\n" );
-#endif
- }
-
- hp100_ints_off();
- val = hp100_inw( IRQ_STATUS );
- hp100_outw( val & HP100_TX_COMPLETE, IRQ_STATUS );
-#ifdef HP100_DEBUG_TX
- printk( "hp100_start_xmit: irq_status = 0x%x, len = %d\n", val, (int)skb -> len );
-#endif
- ok_flag = skb -> len >= HP100_MIN_PACKET_SIZE;
- i = ok_flag ? skb -> len : HP100_MIN_PACKET_SIZE;
- hp100_outw( i, DATA32 ); /* length to memory manager */
- hp100_outw( i, FRAGMENT_LEN );
- if ( lp -> mem_mapped )
- {
- if ( lp -> mem_ptr_virt )
- {
- memcpy( lp -> mem_ptr_virt, skb -> data, skb -> len );
- if ( !ok_flag )
- memset( lp -> mem_ptr_virt, 0, HP100_MIN_PACKET_SIZE - skb -> len );
- }
- else
- {
- memcpy_toio( lp -> mem_ptr_phys, skb -> data, skb -> len );
- if ( !ok_flag )
- memset_io( lp -> mem_ptr_phys, 0, HP100_MIN_PACKET_SIZE - skb -> len );
- }
- }
- else
- {
- outsl( ioaddr + HP100_REG_DATA32, skb -> data, ( skb -> len + 3 ) >> 2 );
- if ( !ok_flag )
- for ( i = ( skb -> len + 3 ) & ~3; i < HP100_MIN_PACKET_SIZE; i += 4 )
- hp100_outl( 0, DATA32 );
- }
- hp100_outw( HP100_TX_CMD | HP100_SET_LB, OPTION_MSW ); /* send packet */
- lp -> stats.tx_packets++;
- dev -> trans_start = jiffies;
- hp100_ints_on();
-
- dev_kfree_skb( skb, FREE_WRITE );
-
-#ifdef HP100_DEBUG_TX
- printk( "hp100_start_xmit: end\n" );
-#endif
-
- return 0;
-}
-
-/*
- * receive - called from interrupt handler
- */
-
-static void hp100_rx( struct device *dev )
-{
- int packets, pkt_len;
- int ioaddr = dev -> base_addr;
- struct hp100_private *lp = (struct hp100_private *)dev -> priv;
- u_int header;
- struct sk_buff *skb;
-
-#if 0
- if ( lp -> lan_type < 0 )
- {
- if ( ( lp -> lan_type = hp100_sense_lan( dev ) ) == HP100_LAN_100 )
- lp -> hub_status = hp100_login_to_vg_hub( dev );
- hp100_page( PERFORMANCE );
- }
-#endif
-
- packets = hp100_inb( RX_PKT_CNT );
-#ifdef HP100_DEBUG
- if ( packets > 1 )
- printk( "hp100_rx: waiting packets = %d\n", packets );
-#endif
- while ( packets-- > 0 )
- {
- for ( pkt_len = 0; pkt_len < 6000 && ( hp100_inw( OPTION_MSW ) & HP100_ADV_NXT_PKT ); pkt_len++ )
- {
-#ifdef HP100_DEBUG_TX
- printk( "hp100_rx: busy, remaining packets = %d\n", packets );
-#endif
- }
- if ( lp -> mem_mapped )
- {
- if ( lp -> mem_ptr_virt )
- header = *(__u32 *)lp -> mem_ptr_virt;
- else
- header = readl( lp -> mem_ptr_phys );
- }
- else
- header = hp100_inl( DATA32 );
- pkt_len = header & HP100_PKT_LEN_MASK;
-#ifdef HP100_DEBUG_RX
- printk( "hp100_rx: new packet - length = %d, errors = 0x%x, dest = 0x%x\n",
- header & HP100_PKT_LEN_MASK, ( header >> 16 ) & 0xfff8, ( header >> 16 ) & 7 );
-#endif
- /*
- * NOTE! This (and the skb_put() below) depends on the skb-functions
- * allocating more than asked (notably, aligning the request up to
- * the next 16-byte length).
- */
- skb = dev_alloc_skb( pkt_len );
- if ( skb == NULL )
- {
-#ifdef HP100_DEBUG
- printk( "hp100_rx: couldn't allocate a sk_buff of size %d\n", pkt_len );
-#endif
- lp -> stats.rx_dropped++;
- }
- else
- {
- u_char *ptr;
-
- skb -> dev = dev;
- ptr = (u_char *)skb_put( skb, pkt_len );
- if ( lp -> mem_mapped )
- {
- if ( lp -> mem_ptr_virt )
- memcpy( ptr, lp -> mem_ptr_virt, ( pkt_len + 3 ) & ~3 );
- else
- memcpy_fromio( ptr, lp -> mem_ptr_phys, ( pkt_len + 3 ) & ~3 );
- }
- else
- insl( ioaddr + HP100_REG_DATA32, ptr, ( pkt_len + 3 ) >> 2 );
- skb -> protocol = eth_type_trans( skb, dev );
- netif_rx( skb );
- lp -> stats.rx_packets++;
-#ifdef HP100_DEBUG_RX
- printk( "rx: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
- ptr[ 0 ], ptr[ 1 ], ptr[ 2 ], ptr[ 3 ], ptr[ 4 ], ptr[ 5 ],
- ptr[ 6 ], ptr[ 7 ], ptr[ 8 ], ptr[ 9 ], ptr[ 10 ], ptr[ 11 ] );
-#endif
- }
- hp100_outw( HP100_ADV_NXT_PKT | HP100_SET_LB, OPTION_MSW );
- switch ( header & 0x00070000 ) {
- case (HP100_MULTI_ADDR_HASH<<16):
- case (HP100_MULTI_ADDR_NO_HASH<<16):
- lp -> stats.multicast++; break;
- }
- }
-#ifdef HP100_DEBUG_RX
- printk( "hp100_rx: end\n" );
-#endif
-}
-
-/*
- * statistics
- */
-
-static struct enet_statistics *hp100_get_stats( struct device *dev )
-{
- int ioaddr = dev -> base_addr;
-
- hp100_ints_off();
- hp100_update_stats( dev );
- hp100_ints_on();
- return &((struct hp100_private *)dev -> priv) -> stats;
-}
-
-static void hp100_update_stats( struct device *dev )
-{
- int ioaddr = dev -> base_addr;
- u_short val;
- struct hp100_private *lp = (struct hp100_private *)dev -> priv;
-
- hp100_page( MAC_CTRL ); /* get all statistics bytes */
- val = hp100_inw( DROPPED ) & 0x0fff;
- lp -> stats.rx_errors += val;
- lp -> stats.rx_over_errors += val;
- val = hp100_inb( CRC );
- lp -> stats.rx_errors += val;
- lp -> stats.rx_crc_errors += val;
- val = hp100_inb( ABORT );
- lp -> stats.tx_errors += val;
- lp -> stats.tx_aborted_errors += val;
- hp100_page( PERFORMANCE );
-}
-
-static void hp100_clear_stats( int ioaddr )
-{
- cli();
- hp100_page( MAC_CTRL ); /* get all statistics bytes */
- hp100_inw( DROPPED );
- hp100_inb( CRC );
- hp100_inb( ABORT );
- hp100_page( PERFORMANCE );
- sti();
-}
-
-/*
- * multicast setup
- */
-
-/*
- * Set or clear the multicast filter for this adapter.
- */
-
-static void hp100_set_multicast_list( struct device *dev)
-{
- int ioaddr = dev -> base_addr;
- struct hp100_private *lp = (struct hp100_private *)dev -> priv;
-
-#ifdef HP100_DEBUG_MULTI
- printk( "hp100_set_multicast_list: num_addrs = %d\n", dev->mc_count);
-#endif
- cli();
- hp100_ints_off();
- hp100_page( MAC_CTRL );
- hp100_andb( ~(HP100_RX_EN | HP100_TX_EN), MAC_CFG_1 ); /* stop rx/tx */
-
- if ( dev->flags&IFF_PROMISC)
- {
- lp -> mac2_mode = HP100_MAC2MODE6; /* promiscuous mode, all good */
- lp -> mac1_mode = HP100_MAC1MODE6; /* packets on the net */
- }
- else
- if ( dev->mc_count || dev->flags&IFF_ALLMULTI )
- {
- lp -> mac2_mode = HP100_MAC2MODE5; /* multicast mode, packets for me */
- lp -> mac1_mode = HP100_MAC1MODE5; /* broadcasts and all multicasts */
- }
- else
- {
- lp -> mac2_mode = HP100_MAC2MODE3; /* normal mode, packets for me */
- lp -> mac1_mode = HP100_MAC1MODE3; /* and broadcasts */
- }
-
- hp100_outb( lp -> mac2_mode, MAC_CFG_2 );
- hp100_andb( HP100_MAC1MODEMASK, MAC_CFG_1 );
- hp100_orb( lp -> mac1_mode |
- HP100_RX_EN | HP100_RX_IDLE | /* enable rx */
- HP100_TX_EN | HP100_TX_IDLE, MAC_CFG_1 ); /* enable tx */
- hp100_page( PERFORMANCE );
- hp100_ints_on();
- sti();
-}
-
-/*
- * hardware interrupt handling
- */
-
-static void hp100_interrupt( int irq, struct pt_regs *regs )
-{
- struct device *dev = (struct device *)irq2dev_map[ irq ];
- struct hp100_private *lp;
- int ioaddr;
- u_short val;
-
- if ( dev == NULL ) return;
- ioaddr = dev -> base_addr;
- if ( dev -> interrupt )
- printk( "%s: re-entering the interrupt handler\n", dev -> name );
- hp100_ints_off();
- dev -> interrupt = 1;
- hp100_page( PERFORMANCE );
- val = hp100_inw( IRQ_STATUS );
-#ifdef HP100_DEBUG_IRQ
- printk( "hp100_interrupt: irq_status = 0x%x\n", val );
-#endif
- if ( val & HP100_RX_PACKET )
- {
- hp100_rx( dev );
- hp100_outw( HP100_RX_PACKET, IRQ_STATUS );
- }
- if ( val & (HP100_TX_SPACE_AVAIL | HP100_TX_COMPLETE) )
- {
- hp100_outw( val & (HP100_TX_SPACE_AVAIL | HP100_TX_COMPLETE), IRQ_STATUS );
- }
- if ( val & ( HP100_TX_ERROR | HP100_RX_ERROR ) )
- {
- lp = (struct hp100_private *)dev -> priv;
- hp100_update_stats( dev );
- hp100_outw( val & (HP100_TX_ERROR | HP100_RX_ERROR), IRQ_STATUS );
- }
-#ifdef HP100_DEBUG_IRQ
- printk( "hp100_interrupt: end\n" );
-#endif
- dev -> interrupt = 0;
- hp100_ints_on();
-}
-
-/*
- * some misc functions
- */
-
-static void hp100_start_interface( struct device *dev )
-{
- int ioaddr = dev -> base_addr;
- struct hp100_private *lp = (struct hp100_private *)dev -> priv;
-
- cli();
- hp100_unreset_card();
- hp100_page( MAC_CTRL );
- hp100_outb( lp -> mac2_mode, MAC_CFG_2 );
- hp100_andb( HP100_MAC1MODEMASK, MAC_CFG_1 );
- hp100_orb( lp -> mac1_mode |
- HP100_RX_EN | HP100_RX_IDLE |
- HP100_TX_EN | HP100_TX_IDLE, MAC_CFG_1 );
- hp100_page( PERFORMANCE );
- hp100_outw( HP100_INT_EN | HP100_SET_LB, OPTION_LSW );
- hp100_outw( HP100_TRI_INT | HP100_RESET_HB, OPTION_LSW );
- if ( lp -> mem_mapped )
- {
- /* enable memory mapping */
- hp100_outw( HP100_MMAP_DIS | HP100_RESET_HB, OPTION_LSW );
- }
- sti();
-}
-
-static void hp100_stop_interface( struct device *dev )
-{
- int ioaddr = dev -> base_addr;
- u_short val;
-
- hp100_outw( HP100_INT_EN | HP100_RESET_LB |
- HP100_TRI_INT | HP100_MMAP_DIS | HP100_SET_HB, OPTION_LSW );
- val = hp100_inw( OPTION_LSW );
- hp100_page( HW_MAP );
- hp100_andb( HP100_BM_SLAVE, BM );
- hp100_page( MAC_CTRL );
- hp100_andb( ~(HP100_RX_EN | HP100_TX_EN), MAC_CFG_1 );
- if ( !(val & HP100_HW_RST) ) return;
- for ( val = 0; val < 6000; val++ )
- if ( ( hp100_inb( MAC_CFG_1 ) & (HP100_TX_IDLE | HP100_RX_IDLE) ) ==
- (HP100_TX_IDLE | HP100_RX_IDLE) )
- return;
- printk( "%s: hp100_stop_interface - timeout\n", dev -> name );
-}
-
-static void hp100_load_eeprom( struct device *dev )
-{
- int i;
- int ioaddr = dev -> base_addr;
-
- hp100_page( EEPROM_CTRL );
- hp100_andw( ~HP100_EEPROM_LOAD, EEPROM_CTRL );
- hp100_orw( HP100_EEPROM_LOAD, EEPROM_CTRL );
- for ( i = 0; i < 6000; i++ )
- if ( !( hp100_inw( OPTION_MSW ) & HP100_EE_LOAD ) ) return;
- printk( "%s: hp100_load_eeprom - timeout\n", dev -> name );
-}
-
-/* return values: LAN_10, LAN_100 or LAN_ERR (not connected or hub is down)... */
-
-static int hp100_sense_lan( struct device *dev )
-{
- int i;
- int ioaddr = dev -> base_addr;
- u_short val_VG, val_10;
- struct hp100_private *lp = (struct hp100_private *)dev -> priv;
-
- hp100_page( MAC_CTRL );
- hp100_orw( HP100_VG_RESET, LAN_CFG_VG );
- val_10 = hp100_inw( LAN_CFG_10 );
- val_VG = hp100_inw( LAN_CFG_VG );
-#ifdef HP100_DEBUG_SENSE
- printk( "hp100_sense_lan: val_VG = 0x%04x, val_10 = 0x%04x\n", val_VG, val_10 );
-#endif
- if ( val_10 & HP100_LINK_BEAT_ST ) return HP100_LAN_10;
- if ( lp -> id -> id == 0x02019F022 ) /* HP J27248B doesn't have 100Mb/s interface */
- return HP100_LAN_ERR;
- for ( i = 0; i < 2500; i++ )
- {
- val_VG = hp100_inw( LAN_CFG_VG );
- if ( val_VG & HP100_LINK_CABLE_ST ) return HP100_LAN_100;
- }
- return HP100_LAN_ERR;
-}
-
-static int hp100_down_vg_link( struct device *dev )
-{
- int ioaddr = dev -> base_addr;
- unsigned long time;
- int i;
-
- hp100_page( MAC_CTRL );
- for ( i = 2500; i > 0; i-- )
- if ( hp100_inw( LAN_CFG_VG ) & HP100_LINK_CABLE_ST ) break;
- if ( i <= 0 ) /* not signal - not logout */
- return 0;
- hp100_andw( ~HP100_LINK_CMD, LAN_CFG_VG );
- time = jiffies + 10;
- while ( time > jiffies )
- if ( !( hp100_inw( LAN_CFG_VG ) & ( HP100_LINK_UP_ST |
- HP100_LINK_CABLE_ST |
- HP100_LINK_GOOD_ST ) ) )
- return 0;
-#ifdef HP100_DEBUG
- printk( "hp100_down_vg_link: timeout\n" );
-#endif
- return -EIO;
-}
-
-static int hp100_login_to_vg_hub( struct device *dev )
-{
- int i;
- int ioaddr = dev -> base_addr;
- u_short val;
- unsigned long time;
-
- hp100_page( MAC_CTRL );
- hp100_orw( HP100_VG_RESET, LAN_CFG_VG );
- time = jiffies + ( HZ / 2 );
- do {
- if ( hp100_inw( LAN_CFG_VG ) & HP100_LINK_CABLE_ST ) break;
- } while ( time > jiffies );
- if ( time <= jiffies )
- {
-#ifdef HP100_DEBUG
- printk( "hp100_login_to_vg_hub: timeout for link\n" );
-#endif
- return -EIO;
- }
-
- if ( hp100_down_vg_link( dev ) < 0 ) /* if fail, try reset VG link */
- {
- hp100_andw( ~HP100_VG_RESET, LAN_CFG_VG );
- hp100_orw( HP100_VG_RESET, LAN_CFG_VG );
- }
- /* bring up link */
- hp100_orw( HP100_LOAD_ADDR | HP100_LINK_CMD, LAN_CFG_VG );
- for ( i = 2500; i > 0; i-- )
- if ( hp100_inw( LAN_CFG_VG ) & HP100_LINK_CABLE_ST ) break;
- if ( i <= 0 )
- {
-#ifdef HP100_DEBUG
- printk( "hp100_login_to_vg_hub: timeout for link (bring up)\n" );
-#endif
- goto down_link;
- }
-
- time = jiffies + ( HZ / 2 );
- do {
- val = hp100_inw( LAN_CFG_VG );
- if ( ( val & ( HP100_LINK_UP_ST | HP100_LINK_GOOD_ST ) ) ==
- ( HP100_LINK_UP_ST | HP100_LINK_GOOD_ST ) )
- return 0; /* success */
- } while ( time > jiffies );
- if ( val & HP100_LINK_GOOD_ST )
- printk( "%s: 100Mb cable training failed, check cable.\n", dev -> name );
- else
- printk( "%s: 100Mb node not accepted by hub, check frame type or security.\n", dev -> name );
-
-down_link:
- hp100_down_vg_link( dev );
- hp100_page( MAC_CTRL );
- hp100_andw( ~( HP100_LOAD_ADDR | HP100_PROM_MODE ), LAN_CFG_VG );
- hp100_orw( HP100_LINK_CMD, LAN_CFG_VG );
- return -EIO;
-}
-
-/*
- * module section
- */
-
-#ifdef MODULE
-
-static int hp100_port = -1;
-
-static char devicename[9] = { 0, };
-static struct device dev_hp100 = {
- devicename, /* device name is inserted by linux/drivers/net/net_init.c */
- 0, 0, 0, 0,
- 0, 0,
- 0, 0, 0, NULL, hp100_probe
-};
-
-int init_module( void )
-{
- if (hp100_port == 0 && !EISA_bus)
- printk("HP100: You should not use auto-probing with insmod!\n");
- if ( hp100_port > 0 )
- dev_hp100.base_addr = hp100_port;
- if ( register_netdev( &dev_hp100 ) != 0 )
- return -EIO;
- return 0;
-}
-
-void cleanup_module( void )
-{
- unregister_netdev( &dev_hp100 );
- release_region( dev_hp100.base_addr, HP100_REGION_SIZE );
- if ( ((struct hp100_private *)dev_hp100.priv) -> mem_ptr_virt )
- vfree( ((struct hp100_private *)dev_hp100.priv) -> mem_ptr_virt );
- kfree_s( dev_hp100.priv, sizeof( struct hp100_private ) );
- dev_hp100.priv = NULL;
-}
-
-#endif
diff --git a/i386/i386at/gpl/linux/net/hp100.h b/i386/i386at/gpl/linux/net/hp100.h
deleted file mode 100644
index 9f14f95a..00000000
--- a/i386/i386at/gpl/linux/net/hp100.h
+++ /dev/null
@@ -1,374 +0,0 @@
-/*
- * hp100.h: Hewlett Packard HP10/100VG ANY LAN ethernet driver for Linux.
- *
- * Author: Jaroslav Kysela, <perex@pf.jcu.cz>
- *
- * Header file...
- *
- * This driver is based on the 'hpfepkt' crynwr packet driver.
- *
- * This source/code is public free; you can distribute it and/or modify
- * it under terms of the GNU General Public License (published by the
- * Free Software Foundation) either version two of this License, or any
- * later version.
- */
-
-/****************************************************************************
- * Hardware Constants
- ****************************************************************************/
-
-/*
- * ATT2MD01 Register Page Constants
- */
-
-#define HP100_PAGE_PERFORMANCE 0x0 /* Page 0 */
-#define HP100_PAGE_MAC_ADDRESS 0x1 /* Page 1 */
-#define HP100_PAGE_HW_MAP 0x2 /* Page 2 */
-#define HP100_PAGE_EEPROM_CTRL 0x3 /* Page 3 */
-#define HP100_PAGE_MAC_CTRL 0x4 /* Page 4 */
-#define HP100_PAGE_MMU_CFG 0x5 /* Page 5 */
-#define HP100_PAGE_ID_MAC_ADDR 0x6 /* Page 6 */
-#define HP100_PAGE_MMU_POINTER 0x7 /* Page 7 */
-
-/*
- * ATT2MD01 Register Addresses
- */
-
-/* Present on all pages */
-
-#define HP100_REG_HW_ID 0x00 /* R: (16) Unique card ID */
-#define HP100_REG_TRACE 0x00 /* W: (16) Used for debug output */
-#define HP100_REG_PAGING 0x02 /* R: (16),15:4 Card ID */
- /* W: (16),3:0 Switch pages */
-#define HP100_REG_OPTION_LSW 0x04 /* RW: (16) Select card functions */
-#define HP100_REG_OPTION_MSW 0x06 /* RW: (16) Select card functions */
-
-/* Page 0 - Performance */
-
-#define HP100_REG_IRQ_STATUS 0x08 /* RW: (16) Which ints are pending */
-#define HP100_REG_IRQ_MASK 0x0a /* RW: (16) Select ints to allow */
-#define HP100_REG_FRAGMENT_LEN 0x0c /* RW: (16)12:0 Current fragment len */
-#define HP100_REG_OFFSET 0x0e /* RW: (16)12:0 Offset to start read */
-#define HP100_REG_DATA32 0x10 /* RW: (32) I/O mode data port */
-#define HP100_REG_DATA16 0x12 /* RW: WORDs must be read from here */
-#define HP100_REG_TX_MEM_FREE 0x14 /* RD: (32) Amount of free Tx mem */
-#define HP100_REG_RX_PKT_CNT 0x18 /* RD: (8) Rx count of pkts on card */
-#define HP100_REG_TX_PKT_CNT 0x19 /* RD: (8) Tx count of pkts on card */
-
-/* Page 1 - MAC Address/Hash Table */
-
-#define HP100_REG_MAC_ADDR 0x08 /* RW: (8) Cards MAC address */
-#define HP100_REG_HASH_BYTE0 0x10 /* RW: (8) Cards multicast filter */
-
-/* Page 2 - Hardware Mapping */
-
-#define HP100_REG_MEM_MAP_LSW 0x08 /* RW: (16) LSW of cards mem addr */
-#define HP100_REG_MEM_MAP_MSW 0x0a /* RW: (16) MSW of cards mem addr */
-#define HP100_REG_IO_MAP 0x0c /* RW: (8) Cards I/O address */
-#define HP100_REG_IRQ_CHANNEL 0x0d /* RW: (8) IRQ and edge/level int */
-#define HP100_REG_SRAM 0x0e /* RW: (8) How much RAM on card */
-#define HP100_REG_BM 0x0f /* RW: (8) Controls BM functions */
-
-/* Page 3 - EEPROM/Boot ROM */
-
-#define HP100_REG_EEPROM_CTRL 0x08 /* RW: (16) Used to load EEPROM */
-
-/* Page 4 - LAN Configuration */
-
-#define HP100_REG_LAN_CFG_10 0x08 /* RW: (16) Set 10M XCVR functions */
-#define HP100_REG_LAN_CFG_VG 0x0a /* RW: (16) Set 100M XCVR functions */
-#define HP100_REG_MAC_CFG_1 0x0c /* RW: (8) Types of pkts to accept */
-#define HP100_REG_MAC_CFG_2 0x0d /* RW: (8) Misc MAC functions */
-/* The follow clear when read: */
-#define HP100_REG_DROPPED 0x10 /* R: (16),11:0 Pkts cant fit in mem*/
-#define HP100_REG_CRC 0x12 /* R: (8) Pkts with CRC */
-#define HP100_REG_ABORT 0x13 /* R: (8) Aborted Tx pkts */
-
-/* Page 5 - MMU */
-
-#define HP100_REG_RX_MEM_STOP 0x0c /* RW: (16) End of Rx ring addr */
-#define HP100_REG_TX_MEM_STOP 0x0e /* RW: (16) End of Tx ring addr */
-
-/* Page 6 - Card ID/Physical LAN Address */
-
-#define HP100_REG_BOARD_ID 0x08 /* R: (8) EISA/ISA card ID */
-#define HP100_REG_BOARD_IO_CHCK 0x0c /* R: (8) Added to ID to get FFh */
-#define HP100_REG_SOFT_MODEL 0x0d /* R: (8) Config program defined */
-#define HP100_REG_LAN_ADDR 0x10 /* R: (8) MAC addr of card */
-#define HP100_REG_LAN_ADDR_CHCK 0x16 /* R: (8) Added to addr to get FFh */
-
-/* Page 7 - MMU Current Pointers */
-
-#define HP100_REG_RX_MEM_BR 0x08 /* R: (16) Current begin of Rx ring */
-#define HP100_REG_RX_MEM_ER 0x0a /* R: (16) Current end of Rx ring */
-#define HP100_REG_TX_MEM_BR 0x0c /* R: (16) Current begin of Tx ring */
-#define HP100_REG_TX_MEM_ER 0x0e /* R: (16) Current end of Rx ring */
-#define HP100_REG_MEM_DEBUG 0x1a /* RW: (16) Used for memory tests */
-
-/*
- * HardwareIDReg bits/masks
- */
-
-#define HP100_HW_ID_0 0x50 /* Hardware ID bytes. */
-#define HP100_HW_ID_1 0x48
-#define HP100_HW_ID_2_REVA 0x50 /* Rev. A ID. NOTE: lower nibble not used */
-#define HP100_HW_ID_3 0x53
-
-/*
- * OptionLSWReg bits/masks
- */
-
-#define HP100_DEBUG_EN 0x8000 /* 0:Disable, 1:Enable Debug Dump Pointer */
-#define HP100_RX_HDR 0x4000 /* 0:Disable, 1:Enable putting pkt into */
- /* system memory before Rx interrupt */
-#define HP100_MMAP_DIS 0x2000 /* 0:Enable, 1:Disable memory mapping. */
- /* MMAP_DIS must be 0 and MEM_EN must */
- /* be 1 for memory-mapped mode to be */
- /* enabled */
-#define HP100_EE_EN 0x1000 /* 0:Disable,1:Enable EEPROM writing */
-#define HP100_BM_WRITE 0x0800 /* 0:Slave, 1:Bus Master for Tx data */
-#define HP100_BM_READ 0x0400 /* 0:Slave, 1:Bus Master for Rx data */
-#define HP100_TRI_INT 0x0200 /* 0:Dont, 1:Do tri-state the int */
-#define HP100_MEM_EN 0x0040 /* Config program set this to */
- /* 0:Disable, 1:Enable mem map. */
- /* See MMAP_DIS. */
-#define HP100_IO_EN 0x0020 /* 0:Disable, 1:Enable I/O transfers */
-#define HP100_BOOT_EN 0x0010 /* 0:Disable, 1:Enable boot ROM access */
-#define HP100_FAKE_INT 0x0008 /* 0:No int, 1:int */
-#define HP100_INT_EN 0x0004 /* 0:Disable, 1:Enable ints from card */
-#define HP100_HW_RST 0x0002 /* 0:Reset, 1:Out of reset */
-
-/*
- * OptionMSWReg bits/masks
- */
-#define HP100_PRIORITY_TX 0x0080 /* 0:Don't, 1:Do all Tx pkts as priority */
-#define HP100_EE_LOAD 0x0040 /* 1:EEPROM loading, 0 when done */
-#define HP100_ADV_NXT_PKT 0x0004 /* 1:Advance to next pkt in Rx queue, */
- /* h/w will set to 0 when done */
-#define HP100_TX_CMD 0x0002 /* 1:Tell h/w download done, h/w will set */
- /* to 0 when done */
-
-/*
- * InterruptStatusReg/InterruptMaskReg bits/masks. These bits will 0 when a 1
- * is written to them.
- */
-#define HP100_RX_PACKET 0x0400 /* 0:No, 1:Yes pkt has been Rx */
-#define HP100_RX_ERROR 0x0200 /* 0:No, 1:Yes Rx pkt had error */
-#define HP100_TX_SPACE_AVAIL 0x0010 /* 0:<8192, 1:>=8192 Tx free bytes */
-#define HP100_TX_COMPLETE 0x0008 /* 0:No, 1:Yes a Tx has completed */
-#define HP100_TX_ERROR 0x0002 /* 0:No, 1:Yes Tx pkt had error */
-
-/*
- * TxMemoryFreeCountReg bits/masks.
- */
-#define HP100_AUTO_COMPARE 0x8000 /* Says at least 8k is available for Tx. */
- /* NOTE: This mask is for the upper */
- /* word of the register. */
-
-/*
- * IRQChannelReg bits/masks.
- */
-#define HP100_ZERO_WAIT_EN 0x80 /* 0:No, 1:Yes assers NOWS signal */
-#define HP100_LEVEL_IRQ 0x10 /* 0:Edge, 1:Level type interrupts. */
- /* Only valid on EISA cards. */
-#define HP100_IRQ_MASK 0x0F /* Isolate the IRQ bits */
-
-/*
- * SRAMReg bits/masks.
- */
-#define HP100_RAM_SIZE_MASK 0xe0 /* AND to get SRAM size index */
-#define HP100_RAM_SIZE_SHIFT 0x05 /* Shift count to put index in lower bits */
-
-/*
- * BMReg bits/masks.
- */
-#define HP100_BM_SLAVE 0x04 /* 0:Slave, 1:BM mode */
-
-/*
- * EEPROMControlReg bits/masks.
- */
-#define HP100_EEPROM_LOAD 0x0001 /* 0->1 loads the EEPROM into registers. */
- /* When it goes back to 0, load is */
- /* complete. This should take ~600us. */
-
-/*
- * LANCntrCfg10Reg bits/masks.
- */
-#define HP100_SQU_ST 0x0100 /* 0:No, 1:Yes collision signal sent */
- /* after Tx. Only used for AUI. */
-#define HP100_MAC10_SEL 0x00c0 /* Get bits to indicate MAC */
-#define HP100_AUI_SEL 0x0020 /* Status of AUI selection */
-#define HP100_LOW_TH 0x0010 /* 0:No, 1:Yes allow better cabling */
-#define HP100_LINK_BEAT_DIS 0x0008 /* 0:Enable, 1:Disable link beat */
-#define HP100_LINK_BEAT_ST 0x0004 /* 0:No, 1:Yes link beat being Rx */
-#define HP100_R_ROL_ST 0x0002 /* 0:No, 1:Yes Rx twisted pair has been */
- /* reversed */
-#define HP100_AUI_ST 0x0001 /* 0:No, 1:Yes use AUI on TP card */
-
-/* MAC Selection, use with MAC10_SEL bits */
-#define HP100_AUTO_SEL_10 0x0 /* Auto select */
-#define HP100_XCVR_LXT901_10 0x1 /* LXT901 10BaseT transceiver */
-#define HP100_XCVR_7213 0x2 /* 7213 transceiver */
-#define HP100_XCVR_82503 0x3 /* 82503 transceiver */
-
-
-/*
- * LANCntrCfgVGReg bits/masks.
- */
-#define HP100_FRAME_FORMAT 0x0800 /* 0:802.3, 1:802.5 frames */
-#define HP100_BRIDGE 0x0400 /* 0:No, 1:Yes tell hub it's a bridge */
-#define HP100_PROM_MODE 0x0200 /* 0:No, 1:Yes tell hub card is */
- /* promiscuous */
-#define HP100_REPEATER 0x0100 /* 0:No, 1:Yes tell hub MAC wants to be */
- /* a cascaded repeater */
-#define HP100_MAC100_SEL 0x0080 /* 0:No, 1:Yes use 100 Mbit MAC */
-#define HP100_LINK_UP_ST 0x0040 /* 0:No, 1:Yes endnode logged in */
-#define HP100_LINK_CABLE_ST 0x0020 /* 0:No, 1:Yes cable can hear tones from */
- /* hub */
-#define HP100_LOAD_ADDR 0x0010 /* 0->1 card addr will be sent to hub. */
- /* 100ms later the link status bits are */
- /* valid */
-#define HP100_LINK_CMD 0x0008 /* 0->1 link will attempt to log in. */
- /* 100ms later the link status bits are */
- /* valid */
-#define HP100_LINK_GOOD_ST 0x0002 /* 0:No, 1:Yes cable passed training */
-#define HP100_VG_RESET 0x0001 /* 0:Yes, 1:No reset the 100VG MAC */
-
-
-/*
- * MACConfiguration1Reg bits/masks.
- */
-#define HP100_RX_IDLE 0x80 /* 0:Yes, 1:No currently receiving pkts */
-#define HP100_TX_IDLE 0x40 /* 0:Yes, 1:No currently Txing pkts */
-#define HP100_RX_EN 0x20 /* 0:No, 1:Yes allow receiving of pkts */
-#define HP100_TX_EN 0x10 /* 0:No, 1:Yes allow transmiting of pkts */
-#define HP100_ACC_ERRORED 0x08 /* 0:No, 1:Yes allow Rx of errored pkts */
-#define HP100_ACC_MC 0x04 /* 0:No, 1:Yes allow Rx of multicast pkts */
-#define HP100_ACC_BC 0x02 /* 0:No, 1:Yes allow Rx of broadcast pkts */
-#define HP100_ACC_PHY 0x01 /* 0:No, 1:Yes allow Rx of ALL physical pkts */
-
-#define HP100_MAC1MODEMASK 0xf0 /* Hide ACC bits */
-#define HP100_MAC1MODE1 0x00 /* Receive nothing, must also disable RX */
-#define HP100_MAC1MODE2 0x00
-#define HP100_MAC1MODE3 HP100_MAC1MODE2 | HP100_ACC_BC
-#define HP100_MAC1MODE4 HP100_MAC1MODE3 | HP100_ACC_MC
-#define HP100_MAC1MODE5 HP100_MAC1MODE4 /* set mc hash to all ones also */
-#define HP100_MAC1MODE6 HP100_MAC1MODE5 | HP100_ACC_PHY /* Promiscuous */
-
-/* Note MODE6 will receive all GOOD packets on the LAN. This really needs
- a mode 7 defined to be LAN Analyzer mode, which will receive errored and
- runt packets, and keep the CRC bytes. */
-
-#define HP100_MAC1MODE7 MAC1MODE6 OR ACC_ERRORED
-
-/*
- * MACConfiguration2Reg bits/masks.
- */
-#define HP100_TR_MODE 0x80 /* 0:No, 1:Yes support Token Ring formats */
-#define HP100_TX_SAME 0x40 /* 0:No, 1:Yes Tx same packet continuous */
-#define HP100_LBK_XCVR 0x20 /* 0:No, 1:Yes loopback through MAC & */
- /* transceiver */
-#define HP100_LBK_MAC 0x10 /* 0:No, 1:Yes loopback through MAC */
-#define HP100_CRC_I 0x08 /* 0:No, 1:Yes inhibit CRC on Tx packets */
-#define HP100_KEEP_CRC 0x02 /* 0:No, 1:Yes keep CRC on Rx packets. */
- /* The length will reflect this. */
-
-#define HP100_MAC2MODEMASK 0x02
-#define HP100_MAC2MODE1 0x00
-#define HP100_MAC2MODE2 0x00
-#define HP100_MAC2MODE3 0x00
-#define HP100_MAC2MODE4 0x00
-#define HP100_MAC2MODE5 0x00
-#define HP100_MAC2MODE6 0x00
-#define HP100_MAC2MODE7 KEEP_CRC
-
-/*
- * Set/Reset bits
- */
-#define HP100_SET_HB 0x0100 /* 0:Set fields to 0 whose mask is 1 */
-#define HP100_SET_LB 0x0001 /* HB sets upper byte, LB sets lower byte */
-#define HP100_RESET_HB 0x0000 /* For readability when resetting bits */
-#define HP100_RESET_LB 0x0000 /* For readability when resetting bits */
-
-/*
- * Misc. Constants
- */
-#define HP100_LAN_100 100 /* lan_type value for VG */
-#define HP100_LAN_10 10 /* lan_type value for 10BaseT */
-#define HP100_LAN_ERR (-1) /* lan_type value for link down */
-
-/*
- * Receive Header Definition.
- */
-
-struct hp100_rx_header {
- u_short rx_length; /* Pkt length is bits 12:0 */
- u_short rx_status; /* status of the packet */
-};
-
-#define HP100_PKT_LEN_MASK 0x1FFF /* AND with RxLength to get length bits */
-
-/* Receive Packet Status. Note, the error bits are only valid if ACC_ERRORED
- bit in the MAC Configuration Register 1 is set. */
-
-#define HP100_RX_PRI 0x8000 /* 0:No, 1:Yes packet is priority */
-#define HP100_SDF_ERR 0x4000 /* 0:No, 1:Yes start of frame error */
-#define HP100_SKEW_ERR 0x2000 /* 0:No, 1:Yes skew out of range */
-#define HP100_BAD_SYMBOL_ERR 0x1000 /* 0:No, 1:Yes invalid symbol received */
-#define HP100_RCV_IPM_ERR 0x0800 /* 0:No, 1:Yes pkt had an invalid packet */
- /* marker */
-#define HP100_SYMBOL_BAL_ERR 0x0400 /* 0:No, 1:Yes symbol balance error */
-#define HP100_VG_ALN_ERR 0x0200 /* 0:No, 1:Yes non-octet received */
-#define HP100_TRUNC_ERR 0x0100 /* 0:No, 1:Yes the packet was truncated */
-#define HP100_RUNT_ERR 0x0040 /* 0:No, 1:Yes pkt length < Min Pkt */
- /* Length Reg. */
-#define HP100_ALN_ERR 0x0010 /* 0:No, 1:Yes align error. */
-#define HP100_CRC_ERR 0x0008 /* 0:No, 1:Yes CRC occurred. */
-
-/* The last three bits indicate the type of destination address */
-
-#define HP100_MULTI_ADDR_HASH 0x0006 /* 110: Addr multicast, matched hash */
-#define HP100_BROADCAST_ADDR 0x0003 /* x11: Addr broadcast */
-#define HP100_MULTI_ADDR_NO_HASH 0x0002 /* 010: Addr multicast, didn't match hash */
-#define HP100_PHYS_ADDR_MATCH 0x0001 /* x01: Addr was physical and mine */
-#define HP100_PHYS_ADDR_NO_MATCH 0x0000 /* x00: Addr was physical but not mine */
-
-/*
- * macros
- */
-
-#define hp100_inb( reg ) \
- inb( ioaddr + HP100_REG_##reg )
-#define hp100_inw( reg ) \
- inw( ioaddr + HP100_REG_##reg )
-#define hp100_inl( reg ) \
- inl( ioaddr + HP100_REG_##reg )
-#define hp100_outb( data, reg ) \
- outb( data, ioaddr + HP100_REG_##reg )
-#define hp100_outw( data, reg ) \
- outw( data, ioaddr + HP100_REG_##reg )
-#define hp100_outl( data, reg ) \
- outl( data, ioaddr + HP100_REG_##reg )
-#define hp100_orb( data, reg ) \
- outb( inb( ioaddr + HP100_REG_##reg ) | (data), ioaddr + HP100_REG_##reg )
-#define hp100_orw( data, reg ) \
- outw( inw( ioaddr + HP100_REG_##reg ) | (data), ioaddr + HP100_REG_##reg )
-#define hp100_andb( data, reg ) \
- outb( inb( ioaddr + HP100_REG_##reg ) & (data), ioaddr + HP100_REG_##reg )
-#define hp100_andw( data, reg ) \
- outw( inw( ioaddr + HP100_REG_##reg ) & (data), ioaddr + HP100_REG_##reg )
-
-#define hp100_page( page ) \
- outw( HP100_PAGE_##page, ioaddr + HP100_REG_PAGING )
-#define hp100_ints_off() \
- outw( HP100_INT_EN | HP100_RESET_LB, ioaddr + HP100_REG_OPTION_LSW )
-#define hp100_ints_on() \
- outw( HP100_INT_EN | HP100_SET_LB, ioaddr + HP100_REG_OPTION_LSW )
-#define hp100_mem_map_enable() \
- outw( HP100_MMAP_DIS | HP100_RESET_HB, ioaddr + HP100_REG_OPTION_LSW )
-#define hp100_mem_map_disable() \
- outw( HP100_MMAP_DIS | HP100_SET_HB, ioaddr + HP100_REG_OPTION_LSW )
-#define hp100_reset_card() \
- outw( HP100_HW_RST | HP100_RESET_LB, ioaddr + HP100_REG_OPTION_LSW )
-#define hp100_unreset_card() \
- outw( HP100_HW_RST | HP100_SET_LB, ioaddr + HP100_REG_OPTION_LSW )
diff --git a/i386/i386at/gpl/linux/net/i82586.h b/i386/i386at/gpl/linux/net/i82586.h
deleted file mode 100644
index ff229e98..00000000
--- a/i386/i386at/gpl/linux/net/i82586.h
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
- * Intel 82586 IEEE 802.3 Ethernet LAN Coprocessor.
- *
- * See:
- * Intel Microcommunications 1991
- * p1-1 to p1-37
- * Intel order No. 231658
- * ISBN 1-55512-119-5
- *
- * Unfortunately, the above chapter mentions neither
- * the System Configuration Pointer (SCP) nor the
- * Intermediate System Configuration Pointer (ISCP),
- * so we probably need to look elsewhere for the
- * whole story -- some recommend the "Intel LAN
- * Components manual" but I have neither a copy
- * nor a full reference. But "elsewhere" may be
- * in the same publication...
- * The description of a later device, the
- * "82596CA High-Performance 32-Bit Local Area Network
- * Coprocessor", (ibid. p1-38 to p1-109) does mention
- * the SCP and ISCP and also has an i82586 compatibility
- * mode. Even more useful is "AP-235 An 82586 Data Link
- * Driver" (ibid. p1-337 to p1-417).
- */
-
-#define I82586_MEMZ (64 * 1024)
-
-#define I82586_SCP_ADDR (I82586_MEMZ - sizeof(scp_t))
-
-#define ADDR_LEN 6
-#define I82586NULL 0xFFFF
-
-#define toff(t,p,f) (unsigned short)((void *)(&((t *)((void *)0 + (p)))->f) - (void *)0)
-
-/*
- * System Configuration Pointer (SCP).
- */
-typedef struct scp_t scp_t;
-struct scp_t
-{
- unsigned short scp_sysbus; /* 82586 bus width: */
-#define SCP_SY_16BBUS (0x0 << 0) /* 16 bits */
-#define SCP_SY_8BBUS (0x1 << 0) /* 8 bits. */
- unsigned short scp_junk[2]; /* Unused */
- unsigned short scp_iscpl; /* lower 16 bits of ISCP_ADDR */
- unsigned short scp_iscph; /* upper 16 bits of ISCP_ADDR */
-};
-
-/*
- * Intermediate System Configuration Pointer (ISCP).
- */
-typedef struct iscp_t iscp_t;
-struct iscp_t
-{
- unsigned short iscp_busy; /* set by CPU before first CA, */
- /* cleared by 82586 after read. */
- unsigned short iscp_offset; /* offset of SCB */
- unsigned short iscp_basel; /* base of SCB */
- unsigned short iscp_baseh; /* " */
-};
-
-/*
- * System Control Block (SCB).
- * The 82586 writes its status to scb_status and then
- * raises an interrupt to alert the CPU.
- * The CPU writes a command to scb_command and
- * then issues a Channel Attention (CA) to alert the 82586.
- */
-typedef struct scb_t scb_t;
-struct scb_t
-{
- unsigned short scb_status; /* Status of 82586 */
-#define SCB_ST_INT (0xF << 12) /* Some of: */
-#define SCB_ST_CX (0x1 << 15) /* Cmd completed */
-#define SCB_ST_FR (0x1 << 14) /* Frame received */
-#define SCB_ST_CNA (0x1 << 13) /* Cmd unit not active */
-#define SCB_ST_RNR (0x1 << 12) /* Rcv unit not ready */
-#define SCB_ST_JUNK0 (0x1 << 11) /* 0 */
-#define SCB_ST_CUS (0x7 << 8) /* Cmd unit status */
-#define SCB_ST_CUS_IDLE (0 << 8) /* Idle */
-#define SCB_ST_CUS_SUSP (1 << 8) /* Suspended */
-#define SCB_ST_CUS_ACTV (2 << 8) /* Active */
-#define SCB_ST_JUNK1 (0x1 << 7) /* 0 */
-#define SCB_ST_RUS (0x7 << 4) /* Rcv unit status */
-#define SCB_ST_RUS_IDLE (0 << 4) /* Idle */
-#define SCB_ST_RUS_SUSP (1 << 4) /* Suspended */
-#define SCB_ST_RUS_NRES (2 << 4) /* No resources */
-#define SCB_ST_RUS_RDY (4 << 4) /* Ready */
- unsigned short scb_command; /* Next command */
-#define SCB_CMD_ACK_CX (0x1 << 15) /* Ack cmd completion */
-#define SCB_CMD_ACK_FR (0x1 << 14) /* Ack frame received */
-#define SCB_CMD_ACK_CNA (0x1 << 13) /* Ack CU not active */
-#define SCB_CMD_ACK_RNR (0x1 << 12) /* Ack RU not ready */
-#define SCB_CMD_JUNKX (0x1 << 11) /* Unused */
-#define SCB_CMD_CUC (0x7 << 8) /* Command Unit command */
-#define SCB_CMD_CUC_NOP (0 << 8) /* Nop */
-#define SCB_CMD_CUC_GO (1 << 8) /* Start cbl_offset */
-#define SCB_CMD_CUC_RES (2 << 8) /* Resume execution */
-#define SCB_CMD_CUC_SUS (3 << 8) /* Suspend " */
-#define SCB_CMD_CUC_ABT (4 << 8) /* Abort " */
-#define SCB_CMD_RESET (0x1 << 7) /* Reset chip (hardware) */
-#define SCB_CMD_RUC (0x7 << 4) /* Receive Unit command */
-#define SCB_CMD_RUC_NOP (0 << 4) /* Nop */
-#define SCB_CMD_RUC_GO (1 << 4) /* Start rfa_offset */
-#define SCB_CMD_RUC_RES (2 << 4) /* Resume reception */
-#define SCB_CMD_RUC_SUS (3 << 4) /* Suspend " */
-#define SCB_CMD_RUC_ABT (4 << 4) /* Abort " */
- unsigned short scb_cbl_offset; /* Offset of first command unit */
- /* Action Command */
- unsigned short scb_rfa_offset; /* Offset of first Receive */
- /* Frame Descriptor in the */
- /* Receive Frame Area */
- unsigned short scb_crcerrs; /* Properly aligned frames */
- /* received with a CRC error */
- unsigned short scb_alnerrs; /* Misaligned frames received */
- /* with a CRC error */
- unsigned short scb_rscerrs; /* Frames lost due to no space */
- unsigned short scb_ovrnerrs; /* Frames lost due to slow bus */
-};
-
-#define scboff(p,f) toff(scb_t, p, f)
-
-/*
- * The eight Action Commands.
- */
-typedef enum acmd_e acmd_e;
-enum acmd_e
-{
- acmd_nop = 0, /* Do nothing */
- acmd_ia_setup = 1, /* Load an (ethernet) address into the */
- /* 82586 */
- acmd_configure = 2, /* Update the 82586 operating parameters */
- acmd_mc_setup = 3, /* Load a list of (ethernet) multicast */
- /* addresses into the 82586 */
- acmd_transmit = 4, /* Transmit a frame */
- acmd_tdr = 5, /* Perform a Time Domain Reflectometer */
- /* test on the serial link */
- acmd_dump = 6, /* Copy 82586 registers to memory */
- acmd_diagnose = 7, /* Run an internal self test */
-};
-
-/*
- * Generic Action Command header.
- */
-typedef struct ach_t ach_t;
-struct ach_t
-{
- unsigned short ac_status; /* Command status: */
-#define AC_SFLD_C (0x1 << 15) /* Command completed */
-#define AC_SFLD_B (0x1 << 14) /* Busy executing */
-#define AC_SFLD_OK (0x1 << 13) /* Completed error free */
-#define AC_SFLD_A (0x1 << 12) /* Command aborted */
-#define AC_SFLD_FAIL (0x1 << 11) /* Selftest failed */
-#define AC_SFLD_S10 (0x1 << 10) /* No carrier sense */
- /* during transmission */
-#define AC_SFLD_S9 (0x1 << 9) /* Tx unsuccessful: */
- /* (stopped) lost CTS */
-#define AC_SFLD_S8 (0x1 << 8) /* Tx unsuccessful: */
- /* (stopped) slow DMA */
-#define AC_SFLD_S7 (0x1 << 7) /* Tx deferred: */
- /* other link traffic */
-#define AC_SFLD_S6 (0x1 << 6) /* Heart Beat: collision */
- /* detect after last tx */
-#define AC_SFLD_S5 (0x1 << 5) /* Tx stopped: */
- /* excessive collisions */
-#define AC_SFLD_MAXCOL (0xF << 0) /* Collision count */
- unsigned short ac_command; /* Command specifier: */
-#define AC_CFLD_EL (0x1 << 15) /* End of command list */
-#define AC_CFLD_S (0x1 << 14) /* Suspend on completion */
-#define AC_CFLD_I (0x1 << 13) /* Interrupt on completion */
-#define AC_CFLD_CMD (0x7 << 0) /* acmd_e */
- unsigned short ac_link; /* Next Action Command */
-};
-
-#define acoff(p,f) toff(ach_t, p, f)
-
-/*
- * The Nop Action Command.
- */
-typedef struct ac_nop_t ac_nop_t;
-struct ac_nop_t
-{
- ach_t nop_h;
-};
-
-/*
- * The IA-Setup Action Command.
- */
-typedef struct ac_ias_t ac_ias_t;
-struct ac_ias_t
-{
- ach_t ias_h;
- unsigned char ias_addr[ADDR_LEN]; /* The (ethernet) address */
-};
-
-/*
- * The Configure Action Command.
- */
-typedef struct ac_cfg_t ac_cfg_t;
-struct ac_cfg_t
-{
- ach_t cfg_h;
- unsigned char cfg_byte_cnt; /* Size foll data: 4-12 */
-#define AC_CFG_BYTE_CNT(v) (((v) & 0xF) << 0)
- unsigned char cfg_fifolim; /* FIFO threshold */
-#define AC_CFG_FIFOLIM(v) (((v) & 0xF) << 0)
- unsigned char cfg_byte8;
-#define AC_CFG_SAV_BF(v) (((v) & 0x1) << 7) /* Save rxd bad frames */
-#define AC_CFG_SRDY(v) (((v) & 0x1) << 6) /* SRDY/ARDY pin means */
- /* external sync. */
- unsigned char cfg_byte9;
-#define AC_CFG_ELPBCK(v) (((v) & 0x1) << 7) /* External loopback */
-#define AC_CFG_ILPBCK(v) (((v) & 0x1) << 6) /* Internal loopback */
-#define AC_CFG_PRELEN(v) (((v) & 0x3) << 4) /* Preamble length */
-#define AC_CFG_PLEN_2 0 /* 2 bytes */
-#define AC_CFG_PLEN_4 1 /* 4 bytes */
-#define AC_CFG_PLEN_8 2 /* 8 bytes */
-#define AC_CFG_PLEN_16 3 /* 16 bytes */
-#define AC_CFG_ALOC(v) (((v) & 0x1) << 3) /* Addr/len data is */
- /* explicit in buffers */
-#define AC_CFG_ADDRLEN(v) (((v) & 0x7) << 0) /* Bytes per address */
- unsigned char cfg_byte10;
-#define AC_CFG_BOFMET(v) (((v) & 0x1) << 7) /* Use alternate expo. */
- /* backoff method */
-#define AC_CFG_ACR(v) (((v) & 0x7) << 4) /* Accelerated cont. res. */
-#define AC_CFG_LINPRIO(v) (((v) & 0x7) << 0) /* Linear priority */
- unsigned char cfg_ifs; /* Interframe spacing */
- unsigned char cfg_slotl; /* Slot time (low byte) */
- unsigned char cfg_byte13;
-#define AC_CFG_RETRYNUM(v) (((v) & 0xF) << 4) /* Max. collision retry */
-#define AC_CFG_SLTTMHI(v) (((v) & 0x7) << 0) /* Slot time (high bits) */
- unsigned char cfg_byte14;
-#define AC_CFG_FLGPAD(v) (((v) & 0x1) << 7) /* Pad with HDLC flags */
-#define AC_CFG_BTSTF(v) (((v) & 0x1) << 6) /* Do HDLC bitstuffing */
-#define AC_CFG_CRC16(v) (((v) & 0x1) << 5) /* 16 bit CCITT CRC */
-#define AC_CFG_NCRC(v) (((v) & 0x1) << 4) /* Insert no CRC */
-#define AC_CFG_TNCRS(v) (((v) & 0x1) << 3) /* Tx even if no carrier */
-#define AC_CFG_MANCH(v) (((v) & 0x1) << 2) /* Manchester coding */
-#define AC_CFG_BCDIS(v) (((v) & 0x1) << 1) /* Disable broadcast */
-#define AC_CFG_PRM(v) (((v) & 0x1) << 0) /* Promiscuous mode */
- unsigned char cfg_byte15;
-#define AC_CFG_ICDS(v) (((v) & 0x1) << 7) /* Internal collision */
- /* detect source */
-#define AC_CFG_CDTF(v) (((v) & 0x7) << 4) /* Collision detect */
- /* filter in bit times */
-#define AC_CFG_ICSS(v) (((v) & 0x1) << 3) /* Internal carrier */
- /* sense source */
-#define AC_CFG_CSTF(v) (((v) & 0x7) << 0) /* Carrier sense */
- /* filter in bit times */
- unsigned short cfg_min_frm_len;
-#define AC_CFG_MNFRM(v) (((v) & 0xFF) << 0) /* Min. bytes/frame (<= 255) */
-};
-
-/*
- * The MC-Setup Action Command.
- */
-typedef struct ac_mcs_t ac_mcs_t;
-struct ac_mcs_t
-{
- ach_t mcs_h;
- unsigned short mcs_cnt; /* No. of bytes of MC addresses */
- unsigned short mcs_data[3]; /* The first MC address .. */
-};
-
-/*
- * The Transmit Action Command.
- */
-typedef struct ac_tx_t ac_tx_t;
-struct ac_tx_t
-{
- ach_t tx_h;
- unsigned short tx_tbd_offset; /* Address of list of buffers. */
-#if 0
-Linux packets are passed down with the destination MAC address
-and length/type field already prepended to the data,
-so we do not need to insert it. Consistent with this
-we must also set the AC_CFG_ALOC(..) flag during the
-ac_cfg_t action command.
- unsigned char tx_addr[ADDR_LEN]; /* The frame dest. address */
- unsigned short tx_length; /* The frame length */
-#endif /* 0 */
-};
-
-/*
- * The Time Domain Reflectometer Action Command.
- */
-typedef struct ac_tdr_t ac_tdr_t;
-struct ac_tdr_t
-{
- ach_t tdr_h;
- unsigned short tdr_result; /* Result. */
-#define AC_TDR_LNK_OK (0x1 << 15) /* No link problem */
-#define AC_TDR_XCVR_PRB (0x1 << 14) /* Txcvr cable problem */
-#define AC_TDR_ET_OPN (0x1 << 13) /* Open on the link */
-#define AC_TDR_ET_SRT (0x1 << 12) /* Short on the link */
-#define AC_TDR_TIME (0x7FF << 0) /* Distance to problem */
- /* site in transmit */
- /* clock cycles */
-};
-
-/*
- * The Dump Action Command.
- */
-typedef struct ac_dmp_t ac_dmp_t;
-struct ac_dmp_t
-{
- ach_t dmp_h;
- unsigned short dmp_offset; /* Result. */
-};
-
-/*
- * Size of the result of the dump command.
- */
-#define DUMPBYTES 170
-
-/*
- * The Diagnose Action Command.
- */
-typedef struct ac_dgn_t ac_dgn_t;
-struct ac_dgn_t
-{
- ach_t dgn_h;
-};
-
-/*
- * Transmit Buffer Descriptor (TBD).
- */
-typedef struct tbd_t tbd_t;
-struct tbd_t
-{
- unsigned short tbd_status; /* Written by the CPU */
-#define TBD_STATUS_EOF (0x1 << 15) /* This TBD is the */
- /* last for this frame */
-#define TBD_STATUS_ACNT (0x3FFF << 0) /* Actual count of data */
- /* bytes in this buffer */
- unsigned short tbd_next_bd_offset; /* Next in list */
- unsigned short tbd_bufl; /* Buffer address (low) */
- unsigned short tbd_bufh; /* " " (high) */
-};
-
-/*
- * Receive Buffer Descriptor (RBD).
- */
-typedef struct rbd_t rbd_t;
-struct rbd_t
-{
- unsigned short rbd_status; /* Written by the 82586 */
-#define RBD_STATUS_EOF (0x1 << 15) /* This RBD is the */
- /* last for this frame */
-#define RBD_STATUS_F (0x1 << 14) /* ACNT field is valid */
-#define RBD_STATUS_ACNT (0x3FFF << 0) /* Actual no. of data */
- /* bytes in this buffer */
- unsigned short rbd_next_rbd_offset; /* Next rbd in list */
- unsigned short rbd_bufl; /* Data pointer (low) */
- unsigned short rbd_bufh; /* " " (high) */
- unsigned short rbd_el_size; /* EL+Data buf. size */
-#define RBD_EL (0x1 << 15) /* This BD is the */
- /* last in the list */
-#define RBD_SIZE (0x3FFF << 0) /* No. of bytes the */
- /* buffer can hold */
-};
-
-#define rbdoff(p,f) toff(rbd_t, p, f)
-
-/*
- * Frame Descriptor (FD).
- */
-typedef struct fd_t fd_t;
-struct fd_t
-{
- unsigned short fd_status; /* Written by the 82586 */
-#define FD_STATUS_C (0x1 << 15) /* Completed storing frame */
-#define FD_STATUS_B (0x1 << 14) /* FD was consumed by RU */
-#define FD_STATUS_OK (0x1 << 13) /* Frame rxd successfully */
-#define FD_STATUS_S11 (0x1 << 11) /* CRC error */
-#define FD_STATUS_S10 (0x1 << 10) /* Alignment error */
-#define FD_STATUS_S9 (0x1 << 9) /* Ran out of resources */
-#define FD_STATUS_S8 (0x1 << 8) /* Rx DMA overrun */
-#define FD_STATUS_S7 (0x1 << 7) /* Frame too short */
-#define FD_STATUS_S6 (0x1 << 6) /* No EOF flag */
- unsigned short fd_command; /* Command */
-#define FD_COMMAND_EL (0x1 << 15) /* Last FD in list */
-#define FD_COMMAND_S (0x1 << 14) /* Suspend RU after rx */
- unsigned short fd_link_offset; /* Next FD */
- unsigned short fd_rbd_offset; /* First RBD (data) */
- /* Prepared by CPU, */
- /* updated by 82586 */
-#if 0
-I think the rest is unused since we
-have set AC_CFG_ALOC(..). However, just
-in case, we leave the space.
-#endif /* 0 */
- unsigned char fd_dest[ADDR_LEN]; /* Destination address */
- /* Written by 82586 */
- unsigned char fd_src[ADDR_LEN]; /* Source address */
- /* Written by 82586 */
- unsigned short fd_length; /* Frame length or type */
- /* Written by 82586 */
-};
-
-#define fdoff(p,f) toff(fd_t, p, f)
-
-/*
- * This software may only be used and distributed
- * according to the terms of the GNU Public License.
- *
- * For more details, see wavelan.c.
- */
diff --git a/i386/i386at/gpl/linux/net/iow.h b/i386/i386at/gpl/linux/net/iow.h
deleted file mode 100644
index 6e15688f..00000000
--- a/i386/i386at/gpl/linux/net/iow.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _ASM_IOW_H
-#define _ASM_IOW_H
-
-/* no longer used */
-
-#endif
diff --git a/i386/i386at/gpl/linux/net/lance.c b/i386/i386at/gpl/linux/net/lance.c
deleted file mode 100644
index 4a388f77..00000000
--- a/i386/i386at/gpl/linux/net/lance.c
+++ /dev/null
@@ -1,1129 +0,0 @@
-/* lance.c: An AMD LANCE ethernet driver for linux. */
-/*
- Written 1993,1994,1995 by Donald Becker.
-
- Copyright 1993 United States Government as represented by the
- Director, National Security Agency.
- This software may be used and distributed according to the terms
- of the GNU Public License, incorporated herein by reference.
-
- This driver is for the Allied Telesis AT1500 and HP J2405A, and should work
- with most other LANCE-based bus-master (NE2100 clone) ethercards.
-
- The author may be reached as becker@CESDIS.gsfc.nasa.gov, or C/O
- Center of Excellence in Space Data and Information Sciences
- Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
-*/
-
-static const char *version = "lance.c:v1.08 4/10/95 dplatt@3do.com\n";
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/ptrace.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/malloc.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/bios32.h>
-#include <asm/bitops.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-
-static unsigned int lance_portlist[] = {0x300, 0x320, 0x340, 0x360, 0};
-void lance_probe1(int ioaddr);
-
-#ifdef HAVE_DEVLIST
-struct netdev_entry lance_drv =
-{"lance", lance_probe1, LANCE_TOTAL_SIZE, lance_portlist};
-#endif
-
-#ifdef LANCE_DEBUG
-int lance_debug = LANCE_DEBUG;
-#else
-int lance_debug = 1;
-#endif
-
-/*
- Theory of Operation
-
-I. Board Compatibility
-
-This device driver is designed for the AMD 79C960, the "PCnet-ISA
-single-chip ethernet controller for ISA". This chip is used in a wide
-variety of boards from vendors such as Allied Telesis, HP, Kingston,
-and Boca. This driver is also intended to work with older AMD 7990
-designs, such as the NE1500 and NE2100, and newer 79C961. For convenience,
-I use the name LANCE to refer to all of the AMD chips, even though it properly
-refers only to the original 7990.
-
-II. Board-specific settings
-
-The driver is designed to work the boards that use the faster
-bus-master mode, rather than in shared memory mode. (Only older designs
-have on-board buffer memory needed to support the slower shared memory mode.)
-
-Most ISA boards have jumpered settings for the I/O base, IRQ line, and DMA
-channel. This driver probes the likely base addresses:
-{0x300, 0x320, 0x340, 0x360}.
-After the board is found it generates a DMA-timeout interrupt and uses
-autoIRQ to find the IRQ line. The DMA channel can be set with the low bits
-of the otherwise-unused dev->mem_start value (aka PARAM1). If unset it is
-probed for by enabling each free DMA channel in turn and checking if
-initialization succeeds.
-
-The HP-J2405A board is an exception: with this board it's easy to read the
-EEPROM-set values for the base, IRQ, and DMA. (Of course you must already
-_know_ the base address -- that field is for writing the EEPROM.)
-
-III. Driver operation
-
-IIIa. Ring buffers
-The LANCE uses ring buffers of Tx and Rx descriptors. Each entry describes
-the base and length of the data buffer, along with status bits. The length
-of these buffers is set by LANCE_LOG_{RX,TX}_BUFFERS, which is log_2() of
-the buffer length (rather than being directly the buffer length) for
-implementation ease. The current values are 2 (Tx) and 4 (Rx), which leads to
-ring sizes of 4 (Tx) and 16 (Rx). Increasing the number of ring entries
-needlessly uses extra space and reduces the chance that an upper layer will
-be able to reorder queued Tx packets based on priority. Decreasing the number
-of entries makes it more difficult to achieve back-to-back packet transmission
-and increases the chance that Rx ring will overflow. (Consider the worst case
-of receiving back-to-back minimum-sized packets.)
-
-The LANCE has the capability to "chain" both Rx and Tx buffers, but this driver
-statically allocates full-sized (slightly oversized -- PKT_BUF_SZ) buffers to
-avoid the administrative overhead. For the Rx side this avoids dynamically
-allocating full-sized buffers "just in case", at the expense of a
-memory-to-memory data copy for each packet received. For most systems this
-is a good tradeoff: the Rx buffer will always be in low memory, the copy
-is inexpensive, and it primes the cache for later packet processing. For Tx
-the buffers are only used when needed as low-memory bounce buffers.
-
-IIIB. 16M memory limitations.
-For the ISA bus master mode all structures used directly by the LANCE,
-the initialization block, Rx and Tx rings, and data buffers, must be
-accessible from the ISA bus, i.e. in the lower 16M of real memory.
-This is a problem for current Linux kernels on >16M machines. The network
-devices are initialized after memory initialization, and the kernel doles out
-memory from the top of memory downward. The current solution is to have a
-special network initialization routine that's called before memory
-initialization; this will eventually be generalized for all network devices.
-As mentioned before, low-memory "bounce-buffers" are used when needed.
-
-IIIC. Synchronization
-The driver runs as two independent, single-threaded flows of control. One
-is the send-packet routine, which enforces single-threaded use by the
-dev->tbusy flag. The other thread is the interrupt handler, which is single
-threaded by the hardware and other software.
-
-The send packet thread has partial control over the Tx ring and 'dev->tbusy'
-flag. It sets the tbusy flag whenever it's queuing a Tx packet. If the next
-queue slot is empty, it clears the tbusy flag when finished otherwise it sets
-the 'lp->tx_full' flag.
-
-The interrupt handler has exclusive control over the Rx ring and records stats
-from the Tx ring. (The Tx-done interrupt can't be selectively turned off, so
-we can't avoid the interrupt overhead by having the Tx routine reap the Tx
-stats.) After reaping the stats, it marks the queue entry as empty by setting
-the 'base' to zero. Iff the 'lp->tx_full' flag is set, it clears both the
-tx_full and tbusy flags.
-
-*/
-
-/* Set the number of Tx and Rx buffers, using Log_2(# buffers).
- Reasonable default values are 4 Tx buffers, and 16 Rx buffers.
- That translates to 2 (4 == 2^^2) and 4 (16 == 2^^4). */
-#ifndef LANCE_LOG_TX_BUFFERS
-#define LANCE_LOG_TX_BUFFERS 4
-#define LANCE_LOG_RX_BUFFERS 4
-#endif
-
-#define TX_RING_SIZE (1 << (LANCE_LOG_TX_BUFFERS))
-#define TX_RING_MOD_MASK (TX_RING_SIZE - 1)
-#define TX_RING_LEN_BITS ((LANCE_LOG_TX_BUFFERS) << 29)
-
-#define RX_RING_SIZE (1 << (LANCE_LOG_RX_BUFFERS))
-#define RX_RING_MOD_MASK (RX_RING_SIZE - 1)
-#define RX_RING_LEN_BITS ((LANCE_LOG_RX_BUFFERS) << 29)
-
-#define PKT_BUF_SZ 1544
-
-/* Offsets from base I/O address. */
-#define LANCE_DATA 0x10
-#define LANCE_ADDR 0x12
-#define LANCE_RESET 0x14
-#define LANCE_BUS_IF 0x16
-#define LANCE_TOTAL_SIZE 0x18
-
-/* The LANCE Rx and Tx ring descriptors. */
-struct lance_rx_head {
- int base;
- short buf_length; /* This length is 2s complement (negative)! */
- short msg_length; /* This length is "normal". */
-};
-
-struct lance_tx_head {
- int base;
- short length; /* Length is 2s complement (negative)! */
- short misc;
-};
-
-/* The LANCE initialization block, described in databook. */
-struct lance_init_block {
- unsigned short mode; /* Pre-set mode (reg. 15) */
- unsigned char phys_addr[6]; /* Physical ethernet address */
- unsigned filter[2]; /* Multicast filter (unused). */
- /* Receive and transmit ring base, along with extra bits. */
- unsigned rx_ring; /* Tx and Rx ring base pointers */
- unsigned tx_ring;
-};
-
-struct lance_private {
- /* The Tx and Rx ring entries must be aligned on 8-byte boundaries.
- This is always true for kmalloc'ed memory */
- struct lance_rx_head rx_ring[RX_RING_SIZE];
- struct lance_tx_head tx_ring[TX_RING_SIZE];
- struct lance_init_block init_block;
- const char *name;
- /* The saved address of a sent-in-place packet/buffer, for skfree(). */
- struct sk_buff* tx_skbuff[TX_RING_SIZE];
- long rx_buffs; /* Address of Rx and Tx buffers. */
- /* Tx low-memory "bounce buffer" address. */
- char (*tx_bounce_buffs)[PKT_BUF_SZ];
- int cur_rx, cur_tx; /* The next free ring entry */
- int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */
- int dma;
- struct enet_statistics stats;
- unsigned char chip_version; /* See lance_chip_type. */
- char tx_full;
- char lock;
-};
-
-#define LANCE_MUST_PAD 0x00000001
-#define LANCE_ENABLE_AUTOSELECT 0x00000002
-#define LANCE_MUST_REINIT_RING 0x00000004
-#define LANCE_MUST_UNRESET 0x00000008
-#define LANCE_HAS_MISSED_FRAME 0x00000010
-
-/* A mapping from the chip ID number to the part number and features.
- These are from the datasheets -- in real life the '970 version
- reportedly has the same ID as the '965. */
-static struct lance_chip_type {
- int id_number;
- const char *name;
- int flags;
-} chip_table[] = {
- {0x0000, "LANCE 7990", /* Ancient lance chip. */
- LANCE_MUST_PAD + LANCE_MUST_UNRESET},
- {0x0003, "PCnet/ISA 79C960", /* 79C960 PCnet/ISA. */
- LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
- LANCE_HAS_MISSED_FRAME},
- {0x2260, "PCnet/ISA+ 79C961", /* 79C961 PCnet/ISA+, Plug-n-Play. */
- LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
- LANCE_HAS_MISSED_FRAME},
- {0x2420, "PCnet/PCI 79C970", /* 79C970 or 79C974 PCnet-SCSI, PCI. */
- LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
- LANCE_HAS_MISSED_FRAME},
- /* Bug: the PCnet/PCI actually uses the PCnet/VLB ID number, so just call
- it the PCnet32. */
- {0x2430, "PCnet32", /* 79C965 PCnet for VL bus. */
- LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
- LANCE_HAS_MISSED_FRAME},
- {0x0, "PCnet (unknown)",
- LANCE_ENABLE_AUTOSELECT + LANCE_MUST_REINIT_RING +
- LANCE_HAS_MISSED_FRAME},
-};
-
-enum {OLD_LANCE = 0, PCNET_ISA=1, PCNET_ISAP=2, PCNET_PCI=3, PCNET_VLB=4, LANCE_UNKNOWN=5};
-
-/* Non-zero only if the current card is a PCI with BIOS-set IRQ. */
-static unsigned char pci_irq_line = 0;
-
-/* Non-zero if lance_probe1() needs to allocate low-memory bounce buffers.
- Assume yes until we know the memory size. */
-static unsigned char lance_need_isa_bounce_buffers = 1;
-
-static int lance_open(struct device *dev);
-static void lance_init_ring(struct device *dev);
-static int lance_start_xmit(struct sk_buff *skb, struct device *dev);
-static int lance_rx(struct device *dev);
-static void lance_interrupt(int irq, struct pt_regs *regs);
-static int lance_close(struct device *dev);
-static struct enet_statistics *lance_get_stats(struct device *dev);
-static void set_multicast_list(struct device *dev);
-
-
-
-/* This lance probe is unlike the other board probes in 1.0.*. The LANCE may
- have to allocate a contiguous low-memory region for bounce buffers.
- This requirement is satisfied by having the lance initialization occur
- before the memory management system is started, and thus well before the
- other probes. */
-
-int lance_init(void)
-{
- int *port;
-
- if (high_memory <= 16*1024*1024)
- lance_need_isa_bounce_buffers = 0;
-
-#if defined(CONFIG_PCI)
- if (pcibios_present()) {
- int pci_index;
- printk("lance.c: PCI bios is present, checking for devices...\n");
- for (pci_index = 0; pci_index < 8; pci_index++) {
- unsigned char pci_bus, pci_device_fn;
- unsigned int pci_ioaddr;
- unsigned short pci_command;
-
- if (pcibios_find_device (PCI_VENDOR_ID_AMD,
- PCI_DEVICE_ID_AMD_LANCE, pci_index,
- &pci_bus, &pci_device_fn) != 0)
- break;
- pcibios_read_config_byte(pci_bus, pci_device_fn,
- PCI_INTERRUPT_LINE, &pci_irq_line);
- pcibios_read_config_dword(pci_bus, pci_device_fn,
- PCI_BASE_ADDRESS_0, &pci_ioaddr);
- /* Remove I/O space marker in bit 0. */
- pci_ioaddr &= ~3;
- /* PCI Spec 2.1 states that it is either the driver or PCI card's
- * responsibility to set the PCI Master Enable Bit if needed.
- * (From Mark Stockton <marks@schooner.sys.hou.compaq.com>)
- */
- pcibios_read_config_word(pci_bus, pci_device_fn,
- PCI_COMMAND, &pci_command);
- if ( ! (pci_command & PCI_COMMAND_MASTER)) {
- printk("PCI Master Bit has not been set. Setting...\n");
- pci_command |= PCI_COMMAND_MASTER;
- pcibios_write_config_word(pci_bus, pci_device_fn,
- PCI_COMMAND, pci_command);
- }
- printk("Found PCnet/PCI at %#x, irq %d.\n",
- pci_ioaddr, pci_irq_line);
- lance_probe1(pci_ioaddr);
- pci_irq_line = 0;
- }
- }
-#endif /* defined(CONFIG_PCI) */
-
- for (port = lance_portlist; *port; port++) {
- int ioaddr = *port;
-
- if ( check_region(ioaddr, LANCE_TOTAL_SIZE) == 0) {
- /* Detect "normal" 0x57 0x57 and the NI6510EB 0x52 0x44
- signatures w/ minimal I/O reads */
- char offset15, offset14 = inb(ioaddr + 14);
-
- if ((offset14 == 0x52 || offset14 == 0x57) &&
- ((offset15 = inb(ioaddr + 15)) == 0x57 || offset15 == 0x44))
- lance_probe1(ioaddr);
- }
- }
-
- return 0;
-}
-
-void lance_probe1(int ioaddr)
-{
- struct device *dev;
- struct lance_private *lp;
- short dma_channels; /* Mark spuriously-busy DMA channels */
- int i, reset_val, lance_version;
- const char *chipname;
- /* Flags for specific chips or boards. */
- unsigned char hpJ2405A = 0; /* HP ISA adaptor */
- int hp_builtin = 0; /* HP on-board ethernet. */
- static int did_version = 0; /* Already printed version info. */
-
- /* First we look for special cases.
- Check for HP's on-board ethernet by looking for 'HP' in the BIOS.
- There are two HP versions, check the BIOS for the configuration port.
- This method provided by L. Julliard, Laurent_Julliard@grenoble.hp.com.
- */
- if ( *((unsigned short *) 0x000f0102) == 0x5048) {
- static const short ioaddr_table[] = { 0x300, 0x320, 0x340, 0x360};
- int hp_port = ( *((unsigned char *) 0x000f00f1) & 1) ? 0x499 : 0x99;
- /* We can have boards other than the built-in! Verify this is on-board. */
- if ((inb(hp_port) & 0xc0) == 0x80
- && ioaddr_table[inb(hp_port) & 3] == ioaddr)
- hp_builtin = hp_port;
- }
- /* We also recognize the HP Vectra on-board here, but check below. */
- hpJ2405A = (inb(ioaddr) == 0x08 && inb(ioaddr+1) == 0x00
- && inb(ioaddr+2) == 0x09);
-
- /* Reset the LANCE. */
- reset_val = inw(ioaddr+LANCE_RESET); /* Reset the LANCE */
-
- /* The Un-Reset needed is only needed for the real NE2100, and will
- confuse the HP board. */
- if (!hpJ2405A)
- outw(reset_val, ioaddr+LANCE_RESET);
-
- outw(0x0000, ioaddr+LANCE_ADDR); /* Switch to window 0 */
- if (inw(ioaddr+LANCE_DATA) != 0x0004)
- return;
-
- /* Get the version of the chip. */
- outw(88, ioaddr+LANCE_ADDR);
- if (inw(ioaddr+LANCE_ADDR) != 88) {
- lance_version = 0;
- } else { /* Good, it's a newer chip. */
- int chip_version = inw(ioaddr+LANCE_DATA);
- outw(89, ioaddr+LANCE_ADDR);
- chip_version |= inw(ioaddr+LANCE_DATA) << 16;
- if (lance_debug > 2)
- printk(" LANCE chip version is %#x.\n", chip_version);
- if ((chip_version & 0xfff) != 0x003)
- return;
- chip_version = (chip_version >> 12) & 0xffff;
- for (lance_version = 1; chip_table[lance_version].id_number; lance_version++) {
- if (chip_table[lance_version].id_number == chip_version)
- break;
- }
- }
-
- dev = init_etherdev(0, 0);
- chipname = chip_table[lance_version].name;
- printk("%s: %s at %#3x,", dev->name, chipname, ioaddr);
-
- /* There is a 16 byte station address PROM at the base address.
- The first six bytes are the station address. */
- for (i = 0; i < 6; i++)
- printk(" %2.2x", dev->dev_addr[i] = inb(ioaddr + i));
-
- dev->base_addr = ioaddr;
- request_region(ioaddr, LANCE_TOTAL_SIZE, chip_table[lance_version].name);
-
- /* Make certain the data structures used by the LANCE are aligned and DMAble. */
- lp = (struct lance_private *) kmalloc(sizeof(*lp), GFP_DMA | GFP_KERNEL);
- memset(lp, 0, sizeof(*lp));
- dev->priv = lp;
- lp->name = chipname;
- lp->rx_buffs = (unsigned long) kmalloc(PKT_BUF_SZ*RX_RING_SIZE, GFP_DMA | GFP_KERNEL);
- lp->tx_bounce_buffs = NULL;
- if (lance_need_isa_bounce_buffers)
- lp->tx_bounce_buffs = kmalloc(PKT_BUF_SZ*TX_RING_SIZE, GFP_DMA | GFP_KERNEL);
-
- lp->chip_version = lance_version;
-
- lp->init_block.mode = 0x0003; /* Disable Rx and Tx. */
- for (i = 0; i < 6; i++)
- lp->init_block.phys_addr[i] = dev->dev_addr[i];
- lp->init_block.filter[0] = 0x00000000;
- lp->init_block.filter[1] = 0x00000000;
- lp->init_block.rx_ring = (int)lp->rx_ring | RX_RING_LEN_BITS;
- lp->init_block.tx_ring = (int)lp->tx_ring | TX_RING_LEN_BITS;
-
- outw(0x0001, ioaddr+LANCE_ADDR);
- inw(ioaddr+LANCE_ADDR);
- outw((short) (int) &lp->init_block, ioaddr+LANCE_DATA);
- outw(0x0002, ioaddr+LANCE_ADDR);
- inw(ioaddr+LANCE_ADDR);
- outw(((int)&lp->init_block) >> 16, ioaddr+LANCE_DATA);
- outw(0x0000, ioaddr+LANCE_ADDR);
- inw(ioaddr+LANCE_ADDR);
-
- if (pci_irq_line) {
- dev->dma = 4; /* Native bus-master, no DMA channel needed. */
- dev->irq = pci_irq_line;
- } else if (hp_builtin) {
- static const char dma_tbl[4] = {3, 5, 6, 0};
- static const char irq_tbl[4] = {3, 4, 5, 9};
- unsigned char port_val = inb(hp_builtin);
- dev->dma = dma_tbl[(port_val >> 4) & 3];
- dev->irq = irq_tbl[(port_val >> 2) & 3];
- printk(" HP Vectra IRQ %d DMA %d.\n", dev->irq, dev->dma);
- } else if (hpJ2405A) {
- static const char dma_tbl[4] = {3, 5, 6, 7};
- static const char irq_tbl[8] = {3, 4, 5, 9, 10, 11, 12, 15};
- short reset_val = inw(ioaddr+LANCE_RESET);
- dev->dma = dma_tbl[(reset_val >> 2) & 3];
- dev->irq = irq_tbl[(reset_val >> 4) & 7];
- printk(" HP J2405A IRQ %d DMA %d.\n", dev->irq, dev->dma);
- } else if (lance_version == PCNET_ISAP) { /* The plug-n-play version. */
- short bus_info;
- outw(8, ioaddr+LANCE_ADDR);
- bus_info = inw(ioaddr+LANCE_BUS_IF);
- dev->dma = bus_info & 0x07;
- dev->irq = (bus_info >> 4) & 0x0F;
- } else {
- /* The DMA channel may be passed in PARAM1. */
- if (dev->mem_start & 0x07)
- dev->dma = dev->mem_start & 0x07;
- }
-
- if (dev->dma == 0) {
- /* Read the DMA channel status register, so that we can avoid
- stuck DMA channels in the DMA detection below. */
- dma_channels = ((inb(DMA1_STAT_REG) >> 4) & 0x0f) |
- (inb(DMA2_STAT_REG) & 0xf0);
- }
- if (dev->irq >= 2)
- printk(" assigned IRQ %d", dev->irq);
- else {
- /* To auto-IRQ we enable the initialization-done and DMA error
- interrupts. For ISA boards we get a DMA error, but VLB and PCI
- boards will work. */
- autoirq_setup(0);
-
- /* Trigger an initialization just for the interrupt. */
- outw(0x0041, ioaddr+LANCE_DATA);
-
- dev->irq = autoirq_report(1);
- if (dev->irq)
- printk(", probed IRQ %d", dev->irq);
- else {
- printk(", failed to detect IRQ line.\n");
- return;
- }
-
- /* Check for the initialization done bit, 0x0100, which means
- that we don't need a DMA channel. */
- if (inw(ioaddr+LANCE_DATA) & 0x0100)
- dev->dma = 4;
- }
-
- if (dev->dma == 4) {
- printk(", no DMA needed.\n");
- } else if (dev->dma) {
- if (request_dma(dev->dma, chipname)) {
- printk("DMA %d allocation failed.\n", dev->dma);
- return;
- } else
- printk(", assigned DMA %d.\n", dev->dma);
- } else { /* OK, we have to auto-DMA. */
- for (i = 0; i < 4; i++) {
- static const char dmas[] = { 5, 6, 7, 3 };
- int dma = dmas[i];
- int boguscnt;
-
- /* Don't enable a permanently busy DMA channel, or the machine
- will hang. */
- if (test_bit(dma, &dma_channels))
- continue;
- outw(0x7f04, ioaddr+LANCE_DATA); /* Clear the memory error bits. */
- if (request_dma(dma, chipname))
- continue;
- set_dma_mode(dma, DMA_MODE_CASCADE);
- enable_dma(dma);
-
- /* Trigger an initialization. */
- outw(0x0001, ioaddr+LANCE_DATA);
- for (boguscnt = 100; boguscnt > 0; --boguscnt)
- if (inw(ioaddr+LANCE_DATA) & 0x0900)
- break;
- if (inw(ioaddr+LANCE_DATA) & 0x0100) {
- dev->dma = dma;
- printk(", DMA %d.\n", dev->dma);
- break;
- } else {
- disable_dma(dma);
- free_dma(dma);
- }
- }
- if (i == 4) { /* Failure: bail. */
- printk("DMA detection failed.\n");
- return;
- }
- }
-
- if (chip_table[lp->chip_version].flags & LANCE_ENABLE_AUTOSELECT) {
- /* Turn on auto-select of media (10baseT or BNC) so that the user
- can watch the LEDs even if the board isn't opened. */
- outw(0x0002, ioaddr+LANCE_ADDR);
- outw(0x0002, ioaddr+LANCE_BUS_IF);
- }
-
- if (lance_debug > 0 && did_version++ == 0)
- printk(version);
-
- /* The LANCE-specific entries in the device structure. */
- dev->open = &lance_open;
- dev->hard_start_xmit = &lance_start_xmit;
- dev->stop = &lance_close;
- dev->get_stats = &lance_get_stats;
- dev->set_multicast_list = &set_multicast_list;
-
- return;
-}
-
-
-static int
-lance_open(struct device *dev)
-{
- struct lance_private *lp = (struct lance_private *)dev->priv;
- int ioaddr = dev->base_addr;
- int i;
-
- if (dev->irq == 0 ||
- request_irq(dev->irq, &lance_interrupt, 0, lp->name)) {
- return -EAGAIN;
- }
-
- /* We used to allocate DMA here, but that was silly.
- DMA lines can't be shared! We now permanently allocate them. */
-
- irq2dev_map[dev->irq] = dev;
-
- /* Reset the LANCE */
- inw(ioaddr+LANCE_RESET);
-
- /* The DMA controller is used as a no-operation slave, "cascade mode". */
- if (dev->dma != 4) {
- enable_dma(dev->dma);
- set_dma_mode(dev->dma, DMA_MODE_CASCADE);
- }
-
- /* Un-Reset the LANCE, needed only for the NE2100. */
- if (chip_table[lp->chip_version].flags & LANCE_MUST_UNRESET)
- outw(0, ioaddr+LANCE_RESET);
-
- if (chip_table[lp->chip_version].flags & LANCE_ENABLE_AUTOSELECT) {
- /* This is 79C960-specific: Turn on auto-select of media (AUI, BNC). */
- outw(0x0002, ioaddr+LANCE_ADDR);
- outw(0x0002, ioaddr+LANCE_BUS_IF);
- }
-
- if (lance_debug > 1)
- printk("%s: lance_open() irq %d dma %d tx/rx rings %#x/%#x init %#x.\n",
- dev->name, dev->irq, dev->dma, (int) lp->tx_ring, (int) lp->rx_ring,
- (int) &lp->init_block);
-
- lance_init_ring(dev);
- /* Re-initialize the LANCE, and start it when done. */
- outw(0x0001, ioaddr+LANCE_ADDR);
- outw((short) (int) &lp->init_block, ioaddr+LANCE_DATA);
- outw(0x0002, ioaddr+LANCE_ADDR);
- outw(((int)&lp->init_block) >> 16, ioaddr+LANCE_DATA);
-
- outw(0x0004, ioaddr+LANCE_ADDR);
- outw(0x0915, ioaddr+LANCE_DATA);
-
- outw(0x0000, ioaddr+LANCE_ADDR);
- outw(0x0001, ioaddr+LANCE_DATA);
-
- dev->tbusy = 0;
- dev->interrupt = 0;
- dev->start = 1;
- i = 0;
- while (i++ < 100)
- if (inw(ioaddr+LANCE_DATA) & 0x0100)
- break;
- /*
- * We used to clear the InitDone bit, 0x0100, here but Mark Stockton
- * reports that doing so triggers a bug in the '974.
- */
- outw(0x0042, ioaddr+LANCE_DATA);
-
- if (lance_debug > 2)
- printk("%s: LANCE open after %d ticks, init block %#x csr0 %4.4x.\n",
- dev->name, i, (int) &lp->init_block, inw(ioaddr+LANCE_DATA));
-
- return 0; /* Always succeed */
-}
-
-/* The LANCE has been halted for one reason or another (busmaster memory
- arbitration error, Tx FIFO underflow, driver stopped it to reconfigure,
- etc.). Modern LANCE variants always reload their ring-buffer
- configuration when restarted, so we must reinitialize our ring
- context before restarting. As part of this reinitialization,
- find all packets still on the Tx ring and pretend that they had been
- sent (in effect, drop the packets on the floor) - the higher-level
- protocols will time out and retransmit. It'd be better to shuffle
- these skbs to a temp list and then actually re-Tx them after
- restarting the chip, but I'm too lazy to do so right now. dplatt@3do.com
-*/
-
-static void
-lance_purge_tx_ring(struct device *dev)
-{
- struct lance_private *lp = (struct lance_private *)dev->priv;
- int i;
-
- for (i = 0; i < TX_RING_SIZE; i++) {
- if (lp->tx_skbuff[i]) {
- dev_kfree_skb(lp->tx_skbuff[i],FREE_WRITE);
- lp->tx_skbuff[i] = NULL;
- }
- }
-}
-
-
-/* Initialize the LANCE Rx and Tx rings. */
-static void
-lance_init_ring(struct device *dev)
-{
- struct lance_private *lp = (struct lance_private *)dev->priv;
- int i;
-
- lp->lock = 0, lp->tx_full = 0;
- lp->cur_rx = lp->cur_tx = 0;
- lp->dirty_rx = lp->dirty_tx = 0;
-
- for (i = 0; i < RX_RING_SIZE; i++) {
- lp->rx_ring[i].base = (lp->rx_buffs + i*PKT_BUF_SZ) | 0x80000000;
- lp->rx_ring[i].buf_length = -PKT_BUF_SZ;
- }
- /* The Tx buffer address is filled in as needed, but we do need to clear
- the upper ownership bit. */
- for (i = 0; i < TX_RING_SIZE; i++) {
- lp->tx_ring[i].base = 0;
- }
-
- lp->init_block.mode = 0x0000;
- for (i = 0; i < 6; i++)
- lp->init_block.phys_addr[i] = dev->dev_addr[i];
- lp->init_block.filter[0] = 0x00000000;
- lp->init_block.filter[1] = 0x00000000;
- lp->init_block.rx_ring = (int)lp->rx_ring | RX_RING_LEN_BITS;
- lp->init_block.tx_ring = (int)lp->tx_ring | TX_RING_LEN_BITS;
-}
-
-static void
-lance_restart(struct device *dev, unsigned int csr0_bits, int must_reinit)
-{
- struct lance_private *lp = (struct lance_private *)dev->priv;
-
- if (must_reinit ||
- (chip_table[lp->chip_version].flags & LANCE_MUST_REINIT_RING)) {
- lance_purge_tx_ring(dev);
- lance_init_ring(dev);
- }
- outw(0x0000, dev->base_addr + LANCE_ADDR);
- outw(csr0_bits, dev->base_addr + LANCE_DATA);
-}
-
-static int
-lance_start_xmit(struct sk_buff *skb, struct device *dev)
-{
- struct lance_private *lp = (struct lance_private *)dev->priv;
- int ioaddr = dev->base_addr;
- int entry;
- unsigned long flags;
-
- /* Transmitter timeout, serious problems. */
- if (dev->tbusy) {
- int tickssofar = jiffies - dev->trans_start;
- if (tickssofar < 20)
- return 1;
- outw(0, ioaddr+LANCE_ADDR);
- printk("%s: transmit timed out, status %4.4x, resetting.\n",
- dev->name, inw(ioaddr+LANCE_DATA));
- outw(0x0004, ioaddr+LANCE_DATA);
- lp->stats.tx_errors++;
-#ifndef final_version
- {
- int i;
- printk(" Ring data dump: dirty_tx %d cur_tx %d%s cur_rx %d.",
- lp->dirty_tx, lp->cur_tx, lp->tx_full ? " (full)" : "",
- lp->cur_rx);
- for (i = 0 ; i < RX_RING_SIZE; i++)
- printk("%s %08x %04x %04x", i & 0x3 ? "" : "\n ",
- lp->rx_ring[i].base, -lp->rx_ring[i].buf_length,
- lp->rx_ring[i].msg_length);
- for (i = 0 ; i < TX_RING_SIZE; i++)
- printk("%s %08x %04x %04x", i & 0x3 ? "" : "\n ",
- lp->tx_ring[i].base, -lp->tx_ring[i].length,
- lp->tx_ring[i].misc);
- printk("\n");
- }
-#endif
- lance_restart(dev, 0x0043, 1);
-
- dev->tbusy=0;
- dev->trans_start = jiffies;
-
- return 0;
- }
-
- if (skb == NULL) {
- dev_tint(dev);
- return 0;
- }
-
- if (skb->len <= 0)
- return 0;
-
- if (lance_debug > 3) {
- outw(0x0000, ioaddr+LANCE_ADDR);
- printk("%s: lance_start_xmit() called, csr0 %4.4x.\n", dev->name,
- inw(ioaddr+LANCE_DATA));
- outw(0x0000, ioaddr+LANCE_DATA);
- }
-
- /* Block a timer-based transmit from overlapping. This could better be
- done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
- if (set_bit(0, (void*)&dev->tbusy) != 0) {
- printk("%s: Transmitter access conflict.\n", dev->name);
- return 1;
- }
-
- if (set_bit(0, (void*)&lp->lock) != 0) {
- if (lance_debug > 0)
- printk("%s: tx queue lock!.\n", dev->name);
- /* don't clear dev->tbusy flag. */
- return 1;
- }
-
- /* Fill in a Tx ring entry */
-
- /* Mask to ring buffer boundary. */
- entry = lp->cur_tx & TX_RING_MOD_MASK;
-
- /* Caution: the write order is important here, set the base address
- with the "ownership" bits last. */
-
- /* The old LANCE chips doesn't automatically pad buffers to min. size. */
- if (chip_table[lp->chip_version].flags & LANCE_MUST_PAD) {
- lp->tx_ring[entry].length =
- -(ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN);
- } else
- lp->tx_ring[entry].length = -skb->len;
-
- lp->tx_ring[entry].misc = 0x0000;
-
- /* If any part of this buffer is >16M we must copy it to a low-memory
- buffer. */
- if ((int)(skb->data) + skb->len > 0x01000000) {
- if (lance_debug > 5)
- printk("%s: bouncing a high-memory packet (%#x).\n",
- dev->name, (int)(skb->data));
- memcpy(&lp->tx_bounce_buffs[entry], skb->data, skb->len);
- lp->tx_ring[entry].base =
- (int)(lp->tx_bounce_buffs + entry) | 0x83000000;
- dev_kfree_skb (skb, FREE_WRITE);
- } else {
- lp->tx_skbuff[entry] = skb;
- lp->tx_ring[entry].base = (int)(skb->data) | 0x83000000;
- }
- lp->cur_tx++;
-
- /* Trigger an immediate send poll. */
- outw(0x0000, ioaddr+LANCE_ADDR);
- outw(0x0048, ioaddr+LANCE_DATA);
-
- dev->trans_start = jiffies;
-
- save_flags(flags);
- cli();
- lp->lock = 0;
- if (lp->tx_ring[(entry+1) & TX_RING_MOD_MASK].base == 0)
- dev->tbusy=0;
- else
- lp->tx_full = 1;
- restore_flags(flags);
-
- return 0;
-}
-
-/* The LANCE interrupt handler. */
-static void
-lance_interrupt(int irq, struct pt_regs * regs)
-{
- struct device *dev = (struct device *)(irq2dev_map[irq]);
- struct lance_private *lp;
- int csr0, ioaddr, boguscnt=10;
- int must_restart;
-
- if (dev == NULL) {
- printk ("lance_interrupt(): irq %d for unknown device.\n", irq);
- return;
- }
-
- ioaddr = dev->base_addr;
- lp = (struct lance_private *)dev->priv;
- if (dev->interrupt)
- printk("%s: Re-entering the interrupt handler.\n", dev->name);
-
- dev->interrupt = 1;
-
- outw(0x00, dev->base_addr + LANCE_ADDR);
- while ((csr0 = inw(dev->base_addr + LANCE_DATA)) & 0x8600
- && --boguscnt >= 0) {
- /* Acknowledge all of the current interrupt sources ASAP. */
- outw(csr0 & ~0x004f, dev->base_addr + LANCE_DATA);
-
- must_restart = 0;
-
- if (lance_debug > 5)
- printk("%s: interrupt csr0=%#2.2x new csr=%#2.2x.\n",
- dev->name, csr0, inw(dev->base_addr + LANCE_DATA));
-
- if (csr0 & 0x0400) /* Rx interrupt */
- lance_rx(dev);
-
- if (csr0 & 0x0200) { /* Tx-done interrupt */
- int dirty_tx = lp->dirty_tx;
-
- while (dirty_tx < lp->cur_tx) {
- int entry = dirty_tx & TX_RING_MOD_MASK;
- int status = lp->tx_ring[entry].base;
-
- if (status < 0)
- break; /* It still hasn't been Txed */
-
- lp->tx_ring[entry].base = 0;
-
- if (status & 0x40000000) {
- /* There was an major error, log it. */
- int err_status = lp->tx_ring[entry].misc;
- lp->stats.tx_errors++;
- if (err_status & 0x0400) lp->stats.tx_aborted_errors++;
- if (err_status & 0x0800) lp->stats.tx_carrier_errors++;
- if (err_status & 0x1000) lp->stats.tx_window_errors++;
- if (err_status & 0x4000) {
- /* Ackk! On FIFO errors the Tx unit is turned off! */
- lp->stats.tx_fifo_errors++;
- /* Remove this verbosity later! */
- printk("%s: Tx FIFO error! Status %4.4x.\n",
- dev->name, csr0);
- /* Restart the chip. */
- must_restart = 1;
- }
- } else {
- if (status & 0x18000000)
- lp->stats.collisions++;
- lp->stats.tx_packets++;
- }
-
- /* We must free the original skb if it's not a data-only copy
- in the bounce buffer. */
- if (lp->tx_skbuff[entry]) {
- dev_kfree_skb(lp->tx_skbuff[entry],FREE_WRITE);
- lp->tx_skbuff[entry] = 0;
- }
- dirty_tx++;
- }
-
-#ifndef final_version
- if (lp->cur_tx - dirty_tx >= TX_RING_SIZE) {
- printk("out-of-sync dirty pointer, %d vs. %d, full=%d.\n",
- dirty_tx, lp->cur_tx, lp->tx_full);
- dirty_tx += TX_RING_SIZE;
- }
-#endif
-
- if (lp->tx_full && dev->tbusy
- && dirty_tx > lp->cur_tx - TX_RING_SIZE + 2) {
- /* The ring is no longer full, clear tbusy. */
- lp->tx_full = 0;
- dev->tbusy = 0;
- mark_bh(NET_BH);
- }
-
- lp->dirty_tx = dirty_tx;
- }
-
- /* Log misc errors. */
- if (csr0 & 0x4000) lp->stats.tx_errors++; /* Tx babble. */
- if (csr0 & 0x1000) lp->stats.rx_errors++; /* Missed a Rx frame. */
- if (csr0 & 0x0800) {
- printk("%s: Bus master arbitration failure, status %4.4x.\n",
- dev->name, csr0);
- /* Restart the chip. */
- must_restart = 1;
- }
-
- if (must_restart) {
- /* stop the chip to clear the error condition, then restart */
- outw(0x0000, dev->base_addr + LANCE_ADDR);
- outw(0x0004, dev->base_addr + LANCE_DATA);
- lance_restart(dev, 0x0002, 0);
- }
- }
-
- /* Clear any other interrupt, and set interrupt enable. */
- outw(0x0000, dev->base_addr + LANCE_ADDR);
- outw(0x7940, dev->base_addr + LANCE_DATA);
-
- if (lance_debug > 4)
- printk("%s: exiting interrupt, csr%d=%#4.4x.\n",
- dev->name, inw(ioaddr + LANCE_ADDR),
- inw(dev->base_addr + LANCE_DATA));
-
- dev->interrupt = 0;
- return;
-}
-
-static int
-lance_rx(struct device *dev)
-{
- struct lance_private *lp = (struct lance_private *)dev->priv;
- int entry = lp->cur_rx & RX_RING_MOD_MASK;
- int i;
-
- /* If we own the next entry, it's a new packet. Send it up. */
- while (lp->rx_ring[entry].base >= 0) {
- int status = lp->rx_ring[entry].base >> 24;
-
- if (status != 0x03) { /* There was an error. */
- /* There is a tricky error noted by John Murphy,
- <murf@perftech.com> to Russ Nelson: Even with full-sized
- buffers it's possible for a jabber packet to use two
- buffers, with only the last correctly noting the error. */
- if (status & 0x01) /* Only count a general error at the */
- lp->stats.rx_errors++; /* end of a packet.*/
- if (status & 0x20) lp->stats.rx_frame_errors++;
- if (status & 0x10) lp->stats.rx_over_errors++;
- if (status & 0x08) lp->stats.rx_crc_errors++;
- if (status & 0x04) lp->stats.rx_fifo_errors++;
- lp->rx_ring[entry].base &= 0x03ffffff;
- }
- else
- {
- /* Malloc up new buffer, compatible with net-2e. */
- short pkt_len = (lp->rx_ring[entry].msg_length & 0xfff)-4;
- struct sk_buff *skb;
-
- if(pkt_len<60)
- {
- printk("%s: Runt packet!\n",dev->name);
- lp->stats.rx_errors++;
- }
- else
- {
- skb = dev_alloc_skb(pkt_len+2);
- if (skb == NULL)
- {
- printk("%s: Memory squeeze, deferring packet.\n", dev->name);
- for (i=0; i < RX_RING_SIZE; i++)
- if (lp->rx_ring[(entry+i) & RX_RING_MOD_MASK].base < 0)
- break;
-
- if (i > RX_RING_SIZE -2)
- {
- lp->stats.rx_dropped++;
- lp->rx_ring[entry].base |= 0x80000000;
- lp->cur_rx++;
- }
- break;
- }
- skb->dev = dev;
- skb_reserve(skb,2); /* 16 byte align */
- skb_put(skb,pkt_len); /* Make room */
- eth_copy_and_sum(skb,
- (unsigned char *)(lp->rx_ring[entry].base & 0x00ffffff),
- pkt_len,0);
- skb->protocol=eth_type_trans(skb,dev);
- netif_rx(skb);
- lp->stats.rx_packets++;
- }
- }
- /* The docs say that the buffer length isn't touched, but Andrew Boyd
- of QNX reports that some revs of the 79C965 clear it. */
- lp->rx_ring[entry].buf_length = -PKT_BUF_SZ;
- lp->rx_ring[entry].base |= 0x80000000;
- entry = (++lp->cur_rx) & RX_RING_MOD_MASK;
- }
-
- /* We should check that at least two ring entries are free. If not,
- we should free one and mark stats->rx_dropped++. */
-
- return 0;
-}
-
-static int
-lance_close(struct device *dev)
-{
- int ioaddr = dev->base_addr;
- struct lance_private *lp = (struct lance_private *)dev->priv;
-
- dev->start = 0;
- dev->tbusy = 1;
-
- if (chip_table[lp->chip_version].flags & LANCE_HAS_MISSED_FRAME) {
- outw(112, ioaddr+LANCE_ADDR);
- lp->stats.rx_missed_errors = inw(ioaddr+LANCE_DATA);
- }
- outw(0, ioaddr+LANCE_ADDR);
-
- if (lance_debug > 1)
- printk("%s: Shutting down ethercard, status was %2.2x.\n",
- dev->name, inw(ioaddr+LANCE_DATA));
-
- /* We stop the LANCE here -- it occasionally polls
- memory if we don't. */
- outw(0x0004, ioaddr+LANCE_DATA);
-
- if (dev->dma != 4)
- disable_dma(dev->dma);
-
- free_irq(dev->irq);
-
- irq2dev_map[dev->irq] = 0;
-
- return 0;
-}
-
-static struct enet_statistics *
-lance_get_stats(struct device *dev)
-{
- struct lance_private *lp = (struct lance_private *)dev->priv;
- short ioaddr = dev->base_addr;
- short saved_addr;
- unsigned long flags;
-
- if (chip_table[lp->chip_version].flags & LANCE_HAS_MISSED_FRAME) {
- save_flags(flags);
- cli();
- saved_addr = inw(ioaddr+LANCE_ADDR);
- outw(112, ioaddr+LANCE_ADDR);
- lp->stats.rx_missed_errors = inw(ioaddr+LANCE_DATA);
- outw(saved_addr, ioaddr+LANCE_ADDR);
- restore_flags(flags);
- }
-
- return &lp->stats;
-}
-
-/* Set or clear the multicast filter for this adaptor.
- */
-
-static void set_multicast_list(struct device *dev)
-{
- short ioaddr = dev->base_addr;
-
- outw(0, ioaddr+LANCE_ADDR);
- outw(0x0004, ioaddr+LANCE_DATA); /* Temporarily stop the lance. */
-
- if (dev->flags&IFF_PROMISC) {
- /* Log any net taps. */
- printk("%s: Promiscuous mode enabled.\n", dev->name);
- outw(15, ioaddr+LANCE_ADDR);
- outw(0x8000, ioaddr+LANCE_DATA); /* Set promiscuous mode */
- } else {
- short multicast_table[4];
- int i;
- int num_addrs=dev->mc_count;
- if(dev->flags&IFF_ALLMULTI)
- num_addrs=1;
- /* FIXIT: We don't use the multicast table, but rely on upper-layer filtering. */
- memset(multicast_table, (num_addrs == 0) ? 0 : -1, sizeof(multicast_table));
- for (i = 0; i < 4; i++) {
- outw(8 + i, ioaddr+LANCE_ADDR);
- outw(multicast_table[i], ioaddr+LANCE_DATA);
- }
- outw(15, ioaddr+LANCE_ADDR);
- outw(0x0000, ioaddr+LANCE_DATA); /* Unset promiscuous mode */
- }
-
- lance_restart(dev, 0x0142, 0); /* Resume normal operation */
-
-}
-
-
-/*
- * Local variables:
- * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c lance.c"
- * c-indent-level: 4
- * tab-width: 4
- * End:
- */
diff --git a/i386/i386at/gpl/linux/net/ne.c b/i386/i386at/gpl/linux/net/ne.c
deleted file mode 100644
index 4da4efb7..00000000
--- a/i386/i386at/gpl/linux/net/ne.c
+++ /dev/null
@@ -1,733 +0,0 @@
-/* ne.c: A general non-shared-memory NS8390 ethernet driver for linux. */
-/*
- Written 1992-94 by Donald Becker.
-
- Copyright 1993 United States Government as represented by the
- Director, National Security Agency.
-
- This software may be used and distributed according to the terms
- of the GNU Public License, incorporated herein by reference.
-
- The author may be reached as becker@CESDIS.gsfc.nasa.gov, or C/O
- Center of Excellence in Space Data and Information Sciences
- Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
-
- This driver should work with many programmed-I/O 8390-based ethernet
- boards. Currently it supports the NE1000, NE2000, many clones,
- and some Cabletron products.
-
- Changelog:
-
- Paul Gortmaker : use ENISR_RDC to monitor Tx PIO uploads, made
- sanity checks and bad clone support optional.
- Paul Gortmaker : new reset code, reset card after probe at boot.
- Paul Gortmaker : multiple card support for module users.
- Paul Gortmaker : Support for PCI ne2k clones, similar to lance.c
-
-*/
-
-/* Routines for the NatSemi-based designs (NE[12]000). */
-
-static const char *version =
- "ne.c:v1.10 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
-
-
-#include <linux/module.h>
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/errno.h>
-#include <linux/pci.h>
-#include <linux/bios32.h>
-#include <asm/system.h>
-#include <asm/io.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include "8390.h"
-
-/* Some defines that people can play with if so inclined. */
-
-/* Do we support clones that don't adhere to 14,15 of the SAprom ? */
-#define SUPPORT_NE_BAD_CLONES
-
-/* Do we perform extra sanity checks on stuff ? */
-/* #define NE_SANITY_CHECK */
-
-/* Do we implement the read before write bugfix ? */
-/* #define NE_RW_BUGFIX */
-
-/* Do we have a non std. amount of memory? (in units of 256 byte pages) */
-/* #define PACKETBUF_MEMSIZE 0x40 */
-
-/* ---- No user-serviceable parts below ---- */
-
-/* A zero-terminated list of I/O addresses to be probed. */
-static unsigned int netcard_portlist[] =
-{ 0x300, 0x280, 0x320, 0x340, 0x360, 0};
-
-#ifdef SUPPORT_NE_BAD_CLONES
-/* A list of bad clones that we none-the-less recognize. */
-static struct { const char *name8, *name16; unsigned char SAprefix[4];}
-bad_clone_list[] = {
- {"DE100", "DE200", {0x00, 0xDE, 0x01,}},
- {"DE120", "DE220", {0x00, 0x80, 0xc8,}},
- {"DFI1000", "DFI2000", {'D', 'F', 'I',}}, /* Original, eh? */
- {"EtherNext UTP8", "EtherNext UTP16", {0x00, 0x00, 0x79}},
- {"NE1000","NE2000-invalid", {0x00, 0x00, 0xd8}}, /* Ancient real NE1000. */
- {"NN1000", "NN2000", {0x08, 0x03, 0x08}}, /* Outlaw no-name clone. */
- {"4-DIM8","4-DIM16", {0x00,0x00,0x4d,}}, /* Outlaw 4-Dimension cards. */
- {"Con-Intl_8", "Con-Intl_16", {0x00, 0x00, 0x24}}, /* Connect Int'nl */
- {0,}
-};
-#endif
-
-#define NE_BASE (dev->base_addr)
-#define NE_CMD 0x00
-#define NE_DATAPORT 0x10 /* NatSemi-defined port window offset. */
-#define NE_RESET 0x1f /* Issue a read to reset, a write to clear. */
-#define NE_IO_EXTENT 0x20
-
-#define NE1SM_START_PG 0x20 /* First page of TX buffer */
-#define NE1SM_STOP_PG 0x40 /* Last page +1 of RX ring */
-#define NESM_START_PG 0x40 /* First page of TX buffer */
-#define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */
-
-/* Non-zero only if the current card is a PCI with BIOS-set IRQ. */
-static unsigned char pci_irq_line = 0;
-
-int ne_probe(struct device *dev);
-static int ne_probe1(struct device *dev, int ioaddr);
-
-static int ne_open(struct device *dev);
-static int ne_close(struct device *dev);
-
-static void ne_reset_8390(struct device *dev);
-static void ne_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr,
- int ring_page);
-static void ne_block_input(struct device *dev, int count,
- struct sk_buff *skb, int ring_offset);
-static void ne_block_output(struct device *dev, const int count,
- const unsigned char *buf, const int start_page);
-
-
-/* Probe for various non-shared-memory ethercards.
-
- NEx000-clone boards have a Station Address PROM (SAPROM) in the packet
- buffer memory space. NE2000 clones have 0x57,0x57 in bytes 0x0e,0x0f of
- the SAPROM, while other supposed NE2000 clones must be detected by their
- SA prefix.
-
- Reading the SAPROM from a word-wide card with the 8390 set in byte-wide
- mode results in doubled values, which can be detected and compensated for.
-
- The probe is also responsible for initializing the card and filling
- in the 'dev' and 'ei_status' structures.
-
- We use the minimum memory size for some ethercard product lines, iff we can't
- distinguish models. You can increase the packet buffer size by setting
- PACKETBUF_MEMSIZE. Reported Cabletron packet buffer locations are:
- E1010 starts at 0x100 and ends at 0x2000.
- E1010-x starts at 0x100 and ends at 0x8000. ("-x" means "more memory")
- E2010 starts at 0x100 and ends at 0x4000.
- E2010-x starts at 0x100 and ends at 0xffff. */
-
-#ifdef HAVE_DEVLIST
-struct netdev_entry netcard_drv =
-{"ne", ne_probe1, NE_IO_EXTENT, netcard_portlist};
-#else
-
-/* Note that this probe only picks up one card at a time, even for multiple
- PCI ne2k cards. Use "ether=0,0,eth1" if you have a second PCI ne2k card.
- This keeps things consistent regardless of the bus type of the card. */
-
-int ne_probe(struct device *dev)
-{
- int i;
- int base_addr = dev ? dev->base_addr : 0;
-
- /* First check any supplied i/o locations. User knows best. <cough> */
- if (base_addr > 0x1ff) /* Check a single specified location. */
- return ne_probe1(dev, base_addr);
- else if (base_addr != 0) /* Don't probe at all. */
- return ENXIO;
-
- /* Then look for any installed PCI clones */
-#if defined(CONFIG_PCI)
- if (pcibios_present()) {
- int pci_index;
- for (pci_index = 0; pci_index < 8; pci_index++) {
- unsigned char pci_bus, pci_device_fn;
- unsigned int pci_ioaddr;
-
- /* Currently only Realtek are making PCI ne2k clones. */
- if (pcibios_find_device (PCI_VENDOR_ID_REALTEK,
- PCI_DEVICE_ID_REALTEK_8029, pci_index,
- &pci_bus, &pci_device_fn) != 0)
- break; /* OK, now try to probe for std. ISA card */
- pcibios_read_config_byte(pci_bus, pci_device_fn,
- PCI_INTERRUPT_LINE, &pci_irq_line);
- pcibios_read_config_dword(pci_bus, pci_device_fn,
- PCI_BASE_ADDRESS_0, &pci_ioaddr);
- /* Strip the I/O address out of the returned value */
- pci_ioaddr &= PCI_BASE_ADDRESS_IO_MASK;
- /* Avoid already found cards from previous ne_probe() calls */
- if (check_region(pci_ioaddr, NE_IO_EXTENT))
- continue;
- printk("ne.c: PCI BIOS reports ne2000 clone at i/o %#x, irq %d.\n",
- pci_ioaddr, pci_irq_line);
- if (ne_probe1(dev, pci_ioaddr) != 0) { /* Shouldn't happen. */
- printk(KERN_ERR "ne.c: Probe of PCI card at %#x failed.\n", pci_ioaddr);
- break; /* Hrmm, try to probe for ISA card... */
- }
- pci_irq_line = 0;
- return 0;
- }
- }
-#endif /* defined(CONFIG_PCI) */
-
- /* Last resort. The semi-risky ISA auto-probe. */
- for (i = 0; netcard_portlist[i]; i++) {
- int ioaddr = netcard_portlist[i];
- if (check_region(ioaddr, NE_IO_EXTENT))
- continue;
- if (ne_probe1(dev, ioaddr) == 0)
- return 0;
- }
-
- return ENODEV;
-}
-#endif
-
-static int ne_probe1(struct device *dev, int ioaddr)
-{
- int i;
- unsigned char SA_prom[32];
- int wordlength = 2;
- const char *name = NULL;
- int start_page, stop_page;
- int neX000, ctron;
- int reg0 = inb_p(ioaddr);
- static unsigned version_printed = 0;
-
- if (reg0 == 0xFF)
- return ENODEV;
-
- /* Do a preliminary verification that we have a 8390. */
- { int regd;
- outb_p(E8390_NODMA+E8390_PAGE1+E8390_STOP, ioaddr + E8390_CMD);
- regd = inb_p(ioaddr + 0x0d);
- outb_p(0xff, ioaddr + 0x0d);
- outb_p(E8390_NODMA+E8390_PAGE0, ioaddr + E8390_CMD);
- inb_p(ioaddr + EN0_COUNTER0); /* Clear the counter by reading. */
- if (inb_p(ioaddr + EN0_COUNTER0) != 0) {
- outb_p(reg0, ioaddr);
- outb_p(regd, ioaddr + 0x0d); /* Restore the old values. */
- return ENODEV;
- }
- }
-
- if (ei_debug && version_printed++ == 0)
- printk(version);
-
- printk("NE*000 ethercard probe at %#3x:", ioaddr);
-
- /* Reset card. Who knows what dain-bramaged state it was left in. */
- { unsigned long reset_start_time = jiffies;
-
- /* DON'T change these to inb_p/outb_p or reset will fail on clones. */
- outb(inb(ioaddr + NE_RESET), ioaddr + NE_RESET);
-
- while ((inb_p(ioaddr + EN0_ISR) & ENISR_RESET) == 0)
- if (jiffies - reset_start_time > 2*HZ/100) {
- printk(" not found (no reset ack).\n");
- return ENODEV;
- }
-
- outb_p(0xff, ioaddr + EN0_ISR); /* Ack all intr. */
- }
-
- /* Read the 16 bytes of station address PROM.
- We must first initialize registers, similar to NS8390_init(eifdev, 0).
- We can't reliably read the SAPROM address without this.
- (I learned the hard way!). */
- {
- struct {unsigned char value, offset; } program_seq[] = {
- {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/
- {0x48, EN0_DCFG}, /* Set byte-wide (0x48) access. */
- {0x00, EN0_RCNTLO}, /* Clear the count regs. */
- {0x00, EN0_RCNTHI},
- {0x00, EN0_IMR}, /* Mask completion irq. */
- {0xFF, EN0_ISR},
- {E8390_RXOFF, EN0_RXCR}, /* 0x20 Set to monitor */
- {E8390_TXOFF, EN0_TXCR}, /* 0x02 and loopback mode. */
- {32, EN0_RCNTLO},
- {0x00, EN0_RCNTHI},
- {0x00, EN0_RSARLO}, /* DMA starting at 0x0000. */
- {0x00, EN0_RSARHI},
- {E8390_RREAD+E8390_START, E8390_CMD},
- };
- for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++)
- outb_p(program_seq[i].value, ioaddr + program_seq[i].offset);
-
- }
- for(i = 0; i < 32 /*sizeof(SA_prom)*/; i+=2) {
- SA_prom[i] = inb(ioaddr + NE_DATAPORT);
- SA_prom[i+1] = inb(ioaddr + NE_DATAPORT);
- if (SA_prom[i] != SA_prom[i+1])
- wordlength = 1;
- }
-
- if (wordlength == 2) {
- /* We must set the 8390 for word mode. */
- outb_p(0x49, ioaddr + EN0_DCFG);
- /* We used to reset the ethercard here, but it doesn't seem
- to be necessary. */
- /* Un-double the SA_prom values. */
- for (i = 0; i < 16; i++)
- SA_prom[i] = SA_prom[i+i];
- start_page = NESM_START_PG;
- stop_page = NESM_STOP_PG;
- } else {
- start_page = NE1SM_START_PG;
- stop_page = NE1SM_STOP_PG;
- }
-
- neX000 = (SA_prom[14] == 0x57 && SA_prom[15] == 0x57);
- ctron = (SA_prom[0] == 0x00 && SA_prom[1] == 0x00 && SA_prom[2] == 0x1d);
-
- /* Set up the rest of the parameters. */
- if (neX000) {
- name = (wordlength == 2) ? "NE2000" : "NE1000";
- } else if (ctron) {
- name = (wordlength == 2) ? "Ctron-8" : "Ctron-16";
- start_page = 0x01;
- stop_page = (wordlength == 2) ? 0x40 : 0x20;
- } else {
-#ifdef SUPPORT_NE_BAD_CLONES
- /* Ack! Well, there might be a *bad* NE*000 clone there.
- Check for total bogus addresses. */
- for (i = 0; bad_clone_list[i].name8; i++) {
- if (SA_prom[0] == bad_clone_list[i].SAprefix[0] &&
- SA_prom[1] == bad_clone_list[i].SAprefix[1] &&
- SA_prom[2] == bad_clone_list[i].SAprefix[2]) {
- if (wordlength == 2) {
- name = bad_clone_list[i].name16;
- } else {
- name = bad_clone_list[i].name8;
- }
- break;
- }
- }
- if (bad_clone_list[i].name8 == NULL) {
- printk(" not found (invalid signature %2.2x %2.2x).\n",
- SA_prom[14], SA_prom[15]);
- return ENXIO;
- }
-#else
- printk(" not found.\n");
- return ENXIO;
-#endif
-
- }
-
- /* We should have a "dev" from Space.c or the static module table. */
- if (dev == NULL) {
- printk("ne.c: Passed a NULL device.\n");
- dev = init_etherdev(0, 0);
- }
-
- if (pci_irq_line) {
- dev->irq = pci_irq_line;
- }
-
- if (dev->irq < 2) {
- autoirq_setup(0);
- outb_p(0x50, ioaddr + EN0_IMR); /* Enable one interrupt. */
- outb_p(0x00, ioaddr + EN0_RCNTLO);
- outb_p(0x00, ioaddr + EN0_RCNTHI);
- outb_p(E8390_RREAD+E8390_START, ioaddr); /* Trigger it... */
- outb_p(0x00, ioaddr + EN0_IMR); /* Mask it again. */
- dev->irq = autoirq_report(0);
- if (ei_debug > 2)
- printk(" autoirq is %d\n", dev->irq);
- } else if (dev->irq == 2)
- /* Fixup for users that don't know that IRQ 2 is really IRQ 9,
- or don't know which one to set. */
- dev->irq = 9;
-
- if (! dev->irq) {
- printk(" failed to detect IRQ line.\n");
- return EAGAIN;
- }
-
- /* Snarf the interrupt now. There's no point in waiting since we cannot
- share and the board will usually be enabled. */
- {
- int irqval = request_irq(dev->irq, ei_interrupt, 0, name);
- if (irqval) {
- printk (" unable to get IRQ %d (irqval=%d).\n", dev->irq, irqval);
- return EAGAIN;
- }
- }
-
- dev->base_addr = ioaddr;
-
- /* Allocate dev->priv and fill in 8390 specific dev fields. */
- if (ethdev_init(dev)) {
- printk (" unable to get memory for dev->priv.\n");
- free_irq(dev->irq);
- return -ENOMEM;
- }
-
- request_region(ioaddr, NE_IO_EXTENT, name);
-
- for(i = 0; i < ETHER_ADDR_LEN; i++) {
- printk(" %2.2x", SA_prom[i]);
- dev->dev_addr[i] = SA_prom[i];
- }
-
- printk("\n%s: %s found at %#x, using IRQ %d.\n",
- dev->name, name, ioaddr, dev->irq);
-
- ei_status.name = name;
- ei_status.tx_start_page = start_page;
- ei_status.stop_page = stop_page;
- ei_status.word16 = (wordlength == 2);
-
- ei_status.rx_start_page = start_page + TX_PAGES;
-#ifdef PACKETBUF_MEMSIZE
- /* Allow the packet buffer size to be overridden by know-it-alls. */
- ei_status.stop_page = ei_status.tx_start_page + PACKETBUF_MEMSIZE;
-#endif
-
- ei_status.reset_8390 = &ne_reset_8390;
- ei_status.block_input = &ne_block_input;
- ei_status.block_output = &ne_block_output;
- ei_status.get_8390_hdr = &ne_get_8390_hdr;
- dev->open = &ne_open;
- dev->stop = &ne_close;
- NS8390_init(dev, 0);
- return 0;
-}
-
-static int
-ne_open(struct device *dev)
-{
- ei_open(dev);
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-static int
-ne_close(struct device *dev)
-{
- if (ei_debug > 1)
- printk("%s: Shutting down ethercard.\n", dev->name);
- ei_close(dev);
- MOD_DEC_USE_COUNT;
- return 0;
-}
-
-/* Hard reset the card. This used to pause for the same period that a
- 8390 reset command required, but that shouldn't be necessary. */
-static void
-ne_reset_8390(struct device *dev)
-{
- unsigned long reset_start_time = jiffies;
-
- if (ei_debug > 1) printk("resetting the 8390 t=%ld...", jiffies);
-
- /* DON'T change these to inb_p/outb_p or reset will fail on clones. */
- outb(inb(NE_BASE + NE_RESET), NE_BASE + NE_RESET);
-
- ei_status.txing = 0;
- ei_status.dmaing = 0;
-
- /* This check _should_not_ be necessary, omit eventually. */
- while ((inb_p(NE_BASE+EN0_ISR) & ENISR_RESET) == 0)
- if (jiffies - reset_start_time > 2*HZ/100) {
- printk("%s: ne_reset_8390() did not complete.\n", dev->name);
- break;
- }
- outb_p(ENISR_RESET, NE_BASE + EN0_ISR); /* Ack intr. */
-}
-
-/* Grab the 8390 specific header. Similar to the block_input routine, but
- we don't need to be concerned with ring wrap as the header will be at
- the start of a page, so we optimize accordingly. */
-
-static void
-ne_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
-{
-
- int nic_base = dev->base_addr;
-
- /* This *shouldn't* happen. If it does, it's the last thing you'll see */
- if (ei_status.dmaing) {
- printk("%s: DMAing conflict in ne_get_8390_hdr "
- "[DMAstat:%d][irqlock:%d][intr:%d].\n",
- dev->name, ei_status.dmaing, ei_status.irqlock,
- dev->interrupt);
- return;
- }
-
- ei_status.dmaing |= 0x01;
- outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
- outb_p(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO);
- outb_p(0, nic_base + EN0_RCNTHI);
- outb_p(0, nic_base + EN0_RSARLO); /* On page boundary */
- outb_p(ring_page, nic_base + EN0_RSARHI);
- outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD);
-
- if (ei_status.word16)
- insw(NE_BASE + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)>>1);
- else
- insb(NE_BASE + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr));
-
- outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */
- ei_status.dmaing &= ~0x01;
-}
-
-/* Block input and output, similar to the Crynwr packet driver. If you
- are porting to a new ethercard, look at the packet driver source for hints.
- The NEx000 doesn't share the on-board packet memory -- you have to put
- the packet out through the "remote DMA" dataport using outb. */
-
-static void
-ne_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset)
-{
-#ifdef NE_SANITY_CHECK
- int xfer_count = count;
-#endif
- int nic_base = dev->base_addr;
- char *buf = skb->data;
-
- /* This *shouldn't* happen. If it does, it's the last thing you'll see */
- if (ei_status.dmaing) {
- printk("%s: DMAing conflict in ne_block_input "
- "[DMAstat:%d][irqlock:%d][intr:%d].\n",
- dev->name, ei_status.dmaing, ei_status.irqlock,
- dev->interrupt);
- return;
- }
- ei_status.dmaing |= 0x01;
- outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
- outb_p(count & 0xff, nic_base + EN0_RCNTLO);
- outb_p(count >> 8, nic_base + EN0_RCNTHI);
- outb_p(ring_offset & 0xff, nic_base + EN0_RSARLO);
- outb_p(ring_offset >> 8, nic_base + EN0_RSARHI);
- outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD);
- if (ei_status.word16) {
- insw(NE_BASE + NE_DATAPORT,buf,count>>1);
- if (count & 0x01) {
- buf[count-1] = inb(NE_BASE + NE_DATAPORT);
-#ifdef NE_SANITY_CHECK
- xfer_count++;
-#endif
- }
- } else {
- insb(NE_BASE + NE_DATAPORT, buf, count);
- }
-
-#ifdef NE_SANITY_CHECK
- /* This was for the ALPHA version only, but enough people have
- been encountering problems so it is still here. If you see
- this message you either 1) have a slightly incompatible clone
- or 2) have noise/speed problems with your bus. */
- if (ei_debug > 1) { /* DMA termination address check... */
- int addr, tries = 20;
- do {
- /* DON'T check for 'inb_p(EN0_ISR) & ENISR_RDC' here
- -- it's broken for Rx on some cards! */
- int high = inb_p(nic_base + EN0_RSARHI);
- int low = inb_p(nic_base + EN0_RSARLO);
- addr = (high << 8) + low;
- if (((ring_offset + xfer_count) & 0xff) == low)
- break;
- } while (--tries > 0);
- if (tries <= 0)
- printk("%s: RX transfer address mismatch,"
- "%#4.4x (expected) vs. %#4.4x (actual).\n",
- dev->name, ring_offset + xfer_count, addr);
- }
-#endif
- outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */
- ei_status.dmaing &= ~0x01;
-}
-
-static void
-ne_block_output(struct device *dev, int count,
- const unsigned char *buf, const int start_page)
-{
- int nic_base = NE_BASE;
- unsigned long dma_start;
-#ifdef NE_SANITY_CHECK
- int retries = 0;
-#endif
-
- /* Round the count up for word writes. Do we need to do this?
- What effect will an odd byte count have on the 8390?
- I should check someday. */
- if (ei_status.word16 && (count & 0x01))
- count++;
-
- /* This *shouldn't* happen. If it does, it's the last thing you'll see */
- if (ei_status.dmaing) {
- printk("%s: DMAing conflict in ne_block_output."
- "[DMAstat:%d][irqlock:%d][intr:%d]\n",
- dev->name, ei_status.dmaing, ei_status.irqlock,
- dev->interrupt);
- return;
- }
- ei_status.dmaing |= 0x01;
- /* We should already be in page 0, but to be safe... */
- outb_p(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD);
-
-#ifdef NE_SANITY_CHECK
- retry:
-#endif
-
-#ifdef NE8390_RW_BUGFIX
- /* Handle the read-before-write bug the same way as the
- Crynwr packet driver -- the NatSemi method doesn't work.
- Actually this doesn't always work either, but if you have
- problems with your NEx000 this is better than nothing! */
- outb_p(0x42, nic_base + EN0_RCNTLO);
- outb_p(0x00, nic_base + EN0_RCNTHI);
- outb_p(0x42, nic_base + EN0_RSARLO);
- outb_p(0x00, nic_base + EN0_RSARHI);
- outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD);
- /* Make certain that the dummy read has occurred. */
- SLOW_DOWN_IO;
- SLOW_DOWN_IO;
- SLOW_DOWN_IO;
-#endif
-
- outb_p(ENISR_RDC, nic_base + EN0_ISR);
-
- /* Now the normal output. */
- outb_p(count & 0xff, nic_base + EN0_RCNTLO);
- outb_p(count >> 8, nic_base + EN0_RCNTHI);
- outb_p(0x00, nic_base + EN0_RSARLO);
- outb_p(start_page, nic_base + EN0_RSARHI);
-
- outb_p(E8390_RWRITE+E8390_START, nic_base + NE_CMD);
- if (ei_status.word16) {
- outsw(NE_BASE + NE_DATAPORT, buf, count>>1);
- } else {
- outsb(NE_BASE + NE_DATAPORT, buf, count);
- }
-
- dma_start = jiffies;
-
-#ifdef NE_SANITY_CHECK
- /* This was for the ALPHA version only, but enough people have
- been encountering problems so it is still here. */
- if (ei_debug > 1) { /* DMA termination address check... */
- int addr, tries = 20;
- do {
- int high = inb_p(nic_base + EN0_RSARHI);
- int low = inb_p(nic_base + EN0_RSARLO);
- addr = (high << 8) + low;
- if ((start_page << 8) + count == addr)
- break;
- } while (--tries > 0);
- if (tries <= 0) {
- printk("%s: Tx packet transfer address mismatch,"
- "%#4.4x (expected) vs. %#4.4x (actual).\n",
- dev->name, (start_page << 8) + count, addr);
- if (retries++ == 0)
- goto retry;
- }
- }
-#endif
-
- while ((inb_p(nic_base + EN0_ISR) & ENISR_RDC) == 0)
- if (jiffies - dma_start > 2*HZ/100) { /* 20ms */
- printk("%s: timeout waiting for Tx RDC.\n", dev->name);
- ne_reset_8390(dev);
- NS8390_init(dev,1);
- break;
- }
-
- outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */
- ei_status.dmaing &= ~0x01;
- return;
-}
-
-
-#ifdef MODULE
-#define MAX_NE_CARDS 4 /* Max number of NE cards per module */
-#define NAMELEN 8 /* # of chars for storing dev->name */
-static char namelist[NAMELEN * MAX_NE_CARDS] = { 0, };
-static struct device dev_ne[MAX_NE_CARDS] = {
- {
- NULL, /* assign a chunk of namelist[] below */
- 0, 0, 0, 0,
- 0, 0,
- 0, 0, 0, NULL, NULL
- },
-};
-
-static int io[MAX_NE_CARDS] = { 0, };
-static int irq[MAX_NE_CARDS] = { 0, };
-
-/* This is set up so that no autoprobe takes place. We can't guarantee
-that the ne2k probe is the last 8390 based probe to take place (as it
-is at boot) and so the probe will get confused by any other 8390 cards.
-ISA device autoprobes on a running machine are not recommended anyway. */
-
-int
-init_module(void)
-{
- int this_dev, found = 0;
-
- for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
- struct device *dev = &dev_ne[this_dev];
- dev->name = namelist+(NAMELEN*this_dev);
- dev->irq = irq[this_dev];
- dev->base_addr = io[this_dev];
- dev->init = ne_probe;
- if (io[this_dev] == 0) {
- if (this_dev != 0) break; /* only complain once */
- printk(KERN_NOTICE "ne.c: Module autoprobing not allowed. Append \"io=0xNNN\" value(s).\n");
- return -EPERM;
- }
- if (register_netdev(dev) != 0) {
- printk(KERN_WARNING "ne.c: No NE*000 card found (i/o = 0x%x).\n", io[this_dev]);
- if (found != 0) return 0; /* Got at least one. */
- return -ENXIO;
- }
- found++;
- }
-
- return 0;
-}
-
-void
-cleanup_module(void)
-{
- int this_dev;
-
- for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
- struct device *dev = &dev_ne[this_dev];
- if (dev->priv != NULL) {
- kfree(dev->priv);
- dev->priv = NULL;
- free_irq(dev->irq);
- irq2dev_map[dev->irq] = NULL;
- release_region(dev->base_addr, NE_IO_EXTENT);
- unregister_netdev(dev);
- }
- }
-}
-#endif /* MODULE */
-
-/*
- * Local variables:
- * compile-command: "gcc -DKERNEL -Wall -O6 -fomit-frame-pointer -I/usr/src/linux/net/tcp -c ne.c"
- * version-control: t
- * kept-new-versions: 5
- * End:
- */
diff --git a/i386/i386at/gpl/linux/net/net_init.c b/i386/i386at/gpl/linux/net/net_init.c
deleted file mode 100644
index cedee941..00000000
--- a/i386/i386at/gpl/linux/net/net_init.c
+++ /dev/null
@@ -1,380 +0,0 @@
-/* netdrv_init.c: Initialization for network devices. */
-/*
- Written 1993,1994,1995 by Donald Becker.
-
- The author may be reached as becker@cesdis.gsfc.nasa.gov or
- C/O Center of Excellence in Space Data and Information Sciences
- Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
-
- This file contains the initialization for the "pl14+" style ethernet
- drivers. It should eventually replace most of drivers/net/Space.c.
- It's primary advantage is that it's able to allocate low-memory buffers.
- A secondary advantage is that the dangerous NE*000 netcards can reserve
- their I/O port region before the SCSI probes start.
-
- Modifications/additions by Bjorn Ekwall <bj0rn@blox.se>:
- ethdev_index[MAX_ETH_CARDS]
- register_netdev() / unregister_netdev()
-
- Modifications by Wolfgang Walter
- Use dev_close cleanly so we always shut things down tidily.
-
- Changed 29/10/95, Alan Cox to pass sockaddr's around for mac addresses.
-*/
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/fs.h>
-#include <linux/malloc.h>
-#include <linux/if_ether.h>
-#include <linux/if_arp.h>
-#include <linux/string.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/trdevice.h>
-#ifdef CONFIG_NET_ALIAS
-#include <linux/net_alias.h>
-#endif
-
-/* The network devices currently exist only in the socket namespace, so these
- entries are unused. The only ones that make sense are
- open start the ethercard
- close stop the ethercard
- ioctl To get statistics, perhaps set the interface port (AUI, BNC, etc.)
- One can also imagine getting raw packets using
- read & write
- but this is probably better handled by a raw packet socket.
-
- Given that almost all of these functions are handled in the current
- socket-based scheme, putting ethercard devices in /dev/ seems pointless.
-
- [Removed all support for /dev network devices. When someone adds
- streams then by magic we get them, but otherwise they are un-needed
- and a space waste]
-*/
-
-/* The list of used and available "eth" slots (for "eth0", "eth1", etc.) */
-#define MAX_ETH_CARDS 16 /* same as the number if irq's in irq2dev[] */
-static struct device *ethdev_index[MAX_ETH_CARDS];
-
-/* Fill in the fields of the device structure with ethernet-generic values.
-
- If no device structure is passed, a new one is constructed, complete with
- a SIZEOF_PRIVATE private data area.
-
- If an empty string area is passed as dev->name, or a new structure is made,
- a new name string is constructed. The passed string area should be 8 bytes
- long.
- */
-
-struct device *
-init_etherdev(struct device *dev, int sizeof_priv)
-{
- int new_device = 0;
- int i;
-
- /* Use an existing correctly named device in Space.c:dev_base. */
- if (dev == NULL) {
- int alloc_size = sizeof(struct device) + sizeof("eth%d ")
- + sizeof_priv + 3;
- struct device *cur_dev;
- char pname[8]; /* Putative name for the device. */
-
- for (i = 0; i < MAX_ETH_CARDS; ++i)
- if (ethdev_index[i] == NULL) {
- sprintf(pname, "eth%d", i);
- for (cur_dev = dev_base; cur_dev; cur_dev = cur_dev->next)
- if (strcmp(pname, cur_dev->name) == 0) {
- dev = cur_dev;
- dev->init = NULL;
- sizeof_priv = (sizeof_priv + 3) & ~3;
- dev->priv = sizeof_priv
- ? kmalloc(sizeof_priv, GFP_KERNEL)
- : NULL;
- if (dev->priv) memset(dev->priv, 0, sizeof_priv);
- goto found;
- }
- }
-
- alloc_size &= ~3; /* Round to dword boundary. */
-
- dev = (struct device *)kmalloc(alloc_size, GFP_KERNEL);
- memset(dev, 0, alloc_size);
- if (sizeof_priv)
- dev->priv = (void *) (dev + 1);
- dev->name = sizeof_priv + (char *)(dev + 1);
- new_device = 1;
- }
-
- found: /* From the double loop above. */
-
- if (dev->name &&
- ((dev->name[0] == '\0') || (dev->name[0] == ' '))) {
- for (i = 0; i < MAX_ETH_CARDS; ++i)
- if (ethdev_index[i] == NULL) {
- sprintf(dev->name, "eth%d", i);
- ethdev_index[i] = dev;
- break;
- }
- }
-
- ether_setup(dev); /* Hmmm, should this be called here? */
-
- if (new_device) {
- /* Append the device to the device queue. */
- struct device **old_devp = &dev_base;
- while ((*old_devp)->next)
- old_devp = & (*old_devp)->next;
- (*old_devp)->next = dev;
- dev->next = 0;
- }
- return dev;
-}
-
-
-static int eth_mac_addr(struct device *dev, void *p)
-{
- struct sockaddr *addr=p;
- if(dev->start)
- return -EBUSY;
- memcpy(dev->dev_addr, addr->sa_data,dev->addr_len);
- return 0;
-}
-
-void ether_setup(struct device *dev)
-{
- int i;
-
- /* Fill in the fields of the device structure with ethernet-generic values.
- This should be in a common file instead of per-driver. */
- for (i = 0; i < DEV_NUMBUFFS; i++)
- skb_queue_head_init(&dev->buffs[i]);
-
- /* register boot-defined "eth" devices */
- if (dev->name && (strncmp(dev->name, "eth", 3) == 0)) {
- i = simple_strtoul(dev->name + 3, NULL, 0);
- if (ethdev_index[i] == NULL) {
- ethdev_index[i] = dev;
- }
- else if (dev != ethdev_index[i]) {
- /* Really shouldn't happen! */
-#ifdef MACH
- panic ("ether_setup: Ouch! Someone else took %s, i = %d\n",
- dev->name, i);
-#else
- printk("ether_setup: Ouch! Someone else took %s, i = %d\n",
- dev->name, i);
-#endif
- }
- }
-
-#ifndef MACH
- dev->hard_header = eth_header;
- dev->rebuild_header = eth_rebuild_header;
- dev->set_mac_address = eth_mac_addr;
- dev->header_cache_bind = eth_header_cache_bind;
- dev->header_cache_update= eth_header_cache_update;
-#endif
-
- dev->type = ARPHRD_ETHER;
- dev->hard_header_len = ETH_HLEN;
- dev->mtu = 1500; /* eth_mtu */
- dev->addr_len = ETH_ALEN;
- dev->tx_queue_len = 100; /* Ethernet wants good queues */
-
- memset(dev->broadcast,0xFF, ETH_ALEN);
-
- /* New-style flags. */
- dev->flags = IFF_BROADCAST|IFF_MULTICAST;
- dev->family = AF_INET;
- dev->pa_addr = 0;
- dev->pa_brdaddr = 0;
- dev->pa_mask = 0;
- dev->pa_alen = 4;
-}
-
-#ifdef CONFIG_TR
-
-void tr_setup(struct device *dev)
-{
- int i;
- /* Fill in the fields of the device structure with ethernet-generic values.
- This should be in a common file instead of per-driver. */
- for (i = 0; i < DEV_NUMBUFFS; i++)
- skb_queue_head_init(&dev->buffs[i]);
-
- dev->hard_header = tr_header;
- dev->rebuild_header = tr_rebuild_header;
-
- dev->type = ARPHRD_IEEE802;
- dev->hard_header_len = TR_HLEN;
- dev->mtu = 2000; /* bug in fragmenter...*/
- dev->addr_len = TR_ALEN;
- dev->tx_queue_len = 100; /* Long queues on tr */
-
- memset(dev->broadcast,0xFF, TR_ALEN);
-
- /* New-style flags. */
- dev->flags = IFF_BROADCAST;
- dev->family = AF_INET;
- dev->pa_addr = 0;
- dev->pa_brdaddr = 0;
- dev->pa_mask = 0;
- dev->pa_alen = 4;
-}
-
-#endif
-
-int ether_config(struct device *dev, struct ifmap *map)
-{
- if (map->mem_start != (u_long)(-1))
- dev->mem_start = map->mem_start;
- if (map->mem_end != (u_long)(-1))
- dev->mem_end = map->mem_end;
- if (map->base_addr != (u_short)(-1))
- dev->base_addr = map->base_addr;
- if (map->irq != (u_char)(-1))
- dev->irq = map->irq;
- if (map->dma != (u_char)(-1))
- dev->dma = map->dma;
- if (map->port != (u_char)(-1))
- dev->if_port = map->port;
- return 0;
-}
-
-int register_netdev(struct device *dev)
-{
- struct device *d = dev_base;
- unsigned long flags;
- int i=MAX_ETH_CARDS;
-
- save_flags(flags);
- cli();
-
- if (dev && dev->init) {
- if (dev->name &&
- ((dev->name[0] == '\0') || (dev->name[0] == ' '))) {
- for (i = 0; i < MAX_ETH_CARDS; ++i)
- if (ethdev_index[i] == NULL) {
- sprintf(dev->name, "eth%d", i);
- printk("loading device '%s'...\n", dev->name);
- ethdev_index[i] = dev;
- break;
- }
- }
-
- sti(); /* device probes assume interrupts enabled */
- if (dev->init(dev) != 0) {
- if (i < MAX_ETH_CARDS) ethdev_index[i] = NULL;
- restore_flags(flags);
- return -EIO;
- }
- cli();
-
- /* Add device to end of chain */
- if (dev_base) {
- while (d->next)
- d = d->next;
- d->next = dev;
- }
- else
- dev_base = dev;
- dev->next = NULL;
- }
- restore_flags(flags);
- return 0;
-}
-
-void unregister_netdev(struct device *dev)
-{
- struct device *d = dev_base;
- unsigned long flags;
- int i;
-
- save_flags(flags);
- cli();
-
- if (dev == NULL)
- {
- printk("was NULL\n");
- restore_flags(flags);
- return;
- }
- /* else */
- if (dev->start)
- printk("ERROR '%s' busy and not MOD_IN_USE.\n", dev->name);
-
- /*
- * must jump over main_device+aliases
- * avoid alias devices unregistration so that only
- * net_alias module manages them
- */
-#ifdef CONFIG_NET_ALIAS
- if (dev_base == dev)
- dev_base = net_alias_nextdev(dev);
- else
- {
- while(d && (net_alias_nextdev(d) != dev)) /* skip aliases */
- d = net_alias_nextdev(d);
-
- if (d && (net_alias_nextdev(d) == dev))
- {
- /*
- * Critical: Bypass by consider devices as blocks (maindev+aliases)
- */
- net_alias_nextdev_set(d, net_alias_nextdev(dev));
- }
-#else
- if (dev_base == dev)
- dev_base = dev->next;
- else
- {
- while (d && (d->next != dev))
- d = d->next;
-
- if (d && (d->next == dev))
- {
- d->next = dev->next;
- }
-#endif
- else
- {
- printk("unregister_netdev: '%s' not found\n", dev->name);
- restore_flags(flags);
- return;
- }
- }
- for (i = 0; i < MAX_ETH_CARDS; ++i)
- {
- if (ethdev_index[i] == dev)
- {
- ethdev_index[i] = NULL;
- break;
- }
- }
-
- restore_flags(flags);
-
- /*
- * You can i.e use a interfaces in a route though it is not up.
- * We call close_dev (which is changed: it will down a device even if
- * dev->flags==0 (but it will not call dev->stop if IFF_UP
- * is not set).
- * This will call notifier_call_chain(&netdev_chain, NETDEV_DOWN, dev),
- * dev_mc_discard(dev), ....
- */
-
- dev_close(dev);
-}
-
-
-/*
- * Local variables:
- * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c net_init.c"
- * version-control: t
- * kept-new-versions: 5
- * tab-width: 4
- * End:
- */
diff --git a/i386/i386at/gpl/linux/net/ni52.c b/i386/i386at/gpl/linux/net/ni52.c
deleted file mode 100644
index 13d12359..00000000
--- a/i386/i386at/gpl/linux/net/ni52.c
+++ /dev/null
@@ -1,1110 +0,0 @@
-/*
- * net-3-driver for the NI5210 card (i82586 Ethernet chip)
- *
- * This is an extension to the Linux operating system, and is covered by the
- * same Gnu Public License that covers that work.
- *
- * Alphacode 0.62 (95/01/19) for Linux 1.1.82 (or later)
- * Copyrights (c) 1994,1995 by M.Hipp (Michael.Hipp@student.uni-tuebingen.de)
- * [feel free to mail ....]
- *
- * CAN YOU PLEASE REPORT ME YOUR PERFORMANCE EXPERIENCES !!.
- *
- * If you find a bug, please report me:
- * The kernel panic output and any kmsg from the ni52 driver
- * the ni5210-driver-version and the linux-kernel version
- * how many shared memory (memsize) on the netcard,
- * bootprom: yes/no, base_addr, mem_start
- * maybe the ni5210-card revision and the i82586 version
- *
- * autoprobe for: base_addr: 0x300,0x280,0x360,0x320,0x340
- * mem_start: 0xc8000,0xd0000,0xd4000,0xd8000 (8K and 16K)
- *
- * sources:
- * skeleton.c from Donald Becker
- *
- * I have also done a look in the following sources: (mail me if you need them)
- * crynwr-packet-driver by Russ Nelson
- * Garret A. Wollman's (fourth) i82586-driver for BSD
- * (before getting an i82596 (yes 596 not 586) manual, the existing drivers helped
- * me a lot to understand this tricky chip.)
- *
- * Known Problems:
- * The internal sysbus seems to be slow. So we often lose packets because of
- * overruns while receiving from a fast remote host.
- * This can slow down TCP connections. Maybe the newer ni5210 cards are better.
- *
- * IMPORTANT NOTE:
- * On fast networks, it's a (very) good idea to have 16K shared memory. With
- * 8K, we can store only 4 receive frames, so it can (easily) happen that a remote
- * machine 'overruns' our system.
- *
- * Known i82586 bugs (I'm sure, there are many more!):
- * Running the NOP-mode, the i82586 sometimes seems to forget to report
- * every xmit-interrupt until we restart the CU.
- * Another MAJOR bug is, that the RU sometimes seems to ignore the EL-Bit
- * in the RBD-Struct which indicates an end of the RBD queue.
- * Instead, the RU fetches another (randomly selected and
- * usually used) RBD and begins to fill it. (Maybe, this happens only if
- * the last buffer from the previous RFD fits exact into the queue and
- * the next RFD can't fetch an initial RBD. Anyone knows more? )
- */
-
-/*
- * 18.Nov.95: Mcast changes (AC).
- *
- * 19.Jan.95: verified (MH)
- *
- * 19.Sep.94: Added Multicast support (not tested yet) (MH)
- *
- * 18.Sep.94: Workaround for 'EL-Bug'. Removed flexible RBD-handling.
- * Now, every RFD has exact one RBD. (MH)
- *
- * 14.Sep.94: added promiscuous mode, a few cleanups (MH)
- *
- * 19.Aug.94: changed request_irq() parameter (MH)
- *
- * 20.July.94: removed cleanup bugs, removed a 16K-mem-probe-bug (MH)
- *
- * 19.July.94: lotsa cleanups .. (MH)
- *
- * 17.July.94: some patches ... verified to run with 1.1.29 (MH)
- *
- * 4.July.94: patches for Linux 1.1.24 (MH)
- *
- * 26.March.94: patches for Linux 1.0 and iomem-auto-probe (MH)
- *
- * 30.Sep.93: Added nop-chain .. driver now runs with only one Xmit-Buff, too (MH)
- *
- * < 30.Sep.93: first versions
- */
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/malloc.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <asm/bitops.h>
-#include <asm/io.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-
-#include "ni52.h"
-
-#define DEBUG /* debug on */
-#define SYSBUSVAL 1 /* 8 Bit */
-
-#define ni_attn586() {outb(0,dev->base_addr+NI52_ATTENTION);}
-#define ni_reset586() {outb(0,dev->base_addr+NI52_RESET);}
-
-#define make32(ptr16) (p->memtop + (short) (ptr16) )
-#define make24(ptr32) ((char *) (ptr32) - p->base)
-#define make16(ptr32) ((unsigned short) ((unsigned long) (ptr32) - (unsigned long) p->memtop ))
-
-/******************* how to calculate the buffers *****************************
-
- * IMPORTANT NOTE: if you configure only one NUM_XMIT_BUFFS, the driver works
- * --------------- in a different (more stable?) mode. Only in this mode it's
- * possible to configure the driver with 'NO_NOPCOMMANDS'
-
-sizeof(scp)=12; sizeof(scb)=16; sizeof(iscp)=8;
-sizeof(scp)+sizeof(iscp)+sizeof(scb) = 36 = INIT
-sizeof(rfd) = 24; sizeof(rbd) = 12;
-sizeof(tbd) = 8; sizeof(transmit_cmd) = 16;
-sizeof(nop_cmd) = 8;
-
- * if you don't know the driver, better do not change this values: */
-
-#define RECV_BUFF_SIZE 1524 /* slightly oversized */
-#define XMIT_BUFF_SIZE 1524 /* slightly oversized */
-#define NUM_XMIT_BUFFS 1 /* config for both, 8K and 16K shmem */
-#define NUM_RECV_BUFFS_8 4 /* config for 8K shared mem */
-#define NUM_RECV_BUFFS_16 9 /* config for 16K shared mem */
-#define NO_NOPCOMMANDS /* only possible with NUM_XMIT_BUFFS=1 */
-
-/**************************************************************************/
-
-#define DELAY(x) {int i=jiffies; \
- if(loops_per_sec == 1) \
- while(i+(x)>jiffies); \
- else \
- __delay((loops_per_sec>>5)*x); \
- }
-
-/* a much shorter delay: */
-#define DELAY_16(); { __delay( (loops_per_sec>>16)+1 ); }
-
-/* wait for command with timeout: */
-#define WAIT_4_SCB_CMD() { int i; \
- for(i=0;i<1024;i++) { \
- if(!p->scb->cmd) break; \
- DELAY_16(); \
- if(i == 1023) { \
- printk("%s: scb_cmd timed out .. resetting i82586\n",dev->name); \
- ni_reset586(); } } }
-
-
-#define NI52_TOTAL_SIZE 16
-#define NI52_ADDR0 0x02
-#define NI52_ADDR1 0x07
-#define NI52_ADDR2 0x01
-
-#ifndef HAVE_PORTRESERVE
-#define check_region(ioaddr, size) 0
-#define request_region(ioaddr, size,name) do ; while (0)
-#endif
-
-static int ni52_probe1(struct device *dev,int ioaddr);
-static void ni52_interrupt(int irq,struct pt_regs *reg_ptr);
-static int ni52_open(struct device *dev);
-static int ni52_close(struct device *dev);
-static int ni52_send_packet(struct sk_buff *,struct device *);
-static struct enet_statistics *ni52_get_stats(struct device *dev);
-static void set_multicast_list(struct device *dev);
-
-/* helper-functions */
-static int init586(struct device *dev);
-static int check586(struct device *dev,char *where,unsigned size);
-static void alloc586(struct device *dev);
-static void startrecv586(struct device *dev);
-static void *alloc_rfa(struct device *dev,void *ptr);
-static void ni52_rcv_int(struct device *dev);
-static void ni52_xmt_int(struct device *dev);
-static void ni52_rnr_int(struct device *dev);
-
-struct priv
-{
- struct enet_statistics stats;
- unsigned long base;
- char *memtop;
- volatile struct rfd_struct *rfd_last,*rfd_top,*rfd_first;
- volatile struct scp_struct *scp; /* volatile is important */
- volatile struct iscp_struct *iscp; /* volatile is important */
- volatile struct scb_struct *scb; /* volatile is important */
- volatile struct tbd_struct *xmit_buffs[NUM_XMIT_BUFFS];
- volatile struct transmit_cmd_struct *xmit_cmds[NUM_XMIT_BUFFS];
-#if (NUM_XMIT_BUFFS == 1)
- volatile struct nop_cmd_struct *nop_cmds[2];
-#else
- volatile struct nop_cmd_struct *nop_cmds[NUM_XMIT_BUFFS];
-#endif
- volatile int nop_point,num_recv_buffs;
- volatile char *xmit_cbuffs[NUM_XMIT_BUFFS];
- volatile int xmit_count,xmit_last;
-};
-
-
-/**********************************************
- * close device
- */
-
-static int ni52_close(struct device *dev)
-{
- free_irq(dev->irq);
- irq2dev_map[dev->irq] = 0;
-
- ni_reset586(); /* the hard way to stop the receiver */
-
- dev->start = 0;
- dev->tbusy = 0;
-
- return 0;
-}
-
-/**********************************************
- * open device
- */
-
-static int ni52_open(struct device *dev)
-{
- alloc586(dev);
- init586(dev);
- startrecv586(dev);
-
- if(request_irq(dev->irq, &ni52_interrupt,0,"ni52"))
- {
- ni_reset586();
- return -EAGAIN;
- }
- irq2dev_map[dev->irq] = dev;
-
- dev->interrupt = 0;
- dev->tbusy = 0;
- dev->start = 1;
-
- return 0; /* most done by init */
-}
-
-/**********************************************
- * Check to see if there's an 82586 out there.
- */
-
-static int check586(struct device *dev,char *where,unsigned size)
-{
- struct priv *p = (struct priv *) dev->priv;
- char *iscp_addrs[2];
- int i;
-
- p->base = (unsigned long) where + size - 0x01000000;
- p->memtop = where + size;
- p->scp = (struct scp_struct *)(p->base + SCP_DEFAULT_ADDRESS);
- memset((char *)p->scp,0, sizeof(struct scp_struct));
- p->scp->sysbus = SYSBUSVAL; /* 1 = 8Bit-Bus, 0 = 16 Bit */
-
- iscp_addrs[0] = where;
- iscp_addrs[1]= (char *) p->scp - sizeof(struct iscp_struct);
-
- for(i=0;i<2;i++)
- {
- p->iscp = (struct iscp_struct *) iscp_addrs[i];
- memset((char *)p->iscp,0, sizeof(struct iscp_struct));
-
- p->scp->iscp = make24(p->iscp);
- p->iscp->busy = 1;
-
- ni_reset586();
- ni_attn586();
- DELAY(2); /* wait a while... */
-
- if(p->iscp->busy) /* i82586 clears 'busy' after successful init */
- return 0;
- }
- return 1;
-}
-
-/******************************************************************
- * set iscp at the right place, called by ni52_probe1 and open586.
- */
-
-void alloc586(struct device *dev)
-{
- struct priv *p = (struct priv *) dev->priv;
-
- ni_reset586();
- DELAY(2);
-
- p->scp = (struct scp_struct *) (p->base + SCP_DEFAULT_ADDRESS);
- p->scb = (struct scb_struct *) (dev->mem_start);
- p->iscp = (struct iscp_struct *) ((char *)p->scp - sizeof(struct iscp_struct));
-
- memset((char *) p->iscp,0,sizeof(struct iscp_struct));
- memset((char *) p->scp ,0,sizeof(struct scp_struct));
-
- p->scp->iscp = make24(p->iscp);
- p->scp->sysbus = SYSBUSVAL;
- p->iscp->scb_offset = make16(p->scb);
-
- p->iscp->busy = 1;
- ni_reset586();
- ni_attn586();
-
- DELAY(2);
-
- if(p->iscp->busy)
- printk("%s: Init-Problems (alloc).\n",dev->name);
-
- memset((char *)p->scb,0,sizeof(struct scb_struct));
-}
-
-/**********************************************
- * probe the ni5210-card
- */
-
-int ni52_probe(struct device *dev)
-{
- int *port, ports[] = {0x300, 0x280, 0x360 , 0x320 , 0x340, 0};
- int base_addr = dev->base_addr;
-
- if (base_addr > 0x1ff) /* Check a single specified location. */
- if( (inb(base_addr+NI52_MAGIC1) == NI52_MAGICVAL1) &&
- (inb(base_addr+NI52_MAGIC2) == NI52_MAGICVAL2))
- return ni52_probe1(dev, base_addr);
- else if (base_addr > 0) /* Don't probe at all. */
- return ENXIO;
-
- for (port = ports; *port; port++) {
- int ioaddr = *port;
- if (check_region(ioaddr, NI52_TOTAL_SIZE))
- continue;
- if( !(inb(ioaddr+NI52_MAGIC1) == NI52_MAGICVAL1) ||
- !(inb(ioaddr+NI52_MAGIC2) == NI52_MAGICVAL2))
- continue;
-
- dev->base_addr = ioaddr;
- if (ni52_probe1(dev, ioaddr) == 0)
- return 0;
- }
-
- dev->base_addr = base_addr;
- return ENODEV;
-}
-
-static int ni52_probe1(struct device *dev,int ioaddr)
-{
- long memaddrs[] = { 0xd0000,0xd2000,0xc8000,0xca000,0xd4000,0xd6000,0xd8000, 0 };
- int i,size;
-
- for(i=0;i<ETH_ALEN;i++)
- dev->dev_addr[i] = inb(dev->base_addr+i);
-
- if(dev->dev_addr[0] != NI52_ADDR0 || dev->dev_addr[1] != NI52_ADDR1
- || dev->dev_addr[2] != NI52_ADDR2)
- return ENODEV;
-
- printk("%s: Ni52 found at %#3lx, ",dev->name,dev->base_addr);
-
- request_region(ioaddr,NI52_TOTAL_SIZE,"ni52");
-
- dev->priv = (void *) kmalloc(sizeof(struct priv),GFP_KERNEL);
- /* warning: we don't free it on errors */
- if (dev->priv == NULL)
- return -ENOMEM;
- memset((char *) dev->priv,0,sizeof(struct priv));
-
- /*
- * check (or search) IO-Memory, 8K and 16K
- */
- if(dev->mem_start != 0) /* no auto-mem-probe */
- {
- size = 0x4000; /* check for 16K mem */
- if(!check586(dev,(char *) dev->mem_start,size)) {
- size = 0x2000; /* check for 8K mem */
- if(!check586(dev,(char *) dev->mem_start,size)) {
- printk("?memprobe, Can't find memory at 0x%lx!\n",dev->mem_start);
- return ENODEV;
- }
- }
- }
- else
- {
- for(i=0;;i++)
- {
- if(!memaddrs[i]) {
- printk("?memprobe, Can't find io-memory!\n");
- return ENODEV;
- }
- dev->mem_start = memaddrs[i];
- size = 0x2000; /* check for 8K mem */
- if(check586(dev,(char *)dev->mem_start,size)) /* 8K-check */
- break;
- size = 0x4000; /* check for 16K mem */
- if(check586(dev,(char *)dev->mem_start,size)) /* 16K-check */
- break;
- }
- }
- dev->mem_end = dev->mem_start + size; /* set mem_end showed by 'ifconfig' */
-
- ((struct priv *) (dev->priv))->base = dev->mem_start + size - 0x01000000;
- alloc586(dev);
-
- /* set number of receive-buffs according to memsize */
- if(size == 0x2000)
- ((struct priv *) dev->priv)->num_recv_buffs = NUM_RECV_BUFFS_8;
- else
- ((struct priv *) dev->priv)->num_recv_buffs = NUM_RECV_BUFFS_16;
-
- printk("Memaddr: 0x%lx, Memsize: %d, ",dev->mem_start,size);
-
- if(dev->irq < 2)
- {
- autoirq_setup(0);
- ni_reset586();
- ni_attn586();
- if(!(dev->irq = autoirq_report(2)))
- {
- printk("?autoirq, Failed to detect IRQ line!\n");
- return 1;
- }
- }
- else if(dev->irq == 2)
- dev->irq = 9;
-
- printk("IRQ %d.\n",dev->irq);
-
- dev->open = &ni52_open;
- dev->stop = &ni52_close;
- dev->get_stats = &ni52_get_stats;
- dev->hard_start_xmit = &ni52_send_packet;
- dev->set_multicast_list = &set_multicast_list;
-
- dev->if_port = 0;
-
- ether_setup(dev);
-
- dev->tbusy = 0;
- dev->interrupt = 0;
- dev->start = 0;
-
- return 0;
-}
-
-/**********************************************
- * init the chip (ni52-interrupt should be disabled?!)
- * needs a correct 'allocated' memory
- */
-
-static int init586(struct device *dev)
-{
- void *ptr;
- unsigned long s;
- int i,result=0;
- struct priv *p = (struct priv *) dev->priv;
- volatile struct configure_cmd_struct *cfg_cmd;
- volatile struct iasetup_cmd_struct *ias_cmd;
- volatile struct tdr_cmd_struct *tdr_cmd;
- volatile struct mcsetup_cmd_struct *mc_cmd;
- struct dev_mc_list *dmi=dev->mc_list;
- int num_addrs=dev->mc_count;
-
- ptr = (void *) ((char *)p->scb + sizeof(struct scb_struct));
-
- cfg_cmd = (struct configure_cmd_struct *)ptr; /* configure-command */
- cfg_cmd->cmd_status = 0;
- cfg_cmd->cmd_cmd = CMD_CONFIGURE | CMD_LAST;
- cfg_cmd->cmd_link = 0xffff;
-
- cfg_cmd->byte_cnt = 0x0a; /* number of cfg bytes */
- cfg_cmd->fifo = 0x08; /* fifo-limit (8=tx:32/rx:64) */
- cfg_cmd->sav_bf = 0x40; /* hold or discard bad recv frames (bit 7) */
- cfg_cmd->adr_len = 0x2e; /* addr_len |!src_insert |pre-len |loopback */
- cfg_cmd->priority = 0x00;
- cfg_cmd->ifs = 0x60;
- cfg_cmd->time_low = 0x00;
- cfg_cmd->time_high = 0xf2;
- cfg_cmd->promisc = 0;
- if(dev->flags&(IFF_ALLMULTI|IFF_PROMISC))
- {
- cfg_cmd->promisc=1;
- dev->flags|=IFF_PROMISC;
- }
- cfg_cmd->carr_coll = 0x00;
-
- p->scb->cbl_offset = make16(cfg_cmd);
-
- p->scb->cmd = CUC_START; /* cmd.-unit start */
- ni_attn586();
-
- s = jiffies; /* warning: only active with interrupts on !! */
- while(!(cfg_cmd->cmd_status & STAT_COMPL))
- if(jiffies-s > 30) break;
-
- if((cfg_cmd->cmd_status & (STAT_OK|STAT_COMPL)) != (STAT_COMPL|STAT_OK))
- {
- printk("%s (ni52): configure command failed: %x\n",dev->name,cfg_cmd->cmd_status);
- return 1;
- }
-
- /*
- * individual address setup
- */
- ias_cmd = (struct iasetup_cmd_struct *)ptr;
-
- ias_cmd->cmd_status = 0;
- ias_cmd->cmd_cmd = CMD_IASETUP | CMD_LAST;
- ias_cmd->cmd_link = 0xffff;
-
- memcpy((char *)&ias_cmd->iaddr,(char *) dev->dev_addr,ETH_ALEN);
-
- p->scb->cbl_offset = make16(ias_cmd);
-
- p->scb->cmd = CUC_START; /* cmd.-unit start */
- ni_attn586();
-
- s = jiffies;
- while(!(ias_cmd->cmd_status & STAT_COMPL))
- if(jiffies-s > 30) break;
-
- if((ias_cmd->cmd_status & (STAT_OK|STAT_COMPL)) != (STAT_OK|STAT_COMPL)) {
- printk("%s (ni52): individual address setup command failed: %04x\n",dev->name,ias_cmd->cmd_status);
- return 1;
- }
-
- /*
- * TDR, wire check .. e.g. no resistor e.t.c
- */
- tdr_cmd = (struct tdr_cmd_struct *)ptr;
-
- tdr_cmd->cmd_status = 0;
- tdr_cmd->cmd_cmd = CMD_TDR | CMD_LAST;
- tdr_cmd->cmd_link = 0xffff;
- tdr_cmd->status = 0;
-
- p->scb->cbl_offset = make16(tdr_cmd);
-
- p->scb->cmd = CUC_START; /* cmd.-unit start */
- ni_attn586();
-
- s = jiffies;
- while(!(tdr_cmd->cmd_status & STAT_COMPL))
- if(jiffies - s > 30) {
- printk("%s: Problems while running the TDR.\n",dev->name);
- result = 1;
- }
-
- if(!result)
- {
- DELAY(2); /* wait for result */
- result = tdr_cmd->status;
-
- p->scb->cmd = p->scb->status & STAT_MASK;
- ni_attn586(); /* ack the interrupts */
-
- if(result & TDR_LNK_OK) ;
- else if(result & TDR_XCVR_PRB)
- printk("%s: TDR: Transceiver problem!\n",dev->name);
- else if(result & TDR_ET_OPN)
- printk("%s: TDR: No correct termination %d clocks away.\n",dev->name,result & TDR_TIMEMASK);
- else if(result & TDR_ET_SRT)
- {
- if (result & TDR_TIMEMASK) /* time == 0 -> strange :-) */
- printk("%s: TDR: Detected a short circuit %d clocks away.\n",dev->name,result & TDR_TIMEMASK);
- }
- else
- printk("%s: TDR: Unknown status %04x\n",dev->name,result);
- }
-
- /*
- * ack interrupts
- */
- p->scb->cmd = p->scb->status & STAT_MASK;
- ni_attn586();
-
- /*
- * alloc nop/xmit-cmds
- */
-#if (NUM_XMIT_BUFFS == 1)
- for(i=0;i<2;i++)
- {
- p->nop_cmds[i] = (struct nop_cmd_struct *)ptr;
- p->nop_cmds[i]->cmd_cmd = CMD_NOP;
- p->nop_cmds[i]->cmd_status = 0;
- p->nop_cmds[i]->cmd_link = make16((p->nop_cmds[i]));
- ptr = (char *) ptr + sizeof(struct nop_cmd_struct);
- }
- p->xmit_cmds[0] = (struct transmit_cmd_struct *)ptr; /* transmit cmd/buff 0 */
- ptr = (char *) ptr + sizeof(struct transmit_cmd_struct);
-#else
- for(i=0;i<NUM_XMIT_BUFFS;i++)
- {
- p->nop_cmds[i] = (struct nop_cmd_struct *)ptr;
- p->nop_cmds[i]->cmd_cmd = CMD_NOP;
- p->nop_cmds[i]->cmd_status = 0;
- p->nop_cmds[i]->cmd_link = make16((p->nop_cmds[i]));
- ptr = (char *) ptr + sizeof(struct nop_cmd_struct);
- p->xmit_cmds[i] = (struct transmit_cmd_struct *)ptr; /*transmit cmd/buff 0*/
- ptr = (char *) ptr + sizeof(struct transmit_cmd_struct);
- }
-#endif
-
- ptr = alloc_rfa(dev,(void *)ptr); /* init receive-frame-area */
-
- /*
- * Multicast setup
- */
-
- if(dev->mc_count)
- { /* I don't understand this: do we really need memory after the init? */
- int len = ((char *) p->iscp - (char *) ptr - 8) / 6;
- if(len <= 0)
- {
- printk("%s: Ooooops, no memory for MC-Setup!\n",dev->name);
- }
- else
- {
- if(len < num_addrs)
- {
- /* BUG - should go ALLMULTI in this case */
- num_addrs = len;
- printk("%s: Sorry, can only apply %d MC-Address(es).\n",dev->name,num_addrs);
- }
- mc_cmd = (struct mcsetup_cmd_struct *) ptr;
- mc_cmd->cmd_status = 0;
- mc_cmd->cmd_cmd = CMD_MCSETUP | CMD_LAST;
- mc_cmd->cmd_link = 0xffff;
- mc_cmd->mc_cnt = num_addrs * 6;
- for(i=0;i<num_addrs;i++)
- {
- memcpy((char *) mc_cmd->mc_list[i], dmi->dmi_addr,6);
- dmi=dmi->next;
- }
- p->scb->cbl_offset = make16(mc_cmd);
- p->scb->cmd = CUC_START;
- ni_attn586();
- s = jiffies;
- while(!(mc_cmd->cmd_status & STAT_COMPL))
- if(jiffies - s > 30)
- break;
- if(!(mc_cmd->cmd_status & STAT_COMPL))
- printk("%s: Can't apply multicast-address-list.\n",dev->name);
- }
- }
-
- /*
- * alloc xmit-buffs / init xmit_cmds
- */
- for(i=0;i<NUM_XMIT_BUFFS;i++)
- {
- p->xmit_cbuffs[i] = (char *)ptr; /* char-buffs */
- ptr = (char *) ptr + XMIT_BUFF_SIZE;
- p->xmit_buffs[i] = (struct tbd_struct *)ptr; /* TBD */
- ptr = (char *) ptr + sizeof(struct tbd_struct);
- if((void *)ptr > (void *)p->iscp)
- {
- printk("%s: not enough shared-mem for your configuration!\n",dev->name);
- return 1;
- }
- memset((char *)(p->xmit_cmds[i]) ,0, sizeof(struct transmit_cmd_struct));
- memset((char *)(p->xmit_buffs[i]),0, sizeof(struct tbd_struct));
- p->xmit_cmds[i]->cmd_status = STAT_COMPL;
- p->xmit_cmds[i]->cmd_cmd = CMD_XMIT | CMD_INT;
- p->xmit_cmds[i]->tbd_offset = make16((p->xmit_buffs[i]));
- p->xmit_buffs[i]->next = 0xffff;
- p->xmit_buffs[i]->buffer = make24((p->xmit_cbuffs[i]));
- }
-
- p->xmit_count = 0;
- p->xmit_last = 0;
-#ifndef NO_NOPCOMMANDS
- p->nop_point = 0;
-#endif
-
- /*
- * 'start transmitter' (nop-loop)
- */
-#ifndef NO_NOPCOMMANDS
- p->scb->cbl_offset = make16(p->nop_cmds[0]);
- p->scb->cmd = CUC_START;
- ni_attn586();
- WAIT_4_SCB_CMD();
-#else
- p->xmit_cmds[0]->cmd_link = 0xffff;
- p->xmit_cmds[0]->cmd_cmd = CMD_XMIT | CMD_LAST | CMD_INT;
-#endif
-
- return 0;
-}
-
-/******************************************************
- * This is a helper routine for ni52_rnr_int() and init586().
- * It sets up the Receive Frame Area (RFA).
- */
-
-static void *alloc_rfa(struct device *dev,void *ptr)
-{
- volatile struct rfd_struct *rfd = (struct rfd_struct *)ptr;
- volatile struct rbd_struct *rbd;
- int i;
- struct priv *p = (struct priv *) dev->priv;
-
- memset((char *) rfd,0,sizeof(struct rfd_struct)*p->num_recv_buffs);
- p->rfd_first = rfd;
-
- for(i = 0; i < p->num_recv_buffs; i++)
- rfd[i].next = make16(rfd + (i+1) % p->num_recv_buffs);
- rfd[p->num_recv_buffs-1].last = RFD_SUSP; /* RU suspend */
-
- ptr = (void *) (rfd + p->num_recv_buffs);
-
- rbd = (struct rbd_struct *) ptr;
- ptr = (void *) (rbd + p->num_recv_buffs);
-
- /* clr descriptors */
- memset((char *) rbd,0,sizeof(struct rbd_struct)*p->num_recv_buffs);
-
- for(i=0;i<p->num_recv_buffs;i++)
- {
- rbd[i].next = make16((rbd + (i+1) % p->num_recv_buffs));
- rbd[i].size = RECV_BUFF_SIZE;
- rbd[i].buffer = make24(ptr);
- ptr = (char *) ptr + RECV_BUFF_SIZE;
- }
-
- p->rfd_top = p->rfd_first;
- p->rfd_last = p->rfd_first + p->num_recv_buffs - 1;
-
- p->scb->rfa_offset = make16(p->rfd_first);
- p->rfd_first->rbd_offset = make16(rbd);
-
- return ptr;
-}
-
-
-/**************************************************
- * Interrupt Handler ...
- */
-
-static void ni52_interrupt(int irq,struct pt_regs *reg_ptr)
-{
- struct device *dev = (struct device *) irq2dev_map[irq];
- unsigned short stat;
- struct priv *p;
-
- if (dev == NULL) {
- printk ("ni52-interrupt: irq %d for unknown device.\n",(int) -(((struct pt_regs *)reg_ptr)->orig_eax+2));
- return;
- }
- p = (struct priv *) dev->priv;
-
- dev->interrupt = 1;
-
- while((stat=p->scb->status & STAT_MASK))
- {
- p->scb->cmd = stat;
- ni_attn586(); /* ack inter. */
-
- if(stat & STAT_CX) /* command with I-bit set complete */
- ni52_xmt_int(dev);
-
- if(stat & STAT_FR) /* received a frame */
- ni52_rcv_int(dev);
-
-#ifndef NO_NOPCOMMANDS
- if(stat & STAT_CNA) /* CU went 'not ready' */
- {
- if(dev->start)
- printk("%s: oops! CU has left active state. stat: %04x/%04x.\n",dev->name,(int) stat,(int) p->scb->status);
- }
-#endif
-
- if(stat & STAT_RNR) /* RU went 'not ready' */
- {
- if(p->scb->status & RU_SUSPEND) /* special case: RU_SUSPEND */
- {
- WAIT_4_SCB_CMD();
- p->scb->cmd = RUC_RESUME;
- ni_attn586();
- }
- else
- {
- printk("%s: Receiver-Unit went 'NOT READY': %04x/%04x.\n",dev->name,(int) stat,(int) p->scb->status);
- ni52_rnr_int(dev);
- }
- }
- WAIT_4_SCB_CMD(); /* wait for ack. (ni52_xmt_int can be faster than ack!!) */
- if(p->scb->cmd) /* timed out? */
- break;
- }
-
- dev->interrupt = 0;
-}
-
-/*******************************************************
- * receive-interrupt
- */
-
-static void ni52_rcv_int(struct device *dev)
-{
- int status;
- unsigned short totlen;
- struct sk_buff *skb;
- struct rbd_struct *rbd;
- struct priv *p = (struct priv *) dev->priv;
-
- for(;(status = p->rfd_top->status) & STAT_COMPL;)
- {
- rbd = (struct rbd_struct *) make32(p->rfd_top->rbd_offset);
-
- if(status & STAT_OK) /* frame received without error? */
- {
- if( (totlen = rbd->status) & RBD_LAST) /* the first and the last buffer? */
- {
- totlen &= RBD_MASK; /* length of this frame */
- rbd->status = 0;
- skb = (struct sk_buff *) dev_alloc_skb(totlen+2);
- if(skb != NULL)
- {
- skb->dev = dev;
- skb_reserve(skb,2); /* 16 byte alignment */
- memcpy(skb_put(skb,totlen),(char *) p->base+(unsigned long) rbd->buffer, totlen);
- skb->protocol=eth_type_trans(skb,dev);
- netif_rx(skb);
- p->stats.rx_packets++;
- }
- else
- p->stats.rx_dropped++;
- }
- else
- {
- printk("%s: received oversized frame.\n",dev->name);
- p->stats.rx_dropped++;
- }
- }
- else /* frame !(ok), only with 'save-bad-frames' */
- {
- printk("%s: oops! rfd-error-status: %04x\n",dev->name,status);
- p->stats.rx_errors++;
- }
- p->rfd_top->status = 0;
- p->rfd_top->last = RFD_SUSP;
- p->rfd_last->last = 0; /* delete RU_SUSP */
- p->rfd_last = p->rfd_top;
- p->rfd_top = (struct rfd_struct *) make32(p->rfd_top->next); /* step to next RFD */
- }
-}
-
-/**********************************************************
- * handle 'Receiver went not ready'.
- */
-
-static void ni52_rnr_int(struct device *dev)
-{
- struct priv *p = (struct priv *) dev->priv;
-
- p->stats.rx_errors++;
-
- WAIT_4_SCB_CMD(); /* wait for the last cmd */
- p->scb->cmd = RUC_ABORT; /* usually the RU is in the 'no resource'-state .. abort it now. */
- ni_attn586();
- WAIT_4_SCB_CMD(); /* wait for accept cmd. */
-
- alloc_rfa(dev,(char *)p->rfd_first);
- startrecv586(dev); /* restart RU */
-
- printk("%s: Receive-Unit restarted. Status: %04x\n",dev->name,p->scb->status);
-
-}
-
-/**********************************************************
- * handle xmit - interrupt
- */
-
-static void ni52_xmt_int(struct device *dev)
-{
- int status;
- struct priv *p = (struct priv *) dev->priv;
-
- status = p->xmit_cmds[p->xmit_last]->cmd_status;
- if(!(status & STAT_COMPL))
- printk("%s: strange .. xmit-int without a 'COMPLETE'\n",dev->name);
-
- if(status & STAT_OK)
- {
- p->stats.tx_packets++;
- p->stats.collisions += (status & TCMD_MAXCOLLMASK);
- }
- else
- {
- p->stats.tx_errors++;
- if(status & TCMD_LATECOLL) {
- printk("%s: late collision detected.\n",dev->name);
- p->stats.collisions++;
- }
- else if(status & TCMD_NOCARRIER) {
- p->stats.tx_carrier_errors++;
- printk("%s: no carrier detected.\n",dev->name);
- }
- else if(status & TCMD_LOSTCTS)
- printk("%s: loss of CTS detected.\n",dev->name);
- else if(status & TCMD_UNDERRUN) {
- p->stats.tx_fifo_errors++;
- printk("%s: DMA underrun detected.\n",dev->name);
- }
- else if(status & TCMD_MAXCOLL) {
- printk("%s: Max. collisions exceeded.\n",dev->name);
- p->stats.collisions += 16;
- }
- }
-
-#if (NUM_XMIT_BUFFS != 1)
- if( (++p->xmit_last) == NUM_XMIT_BUFFS)
- p->xmit_last = 0;
-#endif
-
- dev->tbusy = 0;
- mark_bh(NET_BH);
-}
-
-/***********************************************************
- * (re)start the receiver
- */
-
-static void startrecv586(struct device *dev)
-{
- struct priv *p = (struct priv *) dev->priv;
-
- p->scb->rfa_offset = make16(p->rfd_first);
- p->scb->cmd = RUC_START;
- ni_attn586(); /* start cmd. */
- WAIT_4_SCB_CMD(); /* wait for accept cmd. (no timeout!!) */
-}
-
-/******************************************************
- * send frame
- */
-
-static int ni52_send_packet(struct sk_buff *skb, struct device *dev)
-{
- int len,i;
-#ifndef NO_NOPCOMMANDS
- int next_nop;
-#endif
- struct priv *p = (struct priv *) dev->priv;
-
- if(dev->tbusy)
- {
- int tickssofar = jiffies - dev->trans_start;
- if (tickssofar < 5)
- return 1;
-
- if(p->scb->status & CU_ACTIVE) /* COMMAND-UNIT active? */
- {
- dev->tbusy = 0;
-#ifdef DEBUG
- printk("%s: strange ... timeout with CU active?!?\n",dev->name);
- printk("%s: X0: %04x N0: %04x N1: %04x %d\n",dev->name,(int)p->xmit_cmds[0]->cmd_status,(int)p->nop_cmds[0]->cmd_status,(int)p->nop_cmds[1]->cmd_status,(int)p->nop_point);
-#endif
- p->scb->cmd = CUC_ABORT;
- ni_attn586();
- WAIT_4_SCB_CMD();
- p->scb->cbl_offset = make16(p->nop_cmds[p->nop_point]);
- p->scb->cmd = CUC_START;
- ni_attn586();
- WAIT_4_SCB_CMD();
- dev->trans_start = jiffies;
- return 0;
- }
- else
- {
-#ifdef DEBUG
- printk("%s: xmitter timed out, try to restart! stat: %04x\n",dev->name,p->scb->status);
- printk("%s: command-stats: %04x %04x\n",dev->name,p->xmit_cmds[0]->cmd_status,p->xmit_cmds[1]->cmd_status);
-#endif
- ni52_close(dev);
- ni52_open(dev);
- }
- dev->trans_start = jiffies;
- return 0;
- }
-
- if(skb == NULL)
- {
- dev_tint(dev);
- return 0;
- }
-
- if (skb->len <= 0)
- return 0;
- if(skb->len > XMIT_BUFF_SIZE)
- {
- printk("%s: Sorry, max. framelength is %d bytes. The length of your frame is %ld bytes.\n",dev->name,XMIT_BUFF_SIZE,skb->len);
- return 0;
- }
-
- if (set_bit(0, (void*)&dev->tbusy) != 0)
- printk("%s: Transmitter access conflict.\n", dev->name);
- else
- {
- memcpy((char *)p->xmit_cbuffs[p->xmit_count],(char *)(skb->data),skb->len);
- len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
-
-#if (NUM_XMIT_BUFFS == 1)
-# ifdef NO_NOPCOMMANDS
- p->xmit_buffs[0]->size = TBD_LAST | len;
- for(i=0;i<16;i++)
- {
- p->scb->cbl_offset = make16(p->xmit_cmds[0]);
- p->scb->cmd = CUC_START;
- p->xmit_cmds[0]->cmd_status = 0;
-
- ni_attn586();
- dev->trans_start = jiffies;
- if(!i)
- dev_kfree_skb(skb,FREE_WRITE);
- WAIT_4_SCB_CMD();
- if( (p->scb->status & CU_ACTIVE)) /* test it, because CU sometimes doesn't start immediately */
- break;
- if(p->xmit_cmds[0]->cmd_status)
- break;
- if(i==15)
- printk("%s: Can't start transmit-command.\n",dev->name);
- }
-# else
- next_nop = (p->nop_point + 1) & 0x1;
- p->xmit_buffs[0]->size = TBD_LAST | len;
-
- p->xmit_cmds[0]->cmd_link = p->nop_cmds[next_nop]->cmd_link
- = make16((p->nop_cmds[next_nop]));
- p->xmit_cmds[0]->cmd_status = p->nop_cmds[next_nop]->cmd_status = 0;
-
- p->nop_cmds[p->nop_point]->cmd_link = make16((p->xmit_cmds[0]));
- dev->trans_start = jiffies;
- p->nop_point = next_nop;
- dev_kfree_skb(skb,FREE_WRITE);
-# endif
-#else
- p->xmit_buffs[p->xmit_count]->size = TBD_LAST | len;
- if( (next_nop = p->xmit_count + 1) == NUM_XMIT_BUFFS )
- next_nop = 0;
-
- p->xmit_cmds[p->xmit_count]->cmd_status = 0;
- p->xmit_cmds[p->xmit_count]->cmd_link = p->nop_cmds[next_nop]->cmd_link
- = make16((p->nop_cmds[next_nop]));
- p->nop_cmds[next_nop]->cmd_status = 0;
-
- p->nop_cmds[p->xmit_count]->cmd_link = make16((p->xmit_cmds[p->xmit_count]));
- dev->trans_start = jiffies;
- p->xmit_count = next_nop;
-
- cli();
- if(p->xmit_count != p->xmit_last)
- dev->tbusy = 0;
- sti();
- dev_kfree_skb(skb,FREE_WRITE);
-#endif
- }
- return 0;
-}
-
-/*******************************************
- * Someone wanna have the statistics
- */
-
-static struct enet_statistics *ni52_get_stats(struct device *dev)
-{
- struct priv *p = (struct priv *) dev->priv;
- unsigned short crc,aln,rsc,ovrn;
-
- crc = p->scb->crc_errs; /* get error-statistic from the ni82586 */
- p->scb->crc_errs -= crc;
- aln = p->scb->aln_errs;
- p->scb->aln_errs -= aln;
- rsc = p->scb->rsc_errs;
- p->scb->rsc_errs -= rsc;
- ovrn = p->scb->ovrn_errs;
- p->scb->ovrn_errs -= ovrn;
-
- p->stats.rx_crc_errors += crc;
- p->stats.rx_fifo_errors += ovrn;
- p->stats.rx_frame_errors += aln;
- p->stats.rx_dropped += rsc;
-
- return &p->stats;
-}
-
-/********************************************************
- * Set MC list ..
- */
-
-static void set_multicast_list(struct device *dev)
-{
- if(!dev->start)
- {
- printk("%s: Can't apply promiscuous/multicastmode to a not running interface.\n",dev->name);
- return;
- }
-
- dev->start = 0;
- alloc586(dev);
- init586(dev);
- startrecv586(dev);
- dev->start = 1;
-}
-
-/*
- * END: linux/drivers/net/ni52.c
- */
diff --git a/i386/i386at/gpl/linux/net/ni52.h b/i386/i386at/gpl/linux/net/ni52.h
deleted file mode 100644
index 23b0a0e8..00000000
--- a/i386/i386at/gpl/linux/net/ni52.h
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * Intel i82586 Ethernet definitions
- *
- * This is an extension to the Linux operating system, and is covered by the
- * same Gnu Public License that covers that work.
- *
- * copyrights (c) 1994 by Michael Hipp (mhipp@student.uni-tuebingen.de)
- *
- * I have done a look in the following sources:
- * crynwr-packet-driver by Russ Nelson
- * Garret A. Wollman's i82586-driver for BSD
- */
-
-
-#define NI52_RESET 0 /* writing to this address, resets the i82586 */
-#define NI52_ATTENTION 1 /* channel attention, kick the 586 */
-#define NI52_TENA 3 /* 2-5 possibly wrong, Xmit enable */
-#define NI52_TDIS 2 /* Xmit disable */
-#define NI52_INTENA 5 /* Interrupt enable */
-#define NI52_INTDIS 4 /* Interrupt disable */
-#define NI52_MAGIC1 6 /* dunno exact function */
-#define NI52_MAGIC2 7 /* dunno exact function */
-
-#define NI52_MAGICVAL1 0x00 /* magic-values for ni5210 card */
-#define NI52_MAGICVAL2 0x55
-
-/*
- * where to find the System Configuration Pointer (SCP)
- */
-#define SCP_DEFAULT_ADDRESS 0xfffff4
-
-
-/*
- * System Configuration Pointer Struct
- */
-
-struct scp_struct
-{
- unsigned short zero_dum0; /* has to be zero */
- unsigned char sysbus; /* 0=16Bit,1=8Bit */
- unsigned char zero_dum1; /* has to be zero for 586 */
- unsigned short zero_dum2;
- unsigned short zero_dum3;
- char *iscp; /* pointer to the iscp-block */
-};
-
-
-/*
- * Intermediate System Configuration Pointer (ISCP)
- */
-struct iscp_struct
-{
- unsigned char busy; /* 586 clears after successful init */
- unsigned char zero_dummy; /* hast to be zero */
- unsigned short scb_offset; /* pointeroffset to the scb_base */
- char *scb_base; /* base-address of all 16-bit offsets */
-};
-
-/*
- * System Control Block (SCB)
- */
-struct scb_struct
-{
- unsigned short status; /* status word */
- unsigned short cmd; /* command word */
- unsigned short cbl_offset; /* pointeroffset, command block list */
- unsigned short rfa_offset; /* pointeroffset, receive frame area */
- unsigned short crc_errs; /* CRC-Error counter */
- unsigned short aln_errs; /* allignmenterror counter */
- unsigned short rsc_errs; /* Resourceerror counter */
- unsigned short ovrn_errs; /* OVerrunerror counter */
-};
-
-/*
- * possible command values for the command word
- */
-#define RUC_MASK 0x0070 /* mask for RU commands */
-#define RUC_NOP 0x0000 /* NOP-command */
-#define RUC_START 0x0010 /* start RU */
-#define RUC_RESUME 0x0020 /* resume RU after suspend */
-#define RUC_SUSPEND 0x0030 /* suspend RU */
-#define RUC_ABORT 0x0040 /* abort receiver operation immediately */
-
-#define CUC_MASK 0x0700 /* mask for CU command */
-#define CUC_NOP 0x0000 /* NOP-command */
-#define CUC_START 0x0100 /* start execution of 1. cmd on the CBL */
-#define CUC_RESUME 0x0200 /* resume after suspend */
-#define CUC_SUSPEND 0x0300 /* Suspend CU */
-#define CUC_ABORT 0x0400 /* abort command operation immediately */
-
-#define ACK_MASK 0xf000 /* mask for ACK command */
-#define ACK_CX 0x8000 /* acknowledges STAT_CX */
-#define ACK_FR 0x4000 /* ack. STAT_FR */
-#define ACK_CNA 0x2000 /* ack. STAT_CNA */
-#define ACK_RNR 0x1000 /* ack. STAT_RNR */
-
-/*
- * possible status values for the status word
- */
-#define STAT_MASK 0xf000 /* mask for cause of interrupt */
-#define STAT_CX 0x8000 /* CU finished cmd with its I bit set */
-#define STAT_FR 0x4000 /* RU finished receiving a frame */
-#define STAT_CNA 0x2000 /* CU left active state */
-#define STAT_RNR 0x1000 /* RU left ready state */
-
-#define CU_STATUS 0x700 /* CU status, 0=idle */
-#define CU_SUSPEND 0x100 /* CU is suspended */
-#define CU_ACTIVE 0x200 /* CU is active */
-
-#define RU_STATUS 0x70 /* RU status, 0=idle */
-#define RU_SUSPEND 0x10 /* RU suspended */
-#define RU_NOSPACE 0x20 /* RU no resources */
-#define RU_READY 0x40 /* RU is ready */
-
-/*
- * Receive Frame Descriptor (RFD)
- */
-struct rfd_struct
-{
- unsigned short status; /* status word */
- unsigned short last; /* Bit15,Last Frame on List / Bit14,suspend */
- unsigned short next; /* linkoffset to next RFD */
- unsigned short rbd_offset; /* pointeroffset to RBD-buffer */
- unsigned char dest[6]; /* ethernet-address, destination */
- unsigned char source[6]; /* ethernet-address, source */
- unsigned short length; /* 802.3 frame-length */
- unsigned short zero_dummy; /* dummy */
-};
-
-#define RFD_LAST 0x8000 /* last: last rfd in the list */
-#define RFD_SUSP 0x4000 /* last: suspend RU after */
-#define RFD_ERRMASK 0x0fe1 /* status: errormask */
-#define RFD_MATCHADD 0x0002 /* status: Destinationaddress !matches IA */
-#define RFD_RNR 0x0200 /* status: receiver out of resources */
-
-/*
- * Receive Buffer Descriptor (RBD)
- */
-struct rbd_struct
-{
- unsigned short status; /* status word,number of used bytes in buff */
- unsigned short next; /* pointeroffset to next RBD */
- char *buffer; /* receive buffer address pointer */
- unsigned short size; /* size of this buffer */
- unsigned short zero_dummy; /* dummy */
-};
-
-#define RBD_LAST 0x8000 /* last buffer */
-#define RBD_USED 0x4000 /* this buffer has data */
-#define RBD_MASK 0x3fff /* size-mask for length */
-
-/*
- * Statusvalues for Commands/RFD
- */
-#define STAT_COMPL 0x8000 /* status: frame/command is complete */
-#define STAT_BUSY 0x4000 /* status: frame/command is busy */
-#define STAT_OK 0x2000 /* status: frame/command is ok */
-
-/*
- * Action-Commands
- */
-#define CMD_NOP 0x0000 /* NOP */
-#define CMD_IASETUP 0x0001 /* initial address setup command */
-#define CMD_CONFIGURE 0x0002 /* configure command */
-#define CMD_MCSETUP 0x0003 /* MC setup command */
-#define CMD_XMIT 0x0004 /* transmit command */
-#define CMD_TDR 0x0005 /* time domain reflectometer (TDR) command */
-#define CMD_DUMP 0x0006 /* dump command */
-#define CMD_DIAGNOSE 0x0007 /* diagnose command */
-
-/*
- * Action command bits
- */
-#define CMD_LAST 0x8000 /* indicates last command in the CBL */
-#define CMD_SUSPEND 0x4000 /* suspend CU after this CB */
-#define CMD_INT 0x2000 /* generate interrupt after execution */
-
-/*
- * NOP - command
- */
-struct nop_cmd_struct
-{
- unsigned short cmd_status; /* status of this command */
- unsigned short cmd_cmd; /* the command itself (+bits) */
- unsigned short cmd_link; /* offsetpointer to next command */
-};
-
-/*
- * IA Setup command
- */
-struct iasetup_cmd_struct
-{
- unsigned short cmd_status;
- unsigned short cmd_cmd;
- unsigned short cmd_link;
- unsigned char iaddr[6];
-};
-
-/*
- * Configure command
- */
-struct configure_cmd_struct
-{
- unsigned short cmd_status;
- unsigned short cmd_cmd;
- unsigned short cmd_link;
- unsigned char byte_cnt; /* size of the config-cmd */
- unsigned char fifo; /* fifo/recv monitor */
- unsigned char sav_bf; /* save bad frames (bit7=1)*/
- unsigned char adr_len; /* adr_len(0-2),al_loc(3),pream(4-5),loopbak(6-7)*/
- unsigned char priority; /* lin_prio(0-2),exp_prio(4-6),bof_metd(7) */
- unsigned char ifs; /* inter frame spacing */
- unsigned char time_low; /* slot time low */
- unsigned char time_high; /* slot time high(0-2) and max. retries(4-7) */
- unsigned char promisc; /* promisc-mode(0) , et al (1-7) */
- unsigned char carr_coll; /* carrier(0-3)/collision(4-7) stuff */
- unsigned char fram_len; /* minimal frame len */
- unsigned char dummy; /* dummy */
-};
-
-/*
- * Multicast Setup command
- */
-struct mcsetup_cmd_struct
-{
- unsigned short cmd_status;
- unsigned short cmd_cmd;
- unsigned short cmd_link;
- unsigned short mc_cnt; /* number of bytes in the MC-List */
- unsigned char mc_list[0][6]; /* pointer to 6 bytes entries */
-};
-
-/*
- * transmit command
- */
-struct transmit_cmd_struct
-{
- unsigned short cmd_status;
- unsigned short cmd_cmd;
- unsigned short cmd_link;
- unsigned short tbd_offset; /* pointeroffset to TBD */
- unsigned char dest[6]; /* destination address of the frame */
- unsigned short length; /* user defined: 802.3 length / Ether type */
-};
-
-#define TCMD_ERRMASK 0x0fa0
-#define TCMD_MAXCOLLMASK 0x000f
-#define TCMD_MAXCOLL 0x0020
-#define TCMD_HEARTBEAT 0x0040
-#define TCMD_DEFERRED 0x0080
-#define TCMD_UNDERRUN 0x0100
-#define TCMD_LOSTCTS 0x0200
-#define TCMD_NOCARRIER 0x0400
-#define TCMD_LATECOLL 0x0800
-
-struct tdr_cmd_struct
-{
- unsigned short cmd_status;
- unsigned short cmd_cmd;
- unsigned short cmd_link;
- unsigned short status;
-};
-
-#define TDR_LNK_OK 0x8000 /* No link problem identified */
-#define TDR_XCVR_PRB 0x4000 /* indicates a transceiver problem */
-#define TDR_ET_OPN 0x2000 /* open, no correct termination */
-#define TDR_ET_SRT 0x1000 /* TDR detected a short circuit */
-#define TDR_TIMEMASK 0x07ff /* mask for the time field */
-
-/*
- * Transmit Buffer Descriptor (TBD)
- */
-struct tbd_struct
-{
- unsigned short size; /* size + EOF-Flag(15) */
- unsigned short next; /* pointeroffset to next TBD */
- char *buffer; /* pointer to buffer */
-};
-
-#define TBD_LAST 0x8000 /* EOF-Flag, indicates last buffer in list */
-
-
-
-
diff --git a/i386/i386at/gpl/linux/net/ni65.c b/i386/i386at/gpl/linux/net/ni65.c
deleted file mode 100644
index 44a58112..00000000
--- a/i386/i386at/gpl/linux/net/ni65.c
+++ /dev/null
@@ -1,648 +0,0 @@
-/*
- * ni6510 (am7990 'lance' chip) driver for Linux-net-3 by MH
- * Alphacode v0.33 (94/08/22) for 1.1.47 (or later)
- *
- * ----------------------------------------------------------
- * WARNING: DOESN'T WORK ON MACHINES WITH MORE THAN 16MB !!!!
- * ----------------------------------------------------------
- *
- * copyright (c) 1994 M.Hipp
- *
- * This is an extension to the Linux operating system, and is covered by the
- * same Gnu Public License that covers the Linux-kernel.
- *
- * comments/bugs/suggestions can be sent to:
- * Michael Hipp
- * email: mhipp@student.uni-tuebingen.de
- *
- * sources:
- * some things are from the 'ni6510-packet-driver for dos by Russ Nelson'
- * and from the original drivers by D.Becker
- */
-
-/*
- * Nov.18: multicast tweaked (AC).
- *
- * Aug.22: changes in xmit_intr (ack more than one xmitted-packet), ni65_send_packet (p->lock) (MH)
- *
- * July.16: fixed bugs in recv_skb and skb-alloc stuff (MH)
- */
-
-/*
- * known BUGS: 16MB limit
- */
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/ptrace.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/malloc.h>
-#include <linux/interrupt.h>
-#include <asm/bitops.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-
-#include "ni65.h"
-
-/************************************
- * skeleton-stuff
- */
-
-#ifndef HAVE_PORTRESERVE
-#define check_region(ioaddr, size) 0
-#define request_region(ioaddr, size,name) do ; while (0)
-#endif
-
-#ifndef NET_DEBUG
-#define NET_DEBUG 2
-#endif
-/*
-static unsigned int net_debug = NET_DEBUG;
-*/
-
-#define NI65_TOTAL_SIZE 16
-
-#define SA_ADDR0 0x02
-#define SA_ADDR1 0x07
-#define SA_ADDR2 0x01
-#define CARD_ID0 0x00
-#define CARD_ID1 0x55
-
-/*****************************************/
-
-#define PORT dev->base_addr
-
-#define RMDNUM 8
-#define RMDNUMMASK 0x6000 /* log2(RMDNUM)<<13 */
-#define TMDNUM 4
-#define TMDNUMMASK 0x4000 /* log2(TMDNUM)<<13 */
-
-#define R_BUF_SIZE 1518
-#define T_BUF_SIZE 1518
-
-#define MEMSIZE 8+RMDNUM*8+TMDNUM*8
-
-#define L_DATAREG 0x00
-#define L_ADDRREG 0x02
-
-#define L_RESET 0x04
-#define L_CONFIG 0x05
-#define L_EBASE 0x08
-
-/*
- * to access the am7990-regs, you have to write
- * reg-number into L_ADDRREG, then you can access it using L_DATAREG
- */
-#define CSR0 0x00
-#define CSR1 0x01
-#define CSR2 0x02
-#define CSR3 0x03
-
-/* if you #define NO_STATIC the driver is faster but you will have (more) problems with >16MB memory */
-#undef NO_STATIC
-
-#define writereg(val,reg) {outw(reg,PORT+L_ADDRREG);inw(PORT+L_ADDRREG); \
- outw(val,PORT+L_DATAREG);inw(PORT+L_DATAREG);}
-#define readreg(reg) (outw(reg,PORT+L_ADDRREG),inw(PORT+L_ADDRREG),\
- inw(PORT+L_DATAREG))
-#define writedatareg(val) {outw(val,PORT+L_DATAREG);inw(PORT+L_DATAREG);}
-
-static int ni65_probe1(struct device *dev,int);
-static void ni65_interrupt(int irq, struct pt_regs *regs);
- static void recv_intr(struct device *dev);
- static void xmit_intr(struct device *dev);
-static int ni65_open(struct device *dev);
- static int am7990_reinit(struct device *dev);
-static int ni65_send_packet(struct sk_buff *skb, struct device *dev);
-static int ni65_close(struct device *dev);
-static struct enet_statistics *ni65_get_stats(struct device *);
-
-static void set_multicast_list(struct device *dev);
-
-struct priv
-{
- struct init_block ib;
- void *memptr;
- struct rmd *rmdhead;
- struct tmd *tmdhead;
- int rmdnum;
- int tmdnum,tmdlast;
- struct sk_buff *recv_skb[RMDNUM];
- void *tmdbufs[TMDNUM];
- int lock,xmit_queued;
- struct enet_statistics stats;
-};
-
-int irqtab[] = { 9,12,15,5 }; /* irq config-translate */
-int dmatab[] = { 0,3,5,6 }; /* dma config-translate */
-
-/*
- * open (most done by init)
- */
-
-static int ni65_open(struct device *dev)
-{
- if(am7990_reinit(dev))
- {
- dev->tbusy = 0;
- dev->interrupt = 0;
- dev->start = 1;
- return 0;
- }
- else
- {
- dev->start = 0;
- return -EAGAIN;
- }
-}
-
-static int ni65_close(struct device *dev)
-{
- outw(0,PORT+L_RESET); /* that's the hard way */
- dev->tbusy = 1;
- dev->start = 0;
- return 0;
-}
-
-/*
- * Probe The Card (not the lance-chip)
- * and set hardaddress
- */
-
-int ni65_probe(struct device *dev)
-{
- int *port, ports[] = {0x300,0x320,0x340,0x360, 0};
- int base_addr = dev->base_addr;
-
- if (base_addr > 0x1ff) /* Check a single specified location. */
- return ni65_probe1(dev, base_addr);
- else if (base_addr > 0) /* Don't probe at all. */
- return ENXIO;
-
- for (port = ports; *port; port++)
- {
- int ioaddr = *port;
- if (check_region(ioaddr, NI65_TOTAL_SIZE))
- continue;
- if( !(inb(ioaddr+L_EBASE+6) == CARD_ID0) ||
- !(inb(ioaddr+L_EBASE+7) == CARD_ID1) )
- continue;
- dev->base_addr = ioaddr;
- if (ni65_probe1(dev, ioaddr) == 0)
- return 0;
- }
-
- dev->base_addr = base_addr;
- return ENODEV;
-}
-
-
-static int ni65_probe1(struct device *dev,int ioaddr)
-{
- int i;
- unsigned char station_addr[6];
- struct priv *p;
-
- for(i=0;i<6;i++)
- station_addr[i] = dev->dev_addr[i] = inb(PORT+L_EBASE+i);
-
- if(station_addr[0] != SA_ADDR0 || station_addr[1] != SA_ADDR1)
- {
- printk("%s: wrong Hardaddress \n",dev->name);
- return ENODEV;
- }
-
- if(dev->irq == 0)
- dev->irq = irqtab[(inw(PORT+L_CONFIG)>>2)&3];
- if(dev->dma == 0)
- dev->dma = dmatab[inw(PORT+L_CONFIG)&3];
-
- printk("%s: %s found at %#3lx, IRQ %d DMA %d.\n", dev->name,
- "network card", dev->base_addr, dev->irq,dev->dma);
-
- {
- int irqval = request_irq(dev->irq, &ni65_interrupt,0,"ni65");
- if (irqval) {
- printk ("%s: unable to get IRQ %d (irqval=%d).\n",
- dev->name,dev->irq, irqval);
- return EAGAIN;
- }
- if(request_dma(dev->dma, "ni65") != 0)
- {
- printk("%s: Can't request dma-channel %d\n",dev->name,(int) dev->dma);
- free_irq(dev->irq);
- return EAGAIN;
- }
- }
- irq2dev_map[dev->irq] = dev;
-
- /* Grab the region so we can find another board if autoIRQ fails. */
- request_region(ioaddr,NI65_TOTAL_SIZE,"ni65");
-
- p = dev->priv = (void *) kmalloc(sizeof(struct priv),GFP_KERNEL);
- if (p == NULL)
- return -ENOMEM;
- memset((char *) dev->priv,0,sizeof(struct priv));
-
- dev->open = ni65_open;
- dev->stop = ni65_close;
- dev->hard_start_xmit = ni65_send_packet;
- dev->get_stats = ni65_get_stats;
- dev->set_multicast_list = set_multicast_list;
-
- ether_setup(dev);
-
- dev->flags &= ~IFF_MULTICAST;
- dev->interrupt = 0;
- dev->tbusy = 0;
- dev->start = 0;
-
- if( (p->memptr = kmalloc(MEMSIZE,GFP_KERNEL)) == NULL) {
- printk("%s: Can't alloc TMD/RMD-buffer.\n",dev->name);
- return EAGAIN;
- }
- if( (unsigned long) (p->memptr + MEMSIZE) & 0xff000000) {
- printk("%s: Can't alloc TMD/RMD buffer in lower 16MB!\n",dev->name);
- return EAGAIN;
- }
- p->tmdhead = (struct tmd *) ((( (unsigned long)p->memptr ) + 8) & 0xfffffff8);
- p->rmdhead = (struct rmd *) (p->tmdhead + TMDNUM);
-
-#ifndef NO_STATIC
- for(i=0;i<TMDNUM;i++)
- {
- if( (p->tmdbufs[i] = kmalloc(T_BUF_SIZE,GFP_ATOMIC)) == NULL) {
- printk("%s: Can't alloc Xmit-Mem.\n",dev->name);
- return EAGAIN;
- }
- if( (unsigned long) (p->tmdbufs[i]+T_BUF_SIZE) & 0xff000000) {
- printk("%s: Can't alloc Xmit-Mem in lower 16MB!\n",dev->name);
- return EAGAIN;
- }
- }
-#endif
-
- for(i=0;i<RMDNUM;i++)
- {
- if( (p->recv_skb[i] = dev_alloc_skb(R_BUF_SIZE)) == NULL) {
- printk("%s: unable to alloc recv-mem\n",dev->name);
- return EAGAIN;
- }
- if( (unsigned long) (p->recv_skb[i]->data + R_BUF_SIZE) & 0xff000000) {
- printk("%s: unable to alloc receive-memory in lower 16MB!\n",dev->name);
- return EAGAIN;
- }
- }
-
- return 0; /* we've found everything */
-}
-
-/*
- * init lance (write init-values .. init-buffers) (open-helper)
- */
-
-static int am7990_reinit(struct device *dev)
-{
- int i,j;
- struct tmd *tmdp;
- struct rmd *rmdp;
- struct priv *p = (struct priv *) dev->priv;
-
- p->lock = 0;
- p->xmit_queued = 0;
-
- disable_dma(dev->dma); /* I've never worked with dma, but we do it like the packetdriver */
- set_dma_mode(dev->dma,DMA_MODE_CASCADE);
- enable_dma(dev->dma);
-
- outw(0,PORT+L_RESET); /* first: reset the card */
- if(inw(PORT+L_DATAREG) != 0x4)
- {
- printk("%s: can't RESET ni6510 card: %04x\n",dev->name,(int) inw(PORT+L_DATAREG));
- disable_dma(dev->dma);
- free_dma(dev->dma);
- free_irq(dev->irq);
- return 0;
- }
-
- /* here: memset all buffs to zero */
-
- memset(p->memptr,0,MEMSIZE);
-
- p->tmdnum = 0; p->tmdlast = 0;
- for(i=0;i<TMDNUM;i++)
- {
- tmdp = p->tmdhead + i;
-#ifndef NO_STATIC
- tmdp->u.buffer = (unsigned long) p->tmdbufs[i];
-#endif
- tmdp->u.s.status = XMIT_START | XMIT_END;
- }
-
- p->rmdnum = 0;
- for(i=0;i<RMDNUM;i++)
- {
- rmdp = p->rmdhead + i;
- rmdp->u.buffer = (unsigned long) p->recv_skb[i]->data;
- rmdp->u.s.status = RCV_OWN;
- rmdp->blen = -R_BUF_SIZE;
- rmdp->mlen = 0;
- }
-
- for(i=0;i<6;i++)
- {
- p->ib.eaddr[i] = dev->dev_addr[i];
- }
- p->ib.mode = 0;
- for(i=0;i<8;i++)
- p->ib.filter[i] = 0;
- p->ib.trplow = (unsigned short) (( (unsigned long) p->tmdhead ) & 0xffff);
- p->ib.trphigh = (unsigned short) ((( (unsigned long) p->tmdhead )>>16) & 0x00ff) | TMDNUMMASK;
- p->ib.rrplow = (unsigned short) (( (unsigned long) p->rmdhead ) & 0xffff);
- p->ib.rrphigh = (unsigned short) ((( (unsigned long) p->rmdhead )>>16) & 0x00ff) | RMDNUMMASK;
-
- writereg(0,CSR3); /* busmaster/no word-swap */
- writereg((unsigned short) (((unsigned long) &(p->ib)) & 0xffff),CSR1);
- writereg((unsigned short) (((unsigned long) &(p->ib))>>16),CSR2);
-
- writereg(CSR0_INIT,CSR0); /* this changes L_ADDRREG to CSR0 */
-
- /*
- * NOW, WE NEVER WILL CHANGE THE L_ADDRREG, CSR0 IS ALWAYS SELECTED
- */
-
- for(i=0;i<5;i++)
- {
- for(j=0;j<2000000;j++); /* wait a while */
- if(inw(PORT+L_DATAREG) & CSR0_IDON) break; /* init ok ? */
- }
- if(i == 5)
- {
- printk("%s: can't init am7990, status: %04x\n",dev->name,(int) inw(PORT+L_DATAREG));
- disable_dma(dev->dma);
- free_dma(dev->dma);
- free_irq(dev->irq);
- return 0; /* false */
- }
-
- writedatareg(CSR0_CLRALL | CSR0_INEA | CSR0_STRT); /* start lance , enable interrupts */
-
- return 1; /* OK */
-}
-
-/*
- * interrupt handler
- */
-
-static void ni65_interrupt(int irq, struct pt_regs * regs)
-{
- int csr0;
- struct device *dev = (struct device *) irq2dev_map[irq];
-
- if (dev == NULL) {
- printk ("net_interrupt(): irq %d for unknown device.\n", irq);
- return;
- }
-
- csr0 = inw(PORT+L_DATAREG);
- writedatareg(csr0 & CSR0_CLRALL); /* ack interrupts, disable int. */
-
- dev->interrupt = 1;
-
- if(csr0 & CSR0_ERR)
- {
- struct priv *p = (struct priv *) dev->priv;
-
- if(csr0 & CSR0_BABL)
- p->stats.tx_errors++;
- if(csr0 & CSR0_MISS)
- p->stats.rx_errors++;
- }
-
- if(csr0 & CSR0_RINT) /* RECV-int? */
- {
- recv_intr(dev);
- }
- if(csr0 & CSR0_TINT) /* XMIT-int? */
- {
- xmit_intr(dev);
- }
-
- writedatareg(CSR0_INEA); /* reenable inter. */
- dev->interrupt = 0;
-
- return;
-}
-
-/*
- * We have received an Xmit-Interrupt ..
- * send a new packet if necessary
- */
-
-static void xmit_intr(struct device *dev)
-{
- int tmdstat;
- struct tmd *tmdp;
- struct priv *p = (struct priv *) dev->priv;
-
-#ifdef NO_STATIC
- struct sk_buff *skb;
-#endif
-
- while(p->xmit_queued)
- {
- tmdp = p->tmdhead + p->tmdlast;
- tmdstat = tmdp->u.s.status;
- if(tmdstat & XMIT_OWN)
- break;
-#ifdef NO_STATIC
- skb = (struct sk_buff *) p->tmdbufs[p->tmdlast];
- dev_kfree_skb(skb,FREE_WRITE);
-#endif
-
- if(tmdstat & XMIT_ERR)
- {
- printk("%s: xmit-error: %04x %04x\n",dev->name,(int) tmdstat,(int) tmdp->status2);
- if(tmdp->status2 & XMIT_TDRMASK)
- printk("%s: tdr-problems (e.g. no resistor)\n",dev->name);
-
- /* checking some errors */
- if(tmdp->status2 & XMIT_RTRY)
- p->stats.tx_aborted_errors++;
- if(tmdp->status2 & XMIT_LCAR)
- p->stats.tx_carrier_errors++;
- p->stats.tx_errors++;
- tmdp->status2 = 0;
- }
- else
- p->stats.tx_packets++;
-
- p->tmdlast = (p->tmdlast + 1) & (TMDNUM-1);
- if(p->tmdlast == p->tmdnum)
- p->xmit_queued = 0;
- }
-
- dev->tbusy = 0;
- mark_bh(NET_BH);
-}
-
-/*
- * We have received a packet
- */
-
-static void recv_intr(struct device *dev)
-{
- struct rmd *rmdp;
- int rmdstat,len;
- struct sk_buff *skb,*skb1;
- struct priv *p = (struct priv *) dev->priv;
-
- rmdp = p->rmdhead + p->rmdnum;
- while(!( (rmdstat = rmdp->u.s.status) & RCV_OWN))
- {
- if( (rmdstat & (RCV_START | RCV_END)) != (RCV_START | RCV_END) ) /* is packet start & end? */
- {
- if(rmdstat & RCV_START)
- {
- p->stats.rx_errors++;
- p->stats.rx_length_errors++;
- printk("%s: packet too long\n",dev->name);
- }
- rmdp->u.s.status = RCV_OWN; /* change owner */
- }
- else if(rmdstat & RCV_ERR)
- {
- printk("%s: receive-error: %04x\n",dev->name,(int) rmdstat );
- p->stats.rx_errors++;
- if(rmdstat & RCV_FRAM) p->stats.rx_frame_errors++;
- if(rmdstat & RCV_OFLO) p->stats.rx_over_errors++;
- if(rmdstat & RCV_CRC) p->stats.rx_crc_errors++;
- rmdp->u.s.status = RCV_OWN;
- printk("%s: lance-status: %04x\n",dev->name,(int) inw(PORT+L_DATAREG));
- }
- else
- {
- len = (rmdp->mlen & 0x0fff) - 4; /* -4: ignore FCS */
- skb = dev_alloc_skb(R_BUF_SIZE);
- if(skb != NULL)
- {
- if( (unsigned long) (skb->data + R_BUF_SIZE) & 0xff000000) {
- memcpy(skb_put(skb,len),p->recv_skb[p->rmdnum]->data,len);
- skb1 = skb;
- }
- else {
- skb1 = p->recv_skb[p->rmdnum];
- p->recv_skb[p->rmdnum] = skb;
- rmdp->u.buffer = (unsigned long) skb_put(skb1,len);
- }
- rmdp->u.s.status = RCV_OWN;
- rmdp->mlen = 0; /* not necc ???? */
- skb1->dev = dev;
- p->stats.rx_packets++;
- skb1->protocol=eth_type_trans(skb1,dev);
- netif_rx(skb1);
- }
- else
- {
- rmdp->u.s.status = RCV_OWN;
- printk("%s: can't alloc new sk_buff\n",dev->name);
- p->stats.rx_dropped++;
- }
- }
- p->rmdnum++; p->rmdnum &= RMDNUM-1;
- rmdp = p->rmdhead + p->rmdnum;
- }
-}
-
-/*
- * kick xmitter ..
- */
-
-static int ni65_send_packet(struct sk_buff *skb, struct device *dev)
-{
- struct priv *p = (struct priv *) dev->priv;
- struct tmd *tmdp;
-
- if(dev->tbusy)
- {
- int tickssofar = jiffies - dev->trans_start;
- if (tickssofar < 25)
- return 1;
-
- printk("%s: xmitter timed out, try to restart!\n",dev->name);
- am7990_reinit(dev);
- dev->tbusy=0;
- dev->trans_start = jiffies;
- }
-
- if(skb == NULL)
- {
- dev_tint(dev);
- return 0;
- }
-
- if (skb->len <= 0)
- return 0;
-
- if (set_bit(0, (void*)&dev->tbusy) != 0)
- {
- printk("%s: Transmitter access conflict.\n", dev->name);
- return 1;
- }
- if(set_bit(0,(void*) &p->lock) != 0)
- {
- printk("%s: Queue was locked!\n",dev->name);
- return 1;
- }
-
- {
- short len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
-
- tmdp = p->tmdhead + p->tmdnum;
-
-#ifdef NO_STATIC
- tmdp->u.buffer = (unsigned long) (skb->data);
- p->tmdbufs[p->tmdnum] = skb;
-#else
- memcpy((char *) (tmdp->u.buffer & 0x00ffffff),(char *)skb->data,skb->len);
- dev_kfree_skb (skb, FREE_WRITE);
-#endif
- tmdp->blen = -len;
- tmdp->u.s.status = XMIT_OWN | XMIT_START | XMIT_END;
-
- cli();
- p->xmit_queued = 1;
- writedatareg(CSR0_TDMD | CSR0_INEA); /* enable xmit & interrupt */
- p->tmdnum++; p->tmdnum &= TMDNUM-1;
-
- if( !((p->tmdhead + p->tmdnum)->u.s.status & XMIT_OWN) )
- dev->tbusy = 0;
- p->lock = 0;
- sti();
-
- dev->trans_start = jiffies;
-
- }
-
- return 0;
-}
-
-static struct enet_statistics *ni65_get_stats(struct device *dev)
-{
- return &((struct priv *) dev->priv)->stats;
-}
-
-static void set_multicast_list(struct device *dev)
-{
-}
-
-/*
- * END of ni65.c
- */
-
diff --git a/i386/i386at/gpl/linux/net/ni65.h b/i386/i386at/gpl/linux/net/ni65.h
deleted file mode 100644
index 144523fa..00000000
--- a/i386/i386at/gpl/linux/net/ni65.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/* am7990 (lance) definitions
- *
- * This is a extension to the Linux operating system, and is covered by
- * same Gnu Public License that covers that work.
- *
- * Michael Hipp
- * email: mhipp@student.uni-tuebingen.de
- *
- * sources: (mail me or ask archie if you need them)
- * crynwr-packet-driver
- */
-
-/*
- * Control and Status Register 0 (CSR0) bit definitions
- * (R=Readable) (W=Writeable) (S=Set on write) (C-Clear on write)
- *
- */
-
-#define CSR0_ERR 0x8000 /* Error summary (R) */
-#define CSR0_BABL 0x4000 /* Babble transmitter timeout error (RC) */
-#define CSR0_CERR 0x2000 /* Collision Error (RC) */
-#define CSR0_MISS 0x1000 /* Missed packet (RC) */
-#define CSR0_MERR 0x0800 /* Memory Error (RC) */
-#define CSR0_RINT 0x0400 /* Receiver Interrupt (RC) */
-#define CSR0_TINT 0x0200 /* Transmit Interrupt (RC) */
-#define CSR0_IDON 0x0100 /* Initialization Done (RC) */
-#define CSR0_INTR 0x0080 /* Interrupt Flag (R) */
-#define CSR0_INEA 0x0040 /* Interrupt Enable (RW) */
-#define CSR0_RXON 0x0020 /* Receiver on (R) */
-#define CSR0_TXON 0x0010 /* Transmitter on (R) */
-#define CSR0_TDMD 0x0008 /* Transmit Demand (RS) */
-#define CSR0_STOP 0x0004 /* Stop (RS) */
-#define CSR0_STRT 0x0002 /* Start (RS) */
-#define CSR0_INIT 0x0001 /* Initialize (RS) */
-
-#define CSR0_CLRALL 0x7f00 /* mask for all clearable bits */
-/*
- * Initialization Block Mode operation Bit Definitions.
- */
-
-#define M_PROM 0x8000 /* Promiscuous Mode */
-#define M_INTL 0x0040 /* Internal Loopback */
-#define M_DRTY 0x0020 /* Disable Retry */
-#define M_COLL 0x0010 /* Force Collision */
-#define M_DTCR 0x0008 /* Disable Transmit CRC) */
-#define M_LOOP 0x0004 /* Loopback */
-#define M_DTX 0x0002 /* Disable the Transmitter */
-#define M_DRX 0x0001 /* Disable the Receiver */
-
-
-/*
- * Receive message descriptor bit definitions.
- */
-
-#define RCV_OWN 0x80 /* owner bit 0 = host, 1 = lance */
-#define RCV_ERR 0x40 /* Error Summary */
-#define RCV_FRAM 0x20 /* Framing Error */
-#define RCV_OFLO 0x10 /* Overflow Error */
-#define RCV_CRC 0x08 /* CRC Error */
-#define RCV_BUF_ERR 0x04 /* Buffer Error */
-#define RCV_START 0x02 /* Start of Packet */
-#define RCV_END 0x01 /* End of Packet */
-
-
-/*
- * Transmit message descriptor bit definitions.
- */
-
-#define XMIT_OWN 0x80 /* owner bit 0 = host, 1 = lance */
-#define XMIT_ERR 0x40 /* Error Summary */
-#define XMIT_RETRY 0x10 /* more the 1 retry needed to Xmit */
-#define XMIT_1_RETRY 0x08 /* one retry needed to Xmit */
-#define XMIT_DEF 0x04 /* Deferred */
-#define XMIT_START 0x02 /* Start of Packet */
-#define XMIT_END 0x01 /* End of Packet */
-
-/*
- * transmit status (2) (valid if XMIT_ERR == 1)
- */
-
-#define XMIT_RTRY 0x0200 /* Failed after 16 retransmissions */
-#define XMIT_LCAR 0x0400 /* Loss of Carrier */
-#define XMIT_LCOL 0x1000 /* Late collision */
-#define XMIT_RESERV 0x2000 /* Reserved */
-#define XMIT_UFLO 0x4000 /* Underflow (late memory) */
-#define XMIT_BUFF 0x8000 /* Buffering error (no ENP) */
-#define XMIT_TDRMASK 0x003f /* time-domain-reflectometer-value */
-
-struct init_block
-{
- unsigned short mode;
- unsigned char eaddr[6];
- unsigned char filter[8];
- unsigned short rrplow; /* receive ring pointer (align 8) */
- unsigned short rrphigh; /* bit 13-15: number of rmd's (power of 2) */
- unsigned short trplow; /* transmit ring pointer (align 8) */
- unsigned short trphigh; /* bit 13-15: number of tmd's (power of 2) */
-};
-
-struct rmd /* Receive Message Descriptor */
-{
- union
- {
- volatile unsigned long buffer;
- struct
- {
- volatile unsigned char dummy[3];
- volatile unsigned char status;
- } s;
- } u;
- short blen;
- volatile unsigned short mlen;
-};
-
-struct tmd
-{
- union
- {
- volatile unsigned long buffer;
- struct
- {
- volatile unsigned char dummy[3];
- volatile unsigned char status;
- } s;
- } u;
- unsigned short blen;
- volatile unsigned short status2;
-};
-
-
diff --git a/i386/i386at/gpl/linux/net/seeq8005.c b/i386/i386at/gpl/linux/net/seeq8005.c
deleted file mode 100644
index 5799d80c..00000000
--- a/i386/i386at/gpl/linux/net/seeq8005.c
+++ /dev/null
@@ -1,760 +0,0 @@
-/* seeq8005.c: A network driver for linux. */
-/*
- Based on skeleton.c,
- Written 1993-94 by Donald Becker.
- See the skeleton.c file for further copyright information.
-
- This software may be used and distributed according to the terms
- of the GNU Public License, incorporated herein by reference.
-
- The author may be reached as hamish@zot.apana.org.au
-
- This file is a network device driver for the SEEQ 8005 chipset and
- the Linux operating system.
-
-*/
-
-static const char *version =
- "seeq8005.c:v1.00 8/07/95 Hamish Coleman (hamish@zot.apana.org.au)\n";
-
-/*
- Sources:
- SEEQ 8005 databook
-
- Version history:
- 1.00 Public release. cosmetic changes (no warnings now)
- 0.68 Turning per- packet,interrupt debug messages off - testing for release.
- 0.67 timing problems/bad buffer reads seem to be fixed now
- 0.63 *!@$ protocol=eth_type_trans -- now packets flow
- 0.56 Send working
- 0.48 Receive working
-*/
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ptrace.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/malloc.h>
-#include <linux/string.h>
-#include <asm/system.h>
-#include <asm/bitops.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <linux/errno.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include "seeq8005.h"
-
-/* First, a few definitions that the brave might change. */
-/* A zero-terminated list of I/O addresses to be probed. */
-static unsigned int seeq8005_portlist[] =
- { 0x300, 0x320, 0x340, 0x360, 0};
-
-/* use 0 for production, 1 for verification, >2 for debug */
-#ifndef NET_DEBUG
-#define NET_DEBUG 1
-#endif
-static unsigned int net_debug = NET_DEBUG;
-
-/* Information that need to be kept for each board. */
-struct net_local {
- struct enet_statistics stats;
- unsigned short receive_ptr; /* What address in packet memory do we expect a recv_pkt_header? */
- long open_time; /* Useless example local info. */
-};
-
-/* The station (ethernet) address prefix, used for IDing the board. */
-#define SA_ADDR0 0x00
-#define SA_ADDR1 0x80
-#define SA_ADDR2 0x4b
-
-/* Index to functions, as function prototypes. */
-
-extern int seeq8005_probe(struct device *dev);
-
-static int seeq8005_probe1(struct device *dev, int ioaddr);
-static int seeq8005_open(struct device *dev);
-static int seeq8005_send_packet(struct sk_buff *skb, struct device *dev);
-static void seeq8005_interrupt(int irq, struct pt_regs *regs);
-static void seeq8005_rx(struct device *dev);
-static int seeq8005_close(struct device *dev);
-static struct enet_statistics *seeq8005_get_stats(struct device *dev);
-static void set_multicast_list(struct device *dev);
-
-/* Example routines you must write ;->. */
-#define tx_done(dev) (inw(SEEQ_STATUS) & SEEQSTAT_TX_ON)
-extern void hardware_send_packet(struct device *dev, char *buf, int length);
-extern void seeq8005_init(struct device *dev, int startp);
-inline void wait_for_buffer(struct device *dev);
-
-
-/* Check for a network adaptor of this type, and return '0' iff one exists.
- If dev->base_addr == 0, probe all likely locations.
- If dev->base_addr == 1, always return failure.
- If dev->base_addr == 2, allocate space for the device and return success
- (detachable devices only).
- */
-#ifdef HAVE_DEVLIST
-/* Support for a alternate probe manager, which will eliminate the
- boilerplate below. */
-struct netdev_entry seeq8005_drv =
-{"seeq8005", seeq8005_probe1, SEEQ8005_IO_EXTENT, seeq8005_portlist};
-#else
-int
-seeq8005_probe(struct device *dev)
-{
- int i;
- int base_addr = dev ? dev->base_addr : 0;
-
- if (base_addr > 0x1ff) /* Check a single specified location. */
- return seeq8005_probe1(dev, base_addr);
- else if (base_addr != 0) /* Don't probe at all. */
- return ENXIO;
-
- for (i = 0; seeq8005_portlist[i]; i++) {
- int ioaddr = seeq8005_portlist[i];
- if (check_region(ioaddr, SEEQ8005_IO_EXTENT))
- continue;
- if (seeq8005_probe1(dev, ioaddr) == 0)
- return 0;
- }
-
- return ENODEV;
-}
-#endif
-
-/* This is the real probe routine. Linux has a history of friendly device
- probes on the ISA bus. A good device probes avoids doing writes, and
- verifies that the correct device exists and functions. */
-
-static int seeq8005_probe1(struct device *dev, int ioaddr)
-{
- static unsigned version_printed = 0;
- int i,j;
- unsigned char SA_prom[32];
- int old_cfg1;
- int old_cfg2;
- int old_stat;
- int old_dmaar;
- int old_rear;
-
- if (net_debug>1)
- printk("seeq8005: probing at 0x%x\n",ioaddr);
-
- old_stat = inw(SEEQ_STATUS); /* read status register */
- if (old_stat == 0xffff)
- return ENODEV; /* assume that 0xffff == no device */
- if ( (old_stat & 0x1800) != 0x1800 ) { /* assume that unused bits are 1, as my manual says */
- if (net_debug>1) {
- printk("seeq8005: reserved stat bits != 0x1800\n");
- printk(" == 0x%04x\n",old_stat);
- }
- return ENODEV;
- }
-
- old_rear = inw(SEEQ_REA);
- if (old_rear == 0xffff) {
- outw(0,SEEQ_REA);
- if (inw(SEEQ_REA) == 0xffff) { /* assume that 0xffff == no device */
- return ENODEV;
- }
- } else if ((old_rear & 0xff00) != 0xff00) { /* assume that unused bits are 1 */
- if (net_debug>1) {
- printk("seeq8005: unused rear bits != 0xff00\n");
- printk(" == 0x%04x\n",old_rear);
- }
- return ENODEV;
- }
-
- old_cfg2 = inw(SEEQ_CFG2); /* read CFG2 register */
- old_cfg1 = inw(SEEQ_CFG1);
- old_dmaar = inw(SEEQ_DMAAR);
-
- if (net_debug>4) {
- printk("seeq8005: stat = 0x%04x\n",old_stat);
- printk("seeq8005: cfg1 = 0x%04x\n",old_cfg1);
- printk("seeq8005: cfg2 = 0x%04x\n",old_cfg2);
- printk("seeq8005: raer = 0x%04x\n",old_rear);
- printk("seeq8005: dmaar= 0x%04x\n",old_dmaar);
- }
-
- outw( SEEQCMD_FIFO_WRITE | SEEQCMD_SET_ALL_OFF, SEEQ_CMD); /* setup for reading PROM */
- outw( 0, SEEQ_DMAAR); /* set starting PROM address */
- outw( SEEQCFG1_BUFFER_PROM, SEEQ_CFG1); /* set buffer to look at PROM */
-
-
- j=0;
- for(i=0; i <32; i++) {
- j+= SA_prom[i] = inw(SEEQ_BUFFER) & 0xff;
- }
-
-#if 0
- /* untested because I only have the one card */
- if ( (j&0xff) != 0 ) { /* checksum appears to be 8bit = 0 */
- if (net_debug>1) { /* check this before deciding that we have a card */
- printk("seeq8005: prom sum error\n");
- }
- outw( old_stat, SEEQ_STATUS);
- outw( old_dmaar, SEEQ_DMAAR);
- outw( old_cfg1, SEEQ_CFG1);
- return ENODEV;
- }
-#endif
-
- outw( SEEQCFG2_RESET, SEEQ_CFG2); /* reset the card */
- SLOW_DOWN_IO; /* have to wait 4us after a reset - should be fixed */
- SLOW_DOWN_IO;
- SLOW_DOWN_IO;
- SLOW_DOWN_IO;
- outw( SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
-
- if (net_debug) {
- printk("seeq8005: prom sum = 0x%08x\n",j);
- for(j=0; j<32; j+=16) {
- printk("seeq8005: prom %02x: ",j);
- for(i=0;i<16;i++) {
- printk("%02x ",SA_prom[j|i]);
- }
- printk(" ");
- for(i=0;i<16;i++) {
- if ((SA_prom[j|i]>31)&&(SA_prom[j|i]<127)) {
- printk("%c", SA_prom[j|i]);
- } else {
- printk(" ");
- }
- }
- printk("\n");
- }
- }
-
-#if 0
- /*
- * testing the packet buffer memory doesnt work yet
- * but all other buffer accesses do
- * - fixing is not a priority
- */
- if (net_debug>1) { /* test packet buffer memory */
- printk("seeq8005: testing packet buffer ... ");
- outw( SEEQCFG1_BUFFER_BUFFER, SEEQ_CFG1);
- outw( SEEQCMD_FIFO_WRITE | SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
- outw( 0 , SEEQ_DMAAR);
- for(i=0;i<32768;i++) {
- outw(0x5a5a, SEEQ_BUFFER);
- }
- j=jiffies+HZ;
- while ( ((inw(SEEQ_STATUS) & SEEQSTAT_FIFO_EMPTY) != SEEQSTAT_FIFO_EMPTY) && jiffies < j )
- mb();
- outw( 0 , SEEQ_DMAAR);
- while ( ((inw(SEEQ_STATUS) & SEEQSTAT_WINDOW_INT) != SEEQSTAT_WINDOW_INT) && jiffies < j+HZ)
- mb();
- if ( (inw(SEEQ_STATUS) & SEEQSTAT_WINDOW_INT) == SEEQSTAT_WINDOW_INT)
- outw( SEEQCMD_WINDOW_INT_ACK | (inw(SEEQ_STATUS)& SEEQCMD_INT_MASK), SEEQ_CMD);
- outw( SEEQCMD_FIFO_READ | SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
- j=0;
- for(i=0;i<32768;i++) {
- if (inw(SEEQ_BUFFER) != 0x5a5a)
- j++;
- }
- if (j) {
- printk("%i\n",j);
- } else {
- printk("ok.\n");
- }
- }
-#endif
-
- /* Allocate a new 'dev' if needed. */
- if (dev == NULL)
- dev = init_etherdev(0, sizeof(struct net_local));
-
- if (net_debug && version_printed++ == 0)
- printk(version);
-
- printk("%s: %s found at %#3x, ", dev->name, "seeq8005", ioaddr);
-
- /* Fill in the 'dev' fields. */
- dev->base_addr = ioaddr;
-
- /* Retrieve and print the ethernet address. */
- for (i = 0; i < 6; i++)
- printk(" %2.2x", dev->dev_addr[i] = SA_prom[i+6]);
-
- if (dev->irq == 0xff)
- ; /* Do nothing: a user-level program will set it. */
- else if (dev->irq < 2) { /* "Auto-IRQ" */
- autoirq_setup(0);
-
- outw( SEEQCMD_RX_INT_EN | SEEQCMD_SET_RX_ON | SEEQCMD_SET_RX_OFF, SEEQ_CMD );
-
- dev->irq = autoirq_report(0);
-
- if (net_debug >= 2)
- printk(" autoirq is %d\n", dev->irq);
- } else if (dev->irq == 2)
- /* Fixup for users that don't know that IRQ 2 is really IRQ 9,
- * or don't know which one to set.
- */
- dev->irq = 9;
-
-#if 0
- {
- int irqval = request_irq(dev->irq, &seeq8005_interrupt, 0, "seeq8005");
- if (irqval) {
- printk ("%s: unable to get IRQ %d (irqval=%d).\n", dev->name,
- dev->irq, irqval);
- return EAGAIN;
- }
- }
-#endif
-
- /* Grab the region so we can find another board if autoIRQ fails. */
- request_region(ioaddr, SEEQ8005_IO_EXTENT,"seeq8005");
-
- /* Initialize the device structure. */
- dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
- if (dev->priv == NULL)
- return -ENOMEM;
- memset(dev->priv, 0, sizeof(struct net_local));
-
- dev->open = seeq8005_open;
- dev->stop = seeq8005_close;
- dev->hard_start_xmit = seeq8005_send_packet;
- dev->get_stats = seeq8005_get_stats;
- dev->set_multicast_list = &set_multicast_list;
-
- /* Fill in the fields of the device structure with ethernet values. */
- ether_setup(dev);
-
- dev->flags &= ~IFF_MULTICAST;
-
- return 0;
-}
-
-
-/* Open/initialize the board. This is called (in the current kernel)
- sometime after booting when the 'ifconfig' program is run.
-
- This routine should set everything up anew at each open, even
- registers that "should" only need to be set once at boot, so that
- there is non-reboot way to recover if something goes wrong.
- */
-static int
-seeq8005_open(struct device *dev)
-{
- struct net_local *lp = (struct net_local *)dev->priv;
-
- {
- int irqval = request_irq(dev->irq, &seeq8005_interrupt, 0, "seeq8005");
- if (irqval) {
- printk ("%s: unable to get IRQ %d (irqval=%d).\n", dev->name,
- dev->irq, irqval);
- return EAGAIN;
- }
- }
- irq2dev_map[dev->irq] = dev;
-
- /* Reset the hardware here. Don't forget to set the station address. */
- seeq8005_init(dev, 1);
-
- lp->open_time = jiffies;
-
- dev->tbusy = 0;
- dev->interrupt = 0;
- dev->start = 1;
- return 0;
-}
-
-static int
-seeq8005_send_packet(struct sk_buff *skb, struct device *dev)
-{
- int ioaddr = dev->base_addr;
-
- if (dev->tbusy) {
- /* If we get here, some higher level has decided we are broken.
- There should really be a "kick me" function call instead. */
- int tickssofar = jiffies - dev->trans_start;
- if (tickssofar < 5)
- return 1;
- printk("%s: transmit timed out, %s?\n", dev->name,
- tx_done(dev) ? "IRQ conflict" : "network cable problem");
- /* Try to restart the adaptor. */
- seeq8005_init(dev, 1);
- dev->tbusy=0;
- dev->trans_start = jiffies;
- }
-
- /* If some higher layer thinks we've missed an tx-done interrupt
- we are passed NULL. Caution: dev_tint() handles the cli()/sti()
- itself. */
- if (skb == NULL) {
- dev_tint(dev);
- return 0;
- }
-
- /* Block a timer-based transmit from overlapping. This could better be
- done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
- if (set_bit(0, (void*)&dev->tbusy) != 0)
- printk("%s: Transmitter access conflict.\n", dev->name);
- else {
- short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
- unsigned char *buf = skb->data;
-
- hardware_send_packet(dev, buf, length);
- dev->trans_start = jiffies;
- }
- dev_kfree_skb (skb, FREE_WRITE);
-
- /* You might need to clean up and record Tx statistics here. */
-
- return 0;
-}
-
-/* The typical workload of the driver:
- Handle the network interface interrupts. */
-static void
-seeq8005_interrupt(int irq, struct pt_regs * regs)
-{
- struct device *dev = (struct device *)(irq2dev_map[irq]);
- struct net_local *lp;
- int ioaddr, status, boguscount = 0;
-
- if (dev == NULL) {
- printk ("net_interrupt(): irq %d for unknown device.\n", irq);
- return;
- }
-
- if (dev->interrupt)
- printk ("%s: Re-entering the interrupt handler.\n", dev->name);
- dev->interrupt = 1;
-
- ioaddr = dev->base_addr;
- lp = (struct net_local *)dev->priv;
-
- status = inw(SEEQ_STATUS);
- do {
- if (net_debug >2) {
- printk("%s: int, status=0x%04x\n",dev->name,status);
- }
-
- if (status & SEEQSTAT_WINDOW_INT) {
- outw( SEEQCMD_WINDOW_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
- if (net_debug) {
- printk("%s: window int!\n",dev->name);
- }
- }
- if (status & SEEQSTAT_TX_INT) {
- outw( SEEQCMD_TX_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
- lp->stats.tx_packets++;
- dev->tbusy = 0;
- mark_bh(NET_BH); /* Inform upper layers. */
- }
- if (status & SEEQSTAT_RX_INT) {
- /* Got a packet(s). */
- seeq8005_rx(dev);
- }
- status = inw(SEEQ_STATUS);
- } while ( (++boguscount < 10) && (status & SEEQSTAT_ANY_INT)) ;
-
- if(net_debug>2) {
- printk("%s: eoi\n",dev->name);
- }
- dev->interrupt = 0;
- return;
-}
-
-/* We have a good packet(s), get it/them out of the buffers. */
-static void
-seeq8005_rx(struct device *dev)
-{
- struct net_local *lp = (struct net_local *)dev->priv;
- int boguscount = 10;
- int pkt_hdr;
- int ioaddr = dev->base_addr;
-
- do {
- int next_packet;
- int pkt_len;
- int i;
- int status;
-
- status = inw(SEEQ_STATUS);
- outw( lp->receive_ptr, SEEQ_DMAAR);
- outw(SEEQCMD_FIFO_READ | SEEQCMD_RX_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
- wait_for_buffer(dev);
- next_packet = ntohs(inw(SEEQ_BUFFER));
- pkt_hdr = inw(SEEQ_BUFFER);
-
- if (net_debug>2) {
- printk("%s: 0x%04x recv next=0x%04x, hdr=0x%04x\n",dev->name,lp->receive_ptr,next_packet,pkt_hdr);
- }
-
- if ((next_packet == 0) || ((pkt_hdr & SEEQPKTH_CHAIN)==0)) { /* Read all the frames? */
- return; /* Done for now */
- }
-
- if ((pkt_hdr & SEEQPKTS_DONE)==0)
- break;
-
- if (next_packet < lp->receive_ptr) {
- pkt_len = (next_packet + 0x10000 - ((DEFAULT_TEA+1)<<8)) - lp->receive_ptr - 4;
- } else {
- pkt_len = next_packet - lp->receive_ptr - 4;
- }
-
- if (next_packet < ((DEFAULT_TEA+1)<<8)) { /* is the next_packet address sane? */
- printk("%s: recv packet ring corrupt, resetting board\n",dev->name);
- seeq8005_init(dev,1);
- return;
- }
-
- lp->receive_ptr = next_packet;
-
- if (net_debug>2) {
- printk("%s: recv len=0x%04x\n",dev->name,pkt_len);
- }
-
- if (pkt_hdr & SEEQPKTS_ANY_ERROR) { /* There was an error. */
- lp->stats.rx_errors++;
- if (pkt_hdr & SEEQPKTS_SHORT) lp->stats.rx_frame_errors++;
- if (pkt_hdr & SEEQPKTS_DRIB) lp->stats.rx_frame_errors++;
- if (pkt_hdr & SEEQPKTS_OVERSIZE) lp->stats.rx_over_errors++;
- if (pkt_hdr & SEEQPKTS_CRC_ERR) lp->stats.rx_crc_errors++;
- /* skip over this packet */
- outw( SEEQCMD_FIFO_WRITE | SEEQCMD_DMA_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
- outw( (lp->receive_ptr & 0xff00)>>8, SEEQ_REA);
- } else {
- /* Malloc up new buffer. */
- struct sk_buff *skb;
- unsigned char *buf;
-
- skb = dev_alloc_skb(pkt_len);
- if (skb == NULL) {
- printk("%s: Memory squeeze, dropping packet.\n", dev->name);
- lp->stats.rx_dropped++;
- break;
- }
- skb->dev = dev;
- skb_reserve(skb, 2); /* align data on 16 byte */
- buf = skb_put(skb,pkt_len);
-
- insw(SEEQ_BUFFER, buf, (pkt_len + 1) >> 1);
-
- if (net_debug>2) {
- char * p = buf;
- printk("%s: recv ",dev->name);
- for(i=0;i<14;i++) {
- printk("%02x ",*(p++)&0xff);
- }
- printk("\n");
- }
-
- skb->protocol=eth_type_trans(skb,dev);
- netif_rx(skb);
- lp->stats.rx_packets++;
- }
- } while ((--boguscount) && (pkt_hdr & SEEQPKTH_CHAIN));
-
- /* If any worth-while packets have been received, netif_rx()
- has done a mark_bh(NET_BH) for us and will work on them
- when we get to the bottom-half routine. */
- return;
-}
-
-/* The inverse routine to net_open(). */
-static int
-seeq8005_close(struct device *dev)
-{
- struct net_local *lp = (struct net_local *)dev->priv;
- int ioaddr = dev->base_addr;
-
- lp->open_time = 0;
-
- dev->tbusy = 1;
- dev->start = 0;
-
- /* Flush the Tx and disable Rx here. */
- outw( SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
-
- free_irq(dev->irq);
-
- irq2dev_map[dev->irq] = 0;
-
- /* Update the statistics here. */
-
- return 0;
-
-}
-
-/* Get the current statistics. This may be called with the card open or
- closed. */
-static struct enet_statistics *
-seeq8005_get_stats(struct device *dev)
-{
- struct net_local *lp = (struct net_local *)dev->priv;
-
- return &lp->stats;
-}
-
-/* Set or clear the multicast filter for this adaptor.
- num_addrs == -1 Promiscuous mode, receive all packets
- num_addrs == 0 Normal mode, clear multicast list
- num_addrs > 0 Multicast mode, receive normal and MC packets, and do
- best-effort filtering.
- */
-static void
-set_multicast_list(struct device *dev)
-{
-/*
- * I _could_ do upto 6 addresses here, but wont (yet?)
- */
-
-#if 0
- int ioaddr = dev->base_addr;
-/*
- * hmm, not even sure if my matching works _anyway_ - seem to be receiving
- * _everything_ . . .
- */
-
- if (num_addrs) { /* Enable promiscuous mode */
- outw( (inw(SEEQ_CFG1) & ~SEEQCFG1_MATCH_MASK)| SEEQCFG1_MATCH_ALL, SEEQ_CFG1);
- dev->flags|=IFF_PROMISC;
- } else { /* Disable promiscuous mode, use normal mode */
- outw( (inw(SEEQ_CFG1) & ~SEEQCFG1_MATCH_MASK)| SEEQCFG1_MATCH_BROAD, SEEQ_CFG1);
- }
-#endif
-}
-
-void seeq8005_init(struct device *dev, int startp)
-{
- struct net_local *lp = (struct net_local *)dev->priv;
- int ioaddr = dev->base_addr;
- int i;
-
- outw(SEEQCFG2_RESET, SEEQ_CFG2); /* reset device */
- SLOW_DOWN_IO; /* have to wait 4us after a reset - should be fixed */
- SLOW_DOWN_IO;
- SLOW_DOWN_IO;
- SLOW_DOWN_IO;
-
- outw( SEEQCMD_FIFO_WRITE | SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
- outw( 0, SEEQ_DMAAR); /* load start address into both low and high byte */
-/* wait_for_buffer(dev); */ /* I think that you only need a wait for memory buffer */
- outw( SEEQCFG1_BUFFER_MAC0, SEEQ_CFG1);
-
- for(i=0;i<6;i++) { /* set Station address */
- outb(dev->dev_addr[i], SEEQ_BUFFER);
- SLOW_DOWN_IO;
- }
-
- outw( SEEQCFG1_BUFFER_TEA, SEEQ_CFG1); /* set xmit end area pointer to 16K */
- outb( DEFAULT_TEA, SEEQ_BUFFER); /* this gives us 16K of send buffer and 48K of recv buffer */
-
- lp->receive_ptr = (DEFAULT_TEA+1)<<8; /* so we can find our packet_header */
- outw( lp->receive_ptr, SEEQ_RPR); /* Receive Pointer Register is set to recv buffer memory */
-
- outw( 0x00ff, SEEQ_REA); /* Receive Area End */
-
- if (net_debug>4) {
- printk("%s: SA0 = ",dev->name);
-
- outw( SEEQCMD_FIFO_READ | SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
- outw( 0, SEEQ_DMAAR);
- outw( SEEQCFG1_BUFFER_MAC0, SEEQ_CFG1);
-
- for(i=0;i<6;i++) {
- printk("%02x ",inb(SEEQ_BUFFER));
- }
- printk("\n");
- }
-
- outw( SEEQCFG1_MAC0_EN | SEEQCFG1_MATCH_BROAD | SEEQCFG1_BUFFER_BUFFER, SEEQ_CFG1);
- outw( SEEQCFG2_AUTO_REA | SEEQCFG2_CTRLO, SEEQ_CFG2);
- outw( SEEQCMD_SET_RX_ON | SEEQCMD_TX_INT_EN | SEEQCMD_RX_INT_EN, SEEQ_CMD);
-
- if (net_debug>4) {
- int old_cfg1;
- old_cfg1 = inw(SEEQ_CFG1);
- printk("%s: stat = 0x%04x\n",dev->name,inw(SEEQ_STATUS));
- printk("%s: cfg1 = 0x%04x\n",dev->name,old_cfg1);
- printk("%s: cfg2 = 0x%04x\n",dev->name,inw(SEEQ_CFG2));
- printk("%s: raer = 0x%04x\n",dev->name,inw(SEEQ_REA));
- printk("%s: dmaar= 0x%04x\n",dev->name,inw(SEEQ_DMAAR));
-
- }
-}
-
-
-void hardware_send_packet(struct device * dev, char *buf, int length)
-{
- int ioaddr = dev->base_addr;
- int status = inw(SEEQ_STATUS);
- int transmit_ptr = 0;
- int tmp;
-
- if (net_debug>4) {
- printk("%s: send 0x%04x\n",dev->name,length);
- }
-
- /* Set FIFO to writemode and set packet-buffer address */
- outw( SEEQCMD_FIFO_WRITE | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
- outw( transmit_ptr, SEEQ_DMAAR);
-
- /* output SEEQ Packet header barfage */
- outw( htons(length + 4), SEEQ_BUFFER);
- outw( SEEQPKTH_XMIT | SEEQPKTH_DATA_FOLLOWS | SEEQPKTH_XMIT_INT_EN, SEEQ_BUFFER );
-
- /* blat the buffer */
- outsw( SEEQ_BUFFER, buf, (length +1) >> 1);
- /* paranoia !! */
- outw( 0, SEEQ_BUFFER);
- outw( 0, SEEQ_BUFFER);
-
- /* set address of start of transmit chain */
- outw( transmit_ptr, SEEQ_TPR);
-
- /* drain FIFO */
- tmp = jiffies;
- while ( (((status=inw(SEEQ_STATUS)) & SEEQSTAT_FIFO_EMPTY) == 0) && (jiffies < tmp + HZ))
- mb();
-
- /* doit ! */
- outw( SEEQCMD_WINDOW_INT_ACK | SEEQCMD_SET_TX_ON | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
-
-}
-
-
-/*
- * wait_for_buffer
- *
- * This routine waits for the SEEQ chip to assert that the FIFO is ready
- * by checking for a window interrupt, and then clearing it
- */
-inline void wait_for_buffer(struct device * dev)
-{
- int ioaddr = dev->base_addr;
- int tmp;
- int status;
-
- tmp = jiffies + HZ;
- while ( ( ((status=inw(SEEQ_STATUS)) & SEEQSTAT_WINDOW_INT) != SEEQSTAT_WINDOW_INT) && jiffies < tmp)
- mb();
-
- if ( (status & SEEQSTAT_WINDOW_INT) == SEEQSTAT_WINDOW_INT)
- outw( SEEQCMD_WINDOW_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
-}
-
-
-/*
- * Local variables:
- * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c skeleton.c"
- * version-control: t
- * kept-new-versions: 5
- * tab-width: 4
- * End:
- */
diff --git a/i386/i386at/gpl/linux/net/seeq8005.h b/i386/i386at/gpl/linux/net/seeq8005.h
deleted file mode 100644
index 7122340c..00000000
--- a/i386/i386at/gpl/linux/net/seeq8005.h
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * defines, etc for the seeq8005
- */
-
-/*
- * This file is distributed under GPL.
- *
- * This style and layout of this file is also copied
- * from many of the other linux network device drivers.
- */
-
-/* The number of low I/O ports used by the ethercard. */
-#define SEEQ8005_IO_EXTENT 16
-
-#define SEEQ_B (ioaddr)
-
-#define SEEQ_CMD (SEEQ_B) /* Write only */
-#define SEEQ_STATUS (SEEQ_B) /* Read only */
-#define SEEQ_CFG1 (SEEQ_B + 2)
-#define SEEQ_CFG2 (SEEQ_B + 4)
-#define SEEQ_REA (SEEQ_B + 6) /* Receive End Area Register */
-#define SEEQ_RPR (SEEQ_B + 10) /* Receive Pointer Register */
-#define SEEQ_TPR (SEEQ_B + 12) /* Transmit Pointer Register */
-#define SEEQ_DMAAR (SEEQ_B + 14) /* DMA Address Register */
-#define SEEQ_BUFFER (SEEQ_B + 8) /* Buffer Window Register */
-
-#define DEFAULT_TEA (0x3f)
-
-#define SEEQCMD_DMA_INT_EN (0x0001) /* DMA Interrupt Enable */
-#define SEEQCMD_RX_INT_EN (0x0002) /* Receive Interrupt Enable */
-#define SEEQCMD_TX_INT_EN (0x0004) /* Transmit Interrupt Enable */
-#define SEEQCMD_WINDOW_INT_EN (0x0008) /* What the hell is this for?? */
-#define SEEQCMD_INT_MASK (0x000f)
-
-#define SEEQCMD_DMA_INT_ACK (0x0010) /* DMA ack */
-#define SEEQCMD_RX_INT_ACK (0x0020)
-#define SEEQCMD_TX_INT_ACK (0x0040)
-#define SEEQCMD_WINDOW_INT_ACK (0x0080)
-#define SEEQCMD_ACK_ALL (0x00f0)
-
-#define SEEQCMD_SET_DMA_ON (0x0100) /* Enables DMA Request logic */
-#define SEEQCMD_SET_RX_ON (0x0200) /* Enables Packet RX */
-#define SEEQCMD_SET_TX_ON (0x0400) /* Starts TX run */
-#define SEEQCMD_SET_DMA_OFF (0x0800)
-#define SEEQCMD_SET_RX_OFF (0x1000)
-#define SEEQCMD_SET_TX_OFF (0x2000)
-#define SEEQCMD_SET_ALL_OFF (0x3800) /* set all logic off */
-
-#define SEEQCMD_FIFO_READ (0x4000) /* Set FIFO to read mode (read from Buffer) */
-#define SEEQCMD_FIFO_WRITE (0x8000) /* Set FIFO to write mode */
-
-#define SEEQSTAT_DMA_INT_EN (0x0001) /* Status of interrupt enable */
-#define SEEQSTAT_RX_INT_EN (0x0002)
-#define SEEQSTAT_TX_INT_EN (0x0004)
-#define SEEQSTAT_WINDOW_INT_EN (0x0008)
-
-#define SEEQSTAT_DMA_INT (0x0010) /* Interrupt flagged */
-#define SEEQSTAT_RX_INT (0x0020)
-#define SEEQSTAT_TX_INT (0x0040)
-#define SEEQSTAT_WINDOW_INT (0x0080)
-#define SEEQSTAT_ANY_INT (0x00f0)
-
-#define SEEQSTAT_DMA_ON (0x0100) /* DMA logic on */
-#define SEEQSTAT_RX_ON (0x0200) /* Packet RX on */
-#define SEEQSTAT_TX_ON (0x0400) /* TX running */
-
-#define SEEQSTAT_FIFO_FULL (0x2000)
-#define SEEQSTAT_FIFO_EMPTY (0x4000)
-#define SEEQSTAT_FIFO_DIR (0x8000) /* 1=read, 0=write */
-
-#define SEEQCFG1_BUFFER_MASK (0x000f) /* define what mapps into the BUFFER register */
-#define SEEQCFG1_BUFFER_MAC0 (0x0000) /* MAC station addresses 0-5 */
-#define SEEQCFG1_BUFFER_MAC1 (0x0001)
-#define SEEQCFG1_BUFFER_MAC2 (0x0002)
-#define SEEQCFG1_BUFFER_MAC3 (0x0003)
-#define SEEQCFG1_BUFFER_MAC4 (0x0004)
-#define SEEQCFG1_BUFFER_MAC5 (0x0005)
-#define SEEQCFG1_BUFFER_PROM (0x0006) /* The Address/CFG PROM */
-#define SEEQCFG1_BUFFER_TEA (0x0007) /* Transmit end area */
-#define SEEQCFG1_BUFFER_BUFFER (0x0008) /* Packet buffer memory */
-#define SEEQCFG1_BUFFER_INT_VEC (0x0009) /* Interrupt Vector */
-
-#define SEEQCFG1_DMA_INTVL_MASK (0x0030)
-#define SEEQCFG1_DMA_CONT (0x0000)
-#define SEEQCFG1_DMA_800ns (0x0010)
-#define SEEQCFG1_DMA_1600ns (0x0020)
-#define SEEQCFG1_DMA_3200ns (0x0030)
-
-#define SEEQCFG1_DMA_LEN_MASK (0x00c0)
-#define SEEQCFG1_DMA_LEN1 (0x0000)
-#define SEEQCFG1_DMA_LEN2 (0x0040)
-#define SEEQCFG1_DMA_LEN4 (0x0080)
-#define SEEQCFG1_DMA_LEN8 (0x00c0)
-
-#define SEEQCFG1_MAC_MASK (0x3f00) /* Dis/enable bits for MAC addresses */
-#define SEEQCFG1_MAC0_EN (0x0100)
-#define SEEQCFG1_MAC1_EN (0x0200)
-#define SEEQCFG1_MAC2_EN (0x0400)
-#define SEEQCFG1_MAC3_EN (0x0800)
-#define SEEQCFG1_MAC4_EN (0x1000)
-#define SEEQCFG1_MAC5_EN (0x2000)
-
-#define SEEQCFG1_MATCH_MASK (0xc000) /* Packet matching logic cfg bits */
-#define SEEQCFG1_MATCH_SPECIFIC (0x0000) /* only matching MAC addresses */
-#define SEEQCFG1_MATCH_BROAD (0x4000) /* matching and broadcast addresses */
-#define SEEQCFG1_MATCH_MULTI (0x8000) /* matching, broadcast and multicast */
-#define SEEQCFG1_MATCH_ALL (0xc000) /* Promiscuous mode */
-
-#define SEEQCFG1_DEFAULT (SEEQCFG1_BUFFER_BUFFER | SEEQCFG1_MAC0_EN | SEEQCFG1_MATCH_BROAD)
-
-#define SEEQCFG2_BYTE_SWAP (0x0001) /* 0=Intel byte-order */
-#define SEEQCFG2_AUTO_REA (0x0002) /* if set, Receive End Area will be updated when reading from Buffer */
-
-#define SEEQCFG2_CRC_ERR_EN (0x0008) /* enables receiving of packets with CRC errors */
-#define SEEQCFG2_DRIBBLE_EN (0x0010) /* enables receiving of non-aligned packets */
-#define SEEQCFG2_SHORT_EN (0x0020) /* enables receiving of short packets */
-
-#define SEEQCFG2_SLOTSEL (0x0040) /* 0= standard IEEE802.3, 1= smaller,faster, non-standard */
-#define SEEQCFG2_NO_PREAM (0x0080) /* 1= user supplies Xmit preamble bytes */
-#define SEEQCFG2_ADDR_LEN (0x0100) /* 1= 2byte addresses */
-#define SEEQCFG2_REC_CRC (0x0200) /* 0= received packets will have CRC stripped from them */
-#define SEEQCFG2_XMIT_NO_CRC (0x0400) /* dont xmit CRC with each packet (user supplies it) */
-#define SEEQCFG2_LOOPBACK (0x0800)
-#define SEEQCFG2_CTRLO (0x1000)
-#define SEEQCFG2_RESET (0x8000) /* software Hard-reset bit */
-
-struct seeq_pkt_hdr {
- unsigned short next; /* address of next packet header */
- unsigned char babble_int:1, /* enable int on >1514 byte packet */
- coll_int:1, /* enable int on collision */
- coll_16_int:1, /* enable int on >15 collision */
- xmit_int:1, /* enable int on success (or xmit with <15 collision) */
- unused:1,
- data_follows:1, /* if not set, process this as a header and pointer only */
- chain_cont:1, /* if set, more headers in chain only cmd bit valid in recv header */
- xmit_recv:1; /* if set, a xmit packet, else a receive packet.*/
- unsigned char status;
-};
-
-#define SEEQPKTH_BAB_INT_EN (0x01) /* xmit only */
-#define SEEQPKTH_COL_INT_EN (0x02) /* xmit only */
-#define SEEQPKTH_COL16_INT_EN (0x04) /* xmit only */
-#define SEEQPKTH_XMIT_INT_EN (0x08) /* xmit only */
-#define SEEQPKTH_DATA_FOLLOWS (0x20) /* supposedly in xmit only */
-#define SEEQPKTH_CHAIN (0x40) /* more headers follow */
-#define SEEQPKTH_XMIT (0x80)
-
-#define SEEQPKTS_BABBLE (0x0100) /* xmit only */
-#define SEEQPKTS_OVERSIZE (0x0100) /* recv only */
-#define SEEQPKTS_COLLISION (0x0200) /* xmit only */
-#define SEEQPKTS_CRC_ERR (0x0200) /* recv only */
-#define SEEQPKTS_COLL16 (0x0400) /* xmit only */
-#define SEEQPKTS_DRIB (0x0400) /* recv only */
-#define SEEQPKTS_SHORT (0x0800) /* recv only */
-#define SEEQPKTS_DONE (0x8000)
-#define SEEQPKTS_ANY_ERROR (0x0f00)
diff --git a/i386/i386at/gpl/linux/net/sk_g16.c b/i386/i386at/gpl/linux/net/sk_g16.c
deleted file mode 100644
index 83989485..00000000
--- a/i386/i386at/gpl/linux/net/sk_g16.c
+++ /dev/null
@@ -1,2111 +0,0 @@
-/*-
- * Copyright (C) 1994 by PJD Weichmann & SWS Bern, Switzerland
- *
- * This software may be used and distributed according to the terms
- * of the GNU Public License, incorporated herein by reference.
- *
- * Module : sk_g16.c
- *
- * Version : $Revision: 1.1.1.1 $
- *
- * Author : Patrick J.D. Weichmann
- *
- * Date Created : 94/05/26
- * Last Updated : $Date: 1997/02/25 21:27:39 $
- *
- * Description : Schneider & Koch G16 Ethernet Device Driver for
- * Linux Kernel >= 1.1.22
- * Update History :
- *
--*/
-
-static const char *rcsid = "$Id: sk_g16.c,v 1.1.1.1 1997/02/25 21:27:39 thomas Exp $";
-
-/*
- * The Schneider & Koch (SK) G16 Network device driver is based
- * on the 'ni6510' driver from Michael Hipp which can be found at
- * ftp://sunsite.unc.edu/pub/Linux/system/Network/drivers/nidrivers.tar.gz
- *
- * Sources: 1) ni6510.c by M. Hipp
- * 2) depca.c by D.C. Davies
- * 3) skeleton.c by D. Becker
- * 4) Am7990 Local Area Network Controller for Ethernet (LANCE),
- * AMD, Pub. #05698, June 1989
- *
- * Many Thanks for helping me to get things working to:
- *
- * A. Cox (A.Cox@swansea.ac.uk)
- * M. Hipp (mhipp@student.uni-tuebingen.de)
- * R. Bolz (Schneider & Koch, Germany)
- *
- * See README.sk_g16 for details about limitations and bugs for the
- * current version.
- *
- * To Do:
- * - Support of SK_G8 and other SK Network Cards.
- * - Autoset memory mapped RAM. Check for free memory and then
- * configure RAM correctly.
- * - SK_close should really set card in to initial state.
- * - Test if IRQ 3 is not switched off. Use autoirq() functionality.
- * (as in /drivers/net/skeleton.c)
- * - Implement Multicast addressing. At minimum something like
- * in depca.c.
- * - Redo the statistics part.
- * - Try to find out if the board is in 8 Bit or 16 Bit slot.
- * If in 8 Bit mode don't use IRQ 11.
- * - (Try to make it slightly faster.)
- */
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-#include <linux/fcntl.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/malloc.h>
-#include <linux/ioport.h>
-#include <linux/string.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/bitops.h>
-#include <linux/errno.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-
-#include "sk_g16.h"
-
-/*
- * Schneider & Koch Card Definitions
- * =================================
- */
-
-#define SK_NAME "SK_G16"
-
-/*
- * SK_G16 Configuration
- * --------------------
- */
-
-/*
- * Abbreviations
- * -------------
- *
- * RAM - used for the 16KB shared memory
- * Boot_ROM, ROM - are used for referencing the BootEPROM
- *
- * SK_BOOT_ROM and SK_ADDR are symbolic constants used to configure
- * the behaviour of the driver and the SK_G16.
- *
- * ! See sk_g16.install on how to install and configure the driver !
- *
- * SK_BOOT_ROM defines if the Boot_ROM should be switched off or not.
- *
- * SK_ADDR defines the address where the RAM will be mapped into the real
- * host memory.
- * valid addresses are from 0xa0000 to 0xfc000 in 16Kbyte steps.
- */
-
-#define SK_BOOT_ROM 1 /* 1=BootROM on 0=off */
-
-#define SK_ADDR 0xcc000
-
-/*
- * In POS3 are bits A14-A19 of the address bus. These bits can be set
- * to choose the RAM address. Thats why we only can choose the RAM address
- * in 16KB steps.
- */
-
-#define POS_ADDR (rom_addr>>14) /* Do not change this line */
-
-/*
- * SK_G16 I/O PORT's + IRQ's + Boot_ROM locations
- * ----------------------------------------------
- */
-
-/*
- * As nearly every card has also SK_G16 a specified I/O Port region and
- * only a few possible IRQ's.
- * In the Installation Guide from Schneider & Koch is listed a possible
- * Interrupt IRQ2. IRQ2 is always IRQ9 in boards with two cascaded interrupt
- * controllers. So we use in SK_IRQS IRQ9.
- */
-
-/* Don't touch any of the following #defines. */
-
-#define SK_IO_PORTS { 0x100, 0x180, 0x208, 0x220, 0x288, 0x320, 0x328, 0x390, 0 }
-
-#define SK_IRQS { 3, 5, 9, 11, 0 }
-
-#define SK_BOOT_ROM_LOCATIONS { 0xc0000, 0xc4000, 0xc8000, 0xcc000, 0xd0000, 0xd4000, 0xd8000, 0xdc000, 0 }
-
-#define SK_BOOT_ROM_ID { 0x55, 0xaa, 0x10, 0x50, 0x06, 0x33 }
-
-/*
- * SK_G16 POS REGISTERS
- * --------------------
- */
-
-/*
- * SK_G16 has a Programmable Option Select (POS) Register.
- * The POS is composed of 8 separate registers (POS0-7) which
- * are I/O mapped on an address set by the W1 switch.
- *
- */
-
-#define SK_POS_SIZE 8 /* 8 I/O Ports are used by SK_G16 */
-
-#define SK_POS0 ioaddr /* Card-ID Low (R) */
-#define SK_POS1 ioaddr+1 /* Card-ID High (R) */
-#define SK_POS2 ioaddr+2 /* Card-Enable, Boot-ROM Disable (RW) */
-#define SK_POS3 ioaddr+3 /* Base address of RAM */
-#define SK_POS4 ioaddr+4 /* IRQ */
-
-/* POS5 - POS7 are unused */
-
-/*
- * SK_G16 MAC PREFIX
- * -----------------
- */
-
-/*
- * Scheider & Koch manufacturer code (00:00:a5).
- * This must be checked, that we are sure it is a SK card.
- */
-
-#define SK_MAC0 0x00
-#define SK_MAC1 0x00
-#define SK_MAC2 0x5a
-
-/*
- * SK_G16 ID
- * ---------
- */
-
-/*
- * If POS0,POS1 contain the following ID, then we know
- * at which I/O Port Address we are.
- */
-
-#define SK_IDLOW 0xfd
-#define SK_IDHIGH 0x6a
-
-
-/*
- * LANCE POS Bit definitions
- * -------------------------
- */
-
-#define SK_ROM_RAM_ON (POS2_CARD)
-#define SK_ROM_RAM_OFF (POS2_EPROM)
-#define SK_ROM_ON (inb(SK_POS2) & POS2_CARD)
-#define SK_ROM_OFF (inb(SK_POS2) | POS2_EPROM)
-#define SK_RAM_ON (inb(SK_POS2) | POS2_CARD)
-#define SK_RAM_OFF (inb(SK_POS2) & POS2_EPROM)
-
-#define POS2_CARD 0x0001 /* 1 = SK_G16 on 0 = off */
-#define POS2_EPROM 0x0002 /* 1 = Boot EPROM off 0 = on */
-
-/*
- * SK_G16 Memory mapped Registers
- * ------------------------------
- *
- */
-
-#define SK_IOREG (board->ioreg) /* LANCE data registers. */
-#define SK_PORT (board->port) /* Control, Status register */
-#define SK_IOCOM (board->iocom) /* I/O Command */
-
-/*
- * SK_G16 Status/Control Register bits
- * -----------------------------------
- *
- * (C) Controlreg (S) Statusreg
- */
-
-/*
- * Register transfer: 0 = no transfer
- * 1 = transferring data between LANCE and I/O reg
- */
-#define SK_IORUN 0x20
-
-/*
- * LANCE interrupt: 0 = LANCE interrupt occurred
- * 1 = no LANCE interrupt occurred
- */
-#define SK_IRQ 0x10
-
-#define SK_RESET 0x08 /* Reset SK_CARD: 0 = RESET 1 = normal */
-#define SK_RW 0x02 /* 0 = write to 1 = read from */
-#define SK_ADR 0x01 /* 0 = REG DataPort 1 = RAP Reg addr port */
-
-
-#define SK_RREG SK_RW /* Transferdirection to read from lance */
-#define SK_WREG 0 /* Transferdirection to write to lance */
-#define SK_RAP SK_ADR /* Destination Register RAP */
-#define SK_RDATA 0 /* Destination Register REG DataPort */
-
-/*
- * SK_G16 I/O Command
- * ------------------
- */
-
-/*
- * Any bitcombination sets the internal I/O bit (transfer will start)
- * when written to I/O Command
- */
-
-#define SK_DOIO 0x80 /* Do Transfer */
-
-/*
- * LANCE RAP (Register Address Port).
- * ---------------------------------
- */
-
-/*
- * The LANCE internal registers are selected through the RAP.
- * The Registers are:
- *
- * CSR0 - Status and Control flags
- * CSR1 - Low order bits of initialize block (bits 15:00)
- * CSR2 - High order bits of initialize block (bits 07:00, 15:08 are reserved)
- * CSR3 - Allows redefinition of the Bus Master Interface.
- * This register must be set to 0x0002, which means BSWAP = 0,
- * ACON = 1, BCON = 0;
- *
- */
-
-#define CSR0 0x00
-#define CSR1 0x01
-#define CSR2 0x02
-#define CSR3 0x03
-
-/*
- * General Definitions
- * ===================
- */
-
-/*
- * Set the number of Tx and Rx buffers, using Log_2(# buffers).
- * We have 16KB RAM which can be accessed by the LANCE. In the
- * memory are not only the buffers but also the ring descriptors and
- * the initialize block.
- * Don't change anything unless you really know what you do.
- */
-
-#define LC_LOG_TX_BUFFERS 1 /* (2 == 2^^1) 2 Transmit buffers */
-#define LC_LOG_RX_BUFFERS 3 /* (8 == 2^^3) 8 Receive buffers */
-
-/* Descriptor ring sizes */
-
-#define TMDNUM (1 << (LC_LOG_TX_BUFFERS)) /* 2 Transmit descriptor rings */
-#define RMDNUM (1 << (LC_LOG_RX_BUFFERS)) /* 8 Receive Buffers */
-
-/* Define Mask for setting RMD, TMD length in the LANCE init_block */
-
-#define TMDNUMMASK (LC_LOG_TX_BUFFERS << 29)
-#define RMDNUMMASK (LC_LOG_RX_BUFFERS << 29)
-
-/*
- * Data Buffer size is set to maximum packet length.
- */
-
-#define PKT_BUF_SZ 1518
-
-/*
- * The number of low I/O ports used by the ethercard.
- */
-
-#define ETHERCARD_TOTAL_SIZE SK_POS_SIZE
-
-/*
- * Portreserve is there to mark the Card I/O Port region as used.
- * Check_region is to check if the region at ioaddr with the size "size"
- * is free or not.
- * Snarf_region allocates the I/O Port region.
- */
-
-#ifndef HAVE_PORTRESERVE
-
-#define check_region(ioaddr, size) 0
-#define request_region(ioaddr, size,name) do ; while (0)
-
-#endif
-
-/*
- * SK_DEBUG
- *
- * Here you can choose what level of debugging wanted.
- *
- * If SK_DEBUG and SK_DEBUG2 are undefined, then only the
- * necessary messages will be printed.
- *
- * If SK_DEBUG is defined, there will be many debugging prints
- * which can help to find some mistakes in configuration or even
- * in the driver code.
- *
- * If SK_DEBUG2 is defined, many many messages will be printed
- * which normally you don't need. I used this to check the interrupt
- * routine.
- *
- * (If you define only SK_DEBUG2 then only the messages for
- * checking interrupts will be printed!)
- *
- * Normal way of live is:
- *
- * For the whole thing get going let both symbolic constants
- * undefined. If you face any problems and you know what's going
- * on (you know something about the card and you can interpret some
- * hex LANCE register output) then define SK_DEBUG
- *
- */
-
-#undef SK_DEBUG /* debugging */
-#undef SK_DEBUG2 /* debugging with more verbose report */
-
-#ifdef SK_DEBUG
-#define PRINTK(x) printk x
-#else
-#define PRINTK(x) /**/
-#endif
-
-#ifdef SK_DEBUG2
-#define PRINTK2(x) printk x
-#else
-#define PRINTK2(x) /**/
-#endif
-
-/*
- * SK_G16 RAM
- *
- * The components are memory mapped and can be set in a region from
- * 0x00000 through 0xfc000 in 16KB steps.
- *
- * The Network components are: dual ported RAM, Prom, I/O Reg, Status-,
- * Controlregister and I/O Command.
- *
- * dual ported RAM: This is the only memory region which the LANCE chip
- * has access to. From the Lance it is addressed from 0x0000 to
- * 0x3fbf. The host accesses it normally.
- *
- * PROM: The PROM obtains the ETHERNET-MAC-Address. It is realised as a
- * 8-Bit PROM, this means only the 16 even addresses are used of the
- * 32 Byte Address region. Access to a odd address results in invalid
- * data.
- *
- * LANCE I/O Reg: The I/O Reg is build of 4 single Registers, Low-Byte Write,
- * Hi-Byte Write, Low-Byte Read, Hi-Byte Read.
- * Transfer from or to the LANCE is always in 16Bit so Low and High
- * registers are always relevant.
- *
- * The Data from the Readregister is not the data in the Writeregister!!
- *
- * Port: Status- and Controlregister.
- * Two different registers which share the same address, Status is
- * read-only, Control is write-only.
- *
- * I/O Command:
- * Any bitcombination written in here starts the transmission between
- * Host and LANCE.
- */
-
-typedef struct
-{
- unsigned char ram[0x3fc0]; /* 16KB dual ported ram */
- unsigned char rom[0x0020]; /* 32Byte PROM containing 6Byte MAC */
- unsigned char res1[0x0010]; /* reserved */
- unsigned volatile short ioreg;/* LANCE I/O Register */
- unsigned volatile char port; /* Statusregister and Controlregister */
- unsigned char iocom; /* I/O Command Register */
-} SK_RAM;
-
-/* struct */
-
-/*
- * This is the structure for the dual ported ram. We
- * have exactly 16 320 Bytes. In here there must be:
- *
- * - Initialize Block (starting at a word boundary)
- * - Receive and Transmit Descriptor Rings (quadword boundary)
- * - Data Buffers (arbitrary boundary)
- *
- * This is because LANCE has on SK_G16 only access to the dual ported
- * RAM and nowhere else.
- */
-
-struct SK_ram
-{
- struct init_block ib;
- struct tmd tmde[TMDNUM];
- struct rmd rmde[RMDNUM];
- char tmdbuf[TMDNUM][PKT_BUF_SZ];
- char rmdbuf[RMDNUM][PKT_BUF_SZ];
-};
-
-/*
- * Structure where all necessary information is for ring buffer
- * management and statistics.
- */
-
-struct priv
-{
- struct SK_ram *ram; /* dual ported ram structure */
- struct rmd *rmdhead; /* start of receive ring descriptors */
- struct tmd *tmdhead; /* start of transmit ring descriptors */
- int rmdnum; /* actual used ring descriptor */
- int tmdnum; /* actual transmit descriptor for transmitting data */
- int tmdlast; /* last sent descriptor used for error handling, etc */
- void *rmdbufs[RMDNUM]; /* pointer to the receive buffers */
- void *tmdbufs[TMDNUM]; /* pointer to the transmit buffers */
- struct enet_statistics stats; /* Device driver statistics */
-};
-
-/* global variable declaration */
-
-/* IRQ map used to reserve a IRQ (see SK_open()) */
-
-/* extern void *irq2dev_map[16]; */ /* Declared in <linux/ioport.h> */
-
-/* static variables */
-
-static SK_RAM *board; /* pointer to our memory mapped board components */
-
-/* Macros */
-
-
-/* Function Prototypes */
-
-/*
- * Device Driver functions
- * -----------------------
- * See for short explanation of each function its definitions header.
- */
-
-int SK_init(struct device *dev);
-static int SK_probe(struct device *dev, short ioaddr);
-
-static int SK_open(struct device *dev);
-static int SK_send_packet(struct sk_buff *skb, struct device *dev);
-static void SK_interrupt(int irq, struct pt_regs * regs);
-static void SK_rxintr(struct device *dev);
-static void SK_txintr(struct device *dev);
-static int SK_close(struct device *dev);
-
-static struct enet_statistics *SK_get_stats(struct device *dev);
-
-unsigned int SK_rom_addr(void);
-
-static void set_multicast_list(struct device *dev);
-
-/*
- * LANCE Functions
- * ---------------
- */
-
-static int SK_lance_init(struct device *dev, unsigned short mode);
-void SK_reset_board(void);
-void SK_set_RAP(int reg_number);
-int SK_read_reg(int reg_number);
-int SK_rread_reg(void);
-void SK_write_reg(int reg_number, int value);
-
-/*
- * Debugging functions
- * -------------------
- */
-
-void SK_print_pos(struct device *dev, char *text);
-void SK_print_dev(struct device *dev, char *text);
-void SK_print_ram(struct device *dev);
-
-
-/*-
- * Function : SK_init
- * Author : Patrick J.D. Weichmann
- * Date Created : 94/05/26
- *
- * Description : Check for a SK_G16 network adaptor and initialize it.
- * This function gets called by dev_init which initializes
- * all Network devices.
- *
- * Parameters : I : struct device *dev - structure preconfigured
- * from Space.c
- * Return Value : 0 = Driver Found and initialized
- * Errors : ENODEV - no device found
- * ENXIO - not probed
- * Globals : None
- * Update History :
- * YY/MM/DD uid Description
--*/
-
-/*
- * Check for a network adaptor of this type, and return '0' if one exists.
- * If dev->base_addr == 0, probe all likely locations.
- * If dev->base_addr == 1, always return failure.
- * If dev->base_addr == 2, allocate space for the device and return success
- * (detachable devices only).
- */
-
-int SK_init(struct device *dev)
-{
- int ioaddr = 0; /* I/O port address used for POS regs */
- int *port, ports[] = SK_IO_PORTS; /* SK_G16 supported ports */
-
- /* get preconfigured base_addr from dev which is done in Space.c */
- int base_addr = dev->base_addr;
-
- PRINTK(("%s: %s", SK_NAME, rcsid));
- rcsid = NULL; /* We do not want to use this further */
-
- if (base_addr > 0x0ff) /* Check a single specified address */
- {
- /* Check if on specified address is a SK_G16 */
-
- if ( (inb(SK_POS0) == SK_IDLOW) ||
- (inb(SK_POS1) == SK_IDHIGH) )
- {
- return SK_probe(dev, base_addr);
- }
-
- return ENODEV; /* Sorry, but on specified address NO SK_G16 */
- }
- else if (base_addr > 0) /* Don't probe at all */
- {
- return ENXIO;
- }
-
- /* Autoprobe base_addr */
-
- for (port = &ports[0]; *port; port++)
- {
- ioaddr = *port; /* we need ioaddr for accessing POS regs */
-
- /* Check if I/O Port region is used by another board */
-
- if (check_region(ioaddr, ETHERCARD_TOTAL_SIZE))
- {
- continue; /* Try next Port address */
- }
-
- /* Check if at ioaddr is a SK_G16 */
-
- if ( !(inb(SK_POS0) == SK_IDLOW) ||
- !(inb(SK_POS1) == SK_IDHIGH) )
- {
- continue; /* Try next Port address */
- }
-
- dev->base_addr = ioaddr; /* Set I/O Port Address */
-
- if (SK_probe(dev, ioaddr) == 0)
- {
- return 0; /* Card found and initialized */
- }
- }
-
- dev->base_addr = base_addr; /* Write back original base_addr */
-
- return ENODEV; /* Failed to find or init driver */
-
-} /* End of SK_init */
-
-
-/*-
- * Function : SK_probe
- * Author : Patrick J.D. Weichmann
- * Date Created : 94/05/26
- *
- * Description : This function is called by SK_init and
- * does the main part of initialization.
- *
- * Parameters : I : struct device *dev - SK_G16 device structure
- * I : short ioaddr - I/O Port address where POS is.
- * Return Value : 0 = Initialization done
- * Errors : ENODEV - No SK_G16 found
- * -1 - Configuration problem
- * Globals : irq2dev_map - Which device uses which IRQ
- * : board - pointer to SK_RAM
- * Update History :
- * YY/MM/DD uid Description
- * 94/06/30 pwe SK_ADDR now checked and at the correct place
--*/
-
-int SK_probe(struct device *dev, short ioaddr)
-{
- int i,j; /* Counters */
- int sk_addr_flag = 0; /* SK ADDR correct? 1 - no, 0 - yes */
- unsigned int rom_addr; /* used to store RAM address used for POS_ADDR */
-
- struct priv *p; /* SK_G16 private structure */
-
- if (SK_ADDR & 0x3fff || SK_ADDR < 0xa0000)
- {
-
- sk_addr_flag = 1;
-
- /*
- * Now here we could use a routine which searches for a free
- * place in the ram and set SK_ADDR if found. TODO.
- */
- }
-
- if (SK_BOOT_ROM) /* Shall we keep Boot_ROM on ? */
- {
- PRINTK(("## %s: SK_BOOT_ROM is set.\n", SK_NAME));
-
- rom_addr = SK_rom_addr();
-
- if (rom_addr == 0) /* No Boot_ROM found */
- {
- if (sk_addr_flag) /* No or Invalid SK_ADDR is defined */
- {
- printk("%s: SK_ADDR %#08x is not valid. Check configuration.\n",
- dev->name, SK_ADDR);
- return -1;
- }
-
- rom_addr = SK_ADDR; /* assign predefined address */
-
- PRINTK(("## %s: NO Bootrom found \n", SK_NAME));
-
- outb(SK_ROM_RAM_OFF, SK_POS2); /* Boot_ROM + RAM off */
- outb(POS_ADDR, SK_POS3); /* Set RAM address */
- outb(SK_RAM_ON, SK_POS2); /* enable RAM */
- }
- else if (rom_addr == SK_ADDR)
- {
- printk("%s: RAM + ROM are set to the same address %#08x\n"
- " Check configuration. Now switching off Boot_ROM\n",
- SK_NAME, rom_addr);
-
- outb(SK_ROM_RAM_OFF, SK_POS2); /* Boot_ROM + RAM off*/
- outb(POS_ADDR, SK_POS3); /* Set RAM address */
- outb(SK_RAM_ON, SK_POS2); /* enable RAM */
- }
- else
- {
- PRINTK(("## %s: Found ROM at %#08x\n", SK_NAME, rom_addr));
- PRINTK(("## %s: Keeping Boot_ROM on\n", SK_NAME));
-
- if (sk_addr_flag) /* No or Invalid SK_ADDR is defined */
- {
- printk("%s: SK_ADDR %#08x is not valid. Check configuration.\n",
- dev->name, SK_ADDR);
- return -1;
- }
-
- rom_addr = SK_ADDR;
-
- outb(SK_ROM_RAM_OFF, SK_POS2); /* Boot_ROM + RAM off */
- outb(POS_ADDR, SK_POS3); /* Set RAM address */
- outb(SK_ROM_RAM_ON, SK_POS2); /* RAM on, BOOT_ROM on */
- }
- }
- else /* Don't keep Boot_ROM */
- {
- PRINTK(("## %s: SK_BOOT_ROM is not set.\n", SK_NAME));
-
- if (sk_addr_flag) /* No or Invalid SK_ADDR is defined */
- {
- printk("%s: SK_ADDR %#08x is not valid. Check configuration.\n",
- dev->name, SK_ADDR);
- return -1;
- }
-
- rom_addr = SK_rom_addr(); /* Try to find a Boot_ROM */
-
- /* IF we find a Boot_ROM disable it */
-
- outb(SK_ROM_RAM_OFF, SK_POS2); /* Boot_ROM + RAM off */
-
- /* We found a Boot_ROM and it's gone. Set RAM address on
- * Boot_ROM address.
- */
-
- if (rom_addr)
- {
- printk("%s: We found Boot_ROM at %#08x. Now setting RAM on"
- "that address\n", SK_NAME, rom_addr);
-
- outb(POS_ADDR, SK_POS3); /* Set RAM on Boot_ROM address */
- }
- else /* We did not find a Boot_ROM, use predefined SK_ADDR for ram */
- {
- if (sk_addr_flag) /* No or Invalid SK_ADDR is defined */
- {
- printk("%s: SK_ADDR %#08x is not valid. Check configuration.\n",
- dev->name, SK_ADDR);
- return -1;
- }
-
- rom_addr = SK_ADDR;
-
- outb(POS_ADDR, SK_POS3); /* Set RAM address */
- }
- outb(SK_RAM_ON, SK_POS2); /* enable RAM */
- }
-
-#ifdef SK_DEBUG
- SK_print_pos(dev, "POS registers after ROM, RAM config");
-#endif
-
- board = (SK_RAM *) rom_addr;
-
- /* Read in station address */
- for (i = 0, j = 0; i < ETH_ALEN; i++, j+=2)
- {
- dev->dev_addr[i] = board->rom[j];
- }
-
- /* Check for manufacturer code */
- if (!(dev->dev_addr[0] == SK_MAC0 &&
- dev->dev_addr[1] == SK_MAC1 &&
- dev->dev_addr[2] == SK_MAC2) )
- {
- PRINTK(("## %s: We did not find SK_G16 at RAM location.\n",
- SK_NAME));
- return ENODEV; /* NO SK_G16 found */
- }
-
- printk("%s: %s found at %#3x, HW addr: %#04x:%02x:%02x:%02x:%02x:%02x\n",
- dev->name,
- "Schneider & Koch Netcard",
- (unsigned int) dev->base_addr,
- dev->dev_addr[0],
- dev->dev_addr[1],
- dev->dev_addr[2],
- dev->dev_addr[3],
- dev->dev_addr[4],
- dev->dev_addr[5]);
-
- /* Grab the I/O Port region */
- request_region(ioaddr, ETHERCARD_TOTAL_SIZE,"sk_g16");
-
- /* Initialize device structure */
-
- /* Allocate memory for private structure */
- p = dev->priv = (void *) kmalloc(sizeof(struct priv), GFP_KERNEL);
- if (p == NULL)
- return -ENOMEM;
- memset((char *) dev->priv, 0, sizeof(struct priv)); /* clear memory */
-
- /* Assign our Device Driver functions */
-
- dev->open = &SK_open;
- dev->stop = &SK_close;
- dev->hard_start_xmit = &SK_send_packet;
- dev->get_stats = &SK_get_stats;
- dev->set_multicast_list = &set_multicast_list;
-
-
- /* Set the generic fields of the device structure */
-
- ether_setup(dev);
-
- dev->flags &= ~IFF_MULTICAST;
-
- /* Initialize private structure */
-
- p->ram = (struct SK_ram *) rom_addr; /* Set dual ported RAM addr */
- p->tmdhead = &(p->ram)->tmde[0]; /* Set TMD head */
- p->rmdhead = &(p->ram)->rmde[0]; /* Set RMD head */
-
- /* Initialize buffer pointers */
-
- for (i = 0; i < TMDNUM; i++)
- {
- p->tmdbufs[i] = &(p->ram)->tmdbuf[i];
- }
-
- for (i = 0; i < RMDNUM; i++)
- {
- p->rmdbufs[i] = &(p->ram)->rmdbuf[i];
- }
-
-#ifdef SK_DEBUG
- SK_print_pos(dev, "End of SK_probe");
- SK_print_ram(dev);
-#endif
-
- return 0; /* Initialization done */
-
-} /* End of SK_probe() */
-
-
-/*-
- * Function : SK_open
- * Author : Patrick J.D. Weichmann
- * Date Created : 94/05/26
- *
- * Description : This function is called sometimes after booting
- * when ifconfig program is run.
- *
- * This function requests an IRQ, sets the correct
- * IRQ in the card. Then calls SK_lance_init() to
- * init and start the LANCE chip. Then if everything is
- * ok returns with 0 (OK), which means SK_G16 is now
- * opened and operational.
- *
- * (Called by dev_open() /net/inet/dev.c)
- *
- * Parameters : I : struct device *dev - SK_G16 device structure
- * Return Value : 0 - Device opened
- * Errors : -EAGAIN - Open failed
- * Globals : irq2dev_map - which device uses which irq
- * Side Effects : None
- * Update History :
- * YY/MM/DD uid Description
--*/
-
-static int SK_open(struct device *dev)
-{
- int i = 0;
- int irqval = 0;
- int ioaddr = dev->base_addr;
-
- int irqtab[] = SK_IRQS;
-
- struct priv *p = (struct priv *)dev->priv;
-
- PRINTK(("## %s: At beginning of SK_open(). CSR0: %#06x\n",
- SK_NAME, SK_read_reg(CSR0)));
-
- if (dev->irq == 0) /* Autoirq */
- {
- i = 0;
-
- /*
- * Check if one IRQ out of SK_IRQS is free and install
- * interrupt handler.
- * Most done by request_irq().
- * irqval: 0 - interrupt handler installed for IRQ irqtab[i]
- * -EBUSY - interrupt busy
- * -EINVAL - irq > 15 or handler = NULL
- */
-
- do
- {
- irqval = request_irq(irqtab[i], &SK_interrupt, 0, "sk_g16");
- i++;
- } while (irqval && irqtab[i]);
-
- if (irqval) /* We tried every possible IRQ but no success */
- {
- printk("%s: unable to get an IRQ\n", dev->name);
- return -EAGAIN;
- }
-
- dev->irq = irqtab[--i];
-
- outb(i<<2, SK_POS4); /* Set Card on probed IRQ */
-
- }
- else if (dev->irq == 2) /* IRQ2 is always IRQ9 */
- {
- if (request_irq(9, &SK_interrupt, 0, "sk_g16"))
- {
- printk("%s: unable to get IRQ 9\n", dev->name);
- return -EAGAIN;
- }
- dev->irq = 9;
-
- /*
- * Now we set card on IRQ2.
- * This can be confusing, but remember that IRQ2 on the network
- * card is in reality IRQ9
- */
- outb(0x08, SK_POS4); /* set card to IRQ2 */
-
- }
- else /* Check IRQ as defined in Space.c */
- {
- int i = 0;
-
- /* check if IRQ free and valid. Then install Interrupt handler */
-
- if (request_irq(dev->irq, &SK_interrupt, 0, "sk_g16"))
- {
- printk("%s: unable to get selected IRQ\n", dev->name);
- return -EAGAIN;
- }
-
- switch(dev->irq)
- {
- case 3: i = 0;
- break;
- case 5: i = 1;
- break;
- case 2: i = 2;
- break;
- case 11:i = 3;
- break;
- default:
- printk("%s: Preselected IRQ %d is invalid for %s boards",
- dev->name,
- dev->irq,
- SK_NAME);
- return -EAGAIN;
- }
-
- outb(i<<2, SK_POS4); /* Set IRQ on card */
- }
-
- irq2dev_map[dev->irq] = dev; /* Set IRQ as used by us */
-
- printk("%s: Schneider & Koch G16 at %#3x, IRQ %d, shared mem at %#08x\n",
- dev->name, (unsigned int)dev->base_addr,
- (int) dev->irq, (unsigned int) p->ram);
-
- if (!(i = SK_lance_init(dev, 0))) /* LANCE init OK? */
- {
-
-
- dev->tbusy = 0;
- dev->interrupt = 0;
- dev->start = 1;
-
-#ifdef SK_DEBUG
-
- /*
- * This debug block tries to stop LANCE,
- * reinit LANCE with transmitter and receiver disabled,
- * then stop again and reinit with NORMAL_MODE
- */
-
- printk("## %s: After lance init. CSR0: %#06x\n",
- SK_NAME, SK_read_reg(CSR0));
- SK_write_reg(CSR0, CSR0_STOP);
- printk("## %s: LANCE stopped. CSR0: %#06x\n",
- SK_NAME, SK_read_reg(CSR0));
- SK_lance_init(dev, MODE_DTX | MODE_DRX);
- printk("## %s: Reinit with DTX + DRX off. CSR0: %#06x\n",
- SK_NAME, SK_read_reg(CSR0));
- SK_write_reg(CSR0, CSR0_STOP);
- printk("## %s: LANCE stopped. CSR0: %#06x\n",
- SK_NAME, SK_read_reg(CSR0));
- SK_lance_init(dev, MODE_NORMAL);
- printk("## %s: LANCE back to normal mode. CSR0: %#06x\n",
- SK_NAME, SK_read_reg(CSR0));
- SK_print_pos(dev, "POS regs before returning OK");
-
-#endif /* SK_DEBUG */
-
- return 0; /* SK_open() is successful */
- }
- else /* LANCE init failed */
- {
-
- PRINTK(("## %s: LANCE init failed: CSR0: %#06x\n",
- SK_NAME, SK_read_reg(CSR0)));
-
- dev->start = 0; /* Device not ready */
- return -EAGAIN;
- }
-
-} /* End of SK_open() */
-
-
-/*-
- * Function : SK_lance_init
- * Author : Patrick J.D. Weichmann
- * Date Created : 94/05/26
- *
- * Description : Reset LANCE chip, fill RMD, TMD structures with
- * start values and Start LANCE.
- *
- * Parameters : I : struct device *dev - SK_G16 device structure
- * I : int mode - put LANCE into "mode" see data-sheet for
- * more info.
- * Return Value : 0 - Init done
- * Errors : -1 - Init failed
- * Update History :
- * YY/MM/DD uid Description
--*/
-
-static int SK_lance_init(struct device *dev, unsigned short mode)
-{
- int i;
- struct priv *p = (struct priv *) dev->priv;
- struct tmd *tmdp;
- struct rmd *rmdp;
-
- PRINTK(("## %s: At beginning of LANCE init. CSR0: %#06x\n",
- SK_NAME, SK_read_reg(CSR0)));
-
- /* Reset LANCE */
- SK_reset_board();
-
- /* Initialize TMD's with start values */
- p->tmdnum = 0; /* First descriptor for transmitting */
- p->tmdlast = 0; /* First descriptor for reading stats */
-
- for (i = 0; i < TMDNUM; i++) /* Init all TMD's */
- {
- tmdp = p->tmdhead + i;
-
- tmdp->u.buffer = (unsigned long) p->tmdbufs[i]; /* assign buffer */
-
- /* Mark TMD as start and end of packet */
- tmdp->u.s.status = TX_STP | TX_ENP;
- }
-
-
- /* Initialize RMD's with start values */
-
- p->rmdnum = 0; /* First RMD which will be used */
-
- for (i = 0; i < RMDNUM; i++) /* Init all RMD's */
- {
- rmdp = p->rmdhead + i;
-
-
- rmdp->u.buffer = (unsigned long) p->rmdbufs[i]; /* assign buffer */
-
- /*
- * LANCE must be owner at beginning so that he can fill in
- * receiving packets, set status and release RMD
- */
-
- rmdp->u.s.status = RX_OWN;
-
- rmdp->blen = -PKT_BUF_SZ; /* Buffer Size in a two's complement */
-
- rmdp->mlen = 0; /* init message length */
-
- }
-
- /* Fill LANCE Initialize Block */
-
- (p->ram)->ib.mode = mode; /* Set operation mode */
-
- for (i = 0; i < ETH_ALEN; i++) /* Set physical address */
- {
- (p->ram)->ib.paddr[i] = dev->dev_addr[i];
- }
-
- for (i = 0; i < 8; i++) /* Set multicast, logical address */
- {
- (p->ram)->ib.laddr[i] = 0; /* We do not use logical addressing */
- }
-
- /* Set ring descriptor pointers and set number of descriptors */
-
- (p->ram)->ib.rdrp = (int) p->rmdhead | RMDNUMMASK;
- (p->ram)->ib.tdrp = (int) p->tmdhead | TMDNUMMASK;
-
- /* Prepare LANCE Control and Status Registers */
-
- cli();
-
- SK_write_reg(CSR3, CSR3_ACON); /* Ale Control !!!THIS MUST BE SET!!!! */
-
- /*
- * LANCE addresses the RAM from 0x0000 to 0x3fbf and has no access to
- * PC Memory locations.
- *
- * In structure SK_ram is defined that the first thing in ram
- * is the initialization block. So his address is for LANCE always
- * 0x0000
- *
- * CSR1 contains low order bits 15:0 of initialization block address
- * CSR2 is built of:
- * 7:0 High order bits 23:16 of initialization block address
- * 15:8 reserved, must be 0
- */
-
- /* Set initialization block address (must be on word boundary) */
- SK_write_reg(CSR1, 0); /* Set low order bits 15:0 */
- SK_write_reg(CSR2, 0); /* Set high order bits 23:16 */
-
-
- PRINTK(("## %s: After setting CSR1-3. CSR0: %#06x\n",
- SK_NAME, SK_read_reg(CSR0)));
-
- /* Initialize LANCE */
-
- /*
- * INIT = Initialize, when set, causes the LANCE to begin the
- * initialization procedure and access the Init Block.
- */
-
- SK_write_reg(CSR0, CSR0_INIT);
-
- sti();
-
- /* Wait until LANCE finished initialization */
-
- SK_set_RAP(CSR0); /* Register Address Pointer to CSR0 */
-
- for (i = 0; (i < 100) && !(SK_rread_reg() & CSR0_IDON); i++)
- ; /* Wait until init done or go ahead if problems (i>=100) */
-
- if (i >= 100) /* Something is wrong ! */
- {
- printk("%s: can't init am7990, status: %04x "
- "init_block: %#08x\n",
- dev->name, (int) SK_read_reg(CSR0),
- (unsigned int) &(p->ram)->ib);
-
-#ifdef SK_DEBUG
- SK_print_pos(dev, "LANCE INIT failed");
- SK_print_dev(dev,"Device Structure:");
-#endif
-
- return -1; /* LANCE init failed */
- }
-
- PRINTK(("## %s: init done after %d ticks\n", SK_NAME, i));
-
- /* Clear Initialize done, enable Interrupts, start LANCE */
-
- SK_write_reg(CSR0, CSR0_IDON | CSR0_INEA | CSR0_STRT);
-
- PRINTK(("## %s: LANCE started. CSR0: %#06x\n", SK_NAME,
- SK_read_reg(CSR0)));
-
- return 0; /* LANCE is up and running */
-
-} /* End of SK_lance_init() */
-
-
-
-/*-
- * Function : SK_send_packet
- * Author : Patrick J.D. Weichmann
- * Date Created : 94/05/27
- *
- * Description : Writes an socket buffer into a transmit descriptor
- * and starts transmission.
- *
- * Parameters : I : struct sk_buff *skb - packet to transfer
- * I : struct device *dev - SK_G16 device structure
- * Return Value : 0 - OK
- * 1 - Could not transmit (dev_queue_xmit will queue it)
- * and try to sent it later
- * Globals : None
- * Side Effects : None
- * Update History :
- * YY/MM/DD uid Description
--*/
-
-static int SK_send_packet(struct sk_buff *skb, struct device *dev)
-{
- struct priv *p = (struct priv *) dev->priv;
- struct tmd *tmdp;
-
- if (dev->tbusy)
- {
- /* if Transmitter more than 150ms busy -> time_out */
-
- int tickssofar = jiffies - dev->trans_start;
- if (tickssofar < 15)
- {
- return 1; /* We have to try transmit later */
- }
-
- printk("%s: xmitter timed out, try to restart!\n", dev->name);
-
- SK_lance_init(dev, MODE_NORMAL); /* Reinit LANCE */
-
- dev->tbusy = 0; /* Clear Transmitter flag */
-
- dev->trans_start = jiffies; /* Mark Start of transmission */
-
- }
-
- /*
- * If some upper Layer thinks we missed a transmit done interrupt
- * we are passed NULL.
- * (dev_queue_xmit net/inet/dev.c
- */
-
- if (skb == NULL)
- {
- /*
- * Dequeue packets from transmit queue and send them.
- */
- dev_tint(dev);
-
- return 0;
- }
-
- PRINTK2(("## %s: SK_send_packet() called, CSR0 %#04x.\n",
- SK_NAME, SK_read_reg(CSR0)));
-
-
- /*
- * Block a timer-based transmit from overlapping.
- * This means check if we are already in.
- */
-
- if (set_bit(0, (void *) &dev->tbusy) != 0) /* dev->tbusy already set ? */
- {
- printk("%s: Transmitter access conflict.\n", dev->name);
- }
- else
- {
- /* Evaluate Packet length */
- short len = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
-
- tmdp = p->tmdhead + p->tmdnum; /* Which descriptor for transmitting */
-
- /* Fill in Transmit Message Descriptor */
-
- /* Copy data into dual ported ram */
-
- memcpy((char *) (tmdp->u.buffer & 0x00ffffff), (char *)skb->data,
- skb->len);
-
- tmdp->blen = -len; /* set length to transmit */
-
- /*
- * Packet start and end is always set because we use the maximum
- * packet length as buffer length.
- * Relinquish ownership to LANCE
- */
-
- tmdp->u.s.status = TX_OWN | TX_STP | TX_ENP;
-
- /* Start Demand Transmission */
- SK_write_reg(CSR0, CSR0_TDMD | CSR0_INEA);
-
- dev->trans_start = jiffies; /* Mark start of transmission */
-
- /* Set pointer to next transmit buffer */
- p->tmdnum++;
- p->tmdnum &= TMDNUM-1;
-
- /* Do we own the next transmit buffer ? */
- if (! ((p->tmdhead + p->tmdnum)->u.s.status & TX_OWN) )
- {
- /*
- * We own next buffer and are ready to transmit, so
- * clear busy flag
- */
- dev->tbusy = 0;
- }
- }
- dev_kfree_skb(skb, FREE_WRITE);
- return 0;
-} /* End of SK_send_packet */
-
-
-/*-
- * Function : SK_interrupt
- * Author : Patrick J.D. Weichmann
- * Date Created : 94/05/27
- *
- * Description : SK_G16 interrupt handler which checks for LANCE
- * Errors, handles transmit and receive interrupts
- *
- * Parameters : I : int irq, struct pt_regs * regs -
- * Return Value : None
- * Errors : None
- * Globals : None
- * Side Effects : None
- * Update History :
- * YY/MM/DD uid Description
--*/
-
-static void SK_interrupt(int irq, struct pt_regs * regs)
-{
- int csr0;
- struct device *dev = (struct device *) irq2dev_map[irq];
- struct priv *p = (struct priv *) dev->priv;
-
-
- PRINTK2(("## %s: SK_interrupt(). status: %#06x\n",
- SK_NAME, SK_read_reg(CSR0)));
-
- if (dev == NULL)
- {
- printk("SK_interrupt(): IRQ %d for unknown device.\n", irq);
- }
-
-
- if (dev->interrupt)
- {
- printk("%s: Re-entering the interrupt handler.\n", dev->name);
- }
-
- csr0 = SK_read_reg(CSR0); /* store register for checking */
-
- dev->interrupt = 1; /* We are handling an interrupt */
-
- /*
- * Acknowledge all of the current interrupt sources, disable
- * Interrupts (INEA = 0)
- */
-
- SK_write_reg(CSR0, csr0 & CSR0_CLRALL);
-
- if (csr0 & CSR0_ERR) /* LANCE Error */
- {
- printk("%s: error: %04x\n", dev->name, csr0);
-
- if (csr0 & CSR0_MISS) /* No place to store packet ? */
- {
- p->stats.rx_dropped++;
- }
- }
-
- if (csr0 & CSR0_RINT) /* Receive Interrupt (packet arrived) */
- {
- SK_rxintr(dev);
- }
-
- if (csr0 & CSR0_TINT) /* Transmit interrupt (packet sent) */
- {
- SK_txintr(dev);
- }
-
- SK_write_reg(CSR0, CSR0_INEA); /* Enable Interrupts */
-
- dev->interrupt = 0; /* We are out */
-} /* End of SK_interrupt() */
-
-
-/*-
- * Function : SK_txintr
- * Author : Patrick J.D. Weichmann
- * Date Created : 94/05/27
- *
- * Description : After sending a packet we check status, update
- * statistics and relinquish ownership of transmit
- * descriptor ring.
- *
- * Parameters : I : struct device *dev - SK_G16 device structure
- * Return Value : None
- * Errors : None
- * Globals : None
- * Update History :
- * YY/MM/DD uid Description
--*/
-
-static void SK_txintr(struct device *dev)
-{
- int tmdstat;
- struct tmd *tmdp;
- struct priv *p = (struct priv *) dev->priv;
-
-
- PRINTK2(("## %s: SK_txintr() status: %#06x\n",
- SK_NAME, SK_read_reg(CSR0)));
-
- tmdp = p->tmdhead + p->tmdlast; /* Which buffer we sent at last ? */
-
- /* Set next buffer */
- p->tmdlast++;
- p->tmdlast &= TMDNUM-1;
-
- tmdstat = tmdp->u.s.status & 0xff00; /* filter out status bits 15:08 */
-
- /*
- * We check status of transmitted packet.
- * see LANCE data-sheet for error explanation
- */
- if (tmdstat & TX_ERR) /* Error occurred */
- {
- printk("%s: TX error: %04x %04x\n", dev->name, (int) tmdstat,
- (int) tmdp->status2);
-
- if (tmdp->status2 & TX_TDR) /* TDR problems? */
- {
- printk("%s: tdr-problems \n", dev->name);
- }
-
- if (tmdp->status2 & TX_RTRY) /* Failed in 16 attempts to transmit ? */
- p->stats.tx_aborted_errors++;
- if (tmdp->status2 & TX_LCOL) /* Late collision ? */
- p->stats.tx_window_errors++;
- if (tmdp->status2 & TX_LCAR) /* Loss of Carrier ? */
- p->stats.tx_carrier_errors++;
- if (tmdp->status2 & TX_UFLO) /* Underflow error ? */
- {
- p->stats.tx_fifo_errors++;
-
- /*
- * If UFLO error occurs it will turn transmitter of.
- * So we must reinit LANCE
- */
-
- SK_lance_init(dev, MODE_NORMAL);
- }
-
- p->stats.tx_errors++;
-
- tmdp->status2 = 0; /* Clear error flags */
- }
- else if (tmdstat & TX_MORE) /* Collisions occurred ? */
- {
- /*
- * Here I have a problem.
- * I only know that there must be one or up to 15 collisions.
- * Thats why TX_MORE is set, because after 16 attempts TX_RTRY
- * will be set which means couldn't send packet aborted transfer.
- *
- * First I did not have this in but then I thought at minimum
- * we see that something was not ok.
- * If anyone knows something better than this to handle this
- * please report it. (see Email addresses in the README file)
- */
-
- p->stats.collisions++;
- }
- else /* Packet sent without any problems */
- {
- p->stats.tx_packets++;
- }
-
- /*
- * We mark transmitter not busy anymore, because now we have a free
- * transmit descriptor which can be filled by SK_send_packet and
- * afterwards sent by the LANCE
- */
-
- dev->tbusy = 0;
-
- /*
- * mark_bh(NET_BH);
- * This will cause net_bh() to run after this interrupt handler.
- *
- * The function which do handle slow IRQ parts is do_bottom_half()
- * which runs at normal kernel priority, that means all interrupt are
- * enabled. (see kernel/irq.c)
- *
- * net_bh does something like this:
- * - check if already in net_bh
- * - try to transmit something from the send queue
- * - if something is in the receive queue send it up to higher
- * levels if it is a known protocol
- * - try to transmit something from the send queue
- */
-
- mark_bh(NET_BH);
-
-} /* End of SK_txintr() */
-
-
-/*-
- * Function : SK_rxintr
- * Author : Patrick J.D. Weichmann
- * Date Created : 94/05/27
- *
- * Description : Buffer sent, check for errors, relinquish ownership
- * of the receive message descriptor.
- *
- * Parameters : I : SK_G16 device structure
- * Return Value : None
- * Globals : None
- * Update History :
- * YY/MM/DD uid Description
--*/
-
-static void SK_rxintr(struct device *dev)
-{
-
- struct rmd *rmdp;
- int rmdstat;
- struct priv *p = (struct priv *) dev->priv;
-
- PRINTK2(("## %s: SK_rxintr(). CSR0: %#06x\n",
- SK_NAME, SK_read_reg(CSR0)));
-
- rmdp = p->rmdhead + p->rmdnum;
-
- /* As long as we own the next entry, check status and send
- * it up to higher layer
- */
-
- while (!( (rmdstat = rmdp->u.s.status) & RX_OWN))
- {
- /*
- * Start and end of packet must be set, because we use
- * the ethernet maximum packet length (1518) as buffer size.
- *
- * Because our buffers are at maximum OFLO and BUFF errors are
- * not to be concerned (see Data sheet)
- */
-
- if ((rmdstat & (RX_STP | RX_ENP)) != (RX_STP | RX_ENP))
- {
- /* Start of a frame > 1518 Bytes ? */
-
- if (rmdstat & RX_STP)
- {
- p->stats.rx_errors++; /* bad packet received */
- p->stats.rx_length_errors++; /* packet to long */
-
- printk("%s: packet too long\n", dev->name);
- }
-
- /*
- * All other packets will be ignored until a new frame with
- * start (RX_STP) set follows.
- *
- * What we do is just give descriptor free for new incoming
- * packets.
- */
-
- rmdp->u.s.status = RX_OWN; /* Relinquish ownership to LANCE */
-
- }
- else if (rmdstat & RX_ERR) /* Receive Error ? */
- {
- printk("%s: RX error: %04x\n", dev->name, (int) rmdstat);
-
- p->stats.rx_errors++;
-
- if (rmdstat & RX_FRAM) p->stats.rx_frame_errors++;
- if (rmdstat & RX_CRC) p->stats.rx_crc_errors++;
-
- rmdp->u.s.status = RX_OWN; /* Relinquish ownership to LANCE */
-
- }
- else /* We have a packet which can be queued for the upper layers */
- {
-
- int len = (rmdp->mlen & 0x0fff); /* extract message length from receive buffer */
- struct sk_buff *skb;
-
- skb = dev_alloc_skb(len+2); /* allocate socket buffer */
-
- if (skb == NULL) /* Could not get mem ? */
- {
-
- /*
- * Couldn't allocate sk_buffer so we give descriptor back
- * to Lance, update statistics and go ahead.
- */
-
- rmdp->u.s.status = RX_OWN; /* Relinquish ownership to LANCE */
- printk("%s: Couldn't allocate sk_buff, deferring packet.\n",
- dev->name);
- p->stats.rx_dropped++;
-
- break; /* Jump out */
- }
-
- /* Prepare sk_buff to queue for upper layers */
-
- skb->dev = dev;
- skb_reserve(skb,2); /* Align IP header on 16 byte boundary */
-
- /*
- * Copy data out of our receive descriptor into sk_buff.
- *
- * (rmdp->u.buffer & 0x00ffffff) -> get address of buffer and
- * ignore status fields)
- */
-
- memcpy(skb_put(skb,len), (unsigned char *) (rmdp->u.buffer & 0x00ffffff),
- len);
-
-
- /*
- * Notify the upper protocol layers that there is another packet
- * to handle
- *
- * netif_rx() always succeeds. see /net/inet/dev.c for more.
- */
-
- skb->protocol=eth_type_trans(skb,dev);
- netif_rx(skb); /* queue packet and mark it for processing */
-
- /*
- * Packet is queued and marked for processing so we
- * free our descriptor and update statistics
- */
-
- rmdp->u.s.status = RX_OWN;
- p->stats.rx_packets++;
-
-
- p->rmdnum++;
- p->rmdnum %= RMDNUM;
-
- rmdp = p->rmdhead + p->rmdnum;
- }
- }
-} /* End of SK_rxintr() */
-
-
-/*-
- * Function : SK_close
- * Author : Patrick J.D. Weichmann
- * Date Created : 94/05/26
- *
- * Description : close gets called from dev_close() and should
- * deinstall the card (free_irq, mem etc).
- *
- * Parameters : I : struct device *dev - our device structure
- * Return Value : 0 - closed device driver
- * Errors : None
- * Globals : None
- * Update History :
- * YY/MM/DD uid Description
--*/
-
-/* I have tried to set BOOT_ROM on and RAM off but then, after a 'ifconfig
- * down' the system stops. So I don't shut set card to init state.
- */
-
-static int SK_close(struct device *dev)
-{
-
- PRINTK(("## %s: SK_close(). CSR0: %#06x\n",
- SK_NAME, SK_read_reg(CSR0)));
-
- dev->tbusy = 1; /* Transmitter busy */
- dev->start = 0; /* Card down */
-
- printk("%s: Shutting %s down CSR0 %#06x\n", dev->name, SK_NAME,
- (int) SK_read_reg(CSR0));
-
- SK_write_reg(CSR0, CSR0_STOP); /* STOP the LANCE */
-
- free_irq(dev->irq); /* Free IRQ */
- irq2dev_map[dev->irq] = 0; /* Mark IRQ as unused */
-
- return 0; /* always succeed */
-
-} /* End of SK_close() */
-
-
-/*-
- * Function : SK_get_stats
- * Author : Patrick J.D. Weichmann
- * Date Created : 94/05/26
- *
- * Description : Return current status structure to upper layers.
- * It is called by sprintf_stats (dev.c).
- *
- * Parameters : I : struct device *dev - our device structure
- * Return Value : struct enet_statistics * - our current statistics
- * Errors : None
- * Side Effects : None
- * Update History :
- * YY/MM/DD uid Description
--*/
-
-static struct enet_statistics *SK_get_stats(struct device *dev)
-{
-
- struct priv *p = (struct priv *) dev->priv;
-
- PRINTK(("## %s: SK_get_stats(). CSR0: %#06x\n",
- SK_NAME, SK_read_reg(CSR0)));
-
- return &p->stats; /* Return Device status */
-
-} /* End of SK_get_stats() */
-
-
-/*-
- * Function : set_multicast_list
- * Author : Patrick J.D. Weichmann
- * Date Created : 94/05/26
- *
- * Description : This function gets called when a program performs
- * a SIOCSIFFLAGS call. Ifconfig does this if you call
- * 'ifconfig [-]allmulti' which enables or disables the
- * Promiscuous mode.
- * Promiscuous mode is when the Network card accepts all
- * packets, not only the packets which match our MAC
- * Address. It is useful for writing a network monitor,
- * but it is also a security problem. You have to remember
- * that all information on the net is not encrypted.
- *
- * Parameters : I : struct device *dev - SK_G16 device Structure
- * Return Value : None
- * Errors : None
- * Globals : None
- * Update History :
- * YY/MM/DD uid Description
- * 95/10/18 ACox Noew multicast calling scheme
--*/
-
-
-/* Set or clear the multicast filter for SK_G16.
- */
-
-static void set_multicast_list(struct device *dev)
-{
-
- if (dev->flags&IFF_PROMISC)
- {
- /* Reinitialize LANCE with MODE_PROM set */
- SK_lance_init(dev, MODE_PROM);
- }
- else if (dev->mc_count==0 && !(dev->flags&IFF_ALLMULTI))
- {
- /* Reinitialize LANCE without MODE_PROM */
- SK_lance_init(dev, MODE_NORMAL);
- }
- else
- {
- /* Multicast with logical address filter on */
- /* Reinitialize LANCE without MODE_PROM */
- SK_lance_init(dev, MODE_NORMAL);
-
- /* Not implemented yet. */
- }
-} /* End of set_multicast_list() */
-
-
-
-/*-
- * Function : SK_rom_addr
- * Author : Patrick J.D. Weichmann
- * Date Created : 94/06/01
- *
- * Description : Try to find a Boot_ROM at all possible locations
- *
- * Parameters : None
- * Return Value : Address where Boot_ROM is
- * Errors : 0 - Did not find Boot_ROM
- * Globals : None
- * Update History :
- * YY/MM/DD uid Description
--*/
-
-unsigned int SK_rom_addr(void)
-{
- int i,j;
- int rom_found = 0;
- unsigned int rom_location[] = SK_BOOT_ROM_LOCATIONS;
- unsigned char rom_id[] = SK_BOOT_ROM_ID;
- unsigned char *test_byte;
-
- /* Autodetect Boot_ROM */
- PRINTK(("## %s: Autodetection of Boot_ROM\n", SK_NAME));
-
- for (i = 0; (rom_location[i] != 0) && (rom_found == 0); i++)
- {
-
- PRINTK(("## Trying ROM location %#08x", rom_location[i]));
-
- rom_found = 1;
- for (j = 0; j < 6; j++)
- {
- test_byte = (unsigned char *) (rom_location[i]+j);
- PRINTK((" %02x ", *test_byte));
-
- if(!(*test_byte == rom_id[j]))
- {
- rom_found = 0;
- }
- }
- PRINTK(("\n"));
- }
-
- if (rom_found == 1)
- {
- PRINTK(("## %s: Boot_ROM found at %#08x\n",
- SK_NAME, rom_location[(i-1)]));
-
- return (rom_location[--i]);
- }
- else
- {
- PRINTK(("%s: No Boot_ROM found\n", SK_NAME));
- return 0;
- }
-} /* End of SK_rom_addr() */
-
-
-
-/* LANCE access functions
- *
- * ! CSR1-3 can only be accessed when in CSR0 the STOP bit is set !
- */
-
-
-/*-
- * Function : SK_reset_board
- *
- * Author : Patrick J.D. Weichmann
- *
- * Date Created : 94/05/25
- *
- * Description : This function resets SK_G16 and all components, but
- * POS registers are not changed
- *
- * Parameters : None
- * Return Value : None
- * Errors : None
- * Globals : SK_RAM *board - SK_RAM structure pointer
- *
- * Update History :
- * YY/MM/DD uid Description
--*/
-
-void SK_reset_board(void)
-{
- int i;
-
- SK_PORT = 0x00; /* Reset active */
- for (i = 0; i < 10 ; i++) /* Delay min 5ms */
- ;
- SK_PORT = SK_RESET; /* Set back to normal operation */
-
-} /* End of SK_reset_board() */
-
-
-/*-
- * Function : SK_set_RAP
- * Author : Patrick J.D. Weichmann
- * Date Created : 94/05/25
- *
- * Description : Set LANCE Register Address Port to register
- * for later data transfer.
- *
- * Parameters : I : reg_number - which CSR to read/write from/to
- * Return Value : None
- * Errors : None
- * Globals : SK_RAM *board - SK_RAM structure pointer
- * Update History :
- * YY/MM/DD uid Description
--*/
-
-void SK_set_RAP(int reg_number)
-{
- SK_IOREG = reg_number;
- SK_PORT = SK_RESET | SK_RAP | SK_WREG;
- SK_IOCOM = SK_DOIO;
-
- while (SK_PORT & SK_IORUN)
- ;
-} /* End of SK_set_RAP() */
-
-
-/*-
- * Function : SK_read_reg
- * Author : Patrick J.D. Weichmann
- * Date Created : 94/05/25
- *
- * Description : Set RAP and read data from a LANCE CSR register
- *
- * Parameters : I : reg_number - which CSR to read from
- * Return Value : Register contents
- * Errors : None
- * Globals : SK_RAM *board - SK_RAM structure pointer
- * Update History :
- * YY/MM/DD uid Description
--*/
-
-int SK_read_reg(int reg_number)
-{
- SK_set_RAP(reg_number);
-
- SK_PORT = SK_RESET | SK_RDATA | SK_RREG;
- SK_IOCOM = SK_DOIO;
-
- while (SK_PORT & SK_IORUN)
- ;
- return (SK_IOREG);
-
-} /* End of SK_read_reg() */
-
-
-/*-
- * Function : SK_rread_reg
- * Author : Patrick J.D. Weichmann
- * Date Created : 94/05/28
- *
- * Description : Read data from preseted register.
- * This function requires that you know which
- * Register is actually set. Be aware that CSR1-3
- * can only be accessed when in CSR0 STOP is set.
- *
- * Return Value : Register contents
- * Errors : None
- * Globals : SK_RAM *board - SK_RAM structure pointer
- * Update History :
- * YY/MM/DD uid Description
--*/
-
-int SK_rread_reg(void)
-{
- SK_PORT = SK_RESET | SK_RDATA | SK_RREG;
-
- SK_IOCOM = SK_DOIO;
-
- while (SK_PORT & SK_IORUN)
- ;
- return (SK_IOREG);
-
-} /* End of SK_rread_reg() */
-
-
-/*-
- * Function : SK_write_reg
- * Author : Patrick J.D. Weichmann
- * Date Created : 94/05/25
- *
- * Description : This function sets the RAP then fills in the
- * LANCE I/O Reg and starts Transfer to LANCE.
- * It waits until transfer has ended which is max. 7 ms
- * and then it returns.
- *
- * Parameters : I : reg_number - which CSR to write to
- * I : value - what value to fill into register
- * Return Value : None
- * Errors : None
- * Globals : SK_RAM *board - SK_RAM structure pointer
- * Update History :
- * YY/MM/DD uid Description
--*/
-
-void SK_write_reg(int reg_number, int value)
-{
- SK_set_RAP(reg_number);
-
- SK_IOREG = value;
- SK_PORT = SK_RESET | SK_RDATA | SK_WREG;
- SK_IOCOM = SK_DOIO;
-
- while (SK_PORT & SK_IORUN)
- ;
-} /* End of SK_write_reg */
-
-
-
-/*
- * Debugging functions
- * -------------------
- */
-
-/*-
- * Function : SK_print_pos
- * Author : Patrick J.D. Weichmann
- * Date Created : 94/05/25
- *
- * Description : This function prints out the 4 POS (Programmable
- * Option Select) Registers. Used mainly to debug operation.
- *
- * Parameters : I : struct device *dev - SK_G16 device structure
- * I : char * - Text which will be printed as title
- * Return Value : None
- * Errors : None
- * Update History :
- * YY/MM/DD uid Description
--*/
-
-void SK_print_pos(struct device *dev, char *text)
-{
- int ioaddr = dev->base_addr;
-
- unsigned char pos0 = inb(SK_POS0),
- pos1 = inb(SK_POS1),
- pos2 = inb(SK_POS2),
- pos3 = inb(SK_POS3),
- pos4 = inb(SK_POS4);
-
-
- printk("## %s: %s.\n"
- "## pos0=%#4x pos1=%#4x pos2=%#04x pos3=%#08x pos4=%#04x\n",
- SK_NAME, text, pos0, pos1, pos2, (pos3<<14), pos4);
-
-} /* End of SK_print_pos() */
-
-
-
-/*-
- * Function : SK_print_dev
- * Author : Patrick J.D. Weichmann
- * Date Created : 94/05/25
- *
- * Description : This function simply prints out the important fields
- * of the device structure.
- *
- * Parameters : I : struct device *dev - SK_G16 device structure
- * I : char *text - Title for printing
- * Return Value : None
- * Errors : None
- * Update History :
- * YY/MM/DD uid Description
--*/
-
-void SK_print_dev(struct device *dev, char *text)
-{
- if (dev == NULL)
- {
- printk("## %s: Device Structure. %s\n", SK_NAME, text);
- printk("## DEVICE == NULL\n");
- }
- else
- {
- printk("## %s: Device Structure. %s\n", SK_NAME, text);
- printk("## Device Name: %s Base Address: %#06lx IRQ: %d\n",
- dev->name, dev->base_addr, dev->irq);
-
- printk("## FLAGS: start: %d tbusy: %ld int: %d\n",
- dev->start, dev->tbusy, dev->interrupt);
-
- printk("## next device: %#08x init function: %#08x\n",
- (int) dev->next, (int) dev->init);
- }
-
-} /* End of SK_print_dev() */
-
-
-
-/*-
- * Function : SK_print_ram
- * Author : Patrick J.D. Weichmann
- * Date Created : 94/06/02
- *
- * Description : This function is used to check how are things set up
- * in the 16KB RAM. Also the pointers to the receive and
- * transmit descriptor rings and rx and tx buffers locations.
- * It contains a minor bug in printing, but has no effect to the values
- * only newlines are not correct.
- *
- * Parameters : I : struct device *dev - SK_G16 device structure
- * Return Value : None
- * Errors : None
- * Globals : None
- * Update History :
- * YY/MM/DD uid Description
--*/
-
-void SK_print_ram(struct device *dev)
-{
-
- int i;
- struct priv *p = (struct priv *) dev->priv;
-
- printk("## %s: RAM Details.\n"
- "## RAM at %#08x tmdhead: %#08x rmdhead: %#08x initblock: %#08x\n",
- SK_NAME,
- (unsigned int) p->ram,
- (unsigned int) p->tmdhead,
- (unsigned int) p->rmdhead,
- (unsigned int) &(p->ram)->ib);
-
- printk("## ");
-
- for(i = 0; i < TMDNUM; i++)
- {
- if (!(i % 3)) /* Every third line do a newline */
- {
- printk("\n## ");
- }
- printk("tmdbufs%d: %#08x ", (i+1), (int) p->tmdbufs[i]);
- }
- printk("## ");
-
- for(i = 0; i < RMDNUM; i++)
- {
- if (!(i % 3)) /* Every third line do a newline */
- {
- printk("\n## ");
- }
- printk("rmdbufs%d: %#08x ", (i+1), (int) p->rmdbufs[i]);
- }
- printk("\n");
-
-} /* End of SK_print_ram() */
-
diff --git a/i386/i386at/gpl/linux/net/sk_g16.h b/i386/i386at/gpl/linux/net/sk_g16.h
deleted file mode 100644
index 3a92f1f9..00000000
--- a/i386/i386at/gpl/linux/net/sk_g16.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/*-
- *
- * This software may be used and distributed according to the terms
- * of the GNU Public License, incorporated herein by reference.
- *
- * Module : sk_g16.h
- * Version : $Revision: 1.1.1.1 $
- *
- * Author : M.Hipp (mhipp@student.uni-tuebingen.de)
- * changes by : Patrick J.D. Weichmann
- *
- * Date Created : 94/05/25
- *
- * Description : In here are all necessary definitions of
- * the am7990 (LANCE) chip used for writing a
- * network device driver which uses this chip
- *
- * $Log: sk_g16.h,v $
- * Revision 1.1.1.1 1996/10/30 01:39:56 thomas
- * Imported from UK22
- *
- * Revision 1.3 1996/03/25 20:24:35 goel
- * Linux driver merge.
- *
--*/
-
-#ifndef SK_G16_H
-
-#define SK_G16_H
-
-
-/*
- * Control and Status Register 0 (CSR0) bit definitions
- *
- * (R=Readable) (W=Writeable) (S=Set on write) (C-Clear on write)
- *
- */
-
-#define CSR0_ERR 0x8000 /* Error summary (R) */
-#define CSR0_BABL 0x4000 /* Babble transmitter timeout error (RC) */
-#define CSR0_CERR 0x2000 /* Collision Error (RC) */
-#define CSR0_MISS 0x1000 /* Missed packet (RC) */
-#define CSR0_MERR 0x0800 /* Memory Error (RC) */
-#define CSR0_RINT 0x0400 /* Receiver Interrupt (RC) */
-#define CSR0_TINT 0x0200 /* Transmit Interrupt (RC) */
-#define CSR0_IDON 0x0100 /* Initialization Done (RC) */
-#define CSR0_INTR 0x0080 /* Interrupt Flag (R) */
-#define CSR0_INEA 0x0040 /* Interrupt Enable (RW) */
-#define CSR0_RXON 0x0020 /* Receiver on (R) */
-#define CSR0_TXON 0x0010 /* Transmitter on (R) */
-#define CSR0_TDMD 0x0008 /* Transmit Demand (RS) */
-#define CSR0_STOP 0x0004 /* Stop (RS) */
-#define CSR0_STRT 0x0002 /* Start (RS) */
-#define CSR0_INIT 0x0001 /* Initialize (RS) */
-
-#define CSR0_CLRALL 0x7f00 /* mask for all clearable bits */
-
-/*
- * Control and Status Register 3 (CSR3) bit definitions
- *
- */
-
-#define CSR3_BSWAP 0x0004 /* Byte Swap (RW) */
-#define CSR3_ACON 0x0002 /* ALE Control (RW) */
-#define CSR3_BCON 0x0001 /* Byte Control (RW) */
-
-/*
- * Initialization Block Mode operation Bit Definitions.
- */
-
-#define MODE_PROM 0x8000 /* Promiscuous Mode */
-#define MODE_INTL 0x0040 /* Internal Loopback */
-#define MODE_DRTY 0x0020 /* Disable Retry */
-#define MODE_COLL 0x0010 /* Force Collision */
-#define MODE_DTCR 0x0008 /* Disable Transmit CRC) */
-#define MODE_LOOP 0x0004 /* Loopback */
-#define MODE_DTX 0x0002 /* Disable the Transmitter */
-#define MODE_DRX 0x0001 /* Disable the Receiver */
-
-#define MODE_NORMAL 0x0000 /* Normal operation mode */
-
-/*
- * Receive message descriptor status bit definitions.
- */
-
-#define RX_OWN 0x80 /* Owner bit 0 = host, 1 = lance */
-#define RX_ERR 0x40 /* Error Summary */
-#define RX_FRAM 0x20 /* Framing Error */
-#define RX_OFLO 0x10 /* Overflow Error */
-#define RX_CRC 0x08 /* CRC Error */
-#define RX_BUFF 0x04 /* Buffer Error */
-#define RX_STP 0x02 /* Start of Packet */
-#define RX_ENP 0x01 /* End of Packet */
-
-
-/*
- * Transmit message descriptor status bit definitions.
- */
-
-#define TX_OWN 0x80 /* Owner bit 0 = host, 1 = lance */
-#define TX_ERR 0x40 /* Error Summary */
-#define TX_MORE 0x10 /* More the 1 retry needed to Xmit */
-#define TX_ONE 0x08 /* One retry needed to Xmit */
-#define TX_DEF 0x04 /* Deferred */
-#define TX_STP 0x02 /* Start of Packet */
-#define TX_ENP 0x01 /* End of Packet */
-
-/*
- * Transmit status (2) (valid if TX_ERR == 1)
- */
-
-#define TX_BUFF 0x8000 /* Buffering error (no ENP) */
-#define TX_UFLO 0x4000 /* Underflow (late memory) */
-#define TX_LCOL 0x1000 /* Late collision */
-#define TX_LCAR 0x0400 /* Loss of Carrier */
-#define TX_RTRY 0x0200 /* Failed after 16 retransmissions */
-#define TX_TDR 0x003f /* Time-domain-reflectometer-value */
-
-
-/*
- * Structures used for Communication with the LANCE
- */
-
-/* LANCE Initialize Block */
-
-struct init_block
-{
- unsigned short mode; /* Mode Register */
- unsigned char paddr[6]; /* Physical Address (MAC) */
- unsigned char laddr[8]; /* Logical Filter Address (not used) */
- unsigned int rdrp; /* Receive Descriptor Ring pointer */
- unsigned int tdrp; /* Transmit Descriptor Ring pointer */
-};
-
-
-/* Receive Message Descriptor Entry */
-
-struct rmd
-{
- union
- {
- unsigned long buffer; /* Address of buffer */
- struct
- {
- unsigned char unused[3];
- unsigned volatile char status; /* Status Bits */
- } s;
- } u;
- volatile short blen; /* Buffer Length (two's complement) */
- unsigned short mlen; /* Message Byte Count */
-};
-
-
-/* Transmit Message Descriptor Entry */
-
-struct tmd
-{
- union
- {
- unsigned long buffer; /* Address of buffer */
- struct
- {
- unsigned char unused[3];
- unsigned volatile char status; /* Status Bits */
- } s;
- } u;
- unsigned short blen; /* Buffer Length (two's complement) */
- unsigned volatile short status2; /* Error Status Bits */
-};
-
-#endif /* End of SK_G16_H */
diff --git a/i386/i386at/gpl/linux/net/smc-ultra.c b/i386/i386at/gpl/linux/net/smc-ultra.c
deleted file mode 100644
index f13cd0a7..00000000
--- a/i386/i386at/gpl/linux/net/smc-ultra.c
+++ /dev/null
@@ -1,419 +0,0 @@
-/* smc-ultra.c: A SMC Ultra ethernet driver for linux. */
-/*
- Written 1993,1994,1995 by Donald Becker.
-
- Copyright 1993 United States Government as represented by the
- Director, National Security Agency.
-
- This software may be used and distributed according to the terms
- of the GNU Public License, incorporated herein by reference.
-
- The author may be reached as becker@CESDIS.gsfc.nasa.gov, or C/O
- Center of Excellence in Space Data and Information Sciences
- Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
-
- This is a driver for the SMC Ultra and SMC EtherEZ ethercards.
-
- This driver uses the cards in the 8390-compatible, shared memory mode.
- Most of the run-time complexity is handled by the generic code in
- 8390.c. The code in this file is responsible for
-
- ultra_probe() Detecting and initializing the card.
- ultra_probe1()
-
- ultra_open() The card-specific details of starting, stopping
- ultra_reset_8390() and resetting the 8390 NIC core.
- ultra_close()
-
- ultra_block_input() Routines for reading and writing blocks of
- ultra_block_output() packet buffer memory.
-
- This driver enables the shared memory only when doing the actual data
- transfers to avoid a bug in early version of the card that corrupted
- data transferred by a AHA1542.
-
- This driver does not support the programmed-I/O data transfer mode of
- the EtherEZ. That support (if available) is smc-ez.c. Nor does it
- use the non-8390-compatible "Altego" mode. (No support currently planned.)
-
- Changelog:
-
- Paul Gortmaker : multiple card support for module users.
-*/
-
-static const char *version =
- "smc-ultra.c:v1.12 1/18/95 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
-
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <asm/io.h>
-#include <asm/system.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include "8390.h"
-
-/* A zero-terminated list of I/O addresses to be probed. */
-static unsigned int ultra_portlist[] =
-{0x200, 0x220, 0x240, 0x280, 0x300, 0x340, 0x380, 0};
-
-int ultra_probe(struct device *dev);
-int ultra_probe1(struct device *dev, int ioaddr);
-
-static int ultra_open(struct device *dev);
-static void ultra_reset_8390(struct device *dev);
-static void ultra_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr,
- int ring_page);
-static void ultra_block_input(struct device *dev, int count,
- struct sk_buff *skb, int ring_offset);
-static void ultra_block_output(struct device *dev, int count,
- const unsigned char *buf, const start_page);
-static int ultra_close_card(struct device *dev);
-
-
-#define START_PG 0x00 /* First page of TX buffer */
-
-#define ULTRA_CMDREG 0 /* Offset to ASIC command register. */
-#define ULTRA_RESET 0x80 /* Board reset, in ULTRA_CMDREG. */
-#define ULTRA_MEMENB 0x40 /* Enable the shared memory. */
-#define ULTRA_NIC_OFFSET 16 /* NIC register offset from the base_addr. */
-#define ULTRA_IO_EXTENT 32
-
-/* Probe for the Ultra. This looks like a 8013 with the station
- address PROM at I/O ports <base>+8 to <base>+13, with a checksum
- following.
-*/
-#ifdef HAVE_DEVLIST
-struct netdev_entry ultra_drv =
-{"ultra", ultra_probe1, NETCARD_IO_EXTENT, netcard_portlist};
-#else
-
-int ultra_probe(struct device *dev)
-{
- int i;
- int base_addr = dev ? dev->base_addr : 0;
-
- if (base_addr > 0x1ff) /* Check a single specified location. */
- return ultra_probe1(dev, base_addr);
- else if (base_addr != 0) /* Don't probe at all. */
- return ENXIO;
-
- for (i = 0; ultra_portlist[i]; i++) {
- int ioaddr = ultra_portlist[i];
- if (check_region(ioaddr, ULTRA_IO_EXTENT))
- continue;
- if (ultra_probe1(dev, ioaddr) == 0)
- return 0;
- }
-
- return ENODEV;
-}
-#endif
-
-int ultra_probe1(struct device *dev, int ioaddr)
-{
- int i;
- int checksum = 0;
- const char *model_name;
- unsigned char eeprom_irq = 0;
- static unsigned version_printed = 0;
- /* Values from various config regs. */
- unsigned char num_pages, irqreg, addr;
- unsigned char idreg = inb(ioaddr + 7);
- unsigned char reg4 = inb(ioaddr + 4) & 0x7f;
-
- /* Check the ID nibble. */
- if ((idreg & 0xF0) != 0x20 /* SMC Ultra */
- && (idreg & 0xF0) != 0x40) /* SMC EtherEZ */
- return ENODEV;
-
- /* Select the station address register set. */
- outb(reg4, ioaddr + 4);
-
- for (i = 0; i < 8; i++)
- checksum += inb(ioaddr + 8 + i);
- if ((checksum & 0xff) != 0xFF)
- return ENODEV;
-
- /* We should have a "dev" from Space.c or the static module table. */
- if (dev == NULL) {
- printk("smc-ultra.c: Passed a NULL device.\n");
- dev = init_etherdev(0, 0);
- }
-
- if (ei_debug && version_printed++ == 0)
- printk(version);
-
- model_name = (idreg & 0xF0) == 0x20 ? "SMC Ultra" : "SMC EtherEZ";
-
- printk("%s: %s at %#3x,", dev->name, model_name, ioaddr);
-
- for (i = 0; i < 6; i++)
- printk(" %2.2X", dev->dev_addr[i] = inb(ioaddr + 8 + i));
-
- /* Switch from the station address to the alternate register set and
- read the useful registers there. */
- outb(0x80 | reg4, ioaddr + 4);
-
- /* Enabled FINE16 mode to avoid BIOS ROM width mismatches @ reboot. */
- outb(0x80 | inb(ioaddr + 0x0c), ioaddr + 0x0c);
- irqreg = inb(ioaddr + 0xd);
- addr = inb(ioaddr + 0xb);
-
- /* Switch back to the station address register set so that the MS-DOS driver
- can find the card after a warm boot. */
- outb(reg4, ioaddr + 4);
-
- if (dev->irq < 2) {
- unsigned char irqmap[] = {0, 9, 3, 5, 7, 10, 11, 15};
- int irq;
-
- /* The IRQ bits are split. */
- irq = irqmap[((irqreg & 0x40) >> 4) + ((irqreg & 0x0c) >> 2)];
-
- if (irq == 0) {
- printk(", failed to detect IRQ line.\n");
- return -EAGAIN;
- }
- dev->irq = irq;
- eeprom_irq = 1;
- }
-
- /* Allocate dev->priv and fill in 8390 specific dev fields. */
- if (ethdev_init(dev)) {
- printk (", no memory for dev->priv.\n");
- return -ENOMEM;
- }
-
- /* OK, we are certain this is going to work. Setup the device. */
- request_region(ioaddr, ULTRA_IO_EXTENT, model_name);
-
- /* The 8390 isn't at the base address, so fake the offset */
- dev->base_addr = ioaddr+ULTRA_NIC_OFFSET;
-
- {
- int addr_tbl[4] = {0x0C0000, 0x0E0000, 0xFC0000, 0xFE0000};
- short num_pages_tbl[4] = {0x20, 0x40, 0x80, 0xff};
-
- dev->mem_start = ((addr & 0x0f) << 13) + addr_tbl[(addr >> 6) & 3] ;
- num_pages = num_pages_tbl[(addr >> 4) & 3];
- }
-
- ei_status.name = model_name;
- ei_status.word16 = 1;
- ei_status.tx_start_page = START_PG;
- ei_status.rx_start_page = START_PG + TX_PAGES;
- ei_status.stop_page = num_pages;
-
- dev->rmem_start = dev->mem_start + TX_PAGES*256;
- dev->mem_end = dev->rmem_end
- = dev->mem_start + (ei_status.stop_page - START_PG)*256;
-
- printk(",%s IRQ %d memory %#lx-%#lx.\n", eeprom_irq ? "" : "assigned ",
- dev->irq, dev->mem_start, dev->mem_end-1);
-
- ei_status.reset_8390 = &ultra_reset_8390;
- ei_status.block_input = &ultra_block_input;
- ei_status.block_output = &ultra_block_output;
- ei_status.get_8390_hdr = &ultra_get_8390_hdr;
- dev->open = &ultra_open;
- dev->stop = &ultra_close_card;
- NS8390_init(dev, 0);
-
- return 0;
-}
-
-static int
-ultra_open(struct device *dev)
-{
- int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */
-
- if (request_irq(dev->irq, ei_interrupt, 0, ei_status.name))
- return -EAGAIN;
-
- outb(ULTRA_MEMENB, ioaddr); /* Enable memory, 16 bit mode. */
- outb(0x80, ioaddr + 5);
- outb(0x01, ioaddr + 6); /* Enable interrupts and memory. */
- ei_open(dev);
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-static void
-ultra_reset_8390(struct device *dev)
-{
- int cmd_port = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC base addr */
-
- outb(ULTRA_RESET, cmd_port);
- if (ei_debug > 1) printk("resetting Ultra, t=%ld...", jiffies);
- ei_status.txing = 0;
-
- outb(ULTRA_MEMENB, cmd_port);
-
- if (ei_debug > 1) printk("reset done\n");
- return;
-}
-
-/* Grab the 8390 specific header. Similar to the block_input routine, but
- we don't need to be concerned with ring wrap as the header will be at
- the start of a page, so we optimize accordingly. */
-
-static void
-ultra_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
-{
-
- unsigned long hdr_start = dev->mem_start + ((ring_page - START_PG)<<8);
-
- outb(ULTRA_MEMENB, dev->base_addr - ULTRA_NIC_OFFSET); /* shmem on */
-#ifdef notdef
- /* Officially this is what we are doing, but the readl() is faster */
- memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
-#else
- ((unsigned int*)hdr)[0] = readl(hdr_start);
-#endif
- outb(0x00, dev->base_addr - ULTRA_NIC_OFFSET); /* shmem off */
-}
-
-/* Block input and output are easy on shared memory ethercards, the only
- complication is when the ring buffer wraps. */
-
-static void
-ultra_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset)
-{
- unsigned long xfer_start = dev->mem_start + ring_offset - (START_PG<<8);
-
- /* Enable shared memory. */
- outb(ULTRA_MEMENB, dev->base_addr - ULTRA_NIC_OFFSET);
-
- if (xfer_start + count > dev->rmem_end) {
- /* We must wrap the input move. */
- int semi_count = dev->rmem_end - xfer_start;
- memcpy_fromio(skb->data, xfer_start, semi_count);
- count -= semi_count;
- memcpy_fromio(skb->data + semi_count, dev->rmem_start, count);
- } else {
- /* Packet is in one chunk -- we can copy + cksum. */
- eth_io_copy_and_sum(skb, xfer_start, count, 0);
- }
-
- outb(0x00, dev->base_addr - ULTRA_NIC_OFFSET); /* Disable memory. */
-}
-
-static void
-ultra_block_output(struct device *dev, int count, const unsigned char *buf,
- int start_page)
-{
- unsigned long shmem = dev->mem_start + ((start_page - START_PG)<<8);
-
- /* Enable shared memory. */
- outb(ULTRA_MEMENB, dev->base_addr - ULTRA_NIC_OFFSET);
-
- memcpy_toio(shmem, buf, count);
-
- outb(0x00, dev->base_addr - ULTRA_NIC_OFFSET); /* Disable memory. */
-}
-
-static int
-ultra_close_card(struct device *dev)
-{
- int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* CMDREG */
-
- dev->start = 0;
- dev->tbusy = 1;
-
- if (ei_debug > 1)
- printk("%s: Shutting down ethercard.\n", dev->name);
-
- outb(0x00, ioaddr + 6); /* Disable interrupts. */
- free_irq(dev->irq);
- irq2dev_map[dev->irq] = 0;
-
- NS8390_init(dev, 0);
-
- /* We should someday disable shared memory and change to 8-bit mode
- "just in case"... */
-
- MOD_DEC_USE_COUNT;
-
- return 0;
-}
-
-
-#ifdef MODULE
-#define MAX_ULTRA_CARDS 4 /* Max number of Ultra cards per module */
-#define NAMELEN 8 /* # of chars for storing dev->name */
-static char namelist[NAMELEN * MAX_ULTRA_CARDS] = { 0, };
-static struct device dev_ultra[MAX_ULTRA_CARDS] = {
- {
- NULL, /* assign a chunk of namelist[] below */
- 0, 0, 0, 0,
- 0, 0,
- 0, 0, 0, NULL, NULL
- },
-};
-
-static int io[MAX_ULTRA_CARDS] = { 0, };
-static int irq[MAX_ULTRA_CARDS] = { 0, };
-
-/* This is set up so that only a single autoprobe takes place per call.
-ISA device autoprobes on a running machine are not recommended. */
-int
-init_module(void)
-{
- int this_dev, found = 0;
-
- for (this_dev = 0; this_dev < MAX_ULTRA_CARDS; this_dev++) {
- struct device *dev = &dev_ultra[this_dev];
- dev->name = namelist+(NAMELEN*this_dev);
- dev->irq = irq[this_dev];
- dev->base_addr = io[this_dev];
- dev->init = ultra_probe;
- if (io[this_dev] == 0) {
- if (this_dev != 0) break; /* only autoprobe 1st one */
- printk(KERN_NOTICE "smc-ultra.c: Presently autoprobing (not recommended) for a single card.\n");
- }
- if (register_netdev(dev) != 0) {
- printk(KERN_WARNING "smc-ultra.c: No SMC Ultra card found (i/o = 0x%x).\n", io[this_dev]);
- if (found != 0) return 0; /* Got at least one. */
- return -ENXIO;
- }
- found++;
- }
-
- return 0;
-}
-
-void
-cleanup_module(void)
-{
- int this_dev;
-
- for (this_dev = 0; this_dev < MAX_ULTRA_CARDS; this_dev++) {
- struct device *dev = &dev_ultra[this_dev];
- if (dev->priv != NULL) {
- /* NB: ultra_close_card() does free_irq + irq2dev */
- int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET;
- kfree(dev->priv);
- dev->priv = NULL;
- release_region(ioaddr, ULTRA_IO_EXTENT);
- unregister_netdev(dev);
- }
- }
-}
-#endif /* MODULE */
-
-
-/*
- * Local variables:
- * compile-command: "gcc -D__KERNEL__ -Wall -O6 -I/usr/src/linux/net/inet -c smc-ultra.c"
- * version-control: t
- * kept-new-versions: 5
- * c-indent-level: 4
- * tab-width: 4
- * End:
- */
diff --git a/i386/i386at/gpl/linux/net/tulip.c b/i386/i386at/gpl/linux/net/tulip.c
deleted file mode 100644
index 3386a9b8..00000000
--- a/i386/i386at/gpl/linux/net/tulip.c
+++ /dev/null
@@ -1,782 +0,0 @@
-/* tulip.c: A DEC 21040 ethernet driver for linux. */
-/*
- NOTICE: this version works with kernels 1.1.82 and later only!
- Written 1994,1995 by Donald Becker.
-
- This software may be used and distributed according to the terms
- of the GNU Public License, incorporated herein by reference.
-
- This driver is for the SMC EtherPower PCI ethernet adapter.
- It should work with most other DEC 21*40-based ethercards.
-
- The author may be reached as becker@CESDIS.gsfc.nasa.gov, or C/O
- Center of Excellence in Space Data and Information Sciences
- Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
-*/
-
-static const char *version = "tulip.c:v0.05 1/20/95 becker@cesdis.gsfc.nasa.gov\n";
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/ptrace.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/malloc.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/bios32.h>
-#include <asm/bitops.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-
-/* The total size is unusually large: The 21040 aligns each of its 16
- longword-wide registers on a quadword boundary. */
-#define TULIP_TOTAL_SIZE 0x80
-
-#ifdef HAVE_DEVLIST
-struct netdev_entry tulip_drv =
-{"Tulip", tulip_pci_probe, TULIP_TOTAL_SIZE, NULL};
-#endif
-
-#define TULIP_DEBUG 1
-#ifdef TULIP_DEBUG
-int tulip_debug = TULIP_DEBUG;
-#else
-int tulip_debug = 1;
-#endif
-
-/*
- Theory of Operation
-
-I. Board Compatibility
-
-This device driver is designed for the DECchip 21040 "Tulip", Digital's
-single-chip ethernet controller for PCI, as used on the SMC EtherPower
-ethernet adapter.
-
-II. Board-specific settings
-
-PCI bus devices are configured by the system at boot time, so no jumpers
-need to be set on the board. The system BIOS should be set to assign the
-PCI INTA signal to an otherwise unused system IRQ line. While it's
-physically possible to shared PCI interrupt lines, the kernel doesn't
-support it.
-
-III. Driver operation
-
-IIIa. Ring buffers
-The Tulip can use either ring buffers or lists of Tx and Rx descriptors.
-The current driver uses a statically allocated Rx ring of descriptors and
-buffers, and a list of the Tx buffers.
-
-IIIC. Synchronization
-The driver runs as two independent, single-threaded flows of control. One
-is the send-packet routine, which enforces single-threaded use by the
-dev->tbusy flag. The other thread is the interrupt handler, which is single
-threaded by the hardware and other software.
-
-The send packet thread has partial control over the Tx ring and 'dev->tbusy'
-flag. It sets the tbusy flag whenever it's queuing a Tx packet. If the next
-queue slot is empty, it clears the tbusy flag when finished otherwise it sets
-the 'tp->tx_full' flag.
-
-The interrupt handler has exclusive control over the Rx ring and records stats
-from the Tx ring. (The Tx-done interrupt can't be selectively turned off, so
-we can't avoid the interrupt overhead by having the Tx routine reap the Tx
-stats.) After reaping the stats, it marks the queue entry as empty by setting
-the 'base' to zero. Iff the 'tp->tx_full' flag is set, it clears both the
-tx_full and tbusy flags.
-
-IV. Notes
-
-Thanks to Duke Kamstra of SMC for providing an EtherPower board.
-
-The DEC databook doesn't document which Rx filter settings accept broadcast
-packets. Nor does it document how to configure the part to configure the
-serial subsystem for normal (vs. loopback) operation or how to have it
-autoswitch between internal 10baseT, SIA and AUI transceivers.
-
-The databook claims that CSR13, CSR14, and CSR15 should each be the last
-register of the set CSR12-15 written. Hmmm, now how is that possible?
-*/
-
-#define DEC_VENDOR_ID 0x1011 /* Hex 'D' :-> */
-#define DEC_21040_ID 0x0002 /* Change for 21140. */
-
-/* Keep the ring sizes a power of two for efficiency. */
-#define TX_RING_SIZE 4
-#define RX_RING_SIZE 4
-#define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer.*/
-
-/* Offsets to the Command and Status Registers, "CSRs". All accesses
- must be longword instructions and quadword aligned. */
-enum tulip_offsets {
- CSR0=0, CSR1=0x08, CSR2=0x10, CSR3=0x18, CSR4=0x20, CSR5=0x28,
- CSR6=0x30, CSR7=0x38, CSR8=0x40, CSR9=0x48, CSR10=0x50, CSR11=0x58,
- CSR12=0x60, CSR13=0x68, CSR14=0x70, CSR15=0x78 };
-
-/* The Tulip Rx and Tx buffer descriptors. */
-struct tulip_rx_desc {
- int status;
- int length;
- char *buffer1, *buffer2; /* We use only buffer 1. */
-};
-
-struct tulip_tx_desc {
- int status;
- int length;
- char *buffer1, *buffer2; /* We use only buffer 1. */
-};
-
-struct tulip_private {
- char devname[8]; /* Used only for kernel debugging. */
- struct tulip_rx_desc rx_ring[RX_RING_SIZE];
- struct tulip_tx_desc tx_ring[TX_RING_SIZE];
- /* The saved address of a sent-in-place packet/buffer, for skfree(). */
- struct sk_buff* tx_skbuff[TX_RING_SIZE];
- long rx_buffs; /* Address of temporary Rx buffers. */
- struct enet_statistics stats;
- int setup_frame[48]; /* Pseudo-Tx frame to init address table. */
- unsigned int cur_rx, cur_tx; /* The next free ring entry */
- unsigned int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */
- unsigned int tx_full:1;
- int pad0, pad1; /* Used for 8-byte alignment */
-};
-
-static void tulip_probe1(int ioaddr, int irq);
-static int tulip_open(struct device *dev);
-static void tulip_init_ring(struct device *dev);
-static int tulip_start_xmit(struct sk_buff *skb, struct device *dev);
-static int tulip_rx(struct device *dev);
-static void tulip_interrupt(int irq, struct pt_regs *regs);
-static int tulip_close(struct device *dev);
-static struct enet_statistics *tulip_get_stats(struct device *dev);
-static void set_multicast_list(struct device *dev);
-static int set_mac_address(struct device *dev, void *addr);
-
-
-
-#ifndef MODULE
-/* This 21040 probe is unlike most other board probes. We can use memory
- efficiently by allocating a large contiguous region and dividing it
- ourselves. This is done by having the initialization occur before
- the 'kmalloc()' memory management system is started. */
-
-int dec21040_init(void)
-{
-
- if (pcibios_present()) {
- int pci_index;
- for (pci_index = 0; pci_index < 8; pci_index++) {
- unsigned char pci_bus, pci_device_fn, pci_irq_line;
- unsigned long pci_ioaddr;
-
- if (pcibios_find_device (DEC_VENDOR_ID, DEC_21040_ID, pci_index,
- &pci_bus, &pci_device_fn) != 0)
- break;
- pcibios_read_config_byte(pci_bus, pci_device_fn,
- PCI_INTERRUPT_LINE, &pci_irq_line);
- pcibios_read_config_dword(pci_bus, pci_device_fn,
- PCI_BASE_ADDRESS_0, &pci_ioaddr);
- /* Remove I/O space marker in bit 0. */
- pci_ioaddr &= ~3;
- if (tulip_debug > 2)
- printk("Found DEC PCI Tulip at I/O %#lx, IRQ %d.\n",
- pci_ioaddr, pci_irq_line);
- tulip_probe1(pci_ioaddr, pci_irq_line);
- }
- }
-
- return 0;
-}
-#endif
-#ifdef MODULE
-static int tulip_probe(struct device *dev)
-{
- printk("tulip: This driver does not yet install properly from module!\n");
- return -1;
-}
-#endif
-
-static void tulip_probe1(int ioaddr, int irq)
-{
- static int did_version = 0; /* Already printed version info. */
- struct device *dev;
- struct tulip_private *tp;
- int i;
-
- if (tulip_debug > 0 && did_version++ == 0)
- printk(version);
-
- dev = init_etherdev(0, 0);
-
- printk("%s: DEC 21040 Tulip at %#3x,", dev->name, ioaddr);
-
- /* Stop the chip's Tx and Rx processes. */
- outl(inl(ioaddr + CSR6) & ~0x2002, ioaddr + CSR6);
- /* Clear the missed-packet counter. */
- inl(ioaddr + CSR8) & 0xffff;
-
- /* The station address ROM is read byte serially. The register must
- be polled, waiting for the value to be read bit serially from the
- EEPROM.
- */
- outl(0, ioaddr + CSR9); /* Reset the pointer with a dummy write. */
- for (i = 0; i < 6; i++) {
- int value, boguscnt = 100000;
- do
- value = inl(ioaddr + CSR9);
- while (value < 0 && --boguscnt > 0);
- printk(" %2.2x", dev->dev_addr[i] = value);
- }
- printk(", IRQ %d\n", irq);
-
- /* We do a request_region() only to register /proc/ioports info. */
- request_region(ioaddr, TULIP_TOTAL_SIZE, "DEC Tulip Ethernet");
-
- dev->base_addr = ioaddr;
- dev->irq = irq;
-
- /* Make certain the data structures are quadword aligned. */
- tp = kmalloc(sizeof(*tp), GFP_KERNEL | GFP_DMA);
- dev->priv = tp;
- tp->rx_buffs = kmalloc(PKT_BUF_SZ*RX_RING_SIZE, GFP_KERNEL | GFP_DMA);
-
- /* The Tulip-specific entries in the device structure. */
- dev->open = &tulip_open;
- dev->hard_start_xmit = &tulip_start_xmit;
- dev->stop = &tulip_close;
- dev->get_stats = &tulip_get_stats;
- dev->set_multicast_list = &set_multicast_list;
- dev->set_mac_address = &set_mac_address;
-
- return;
-}
-
-
-static int
-tulip_open(struct device *dev)
-{
- struct tulip_private *tp = (struct tulip_private *)dev->priv;
- int ioaddr = dev->base_addr;
-
- /* Reset the chip, holding bit 0 set at least 10 PCI cycles. */
- outl(0xfff80001, ioaddr + CSR0);
- SLOW_DOWN_IO;
- /* Deassert reset. Set 8 longword cache alignment, 8 longword burst.
- Cache alignment bits 15:14 Burst length 13:8
- 0000 No alignment 0x00000000 unlimited 0800 8 longwords
- 4000 8 longwords 0100 1 longword 1000 16 longwords
- 8000 16 longwords 0200 2 longwords 2000 32 longwords
- C000 32 longwords 0400 4 longwords
- Wait the specified 50 PCI cycles after a reset by initializing
- Tx and Rx queues and the address filter list. */
- outl(0xfff84800, ioaddr + CSR0);
-
- if (irq2dev_map[dev->irq] != NULL
- || (irq2dev_map[dev->irq] = dev) == NULL
- || dev->irq == 0
- || request_irq(dev->irq, &tulip_interrupt, 0, "DEC 21040 Tulip")) {
- return -EAGAIN;
- }
-
- if (tulip_debug > 1)
- printk("%s: tulip_open() irq %d.\n", dev->name, dev->irq);
-
- tulip_init_ring(dev);
-
- /* Fill the whole address filter table with our physical address. */
- {
- unsigned short *eaddrs = (unsigned short *)dev->dev_addr;
- int *setup_frm = tp->setup_frame, i;
-
- /* You must add the broadcast address when doing perfect filtering! */
- *setup_frm++ = 0xffff;
- *setup_frm++ = 0xffff;
- *setup_frm++ = 0xffff;
- /* Fill the rest of the accept table with our physical address. */
- for (i = 1; i < 16; i++) {
- *setup_frm++ = eaddrs[0];
- *setup_frm++ = eaddrs[1];
- *setup_frm++ = eaddrs[2];
- }
- /* Put the setup frame on the Tx list. */
- tp->tx_ring[0].length = 0x08000000 | 192;
- tp->tx_ring[0].buffer1 = (char *)tp->setup_frame;
- tp->tx_ring[0].buffer2 = 0;
- tp->tx_ring[0].status = 0x80000000;
-
- tp->cur_tx++, tp->dirty_tx++;
- }
-
- outl((int)tp->rx_ring, ioaddr + CSR3);
- outl((int)tp->tx_ring, ioaddr + CSR4);
-
- /* Turn on the xcvr interface. */
- outl(0x00000000, ioaddr + CSR13);
- outl(0x00000004, ioaddr + CSR13);
-
- /* Start the chip's Tx and Rx processes. */
- outl(0xfffe2002, ioaddr + CSR6);
-
- /* Trigger an immediate transmit demand to process the setup frame. */
- outl(0, ioaddr + CSR1);
-
- dev->tbusy = 0;
- dev->interrupt = 0;
- dev->start = 1;
-
- /* Enable interrupts by setting the interrupt mask. */
- outl(0xFFFFFFFF, ioaddr + CSR7);
-
- if (tulip_debug > 2) {
- printk("%s: Done tulip_open(), CSR0 %8.8x, CSR13 %8.8x.\n",
- dev->name, inl(ioaddr + CSR0), inl(ioaddr + CSR13));
- }
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-/* Initialize the Rx and Tx rings, along with various 'dev' bits. */
-static void
-tulip_init_ring(struct device *dev)
-{
- struct tulip_private *tp = (struct tulip_private *)dev->priv;
- int i;
-
- tp->tx_full = 0;
- tp->cur_rx = tp->cur_tx = 0;
- tp->dirty_rx = tp->dirty_tx = 0;
-
- for (i = 0; i < RX_RING_SIZE; i++) {
- tp->rx_ring[i].status = 0x80000000; /* Owned by Tulip chip */
- tp->rx_ring[i].length = PKT_BUF_SZ;
- tp->rx_ring[i].buffer1 = (char *)(tp->rx_buffs + i*PKT_BUF_SZ);
- tp->rx_ring[i].buffer2 = (char *)&tp->rx_ring[i+1];
- }
- /* Mark the last entry as wrapping the ring. */
- tp->rx_ring[i-1].length = PKT_BUF_SZ | 0x02000000;
- tp->rx_ring[i-1].buffer2 = (char *)&tp->rx_ring[0];
-
- /* The Tx buffer descriptor is filled in as needed, but we
- do need to clear the ownership bit. */
- for (i = 0; i < TX_RING_SIZE; i++) {
- tp->tx_ring[i].status = 0x00000000;
- }
-}
-
-static int
-tulip_start_xmit(struct sk_buff *skb, struct device *dev)
-{
- struct tulip_private *tp = (struct tulip_private *)dev->priv;
- int ioaddr = dev->base_addr;
- int entry;
-
- /* Transmitter timeout, serious problems. */
- if (dev->tbusy) {
- int tickssofar = jiffies - dev->trans_start;
- int i;
- if (tickssofar < 20)
- return 1;
- printk("%s: transmit timed out, status %8.8x, SIA %8.8x %8.8x %8.8x %8.8x, resetting...\n",
- dev->name, inl(ioaddr + CSR5), inl(ioaddr + CSR12),
- inl(ioaddr + CSR13), inl(ioaddr + CSR14), inl(ioaddr + CSR15));
- printk(" Rx ring %8.8x: ", (int)tp->rx_ring);
- for (i = 0; i < RX_RING_SIZE; i++)
- printk(" %8.8x", (unsigned int)tp->rx_ring[i].status);
- printk("\n Tx ring %8.8x: ", (int)tp->tx_ring);
- for (i = 0; i < TX_RING_SIZE; i++)
- printk(" %8.8x", (unsigned int)tp->tx_ring[i].status);
- printk("\n");
-
- tp->stats.tx_errors++;
- /* We should reinitialize the hardware here. */
- dev->tbusy=0;
- dev->trans_start = jiffies;
- return 0;
- }
-
- if (skb == NULL || skb->len <= 0) {
- printk("%s: Obsolete driver layer request made: skbuff==NULL.\n",
- dev->name);
- dev_tint(dev);
- return 0;
- }
-
- /* Block a timer-based transmit from overlapping. This could better be
- done with atomic_swap(1, dev->tbusy), but set_bit() works as well.
- If this ever occurs the queue layer is doing something evil! */
- if (set_bit(0, (void*)&dev->tbusy) != 0) {
- printk("%s: Transmitter access conflict.\n", dev->name);
- return 1;
- }
-
- /* Caution: the write order is important here, set the base address
- with the "ownership" bits last. */
-
- /* Calculate the next Tx descriptor entry. */
- entry = tp->cur_tx % TX_RING_SIZE;
-
- tp->tx_full = 1;
- tp->tx_skbuff[entry] = skb;
- tp->tx_ring[entry].length = skb->len |
- (entry == TX_RING_SIZE-1 ? 0xe2000000 : 0xe0000000);
- tp->tx_ring[entry].buffer1 = skb->data;
- tp->tx_ring[entry].buffer2 = 0;
- tp->tx_ring[entry].status = 0x80000000; /* Pass ownership to the chip. */
-
- tp->cur_tx++;
-
- /* Trigger an immediate transmit demand. */
- outl(0, ioaddr + CSR1);
-
- dev->trans_start = jiffies;
-
- return 0;
-}
-
-/* The interrupt handler does all of the Rx thread work and cleans up
- after the Tx thread. */
-static void tulip_interrupt(int irq, struct pt_regs *regs)
-{
- struct device *dev = (struct device *)(irq2dev_map[irq]);
- struct tulip_private *lp;
- int csr5, ioaddr, boguscnt=10;
-
- if (dev == NULL) {
- printk ("tulip_interrupt(): irq %d for unknown device.\n", irq);
- return;
- }
-
- ioaddr = dev->base_addr;
- lp = (struct tulip_private *)dev->priv;
- if (dev->interrupt)
- printk("%s: Re-entering the interrupt handler.\n", dev->name);
-
- dev->interrupt = 1;
-
- do {
- csr5 = inl(ioaddr + CSR5);
- /* Acknowledge all of the current interrupt sources ASAP. */
- outl(csr5 & 0x0001ffff, ioaddr + CSR5);
-
- if (tulip_debug > 4)
- printk("%s: interrupt csr5=%#8.8x new csr5=%#8.8x.\n",
- dev->name, csr5, inl(dev->base_addr + CSR5));
-
- if ((csr5 & 0x00018000) == 0)
- break;
-
- if (csr5 & 0x0040) /* Rx interrupt */
- tulip_rx(dev);
-
- if (csr5 & 0x0001) { /* Tx-done interrupt */
- int dirty_tx = lp->dirty_tx;
-
- while (dirty_tx < lp->cur_tx) {
- int entry = dirty_tx % TX_RING_SIZE;
- int status = lp->tx_ring[entry].status;
-
- if (status < 0)
- break; /* It still hasn't been Txed */
-
- if (status & 0x8000) {
- /* There was an major error, log it. */
- lp->stats.tx_errors++;
- if (status & 0x4104) lp->stats.tx_aborted_errors++;
- if (status & 0x0C00) lp->stats.tx_carrier_errors++;
- if (status & 0x0200) lp->stats.tx_window_errors++;
- if (status & 0x0002) lp->stats.tx_fifo_errors++;
- if (status & 0x0080) lp->stats.tx_heartbeat_errors++;
-#ifdef ETHER_STATS
- if (status & 0x0100) lp->stats.collisions16++;
-#endif
- } else {
-#ifdef ETHER_STATS
- if (status & 0x0001) lp->stats.tx_deferred++;
-#endif
- lp->stats.collisions += (status >> 3) & 15;
- lp->stats.tx_packets++;
- }
-
- /* Free the original skb. */
- dev_kfree_skb(lp->tx_skbuff[entry], FREE_WRITE);
- dirty_tx++;
- }
-
-#ifndef final_version
- if (lp->cur_tx - dirty_tx >= TX_RING_SIZE) {
- printk("out-of-sync dirty pointer, %d vs. %d, full=%d.\n",
- dirty_tx, lp->cur_tx, lp->tx_full);
- dirty_tx += TX_RING_SIZE;
- }
-#endif
-
- if (lp->tx_full && dev->tbusy
- && dirty_tx > lp->cur_tx - TX_RING_SIZE + 2) {
- /* The ring is no longer full, clear tbusy. */
- lp->tx_full = 0;
- dev->tbusy = 0;
- mark_bh(NET_BH);
- }
-
- lp->dirty_tx = dirty_tx;
- }
-
- /* Log errors. */
- if (csr5 & 0x8000) { /* Abnormal error summary bit. */
- if (csr5 & 0x0008) lp->stats.tx_errors++; /* Tx babble. */
- if (csr5 & 0x0100) { /* Missed a Rx frame. */
- lp->stats.rx_errors++;
- lp->stats.rx_missed_errors += inl(ioaddr + CSR8) & 0xffff;
- }
- if (csr5 & 0x0800) {
- printk("%s: Something Wicked happened! %8.8x.\n",
- dev->name, csr5);
- /* Hmmmmm, it's not clear what to do here. */
- }
- }
- if (--boguscnt < 0) {
- printk("%s: Too much work at interrupt, csr5=0x%8.8x.\n",
- dev->name, csr5);
- /* Clear all interrupt sources. */
- outl(0x0001ffff, ioaddr + CSR5);
- break;
- }
- } while (1);
-
- if (tulip_debug > 3)
- printk("%s: exiting interrupt, csr5=%#4.4x.\n",
- dev->name, inl(ioaddr + CSR5));
-
- /* Special code for testing *only*. */
- {
- static int stopit = 10;
- if (dev->start == 0 && --stopit < 0) {
- printk("%s: Emergency stop, looping startup interrupt.\n",
- dev->name);
- free_irq(irq);
- }
- }
-
- dev->interrupt = 0;
- return;
-}
-
-static int
-tulip_rx(struct device *dev)
-{
- struct tulip_private *lp = (struct tulip_private *)dev->priv;
- int entry = lp->cur_rx % RX_RING_SIZE;
- int i;
-
- if (tulip_debug > 4)
- printk(" In tulip_rx().\n");
- /* If we own the next entry, it's a new packet. Send it up. */
- while (lp->rx_ring[entry].status >= 0) {
- int status = lp->rx_ring[entry].status;
-
- if (tulip_debug > 4)
- printk(" tulip_rx() status was %8.8x.\n", status);
- if ((status & 0x0300) != 0x0300) {
- printk("%s: Ethernet frame spanned multiple buffers, status %8.8x!\n",
- dev->name, status);
- } else if (status & 0x8000) {
- /* There was a fatal error. */
- lp->stats.rx_errors++; /* end of a packet.*/
- if (status & 0x0890) lp->stats.rx_length_errors++;
- if (status & 0x0004) lp->stats.rx_frame_errors++;
- if (status & 0x0002) lp->stats.rx_crc_errors++;
- if (status & 0x0001) lp->stats.rx_fifo_errors++;
- } else {
- /* Malloc up new buffer, compatible with net-2e. */
- short pkt_len = lp->rx_ring[entry].status >> 16;
- struct sk_buff *skb;
-
- skb = dev_alloc_skb(pkt_len+2);
- if (skb == NULL) {
- printk("%s: Memory squeeze, deferring packet.\n", dev->name);
- /* Check that at least two ring entries are free.
- If not, free one and mark stats->rx_dropped++. */
- for (i=0; i < RX_RING_SIZE; i++)
- if (lp->rx_ring[(entry+i) % RX_RING_SIZE].status < 0)
- break;
-
- if (i > RX_RING_SIZE -2) {
- lp->stats.rx_dropped++;
- lp->rx_ring[entry].status = 0x80000000;
- lp->cur_rx++;
- }
- break;
- }
- skb->dev = dev;
- skb_reserve(skb,2); /* 16 byte align the data fields */
- memcpy(skb_put(skb,pkt_len), lp->rx_ring[entry].buffer1, pkt_len);
- skb->protocol=eth_type_trans(skb,dev);
- netif_rx(skb);
- lp->stats.rx_packets++;
- }
-
- lp->rx_ring[entry].status = 0x80000000;
- entry = (++lp->cur_rx) % RX_RING_SIZE;
- }
-
- return 0;
-}
-
-static int
-tulip_close(struct device *dev)
-{
- int ioaddr = dev->base_addr;
- struct tulip_private *tp = (struct tulip_private *)dev->priv;
-
- dev->start = 0;
- dev->tbusy = 1;
-
- if (tulip_debug > 1)
- printk("%s: Shutting down ethercard, status was %2.2x.\n",
- dev->name, inl(ioaddr + CSR5));
-
- /* Disable interrupts by clearing the interrupt mask. */
- outl(0x00000000, ioaddr + CSR7);
- /* Stop the chip's Tx and Rx processes. */
- outl(inl(ioaddr + CSR6) & ~0x2002, ioaddr + CSR6);
-
- tp->stats.rx_missed_errors += inl(ioaddr + CSR8) & 0xffff;
-
- free_irq(dev->irq);
- irq2dev_map[dev->irq] = 0;
-
- MOD_DEC_USE_COUNT;
- return 0;
-}
-
-static struct enet_statistics *
-tulip_get_stats(struct device *dev)
-{
- struct tulip_private *tp = (struct tulip_private *)dev->priv;
- short ioaddr = dev->base_addr;
-
- tp->stats.rx_missed_errors += inl(ioaddr + CSR8) & 0xffff;
-
- return &tp->stats;
-}
-
-/*
- * Set or clear the multicast filter for this adaptor.
- */
-
-static void set_multicast_list(struct device *dev)
-{
- short ioaddr = dev->base_addr;
- int csr6 = inl(ioaddr + CSR6) & ~0x00D5;
-
- if (dev->flags&IFF_PROMISC)
- { /* Set promiscuous. */
- outl(csr6 | 0x00C0, ioaddr + CSR6);
- /* Log any net taps. */
- printk("%s: Promiscuous mode enabled.\n", dev->name);
- }
- else if (dev->mc_count > 15 || (dev->flags&IFF_ALLMULTI))
- {
- /* Too many to filter perfectly -- accept all multicasts. */
- outl(csr6 | 0x0080, ioaddr + CSR6);
- }
- else
- {
- struct tulip_private *tp = (struct tulip_private *)dev->priv;
- struct dev_mc_list *dmi=dev->mc_list;
- int *setup_frm = tp->setup_frame;
- unsigned short *eaddrs;
- int i;
-
- /* We have <= 15 addresses that we can use the wonderful
- 16 address perfect filtering of the Tulip. Note that only
- the low shortword of setup_frame[] is valid. */
- outl(csr6 | 0x0000, ioaddr + CSR6);
- i=0;
- while(dmi)
- {
- eaddrs=(unsigned short *)dmi->dmi_addr;
- dmi=dmi->next;
- i++;
- *setup_frm++ = *eaddrs++;
- *setup_frm++ = *eaddrs++;
- *setup_frm++ = *eaddrs++;
- }
- /* Fill the rest of the table with our physical address. */
- eaddrs = (unsigned short *)dev->dev_addr;
- do {
- *setup_frm++ = eaddrs[0];
- *setup_frm++ = eaddrs[1];
- *setup_frm++ = eaddrs[2];
- } while (++i < 16);
-
- /* Now add this frame to the Tx list. */
- }
-}
-
-static int
-set_mac_address(struct device *dev, void *addr)
-{
- int i;
- struct sockaddr *sa=(struct sockaddr *)addr;
- if (dev->start)
- return -EBUSY;
- printk("%s: Setting MAC address to ", dev->name);
- for (i = 0; i < 6; i++)
- printk(" %2.2x", dev->dev_addr[i] = sa->sa_data[i]);
- printk(".\n");
- return 0;
-}
-
-#ifdef MODULE
-static char devicename[9] = { 0, };
-static struct device dev_tulip = {
- devicename, /* device name is inserted by linux/drivers/net/net_init.c */
- 0, 0, 0, 0,
- 0, 0,
- 0, 0, 0, NULL, tulip_probe
-};
-
-static int io = 0;
-static int irq = 0;
-
-int init_module(void)
-{
- printk("tulip: Sorry, modularization is not completed\n");
- return -EIO;
-#if 0
- if (io == 0)
- printk("tulip: You should not use auto-probing with insmod!\n");
- dev_tulip.base_addr = io;
- dev_tulip.irq = irq;
- if (register_netdev(&dev_tulip) != 0) {
- printk("tulip: register_netdev() returned non-zero.\n");
- return -EIO;
- }
- return 0;
-#endif
-}
-
-void
-cleanup_module(void)
-{
- unregister_netdev(&dev_tulip);
-}
-#endif /* MODULE */
-
-/*
- * Local variables:
- * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c tulip.c"
- * c-indent-level: 4
- * tab-width: 4
- * End:
- */
diff --git a/i386/i386at/gpl/linux/net/wavelan.c b/i386/i386at/gpl/linux/net/wavelan.c
deleted file mode 100644
index 4d09badd..00000000
--- a/i386/i386at/gpl/linux/net/wavelan.c
+++ /dev/null
@@ -1,2526 +0,0 @@
-/*
- * AT&T GIS (nee NCR) WaveLAN card:
- * An Ethernet-like radio transceiver
- * controlled by an Intel 82586 coprocessor.
- */
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/stat.h>
-#include <linux/ptrace.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/string.h>
-#include <linux/delay.h>
-#include <asm/system.h>
-#include <asm/bitops.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <linux/errno.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/malloc.h>
-#include <linux/timer.h>
-#include <linux/proc_fs.h>
-#define STRUCT_CHECK 1
-#ifdef MACH
-#include <net/i82586.h>
-#else
-#include "i82586.h"
-#endif
-#include "wavelan.h"
-
-#ifndef WAVELAN_DEBUG
-#define WAVELAN_DEBUG 0
-#endif /* WAVELAN_DEBUG */
-
-#define WATCHDOG_JIFFIES 512 /* TODO: express in HZ. */
-#define ENABLE_FULL_PROMISCUOUS 0x10000
-
-#define nels(a) (sizeof(a) / sizeof(a[0]))
-
-typedef struct device device;
-typedef struct enet_statistics en_stats;
-typedef struct net_local net_local;
-typedef struct timer_list timer_list;
-
-struct net_local
-{
- en_stats stats;
- unsigned int tx_n_in_use;
- unsigned char nwid[2];
- unsigned short hacr;
- unsigned short rx_head;
- unsigned short rx_last;
- unsigned short tx_first_free;
- unsigned short tx_first_in_use;
- unsigned int nresets;
- unsigned int correct_nwid;
- unsigned int wrong_nwid;
- unsigned int promiscuous;
- unsigned int full_promiscuous;
- timer_list watchdog;
- device *dev;
- net_local *prev;
- net_local *next;
-};
-
-extern int wavelan_probe(device *); /* See Space.c */
-
-static const char *version = "wavelan.c:v7 95/4/8\n";
-
-/*
- * Entry point forward declarations.
- */
-static int wavelan_probe1(device *, unsigned short);
-static int wavelan_open(device *);
-static int wavelan_send_packet(struct sk_buff *, device *);
-static void wavelan_interrupt(int, struct pt_regs *);
-static int wavelan_close(device *);
-static en_stats *wavelan_get_stats(device *);
-static void wavelan_set_multicast_list(device *);
-static int wavelan_get_info(char*, char**, off_t, int, int);
-
-/*
- * Other forward declarations.
- */
-static void wavelan_cu_show_one(device *, net_local *, int, unsigned short);
-static void wavelan_cu_start(device *);
-static void wavelan_ru_start(device *);
-static void wavelan_watchdog(unsigned long);
-#if 0
-static void wavelan_psa_show(psa_t *);
-static void wavelan_mmc_show(unsigned short);
-#endif /* 0 */
-static void wavelan_scb_show(unsigned short);
-static void wavelan_ru_show(device *);
-static void wavelan_cu_show(device *);
-static void wavelan_dev_show(device *);
-static void wavelan_local_show(device *);
-
-static unsigned int wavelan_debug = WAVELAN_DEBUG;
-static net_local *first_wavelan = (net_local *)0;
-
-static
-unsigned long
-wavelan_splhi(void)
-{
- unsigned long flags;
-
- save_flags(flags);
- cli();
-
- return flags;
-}
-
-static
-void
-wavelan_splx(unsigned long flags)
-{
- restore_flags(flags);
-}
-
-static
-unsigned short
-hasr_read(unsigned short ioaddr)
-{
- return inw(HASR(ioaddr));
-}
-
-static
-void
-hacr_write(unsigned short ioaddr, int hacr)
-{
- outw(hacr, HACR(ioaddr));
-}
-
-static
-void
-hacr_write_slow(unsigned short ioaddr, int hacr)
-{
- hacr_write(ioaddr, hacr);
- /* delay might only be needed sometimes */
- udelay(1000);
-}
-
-/*
- * Set the channel attention bit.
- */
-static
-void
-set_chan_attn(unsigned short ioaddr, unsigned short current_hacr)
-{
- hacr_write(ioaddr, current_hacr | HACR_CA);
-}
-
-/*
- * Reset, and then set host adaptor into default mode.
- */
-static
-void
-wavelan_reset(unsigned short ioaddr)
-{
- hacr_write_slow(ioaddr, HACR_RESET);
- hacr_write(ioaddr, HACR_DEFAULT);
-}
-
-static
-void
-wavelan_16_off(unsigned short ioaddr, unsigned short hacr)
-{
- hacr &= ~HACR_16BITS;
-
- hacr_write(ioaddr, hacr);
-}
-
-static
-void
-wavelan_16_on(unsigned short ioaddr, unsigned short hacr)
-{
- hacr |= HACR_16BITS;
-
- hacr_write(ioaddr, hacr);
-}
-
-static
-void
-wavelan_ints_off(device *dev)
-{
- unsigned short ioaddr;
- net_local *lp;
- unsigned long x;
-
- ioaddr = dev->base_addr;
- lp = (net_local *)dev->priv;
-
- x = wavelan_splhi();
-
- lp->hacr &= ~HACR_INTRON;
- hacr_write(ioaddr, lp->hacr);
-
- wavelan_splx(x);
-}
-
-static
-void
-wavelan_ints_on(device *dev)
-{
- unsigned short ioaddr;
- net_local *lp;
- unsigned long x;
-
- ioaddr = dev->base_addr;
- lp = (net_local *)dev->priv;
-
- x = wavelan_splhi();
-
- lp->hacr |= HACR_INTRON;
- hacr_write(ioaddr, lp->hacr);
-
- wavelan_splx(x);
-}
-
-/*
- * Read bytes from the PSA.
- */
-static
-void
-psa_read(unsigned short ioaddr, unsigned short hacr, int o, unsigned char *b, int n)
-{
- wavelan_16_off(ioaddr, hacr);
-
- while (n-- > 0)
- {
- outw(o, PIOR2(ioaddr));
- o++;
- *b++ = inb(PIOP2(ioaddr));
- }
-
- wavelan_16_on(ioaddr, hacr);
-}
-
-#if defined(IRQ_SET_WORKS)
-/*
- * Write bytes to the PSA.
- */
-static
-void
-psa_write(unsigned short ioaddr, unsigned short hacr, int o, unsigned char *b, int n)
-{
- wavelan_16_off(ioaddr, hacr);
-
- while (n-- > 0)
- {
- outw(o, PIOR2(ioaddr));
- o++;
- outb(*b, PIOP2(ioaddr));
- b++;
- }
-
- wavelan_16_on(ioaddr, hacr);
-}
-#endif /* defined(IRQ_SET_WORKS) */
-
-/*
- * Read bytes from the on-board RAM.
- */
-static
-void
-obram_read(unsigned short ioaddr, unsigned short o, unsigned char *b, int n)
-{
- n = (n + 1) / (sizeof(unsigned short) / sizeof(unsigned char));
-
- outw(o, PIOR1(ioaddr));
-
- insw(PIOP1(ioaddr), (unsigned short *)b, n);
-}
-
-/*
- * Write bytes to the on-board RAM.
- */
-static
-void
-obram_write(unsigned short ioaddr, unsigned short o, unsigned char *b, int n)
-{
- n = (n + 1) / (sizeof(unsigned short) / sizeof(unsigned char));
-
- outw(o, PIOR1(ioaddr));
-
- outsw(PIOP1(ioaddr), (unsigned short *)b, n);
-}
-
-/*
- * Read bytes from the MMC.
- */
-static
-void
-mmc_read(unsigned short ioaddr, unsigned short o, unsigned char *b, int n)
-{
- while (n-- > 0)
- {
- while (inw(HASR(ioaddr)) & HASR_MMC_BUSY)
- ;
-
- outw(o << 1, MMCR(ioaddr));
- o++;
-
- while (inw(HASR(ioaddr)) & HASR_MMC_BUSY)
- ;
-
- *b++ = (unsigned char)(inw(MMCR(ioaddr)) >> 8);
- }
-}
-
-/*
- * Write bytes to the MMC.
- */
-static
-void
-mmc_write(unsigned short ioaddr, unsigned short o, unsigned char *b, int n)
-{
- while (n-- > 0)
- {
- while (inw(HASR(ioaddr)) & HASR_MMC_BUSY)
- ;
-
- outw((unsigned short)(((unsigned short)*b << 8) | (o << 1) | 1), MMCR(ioaddr));
- b++;
- o++;
- }
-}
-
-static int irqvals[] =
-{
- 0, 0, 0, 0x01,
- 0x02, 0x04, 0, 0x08,
- 0, 0, 0x10, 0x20,
- 0x40, 0, 0, 0x80,
-};
-
-#if defined(IRQ_SET_WORKS)
-static
-int
-wavelan_unmap_irq(int irq, unsigned char *irqval)
-{
- if (irq < 0 || irq >= nels(irqvals) || irqvals[irq] == 0)
- return -1;
-
- *irqval = (unsigned char)irqvals[irq];
-
- return 0;
-}
-#endif /* defined(IRQ_SET_WORKS) */
-
-/*
- * Map values from the irq parameter register to irq numbers.
- */
-static
-int
-wavelan_map_irq(unsigned char irqval)
-{
- int irq;
-
- for (irq = 0; irq < nels(irqvals); irq++)
- {
- if (irqvals[irq] == (int)irqval)
- return irq;
- }
-
- return -1;
-}
-
-/*
- * Initialize the Modem Management Controller.
- */
-static
-void
-wavelan_mmc_init(device *dev, psa_t *psa)
-{
- unsigned short ioaddr;
- net_local *lp;
- mmw_t m;
- int configured;
-
- ioaddr = dev->base_addr;
- lp = (net_local *)dev->priv;
- memset(&m, 0x00, sizeof(m));
-
- /*
- * configured = psa->psa_conf_status & 1;
- *
- * For now we use the persistent PSA
- * information as little as possible, thereby
- * allowing us to return to the same known state
- * during a hardware reset.
- */
- configured = 0;
-
- /*
- * Set default modem control parameters.
- * See NCR document 407-0024326 Rev. A.
- */
- m.mmw_jabber_enable = 0x01;
- m.mmw_anten_sel = MMW_ANTEN_SEL_ALG_EN;
- m.mmw_ifs = 0x20;
- m.mmw_mod_delay = 0x04;
- m.mmw_jam_time = 0x38;
-
- m.mmw_encr_enable = 0;
- m.mmw_des_io_invert = 0;
- m.mmw_freeze = 0;
- m.mmw_decay_prm = 0;
- m.mmw_decay_updat_prm = 0;
-
- if (configured)
- {
- /*
- * Use configuration defaults from parameter storage area.
- */
- if (psa->psa_undefined & 1)
- m.mmw_loopt_sel = 0x00;
- else
- m.mmw_loopt_sel = MMW_LOOPT_SEL_UNDEFINED;
-
- m.mmw_thr_pre_set = psa->psa_thr_pre_set & 0x3F;
- m.mmw_quality_thr = psa->psa_quality_thr & 0x0F;
- }
- else
- {
- if (lp->promiscuous && lp->full_promiscuous)
- m.mmw_loopt_sel = MMW_LOOPT_SEL_UNDEFINED;
- else
- m.mmw_loopt_sel = 0x00;
-
- /*
- * 0x04 for AT,
- * 0x01 for MCA.
- */
- if (psa->psa_comp_number & 1)
- m.mmw_thr_pre_set = 0x01;
- else
- m.mmw_thr_pre_set = 0x04;
-
- m.mmw_quality_thr = 0x03;
- }
-
- m.mmw_netw_id_l = lp->nwid[1];
- m.mmw_netw_id_h = lp->nwid[0];
-
- mmc_write(ioaddr, 0, (unsigned char *)&m, sizeof(m));
-}
-
-static
-void
-wavelan_ack(device *dev)
-{
- unsigned short ioaddr;
- net_local *lp;
- unsigned short scb_cs;
- int i;
-
- ioaddr = dev->base_addr;
- lp = (net_local *)dev->priv;
-
- obram_read(ioaddr, scboff(OFFSET_SCB, scb_status), (unsigned char *)&scb_cs, sizeof(scb_cs));
- scb_cs &= SCB_ST_INT;
-
- if (scb_cs == 0)
- return;
-
- obram_write(ioaddr, scboff(OFFSET_SCB, scb_command), (unsigned char *)&scb_cs, sizeof(scb_cs));
-
- set_chan_attn(ioaddr, lp->hacr);
-
- for (i = 1000; i > 0; i--)
- {
- obram_read(ioaddr, scboff(OFFSET_SCB, scb_command), (unsigned char *)&scb_cs, sizeof(scb_cs));
- if (scb_cs == 0)
- break;
-
- udelay(1000);
- }
-
- if (i <= 0)
- printk("%s: wavelan_ack(): board not accepting command.\n", dev->name);
-}
-
-/*
- * Set channel attention bit and busy wait until command has
- * completed, then acknowledge the command completion.
- */
-static
-int
-wavelan_synchronous_cmd(device *dev, const char *str)
-{
- unsigned short ioaddr;
- net_local *lp;
- unsigned short scb_cmd;
- ach_t cb;
- int i;
-
- ioaddr = dev->base_addr;
- lp = (net_local *)dev->priv;
-
- scb_cmd = SCB_CMD_CUC & SCB_CMD_CUC_GO;
- obram_write(ioaddr, scboff(OFFSET_SCB, scb_command), (unsigned char *)&scb_cmd, sizeof(scb_cmd));
-
- set_chan_attn(ioaddr, lp->hacr);
-
- for (i = 64; i > 0; i--)
- {
- obram_read(ioaddr, OFFSET_CU, (unsigned char *)&cb, sizeof(cb));
- if (cb.ac_status & AC_SFLD_C)
- break;
-
- udelay(1000);
- }
-
- if (i <= 0 || !(cb.ac_status & AC_SFLD_OK))
- {
- printk("%s: %s failed; status = 0x%x\n", dev->name, str, cb.ac_status);
- wavelan_scb_show(ioaddr);
- return -1;
- }
-
- wavelan_ack(dev);
-
- return 0;
-}
-
-static
-int
-wavelan_hardware_reset(device *dev)
-{
- unsigned short ioaddr;
- psa_t psa;
- net_local *lp;
- scp_t scp;
- iscp_t iscp;
- scb_t scb;
- ach_t cb;
- int i;
- ac_cfg_t cfg;
- ac_ias_t ias;
-
- if (wavelan_debug > 0)
- printk("%s: ->wavelan_hardware_reset(dev=0x%x)\n", dev->name, (unsigned int)dev);
-
- ioaddr = dev->base_addr;
- lp = (net_local *)dev->priv;
-
- lp->nresets++;
-
- wavelan_reset(ioaddr);
- lp->hacr = HACR_DEFAULT;
-
- /*
- * Clear the onboard RAM.
- */
- {
- unsigned char zeroes[512];
-
- memset(&zeroes[0], 0x00, sizeof(zeroes));
-
- for (i = 0; i < I82586_MEMZ; i += sizeof(zeroes))
- obram_write(ioaddr, i, &zeroes[0], sizeof(zeroes));
- }
-
- psa_read(ioaddr, lp->hacr, 0, (unsigned char *)&psa, sizeof(psa));
-
- wavelan_mmc_init(dev, &psa);
-
- /*
- * Construct the command unit structures:
- * scp, iscp, scb, cb.
- */
- memset(&scp, 0x00, sizeof(scp));
- scp.scp_sysbus = SCP_SY_16BBUS;
- scp.scp_iscpl = OFFSET_ISCP;
- obram_write(ioaddr, OFFSET_SCP, (unsigned char *)&scp, sizeof(scp));
-
- memset(&iscp, 0x00, sizeof(iscp));
- iscp.iscp_busy = 1;
- iscp.iscp_offset = OFFSET_SCB;
- obram_write(ioaddr, OFFSET_ISCP, (unsigned char *)&iscp, sizeof(iscp));
-
- memset(&scb, 0x00, sizeof(scb));
- scb.scb_command = SCB_CMD_RESET;
- scb.scb_cbl_offset = OFFSET_CU;
- scb.scb_rfa_offset = OFFSET_RU;
- obram_write(ioaddr, OFFSET_SCB, (unsigned char *)&scb, sizeof(scb));
-
- set_chan_attn(ioaddr, lp->hacr);
-
- for (i = 1000; i > 0; i--)
- {
- obram_read(ioaddr, OFFSET_ISCP, (unsigned char *)&iscp, sizeof(iscp));
-
- if (iscp.iscp_busy == (unsigned short)0)
- break;
-
- udelay(1000);
- }
-
- if (i <= 0)
- {
- printk("%s: wavelan_hardware_reset(): iscp_busy timeout.\n", dev->name);
- if (wavelan_debug > 0)
- printk("%s: <-wavelan_hardware_reset(): -1\n", dev->name);
- return -1;
- }
-
- for (i = 15; i > 0; i--)
- {
- obram_read(ioaddr, OFFSET_SCB, (unsigned char *)&scb, sizeof(scb));
-
- if (scb.scb_status == (SCB_ST_CX | SCB_ST_CNA))
- break;
-
- udelay(1000);
- }
-
- if (i <= 0)
- {
- printk("%s: wavelan_hardware_reset(): status: expected 0x%02x, got 0x%02x.\n", dev->name, SCB_ST_CX | SCB_ST_CNA, scb.scb_status);
- if (wavelan_debug > 0)
- printk("%s: <-wavelan_hardware_reset(): -1\n", dev->name);
- return -1;
- }
-
- wavelan_ack(dev);
-
- memset(&cb, 0x00, sizeof(cb));
- cb.ac_command = AC_CFLD_EL | (AC_CFLD_CMD & acmd_diagnose);
- cb.ac_link = OFFSET_CU;
- obram_write(ioaddr, OFFSET_CU, (unsigned char *)&cb, sizeof(cb));
-
- if (wavelan_synchronous_cmd(dev, "diag()") == -1)
- {
- if (wavelan_debug > 0)
- printk("%s: <-wavelan_hardware_reset(): -1\n", dev->name);
- return -1;
- }
-
- obram_read(ioaddr, OFFSET_CU, (unsigned char *)&cb, sizeof(cb));
- if (cb.ac_status & AC_SFLD_FAIL)
- {
- printk("%s: wavelan_hardware_reset(): i82586 Self Test failed.\n", dev->name);
- if (wavelan_debug > 0)
- printk("%s: <-wavelan_hardware_reset(): -1\n", dev->name);
- return -1;
- }
-
- memset(&cfg, 0x00, sizeof(cfg));
-
-#if 0
- /*
- * The default board configuration.
- */
- cfg.fifolim_bytecnt = 0x080c;
- cfg.addrlen_mode = 0x2600;
- cfg.linprio_interframe = 0x7820; /* IFS=120, ACS=2 */
- cfg.slot_time = 0xf00c; /* slottime=12 */
- cfg.hardware = 0x0008; /* tx even w/o CD */
- cfg.min_frame_len = 0x0040;
-#endif /* 0 */
-
- /*
- * For Linux we invert AC_CFG_ALOC(..) so as to conform
- * to the way that net packets reach us from above.
- * (See also ac_tx_t.)
- */
- cfg.cfg_byte_cnt = AC_CFG_BYTE_CNT(sizeof(ac_cfg_t) - sizeof(ach_t));
- cfg.cfg_fifolim = AC_CFG_FIFOLIM(8);
- cfg.cfg_byte8 = AC_CFG_SAV_BF(0) |
- AC_CFG_SRDY(0);
- cfg.cfg_byte9 = AC_CFG_ELPBCK(0) |
- AC_CFG_ILPBCK(0) |
- AC_CFG_PRELEN(AC_CFG_PLEN_2) |
- AC_CFG_ALOC(1) |
- AC_CFG_ADDRLEN(WAVELAN_ADDR_SIZE);
- cfg.cfg_byte10 = AC_CFG_BOFMET(0) |
- AC_CFG_ACR(0) |
- AC_CFG_LINPRIO(0);
- cfg.cfg_ifs = 32;
- cfg.cfg_slotl = 0;
- cfg.cfg_byte13 = AC_CFG_RETRYNUM(15) |
- AC_CFG_SLTTMHI(2);
- cfg.cfg_byte14 = AC_CFG_FLGPAD(0) |
- AC_CFG_BTSTF(0) |
- AC_CFG_CRC16(0) |
- AC_CFG_NCRC(0) |
- AC_CFG_TNCRS(1) |
- AC_CFG_MANCH(0) |
- AC_CFG_BCDIS(0) |
- AC_CFG_PRM(lp->promiscuous);
- cfg.cfg_byte15 = AC_CFG_ICDS(0) |
- AC_CFG_CDTF(0) |
- AC_CFG_ICSS(0) |
- AC_CFG_CSTF(0);
-/*
- cfg.cfg_min_frm_len = AC_CFG_MNFRM(64);
-*/
- cfg.cfg_min_frm_len = AC_CFG_MNFRM(8);
-
- cfg.cfg_h.ac_command = AC_CFLD_EL | (AC_CFLD_CMD & acmd_configure);
- cfg.cfg_h.ac_link = OFFSET_CU;
- obram_write(ioaddr, OFFSET_CU, (unsigned char *)&cfg, sizeof(cfg));
-
- if (wavelan_synchronous_cmd(dev, "reset()-configure") == -1)
- {
- if (wavelan_debug > 0)
- printk("%s: <-wavelan_hardware_reset(): -1\n", dev->name);
-
- return -1;
- }
-
- memset(&ias, 0x00, sizeof(ias));
- ias.ias_h.ac_command = AC_CFLD_EL | (AC_CFLD_CMD & acmd_ia_setup);
- ias.ias_h.ac_link = OFFSET_CU;
- memcpy(&ias.ias_addr[0], (unsigned char *)&dev->dev_addr[0], sizeof(ias.ias_addr));
- obram_write(ioaddr, OFFSET_CU, (unsigned char *)&ias, sizeof(ias));
-
- if (wavelan_synchronous_cmd(dev, "reset()-address") == -1)
- {
- if (wavelan_debug > 0)
- printk("%s: <-wavelan_hardware_reset(): -1\n", dev->name);
-
- return -1;
- }
-
- wavelan_ints_on(dev);
-
- if (wavelan_debug > 4)
- wavelan_scb_show(ioaddr);
-
- wavelan_ru_start(dev);
- wavelan_cu_start(dev);
-
- if (wavelan_debug > 0)
- printk("%s: <-wavelan_hardware_reset(): 0\n", dev->name);
-
- return 0;
-}
-
-#if STRUCT_CHECK == 1
-
-static
-const char *
-wavelan_struct_check(void)
-{
-#define SC(t,s,n) if (sizeof(t) != s) return n
- SC(psa_t, PSA_SIZE, "psa_t");
- SC(mmw_t, MMW_SIZE, "mmw_t");
- SC(mmr_t, MMR_SIZE, "mmr_t");
- SC(ha_t, HA_SIZE, "ha_t");
-#undef SC
-
- return (char *)0;
-}
-
-#endif /* STRUCT_CHECK == 1 */
-
-/*
- * Check for a network adaptor of this type.
- * Return '0' iff one exists.
- * (There seem to be different interpretations of
- * the initial value of dev->base_addr.
- * We follow the example in drivers/net/ne.c.)
- */
-int
-wavelan_probe(device *dev)
-{
- int i;
- int r;
- short base_addr;
- static unsigned short iobase[] =
- {
-#if 0
- Leave out 0x3C0 for now -- seems to clash
- with some video controllers.
- Leave out the others too -- we will always
- use 0x390 and leave 0x300 for the Ethernet device.
- 0x300, 0x390, 0x3E0, 0x3C0,
-#endif /* 0 */
- 0x390,
- };
-
- if (wavelan_debug > 0)
- printk("%s: ->wavelan_probe(dev=0x%x (base_addr=0x%x))\n", dev->name, (unsigned int)dev, (unsigned int)dev->base_addr);
-
-#if STRUCT_CHECK == 1
- if (wavelan_struct_check() != (char *)0)
- {
- printk("%s: structure/compiler botch: \"%s\"\n", dev->name, wavelan_struct_check());
-
- if (wavelan_debug > 0)
- printk("%s: <-wavelan_probe(): ENODEV\n", dev->name);
-
- return ENODEV;
- }
-#endif /* STRUCT_CHECK == 1 */
-
- base_addr = dev->base_addr;
-
- if (base_addr < 0)
- {
- /*
- * Don't probe at all.
- */
- if (wavelan_debug > 0)
- printk("%s: <-wavelan_probe(): ENXIO\n", dev->name);
- return ENXIO;
- }
-
- if (base_addr > 0x100)
- {
- /*
- * Check a single specified location.
- */
- r = wavelan_probe1(dev, base_addr);
- if (wavelan_debug > 0)
- printk("%s: <-wavelan_probe(): %d\n", dev->name, r);
- return r;
- }
-
- for (i = 0; i < nels(iobase); i++)
- {
- if (check_region(iobase[i], sizeof(ha_t)))
- continue;
-
- if (wavelan_probe1(dev, iobase[i]) == 0)
- {
- if (wavelan_debug > 0)
- printk("%s: <-wavelan_probe(): 0\n", dev->name);
- proc_net_register(&(struct proc_dir_entry) {
- PROC_NET_WAVELAN, 7, "wavelan",
- S_IFREG | S_IRUGO, 1, 0, 0,
- 0, &proc_net_inode_operations,
- wavelan_get_info
- });
-
- return 0;
- }
- }
-
- if (wavelan_debug > 0)
- printk("%s: <-wavelan_probe(): ENODEV\n", dev->name);
-
- return ENODEV;
-}
-
-static
-int
-wavelan_probe1(device *dev, unsigned short ioaddr)
-{
- psa_t psa;
- int irq;
- int i;
- net_local *lp;
- int enable_full_promiscuous;
-
- if (wavelan_debug > 0)
- printk("%s: ->wavelan_probe1(dev=0x%x, ioaddr=0x%x)\n", dev->name, (unsigned int)dev, ioaddr);
-
- wavelan_reset(ioaddr);
-
- psa_read(ioaddr, HACR_DEFAULT, 0, (unsigned char *)&psa, sizeof(psa));
-
- /*
- * Check the first three octets of the MAC address
- * for the manufacturer's code.
- */
- if
- (
- psa.psa_univ_mac_addr[0] != SA_ADDR0
- ||
- psa.psa_univ_mac_addr[1] != SA_ADDR1
- ||
- psa.psa_univ_mac_addr[2] != SA_ADDR2
- )
- {
- if (wavelan_debug > 0)
- printk("%s: <-wavelan_probe1(): ENODEV\n", dev->name);
- return ENODEV;
- }
-
- printk("%s: WaveLAN at %#x,", dev->name, ioaddr);
-
- if (dev->irq != 0)
- {
- printk("[WARNING: explicit IRQ value %d ignored: using PSA value instead]", dev->irq);
-#if defined(IRQ_SET_WORKS)
-Leave this out until I can get it to work -- BJ.
- if (wavelan_unmap_irq(dev->irq, &psa.psa_int_req_no) == -1)
- {
- printk(" could not wavelan_unmap_irq(%d, ..) -- ignored.\n", dev->irq);
- dev->irq = 0;
- }
- else
- {
- psa_write(ioaddr, HACR_DEFAULT, (char *)&psa.psa_int_req_no - (char *)&psa, (unsigned char *)&psa.psa_int_req_no, sizeof(psa.psa_int_req_no));
- wavelan_reset(ioaddr);
- }
-#endif /* defined(IRQ_SET_WORKS) */
- }
-
- if ((irq = wavelan_map_irq(psa.psa_int_req_no)) == -1)
- {
- printk(" could not wavelan_map_irq(%d).\n", psa.psa_int_req_no);
- if (wavelan_debug > 0)
- printk("%s: <-wavelan_probe1(): EAGAIN\n", dev->name);
- return EAGAIN;
- }
-
- dev->irq = irq;
-
- request_region(ioaddr, sizeof(ha_t), "wavelan");
- dev->base_addr = ioaddr;
-
- /*
- * The third numeric argument to LILO's
- * `ether=' control line arrives here as `dev->mem_start'.
- *
- * If bit 16 of dev->mem_start is non-zero we enable
- * full promiscuity.
- *
- * If either of the least significant two bytes of
- * dev->mem_start are non-zero we use them instead
- * of the PSA NWID.
- */
- enable_full_promiscuous = (dev->mem_start & ENABLE_FULL_PROMISCUOUS) == ENABLE_FULL_PROMISCUOUS;
- dev->mem_start &= ~ENABLE_FULL_PROMISCUOUS;
-
- if (dev->mem_start != 0)
- {
- psa.psa_nwid[0] = (dev->mem_start >> 8) & 0xFF;
- psa.psa_nwid[1] = (dev->mem_start >> 0) & 0xFF;
- }
-
- dev->mem_start = 0x0000;
- dev->mem_end = 0x0000;
- dev->if_port = 0;
-
- memcpy(&dev->dev_addr[0], &psa.psa_univ_mac_addr[0], WAVELAN_ADDR_SIZE);
-
- for (i = 0; i < WAVELAN_ADDR_SIZE; i++)
- printk("%s%02x", (i == 0) ? " " : ":", dev->dev_addr[i]);
-
- printk(", IRQ %d", dev->irq);
- if (enable_full_promiscuous)
- printk(", promisc");
- printk(", nwid 0x%02x%02x", psa.psa_nwid[0], psa.psa_nwid[1]);
-
- printk(", PC");
- switch (psa.psa_comp_number)
- {
- case PSA_COMP_PC_AT_915:
- case PSA_COMP_PC_AT_2400:
- printk("-AT");
- break;
-
- case PSA_COMP_PC_MC_915:
- case PSA_COMP_PC_MC_2400:
- printk("-MC");
- break;
-
- case PSA_COMP_PCMCIA_915:
- printk("MCIA");
- break;
-
- default:
- printk("???");
- break;
- }
-
- printk(", ");
- switch (psa.psa_subband)
- {
- case PSA_SUBBAND_915:
- printk("915");
- break;
-
- case PSA_SUBBAND_2425:
- printk("2425");
- break;
-
- case PSA_SUBBAND_2460:
- printk("2460");
- break;
-
- case PSA_SUBBAND_2484:
- printk("2484");
- break;
-
- case PSA_SUBBAND_2430_5:
- printk("2430.5");
- break;
-
- default:
- printk("???");
- break;
- }
- printk(" MHz");
-
- printk("\n");
-
- if (wavelan_debug > 0)
- printk(version);
-
- dev->priv = kmalloc(sizeof(net_local), GFP_KERNEL);
- if (dev->priv == NULL)
- return -ENOMEM;
- memset(dev->priv, 0x00, sizeof(net_local));
- lp = (net_local *)dev->priv;
-
- if (first_wavelan == (net_local *)0)
- {
- first_wavelan = lp;
- lp->prev = lp;
- lp->next = lp;
- }
- else
- {
- lp->prev = first_wavelan->prev;
- lp->next = first_wavelan;
- first_wavelan->prev->next = lp;
- first_wavelan->prev = lp;
- }
- lp->dev = dev;
-
- lp->hacr = HACR_DEFAULT;
-
- lp->full_promiscuous = enable_full_promiscuous;
- lp->nwid[0] = psa.psa_nwid[0];
- lp->nwid[1] = psa.psa_nwid[1];
-
- lp->watchdog.function = wavelan_watchdog;
- lp->watchdog.data = (unsigned long)dev;
-
- dev->open = wavelan_open;
- dev->stop = wavelan_close;
- dev->hard_start_xmit = wavelan_send_packet;
- dev->get_stats = wavelan_get_stats;
- dev->set_multicast_list = &wavelan_set_multicast_list;
-
- /*
- * Fill in the fields of the device structure
- * with ethernet-generic values.
- */
- ether_setup(dev);
-
- dev->flags &= ~IFF_MULTICAST; /* Not yet supported */
-
- dev->mtu = WAVELAN_MTU;
-
- if (wavelan_debug > 0)
- printk("%s: <-wavelan_probe1(): 0\n", dev->name);
-
- return 0;
-}
-
-/*
- * Construct the fd and rbd structures.
- * Start the receive unit.
- */
-static
-void
-wavelan_ru_start(device *dev)
-{
- unsigned short ioaddr;
- net_local *lp;
- unsigned short scb_cs;
- fd_t fd;
- rbd_t rbd;
- unsigned short rx;
- unsigned short rx_next;
- int i;
-
- ioaddr = dev->base_addr;
- lp = (net_local *)dev->priv;
-
- obram_read(ioaddr, scboff(OFFSET_SCB, scb_status), (unsigned char *)&scb_cs, sizeof(scb_cs));
- if ((scb_cs & SCB_ST_RUS) == SCB_ST_RUS_RDY)
- return;
-
- lp->rx_head = OFFSET_RU;
-
- for (i = 0, rx = lp->rx_head; i < NRXBLOCKS; i++, rx = rx_next)
- {
- rx_next = (i == NRXBLOCKS - 1) ? lp->rx_head : rx + RXBLOCKZ;
-
- fd.fd_status = 0;
- fd.fd_command = (i == NRXBLOCKS - 1) ? FD_COMMAND_EL : 0;
- fd.fd_link_offset = rx_next;
- fd.fd_rbd_offset = rx + sizeof(fd);
- obram_write(ioaddr, rx, (unsigned char *)&fd, sizeof(fd));
-
- rbd.rbd_status = 0;
- rbd.rbd_next_rbd_offset = I82586NULL;
- rbd.rbd_bufl = rx + sizeof(fd) + sizeof(rbd);
- rbd.rbd_bufh = 0;
- rbd.rbd_el_size = RBD_EL | (RBD_SIZE & MAXDATAZ);
- obram_write(ioaddr, rx + sizeof(fd), (unsigned char *)&rbd, sizeof(rbd));
-
- lp->rx_last = rx;
- }
-
- obram_write(ioaddr, scboff(OFFSET_SCB, scb_rfa_offset), (unsigned char *)&lp->rx_head, sizeof(lp->rx_head));
-
- scb_cs = SCB_CMD_RUC_GO;
- obram_write(ioaddr, scboff(OFFSET_SCB, scb_command), (unsigned char *)&scb_cs, sizeof(scb_cs));
-
- set_chan_attn(ioaddr, lp->hacr);
-
- for (i = 1000; i > 0; i--)
- {
- obram_read(ioaddr, scboff(OFFSET_SCB, scb_command), (unsigned char *)&scb_cs, sizeof(scb_cs));
- if (scb_cs == 0)
- break;
-
- udelay(1000);
- }
-
- if (i <= 0)
- printk("%s: wavelan_ru_start(): board not accepting command.\n", dev->name);
-}
-
-/*
- * Initialise the transmit blocks.
- * Start the command unit executing the NOP
- * self-loop of the first transmit block.
- */
-static
-void
-wavelan_cu_start(device *dev)
-{
- unsigned short ioaddr;
- net_local *lp;
- int i;
- unsigned short txblock;
- unsigned short first_nop;
- unsigned short scb_cs;
-
- ioaddr = dev->base_addr;
- lp = (net_local *)dev->priv;
-
- lp->tx_first_free = OFFSET_CU;
- lp->tx_first_in_use = I82586NULL;
-
- for
- (
- i = 0, txblock = OFFSET_CU;
- i < NTXBLOCKS;
- i++, txblock += TXBLOCKZ
- )
- {
- ac_tx_t tx;
- ac_nop_t nop;
- tbd_t tbd;
- unsigned short tx_addr;
- unsigned short nop_addr;
- unsigned short tbd_addr;
- unsigned short buf_addr;
-
- tx_addr = txblock;
- nop_addr = tx_addr + sizeof(tx);
- tbd_addr = nop_addr + sizeof(nop);
- buf_addr = tbd_addr + sizeof(tbd);
-
- tx.tx_h.ac_status = 0;
- tx.tx_h.ac_command = acmd_transmit | AC_CFLD_I;
- tx.tx_h.ac_link = nop_addr;
- tx.tx_tbd_offset = tbd_addr;
- obram_write(ioaddr, tx_addr, (unsigned char *)&tx, sizeof(tx));
-
- nop.nop_h.ac_status = 0;
- nop.nop_h.ac_command = acmd_nop;
- nop.nop_h.ac_link = nop_addr;
- obram_write(ioaddr, nop_addr, (unsigned char *)&nop, sizeof(nop));
-
- tbd.tbd_status = TBD_STATUS_EOF;
- tbd.tbd_next_bd_offset = I82586NULL;
- tbd.tbd_bufl = buf_addr;
- tbd.tbd_bufh = 0;
- obram_write(ioaddr, tbd_addr, (unsigned char *)&tbd, sizeof(tbd));
- }
-
- first_nop = OFFSET_CU + (NTXBLOCKS - 1) * TXBLOCKZ + sizeof(ac_tx_t);
- obram_write(ioaddr, scboff(OFFSET_SCB, scb_cbl_offset), (unsigned char *)&first_nop, sizeof(first_nop));
-
- scb_cs = SCB_CMD_CUC_GO;
- obram_write(ioaddr, scboff(OFFSET_SCB, scb_command), (unsigned char *)&scb_cs, sizeof(scb_cs));
-
- set_chan_attn(ioaddr, lp->hacr);
-
- for (i = 1000; i > 0; i--)
- {
- obram_read(ioaddr, scboff(OFFSET_SCB, scb_command), (unsigned char *)&scb_cs, sizeof(scb_cs));
- if (scb_cs == 0)
- break;
-
- udelay(1000);
- }
-
- if (i <= 0)
- printk("%s: wavelan_cu_start(): board not accepting command.\n", dev->name);
-
- lp->tx_n_in_use = 0;
- dev->tbusy = 0;
-}
-
-static
-int
-wavelan_open(device *dev)
-{
- unsigned short ioaddr;
- net_local *lp;
- unsigned long x;
- int r;
-
- if (wavelan_debug > 0)
- printk("%s: ->wavelan_open(dev=0x%x)\n", dev->name, (unsigned int)dev);
-
- ioaddr = dev->base_addr;
- lp = (net_local *)dev->priv;
-
- if (dev->irq == 0)
- {
- if (wavelan_debug > 0)
- printk("%s: <-wavelan_open(): -ENXIO\n", dev->name);
- return -ENXIO;
- }
-
- if
- (
- irq2dev_map[dev->irq] != (device *)0
- /* This is always true, but avoid the false IRQ. */
- ||
- (irq2dev_map[dev->irq] = dev) == (device *)0
- ||
- request_irq(dev->irq, &wavelan_interrupt, 0, "WaveLAN") != 0
- )
- {
- irq2dev_map[dev->irq] = (device *)0;
- if (wavelan_debug > 0)
- printk("%s: <-wavelan_open(): -EAGAIN\n", dev->name);
- return -EAGAIN;
- }
-
- x = wavelan_splhi();
- if ((r = wavelan_hardware_reset(dev)) != -1)
- {
- dev->interrupt = 0;
- dev->start = 1;
- }
- wavelan_splx(x);
-
- if (r == -1)
- {
- free_irq(dev->irq);
- irq2dev_map[dev->irq] = (device *)0;
- if (wavelan_debug > 0)
- printk("%s: <-wavelan_open(): -EAGAIN(2)\n", dev->name);
- return -EAGAIN;
- }
-
- MOD_INC_USE_COUNT;
-
- if (wavelan_debug > 0)
- printk("%s: <-wavelan_open(): 0\n", dev->name);
-
- return 0;
-}
-
-static
-void
-hardware_send_packet(device *dev, void *buf, short length)
-{
- unsigned short ioaddr;
- net_local *lp;
- unsigned short txblock;
- unsigned short txpred;
- unsigned short tx_addr;
- unsigned short nop_addr;
- unsigned short tbd_addr;
- unsigned short buf_addr;
- ac_tx_t tx;
- ac_nop_t nop;
- tbd_t tbd;
- unsigned long x;
-
- ioaddr = dev->base_addr;
- lp = (net_local *)dev->priv;
-
- x = wavelan_splhi();
-
- txblock = lp->tx_first_free;
- txpred = txblock - TXBLOCKZ;
- if (txpred < OFFSET_CU)
- txpred += NTXBLOCKS * TXBLOCKZ;
- lp->tx_first_free += TXBLOCKZ;
- if (lp->tx_first_free >= OFFSET_CU + NTXBLOCKS * TXBLOCKZ)
- lp->tx_first_free -= NTXBLOCKS * TXBLOCKZ;
-
-/*
-if (lp->tx_n_in_use > 0)
- printk("%c", "0123456789abcdefghijk"[lp->tx_n_in_use]);
-*/
-
- lp->tx_n_in_use++;
-
- tx_addr = txblock;
- nop_addr = tx_addr + sizeof(tx);
- tbd_addr = nop_addr + sizeof(nop);
- buf_addr = tbd_addr + sizeof(tbd);
-
- /*
- * Transmit command.
- */
- tx.tx_h.ac_status = 0;
- obram_write(ioaddr, toff(ac_tx_t, tx_addr, tx_h.ac_status), (unsigned char *)&tx.tx_h.ac_status, sizeof(tx.tx_h.ac_status));
-
- /*
- * NOP command.
- */
- nop.nop_h.ac_status = 0;
- obram_write(ioaddr, toff(ac_nop_t, nop_addr, nop_h.ac_status), (unsigned char *)&nop.nop_h.ac_status, sizeof(nop.nop_h.ac_status));
- nop.nop_h.ac_link = nop_addr;
- obram_write(ioaddr, toff(ac_nop_t, nop_addr, nop_h.ac_link), (unsigned char *)&nop.nop_h.ac_link, sizeof(nop.nop_h.ac_link));
-
- /*
- * Transmit buffer descriptor.
- */
- tbd.tbd_status = TBD_STATUS_EOF | (TBD_STATUS_ACNT & length);
- tbd.tbd_next_bd_offset = I82586NULL;
- tbd.tbd_bufl = buf_addr;
- tbd.tbd_bufh = 0;
- obram_write(ioaddr, tbd_addr, (unsigned char *)&tbd, sizeof(tbd));
-
- /*
- * Data.
- */
- obram_write(ioaddr, buf_addr, buf, length);
-
- /*
- * Overwrite the predecessor NOP link
- * so that it points to this txblock.
- */
- nop_addr = txpred + sizeof(tx);
- nop.nop_h.ac_status = 0;
- obram_write(ioaddr, toff(ac_nop_t, nop_addr, nop_h.ac_status), (unsigned char *)&nop.nop_h.ac_status, sizeof(nop.nop_h.ac_status));
- nop.nop_h.ac_link = txblock;
- obram_write(ioaddr, toff(ac_nop_t, nop_addr, nop_h.ac_link), (unsigned char *)&nop.nop_h.ac_link, sizeof(nop.nop_h.ac_link));
-
- if (lp->tx_first_in_use == I82586NULL)
- lp->tx_first_in_use = txblock;
-
- if (lp->tx_n_in_use < NTXBLOCKS - 1)
- dev->tbusy = 0;
-
- dev->trans_start = jiffies;
-
- if (lp->watchdog.next == (timer_list *)0)
- wavelan_watchdog((unsigned long)dev);
-
- wavelan_splx(x);
-
- if (wavelan_debug > 4)
- {
- unsigned char *a;
-
- a = (unsigned char *)buf;
-
- printk
- (
- "%s: tx: dest %02x:%02x:%02x:%02x:%02x:%02x, length %d, tbd.tbd_bufl 0x%x.\n",
- dev->name,
- a[0], a[1], a[2], a[3], a[4], a[5],
- length,
- buf_addr
- );
- }
-}
-
-static
-int
-wavelan_send_packet(struct sk_buff *skb, device *dev)
-{
- unsigned short ioaddr;
-
- ioaddr = dev->base_addr;
-
- if (dev->tbusy)
- {
- /*
- * If we get here, some higher level
- * has decided we are broken.
- */
- int tickssofar;
-
- tickssofar = jiffies - dev->trans_start;
-
- /*
- * But for the moment, we will rely on wavelan_watchdog()
- * instead as it allows finer control over exactly when we
- * make the determination of failure.
- *
- if (tickssofar < 5)
- */
- return 1;
-
- wavelan_scb_show(ioaddr);
- wavelan_ru_show(dev);
- wavelan_cu_show(dev);
- wavelan_dev_show(dev);
- wavelan_local_show(dev);
-
- printk("%s: transmit timed out -- resetting board.\n", dev->name);
-
- (void)wavelan_hardware_reset(dev);
- }
-
- /*
- * If some higher layer thinks we've missed
- * a tx-done interrupt we are passed NULL.
- * Caution: dev_tint() handles the cli()/sti() itself.
- */
- if (skb == (struct sk_buff *)0)
- {
- dev_tint(dev);
- return 0;
- }
-
- /*
- * Block a timer-based transmit from overlapping.
- */
- if (set_bit(0, (void *)&dev->tbusy) == 0)
- {
- short length;
- unsigned char *buf;
-
- length = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
- buf = skb->data;
-
- hardware_send_packet(dev, buf, length);
- }
- else
- printk("%s: Transmitter access conflict.\n", dev->name);
-
- dev_kfree_skb(skb, FREE_WRITE);
-
- return 0;
-}
-
-#if 0
-static
-int
-addrcmp(unsigned char *a0, unsigned char *a1)
-{
- int i;
-
- for (i = 0; i < WAVELAN_ADDR_SIZE; i++)
- {
- if (a0[i] != a1[i])
- return a0[i] - a1[i];
- }
-
- return 0;
-}
-#endif /* 0 */
-
-/*
- * Transfer as many packets as we can
- * from the device RAM.
- * Called by the interrupt handler.
- */
-static
-void
-wavelan_receive(device *dev)
-{
- unsigned short ioaddr;
- net_local *lp;
- int nreaped;
-
- ioaddr = dev->base_addr;
- lp = (net_local *)dev->priv;
- nreaped = 0;
-
- for (;;)
- {
- fd_t fd;
- rbd_t rbd;
- ushort pkt_len;
- int sksize;
- struct sk_buff *skb;
-
- obram_read(ioaddr, lp->rx_head, (unsigned char *)&fd, sizeof(fd));
-
- if ((fd.fd_status & FD_STATUS_C) != FD_STATUS_C)
- break;
-
- nreaped++;
-
- if
- (
- (fd.fd_status & (FD_STATUS_B | FD_STATUS_OK))
- !=
- (FD_STATUS_B | FD_STATUS_OK)
- )
- {
- /*
- * Not sure about this one -- it does not seem
- * to be an error so we will keep quiet about it.
- if ((fd.fd_status & FD_STATUS_B) != FD_STATUS_B)
- printk("%s: frame not consumed by RU.\n", dev->name);
- */
-
- if ((fd.fd_status & FD_STATUS_OK) != FD_STATUS_OK)
- printk("%s: frame not received successfully.\n", dev->name);
- }
-
- if ((fd.fd_status & (FD_STATUS_S6 | FD_STATUS_S7 | FD_STATUS_S8 | FD_STATUS_S9 | FD_STATUS_S10 | FD_STATUS_S11)) != 0)
- {
- lp->stats.rx_errors++;
-
- if ((fd.fd_status & FD_STATUS_S6) != 0)
- printk("%s: no EOF flag.\n", dev->name);
-
- if ((fd.fd_status & FD_STATUS_S7) != 0)
- {
- lp->stats.rx_length_errors++;
- printk("%s: frame too short.\n", dev->name);
- }
-
- if ((fd.fd_status & FD_STATUS_S8) != 0)
- {
- lp->stats.rx_over_errors++;
- printk("%s: rx DMA overrun.\n", dev->name);
- }
-
- if ((fd.fd_status & FD_STATUS_S9) != 0)
- {
- lp->stats.rx_fifo_errors++;
- printk("%s: ran out of resources.\n", dev->name);
- }
-
- if ((fd.fd_status & FD_STATUS_S10) != 0)
- {
- lp->stats.rx_frame_errors++;
- printk("%s: alignment error.\n", dev->name);
- }
-
- if ((fd.fd_status & FD_STATUS_S11) != 0)
- {
- lp->stats.rx_crc_errors++;
- printk("%s: CRC error.\n", dev->name);
- }
- }
-
- if (fd.fd_rbd_offset == I82586NULL)
- printk("%s: frame has no data.\n", dev->name);
- else
- {
- obram_read(ioaddr, fd.fd_rbd_offset, (unsigned char *)&rbd, sizeof(rbd));
-
- if ((rbd.rbd_status & RBD_STATUS_EOF) != RBD_STATUS_EOF)
- printk("%s: missing EOF flag.\n", dev->name);
-
- if ((rbd.rbd_status & RBD_STATUS_F) != RBD_STATUS_F)
- printk("%s: missing F flag.\n", dev->name);
-
- pkt_len = rbd.rbd_status & RBD_STATUS_ACNT;
-
-#if 0
- {
- unsigned char addr[WAVELAN_ADDR_SIZE];
- int i;
- static unsigned char toweraddr[WAVELAN_ADDR_SIZE] =
- {
- 0x08, 0x00, 0x0e, 0x20, 0x3e, 0xd3,
- };
-
- obram_read(ioaddr, rbd.rbd_bufl + sizeof(addr), &addr[0], sizeof(addr));
- if
- (
- /*
- addrcmp(&addr[0], &dev->dev_addr[0]) != 0
- &&
- */
- addrcmp(&addr[0], toweraddr) != 0
- )
- {
- printk("%s: foreign MAC source addr=", dev->name);
- for (i = 0; i < WAVELAN_ADDR_SIZE; i++)
- printk("%s%02x", (i == 0) ? "" : ":", addr[i]);
- printk("\n");
- }
- }
-#endif /* 0 */
-
- if (wavelan_debug > 5)
- {
- unsigned char addr[WAVELAN_ADDR_SIZE];
- unsigned short ltype;
- int i;
-
-#if 0
- printk("%s: fd_dest=", dev->name);
- for (i = 0; i < WAVELAN_ADDR_SIZE; i++)
- printk("%s%02x", (i == 0) ? "" : ":", fd.fd_dest[i]);
- printk("\n");
-
- printk("%s: fd_src=", dev->name);
- for (i = 0; i < WAVELAN_ADDR_SIZE; i++)
- printk("%s%02x", (i == 0) ? "" : ":", fd.fd_src[i]);
- printk("\n");
- printk("%s: fd_length=%d\n", dev->name, fd.fd_length);
-#endif /* 0 */
-
- obram_read(ioaddr, rbd.rbd_bufl, &addr[0], sizeof(addr));
- printk("%s: dest=", dev->name);
- for (i = 0; i < WAVELAN_ADDR_SIZE; i++)
- printk("%s%02x", (i == 0) ? "" : ":", addr[i]);
- printk("\n");
-
- obram_read(ioaddr, rbd.rbd_bufl + sizeof(addr), &addr[0], sizeof(addr));
- printk("%s: src=", dev->name);
- for (i = 0; i < WAVELAN_ADDR_SIZE; i++)
- printk("%s%02x", (i == 0) ? "" : ":", addr[i]);
- printk("\n");
-
- obram_read(ioaddr, rbd.rbd_bufl + sizeof(addr) * 2, (unsigned char *)&ltype, sizeof(ltype));
- printk("%s: ntohs(length/type)=0x%04x\n", dev->name, ntohs(ltype));
- }
-
- sksize = pkt_len;
-
- if ((skb = dev_alloc_skb(sksize)) == (struct sk_buff *)0)
- {
- printk("%s: could not alloc_skb(%d, GFP_ATOMIC).\n", dev->name, sksize);
- lp->stats.rx_dropped++;
- }
- else
- {
- skb->dev = dev;
-
- obram_read(ioaddr, rbd.rbd_bufl, skb_put(skb,pkt_len), pkt_len);
-
- if (wavelan_debug > 5)
- {
- int i;
- int maxi;
-
- printk("%s: pkt_len=%d, data=\"", dev->name, pkt_len);
-
- if ((maxi = pkt_len) > 16)
- maxi = 16;
-
- for (i = 0; i < maxi; i++)
- {
- unsigned char c;
-
- c = skb->data[i];
- if (c >= ' ' && c <= '~')
- printk(" %c", skb->data[i]);
- else
- printk("%02x", skb->data[i]);
- }
-
- if (maxi < pkt_len)
- printk("..");
-
- printk("\"\n\n");
- }
-
- skb->protocol=eth_type_trans(skb,dev);
- netif_rx(skb);
-
- lp->stats.rx_packets++;
- }
- }
-
- fd.fd_status = 0;
- obram_write(ioaddr, fdoff(lp->rx_head, fd_status), (unsigned char *)&fd.fd_status, sizeof(fd.fd_status));
-
- fd.fd_command = FD_COMMAND_EL;
- obram_write(ioaddr, fdoff(lp->rx_head, fd_command), (unsigned char *)&fd.fd_command, sizeof(fd.fd_command));
-
- fd.fd_command = 0;
- obram_write(ioaddr, fdoff(lp->rx_last, fd_command), (unsigned char *)&fd.fd_command, sizeof(fd.fd_command));
-
- lp->rx_last = lp->rx_head;
- lp->rx_head = fd.fd_link_offset;
- }
-
-/*
- if (nreaped > 1)
- printk("r%d", nreaped);
-*/
-}
-
-/*
- * Command completion interrupt.
- * Reclaim as many freed tx buffers as we can.
- */
-static
-int
-wavelan_complete(device *dev, unsigned short ioaddr, net_local *lp)
-{
- int nreaped;
-
- nreaped = 0;
-
- for (;;)
- {
- unsigned short tx_status;
-
- if (lp->tx_first_in_use == I82586NULL)
- break;
-
- obram_read(ioaddr, acoff(lp->tx_first_in_use, ac_status), (unsigned char *)&tx_status, sizeof(tx_status));
-
- if ((tx_status & AC_SFLD_C) == 0)
- break;
-
- nreaped++;
-
- --lp->tx_n_in_use;
-
-/*
-if (lp->tx_n_in_use > 0)
- printk("%c", "0123456789abcdefghijk"[lp->tx_n_in_use]);
-*/
-
- if (lp->tx_n_in_use <= 0)
- lp->tx_first_in_use = I82586NULL;
- else
- {
- lp->tx_first_in_use += TXBLOCKZ;
- if (lp->tx_first_in_use >= OFFSET_CU + NTXBLOCKS * TXBLOCKZ)
- lp->tx_first_in_use -= NTXBLOCKS * TXBLOCKZ;
- }
-
- if (tx_status & AC_SFLD_OK)
- {
- int ncollisions;
-
- lp->stats.tx_packets++;
- ncollisions = tx_status & AC_SFLD_MAXCOL;
- lp->stats.collisions += ncollisions;
- /*
- if (ncollisions > 0)
- printk("%s: tx completed after %d collisions.\n", dev->name, ncollisions);
- */
- }
- else
- {
- lp->stats.tx_errors++;
- if (tx_status & AC_SFLD_S10)
- {
- lp->stats.tx_carrier_errors++;
- if (wavelan_debug > 0)
- printk("%s: tx error: no CS.\n", dev->name);
- }
- if (tx_status & AC_SFLD_S9)
- {
- lp->stats.tx_carrier_errors++;
- printk("%s: tx error: lost CTS.\n", dev->name);
- }
- if (tx_status & AC_SFLD_S8)
- {
- lp->stats.tx_fifo_errors++;
- printk("%s: tx error: slow DMA.\n", dev->name);
- }
- if (tx_status & AC_SFLD_S6)
- {
- lp->stats.tx_heartbeat_errors++;
- if (wavelan_debug > 0)
- printk("%s: tx error: heart beat.\n", dev->name);
- }
- if (tx_status & AC_SFLD_S5)
- {
- lp->stats.tx_aborted_errors++;
- if (wavelan_debug > 0)
- printk("%s: tx error: too many collisions.\n", dev->name);
- }
- }
-
- if (wavelan_debug > 5)
- printk("%s: tx completed, tx_status 0x%04x.\n", dev->name, tx_status);
- }
-
-/*
- if (nreaped > 1)
- printk("c%d", nreaped);
-*/
-
- /*
- * Inform upper layers.
- */
- if (lp->tx_n_in_use < NTXBLOCKS - 1)
- {
- dev->tbusy = 0;
- mark_bh(NET_BH);
- }
-
- return nreaped;
-}
-
-static
-void
-wavelan_watchdog(unsigned long a)
-{
- device *dev;
- net_local *lp;
- unsigned short ioaddr;
- unsigned long x;
- unsigned int nreaped;
-
- x = wavelan_splhi();
-
- dev = (device *)a;
- ioaddr = dev->base_addr;
- lp = (net_local *)dev->priv;
-
- if (lp->tx_n_in_use <= 0)
- {
- wavelan_splx(x);
- return;
- }
-
- lp->watchdog.expires = jiffies+WATCHDOG_JIFFIES;
- add_timer(&lp->watchdog);
-
- if (jiffies - dev->trans_start < WATCHDOG_JIFFIES)
- {
- wavelan_splx(x);
- return;
- }
-
- nreaped = wavelan_complete(dev, ioaddr, lp);
-
- printk("%s: warning: wavelan_watchdog(): %d reaped, %d remain.\n", dev->name, nreaped, lp->tx_n_in_use);
- /*
- wavelan_scb_show(ioaddr);
- wavelan_ru_show(dev);
- wavelan_cu_show(dev);
- wavelan_dev_show(dev);
- wavelan_local_show(dev);
- */
-
- wavelan_splx(x);
-}
-
-static
-void
-wavelan_interrupt(int irq, struct pt_regs *regs)
-{
- device *dev;
- unsigned short ioaddr;
- net_local *lp;
- unsigned short hasr;
- unsigned short status;
- unsigned short ack_cmd;
-
- if ((dev = (device *)(irq2dev_map[irq])) == (device *)0)
- {
- printk("wavelan_interrupt(): irq %d for unknown device.\n", irq);
- return;
- }
-
- ioaddr = dev->base_addr;
- lp = (net_local *)dev->priv;
-
- dev->interrupt = 1;
-
- if ((hasr = hasr_read(ioaddr)) & HASR_MMC_INTR)
- {
- unsigned char dce_status;
-
- /*
- * Interrupt from the modem management controller.
- * This will clear it -- ignored for now.
- */
- mmc_read(ioaddr, mmroff(0, mmr_dce_status), &dce_status, sizeof(dce_status));
- if (wavelan_debug > 0)
- printk("%s: warning: wavelan_interrupt(): unexpected mmc interrupt: status 0x%04x.\n", dev->name, dce_status);
- }
-
- if ((hasr & HASR_82586_INTR) == 0)
- {
- dev->interrupt = 0;
- if (wavelan_debug > 0)
- printk("%s: warning: wavelan_interrupt() but (hasr & HASR_82586_INTR) == 0.\n", dev->name);
- return;
- }
-
- obram_read(ioaddr, scboff(OFFSET_SCB, scb_status), (unsigned char *)&status, sizeof(status));
-
- /*
- * Acknowledge the interrupt(s).
- */
- ack_cmd = status & SCB_ST_INT;
-
- obram_write(ioaddr, scboff(OFFSET_SCB, scb_command), (unsigned char *)&ack_cmd, sizeof(ack_cmd));
-
- set_chan_attn(ioaddr, lp->hacr);
-
- if (wavelan_debug > 5)
- printk("%s: interrupt, status 0x%04x.\n", dev->name, status);
-
- if ((status & SCB_ST_CX) == SCB_ST_CX)
- {
- /*
- * Command completed.
- */
- if (wavelan_debug > 5)
- printk("%s: command completed.\n", dev->name);
- (void)wavelan_complete(dev, ioaddr, lp);
- }
-
- if ((status & SCB_ST_FR) == SCB_ST_FR)
- {
- /*
- * Frame received.
- */
- if (wavelan_debug > 5)
- printk("%s: received packet.\n", dev->name);
- wavelan_receive(dev);
- }
-
- if
- (
- (status & SCB_ST_CNA) == SCB_ST_CNA
- ||
- (((status & SCB_ST_CUS) != SCB_ST_CUS_ACTV) && dev->start)
- )
- {
- printk("%s: warning: CU inactive -- restarting.\n", dev->name);
-
- (void)wavelan_hardware_reset(dev);
- }
-
- if
- (
- (status & SCB_ST_RNR) == SCB_ST_RNR
- ||
- (((status & SCB_ST_RUS) != SCB_ST_RUS_RDY) && dev->start)
- )
- {
- printk("%s: warning: RU not ready -- restarting.\n", dev->name);
-
- (void)wavelan_hardware_reset(dev);
- }
-
- dev->interrupt = 0;
-}
-
-static
-int
-wavelan_close(device *dev)
-{
- unsigned short ioaddr;
- net_local *lp;
- unsigned short scb_cmd;
-
- if (wavelan_debug > 0)
- printk("%s: ->wavelan_close(dev=0x%x)\n", dev->name, (unsigned int)dev);
-
- ioaddr = dev->base_addr;
- lp = (net_local *)dev->priv;
-
- dev->tbusy = 1;
- dev->start = 0;
-
- /*
- * Flush the Tx and disable Rx.
- */
- scb_cmd = (SCB_CMD_CUC & SCB_CMD_CUC_SUS) | (SCB_CMD_RUC & SCB_CMD_RUC_SUS);
- obram_write(ioaddr, scboff(OFFSET_SCB, scb_command), (unsigned char *)&scb_cmd, sizeof(scb_cmd));
- set_chan_attn(ioaddr, lp->hacr);
-
- wavelan_ints_off(dev);
-
- free_irq(dev->irq);
- irq2dev_map[dev->irq] = (device *)0;
-
- /*
- * Release the ioport-region.
- */
- release_region(ioaddr, sizeof(ha_t));
-
- MOD_DEC_USE_COUNT;
-
- if (wavelan_debug > 0)
- printk("%s: <-wavelan_close(): 0\n", dev->name);
-
- return 0;
-}
-
-/*
- * Get the current statistics.
- * This may be called with the card open or closed.
- */
-static
-en_stats *
-wavelan_get_stats(device *dev)
-{
- net_local *lp;
-
- lp = (net_local *)dev->priv;
-
- return &lp->stats;
-}
-
-static
-void
-wavelan_set_multicast_list(device *dev)
-{
- net_local *lp;
- unsigned long x;
-
- if (wavelan_debug > 0)
- printk("%s: ->wavelan_set_multicast_list(dev=0x%x)", dev->name, dev);
-
- lp = (net_local *)dev->priv;
-
- if(dev->flags&IFF_PROMISC)
- {
- /*
- * Promiscuous mode: receive all packets.
- */
- lp->promiscuous = 1;
- x = wavelan_splhi();
- (void)wavelan_hardware_reset(dev);
- wavelan_splx(x);
- }
-#if MULTICAST_IS_ADDED
- else if((dev->flags&IFF_ALLMULTI)||dev->mc_list)
- {
-
-
- }
-#endif
- else
- {
- /*
- * Normal mode: disable promiscuous mode,
- * clear multicast list.
- */
- lp->promiscuous = 0;
- x = wavelan_splhi();
- (void)wavelan_hardware_reset(dev);
- wavelan_splx(x);
- }
-
- if (wavelan_debug > 0)
- printk("%s: <-wavelan_set_multicast_list()\n", dev->name);
-}
-
-/*
- * Extra WaveLAN-specific device data.
- * "cat /proc/net/wavelan" -- see fs/proc/net.c.
- */
-static
-int
-sprintf_stats(char *buffer, device *dev)
-{
- net_local *lp;
- unsigned char v;
- mmr_t m;
-
- lp = (net_local *)dev->priv;
-
- if (lp == (net_local *)0)
- return sprintf(buffer, "%6s: No statistics available.\n", dev->name);
-
- v = (unsigned char)1;
- mmc_write(dev->base_addr, mmwoff(0, mmw_freeze), &v, sizeof(v));
-
- mmc_read(dev->base_addr, mmroff(0, mmr_dce_status), &m.mmr_dce_status, sizeof(m.mmr_dce_status));
- mmc_read(dev->base_addr, mmroff(0, mmr_correct_nwid_h), &m.mmr_correct_nwid_h, sizeof(m.mmr_correct_nwid_h));
- mmc_read(dev->base_addr, mmroff(0, mmr_correct_nwid_l), &m.mmr_correct_nwid_l, sizeof(m.mmr_correct_nwid_l));
- mmc_read(dev->base_addr, mmroff(0, mmr_wrong_nwid_h), &m.mmr_wrong_nwid_h, sizeof(m.mmr_wrong_nwid_h));
- mmc_read(dev->base_addr, mmroff(0, mmr_wrong_nwid_l), &m.mmr_wrong_nwid_l, sizeof(m.mmr_wrong_nwid_l));
- mmc_read(dev->base_addr, mmroff(0, mmr_signal_lvl), &m.mmr_signal_lvl, sizeof(m.mmr_signal_lvl));
- mmc_read(dev->base_addr, mmroff(0, mmr_silence_lvl), &m.mmr_silence_lvl, sizeof(m.mmr_silence_lvl));
- mmc_read(dev->base_addr, mmroff(0, mmr_sgnl_qual), &m.mmr_sgnl_qual, sizeof(m.mmr_sgnl_qual));
-
- v = (unsigned char)0;
- mmc_write(dev->base_addr, mmwoff(0, mmw_freeze), &v, sizeof(v));
-
- lp->correct_nwid += (m.mmr_correct_nwid_h << 8) | m.mmr_correct_nwid_l;
- lp->wrong_nwid += (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l;
-
- return sprintf
- (
- buffer,
- "%6s: %02x %08x %08x %02x %02x %02x %02x %u\n",
- dev->name,
- m.mmr_dce_status,
- lp->correct_nwid,
- lp->wrong_nwid,
- m.mmr_signal_lvl,
- m.mmr_silence_lvl,
- m.mmr_sgnl_qual,
- lp->tx_n_in_use,
- lp->nresets
- );
-}
-
-static int
-wavelan_get_info(char *buffer, char **start, off_t offset, int length, int dummy)
-{
- int len;
- off_t begin;
- off_t pos;
- int size;
- unsigned long x;
-
- len = 0;
- begin = 0;
- pos = 0;
-
- size = sprintf(buffer, "%s", "Iface | dce +nwid -nwid lvl slnc qual ntxq nrst\n");
-
- pos += size;
- len += size;
-
- x = wavelan_splhi();
-
- if (first_wavelan != (net_local *)0)
- {
- net_local *lp;
-
- lp = first_wavelan;
- do
- {
- size = sprintf_stats(buffer + len, lp->dev);
-
- len += size;
- pos = begin + len;
-
- if (pos < offset)
- {
- len = 0;
- begin = pos;
- }
-
- if (pos > offset + length)
- break;
- }
- while ((lp = lp->next) != first_wavelan);
- }
-
- wavelan_splx(x);
-
- *start = buffer + (offset - begin); /* Start of wanted data */
- len -= (offset - begin); /* Start slop */
- if (len > length)
- len = length; /* Ending slop */
-
- return len;
-}
-
-#if defined(MODULE)
-static char devicename[9] = { 0, };
-static struct device dev_wavelan =
-{
- devicename, /* device name is inserted by linux/drivers/net/net_init.c */
- 0, 0, 0, 0,
- 0, 0,
- 0, 0, 0, NULL, wavelan_probe
-};
-
-static int io = 0x390; /* Default from above.. */
-static int irq = 0;
-
-int
-init_module(void)
-{
- dev_wavelan.base_addr = io;
- dev_wavelan.irq = irq;
- if (register_netdev(&dev_wavelan) != 0)
- return -EIO;
-
- return 0;
-}
-
-void
-cleanup_module(void)
-{
- proc_net_unregister(PROC_NET_WAVELAN);
- unregister_netdev(&dev_wavelan);
- kfree_s(dev_wavelan.priv, sizeof(struct net_local));
- dev_wavelan.priv = NULL;
-}
-#endif /* defined(MODULE) */
-
-static
-void
-wavelan_cu_show_one(device *dev, net_local *lp, int i, unsigned short p)
-{
- unsigned short ioaddr;
- ac_tx_t actx;
-
- ioaddr = dev->base_addr;
-
- printk("%d: 0x%x:", i, p);
-
- obram_read(ioaddr, p, (unsigned char *)&actx, sizeof(actx));
- printk(" status=0x%x,", actx.tx_h.ac_status);
- printk(" command=0x%x,", actx.tx_h.ac_command);
-
-/*
- {
- tbd_t tbd;
-
- obram_read(ioaddr, actx.tx_tbd_offset, (unsigned char *)&tbd, sizeof(tbd));
- printk(" tbd_status=0x%x,", tbd.tbd_status);
- }
-*/
-
- printk("|");
-}
-
-#if 0
-static
-void
-wavelan_psa_show(psa_t *p)
-{
- printk("psa:");
-
- printk("psa_io_base_addr_1: 0x%02x,", p->psa_io_base_addr_1);
- printk("psa_io_base_addr_2: 0x%02x,", p->psa_io_base_addr_2);
- printk("psa_io_base_addr_3: 0x%02x,", p->psa_io_base_addr_3);
- printk("psa_io_base_addr_4: 0x%02x,", p->psa_io_base_addr_4);
- printk("psa_rem_boot_addr_1: 0x%02x,", p->psa_rem_boot_addr_1);
- printk("psa_rem_boot_addr_2: 0x%02x,", p->psa_rem_boot_addr_2);
- printk("psa_rem_boot_addr_3: 0x%02x,", p->psa_rem_boot_addr_3);
- printk("psa_holi_params: 0x%02x,", p->psa_holi_params);
- printk("psa_int_req_no: %d,", p->psa_int_req_no);
- printk
- (
- "psa_univ_mac_addr[]: %02x:%02x:%02x:%02x:%02x:%02x,",
- p->psa_univ_mac_addr[0],
- p->psa_univ_mac_addr[1],
- p->psa_univ_mac_addr[2],
- p->psa_univ_mac_addr[3],
- p->psa_univ_mac_addr[4],
- p->psa_univ_mac_addr[5]
- );
- printk
- (
- "psa_local_mac_addr[]: %02x:%02x:%02x:%02x:%02x:%02x,",
- p->psa_local_mac_addr[0],
- p->psa_local_mac_addr[1],
- p->psa_local_mac_addr[2],
- p->psa_local_mac_addr[3],
- p->psa_local_mac_addr[4],
- p->psa_local_mac_addr[5]
- );
- printk("psa_univ_local_sel: %d,", p->psa_univ_local_sel);
- printk("psa_comp_number: %d,", p->psa_comp_number);
- printk("psa_thr_pre_set: 0x%02x,", p->psa_thr_pre_set);
- printk("psa_feature_select/decay_prm: 0x%02x,", p->psa_feature_select);
- printk("psa_subband/decay_update_prm: %d,", p->psa_subband);
- printk("psa_quality_thr: 0x%02x,", p->psa_quality_thr);
- printk("psa_mod_delay: 0x%02x,", p->psa_mod_delay);
- printk("psa_nwid: 0x%02x%02x,", p->psa_nwid[0], p->psa_nwid[1]);
- printk("psa_undefined: %d,", p->psa_undefined);
- printk("psa_encryption_select: %d,", p->psa_encryption_select);
- printk
- (
- "psa_encryption_key[]: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x,",
- p->psa_encryption_key[0],
- p->psa_encryption_key[1],
- p->psa_encryption_key[2],
- p->psa_encryption_key[3],
- p->psa_encryption_key[4],
- p->psa_encryption_key[5],
- p->psa_encryption_key[6],
- p->psa_encryption_key[7]
- );
- printk("psa_databus_width: %d,", p->psa_databus_width);
- printk("psa_call_code/auto_squelch: 0x%02x,", p->psa_call_code);
- printk("psa_no_of_retries: %d,", p->psa_no_of_retries);
- printk("psa_acr: %d,", p->psa_acr);
- printk("psa_dump_count: %d,", p->psa_dump_count);
- printk("psa_nwid_prefix: 0x%02x,", p->psa_nwid_prefix);
- printk("psa_conf_status: %d,", p->psa_conf_status);
- printk("psa_crc: 0x%02x%02x,", p->psa_crc[0], p->psa_crc[1]);
- printk("psa_crc_status: 0x%02x,", p->psa_crc_status);
-
- printk("\n");
-}
-
-static
-void
-wavelan_mmc_show(unsigned short ioaddr)
-{
- mmr_t m;
-
- mmc_read(ioaddr, 0, (unsigned char *)&m, sizeof(m));
-
- printk("mmr:");
- printk(" des_status: 0x%x", m.mmr_des_status);
- printk(" des_avail: 0x%x", m.mmr_des_avail);
- printk(" des_io_invert: 0x%x", m.mmr_des_io_invert);
- printk
- (
- " dce_status: 0x%x[%s%s%s%s]",
- m.mmr_dce_status & 0x0F,
- (m.mmr_dce_status & MMR_DCE_STATUS_ENERG_DET) ? "energy detected," : "",
- (m.mmr_dce_status & MMR_DCE_STATUS_LOOPT_IND) ? "loop test indicated," : "",
- (m.mmr_dce_status & MMR_DCE_STATUS_XMTITR_IND) ? "transmitter on," : "",
- (m.mmr_dce_status & MMR_DCE_STATUS_JBR_EXPIRED) ? "jabber timer expired," : ""
- );
- printk(" correct_nwid: %d", m.mmr_correct_nwid_h << 8 | m.mmr_correct_nwid_l);
- printk(" wrong_nwid: %d", (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l);
- printk(" thr_pre_set: 0x%x", m.mmr_thr_pre_set);
- printk(" signal_lvl: %d", m.mmr_signal_lvl);
- printk(" silence_lvl: %d", m.mmr_silence_lvl);
- printk(" sgnl_qual: 0x%x", m.mmr_sgnl_qual);
- printk(" netw_id_l: %x", m.mmr_netw_id_l);
-
- printk("\n");
-}
-#endif /* 0 */
-
-static
-void
-wavelan_scb_show(unsigned short ioaddr)
-{
- scb_t scb;
-
- obram_read(ioaddr, OFFSET_SCB, (unsigned char *)&scb, sizeof(scb));
-
- printk("scb:");
-
- printk(" status:");
- printk
- (
- " stat 0x%x[%s%s%s%s]",
- (scb.scb_status & (SCB_ST_CX | SCB_ST_FR | SCB_ST_CNA | SCB_ST_RNR)) >> 12,
- (scb.scb_status & SCB_ST_CX) ? "cmd completion interrupt," : "",
- (scb.scb_status & SCB_ST_FR) ? "frame received," : "",
- (scb.scb_status & SCB_ST_CNA) ? "cmd unit not active," : "",
- (scb.scb_status & SCB_ST_RNR) ? "rcv unit not ready," : ""
- );
- printk
- (
- " cus 0x%x[%s%s%s]",
- (scb.scb_status & SCB_ST_CUS) >> 8,
- ((scb.scb_status & SCB_ST_CUS) == SCB_ST_CUS_IDLE) ? "idle" : "",
- ((scb.scb_status & SCB_ST_CUS) == SCB_ST_CUS_SUSP) ? "suspended" : "",
- ((scb.scb_status & SCB_ST_CUS) == SCB_ST_CUS_ACTV) ? "active" : ""
- );
- printk
- (
- " rus 0x%x[%s%s%s%s]",
- (scb.scb_status & SCB_ST_RUS) >> 4,
- ((scb.scb_status & SCB_ST_RUS) == SCB_ST_RUS_IDLE) ? "idle" : "",
- ((scb.scb_status & SCB_ST_RUS) == SCB_ST_RUS_SUSP) ? "suspended" : "",
- ((scb.scb_status & SCB_ST_RUS) == SCB_ST_RUS_NRES) ? "no resources" : "",
- ((scb.scb_status & SCB_ST_RUS) == SCB_ST_RUS_RDY) ? "ready" : ""
- );
-
- printk(" command:");
- printk
- (
- " ack 0x%x[%s%s%s%s]",
- (scb.scb_command & (SCB_CMD_ACK_CX | SCB_CMD_ACK_FR | SCB_CMD_ACK_CNA | SCB_CMD_ACK_RNR)) >> 12,
- (scb.scb_command & SCB_CMD_ACK_CX) ? "ack cmd completion," : "",
- (scb.scb_command & SCB_CMD_ACK_FR) ? "ack frame received," : "",
- (scb.scb_command & SCB_CMD_ACK_CNA) ? "ack CU not active," : "",
- (scb.scb_command & SCB_CMD_ACK_RNR) ? "ack RU not ready," : ""
- );
- printk
- (
- " cuc 0x%x[%s%s%s%s%s]",
- (scb.scb_command & SCB_CMD_CUC) >> 8,
- ((scb.scb_command & SCB_CMD_CUC) == SCB_CMD_CUC_NOP) ? "nop" : "",
- ((scb.scb_command & SCB_CMD_CUC) == SCB_CMD_CUC_GO) ? "start cbl_offset" : "",
- ((scb.scb_command & SCB_CMD_CUC) == SCB_CMD_CUC_RES) ? "resume execution" : "",
- ((scb.scb_command & SCB_CMD_CUC) == SCB_CMD_CUC_SUS) ? "suspend execution" : "",
- ((scb.scb_command & SCB_CMD_CUC) == SCB_CMD_CUC_ABT) ? "abort execution" : ""
- );
- printk
- (
- " ruc 0x%x[%s%s%s%s%s]",
- (scb.scb_command & SCB_CMD_RUC) >> 4,
- ((scb.scb_command & SCB_CMD_RUC) == SCB_CMD_RUC_NOP) ? "nop" : "",
- ((scb.scb_command & SCB_CMD_RUC) == SCB_CMD_RUC_GO) ? "start rfa_offset" : "",
- ((scb.scb_command & SCB_CMD_RUC) == SCB_CMD_RUC_RES) ? "resume reception" : "",
- ((scb.scb_command & SCB_CMD_RUC) == SCB_CMD_RUC_SUS) ? "suspend reception" : "",
- ((scb.scb_command & SCB_CMD_RUC) == SCB_CMD_RUC_ABT) ? "abort reception" : ""
- );
-
- printk(" cbl_offset 0x%x", scb.scb_cbl_offset);
- printk(" rfa_offset 0x%x", scb.scb_rfa_offset);
-
- printk(" crcerrs %d", scb.scb_crcerrs);
- printk(" alnerrs %d", scb.scb_alnerrs);
- printk(" rscerrs %d", scb.scb_rscerrs);
- printk(" ovrnerrs %d", scb.scb_ovrnerrs);
-
- printk("\n");
-}
-
-static
-void
-wavelan_ru_show(device *dev)
-{
- net_local *lp;
-
- lp = (net_local *)dev->priv;
-
- printk("ru:");
- /*
- * Not implemented yet...
- */
- printk("\n");
-}
-
-static
-void
-wavelan_cu_show(device *dev)
-{
- net_local *lp;
- unsigned int i;
- unsigned short p;
-
- lp = (net_local *)dev->priv;
-
- printk("cu:");
- printk("\n");
-
- for (i = 0, p = lp->tx_first_in_use; i < NTXBLOCKS; i++)
- {
- wavelan_cu_show_one(dev, lp, i, p);
-
- p += TXBLOCKZ;
- if (p >= OFFSET_CU + NTXBLOCKS * TXBLOCKZ)
- p -= NTXBLOCKS * TXBLOCKZ;
- }
-}
-
-static
-void
-wavelan_dev_show(device *dev)
-{
- printk("dev:");
- printk(" start=%d,", dev->start);
- printk(" tbusy=%ld,", dev->tbusy);
- printk(" interrupt=%d,", dev->interrupt);
- printk(" trans_start=%ld,", dev->trans_start);
- printk(" flags=0x%x,", dev->flags);
- printk("\n");
-}
-
-static
-void
-wavelan_local_show(device *dev)
-{
- net_local *lp;
-
- lp = (net_local *)dev->priv;
-
- printk("local:");
- printk(" tx_n_in_use=%d,", lp->tx_n_in_use);
- printk(" hacr=0x%x,", lp->hacr);
- printk(" rx_head=0x%x,", lp->rx_head);
- printk(" rx_last=0x%x,", lp->rx_last);
- printk(" tx_first_free=0x%x,", lp->tx_first_free);
- printk(" tx_first_in_use=0x%x,", lp->tx_first_in_use);
- printk("\n");
-}
-
-/*
- * This software may only be used and distributed
- * according to the terms of the GNU Public License.
- *
- * This software was developed as a component of the
- * Linux operating system.
- * It is based on other device drivers and information
- * either written or supplied by:
- * Ajay Bakre (bakre@paul.rutgers.edu),
- * Donald Becker (becker@cesdis.gsfc.nasa.gov),
- * Loeke Brederveld (Loeke.Brederveld@Utrecht.NCR.com),
- * Anders Klemets (klemets@it.kth.se),
- * Vladimir V. Kolpakov (w@stier.koenig.ru),
- * Marc Meertens (Marc.Meertens@Utrecht.NCR.com),
- * Pauline Middelink (middelin@polyware.iaf.nl),
- * Robert Morris (rtm@das.harvard.edu),
- * Girish Welling (welling@paul.rutgers.edu),
- *
- * Thanks go also to:
- * James Ashton (jaa101@syseng.anu.edu.au),
- * Alan Cox (iialan@iiit.swan.ac.uk),
- * Allan Creighton (allanc@cs.usyd.edu.au),
- * Matthew Geier (matthew@cs.usyd.edu.au),
- * Remo di Giovanni (remo@cs.usyd.edu.au),
- * Eckhard Grah (grah@wrcs1.urz.uni-wuppertal.de),
- * Vipul Gupta (vgupta@cs.binghamton.edu),
- * Mark Hagan (mhagan@wtcpost.daytonoh.NCR.COM),
- * Tim Nicholson (tim@cs.usyd.edu.au),
- * Ian Parkin (ian@cs.usyd.edu.au),
- * John Rosenberg (johnr@cs.usyd.edu.au),
- * George Rossi (george@phm.gov.au),
- * Arthur Scott (arthur@cs.usyd.edu.au),
- * Peter Storey,
- * for their assistance and advice.
- *
- * Please send bug reports, updates, comments to:
- *
- * Bruce Janson Email: bruce@cs.usyd.edu.au
- * Basser Department of Computer Science Phone: +61-2-351-3423
- * University of Sydney, N.S.W., 2006, AUSTRALIA Fax: +61-2-351-3838
- */
diff --git a/i386/i386at/gpl/linux/net/wavelan.h b/i386/i386at/gpl/linux/net/wavelan.h
deleted file mode 100644
index 3eb221c0..00000000
--- a/i386/i386at/gpl/linux/net/wavelan.h
+++ /dev/null
@@ -1,252 +0,0 @@
-#define WAVELAN_ADDR_SIZE 6 /* Size of a MAC address */
-#define SA_ADDR0 0x08 /* First octet of WaveLAN MAC addresses */
-#define SA_ADDR1 0x00 /* Second octet of WaveLAN MAC addresses */
-#define SA_ADDR2 0x0E /* Third octet of WaveLAN MAC addresses */
-#define WAVELAN_MTU 1500 /* Maximum size of WaveLAN packet */
-
-/*
- * Parameter Storage Area (PSA).
- */
-typedef struct psa_t psa_t;
-struct psa_t
-{
- unsigned char psa_io_base_addr_1; /* Base address 1 ??? */
- unsigned char psa_io_base_addr_2; /* Base address 2 */
- unsigned char psa_io_base_addr_3; /* Base address 3 */
- unsigned char psa_io_base_addr_4; /* Base address 4 */
- unsigned char psa_rem_boot_addr_1; /* Remote Boot Address 1 */
- unsigned char psa_rem_boot_addr_2; /* Remote Boot Address 2 */
- unsigned char psa_rem_boot_addr_3; /* Remote Boot Address 3 */
- unsigned char psa_holi_params; /* HOst Lan Interface (HOLI) Parameters */
- unsigned char psa_int_req_no; /* Interrupt Request Line */
- unsigned char psa_unused0[7]; /* unused */
- unsigned char psa_univ_mac_addr[WAVELAN_ADDR_SIZE]; /* Universal (factory) MAC Address */
- unsigned char psa_local_mac_addr[WAVELAN_ADDR_SIZE]; /* Local MAC Address */
- unsigned char psa_univ_local_sel; /* Universal Local Selection */
-#define PSA_UNIVERSAL 0 /* Universal (factory) */
-#define PSA_LOCAL 1 /* Local */
- unsigned char psa_comp_number; /* Compatibility Number: */
-#define PSA_COMP_PC_AT_915 0 /* PC-AT 915 MHz */
-#define PSA_COMP_PC_MC_915 1 /* PC-MC 915 MHz */
-#define PSA_COMP_PC_AT_2400 2 /* PC-AT 2.4 GHz */
-#define PSA_COMP_PC_MC_2400 3 /* PC-MC 2.4 GHz */
-#define PSA_COMP_PCMCIA_915 4 /* PCMCIA 915 MHz */
- unsigned char psa_thr_pre_set; /* Modem Threshold Preset */
- unsigned char psa_feature_select; /* ??? */
-#if 0
- <alias for above>
- unsigned char psa_decay_prm; /* Modem Decay */
-#endif /* 0 */
- unsigned char psa_subband; /* Subband */
-#define PSA_SUBBAND_915 0 /* 915 MHz */
-#define PSA_SUBBAND_2425 1 /* 2425 MHz */
-#define PSA_SUBBAND_2460 2 /* 2460 MHz */
-#define PSA_SUBBAND_2484 3 /* 2484 MHz */
-#define PSA_SUBBAND_2430_5 4 /* 2430.5 MHz */
-#if 0
- <alias for above>
- unsigned char psa_decay_updat_prm; /* Modem Decay Update ??? */
-#endif /* 0 */
- unsigned char psa_quality_thr; /* Modem Quality Threshold */
- unsigned char psa_mod_delay; /* Modem Delay ??? */
- unsigned char psa_nwid[2]; /* Network ID */
- unsigned char psa_undefined; /* undefined */
- unsigned char psa_encryption_select; /* Encryption On Off */
- unsigned char psa_encryption_key[8]; /* Encryption Key */
- unsigned char psa_databus_width; /* 8/16 bit bus width */
- unsigned char psa_call_code; /* ??? */
-#if 0
- <alias for above>
- unsigned char psa_auto_squelch; /* Automatic Squelch level On off ??? */
-#endif /* 0 */
- unsigned char psa_no_of_retries; /* LAN Cont. No of retries */
- unsigned char psa_acr; /* LAN Cont. ACR */
- unsigned char psa_dump_count; /* number of Dump Commands in TFB */
- unsigned char psa_unused1[4]; /* unused */
- unsigned char psa_nwid_prefix; /* ??? */
- unsigned char psa_unused2[3]; /* unused */
- unsigned char psa_conf_status; /* Card Configuration Status */
- unsigned char psa_crc[2]; /* CRC over PSA */
- unsigned char psa_crc_status; /* CRC Valid Flag */
-};
-#if STRUCT_CHECK == 1
-#define PSA_SIZE 64
-#endif /* STRUCT_CHECK == 1 */
-
-/*
- * Modem Management Controller (MMC) write structure.
- */
-typedef struct mmw_t mmw_t;
-struct mmw_t
-{
- unsigned char mmw_encr_key[8]; /* encryption key */
- unsigned char mmw_encr_enable; /* enable/disable encryption */
- unsigned char mmw_unused0[1]; /* unused */
- unsigned char mmw_des_io_invert; /* ??? */
- unsigned char mmw_unused1[5]; /* unused */
- unsigned char mmw_loopt_sel; /* looptest selection */
-#define MMW_LOOPT_SEL_UNDEFINED 0x40 /* undefined */
-#define MMW_LOOPT_SEL_INT 0x20 /* activate Attention Request */
-#define MMW_LOOPT_SEL_LS 0x10 /* looptest without collision avoidance */
-#define MMW_LOOPT_SEL_LT3A 0x08 /* looptest 3a */
-#define MMW_LOOPT_SEL_LT3B 0x04 /* looptest 3b */
-#define MMW_LOOPT_SEL_LT3C 0x02 /* looptest 3c */
-#define MMW_LOOPT_SEL_LT3D 0x01 /* looptest 3d */
- unsigned char mmw_jabber_enable; /* jabber timer enable */
- unsigned char mmw_freeze; /* freeze / unfreeze signal level */
- unsigned char mmw_anten_sel; /* antenna selection */
-#define MMW_ANTEN_SEL_SEL 0x01 /* direct antenna selection */
-#define MMW_ANTEN_SEL_ALG_EN 0x02 /* antenna selection algorithm enable */
- unsigned char mmw_ifs; /* inter frame spacing */
- unsigned char mmw_mod_delay; /* modem delay */
- unsigned char mmw_jam_time; /* jamming time */
- unsigned char mmw_unused2[1]; /* unused */
- unsigned char mmw_thr_pre_set; /* level threshold preset */
- unsigned char mmw_decay_prm; /* decay parameters */
- unsigned char mmw_decay_updat_prm; /* decay update parameters */
- unsigned char mmw_quality_thr; /* quality (z-quotient) threshold */
- unsigned char mmw_netw_id_l; /* NWID low order byte */
- unsigned char mmw_netw_id_h; /* NWID high order byte */
-};
-#if STRUCT_CHECK == 1
-#define MMW_SIZE 30
-#endif /* STRUCT_CHECK == 1 */
-
-#define mmwoff(p,f) (unsigned short)((void *)(&((mmw_t *)((void *)0 + (p)))->f) - (void *)0)
-
-/*
- * Modem Management Controller (MMC) read structure.
- */
-typedef struct mmr_t mmr_t;
-struct mmr_t
-{
- unsigned char mmr_unused0[8]; /* unused */
- unsigned char mmr_des_status; /* encryption status */
- unsigned char mmr_des_avail; /* encryption available (0x55 read) */
- unsigned char mmr_des_io_invert; /* des I/O invert register */
- unsigned char mmr_unused1[5]; /* unused */
- unsigned char mmr_dce_status; /* DCE status */
-#define MMR_DCE_STATUS_ENERG_DET 0x01 /* energy detected */
-#define MMR_DCE_STATUS_LOOPT_IND 0x02 /* loop test indicated */
-#define MMR_DCE_STATUS_XMTITR_IND 0x04 /* transmitter on */
-#define MMR_DCE_STATUS_JBR_EXPIRED 0x08 /* jabber timer expired */
- unsigned char mmr_unused2[3]; /* unused */
- unsigned char mmr_correct_nwid_l; /* no. of correct NWID's rxd (low) */
- unsigned char mmr_correct_nwid_h; /* no. of correct NWID's rxd (high) */
- unsigned char mmr_wrong_nwid_l; /* count of wrong NWID's received (low) */
- unsigned char mmr_wrong_nwid_h; /* count of wrong NWID's received (high) */
- unsigned char mmr_thr_pre_set; /* level threshold preset */
- unsigned char mmr_signal_lvl; /* signal level */
- unsigned char mmr_silence_lvl; /* silence level */
- unsigned char mmr_sgnl_qual; /* signal quality */
-#define MMR_SGNL_QUAL_0 0x01 /* signal quality 0 */
-#define MMR_SGNL_QUAL_1 0x02 /* signal quality 1 */
-#define MMR_SGNL_QUAL_2 0x04 /* signal quality 2 */
-#define MMR_SGNL_QUAL_3 0x08 /* signal quality 3 */
-#define MMR_SGNL_QUAL_S_A 0x80 /* currently selected antenna */
- unsigned char mmr_netw_id_l; /* NWID low order byte ??? */
- unsigned char mmr_unused3[1]; /* unused */
-};
-#if STRUCT_CHECK == 1
-#define MMR_SIZE 30
-#endif /* STRUCT_CHECK == 1 */
-
-#define MMR_LEVEL_MASK 0x3F
-
-#define mmroff(p,f) (unsigned short)((void *)(&((mmr_t *)((void *)0 + (p)))->f) - (void *)0)
-
-/*
- * Host Adaptor structure.
- * (base is board port address).
- */
-typedef union hacs_u hacs_u;
-union hacs_u
-{
- unsigned short hu_command; /* Command register */
-#define HACR_RESET 0x0001 /* Reset board */
-#define HACR_CA 0x0002 /* Set Channel Attention for 82586 */
-#define HACR_16BITS 0x0004 /* 16 bits operation (0 => 8bits) */
-#define HACR_OUT0 0x0008 /* General purpose output pin 0 */
- /* not used - must be 1 */
-#define HACR_OUT1 0x0010 /* General purpose output pin 1 */
- /* not used - must be 1 */
-#define HACR_82586_INT_ENABLE 0x0020 /* Enable 82586 interrupts */
-#define HACR_MMC_INT_ENABLE 0x0040 /* Enable MMC interrupts */
-#define HACR_INTR_CLR_ENABLE 0x0080 /* Enable interrupt status read/clear */
- unsigned short hu_status; /* Status Register */
-#define HASR_82586_INTR 0x0001 /* Interrupt request from 82586 */
-#define HASR_MMC_INTR 0x0002 /* Interrupt request from MMC */
-#define HASR_MMC_BUSY 0x0004 /* MMC busy indication */
-#define HASR_PSA_BUSY 0x0008 /* LAN parameter storage area busy */
-};
-
-typedef struct ha_t ha_t;
-struct ha_t
-{
- hacs_u ha_cs; /* Command and status registers */
-#define ha_command ha_cs.hu_command
-#define ha_status ha_cs.hu_status
- unsigned short ha_mmcr; /* Modem Management Ctrl Register */
- unsigned short ha_pior0; /* Program I/O Address Register Port 0 */
- unsigned short ha_piop0; /* Program I/O Port 0 */
- unsigned short ha_pior1; /* Program I/O Address Register Port 1 */
- unsigned short ha_piop1; /* Program I/O Port 1 */
- unsigned short ha_pior2; /* Program I/O Address Register Port 2 */
- unsigned short ha_piop2; /* Program I/O Port 2 */
-};
-#if STRUCT_CHECK == 1
-#define HA_SIZE 16
-#endif /* STRUCT_CHECK == 1 */
-
-#define hoff(p,f) (unsigned short)((void *)(&((ha_t *)((void *)0 + (p)))->f) - (void *)0)
-#define HACR(p) hoff(p, ha_command)
-#define HASR(p) hoff(p, ha_status)
-#define MMCR(p) hoff(p, ha_mmcr)
-#define PIOR0(p) hoff(p, ha_pior0)
-#define PIOP0(p) hoff(p, ha_piop0)
-#define PIOR1(p) hoff(p, ha_pior1)
-#define PIOP1(p) hoff(p, ha_piop1)
-#define PIOR2(p) hoff(p, ha_pior2)
-#define PIOP2(p) hoff(p, ha_piop2)
-
-/*
- * Program I/O Mode Register values.
- */
-#define STATIC_PIO 0 /* Mode 1: static mode */
- /* RAM access ??? */
-#define AUTOINCR_PIO 1 /* Mode 2: auto increment mode */
- /* RAM access ??? */
-#define AUTODECR_PIO 2 /* Mode 3: auto decrement mode */
- /* RAM access ??? */
-#define PARAM_ACCESS_PIO 3 /* Mode 4: LAN parameter access mode */
- /* Parameter access. */
-#define PIO_MASK 3 /* register mask */
-#define PIOM(cmd,piono) ((u_short)cmd << 10 << (piono * 2))
-
-#define HACR_DEFAULT (HACR_OUT0 | HACR_OUT1 | HACR_16BITS | PIOM(STATIC_PIO, 0) | PIOM(AUTOINCR_PIO, 1) | PIOM(PARAM_ACCESS_PIO, 2))
-#define HACR_INTRON (HACR_82586_INT_ENABLE | HACR_MMC_INT_ENABLE | HACR_INTR_CLR_ENABLE)
-
-#define MAXDATAZ (WAVELAN_ADDR_SIZE + WAVELAN_ADDR_SIZE + 2 + WAVELAN_MTU)
-
-/*
- * Onboard 64k RAM layout.
- * (Offsets from 0x0000.)
- */
-#define OFFSET_RU 0x0000
-#define OFFSET_CU 0x8000
-#define OFFSET_SCB (OFFSET_ISCP - sizeof(scb_t))
-#define OFFSET_ISCP (OFFSET_SCP - sizeof(iscp_t))
-#define OFFSET_SCP I82586_SCP_ADDR
-
-#define RXBLOCKZ (sizeof(fd_t) + sizeof(rbd_t) + MAXDATAZ)
-#define TXBLOCKZ (sizeof(ac_tx_t) + sizeof(ac_nop_t) + sizeof(tbd_t) + MAXDATAZ)
-
-#define NRXBLOCKS ((OFFSET_CU - OFFSET_RU) / RXBLOCKZ)
-#define NTXBLOCKS ((OFFSET_SCB - OFFSET_CU) / TXBLOCKZ)
-
-/*
- * This software may only be used and distributed
- * according to the terms of the GNU Public License.
- *
- * For more details, see wavelan.c.
- */
diff --git a/i386/i386at/gpl/linux/net/wd.c b/i386/i386at/gpl/linux/net/wd.c
deleted file mode 100644
index 5eaa6585..00000000
--- a/i386/i386at/gpl/linux/net/wd.c
+++ /dev/null
@@ -1,513 +0,0 @@
-/* wd.c: A WD80x3 ethernet driver for linux. */
-/*
- Written 1993-94 by Donald Becker.
-
- Copyright 1993 United States Government as represented by the
- Director, National Security Agency.
-
- This software may be used and distributed according to the terms
- of the GNU Public License, incorporated herein by reference.
-
- The author may be reached as becker@CESDIS.gsfc.nasa.gov, or C/O
- Center of Excellence in Space Data and Information Sciences
- Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
-
- This is a driver for WD8003 and WD8013 "compatible" ethercards.
-
- Thanks to Russ Nelson (nelson@crnwyr.com) for loaning me a WD8013.
-
- Changelog:
-
- Paul Gortmaker : multiple card support for module users, support
- for non-standard memory sizes.
-
-
-*/
-
-static const char *version =
- "wd.c:v1.10 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <asm/io.h>
-#include <asm/system.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include "8390.h"
-
-/* A zero-terminated list of I/O addresses to be probed. */
-static unsigned int wd_portlist[] =
-{0x300, 0x280, 0x380, 0x240, 0};
-
-int wd_probe(struct device *dev);
-int wd_probe1(struct device *dev, int ioaddr);
-
-static int wd_open(struct device *dev);
-static void wd_reset_8390(struct device *dev);
-static void wd_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr,
- int ring_page);
-static void wd_block_input(struct device *dev, int count,
- struct sk_buff *skb, int ring_offset);
-static void wd_block_output(struct device *dev, int count,
- const unsigned char *buf, const start_page);
-static int wd_close_card(struct device *dev);
-
-
-#define WD_START_PG 0x00 /* First page of TX buffer */
-#define WD03_STOP_PG 0x20 /* Last page +1 of RX ring */
-#define WD13_STOP_PG 0x40 /* Last page +1 of RX ring */
-
-#define WD_CMDREG 0 /* Offset to ASIC command register. */
-#define WD_RESET 0x80 /* Board reset, in WD_CMDREG. */
-#define WD_MEMENB 0x40 /* Enable the shared memory. */
-#define WD_CMDREG5 5 /* Offset to 16-bit-only ASIC register 5. */
-#define ISA16 0x80 /* Enable 16 bit access from the ISA bus. */
-#define NIC16 0x40 /* Enable 16 bit access from the 8390. */
-#define WD_NIC_OFFSET 16 /* Offset to the 8390 from the base_addr. */
-#define WD_IO_EXTENT 32
-
-
-/* Probe for the WD8003 and WD8013. These cards have the station
- address PROM at I/O ports <base>+8 to <base>+13, with a checksum
- following. A Soundblaster can have the same checksum as an WDethercard,
- so we have an extra exclusionary check for it.
-
- The wd_probe1() routine initializes the card and fills the
- station address field. */
-
-#ifdef HAVE_DEVLIST
-struct netdev_entry wd_drv =
-{"wd", wd_probe1, WD_IO_EXTENT, wd_portlist};
-#else
-
-int wd_probe(struct device *dev)
-{
- int i;
- int base_addr = dev ? dev->base_addr : 0;
-
- if (base_addr > 0x1ff) /* Check a single specified location. */
- return wd_probe1(dev, base_addr);
- else if (base_addr != 0) /* Don't probe at all. */
- return ENXIO;
-
- for (i = 0; wd_portlist[i]; i++) {
- int ioaddr = wd_portlist[i];
- if (check_region(ioaddr, WD_IO_EXTENT))
- continue;
- if (wd_probe1(dev, ioaddr) == 0)
- return 0;
- }
-
- return ENODEV;
-}
-#endif
-
-int wd_probe1(struct device *dev, int ioaddr)
-{
- int i;
- int checksum = 0;
- int ancient = 0; /* An old card without config registers. */
- int word16 = 0; /* 0 = 8 bit, 1 = 16 bit */
- const char *model_name;
- static unsigned version_printed = 0;
-
- for (i = 0; i < 8; i++)
- checksum += inb(ioaddr + 8 + i);
- if (inb(ioaddr + 8) == 0xff /* Extra check to avoid soundcard. */
- || inb(ioaddr + 9) == 0xff
- || (checksum & 0xff) != 0xFF)
- return ENODEV;
-
- /* We should have a "dev" from Space.c or the static module table. */
- if (dev == NULL) {
- printk("wd.c: Passed a NULL device.\n");
- dev = init_etherdev(0, 0);
- }
-
- /* Check for semi-valid mem_start/end values if supplied. */
- if ((dev->mem_start % 0x2000) || (dev->mem_end % 0x2000)) {
- printk(KERN_WARNING "wd.c: user supplied mem_start or mem_end not on 8kB boundary - ignored.\n");
- dev->mem_start = 0;
- dev->mem_end = 0;
- }
-
- if (ei_debug && version_printed++ == 0)
- printk(version);
-
- printk("%s: WD80x3 at %#3x, ", dev->name, ioaddr);
- for (i = 0; i < 6; i++)
- printk(" %2.2X", dev->dev_addr[i] = inb(ioaddr + 8 + i));
-
- /* The following PureData probe code was contributed by
- Mike Jagdis <jaggy@purplet.demon.co.uk>. Puredata does software
- configuration differently from others so we have to check for them.
- This detects an 8 bit, 16 bit or dumb (Toshiba, jumpered) card.
- */
- if (inb(ioaddr+0) == 'P' && inb(ioaddr+1) == 'D') {
- unsigned char reg5 = inb(ioaddr+5);
-
- switch (inb(ioaddr+2)) {
- case 0x03: word16 = 0; model_name = "PDI8023-8"; break;
- case 0x05: word16 = 0; model_name = "PDUC8023"; break;
- case 0x0a: word16 = 1; model_name = "PDI8023-16"; break;
- /* Either 0x01 (dumb) or they've released a new version. */
- default: word16 = 0; model_name = "PDI8023"; break;
- }
- dev->mem_start = ((reg5 & 0x1c) + 0xc0) << 12;
- dev->irq = (reg5 & 0xe0) == 0xe0 ? 10 : (reg5 >> 5) + 1;
- } else { /* End of PureData probe */
- /* This method of checking for a 16-bit board is borrowed from the
- we.c driver. A simpler method is just to look in ASIC reg. 0x03.
- I'm comparing the two method in alpha test to make certain they
- return the same result. */
- /* Check for the old 8 bit board - it has register 0/8 aliasing.
- Do NOT check i>=6 here -- it hangs the old 8003 boards! */
- for (i = 0; i < 6; i++)
- if (inb(ioaddr+i) != inb(ioaddr+8+i))
- break;
- if (i >= 6) {
- ancient = 1;
- model_name = "WD8003-old";
- word16 = 0;
- } else {
- int tmp = inb(ioaddr+1); /* fiddle with 16bit bit */
- outb( tmp ^ 0x01, ioaddr+1 ); /* attempt to clear 16bit bit */
- if (((inb( ioaddr+1) & 0x01) == 0x01) /* A 16 bit card */
- && (tmp & 0x01) == 0x01 ) { /* In a 16 slot. */
- int asic_reg5 = inb(ioaddr+WD_CMDREG5);
- /* Magic to set ASIC to word-wide mode. */
- outb( NIC16 | (asic_reg5&0x1f), ioaddr+WD_CMDREG5);
- outb(tmp, ioaddr+1);
- model_name = "WD8013";
- word16 = 1; /* We have a 16bit board here! */
- } else {
- model_name = "WD8003";
- word16 = 0;
- }
- outb(tmp, ioaddr+1); /* Restore original reg1 value. */
- }
-#ifndef final_version
- if ( !ancient && (inb(ioaddr+1) & 0x01) != (word16 & 0x01))
- printk("\nWD80?3: Bus width conflict, %d (probe) != %d (reg report).",
- word16 ? 16 : 8, (inb(ioaddr+1) & 0x01) ? 16 : 8);
-#endif
- }
-
-#if defined(WD_SHMEM) && WD_SHMEM > 0x80000
- /* Allow a compile-time override. */
- dev->mem_start = WD_SHMEM;
-#else
- if (dev->mem_start == 0) {
- /* Sanity and old 8003 check */
- int reg0 = inb(ioaddr);
- if (reg0 == 0xff || reg0 == 0) {
- /* Future plan: this could check a few likely locations first. */
- dev->mem_start = 0xd0000;
- printk(" assigning address %#lx", dev->mem_start);
- } else {
- int high_addr_bits = inb(ioaddr+WD_CMDREG5) & 0x1f;
- /* Some boards don't have the register 5 -- it returns 0xff. */
- if (high_addr_bits == 0x1f || word16 == 0)
- high_addr_bits = 0x01;
- dev->mem_start = ((reg0&0x3f) << 13) + (high_addr_bits << 19);
- }
- }
-#endif
-
- /* The 8390 isn't at the base address -- the ASIC regs are there! */
- dev->base_addr = ioaddr+WD_NIC_OFFSET;
-
- if (dev->irq < 2) {
- int irqmap[] = {9,3,5,7,10,11,15,4};
- int reg1 = inb(ioaddr+1);
- int reg4 = inb(ioaddr+4);
- if (ancient || reg1 == 0xff) { /* Ack!! No way to read the IRQ! */
- short nic_addr = ioaddr+WD_NIC_OFFSET;
-
- /* We have an old-style ethercard that doesn't report its IRQ
- line. Do autoirq to find the IRQ line. Note that this IS NOT
- a reliable way to trigger an interrupt. */
- outb_p(E8390_NODMA + E8390_STOP, nic_addr);
- outb(0x00, nic_addr+EN0_IMR); /* Disable all intrs. */
- autoirq_setup(0);
- outb_p(0xff, nic_addr + EN0_IMR); /* Enable all interrupts. */
- outb_p(0x00, nic_addr + EN0_RCNTLO);
- outb_p(0x00, nic_addr + EN0_RCNTHI);
- outb(E8390_RREAD+E8390_START, nic_addr); /* Trigger it... */
- dev->irq = autoirq_report(2);
- outb_p(0x00, nic_addr+EN0_IMR); /* Mask all intrs. again. */
-
- if (ei_debug > 2)
- printk(" autoirq is %d", dev->irq);
- if (dev->irq < 2)
- dev->irq = word16 ? 10 : 5;
- } else
- dev->irq = irqmap[((reg4 >> 5) & 0x03) + (reg1 & 0x04)];
- } else if (dev->irq == 2) /* Fixup bogosity: IRQ2 is really IRQ9 */
- dev->irq = 9;
-
- /* Snarf the interrupt now. There's no point in waiting since we cannot
- share and the board will usually be enabled. */
- if (request_irq(dev->irq, ei_interrupt, 0, model_name)) {
- printk (" unable to get IRQ %d.\n", dev->irq);
- return EAGAIN;
- }
-
- /* Allocate dev->priv and fill in 8390 specific dev fields. */
- if (ethdev_init(dev)) {
- printk (" unable to get memory for dev->priv.\n");
- free_irq(dev->irq);
- return -ENOMEM;
- }
-
- /* OK, were are certain this is going to work. Setup the device. */
- request_region(ioaddr, WD_IO_EXTENT, model_name);
-
- ei_status.name = model_name;
- ei_status.word16 = word16;
- ei_status.tx_start_page = WD_START_PG;
- ei_status.rx_start_page = WD_START_PG + TX_PAGES;
-
- /* Don't map in the shared memory until the board is actually opened. */
- dev->rmem_start = dev->mem_start + TX_PAGES*256;
-
- /* Some cards (eg WD8003EBT) can be jumpered for more (32k!) memory. */
- if (dev->mem_end != 0) {
- ei_status.stop_page = (dev->mem_end - dev->mem_start)/256;
- } else {
- ei_status.stop_page = word16 ? WD13_STOP_PG : WD03_STOP_PG;
- dev->mem_end = dev->mem_start + (ei_status.stop_page - WD_START_PG)*256;
- }
- dev->rmem_end = dev->mem_end;
-
- printk(" %s, IRQ %d, shared memory at %#lx-%#lx.\n",
- model_name, dev->irq, dev->mem_start, dev->mem_end-1);
-
- ei_status.reset_8390 = &wd_reset_8390;
- ei_status.block_input = &wd_block_input;
- ei_status.block_output = &wd_block_output;
- ei_status.get_8390_hdr = &wd_get_8390_hdr;
- dev->open = &wd_open;
- dev->stop = &wd_close_card;
- NS8390_init(dev, 0);
-
-#if 1
- /* Enable interrupt generation on softconfig cards -- M.U */
- /* .. but possibly potentially unsafe - Donald */
- if (inb(ioaddr+14) & 0x20)
- outb(inb(ioaddr+4)|0x80, ioaddr+4);
-#endif
-
- return 0;
-}
-
-static int
-wd_open(struct device *dev)
-{
- int ioaddr = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */
-
- /* Map in the shared memory. Always set register 0 last to remain
- compatible with very old boards. */
- ei_status.reg0 = ((dev->mem_start>>13) & 0x3f) | WD_MEMENB;
- ei_status.reg5 = ((dev->mem_start>>19) & 0x1f) | NIC16;
-
- if (ei_status.word16)
- outb(ei_status.reg5, ioaddr+WD_CMDREG5);
- outb(ei_status.reg0, ioaddr); /* WD_CMDREG */
-
- ei_open(dev);
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-static void
-wd_reset_8390(struct device *dev)
-{
- int wd_cmd_port = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */
-
- outb(WD_RESET, wd_cmd_port);
- if (ei_debug > 1) printk("resetting the WD80x3 t=%lu...", jiffies);
- ei_status.txing = 0;
-
- /* Set up the ASIC registers, just in case something changed them. */
- outb((((dev->mem_start>>13) & 0x3f)|WD_MEMENB), wd_cmd_port);
- if (ei_status.word16)
- outb(NIC16 | ((dev->mem_start>>19) & 0x1f), wd_cmd_port+WD_CMDREG5);
-
- if (ei_debug > 1) printk("reset done\n");
- return;
-}
-
-/* Grab the 8390 specific header. Similar to the block_input routine, but
- we don't need to be concerned with ring wrap as the header will be at
- the start of a page, so we optimize accordingly. */
-
-static void
-wd_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
-{
-
- int wd_cmdreg = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */
- unsigned long hdr_start = dev->mem_start + ((ring_page - WD_START_PG)<<8);
-
- /* We'll always get a 4 byte header read followed by a packet read, so
- we enable 16 bit mode before the header, and disable after the body. */
- if (ei_status.word16)
- outb(ISA16 | ei_status.reg5, wd_cmdreg+WD_CMDREG5);
-
-#ifdef notdef
- /* Officially this is what we are doing, but the readl() is faster */
- memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
-#else
- ((unsigned int*)hdr)[0] = readl(hdr_start);
-#endif
-}
-
-/* Block input and output are easy on shared memory ethercards, and trivial
- on the Western digital card where there is no choice of how to do it.
- The only complications are that the ring buffer wraps, and need to map
- switch between 8- and 16-bit modes. */
-
-static void
-wd_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset)
-{
- int wd_cmdreg = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */
- unsigned long xfer_start = dev->mem_start + ring_offset - (WD_START_PG<<8);
-
- if (xfer_start + count > dev->rmem_end) {
- /* We must wrap the input move. */
- int semi_count = dev->rmem_end - xfer_start;
- memcpy_fromio(skb->data, xfer_start, semi_count);
- count -= semi_count;
- memcpy_fromio(skb->data + semi_count, dev->rmem_start, count);
- } else {
- /* Packet is in one chunk -- we can copy + cksum. */
- eth_io_copy_and_sum(skb, xfer_start, count, 0);
- }
-
- /* Turn off 16 bit access so that reboot works. ISA brain-damage */
- if (ei_status.word16)
- outb(ei_status.reg5, wd_cmdreg+WD_CMDREG5);
-}
-
-static void
-wd_block_output(struct device *dev, int count, const unsigned char *buf,
- int start_page)
-{
- int wd_cmdreg = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */
- long shmem = dev->mem_start + ((start_page - WD_START_PG)<<8);
-
-
- if (ei_status.word16) {
- /* Turn on and off 16 bit access so that reboot works. */
- outb(ISA16 | ei_status.reg5, wd_cmdreg+WD_CMDREG5);
- memcpy_toio(shmem, buf, count);
- outb(ei_status.reg5, wd_cmdreg+WD_CMDREG5);
- } else
- memcpy_toio(shmem, buf, count);
-}
-
-
-static int
-wd_close_card(struct device *dev)
-{
- int wd_cmdreg = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */
-
- if (ei_debug > 1)
- printk("%s: Shutting down ethercard.\n", dev->name);
- ei_close(dev);
-
- /* Change from 16-bit to 8-bit shared memory so reboot works. */
- if (ei_status.word16)
- outb(ei_status.reg5, wd_cmdreg + WD_CMDREG5 );
-
- /* And disable the shared memory. */
- outb(ei_status.reg0 & ~WD_MEMENB, wd_cmdreg);
-
- MOD_DEC_USE_COUNT;
-
- return 0;
-}
-
-
-#ifdef MODULE
-#define MAX_WD_CARDS 4 /* Max number of wd cards per module */
-#define NAMELEN 8 /* # of chars for storing dev->name */
-static char namelist[NAMELEN * MAX_WD_CARDS] = { 0, };
-static struct device dev_wd[MAX_WD_CARDS] = {
- {
- NULL, /* assign a chunk of namelist[] below */
- 0, 0, 0, 0,
- 0, 0,
- 0, 0, 0, NULL, NULL
- },
-};
-
-static int io[MAX_WD_CARDS] = { 0, };
-static int irq[MAX_WD_CARDS] = { 0, };
-static int mem[MAX_WD_CARDS] = { 0, };
-static int mem_end[MAX_WD_CARDS] = { 0, }; /* for non std. mem size */
-
-/* This is set up so that only a single autoprobe takes place per call.
-ISA device autoprobes on a running machine are not recommended. */
-int
-init_module(void)
-{
- int this_dev, found = 0;
-
- for (this_dev = 0; this_dev < MAX_WD_CARDS; this_dev++) {
- struct device *dev = &dev_wd[this_dev];
- dev->name = namelist+(NAMELEN*this_dev);
- dev->irq = irq[this_dev];
- dev->base_addr = io[this_dev];
- dev->mem_start = mem[this_dev];
- dev->mem_end = mem_end[this_dev];
- dev->init = wd_probe;
- if (io[this_dev] == 0) {
- if (this_dev != 0) break; /* only autoprobe 1st one */
- printk(KERN_NOTICE "wd.c: Presently autoprobing (not recommended) for a single card.\n");
- }
- if (register_netdev(dev) != 0) {
- printk(KERN_WARNING "wd.c: No wd80x3 card found (i/o = 0x%x).\n", io[this_dev]);
- if (found != 0) return 0; /* Got at least one. */
- return -ENXIO;
- }
- found++;
- }
-
- return 0;
-}
-
-void
-cleanup_module(void)
-{
- int this_dev;
-
- for (this_dev = 0; this_dev < MAX_WD_CARDS; this_dev++) {
- struct device *dev = &dev_wd[this_dev];
- if (dev->priv != NULL) {
- int ioaddr = dev->base_addr - WD_NIC_OFFSET;
- kfree(dev->priv);
- dev->priv = NULL;
- free_irq(dev->irq);
- irq2dev_map[dev->irq] = NULL;
- release_region(ioaddr, WD_IO_EXTENT);
- unregister_netdev(dev);
- }
- }
-}
-#endif /* MODULE */
-
-
-/*
- * Local variables:
- * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c wd.c"
- * version-control: t
- * tab-width: 4
- * kept-new-versions: 5
- * End:
- */
diff --git a/i386/i386at/gpl/linux/net/znet.c b/i386/i386at/gpl/linux/net/znet.c
deleted file mode 100644
index 9f44928e..00000000
--- a/i386/i386at/gpl/linux/net/znet.c
+++ /dev/null
@@ -1,746 +0,0 @@
-/* znet.c: An Zenith Z-Note ethernet driver for linux. */
-
-static const char *version = "znet.c:v1.02 9/23/94 becker@cesdis.gsfc.nasa.gov\n";
-
-/*
- Written by Donald Becker.
-
- The author may be reached as becker@cesdis.gsfc.nasa.gov.
- This driver is based on the Linux skeleton driver. The copyright of the
- skeleton driver is held by the United States Government, as represented
- by DIRNSA, and it is released under the GPL.
-
- Thanks to Mike Hollick for alpha testing and suggestions.
-
- References:
- The Crynwr packet driver.
-
- "82593 CSMA/CD Core LAN Controller" Intel datasheet, 1992
- Intel Microcommunications Databook, Vol. 1, 1990.
- As usual with Intel, the documentation is incomplete and inaccurate.
- I had to read the Crynwr packet driver to figure out how to actually
- use the i82593, and guess at what register bits matched the loosely
- related i82586.
-
- Theory of Operation
-
- The i82593 used in the Zenith Z-Note series operates using two(!) slave
- DMA channels, one interrupt, and one 8-bit I/O port.
-
- While there several ways to configure '593 DMA system, I chose the one
- that seemed commensurate with the highest system performance in the face
- of moderate interrupt latency: Both DMA channels are configured as
- recirculating ring buffers, with one channel (#0) dedicated to Rx and
- the other channel (#1) to Tx and configuration. (Note that this is
- different than the Crynwr driver, where the Tx DMA channel is initialized
- before each operation. That approach simplifies operation and Tx error
- recovery, but requires additional I/O in normal operation and precludes
- transmit buffer chaining.)
-
- Both rings are set to 8192 bytes using {TX,RX}_RING_SIZE. This provides
- a reasonable ring size for Rx, while simplifying DMA buffer allocation --
- DMA buffers must not cross a 128K boundary. (In truth the size selection
- was influenced by my lack of '593 documentation. I thus was constrained
- to use the Crynwr '593 initialization table, which sets the Rx ring size
- to 8K.)
-
- Despite my usual low opinion about Intel-designed parts, I must admit
- that the bulk data handling of the i82593 is a good design for
- an integrated system, like a laptop, where using two slave DMA channels
- doesn't pose a problem. I still take issue with using only a single I/O
- port. In the same controlled environment there are essentially no
- limitations on I/O space, and using multiple locations would eliminate
- the need for multiple operations when looking at status registers,
- setting the Rx ring boundary, or switching to promiscuous mode.
-
- I also question Zenith's selection of the '593: one of the advertised
- advantages of earlier Intel parts was that if you figured out the magic
- initialization incantation you could use the same part on many different
- network types. Zenith's use of the "FriendlyNet" (sic) connector rather
- than an on-board transceiver leads me to believe that they were planning
- to take advantage of this. But, uhmmm, the '593 omits all but ethernet
- functionality from the serial subsystem.
- */
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/ptrace.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <asm/system.h>
-#include <asm/bitops.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/if_arp.h>
-
-#ifndef ZNET_DEBUG
-#define ZNET_DEBUG 1
-#endif
-static unsigned int znet_debug = ZNET_DEBUG;
-
-/* The DMA modes we need aren't in <dma.h>. */
-#define DMA_RX_MODE 0x14 /* Auto init, I/O to mem, ++, demand. */
-#define DMA_TX_MODE 0x18 /* Auto init, Mem to I/O, ++, demand. */
-#define dma_page_eq(ptr1, ptr2) ((long)(ptr1)>>17 == (long)(ptr2)>>17)
-#define DMA_BUF_SIZE 8192
-#define RX_BUF_SIZE 8192
-#define TX_BUF_SIZE 8192
-
-/* Commands to the i82593 channel 0. */
-#define CMD0_CHNL_0 0x00
-#define CMD0_CHNL_1 0x10 /* Switch to channel 1. */
-#define CMD0_NOP (CMD0_CHNL_0)
-#define CMD0_PORT_1 CMD0_CHNL_1
-#define CMD1_PORT_0 1
-#define CMD0_IA_SETUP 1
-#define CMD0_CONFIGURE 2
-#define CMD0_MULTICAST_LIST 3
-#define CMD0_TRANSMIT 4
-#define CMD0_DUMP 6
-#define CMD0_DIAGNOSE 7
-#define CMD0_Rx_ENABLE 8
-#define CMD0_Rx_DISABLE 10
-#define CMD0_Rx_STOP 11
-#define CMD0_RETRANSMIT 12
-#define CMD0_ABORT 13
-#define CMD0_RESET 14
-
-#define CMD0_ACK 0x80
-
-#define CMD0_STAT0 (0 << 5)
-#define CMD0_STAT1 (1 << 5)
-#define CMD0_STAT2 (2 << 5)
-#define CMD0_STAT3 (3 << 5)
-
-#define net_local znet_private
-struct znet_private {
- int rx_dma, tx_dma;
- struct enet_statistics stats;
- /* The starting, current, and end pointers for the packet buffers. */
- ushort *rx_start, *rx_cur, *rx_end;
- ushort *tx_start, *tx_cur, *tx_end;
- ushort tx_buf_len; /* Tx buffer length, in words. */
-};
-
-/* Only one can be built-in;-> */
-static struct znet_private zn;
-static ushort dma_buffer1[DMA_BUF_SIZE/2];
-static ushort dma_buffer2[DMA_BUF_SIZE/2];
-static ushort dma_buffer3[DMA_BUF_SIZE/2 + 8];
-
-/* The configuration block. What an undocumented nightmare. The first
- set of values are those suggested (without explanation) for ethernet
- in the Intel 82586 databook. The rest appear to be completely undocumented,
- except for cryptic notes in the Crynwr packet driver. This driver uses
- the Crynwr values verbatim. */
-
-static unsigned char i593_init[] = {
- 0xAA, /* 0: 16-byte input & 80-byte output FIFO. */
- /* threshold, 96-byte FIFO, 82593 mode. */
- 0x88, /* 1: Continuous w/interrupts, 128-clock DMA.*/
- 0x2E, /* 2: 8-byte preamble, NO address insertion, */
- /* 6-byte Ethernet address, loopback off.*/
- 0x00, /* 3: Default priorities & backoff methods. */
- 0x60, /* 4: 96-bit interframe spacing. */
- 0x00, /* 5: 512-bit slot time (low-order). */
- 0xF2, /* 6: Slot time (high-order), 15 COLL retries. */
- 0x00, /* 7: Promisc-off, broadcast-on, default CRC. */
- 0x00, /* 8: Default carrier-sense, collision-detect. */
- 0x40, /* 9: 64-byte minimum frame length. */
- 0x5F, /* A: Type/length checks OFF, no CRC input,
- "jabber" termination, etc. */
- 0x00, /* B: Full-duplex disabled. */
- 0x3F, /* C: Default multicast addresses & backoff. */
- 0x07, /* D: Default IFS retriggering. */
- 0x31, /* E: Internal retransmit, drop "runt" packets,
- synchr. DRQ deassertion, 6 status bytes. */
- 0x22, /* F: Receive ring-buffer size (8K),
- receive-stop register enable. */
-};
-
-struct netidblk {
- char magic[8]; /* The magic number (string) "NETIDBLK" */
- unsigned char netid[8]; /* The physical station address */
- char nettype, globalopt;
- char vendor[8]; /* The machine vendor and product name. */
- char product[8];
- char irq1, irq2; /* Interrupts, only one is currently used. */
- char dma1, dma2;
- short dma_mem_misc[8]; /* DMA buffer locations (unused in Linux). */
- short iobase1, iosize1;
- short iobase2, iosize2; /* Second iobase unused. */
- char driver_options; /* Misc. bits */
- char pad;
-};
-
-int znet_probe(struct device *dev);
-static int znet_open(struct device *dev);
-static int znet_send_packet(struct sk_buff *skb, struct device *dev);
-static void znet_interrupt(int irq, struct pt_regs *regs);
-static void znet_rx(struct device *dev);
-static int znet_close(struct device *dev);
-static struct enet_statistics *net_get_stats(struct device *dev);
-static void set_multicast_list(struct device *dev);
-static void hardware_init(struct device *dev);
-static void update_stop_hit(short ioaddr, unsigned short rx_stop_offset);
-
-#ifdef notdef
-static struct sigaction znet_sigaction = { &znet_interrupt, 0, 0, NULL, };
-#endif
-
-
-/* The Z-Note probe is pretty easy. The NETIDBLK exists in the safe-to-probe
- BIOS area. We just scan for the signature, and pull the vital parameters
- out of the structure. */
-
-int znet_probe(struct device *dev)
-{
- int i;
- struct netidblk *netinfo;
- char *p;
-
- /* This code scans the region 0xf0000 to 0xfffff for a "NETIDBLK". */
- for(p = (char *)0xf0000; p < (char *)0x100000; p++)
- if (*p == 'N' && strncmp(p, "NETIDBLK", 8) == 0)
- break;
-
- if (p >= (char *)0x100000) {
- if (znet_debug > 1)
- printk(KERN_INFO "No Z-Note ethernet adaptor found.\n");
- return ENODEV;
- }
- netinfo = (struct netidblk *)p;
- dev->base_addr = netinfo->iobase1;
- dev->irq = netinfo->irq1;
-
- printk(KERN_INFO "%s: ZNET at %#3lx,", dev->name, dev->base_addr);
-
- /* The station address is in the "netidblk" at 0x0f0000. */
- for (i = 0; i < 6; i++)
- printk(" %2.2x", dev->dev_addr[i] = netinfo->netid[i]);
-
- printk(", using IRQ %d DMA %d and %d.\n", dev->irq, netinfo->dma1,
- netinfo->dma2);
-
- if (znet_debug > 1) {
- printk(KERN_INFO "%s: vendor '%16.16s' IRQ1 %d IRQ2 %d DMA1 %d DMA2 %d.\n",
- dev->name, netinfo->vendor,
- netinfo->irq1, netinfo->irq2,
- netinfo->dma1, netinfo->dma2);
- printk(KERN_INFO "%s: iobase1 %#x size %d iobase2 %#x size %d net type %2.2x.\n",
- dev->name, netinfo->iobase1, netinfo->iosize1,
- netinfo->iobase2, netinfo->iosize2, netinfo->nettype);
- }
-
- if (znet_debug > 0)
- printk("%s%s", KERN_INFO, version);
-
- dev->priv = (void *) &zn;
- zn.rx_dma = netinfo->dma1;
- zn.tx_dma = netinfo->dma2;
-
- /* These should never fail. You can't add devices to a sealed box! */
- if (request_irq(dev->irq, &znet_interrupt, 0, "ZNet")
- || request_dma(zn.rx_dma,"ZNet rx")
- || request_dma(zn.tx_dma,"ZNet tx")) {
- printk(KERN_WARNING "%s: Not opened -- resource busy?!?\n", dev->name);
- return EBUSY;
- }
- irq2dev_map[dev->irq] = dev;
-
- /* Allocate buffer memory. We can cross a 128K boundary, so we
- must be careful about the allocation. It's easiest to waste 8K. */
- if (dma_page_eq(dma_buffer1, &dma_buffer1[RX_BUF_SIZE/2-1]))
- zn.rx_start = dma_buffer1;
- else
- zn.rx_start = dma_buffer2;
-
- if (dma_page_eq(dma_buffer3, &dma_buffer3[RX_BUF_SIZE/2-1]))
- zn.tx_start = dma_buffer3;
- else
- zn.tx_start = dma_buffer2;
- zn.rx_end = zn.rx_start + RX_BUF_SIZE/2;
- zn.tx_buf_len = TX_BUF_SIZE/2;
- zn.tx_end = zn.tx_start + zn.tx_buf_len;
-
- /* The ZNET-specific entries in the device structure. */
- dev->open = &znet_open;
- dev->hard_start_xmit = &znet_send_packet;
- dev->stop = &znet_close;
- dev->get_stats = net_get_stats;
- dev->set_multicast_list = &set_multicast_list;
-
- /* Fill in the 'dev' with ethernet-generic values. */
- ether_setup(dev);
-
- return 0;
-}
-
-
-static int znet_open(struct device *dev)
-{
- int ioaddr = dev->base_addr;
-
- if (znet_debug > 2)
- printk(KERN_DEBUG "%s: znet_open() called.\n", dev->name);
-
- /* Turn on the 82501 SIA, using zenith-specific magic. */
- outb(0x10, 0xe6); /* Select LAN control register */
- outb(inb(0xe7) | 0x84, 0xe7); /* Turn on LAN power (bit 2). */
- /* According to the Crynwr driver we should wait 50 msec. for the
- LAN clock to stabilize. My experiments indicates that the '593 can
- be initialized immediately. The delay is probably needed for the
- DC-to-DC converter to come up to full voltage, and for the oscillator
- to be spot-on at 20Mhz before transmitting.
- Until this proves to be a problem we rely on the higher layers for the
- delay and save allocating a timer entry. */
-
- /* This follows the packet driver's lead, and checks for success. */
- if (inb(ioaddr) != 0x10 && inb(ioaddr) != 0x00)
- printk(KERN_WARNING "%s: Problem turning on the transceiver power.\n",
- dev->name);
-
- dev->tbusy = 0;
- dev->interrupt = 0;
- hardware_init(dev);
- dev->start = 1;
-
- return 0;
-}
-
-static int znet_send_packet(struct sk_buff *skb, struct device *dev)
-{
- int ioaddr = dev->base_addr;
-
- if (znet_debug > 4)
- printk(KERN_DEBUG "%s: ZNet_send_packet(%ld).\n", dev->name, dev->tbusy);
-
- /* Transmitter timeout, likely just recovery after suspending the machine. */
- if (dev->tbusy) {
- ushort event, tx_status, rx_offset, state;
- int tickssofar = jiffies - dev->trans_start;
- if (tickssofar < 10)
- return 1;
- outb(CMD0_STAT0, ioaddr); event = inb(ioaddr);
- outb(CMD0_STAT1, ioaddr); tx_status = inw(ioaddr);
- outb(CMD0_STAT2, ioaddr); rx_offset = inw(ioaddr);
- outb(CMD0_STAT3, ioaddr); state = inb(ioaddr);
- printk(KERN_WARNING "%s: transmit timed out, status %02x %04x %04x %02x,"
- " resetting.\n", dev->name, event, tx_status, rx_offset, state);
- if (tx_status == 0x0400)
- printk(KERN_WARNING "%s: Tx carrier error, check transceiver cable.\n",
- dev->name);
- outb(CMD0_RESET, ioaddr);
- hardware_init(dev);
- }
-
- if (skb == NULL) {
- dev_tint(dev);
- return 0;
- }
-
- /* Check that the part hasn't reset itself, probably from suspend. */
- outb(CMD0_STAT0, ioaddr);
- if (inw(ioaddr) == 0x0010
- && inw(ioaddr) == 0x0000
- && inw(ioaddr) == 0x0010)
- hardware_init(dev);
-
- /* Block a timer-based transmit from overlapping. This could better be
- done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
- if (set_bit(0, (void*)&dev->tbusy) != 0)
- printk(KERN_WARNING "%s: Transmitter access conflict.\n", dev->name);
- else {
- short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
- unsigned char *buf = (void *)skb->data;
- ushort *tx_link = zn.tx_cur - 1;
- ushort rnd_len = (length + 1)>>1;
-
- {
- short dma_port = ((zn.tx_dma&3)<<2) + IO_DMA2_BASE;
- unsigned addr = inb(dma_port);
- addr |= inb(dma_port) << 8;
- addr <<= 1;
- if (((int)zn.tx_cur & 0x1ffff) != addr)
- printk(KERN_WARNING "Address mismatch at Tx: %#x vs %#x.\n",
- (int)zn.tx_cur & 0xffff, addr);
- zn.tx_cur = (ushort *)(((int)zn.tx_cur & 0xfe0000) | addr);
- }
-
- if (zn.tx_cur >= zn.tx_end)
- zn.tx_cur = zn.tx_start;
- *zn.tx_cur++ = length;
- if (zn.tx_cur + rnd_len + 1 > zn.tx_end) {
- int semi_cnt = (zn.tx_end - zn.tx_cur)<<1; /* Cvrt to byte cnt. */
- memcpy(zn.tx_cur, buf, semi_cnt);
- rnd_len -= semi_cnt>>1;
- memcpy(zn.tx_start, buf + semi_cnt, length - semi_cnt);
- zn.tx_cur = zn.tx_start + rnd_len;
- } else {
- memcpy(zn.tx_cur, buf, skb->len);
- zn.tx_cur += rnd_len;
- }
- *zn.tx_cur++ = 0;
- cli(); {
- *tx_link = CMD0_TRANSMIT + CMD0_CHNL_1;
- /* Is this always safe to do? */
- outb(CMD0_TRANSMIT + CMD0_CHNL_1,ioaddr);
- } sti();
-
- dev->trans_start = jiffies;
- if (znet_debug > 4)
- printk(KERN_DEBUG "%s: Transmitter queued, length %d.\n", dev->name, length);
- }
- dev_kfree_skb(skb, FREE_WRITE);
- return 0;
-}
-
-/* The ZNET interrupt handler. */
-static void znet_interrupt(int irq, struct pt_regs * regs)
-{
- struct device *dev = irq2dev_map[irq];
- int ioaddr;
- int boguscnt = 20;
-
- if (dev == NULL) {
- printk(KERN_WARNING "znet_interrupt(): IRQ %d for unknown device.\n", irq);
- return;
- }
-
- dev->interrupt = 1;
- ioaddr = dev->base_addr;
-
- outb(CMD0_STAT0, ioaddr);
- do {
- ushort status = inb(ioaddr);
- if (znet_debug > 5) {
- ushort result, rx_ptr, running;
- outb(CMD0_STAT1, ioaddr);
- result = inw(ioaddr);
- outb(CMD0_STAT2, ioaddr);
- rx_ptr = inw(ioaddr);
- outb(CMD0_STAT3, ioaddr);
- running = inb(ioaddr);
- printk(KERN_DEBUG "%s: interrupt, status %02x, %04x %04x %02x serial %d.\n",
- dev->name, status, result, rx_ptr, running, boguscnt);
- }
- if ((status & 0x80) == 0)
- break;
-
- if ((status & 0x0F) == 4) { /* Transmit done. */
- struct net_local *lp = (struct net_local *)dev->priv;
- int tx_status;
- outb(CMD0_STAT1, ioaddr);
- tx_status = inw(ioaddr);
- /* It's undocumented, but tx_status seems to match the i82586. */
- if (tx_status & 0x2000) {
- lp->stats.tx_packets++;
- lp->stats.collisions += tx_status & 0xf;
- } else {
- if (tx_status & 0x0600) lp->stats.tx_carrier_errors++;
- if (tx_status & 0x0100) lp->stats.tx_fifo_errors++;
- if (!(tx_status & 0x0040)) lp->stats.tx_heartbeat_errors++;
- if (tx_status & 0x0020) lp->stats.tx_aborted_errors++;
- /* ...and the catch-all. */
- if ((tx_status | 0x0760) != 0x0760)
- lp->stats.tx_errors++;
- }
- dev->tbusy = 0;
- mark_bh(NET_BH); /* Inform upper layers. */
- }
-
- if ((status & 0x40)
- || (status & 0x0f) == 11) {
- znet_rx(dev);
- }
- /* Clear the interrupts we've handled. */
- outb(CMD0_ACK,ioaddr);
- } while (boguscnt--);
-
- dev->interrupt = 0;
- return;
-}
-
-static void znet_rx(struct device *dev)
-{
- struct net_local *lp = (struct net_local *)dev->priv;
- int ioaddr = dev->base_addr;
- int boguscount = 1;
- short next_frame_end_offset = 0; /* Offset of next frame start. */
- short *cur_frame_end;
- short cur_frame_end_offset;
-
- outb(CMD0_STAT2, ioaddr);
- cur_frame_end_offset = inw(ioaddr);
-
- if (cur_frame_end_offset == zn.rx_cur - zn.rx_start) {
- printk(KERN_WARNING "%s: Interrupted, but nothing to receive, offset %03x.\n",
- dev->name, cur_frame_end_offset);
- return;
- }
-
- /* Use same method as the Crynwr driver: construct a forward list in
- the same area of the backwards links we now have. This allows us to
- pass packets to the upper layers in the order they were received --
- important for fast-path sequential operations. */
- while (zn.rx_start + cur_frame_end_offset != zn.rx_cur
- && ++boguscount < 5) {
- unsigned short hi_cnt, lo_cnt, hi_status, lo_status;
- int count, status;
-
- if (cur_frame_end_offset < 4) {
- /* Oh no, we have a special case: the frame trailer wraps around
- the end of the ring buffer. We've saved space at the end of
- the ring buffer for just this problem. */
- memcpy(zn.rx_end, zn.rx_start, 8);
- cur_frame_end_offset += (RX_BUF_SIZE/2);
- }
- cur_frame_end = zn.rx_start + cur_frame_end_offset - 4;
-
- lo_status = *cur_frame_end++;
- hi_status = *cur_frame_end++;
- status = ((hi_status & 0xff) << 8) + (lo_status & 0xff);
- lo_cnt = *cur_frame_end++;
- hi_cnt = *cur_frame_end++;
- count = ((hi_cnt & 0xff) << 8) + (lo_cnt & 0xff);
-
- if (znet_debug > 5)
- printk(KERN_DEBUG "Constructing trailer at location %03x, %04x %04x %04x %04x"
- " count %#x status %04x.\n",
- cur_frame_end_offset<<1, lo_status, hi_status, lo_cnt, hi_cnt,
- count, status);
- cur_frame_end[-4] = status;
- cur_frame_end[-3] = next_frame_end_offset;
- cur_frame_end[-2] = count;
- next_frame_end_offset = cur_frame_end_offset;
- cur_frame_end_offset -= ((count + 1)>>1) + 3;
- if (cur_frame_end_offset < 0)
- cur_frame_end_offset += RX_BUF_SIZE/2;
- };
-
- /* Now step forward through the list. */
- do {
- ushort *this_rfp_ptr = zn.rx_start + next_frame_end_offset;
- int status = this_rfp_ptr[-4];
- int pkt_len = this_rfp_ptr[-2];
-
- if (znet_debug > 5)
- printk(KERN_DEBUG "Looking at trailer ending at %04x status %04x length %03x"
- " next %04x.\n", next_frame_end_offset<<1, status, pkt_len,
- this_rfp_ptr[-3]<<1);
- /* Once again we must assume that the i82586 docs apply. */
- if ( ! (status & 0x2000)) { /* There was an error. */
- lp->stats.rx_errors++;
- if (status & 0x0800) lp->stats.rx_crc_errors++;
- if (status & 0x0400) lp->stats.rx_frame_errors++;
- if (status & 0x0200) lp->stats.rx_over_errors++; /* Wrong. */
- if (status & 0x0100) lp->stats.rx_fifo_errors++;
- if (status & 0x0080) lp->stats.rx_length_errors++;
- } else if (pkt_len > 1536) {
- lp->stats.rx_length_errors++;
- } else {
- /* Malloc up new buffer. */
- struct sk_buff *skb;
-
- skb = dev_alloc_skb(pkt_len);
- if (skb == NULL) {
- if (znet_debug)
- printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name);
- lp->stats.rx_dropped++;
- break;
- }
- skb->dev = dev;
-
- if (&zn.rx_cur[(pkt_len+1)>>1] > zn.rx_end) {
- int semi_cnt = (zn.rx_end - zn.rx_cur)<<1;
- memcpy(skb_put(skb,semi_cnt), zn.rx_cur, semi_cnt);
- memcpy(skb_put(skb,pkt_len-semi_cnt), zn.rx_start,
- pkt_len - semi_cnt);
- } else {
- memcpy(skb_put(skb,pkt_len), zn.rx_cur, pkt_len);
- if (znet_debug > 6) {
- unsigned int *packet = (unsigned int *) skb->data;
- printk(KERN_DEBUG "Packet data is %08x %08x %08x %08x.\n", packet[0],
- packet[1], packet[2], packet[3]);
- }
- }
- skb->protocol=eth_type_trans(skb,dev);
- netif_rx(skb);
- lp->stats.rx_packets++;
- }
- zn.rx_cur = this_rfp_ptr;
- if (zn.rx_cur >= zn.rx_end)
- zn.rx_cur -= RX_BUF_SIZE/2;
- update_stop_hit(ioaddr, (zn.rx_cur - zn.rx_start)<<1);
- next_frame_end_offset = this_rfp_ptr[-3];
- if (next_frame_end_offset == 0) /* Read all the frames? */
- break; /* Done for now */
- this_rfp_ptr = zn.rx_start + next_frame_end_offset;
- } while (--boguscount);
-
- /* If any worth-while packets have been received, dev_rint()
- has done a mark_bh(INET_BH) for us and will work on them
- when we get to the bottom-half routine. */
- return;
-}
-
-/* The inverse routine to znet_open(). */
-static int znet_close(struct device *dev)
-{
- int ioaddr = dev->base_addr;
-
- dev->tbusy = 1;
- dev->start = 0;
-
- outb(CMD0_RESET, ioaddr); /* CMD0_RESET */
-
- disable_dma(zn.rx_dma);
- disable_dma(zn.tx_dma);
-
- free_irq(dev->irq);
-
- if (znet_debug > 1)
- printk(KERN_DEBUG "%s: Shutting down ethercard.\n", dev->name);
- /* Turn off transceiver power. */
- outb(0x10, 0xe6); /* Select LAN control register */
- outb(inb(0xe7) & ~0x84, 0xe7); /* Turn on LAN power (bit 2). */
-
- return 0;
-}
-
-/* Get the current statistics. This may be called with the card open or
- closed. */
-static struct enet_statistics *net_get_stats(struct device *dev)
-{
- struct net_local *lp = (struct net_local *)dev->priv;
-
- return &lp->stats;
-}
-
-/* Set or clear the multicast filter for this adaptor.
- As a side effect this routine must also initialize the device parameters.
- This is taken advantage of in open().
-
- N.B. that we change i593_init[] in place. This (properly) makes the
- mode change persistent, but must be changed if this code is moved to
- a multiple adaptor environment.
- */
-static void set_multicast_list(struct device *dev)
-{
- short ioaddr = dev->base_addr;
-
- if (dev->flags&IFF_PROMISC) {
- /* Enable promiscuous mode */
- i593_init[7] &= ~3; i593_init[7] |= 1;
- i593_init[13] &= ~8; i593_init[13] |= 8;
- } else if (dev->mc_list || (dev->flags&IFF_ALLMULTI)) {
- /* Enable accept-all-multicast mode */
- i593_init[7] &= ~3; i593_init[7] |= 0;
- i593_init[13] &= ~8; i593_init[13] |= 8;
- } else { /* Enable normal mode. */
- i593_init[7] &= ~3; i593_init[7] |= 0;
- i593_init[13] &= ~8; i593_init[13] |= 0;
- }
- *zn.tx_cur++ = sizeof(i593_init);
- memcpy(zn.tx_cur, i593_init, sizeof(i593_init));
- zn.tx_cur += sizeof(i593_init)/2;
- outb(CMD0_CONFIGURE+CMD0_CHNL_1, ioaddr);
-#ifdef not_tested
- if (num_addrs > 0) {
- int addrs_len = 6*num_addrs;
- *zn.tx_cur++ = addrs_len;
- memcpy(zn.tx_cur, addrs, addrs_len);
- outb(CMD0_MULTICAST_LIST+CMD0_CHNL_1, ioaddr);
- zn.tx_cur += addrs_len>>1;
- }
-#endif
-}
-
-void show_dma(void)
-{
- short dma_port = ((zn.tx_dma&3)<<2) + IO_DMA2_BASE;
- unsigned addr = inb(dma_port);
- addr |= inb(dma_port) << 8;
- printk("Addr: %04x cnt:%3x...", addr<<1, get_dma_residue(zn.tx_dma));
-}
-
-/* Initialize the hardware. We have to do this when the board is open()ed
- or when we come out of suspend mode. */
-static void hardware_init(struct device *dev)
-{
- short ioaddr = dev->base_addr;
-
- zn.rx_cur = zn.rx_start;
- zn.tx_cur = zn.tx_start;
-
- /* Reset the chip, and start it up. */
- outb(CMD0_RESET, ioaddr);
-
- cli(); { /* Protect against a DMA flip-flop */
- disable_dma(zn.rx_dma); /* reset by an interrupting task. */
- clear_dma_ff(zn.rx_dma);
- set_dma_mode(zn.rx_dma, DMA_RX_MODE);
- set_dma_addr(zn.rx_dma, (unsigned int) zn.rx_start);
- set_dma_count(zn.rx_dma, RX_BUF_SIZE);
- enable_dma(zn.rx_dma);
- /* Now set up the Tx channel. */
- disable_dma(zn.tx_dma);
- clear_dma_ff(zn.tx_dma);
- set_dma_mode(zn.tx_dma, DMA_TX_MODE);
- set_dma_addr(zn.tx_dma, (unsigned int) zn.tx_start);
- set_dma_count(zn.tx_dma, zn.tx_buf_len<<1);
- enable_dma(zn.tx_dma);
- } sti();
-
- if (znet_debug > 1)
- printk(KERN_DEBUG "%s: Initializing the i82593, tx buf %p... ", dev->name,
- zn.tx_start);
- /* Do an empty configure command, just like the Crynwr driver. This
- resets to chip to its default values. */
- *zn.tx_cur++ = 0;
- *zn.tx_cur++ = 0;
- printk("stat:%02x ", inb(ioaddr)); show_dma();
- outb(CMD0_CONFIGURE+CMD0_CHNL_1, ioaddr);
- *zn.tx_cur++ = sizeof(i593_init);
- memcpy(zn.tx_cur, i593_init, sizeof(i593_init));
- zn.tx_cur += sizeof(i593_init)/2;
- printk("stat:%02x ", inb(ioaddr)); show_dma();
- outb(CMD0_CONFIGURE+CMD0_CHNL_1, ioaddr);
- *zn.tx_cur++ = 6;
- memcpy(zn.tx_cur, dev->dev_addr, 6);
- zn.tx_cur += 3;
- printk("stat:%02x ", inb(ioaddr)); show_dma();
- outb(CMD0_IA_SETUP + CMD0_CHNL_1, ioaddr);
- printk("stat:%02x ", inb(ioaddr)); show_dma();
-
- update_stop_hit(ioaddr, 8192);
- if (znet_debug > 1) printk("enabling Rx.\n");
- outb(CMD0_Rx_ENABLE+CMD0_CHNL_0, ioaddr);
- dev->tbusy = 0;
-}
-
-static void update_stop_hit(short ioaddr, unsigned short rx_stop_offset)
-{
- outb(CMD0_PORT_1, ioaddr);
- if (znet_debug > 5)
- printk(KERN_DEBUG "Updating stop hit with value %02x.\n",
- (rx_stop_offset >> 6) | 0x80);
- outb((rx_stop_offset >> 6) | 0x80, ioaddr);
- outb(CMD1_PORT_0, ioaddr);
-}
-
-/*
- * Local variables:
- * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c znet.c"
- * version-control: t
- * kept-new-versions: 5
- * c-indent-level: 4
- * tab-width: 4
- * End:
- */
diff --git a/i386/i386at/gpl/linux/pci/bios32.c b/i386/i386at/gpl/linux/pci/bios32.c
deleted file mode 100644
index f0717fdb..00000000
--- a/i386/i386at/gpl/linux/pci/bios32.c
+++ /dev/null
@@ -1,466 +0,0 @@
-/*
- * bios32.c - BIOS32, PCI BIOS functions.
- *
- * Sponsored by
- * iX Multiuser Multitasking Magazine
- * Hannover, Germany
- * hm@ix.de
- *
- * Copyright 1993, 1994 Drew Eckhardt
- * Visionary Computing
- * (Unix and Linux consulting and custom programming)
- * Drew@Colorado.EDU
- * +1 (303) 786-7975
- *
- * For more information, please consult
- *
- * PCI BIOS Specification Revision
- * PCI Local Bus Specification
- * PCI System Design Guide
- *
- * PCI Special Interest Group
- * M/S HF3-15A
- * 5200 N.E. Elam Young Parkway
- * Hillsboro, Oregon 97124-6497
- * +1 (503) 696-2000
- * +1 (800) 433-5177
- *
- * Manuals are $25 each or $50 for all three, plus $7 shipping
- * within the United States, $35 abroad.
- *
- *
- * CHANGELOG :
- * Jun 17, 1994 : Modified to accommodate the broken pre-PCI BIOS SPECIFICATION
- * Revision 2.0 present on <thys@dennis.ee.up.ac.za>'s ASUS mainboard.
- *
- * Jan 5, 1995 : Modified to probe PCI hardware at boot time by Frederic
- * Potter, potter@cao-vlsi.ibp.fr
- *
- * Jan 10, 1995 : Modified to store the information about configured pci
- * devices into a list, which can be accessed via /proc/pci by
- * Curtis Varner, cvarner@cs.ucr.edu
- *
- * Jan 12, 1995 : CPU-PCI bridge optimization support by Frederic Potter.
- * Alpha version. Intel & UMC chipset support only.
- *
- * Apr 16, 1995 : Source merge with the DEC Alpha PCI support. Most of the code
- * moved to drivers/pci/pci.c.
- *
- *
- */
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/bios32.h>
-#include <linux/pci.h>
-
-#include <asm/segment.h>
-
-#define PCIBIOS_PCI_FUNCTION_ID 0xb1XX
-#define PCIBIOS_PCI_BIOS_PRESENT 0xb101
-#define PCIBIOS_FIND_PCI_DEVICE 0xb102
-#define PCIBIOS_FIND_PCI_CLASS_CODE 0xb103
-#define PCIBIOS_GENERATE_SPECIAL_CYCLE 0xb106
-#define PCIBIOS_READ_CONFIG_BYTE 0xb108
-#define PCIBIOS_READ_CONFIG_WORD 0xb109
-#define PCIBIOS_READ_CONFIG_DWORD 0xb10a
-#define PCIBIOS_WRITE_CONFIG_BYTE 0xb10b
-#define PCIBIOS_WRITE_CONFIG_WORD 0xb10c
-#define PCIBIOS_WRITE_CONFIG_DWORD 0xb10d
-
-
-/* BIOS32 signature: "_32_" */
-#define BIOS32_SIGNATURE (('_' << 0) + ('3' << 8) + ('2' << 16) + ('_' << 24))
-
-/* PCI signature: "PCI " */
-#define PCI_SIGNATURE (('P' << 0) + ('C' << 8) + ('I' << 16) + (' ' << 24))
-
-/* PCI service signature: "$PCI" */
-#define PCI_SERVICE (('$' << 0) + ('P' << 8) + ('C' << 16) + ('I' << 24))
-
-/*
- * This is the standard structure used to identify the entry point
- * to the BIOS32 Service Directory, as documented in
- * Standard BIOS 32-bit Service Directory Proposal
- * Revision 0.4 May 24, 1993
- * Phoenix Technologies Ltd.
- * Norwood, MA
- * and the PCI BIOS specification.
- */
-
-union bios32 {
- struct {
- unsigned long signature; /* _32_ */
- unsigned long entry; /* 32 bit physical address */
- unsigned char revision; /* Revision level, 0 */
- unsigned char length; /* Length in paragraphs should be 01 */
- unsigned char checksum; /* All bytes must add up to zero */
- unsigned char reserved[5]; /* Must be zero */
- } fields;
- char chars[16];
-};
-
-/*
- * Physical address of the service directory. I don't know if we're
- * allowed to have more than one of these or not, so just in case
- * we'll make pcibios_present() take a memory start parameter and store
- * the array there.
- */
-
-static unsigned long bios32_entry = 0;
-static struct {
- unsigned long address;
- unsigned short segment;
-} bios32_indirect = { 0, KERNEL_CS };
-
-#ifdef CONFIG_PCI
-/*
- * Returns the entry point for the given service, NULL on error
- */
-
-static unsigned long bios32_service(unsigned long service)
-{
- unsigned char return_code; /* %al */
- unsigned long address; /* %ebx */
- unsigned long length; /* %ecx */
- unsigned long entry; /* %edx */
-
- __asm__("lcall (%%edi)"
- : "=a" (return_code),
- "=b" (address),
- "=c" (length),
- "=d" (entry)
- : "0" (service),
- "1" (0),
- "D" (&bios32_indirect));
-
- switch (return_code) {
- case 0:
- return address + entry;
- case 0x80: /* Not present */
- printk("bios32_service(%ld) : not present\n", service);
- return 0;
- default: /* Shouldn't happen */
- printk("bios32_service(%ld) : returned 0x%x, mail drew@colorado.edu\n",
- service, return_code);
- return 0;
- }
-}
-
-static long pcibios_entry = 0;
-static struct {
- unsigned long address;
- unsigned short segment;
-} pci_indirect = { 0, KERNEL_CS };
-
-
-extern unsigned long check_pcibios(unsigned long memory_start, unsigned long memory_end)
-{
- unsigned long signature;
- unsigned char present_status;
- unsigned char major_revision;
- unsigned char minor_revision;
- int pack;
-
- if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
- pci_indirect.address = pcibios_entry;
-
- __asm__("lcall (%%edi)\n\t"
- "jc 1f\n\t"
- "xor %%ah, %%ah\n"
- "1:\tshl $8, %%eax\n\t"
- "movw %%bx, %%ax"
- : "=d" (signature),
- "=a" (pack)
- : "1" (PCIBIOS_PCI_BIOS_PRESENT),
- "D" (&pci_indirect)
- : "bx", "cx");
-
- present_status = (pack >> 16) & 0xff;
- major_revision = (pack >> 8) & 0xff;
- minor_revision = pack & 0xff;
- if (present_status || (signature != PCI_SIGNATURE)) {
- printk ("pcibios_init : %s : BIOS32 Service Directory says PCI BIOS is present,\n"
- " but PCI_BIOS_PRESENT subfunction fails with present status of 0x%x\n"
- " and signature of 0x%08lx (%c%c%c%c). mail drew@Colorado.EDU\n",
- (signature == PCI_SIGNATURE) ? "WARNING" : "ERROR",
- present_status, signature,
- (char) (signature >> 0), (char) (signature >> 8),
- (char) (signature >> 16), (char) (signature >> 24));
-
- if (signature != PCI_SIGNATURE)
- pcibios_entry = 0;
- }
-#if 0
- if (pcibios_entry) {
- printk ("pcibios_init : PCI BIOS revision %x.%02x entry at 0x%lx\n",
- major_revision, minor_revision, pcibios_entry);
- }
-#endif
- }
- return memory_start;
-}
-
-int pcibios_present(void)
-{
- return pcibios_entry ? 1 : 0;
-}
-
-int pcibios_find_class (unsigned int class_code, unsigned short index,
- unsigned char *bus, unsigned char *device_fn)
-{
- unsigned long bx;
- unsigned long ret;
-
- __asm__ ("lcall (%%edi)\n\t"
- "jc 1f\n\t"
- "xor %%ah, %%ah\n"
- "1:"
- : "=b" (bx),
- "=a" (ret)
- : "1" (PCIBIOS_FIND_PCI_CLASS_CODE),
- "c" (class_code),
- "S" ((int) index),
- "D" (&pci_indirect));
- *bus = (bx >> 8) & 0xff;
- *device_fn = bx & 0xff;
- return (int) (ret & 0xff00) >> 8;
-}
-
-
-int pcibios_find_device (unsigned short vendor, unsigned short device_id,
- unsigned short index, unsigned char *bus, unsigned char *device_fn)
-{
- unsigned short bx;
- unsigned short ret;
-
- __asm__("lcall (%%edi)\n\t"
- "jc 1f\n\t"
- "xor %%ah, %%ah\n"
- "1:"
- : "=b" (bx),
- "=a" (ret)
- : "1" (PCIBIOS_FIND_PCI_DEVICE),
- "c" (device_id),
- "d" (vendor),
- "S" ((int) index),
- "D" (&pci_indirect));
- *bus = (bx >> 8) & 0xff;
- *device_fn = bx & 0xff;
- return (int) (ret & 0xff00) >> 8;
-}
-
-int pcibios_read_config_byte(unsigned char bus,
- unsigned char device_fn, unsigned char where, unsigned char *value)
-{
- unsigned long ret;
- unsigned long bx = (bus << 8) | device_fn;
-
- __asm__("lcall (%%esi)\n\t"
- "jc 1f\n\t"
- "xor %%ah, %%ah\n"
- "1:"
- : "=c" (*value),
- "=a" (ret)
- : "1" (PCIBIOS_READ_CONFIG_BYTE),
- "b" (bx),
- "D" ((long) where),
- "S" (&pci_indirect));
- return (int) (ret & 0xff00) >> 8;
-}
-
-int pcibios_read_config_word (unsigned char bus,
- unsigned char device_fn, unsigned char where, unsigned short *value)
-{
- unsigned long ret;
- unsigned long bx = (bus << 8) | device_fn;
-
- __asm__("lcall (%%esi)\n\t"
- "jc 1f\n\t"
- "xor %%ah, %%ah\n"
- "1:"
- : "=c" (*value),
- "=a" (ret)
- : "1" (PCIBIOS_READ_CONFIG_WORD),
- "b" (bx),
- "D" ((long) where),
- "S" (&pci_indirect));
- return (int) (ret & 0xff00) >> 8;
-}
-
-int pcibios_read_config_dword (unsigned char bus,
- unsigned char device_fn, unsigned char where, unsigned int *value)
-{
- unsigned long ret;
- unsigned long bx = (bus << 8) | device_fn;
-
- __asm__("lcall (%%esi)\n\t"
- "jc 1f\n\t"
- "xor %%ah, %%ah\n"
- "1:"
- : "=c" (*value),
- "=a" (ret)
- : "1" (PCIBIOS_READ_CONFIG_DWORD),
- "b" (bx),
- "D" ((long) where),
- "S" (&pci_indirect));
- return (int) (ret & 0xff00) >> 8;
-}
-
-int pcibios_write_config_byte (unsigned char bus,
- unsigned char device_fn, unsigned char where, unsigned char value)
-{
- unsigned long ret;
- unsigned long bx = (bus << 8) | device_fn;
-
- __asm__("lcall (%%esi)\n\t"
- "jc 1f\n\t"
- "xor %%ah, %%ah\n"
- "1:"
- : "=a" (ret)
- : "0" (PCIBIOS_WRITE_CONFIG_BYTE),
- "c" (value),
- "b" (bx),
- "D" ((long) where),
- "S" (&pci_indirect));
- return (int) (ret & 0xff00) >> 8;
-}
-
-int pcibios_write_config_word (unsigned char bus,
- unsigned char device_fn, unsigned char where, unsigned short value)
-{
- unsigned long ret;
- unsigned long bx = (bus << 8) | device_fn;
-
- __asm__("lcall (%%esi)\n\t"
- "jc 1f\n\t"
- "xor %%ah, %%ah\n"
- "1:"
- : "=a" (ret)
- : "0" (PCIBIOS_WRITE_CONFIG_WORD),
- "c" (value),
- "b" (bx),
- "D" ((long) where),
- "S" (&pci_indirect));
- return (int) (ret & 0xff00) >> 8;
-}
-
-int pcibios_write_config_dword (unsigned char bus,
- unsigned char device_fn, unsigned char where, unsigned int value)
-{
- unsigned long ret;
- unsigned long bx = (bus << 8) | device_fn;
-
- __asm__("lcall (%%esi)\n\t"
- "jc 1f\n\t"
- "xor %%ah, %%ah\n"
- "1:"
- : "=a" (ret)
- : "0" (PCIBIOS_WRITE_CONFIG_DWORD),
- "c" (value),
- "b" (bx),
- "D" ((long) where),
- "S" (&pci_indirect));
- return (int) (ret & 0xff00) >> 8;
-}
-
-const char *pcibios_strerror (int error)
-{
- static char buf[80];
-
- switch (error) {
- case PCIBIOS_SUCCESSFUL:
- return "SUCCESSFUL";
-
- case PCIBIOS_FUNC_NOT_SUPPORTED:
- return "FUNC_NOT_SUPPORTED";
-
- case PCIBIOS_BAD_VENDOR_ID:
- return "SUCCESSFUL";
-
- case PCIBIOS_DEVICE_NOT_FOUND:
- return "DEVICE_NOT_FOUND";
-
- case PCIBIOS_BAD_REGISTER_NUMBER:
- return "BAD_REGISTER_NUMBER";
-
- case PCIBIOS_SET_FAILED:
- return "SET_FAILED";
-
- case PCIBIOS_BUFFER_TOO_SMALL:
- return "BUFFER_TOO_SMALL";
-
- default:
- sprintf (buf, "UNKNOWN RETURN 0x%x", error);
- return buf;
- }
-}
-
-
-unsigned long pcibios_fixup(unsigned long mem_start, unsigned long mem_end)
-{
-return mem_start;
-}
-
-
-#endif
-
-unsigned long pcibios_init(unsigned long memory_start, unsigned long memory_end)
-{
- union bios32 *check;
- unsigned char sum;
- int i, length;
-
- /*
- * Follow the standard procedure for locating the BIOS32 Service
- * directory by scanning the permissible address range from
- * 0xe0000 through 0xfffff for a valid BIOS32 structure.
- *
- */
-
- for (check = (union bios32 *) 0xe0000; check <= (union bios32 *) 0xffff0; ++check) {
- if (check->fields.signature != BIOS32_SIGNATURE)
- continue;
- length = check->fields.length * 16;
- if (!length)
- continue;
- sum = 0;
- for (i = 0; i < length ; ++i)
- sum += check->chars[i];
- if (sum != 0)
- continue;
- if (check->fields.revision != 0) {
- printk("pcibios_init : unsupported revision %d at 0x%p, mail drew@colorado.edu\n",
- check->fields.revision, check);
- continue;
- }
-#if 0
- printk ("pcibios_init : BIOS32 Service Directory structure at 0x%p\n", check);
-#endif
- if (!bios32_entry) {
- if (check->fields.entry >= 0x100000) {
- printk("pcibios_init: entry in high memory, unable to access\n");
- } else {
- bios32_indirect.address = bios32_entry = check->fields.entry;
-#if 0
- printk ("pcibios_init : BIOS32 Service Directory entry at 0x%lx\n", bios32_entry);
-#endif
- }
- } else {
- printk ("pcibios_init : multiple entries, mail drew@colorado.edu\n");
- /*
- * Jeremy Fitzhardinge reports at least one PCI BIOS
- * with two different service directories, and as both
- * worked for him, we'll just mention the fact, and
- * not actually disallow it..
- */
- }
- }
-#ifdef CONFIG_PCI
- if (bios32_entry) {
- memory_start = check_pcibios (memory_start, memory_end);
- }
-#endif
- return memory_start;
-}
diff --git a/i386/i386at/gpl/linux/pci/pci.c b/i386/i386at/gpl/linux/pci/pci.c
deleted file mode 100644
index e5f59797..00000000
--- a/i386/i386at/gpl/linux/pci/pci.c
+++ /dev/null
@@ -1,917 +0,0 @@
-/*
- * drivers/pci/pci.c
- *
- * PCI services that are built on top of the BIOS32 service.
- *
- * Copyright 1993, 1994, 1995 Drew Eckhardt, Frederic Potter,
- * David Mosberger-Tang
- */
-#include <linux/config.h>
-#include <linux/ptrace.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/bios32.h>
-#include <linux/pci.h>
-#include <linux/string.h>
-
-#include <asm/page.h>
-
-struct pci_bus pci_root;
-struct pci_dev *pci_devices = 0;
-
-
-/*
- * The bridge_id field is an offset of an item into the array
- * BRIDGE_MAPPING_TYPE. 0xff indicates that the device is not a PCI
- * bridge, or that we don't know for the moment how to configure it.
- * I'm trying to do my best so that the kernel stays small. Different
- * chipset can have same optimization structure. i486 and pentium
- * chipsets from the same manufacturer usually have the same
- * structure.
- */
-#define DEVICE(vid,did,name) \
- {PCI_VENDOR_ID_##vid, PCI_DEVICE_ID_##did, (name), 0xff}
-
-#define BRIDGE(vid,did,name,bridge) \
- {PCI_VENDOR_ID_##vid, PCI_DEVICE_ID_##did, (name), (bridge)}
-
-/*
- * Sorted in ascending order by vendor and device.
- * Use binary search for lookup. If you add a device make sure
- * it is sequential by both vendor and device id.
- */
-struct pci_dev_info dev_info[] = {
- DEVICE( COMPAQ, COMPAQ_1280, "QVision 1280/p"),
- DEVICE( COMPAQ, COMPAQ_THUNDER, "ThunderLAN"),
- DEVICE( NCR, NCR_53C810, "53c810"),
- DEVICE( NCR, NCR_53C820, "53c820"),
- DEVICE( NCR, NCR_53C825, "53c825"),
- DEVICE( NCR, NCR_53C815, "53c815"),
- DEVICE( ATI, ATI_68800, "68800AX"),
- DEVICE( ATI, ATI_215CT222, "215CT222"),
- DEVICE( ATI, ATI_210888CX, "210888CX"),
- DEVICE( ATI, ATI_210888GX, "210888GX"),
- DEVICE( VLSI, VLSI_82C592, "82C592-FC1"),
- DEVICE( VLSI, VLSI_82C593, "82C593-FC1"),
- DEVICE( VLSI, VLSI_82C594, "82C594-AFC2"),
- DEVICE( VLSI, VLSI_82C597, "82C597-AFC2"),
- DEVICE( ADL, ADL_2301, "2301"),
- DEVICE( NS, NS_87410, "87410"),
- DEVICE( TSENG, TSENG_W32P_2, "ET4000W32P"),
- DEVICE( TSENG, TSENG_W32P_b, "ET4000W32P rev B"),
- DEVICE( TSENG, TSENG_W32P_c, "ET4000W32P rev C"),
- DEVICE( TSENG, TSENG_W32P_d, "ET4000W32P rev D"),
- DEVICE( WEITEK, WEITEK_P9000, "P9000"),
- DEVICE( WEITEK, WEITEK_P9100, "P9100"),
- BRIDGE( DEC, DEC_BRD, "DC21050", 0x00),
- DEVICE( DEC, DEC_TULIP, "DC21040"),
- DEVICE( DEC, DEC_TGA, "DC21030"),
- DEVICE( DEC, DEC_TULIP_FAST, "DC21140"),
- DEVICE( DEC, DEC_FDDI, "DEFPA"),
- DEVICE( DEC, DEC_TULIP_PLUS, "DC21041"),
- DEVICE( CIRRUS, CIRRUS_5430, "GD 5430"),
- DEVICE( CIRRUS, CIRRUS_5434_4, "GD 5434"),
- DEVICE( CIRRUS, CIRRUS_5434_8, "GD 5434"),
- DEVICE( CIRRUS, CIRRUS_5436, "GD 5436"),
- DEVICE( CIRRUS, CIRRUS_6205, "GD 6205"),
- DEVICE( CIRRUS, CIRRUS_6729, "CL 6729"),
- DEVICE( CIRRUS, CIRRUS_7542, "CL 7542"),
- DEVICE( CIRRUS, CIRRUS_7543, "CL 7543"),
- DEVICE( IBM, IBM_82G2675, "82G2675"),
- DEVICE( WD, WD_7197, "WD 7197"),
- DEVICE( AMD, AMD_LANCE, "79C970"),
- DEVICE( AMD, AMD_SCSI, "53C974"),
- DEVICE( TRIDENT, TRIDENT_9420, "TG 9420"),
- DEVICE( TRIDENT, TRIDENT_9440, "TG 9440"),
- DEVICE( TRIDENT, TRIDENT_9660, "TG 9660"),
- DEVICE( AI, AI_M1435, "M1435"),
- DEVICE( MATROX, MATROX_MGA_2, "Atlas PX2085"),
- DEVICE( MATROX, MATROX_MIL ,"Millenium"),
- DEVICE( MATROX, MATROX_MGA_IMP, "MGA Impression"),
- DEVICE( CT, CT_65545, "65545"),
- DEVICE( FD, FD_36C70, "TMC-18C30"),
- DEVICE( SI, SI_6201, "6201"),
- DEVICE( SI, SI_6202, "6202"),
- DEVICE( SI, SI_503, "85C503"),
- DEVICE( SI, SI_501, "85C501"),
- DEVICE( SI, SI_496, "85C496"),
- DEVICE( SI, SI_601, "85C601"),
- DEVICE( SI, SI_5511, "85C5511"),
- DEVICE( SI, SI_5513, "85C5513"),
- DEVICE( HP, HP_J2585A, "J2585A"),
- DEVICE( PCTECH, PCTECH_RZ1000, "RZ1000 (buggy)"),
- DEVICE( DPT, DPT, "SmartCache/Raid"),
- DEVICE( OPTI, OPTI_92C178, "92C178"),
- DEVICE( OPTI, OPTI_82C557, "82C557"),
- DEVICE( OPTI, OPTI_82C558, "82C558"),
- DEVICE( OPTI, OPTI_82C621, "82C621"),
- DEVICE( OPTI, OPTI_82C822, "82C822"),
- DEVICE( SGS, SGS_2000, "STG 2000X"),
- DEVICE( SGS, SGS_1764, "STG 1764X"),
- DEVICE( BUSLOGIC, BUSLOGIC_946C_2,"BT-946C"),
- DEVICE( BUSLOGIC, BUSLOGIC_946C, "BT-946C"),
- DEVICE( BUSLOGIC, BUSLOGIC_930, "BT-930"),
- DEVICE( OAK, OAK_OTI107, "OTI107"),
- DEVICE( PROMISE, PROMISE_5300, "DC5030"),
- DEVICE( N9, N9_I128, "Imagine 128"),
- DEVICE( N9, N9_I128_2, "Imagine 128v2"),
- DEVICE( UMC, UMC_UM8673F, "UM8673F"),
- BRIDGE( UMC, UMC_UM8891A, "UM8891A", 0x01),
- DEVICE( UMC, UMC_UM8886BF, "UM8886BF"),
- DEVICE( UMC, UMC_UM8886A, "UM8886A"),
- BRIDGE( UMC, UMC_UM8881F, "UM8881F", 0x02),
- DEVICE( UMC, UMC_UM8886F, "UM8886F"),
- DEVICE( UMC, UMC_UM9017F, "UM9017F"),
- DEVICE( UMC, UMC_UM8886N, "UM8886N"),
- DEVICE( UMC, UMC_UM8891N, "UM8891N"),
- DEVICE( X, X_AGX016, "ITT AGX016"),
- DEVICE( NEXGEN, NEXGEN_82C501, "82C501"),
- DEVICE( QLOGIC, QLOGIC_ISP1020, "ISP1020"),
- DEVICE( QLOGIC, QLOGIC_ISP1022, "ISP1022"),
- DEVICE( LEADTEK, LEADTEK_805, "S3 805"),
- DEVICE( CONTAQ, CONTAQ_82C599, "82C599"),
- DEVICE( CMD, CMD_640, "640 (buggy)"),
- DEVICE( CMD, CMD_646, "646"),
- DEVICE( VISION, VISION_QD8500, "QD-8500"),
- DEVICE( VISION, VISION_QD8580, "QD-8580"),
- DEVICE( SIERRA, SIERRA_STB, "STB Horizon 64"),
- DEVICE( ACC, ACC_2056, "2056"),
- DEVICE( WINBOND, WINBOND_83769, "W83769F"),
- DEVICE( WINBOND, WINBOND_82C105, "SL82C105"),
- DEVICE( 3COM, 3COM_3C590, "3C590 10bT"),
- DEVICE( 3COM, 3COM_3C595TX, "3C595 100bTX"),
- DEVICE( 3COM, 3COM_3C595T4, "3C595 100bT4"),
- DEVICE( 3COM, 3COM_3C595MII, "3C595 100b-MII"),
- DEVICE( AL, AL_M1445, "M1445"),
- DEVICE( AL, AL_M1449, "M1449"),
- DEVICE( AL, AL_M1451, "M1451"),
- DEVICE( AL, AL_M1461, "M1461"),
- DEVICE( AL, AL_M1489, "M1489"),
- DEVICE( AL, AL_M1511, "M1511"),
- DEVICE( AL, AL_M1513, "M1513"),
- DEVICE( AL, AL_M4803, "M4803"),
- DEVICE( ASP, ASP_ABP940, "ABP940"),
- DEVICE( IMS, IMS_8849, "8849"),
- DEVICE( TEKRAM2, TEKRAM2_690c, "DC690c"),
- DEVICE( AMCC, AMCC_MYRINET, "Myrinet PCI (M2-PCI-32)"),
- DEVICE( INTERG, INTERG_1680, "IGA-1680"),
- DEVICE( REALTEK, REALTEK_8029, "8029"),
- DEVICE( INIT, INIT_320P, "320 P"),
- DEVICE( VIA, VIA_82C505, "VT 82C505"),
- DEVICE( VIA, VIA_82C561, "VT 82C561"),
- DEVICE( VIA, VIA_82C576, "VT 82C576 3V"),
- DEVICE( VIA, VIA_82C416, "VT 82C416MV"),
- DEVICE( VORTEX, VORTEX_GDT, "GDT 6000b"),
- DEVICE( EF, EF_ATM_FPGA, "155P-MF1 (FPGA)"),
- DEVICE( EF, EF_ATM_ASIC, "155P-MF1 (ASIC)"),
- DEVICE( IMAGINGTECH, IMAGINGTECH_ICPCI, "MVC IC-PCI"),
- DEVICE( FORE, FORE_PCA200PC, "PCA-200PC"),
- DEVICE( PLX, PLX_9060, "PCI9060 i960 bridge"),
- DEVICE( ALLIANCE, ALLIANCE_PROMOTIO, "Promotion-6410"),
- DEVICE( ALLIANCE, ALLIANCE_PROVIDEO, "Provideo"),
- DEVICE( MUTECH, MUTECH_MV1000, "MV-1000"),
- DEVICE( ZEITNET, ZEITNET_1221, "1221"),
- DEVICE( ZEITNET, ZEITNET_1225, "1225"),
- DEVICE( SPECIALIX, SPECIALIX_XIO, "XIO/SIO host"),
- DEVICE( SPECIALIX, SPECIALIX_RIO, "RIO host"),
- DEVICE( RP, RP8OCTA, "RocketPort 8 Oct"),
- DEVICE( RP, RP8INTF, "RocketPort 8 Intf"),
- DEVICE( RP, RP16INTF, "RocketPort 16 Intf"),
- DEVICE( RP, RP32INTF, "RocketPort 32 Intf"),
- DEVICE( CYCLADES, CYCLADES_Y, "Cyclome-Y"),
- DEVICE( SYMPHONY, SYMPHONY_101, "82C101"),
- DEVICE( TEKRAM, TEKRAM_DC290, "DC-290"),
- DEVICE( AVANCE, AVANCE_2302, "ALG-2302"),
- DEVICE( S3, S3_811, "Trio32/Trio64"),
- DEVICE( S3, S3_868, "Vision 868"),
- DEVICE( S3, S3_928, "Vision 928-P"),
- DEVICE( S3, S3_864_1, "Vision 864-P"),
- DEVICE( S3, S3_864_2, "Vision 864-P"),
- DEVICE( S3, S3_964_1, "Vision 964-P"),
- DEVICE( S3, S3_964_2, "Vision 964-P"),
- DEVICE( S3, S3_968, "Vision 968"),
- DEVICE( INTEL, INTEL_82375, "82375EB"),
- BRIDGE( INTEL, INTEL_82424, "82424ZX Saturn", 0x00),
- DEVICE( INTEL, INTEL_82378, "82378IB"),
- DEVICE( INTEL, INTEL_82430, "82430ZX Aries"),
- BRIDGE( INTEL, INTEL_82434, "82434LX Mercury/Neptune", 0x00),
- DEVICE( INTEL, INTEL_7116, "SAA7116"),
- DEVICE( INTEL, INTEL_82596, "82596"),
- DEVICE( INTEL, INTEL_82865, "82865"),
- DEVICE( INTEL, INTEL_82557, "82557"),
- DEVICE( INTEL, INTEL_82437, "82437"),
- DEVICE( INTEL, INTEL_82371_0, "82371 Triton PIIX"),
- DEVICE( INTEL, INTEL_82371_1, "82371 Triton PIIX"),
- DEVICE( INTEL, INTEL_P6, "Orion P6"),
- DEVICE( ADAPTEC, ADAPTEC_7850, "AIC-7850"),
- DEVICE( ADAPTEC, ADAPTEC_7870, "AIC-7870"),
- DEVICE( ADAPTEC, ADAPTEC_7871, "AIC-7871"),
- DEVICE( ADAPTEC, ADAPTEC_7872, "AIC-7872"),
- DEVICE( ADAPTEC, ADAPTEC_7873, "AIC-7873"),
- DEVICE( ADAPTEC, ADAPTEC_7874, "AIC-7874"),
- DEVICE( ADAPTEC, ADAPTEC_7880, "AIC-7880U"),
- DEVICE( ADAPTEC, ADAPTEC_7881, "AIC-7881U"),
- DEVICE( ADAPTEC, ADAPTEC_7882, "AIC-7882U"),
- DEVICE( ADAPTEC, ADAPTEC_7883, "AIC-7883U"),
- DEVICE( ADAPTEC, ADAPTEC_7884, "AIC-7884U"),
- DEVICE( ATRONICS, ATRONICS_2015, "IDE-2015PL"),
- DEVICE( HER, HER_STING, "Stingray"),
- DEVICE( HER, HER_STINGARK, "Stingray ARK 2000PV")
-};
-
-
-#ifdef CONFIG_PCI_OPTIMIZE
-
-/*
- * An item of this structure has the following meaning:
- * for each optimization, the register address, the mask
- * and value to write to turn it on.
- * There are 5 optimizations for the moment:
- * Cache L2 write back best than write through
- * Posted Write for CPU to PCI enable
- * Posted Write for CPU to MEMORY enable
- * Posted Write for PCI to MEMORY enable
- * PCI Burst enable
- *
- * Half of the bios I've meet don't allow you to turn that on, and you
- * can gain more than 15% on graphic accesses using those
- * optimizations...
- */
-struct optimization_type {
- const char *type;
- const char *off;
- const char *on;
-} bridge_optimization[] = {
- {"Cache L2", "write through", "write back"},
- {"CPU-PCI posted write", "off", "on"},
- {"CPU-Memory posted write", "off", "on"},
- {"PCI-Memory posted write", "off", "on"},
- {"PCI burst", "off", "on"}
-};
-
-#define NUM_OPTIMIZATIONS \
- (sizeof(bridge_optimization) / sizeof(bridge_optimization[0]))
-
-struct bridge_mapping_type {
- unsigned char addr; /* config space address */
- unsigned char mask;
- unsigned char value;
-} bridge_mapping[] = {
- /*
- * Intel Neptune/Mercury/Saturn:
- * If the internal cache is write back,
- * the L2 cache must be write through!
- * I've to check out how to control that
- * for the moment, we won't touch the cache
- */
- {0x0 ,0x02 ,0x02 },
- {0x53 ,0x02 ,0x02 },
- {0x53 ,0x01 ,0x01 },
- {0x54 ,0x01 ,0x01 },
- {0x54 ,0x02 ,0x02 },
-
- /*
- * UMC 8891A Pentium chipset:
- * Why did you think UMC was cheaper ??
- */
- {0x50 ,0x10 ,0x00 },
- {0x51 ,0x40 ,0x40 },
- {0x0 ,0x0 ,0x0 },
- {0x0 ,0x0 ,0x0 },
- {0x0 ,0x0 ,0x0 },
-
- /*
- * UMC UM8881F
- * This is a dummy entry for my tests.
- * I have this chipset and no docs....
- */
- {0x0 ,0x1 ,0x1 },
- {0x0 ,0x2 ,0x0 },
- {0x0 ,0x0 ,0x0 },
- {0x0 ,0x0 ,0x0 },
- {0x0 ,0x0 ,0x0 }
-};
-
-#endif /* CONFIG_PCI_OPTIMIZE */
-
-
-/*
- * device_info[] is sorted so we can use binary search
- */
-struct pci_dev_info *pci_lookup_dev(unsigned int vendor, unsigned int dev)
-{
- int min = 0,
- max = sizeof(dev_info)/sizeof(dev_info[0]) - 1;
-
- for ( ; ; )
- {
- int i = (min + max) >> 1;
- long order;
-
- order = dev_info[i].vendor - (long) vendor;
- if (!order)
- order = dev_info[i].device - (long) dev;
-
- if (order < 0)
- {
- min = i + 1;
- if ( min > max )
- return 0;
- continue;
- }
-
- if (order > 0)
- {
- max = i - 1;
- if ( min > max )
- return 0;
- continue;
- }
-
- return & dev_info[ i ];
- }
-}
-
-const char *pci_strclass (unsigned int class)
-{
- switch (class >> 8) {
- case PCI_CLASS_NOT_DEFINED: return "Non-VGA device";
- case PCI_CLASS_NOT_DEFINED_VGA: return "VGA compatible device";
-
- case PCI_CLASS_STORAGE_SCSI: return "SCSI storage controller";
- case PCI_CLASS_STORAGE_IDE: return "IDE interface";
- case PCI_CLASS_STORAGE_FLOPPY: return "Floppy disk controller";
- case PCI_CLASS_STORAGE_IPI: return "IPI bus controller";
- case PCI_CLASS_STORAGE_RAID: return "RAID bus controller";
- case PCI_CLASS_STORAGE_OTHER: return "Unknown mass storage controller";
-
- case PCI_CLASS_NETWORK_ETHERNET: return "Ethernet controller";
- case PCI_CLASS_NETWORK_TOKEN_RING: return "Token ring network controller";
- case PCI_CLASS_NETWORK_FDDI: return "FDDI network controller";
- case PCI_CLASS_NETWORK_ATM: return "ATM network controller";
- case PCI_CLASS_NETWORK_OTHER: return "Network controller";
-
- case PCI_CLASS_DISPLAY_VGA: return "VGA compatible controller";
- case PCI_CLASS_DISPLAY_XGA: return "XGA compatible controller";
- case PCI_CLASS_DISPLAY_OTHER: return "Display controller";
-
- case PCI_CLASS_MULTIMEDIA_VIDEO: return "Multimedia video controller";
- case PCI_CLASS_MULTIMEDIA_AUDIO: return "Multimedia audio controller";
- case PCI_CLASS_MULTIMEDIA_OTHER: return "Multimedia controller";
-
- case PCI_CLASS_MEMORY_RAM: return "RAM memory";
- case PCI_CLASS_MEMORY_FLASH: return "FLASH memory";
- case PCI_CLASS_MEMORY_OTHER: return "Memory";
-
- case PCI_CLASS_BRIDGE_HOST: return "Host bridge";
- case PCI_CLASS_BRIDGE_ISA: return "ISA bridge";
- case PCI_CLASS_BRIDGE_EISA: return "EISA bridge";
- case PCI_CLASS_BRIDGE_MC: return "MicroChannel bridge";
- case PCI_CLASS_BRIDGE_PCI: return "PCI bridge";
- case PCI_CLASS_BRIDGE_PCMCIA: return "PCMCIA bridge";
- case PCI_CLASS_BRIDGE_NUBUS: return "NuBus bridge";
- case PCI_CLASS_BRIDGE_CARDBUS: return "CardBus bridge";
- case PCI_CLASS_BRIDGE_OTHER: return "Bridge";
-
- case PCI_CLASS_COMMUNICATION_SERIAL: return "Serial controller";
- case PCI_CLASS_COMMUNICATION_PARALLEL: return "Parallel controller";
- case PCI_CLASS_COMMUNICATION_OTHER: return "Communication controller";
-
- case PCI_CLASS_SYSTEM_PIC: return "PIC";
- case PCI_CLASS_SYSTEM_DMA: return "DMA controller";
- case PCI_CLASS_SYSTEM_TIMER: return "Timer";
- case PCI_CLASS_SYSTEM_RTC: return "RTC";
- case PCI_CLASS_SYSTEM_OTHER: return "System peripheral";
-
- case PCI_CLASS_INPUT_KEYBOARD: return "Keyboard controller";
- case PCI_CLASS_INPUT_PEN: return "Digitizer Pen";
- case PCI_CLASS_INPUT_MOUSE: return "Mouse controller";
- case PCI_CLASS_INPUT_OTHER: return "Input device controller";
-
- case PCI_CLASS_DOCKING_GENERIC: return "Generic Docking Station";
- case PCI_CLASS_DOCKING_OTHER: return "Docking Station";
-
- case PCI_CLASS_PROCESSOR_386: return "386";
- case PCI_CLASS_PROCESSOR_486: return "486";
- case PCI_CLASS_PROCESSOR_PENTIUM: return "Pentium";
- case PCI_CLASS_PROCESSOR_ALPHA: return "Alpha";
- case PCI_CLASS_PROCESSOR_POWERPC: return "Power PC";
- case PCI_CLASS_PROCESSOR_CO: return "Co-processor";
-
- case PCI_CLASS_SERIAL_FIREWIRE: return "FireWire (IEEE 1394)";
- case PCI_CLASS_SERIAL_ACCESS: return "ACCESS Bus";
- case PCI_CLASS_SERIAL_SSA: return "SSA";
- case PCI_CLASS_SERIAL_FIBER: return "Fiber Channel";
-
- default: return "Unknown class";
- }
-}
-
-
-const char *pci_strvendor(unsigned int vendor)
-{
- switch (vendor) {
- case PCI_VENDOR_ID_COMPAQ: return "Compaq";
- case PCI_VENDOR_ID_NCR: return "NCR";
- case PCI_VENDOR_ID_ATI: return "ATI";
- case PCI_VENDOR_ID_VLSI: return "VLSI";
- case PCI_VENDOR_ID_ADL: return "Advance Logic";
- case PCI_VENDOR_ID_NS: return "NS";
- case PCI_VENDOR_ID_TSENG: return "Tseng'Lab";
- case PCI_VENDOR_ID_WEITEK: return "Weitek";
- case PCI_VENDOR_ID_DEC: return "DEC";
- case PCI_VENDOR_ID_CIRRUS: return "Cirrus Logic";
- case PCI_VENDOR_ID_IBM: return "IBM";
- case PCI_VENDOR_ID_WD: return "Western Digital";
- case PCI_VENDOR_ID_AMD: return "AMD";
- case PCI_VENDOR_ID_TRIDENT: return "Trident";
- case PCI_VENDOR_ID_AI: return "Acer Incorporated";
- case PCI_VENDOR_ID_MATROX: return "Matrox";
- case PCI_VENDOR_ID_CT: return "Chips & Technologies";
- case PCI_VENDOR_ID_FD: return "Future Domain";
- case PCI_VENDOR_ID_SI: return "Silicon Integrated Systems";
- case PCI_VENDOR_ID_HP: return "Hewlett Packard";
- case PCI_VENDOR_ID_PCTECH: return "PCTECH";
- case PCI_VENDOR_ID_DPT: return "DPT";
- case PCI_VENDOR_ID_OPTI: return "OPTI";
- case PCI_VENDOR_ID_SGS: return "SGS Thomson";
- case PCI_VENDOR_ID_BUSLOGIC: return "BusLogic";
- case PCI_VENDOR_ID_OAK: return "OAK";
- case PCI_VENDOR_ID_PROMISE: return "Promise Technology";
- case PCI_VENDOR_ID_N9: return "Number Nine";
- case PCI_VENDOR_ID_UMC: return "UMC";
- case PCI_VENDOR_ID_X: return "X TECHNOLOGY";
- case PCI_VENDOR_ID_NEXGEN: return "Nexgen";
- case PCI_VENDOR_ID_QLOGIC: return "Q Logic";
- case PCI_VENDOR_ID_LEADTEK: return "Leadtek Research";
- case PCI_VENDOR_ID_CONTAQ: return "Contaq";
- case PCI_VENDOR_ID_FOREX: return "Forex";
- case PCI_VENDOR_ID_OLICOM: return "Olicom";
- case PCI_VENDOR_ID_CMD: return "CMD";
- case PCI_VENDOR_ID_VISION: return "Vision";
- case PCI_VENDOR_ID_SIERRA: return "Sierra";
- case PCI_VENDOR_ID_ACC: return "ACC MICROELECTRONICS";
- case PCI_VENDOR_ID_WINBOND: return "Winbond";
- case PCI_VENDOR_ID_3COM: return "3Com";
- case PCI_VENDOR_ID_AL: return "Acer Labs";
- case PCI_VENDOR_ID_ASP: return "Advanced System Products";
- case PCI_VENDOR_ID_IMS: return "IMS";
- case PCI_VENDOR_ID_TEKRAM2: return "Tekram";
- case PCI_VENDOR_ID_AMCC: return "AMCC";
- case PCI_VENDOR_ID_INTERG: return "Intergraphics";
- case PCI_VENDOR_ID_REALTEK: return "Realtek";
- case PCI_VENDOR_ID_INIT: return "Initio Corp";
- case PCI_VENDOR_ID_VIA: return "VIA Technologies";
- case PCI_VENDOR_ID_VORTEX: return "VORTEX";
- case PCI_VENDOR_ID_EF: return "Efficient Networks";
- case PCI_VENDOR_ID_FORE: return "Fore Systems";
- case PCI_VENDOR_ID_IMAGINGTECH: return "Imaging Technology";
- case PCI_VENDOR_ID_PLX: return "PLX";
- case PCI_VENDOR_ID_ALLIANCE: return "Alliance";
- case PCI_VENDOR_ID_MUTECH: return "Mutech";
- case PCI_VENDOR_ID_ZEITNET: return "ZeitNet";
- case PCI_VENDOR_ID_SPECIALIX: return "Specialix";
- case PCI_VENDOR_ID_RP: return "Comtrol";
- case PCI_VENDOR_ID_CYCLADES: return "Cyclades";
- case PCI_VENDOR_ID_SYMPHONY: return "Symphony";
- case PCI_VENDOR_ID_TEKRAM: return "Tekram";
- case PCI_VENDOR_ID_AVANCE: return "Avance";
- case PCI_VENDOR_ID_S3: return "S3 Inc.";
- case PCI_VENDOR_ID_INTEL: return "Intel";
- case PCI_VENDOR_ID_ADAPTEC: return "Adaptec";
- case PCI_VENDOR_ID_ATRONICS: return "Atronics";
- case PCI_VENDOR_ID_HER: return "Hercules";
- default: return "Unknown vendor";
- }
-}
-
-
-const char *pci_strdev(unsigned int vendor, unsigned int device)
-{
- struct pci_dev_info *info;
-
- info = pci_lookup_dev(vendor, device);
- return info ? info->name : "Unknown device";
-}
-
-
-
-/*
- * Turn on/off PCI bridge optimization. This should allow benchmarking.
- */
-static void burst_bridge(unsigned char bus, unsigned char devfn,
- unsigned char pos, int turn_on)
-{
-#ifdef CONFIG_PCI_OPTIMIZE
- struct bridge_mapping_type *bmap;
- unsigned char val;
- int i;
-
- pos *= NUM_OPTIMIZATIONS;
- printk("PCI bridge optimization.\n");
- for (i = 0; i < NUM_OPTIMIZATIONS; i++) {
- printk(" %s: ", bridge_optimization[i].type);
- bmap = &bridge_mapping[pos + i];
- if (!bmap->addr) {
- printk("Not supported.");
- } else {
- pcibios_read_config_byte(bus, devfn, bmap->addr, &val);
- if ((val & bmap->mask) == bmap->value) {
- printk("%s.", bridge_optimization[i].on);
- if (!turn_on) {
- pcibios_write_config_byte(bus, devfn,
- bmap->addr,
- (val | bmap->mask)
- - bmap->value);
- printk("Changed! Now %s.", bridge_optimization[i].off);
- }
- } else {
- printk("%s.", bridge_optimization[i].off);
- if (turn_on) {
- pcibios_write_config_byte(bus, devfn,
- bmap->addr,
- (val & (0xff - bmap->mask))
- + bmap->value);
- printk("Changed! Now %s.", bridge_optimization[i].on);
- }
- }
- }
- printk("\n");
- }
-#endif /* CONFIG_PCI_OPTIMIZE */
-}
-
-
-/*
- * Convert some of the configuration space registers of the device at
- * address (bus,devfn) into a string (possibly several lines each).
- * The configuration string is stored starting at buf[len]. If the
- * string would exceed the size of the buffer (SIZE), 0 is returned.
- */
-static int sprint_dev_config(struct pci_dev *dev, char *buf, int size)
-{
- unsigned long base;
- unsigned int l, class_rev, bus, devfn;
- unsigned short vendor, device, status;
- unsigned char bist, latency, min_gnt, max_lat;
- int reg, len = 0;
- const char *str;
-
- bus = dev->bus->number;
- devfn = dev->devfn;
-
- pcibios_read_config_dword(bus, devfn, PCI_CLASS_REVISION, &class_rev);
- pcibios_read_config_word (bus, devfn, PCI_VENDOR_ID, &vendor);
- pcibios_read_config_word (bus, devfn, PCI_DEVICE_ID, &device);
- pcibios_read_config_word (bus, devfn, PCI_STATUS, &status);
- pcibios_read_config_byte (bus, devfn, PCI_BIST, &bist);
- pcibios_read_config_byte (bus, devfn, PCI_LATENCY_TIMER, &latency);
- pcibios_read_config_byte (bus, devfn, PCI_MIN_GNT, &min_gnt);
- pcibios_read_config_byte (bus, devfn, PCI_MAX_LAT, &max_lat);
- if (len + 80 > size) {
- return -1;
- }
- len += sprintf(buf + len, " Bus %2d, device %3d, function %2d:\n",
- bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
-
- if (len + 80 > size) {
- return -1;
- }
- len += sprintf(buf + len, " %s: %s %s (rev %d).\n ",
- pci_strclass(class_rev >> 8), pci_strvendor(vendor),
- pci_strdev(vendor, device), class_rev & 0xff);
-
- if (!pci_lookup_dev(vendor, device)) {
- len += sprintf(buf + len,
- "Vendor id=%x. Device id=%x.\n ",
- vendor, device);
- }
-
- str = 0; /* to keep gcc shut... */
- switch (status & PCI_STATUS_DEVSEL_MASK) {
- case PCI_STATUS_DEVSEL_FAST: str = "Fast devsel. "; break;
- case PCI_STATUS_DEVSEL_MEDIUM: str = "Medium devsel. "; break;
- case PCI_STATUS_DEVSEL_SLOW: str = "Slow devsel. "; break;
- }
- if (len + strlen(str) > size) {
- return -1;
- }
- len += sprintf(buf + len, str);
-
- if (status & PCI_STATUS_FAST_BACK) {
-# define fast_b2b_capable "Fast back-to-back capable. "
- if (len + strlen(fast_b2b_capable) > size) {
- return -1;
- }
- len += sprintf(buf + len, fast_b2b_capable);
-# undef fast_b2b_capable
- }
-
- if (bist & PCI_BIST_CAPABLE) {
-# define BIST_capable "BIST capable. "
- if (len + strlen(BIST_capable) > size) {
- return -1;
- }
- len += sprintf(buf + len, BIST_capable);
-# undef BIST_capable
- }
-
- if (dev->irq) {
- if (len + 40 > size) {
- return -1;
- }
- len += sprintf(buf + len, "IRQ %d. ", dev->irq);
- }
-
- if (dev->master) {
- if (len + 80 > size) {
- return -1;
- }
- len += sprintf(buf + len, "Master Capable. ");
- if (latency)
- len += sprintf(buf + len, "Latency=%d. ", latency);
- else
- len += sprintf(buf + len, "No bursts. ");
- if (min_gnt)
- len += sprintf(buf + len, "Min Gnt=%d.", min_gnt);
- if (max_lat)
- len += sprintf(buf + len, "Max Lat=%d.", max_lat);
- }
-
- for (reg = PCI_BASE_ADDRESS_0; reg <= PCI_BASE_ADDRESS_5; reg += 4) {
- if (len + 40 > size) {
- return -1;
- }
- pcibios_read_config_dword(bus, devfn, reg, &l);
- base = l;
- if (!base) {
- continue;
- }
-
- if (base & PCI_BASE_ADDRESS_SPACE_IO) {
- len += sprintf(buf + len,
- "\n I/O at 0x%lx.",
- base & PCI_BASE_ADDRESS_IO_MASK);
- } else {
- const char *pref, *type = "unknown";
-
- if (base & PCI_BASE_ADDRESS_MEM_PREFETCH) {
- pref = "P";
- } else {
- pref = "Non-p";
- }
- switch (base & PCI_BASE_ADDRESS_MEM_TYPE_MASK) {
- case PCI_BASE_ADDRESS_MEM_TYPE_32:
- type = "32 bit"; break;
- case PCI_BASE_ADDRESS_MEM_TYPE_1M:
- type = "20 bit"; break;
- case PCI_BASE_ADDRESS_MEM_TYPE_64:
- type = "64 bit";
- /* read top 32 bit address of base addr: */
- reg += 4;
- pcibios_read_config_dword(bus, devfn, reg, &l);
- base |= ((u64) l) << 32;
- break;
- }
- len += sprintf(buf + len,
- "\n %srefetchable %s memory at "
- "0x%lx.", pref, type,
- base & PCI_BASE_ADDRESS_MEM_MASK);
- }
- }
-
- len += sprintf(buf + len, "\n");
- return len;
-}
-
-
-/*
- * Return list of PCI devices as a character string for /proc/pci.
- * BUF is a buffer that is PAGE_SIZE bytes long.
- */
-int get_pci_list(char *buf)
-{
- int nprinted, len, size;
- struct pci_dev *dev;
-# define MSG "\nwarning: page-size limit reached!\n"
-
- /* reserve same for truncation warning message: */
- size = PAGE_SIZE - (strlen(MSG) + 1);
- len = sprintf(buf, "PCI devices found:\n");
-
- for (dev = pci_devices; dev; dev = dev->next) {
- nprinted = sprint_dev_config(dev, buf + len, size - len);
- if (nprinted < 0) {
- return len + sprintf(buf + len, MSG);
- }
- len += nprinted;
- }
- return len;
-}
-
-
-/*
- * pci_malloc() returns initialized memory of size SIZE. Can be
- * used only while pci_init() is active.
- */
-static void *pci_malloc(long size, unsigned long *mem_startp)
-{
- void *mem;
-
-#ifdef DEBUG
- printk("...pci_malloc(size=%ld,mem=%p)", size, *mem_startp);
-#endif
- mem = (void*) *mem_startp;
- *mem_startp += (size + sizeof(void*) - 1) & ~(sizeof(void*) - 1);
- memset(mem, 0, size);
- return mem;
-}
-
-
-static unsigned int scan_bus(struct pci_bus *bus, unsigned long *mem_startp)
-{
- unsigned int devfn, l, max;
- unsigned char cmd, tmp, hdr_type = 0;
- struct pci_dev_info *info;
- struct pci_dev *dev;
- struct pci_bus *child;
-
-#ifdef DEBUG
- printk("...scan_bus(busno=%d,mem=%p)\n", bus->number, *mem_startp);
-#endif
-
- max = bus->secondary;
- for (devfn = 0; devfn < 0xff; ++devfn) {
- if (PCI_FUNC(devfn) == 0) {
- pcibios_read_config_byte(bus->number, devfn,
- PCI_HEADER_TYPE, &hdr_type);
- } else if (!(hdr_type & 0x80)) {
- /* not a multi-function device */
- continue;
- }
-
- pcibios_read_config_dword(bus->number, devfn, PCI_VENDOR_ID,
- &l);
- /* some broken boards return 0 if a slot is empty: */
- if (l == 0xffffffff || l == 0x00000000) {
- hdr_type = 0;
- continue;
- }
-
- dev = pci_malloc(sizeof(*dev), mem_startp);
- dev->bus = bus;
- /*
- * Put it into the simple chain of devices on this
- * bus. It is used to find devices once everything is
- * set up.
- */
- dev->next = pci_devices;
- pci_devices = dev;
-
- dev->devfn = devfn;
- dev->vendor = l & 0xffff;
- dev->device = (l >> 16) & 0xffff;
-
- /*
- * Check to see if we know about this device and report
- * a message at boot time. This is the only way to
- * learn about new hardware...
- */
- info = pci_lookup_dev(dev->vendor, dev->device);
- if (!info) {
- printk("Warning : Unknown PCI device (%x:%x). Please read include/linux/pci.h \n",
- dev->vendor, dev->device);
- } else {
- /* Some BIOS' are lazy. Let's do their job: */
- if (info->bridge_type != 0xff) {
- burst_bridge(bus->number, devfn,
- info->bridge_type, 1);
- }
- }
-
- /* non-destructively determine if device can be a master: */
- pcibios_read_config_byte(bus->number, devfn, PCI_COMMAND,
- &cmd);
- pcibios_write_config_byte(bus->number, devfn, PCI_COMMAND,
- cmd | PCI_COMMAND_MASTER);
- pcibios_read_config_byte(bus->number, devfn, PCI_COMMAND,
- &tmp);
- dev->master = ((tmp & PCI_COMMAND_MASTER) != 0);
- pcibios_write_config_byte(bus->number, devfn, PCI_COMMAND,
- cmd);
-
- /* read irq level (may be changed during pcibios_fixup()): */
- pcibios_read_config_byte(bus->number, devfn,
- PCI_INTERRUPT_LINE, &dev->irq);
-
- /* check to see if this device is a PCI-PCI bridge: */
- pcibios_read_config_dword(bus->number, devfn,
- PCI_CLASS_REVISION, &l);
- l = l >> 8; /* upper 3 bytes */
- dev->class = l;
- /*
- * Now insert it into the list of devices held
- * by the parent bus.
- */
- dev->sibling = bus->devices;
- bus->devices = dev;
-
- if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI) {
- unsigned int buses;
- unsigned short cr;
-
- /*
- * Insert it into the tree of buses.
- */
- child = pci_malloc(sizeof(*child), mem_startp);
- child->next = bus->children;
- bus->children = child;
- child->self = dev;
- child->parent = bus;
-
- /*
- * Set up the primary, secondary and subordinate
- * bus numbers.
- */
- child->number = child->secondary = ++max;
- child->primary = bus->secondary;
- child->subordinate = 0xff;
- /*
- * Clear all status bits and turn off memory,
- * I/O and master enables.
- */
- pcibios_read_config_word(bus->number, devfn,
- PCI_COMMAND, &cr);
- pcibios_write_config_word(bus->number, devfn,
- PCI_COMMAND, 0x0000);
- pcibios_write_config_word(bus->number, devfn,
- PCI_STATUS, 0xffff);
- /*
- * Configure the bus numbers for this bridge:
- */
- pcibios_read_config_dword(bus->number, devfn, 0x18,
- &buses);
- buses &= 0xff000000;
- buses |= (((unsigned int)(child->primary) << 0) |
- ((unsigned int)(child->secondary) << 8) |
- ((unsigned int)(child->subordinate) << 16));
- pcibios_write_config_dword(bus->number, devfn, 0x18,
- buses);
- /*
- * Now we can scan all subordinate buses:
- */
- max = scan_bus(child, mem_startp);
- /*
- * Set the subordinate bus number to its real
- * value:
- */
- child->subordinate = max;
- buses = (buses & 0xff00ffff)
- | ((unsigned int)(child->subordinate) << 16);
- pcibios_write_config_dword(bus->number, devfn, 0x18,
- buses);
- pcibios_write_config_word(bus->number, devfn,
- PCI_COMMAND, cr);
- }
- }
- /*
- * We've scanned the bus and so we know all about what's on
- * the other side of any bridges that may be on this bus plus
- * any devices.
- *
- * Return how far we've got finding sub-buses.
- */
- return max;
-}
-
-
-unsigned long pci_init (unsigned long mem_start, unsigned long mem_end)
-{
- mem_start = pcibios_init(mem_start, mem_end);
-
- if (!pcibios_present()) {
- printk("pci_init: no BIOS32 detected\n");
- return mem_start;
- }
-
-#if 0
- printk("Probing PCI hardware.\n");
-#endif
-
- memset(&pci_root, 0, sizeof(pci_root));
- pci_root.subordinate = scan_bus(&pci_root, &mem_start);
-
- /* give BIOS a chance to apply platform specific fixes: */
- mem_start = pcibios_fixup(mem_start, mem_end);
-
-#ifdef DEBUG
- {
- int len = get_pci_list((char*)mem_start);
- if (len) {
- ((char *) mem_start)[len] = '\0';
- printk("%s\n", (char *) mem_start);
- }
- }
-#endif
- return mem_start;
-}
diff --git a/i386/i386at/gpl/linux/scsi/53c7,8xx.h b/i386/i386at/gpl/linux/scsi/53c7,8xx.h
deleted file mode 100644
index f1dfc4de..00000000
--- a/i386/i386at/gpl/linux/scsi/53c7,8xx.h
+++ /dev/null
@@ -1,1584 +0,0 @@
-/*
- * NCR 53c{7,8}0x0 driver, header file
- *
- * Sponsored by
- * iX Multiuser Multitasking Magazine
- * Hannover, Germany
- * hm@ix.de
- *
- * Copyright 1993, 1994, 1995 Drew Eckhardt
- * Visionary Computing
- * (Unix and Linux consulting and custom programming)
- * drew@PoohSticks.ORG
- * +1 (303) 786-7975
- *
- * TolerANT and SCSI SCRIPTS are registered trademarks of NCR Corporation.
- *
- * PRE-ALPHA
- *
- * For more information, please consult
- *
- * NCR 53C700/53C700-66
- * SCSI I/O Processor
- * Data Manual
- *
- * NCR 53C810
- * PCI-SCSI I/O Processor
- * Data Manual
- *
- * NCR Microelectronics
- * 1635 Aeroplaza Drive
- * Colorado Springs, CO 80916
- * +1 (719) 578-3400
- *
- * Toll free literature number
- * +1 (800) 334-5454
- *
- */
-
-#ifndef NCR53c7x0_H
-#define NCR53c7x0_H
-#if !defined(LINUX_1_2) && !defined(LINUX_1_3)
-#include <linux/version.h>
-#if LINUX_VERSION_CODE > 65536 + 3 * 256
-#define LINUX_1_3
-#else
-#define LINUX_1_2
-#endif
-#endif
-
-/*
- * Prevent name space pollution in hosts.c, and only provide the
- * define we need to get the NCR53c7x0 driver into the host template
- * array.
- */
-
-#if defined(HOSTS_C) || defined(MODULE)
-#include <linux/scsicam.h>
-
-extern int NCR53c7xx_abort(Scsi_Cmnd *);
-extern int NCR53c7xx_detect(Scsi_Host_Template *tpnt);
-extern int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-extern int NCR53c7xx_reset(Scsi_Cmnd *);
-#ifdef MODULE
-extern int NCR53c7xx_release(struct Scsi_Host *);
-#else
-#define NCR53c7xx_release NULL
-#endif
-
-#ifdef LINUX_1_2
-#define NCR53c7xx {NULL, NULL, "NCR53c{7,8}xx (rel 17)", NCR53c7xx_detect,\
- NULL, /* info */ NULL, /* command, deprecated */ NULL, \
- NCR53c7xx_queue_command, NCR53c7xx_abort, NCR53c7xx_reset, \
- NULL /* slave attach */, scsicam_bios_param, /* can queue */ 24, \
- /* id */ 7, 127 /* old SG_ALL */, /* cmd per lun */ 3, \
- /* present */ 0, /* unchecked isa dma */ 0, DISABLE_CLUSTERING}
-#else
-#define NCR53c7xx {NULL, NULL, NULL, NULL, \
- "NCR53c{7,8}xx (rel 17)", NCR53c7xx_detect,\
- NULL, /* info */ NULL, /* command, deprecated */ NULL, \
- NCR53c7xx_queue_command, NCR53c7xx_abort, NCR53c7xx_reset, \
- NULL /* slave attach */, scsicam_bios_param, /* can queue */ 24, \
- /* id */ 7, 127 /* old SG_ALL */, /* cmd per lun */ 3, \
- /* present */ 0, /* unchecked isa dma */ 0, DISABLE_CLUSTERING}
-#endif
-
-#endif /* defined(HOSTS_C) || defined(MODULE) */
-
-#ifndef HOSTS_C
-#ifdef LINUX_1_2
-/*
- * Change virtual addresses to physical addresses and vv.
- * These are trivial on the 1:1 Linux/i386 mapping (but if we ever
- * make the kernel segment mapped at 0, we need to do translation
- * on the i386 as well)
- */
-extern inline unsigned long virt_to_phys(volatile void * address)
-{
- return (unsigned long) address;
-}
-
-extern inline void * phys_to_virt(unsigned long address)
-{
- return (void *) address;
-}
-
-/*
- * IO bus memory addresses are also 1:1 with the physical address
- */
-#define virt_to_bus virt_to_phys
-#define bus_to_virt phys_to_virt
-
-/*
- * readX/writeX() are used to access memory mapped devices. On some
- * architectures the memory mapped IO stuff needs to be accessed
- * differently. On the x86 architecture, we just read/write the
- * memory location directly.
- */
-#define readb(addr) (*(volatile unsigned char *) (addr))
-#define readw(addr) (*(volatile unsigned short *) (addr))
-#define readl(addr) (*(volatile unsigned int *) (addr))
-
-#define writeb(b,addr) ((*(volatile unsigned char *) (addr)) = (b))
-#define writew(b,addr) ((*(volatile unsigned short *) (addr)) = (b))
-#define writel(b,addr) ((*(volatile unsigned int *) (addr)) = (b))
-
-#define mb()
-
-#endif /* def LINUX_1_2 */
-
-/* Register addresses, ordered numerically */
-
-/* SCSI control 0 rw, default = 0xc0 */
-#define SCNTL0_REG 0x00
-#define SCNTL0_ARB1 0x80 /* 0 0 = simple arbitration */
-#define SCNTL0_ARB2 0x40 /* 1 1 = full arbitration */
-#define SCNTL0_STRT 0x20 /* Start Sequence */
-#define SCNTL0_WATN 0x10 /* Select with ATN */
-#define SCNTL0_EPC 0x08 /* Enable parity checking */
-/* Bit 2 is reserved on 800 series chips */
-#define SCNTL0_EPG_700 0x04 /* Enable parity generation */
-#define SCNTL0_AAP 0x02 /* ATN/ on parity error */
-#define SCNTL0_TRG 0x01 /* Target mode */
-
-/* SCSI control 1 rw, default = 0x00 */
-
-#define SCNTL1_REG 0x01
-#define SCNTL1_EXC 0x80 /* Extra Clock Cycle of Data setup */
-#define SCNTL1_ADB 0x40 /* contents of SODL on bus */
-#define SCNTL1_ESR_700 0x20 /* Enable SIOP response to selection
- and reselection */
-#define SCNTL1_DHP_800 0x20 /* Disable halt on parity error or ATN
- target mode only */
-#define SCNTL1_CON 0x10 /* Connected */
-#define SCNTL1_RST 0x08 /* SCSI RST/ */
-#define SCNTL1_AESP 0x04 /* Force bad parity */
-#define SCNTL1_SND_700 0x02 /* Start SCSI send */
-#define SCNTL1_IARB_800 0x02 /* Immediate Arbitration, start
- arbitration immediately after
- busfree is detected */
-#define SCNTL1_RCV_700 0x01 /* Start SCSI receive */
-#define SCNTL1_SST_800 0x01 /* Start SCSI transfer */
-
-/* SCSI control 2 rw, */
-
-#define SCNTL2_REG_800 0x02
-#define SCNTL2_800_SDU 0x80 /* SCSI disconnect unexpected */
-
-/* SCSI control 3 rw */
-
-#define SCNTL3_REG_800 0x03
-#define SCNTL3_800_SCF_SHIFT 4
-#define SCNTL3_800_SCF_MASK 0x70
-#define SCNTL3_800_SCF2 0x40 /* Synchronous divisor */
-#define SCNTL3_800_SCF1 0x20 /* 0x00 = SCLK/3 */
-#define SCNTL3_800_SCF0 0x10 /* 0x10 = SCLK/1 */
- /* 0x20 = SCLK/1.5
- 0x30 = SCLK/2
- 0x40 = SCLK/3 */
-
-#define SCNTL3_800_CCF_SHIFT 0
-#define SCNTL3_800_CCF_MASK 0x07
-#define SCNTL3_800_CCF2 0x04 /* 0x00 50.01 to 66 */
-#define SCNTL3_800_CCF1 0x02 /* 0x01 16.67 to 25 */
-#define SCNTL3_800_CCF0 0x01 /* 0x02 25.01 - 37.5
- 0x03 37.51 - 50
- 0x04 50.01 - 66 */
-
-/*
- * SCSI destination ID rw - the appropriate bit is set for the selected
- * target ID. This is written by the SCSI SCRIPTS processor.
- * default = 0x00
- */
-#define SDID_REG_700 0x02
-#define SDID_REG_800 0x06
-
-#define GP_REG_800 0x07 /* General purpose IO */
-#define GP_800_IO1 0x02
-#define GP_800_IO2 0x01
-
-
-/* SCSI interrupt enable rw, default = 0x00 */
-#define SIEN_REG_700 0x03
-#define SIEN0_REG_800 0x40
-#define SIEN_MA 0x80 /* Phase mismatch (ini) or ATN (tgt) */
-#define SIEN_FC 0x40 /* Function complete */
-#define SIEN_700_STO 0x20 /* Selection or reselection timeout */
-#define SIEN_800_SEL 0x20 /* Selected */
-#define SIEN_700_SEL 0x10 /* Selected or reselected */
-#define SIEN_800_RESEL 0x10 /* Reselected */
-#define SIEN_SGE 0x08 /* SCSI gross error */
-#define SIEN_UDC 0x04 /* Unexpected disconnect */
-#define SIEN_RST 0x02 /* SCSI RST/ received */
-#define SIEN_PAR 0x01 /* Parity error */
-
-/*
- * SCSI chip ID rw
- * NCR53c700 :
- * When arbitrating, the highest bit is used, when reselection or selection
- * occurs, the chip responds to all IDs for which a bit is set.
- * default = 0x00
- * NCR53c810 :
- * Uses bit mapping
- */
-#define SCID_REG 0x04
-/* Bit 7 is reserved on 800 series chips */
-#define SCID_800_RRE 0x40 /* Enable response to reselection */
-#define SCID_800_SRE 0x20 /* Enable response to selection */
-/* Bits four and three are reserved on 800 series chips */
-#define SCID_800_ENC_MASK 0x07 /* Encoded SCSI ID */
-
-/* SCSI transfer rw, default = 0x00 */
-#define SXFER_REG 0x05
-#define SXFER_DHP 0x80 /* Disable halt on parity */
-
-#define SXFER_TP2 0x40 /* Transfer period msb */
-#define SXFER_TP1 0x20
-#define SXFER_TP0 0x10 /* lsb */
-#define SXFER_TP_MASK 0x70
-/* FIXME : SXFER_TP_SHIFT == 5 is right for '8xx chips */
-#define SXFER_TP_SHIFT 5
-#define SXFER_TP_4 0x00 /* Divisors */
-#define SXFER_TP_5 0x10<<1
-#define SXFER_TP_6 0x20<<1
-#define SXFER_TP_7 0x30<<1
-#define SXFER_TP_8 0x40<<1
-#define SXFER_TP_9 0x50<<1
-#define SXFER_TP_10 0x60<<1
-#define SXFER_TP_11 0x70<<1
-
-#define SXFER_MO3 0x08 /* Max offset msb */
-#define SXFER_MO2 0x04
-#define SXFER_MO1 0x02
-#define SXFER_MO0 0x01 /* lsb */
-#define SXFER_MO_MASK 0x0f
-#define SXFER_MO_SHIFT 0
-
-/*
- * SCSI output data latch rw
- * The contents of this register are driven onto the SCSI bus when
- * the Assert Data Bus bit of the SCNTL1 register is set and
- * the CD, IO, and MSG bits of the SOCL register match the SCSI phase
- */
-#define SODL_REG_700 0x06
-#define SODL_REG_800 0x54
-
-
-/*
- * SCSI output control latch rw, default = 0
- * Note that when the chip is being manually programmed as an initiator,
- * the MSG, CD, and IO bits must be set correctly for the phase the target
- * is driving the bus in. Otherwise no data transfer will occur due to
- * phase mismatch.
- */
-
-#define SBCL_REG 0x0b
-#define SBCL_REQ 0x80 /* REQ */
-#define SBCL_ACK 0x40 /* ACK */
-#define SBCL_BSY 0x20 /* BSY */
-#define SBCL_SEL 0x10 /* SEL */
-#define SBCL_ATN 0x08 /* ATN */
-#define SBCL_MSG 0x04 /* MSG */
-#define SBCL_CD 0x02 /* C/D */
-#define SBCL_IO 0x01 /* I/O */
-#define SBCL_PHASE_CMDOUT SBCL_CD
-#define SBCL_PHASE_DATAIN SBCL_IO
-#define SBCL_PHASE_DATAOUT 0
-#define SBCL_PHASE_MSGIN (SBCL_CD|SBCL_IO|SBCL_MSG)
-#define SBCL_PHASE_MSGOUT (SBCL_CD|SBCL_MSG)
-#define SBCL_PHASE_STATIN (SBCL_CD|SBCL_IO)
-#define SBCL_PHASE_MASK (SBCL_CD|SBCL_IO|SBCL_MSG)
-
-/*
- * SCSI first byte received latch ro
- * This register contains the first byte received during a block MOVE
- * SCSI SCRIPTS instruction, including
- *
- * Initiator mode Target mode
- * Message in Command
- * Status Message out
- * Data in Data out
- *
- * It also contains the selecting or reselecting device's ID and our
- * ID.
- *
- * Note that this is the register the various IF conditionals can
- * operate on.
- */
-#define SFBR_REG 0x08
-
-/*
- * SCSI input data latch ro
- * In initiator mode, data is latched into this register on the rising
- * edge of REQ/. In target mode, data is latched on the rising edge of
- * ACK/
- */
-#define SIDL_REG_700 0x09
-#define SIDL_REG_800 0x50
-
-/*
- * SCSI bus data lines ro
- * This register reflects the instantaneous status of the SCSI data
- * lines. Note that SCNTL0 must be set to disable parity checking,
- * otherwise reading this register will latch new parity.
- */
-#define SBDL_REG_700 0x0a
-#define SBDL_REG_800 0x58
-
-#define SSID_REG_800 0x0a
-#define SSID_800_VAL 0x80 /* Exactly two bits asserted at sel */
-#define SSID_800_ENCID_MASK 0x07 /* Device which performed operation */
-
-
-/*
- * SCSI bus control lines rw,
- * instantaneous readout of control lines
- */
-#define SOCL_REG 0x0b
-#define SOCL_REQ 0x80 /* REQ ro */
-#define SOCL_ACK 0x40 /* ACK ro */
-#define SOCL_BSY 0x20 /* BSY ro */
-#define SOCL_SEL 0x10 /* SEL ro */
-#define SOCL_ATN 0x08 /* ATN ro */
-#define SOCL_MSG 0x04 /* MSG ro */
-#define SOCL_CD 0x02 /* C/D ro */
-#define SOCL_IO 0x01 /* I/O ro */
-/*
- * Synchronous SCSI Clock Control bits
- * 0 - set by DCNTL
- * 1 - SCLK / 1.0
- * 2 - SCLK / 1.5
- * 3 - SCLK / 2.0
- */
-#define SBCL_SSCF1 0x02 /* wo, -66 only */
-#define SBCL_SSCF0 0x01 /* wo, -66 only */
-#define SBCL_SSCF_MASK 0x03
-
-/*
- * XXX note : when reading the DSTAT and STAT registers to clear interrupts,
- * insure that 10 clocks elapse between the two
- */
-/* DMA status ro */
-#define DSTAT_REG 0x0c
-#define DSTAT_DFE 0x80 /* DMA FIFO empty */
-#define DSTAT_800_MDPE 0x40 /* Master Data Parity Error */
-#define DSTAT_800_BF 0x20 /* Bus Fault */
-#define DSTAT_ABRT 0x10 /* Aborted - set on error */
-#define DSTAT_SSI 0x08 /* SCRIPTS single step interrupt */
-#define DSTAT_SIR 0x04 /* SCRIPTS interrupt received -
- set when INT instruction is
- executed */
-#define DSTAT_WTD 0x02 /* Watchdog timeout detected */
-#define DSTAT_OPC 0x01 /* Illegal instruction */
-#define DSTAT_800_IID 0x01 /* Same thing, different name */
-
-
-/* NCR53c800 moves this stuff into SIST0 */
-#define SSTAT0_REG 0x0d /* SCSI status 0 ro */
-#define SIST0_REG_800 0x42
-#define SSTAT0_MA 0x80 /* ini : phase mismatch,
- * tgt : ATN/ asserted
- */
-#define SSTAT0_CMP 0x40 /* function complete */
-#define SSTAT0_700_STO 0x20 /* Selection or reselection timeout */
-#define SIST0_800_SEL 0x20 /* Selected */
-#define SSTAT0_700_SEL 0x10 /* Selected or reselected */
-#define SIST0_800_RSL 0x10 /* Reselected */
-#define SSTAT0_SGE 0x08 /* SCSI gross error */
-#define SSTAT0_UDC 0x04 /* Unexpected disconnect */
-#define SSTAT0_RST 0x02 /* SCSI RST/ received */
-#define SSTAT0_PAR 0x01 /* Parity error */
-
-/* And uses SSTAT0 for what was SSTAT1 */
-
-#define SSTAT1_REG 0x0e /* SCSI status 1 ro */
-#define SSTAT1_ILF 0x80 /* SIDL full */
-#define SSTAT1_ORF 0x40 /* SODR full */
-#define SSTAT1_OLF 0x20 /* SODL full */
-#define SSTAT1_AIP 0x10 /* Arbitration in progress */
-#define SSTAT1_LOA 0x08 /* Lost arbitration */
-#define SSTAT1_WOA 0x04 /* Won arbitration */
-#define SSTAT1_RST 0x02 /* Instant readout of RST/ */
-#define SSTAT1_SDP 0x01 /* Instant readout of SDP/ */
-
-#define SSTAT2_REG 0x0f /* SCSI status 2 ro */
-#define SSTAT2_FF3 0x80 /* number of bytes in synchronous */
-#define SSTAT2_FF2 0x40 /* data FIFO */
-#define SSTAT2_FF1 0x20
-#define SSTAT2_FF0 0x10
-#define SSTAT2_FF_MASK 0xf0
-#define SSTAT2_FF_SHIFT 4
-
-/*
- * Latched signals, latched on the leading edge of REQ/ for initiators,
- * ACK/ for targets.
- */
-#define SSTAT2_SDP 0x08 /* SDP */
-#define SSTAT2_MSG 0x04 /* MSG */
-#define SSTAT2_CD 0x02 /* C/D */
-#define SSTAT2_IO 0x01 /* I/O */
-#define SSTAT2_PHASE_CMDOUT SSTAT2_CD
-#define SSTAT2_PHASE_DATAIN SSTAT2_IO
-#define SSTAT2_PHASE_DATAOUT 0
-#define SSTAT2_PHASE_MSGIN (SSTAT2_CD|SSTAT2_IO|SSTAT2_MSG)
-#define SSTAT2_PHASE_MSGOUT (SSTAT2_CD|SSTAT2_MSG)
-#define SSTAT2_PHASE_STATIN (SSTAT2_CD|SSTAT2_IO)
-#define SSTAT2_PHASE_MASK (SSTAT2_CD|SSTAT2_IO|SSTAT2_MSG)
-
-
-/* NCR53c700-66 only */
-#define SCRATCHA_REG_00 0x10 /* through 0x13 Scratch A rw */
-/* NCR53c710 and higher */
-#define DSA_REG 0x10 /* DATA structure address */
-
-#define CTEST0_REG_700 0x14 /* Chip test 0 ro */
-#define CTEST0_REG_800 0x18 /* Chip test 0 rw, general purpose */
-/* 0x80 - 0x04 are reserved */
-#define CTEST0_700_RTRG 0x02 /* Real target mode */
-#define CTEST0_700_DDIR 0x01 /* Data direction, 1 =
- * SCSI bus to host, 0 =
- * host to SCSI.
- */
-
-#define CTEST1_REG_700 0x15 /* Chip test 1 ro */
-#define CTEST1_REG_800 0x19 /* Chip test 1 ro */
-#define CTEST1_FMT3 0x80 /* Identify which byte lanes are empty */
-#define CTEST1_FMT2 0x40 /* in the DMA FIFO */
-#define CTEST1_FMT1 0x20
-#define CTEST1_FMT0 0x10
-
-#define CTEST1_FFL3 0x08 /* Identify which bytes lanes are full */
-#define CTEST1_FFL2 0x04 /* in the DMA FIFO */
-#define CTEST1_FFL1 0x02
-#define CTEST1_FFL0 0x01
-
-#define CTEST2_REG_700 0x16 /* Chip test 2 ro */
-#define CTEST2_REG_800 0x1a /* Chip test 2 ro */
-
-#define CTEST2_800_DDIR 0x80 /* 1 = SCSI->host */
-#define CTEST2_800_SIGP 0x40 /* A copy of SIGP in ISTAT.
- Reading this register clears */
-#define CTEST2_800_CIO 0x20 /* Configured as IO */.
-#define CTEST2_800_CM 0x10 /* Configured as memory */
-
-/* 0x80 - 0x40 are reserved on 700 series chips */
-#define CTEST2_700_SOFF 0x20 /* SCSI Offset Compare,
- * As an initiator, this bit is
- * one when the synchronous offset
- * is zero, as a target this bit
- * is one when the synchronous
- * offset is at the maximum
- * defined in SXFER
- */
-#define CTEST2_700_SFP 0x10 /* SCSI FIFO parity bit,
- * reading CTEST3 unloads a byte
- * from the FIFO and sets this
- */
-#define CTEST2_700_DFP 0x08 /* DMA FIFO parity bit,
- * reading CTEST6 unloads a byte
- * from the FIFO and sets this
- */
-#define CTEST2_TEOP 0x04 /* SCSI true end of process,
- * indicates a totally finished
- * transfer
- */
-#define CTEST2_DREQ 0x02 /* Data request signal */
-/* 0x01 is reserved on 700 series chips */
-#define CTEST2_800_DACK 0x01
-
-/*
- * Chip test 3 ro
- * Unloads the bottom byte of the eight deep SCSI synchronous FIFO,
- * check SSTAT2 FIFO full bits to determine size. Note that a GROSS
- * error results if a read is attempted on this register. Also note
- * that 16 and 32 bit reads of this register will cause corruption.
- */
-#define CTEST3_REG_700 0x17
-/* Chip test 3 rw */
-#define CTEST3_REG_800 0x1b
-#define CTEST3_800_V3 0x80 /* Chip revision */
-#define CTEST3_800_V2 0x40
-#define CTEST3_800_V1 0x20
-#define CTEST3_800_V0 0x10
-#define CTEST3_800_FLF 0x08 /* Flush DMA FIFO */
-#define CTEST3_800_CLF 0x04 /* Clear DMA FIFO */
-#define CTEST3_800_FM 0x02 /* Fetch mode pin */
-/* bit 0 is reserved on 800 series chips */
-
-#define CTEST4_REG_700 0x18 /* Chip test 4 rw */
-#define CTEST4_REG_800 0x21 /* Chip test 4 rw */
-/* 0x80 is reserved on 700 series chips */
-#define CTEST4_800_BDIS 0x80 /* Burst mode disable */
-#define CTEST4_ZMOD 0x40 /* High impedance mode */
-#define CTEST4_SZM 0x20 /* SCSI bus high impedance */
-#define CTEST4_700_SLBE 0x10 /* SCSI loopback enabled */
-#define CTEST4_800_SRTM 0x10 /* Shadow Register Test Mode */
-#define CTEST4_700_SFWR 0x08 /* SCSI FIFO write enable,
- * redirects writes from SODL
- * to the SCSI FIFO.
- */
-#define CTEST4_800_MPEE 0x08 /* Enable parity checking
- during master cycles on PCI
- bus */
-
-/*
- * These bits send the contents of the CTEST6 register to the appropriate
- * byte lane of the 32 bit DMA FIFO. Normal operation is zero, otherwise
- * the high bit means the low two bits select the byte lane.
- */
-#define CTEST4_FBL2 0x04
-#define CTEST4_FBL1 0x02
-#define CTEST4_FBL0 0x01
-#define CTEST4_FBL_MASK 0x07
-#define CTEST4_FBL_0 0x04 /* Select DMA FIFO byte lane 0 */
-#define CTEST4_FBL_1 0x05 /* Select DMA FIFO byte lane 1 */
-#define CTEST4_FBL_2 0x06 /* Select DMA FIFO byte lane 2 */
-#define CTEST4_FBL_3 0x07 /* Select DMA FIFO byte lane 3 */
-#define CTEST4_800_SAVE (CTEST4_800_BDIS)
-
-
-#define CTEST5_REG_700 0x19 /* Chip test 5 rw */
-#define CTEST5_REG_800 0x22 /* Chip test 5 rw */
-/*
- * Clock Address Incrementor. When set, it increments the
- * DNAD register to the next bus size boundary. It automatically
- * resets itself when the operation is complete.
- */
-#define CTEST5_ADCK 0x80
-/*
- * Clock Byte Counter. When set, it decrements the DBC register to
- * the next bus size boundary.
- */
-#define CTEST5_BBCK 0x40
-/*
- * Reset SCSI Offset. Setting this bit to 1 clears the current offset
- * pointer in the SCSI synchronous offset counter (SSTAT). This bit
- * is set to 1 if a SCSI Gross Error Condition occurs. The offset should
- * be cleared when a synchronous transfer fails. When written, it is
- * automatically cleared after the SCSI synchronous offset counter is
- * reset.
- */
-/* Bit 5 is reserved on 800 series chips */
-#define CTEST5_700_ROFF 0x20
-/*
- * Master Control for Set or Reset pulses. When 1, causes the low
- * four bits of register to set when set, 0 causes the low bits to
- * clear when set.
- */
-#define CTEST5_MASR 0x10
-#define CTEST5_DDIR 0x08 /* DMA direction */
-/*
- * Bits 2-0 are reserved on 800 series chips
- */
-#define CTEST5_700_EOP 0x04 /* End of process */
-#define CTEST5_700_DREQ 0x02 /* Data request */
-#define CTEST5_700_DACK 0x01 /* Data acknowledge */
-
-/*
- * Chip test 6 rw - writing to this register writes to the byte
- * lane in the DMA FIFO as determined by the FBL bits in the CTEST4
- * register.
- */
-#define CTEST6_REG_700 0x1a
-#define CTEST6_REG_800 0x23
-
-#define CTEST7_REG 0x1b /* Chip test 7 rw */
-/* 0x80 - 0x40 are reserved on NCR53c700 and NCR53c700-66 chips */
-#define CTEST7_10_CDIS 0x80 /* Cache burst disable */
-#define CTEST7_10_SC1 0x40 /* Snoop control bits */
-#define CTEST7_10_SC0 0x20
-#define CTEST7_10_SC_MASK 0x60
-/* 0x20 is reserved on the NCR53c700 */
-#define CTEST7_0060_FM 0x20 /* Fetch mode */
-#define CTEST7_STD 0x10 /* Selection timeout disable */
-#define CTEST7_DFP 0x08 /* DMA FIFO parity bit for CTEST6 */
-#define CTEST7_EVP 0x04 /* 1 = host bus even parity, 0 = odd */
-#define CTEST7_10_TT1 0x02 /* Transfer type */
-#define CTEST7_00_DC 0x02 /* Set to drive DC low during instruction
- fetch */
-#define CTEST7_DIFF 0x01 /* Differential mode */
-
-#define CTEST7_SAVE ( CTEST7_EVP | CTEST7_DIFF )
-
-
-#define TEMP_REG 0x1c /* through 0x1f Temporary stack rw */
-
-#define DFIFO_REG 0x20 /* DMA FIFO rw */
-/*
- * 0x80 is reserved on the NCR53c710, the CLF and FLF bits have been
- * moved into the CTEST8 register.
- */
-#define DFIFO_00_FLF 0x80 /* Flush DMA FIFO to memory */
-#define DFIFO_00_CLF 0x40 /* Clear DMA and SCSI FIFOs */
-#define DFIFO_BO6 0x40
-#define DFIFO_BO5 0x20
-#define DFIFO_BO4 0x10
-#define DFIFO_BO3 0x08
-#define DFIFO_BO2 0x04
-#define DFIFO_BO1 0x02
-#define DFIFO_BO0 0x01
-#define DFIFO_10_BO_MASK 0x7f /* 7 bit counter */
-#define DFIFO_00_BO_MASK 0x3f /* 6 bit counter */
-
-/*
- * Interrupt status rw
- * Note that this is the only register which can be read while SCSI
- * SCRIPTS are being executed.
- */
-#define ISTAT_REG_700 0x21
-#define ISTAT_REG_800 0x14
-#define ISTAT_ABRT 0x80 /* Software abort, write
- *1 to abort, wait for interrupt. */
-/* 0x40 and 0x20 are reserved on NCR53c700 and NCR53c700-66 chips */
-#define ISTAT_10_SRST 0x40 /* software reset */
-#define ISTAT_10_SIGP 0x20 /* signal script */
-/* 0x10 is reserved on NCR53c700 series chips */
-#define ISTAT_800_SEM 0x10 /* semaphore */
-#define ISTAT_CON 0x08 /* 1 when connected */
-#define ISTAT_800_INTF 0x04 /* Interrupt on the fly */
-#define ISTAT_700_PRE 0x04 /* Pointer register empty.
- * Set to 1 when DSPS and DSP
- * registers are empty in pipeline
- * mode, always set otherwise.
- */
-#define ISTAT_SIP 0x02 /* SCSI interrupt pending from
- * SCSI portion of SIOP see
- * SSTAT0
- */
-#define ISTAT_DIP 0x01 /* DMA interrupt pending
- * see DSTAT
- */
-
-/* NCR53c700-66 and NCR53c710 only */
-#define CTEST8_REG 0x22 /* Chip test 8 rw */
-#define CTEST8_0066_EAS 0x80 /* Enable alternate SCSI clock,
- * ie read from SCLK/ rather than CLK/
- */
-#define CTEST8_0066_EFM 0x40 /* Enable fetch and master outputs */
-#define CTEST8_0066_GRP 0x20 /* Generate Receive Parity for
- * pass through. This insures that
- * bad parity won't reach the host
- * bus.
- */
-#define CTEST8_0066_TE 0x10 /* TolerANT enable. Enable
- * active negation, should only
- * be used for slow SCSI
- * non-differential.
- */
-#define CTEST8_0066_HSC 0x08 /* Halt SCSI clock */
-#define CTEST8_0066_SRA 0x04 /* Shorten REQ/ACK filtering,
- * must be set for fast SCSI-II
- * speeds.
- */
-#define CTEST8_0066_DAS 0x02 /* Disable automatic target/initiator
- * switching.
- */
-#define CTEST8_0066_LDE 0x01 /* Last disconnect enable.
- * The status of pending
- * disconnect is maintained by
- * the core, eliminating
- * the possibility of missing a
- * selection or reselection
- * while waiting to fetch a
- * WAIT DISCONNECT opcode.
- */
-
-#define CTEST8_10_V3 0x80 /* Chip revision */
-#define CTEST8_10_V2 0x40
-#define CTEST8_10_V1 0x20
-#define CTEST8_10_V0 0x10
-#define CTEST8_10_V_MASK 0xf0
-#define CTEST8_10_FLF 0x08 /* Flush FIFOs */
-#define CTEST8_10_CLF 0x04 /* Clear FIFOs */
-#define CTEST8_10_FM 0x02 /* Fetch pin mode */
-#define CTEST8_10_SM 0x01 /* Snoop pin mode */
-
-
-/*
- * The CTEST9 register may be used to differentiate between a
- * NCR53c700 and a NCR53c710.
- *
- * Write 0xff to this register.
- * Read it.
- * If the contents are 0xff, it is a NCR53c700
- * If the contents are 0x00, it is a NCR53c700-66 first revision
- * If the contents are some other value, it is some other NCR53c700-66
- */
-#define CTEST9_REG_00 0x23 /* Chip test 9 ro */
-#define LCRC_REG_10 0x23
-
-/*
- * 0x24 through 0x27 are the DMA byte counter register. Instructions
- * write their high 8 bits into the DCMD register, the low 24 bits into
- * the DBC register.
- *
- * Function is dependent on the command type being executed.
- */
-
-
-#define DBC_REG 0x24
-/*
- * For Block Move Instructions, DBC is a 24 bit quantity representing
- * the number of bytes to transfer.
- * For Transfer Control Instructions, DBC is bit fielded as follows :
- */
-/* Bits 20 - 23 should be clear */
-#define DBC_TCI_TRUE (1 << 19) /* Jump when true */
-#define DBC_TCI_COMPARE_DATA (1 << 18) /* Compare data */
-#define DBC_TCI_COMPARE_PHASE (1 << 17) /* Compare phase with DCMD field */
-#define DBC_TCI_WAIT_FOR_VALID (1 << 16) /* Wait for REQ */
-/* Bits 8 - 15 are reserved on some implementations ? */
-#define DBC_TCI_MASK_MASK 0xff00 /* Mask for data compare */
-#define DBC_TCI_MASK_SHIFT 8
-#define DBC_TCI_DATA_MASK 0xff /* Data to be compared */
-#define DBC_TCI_DATA_SHIFT 0
-
-#define DBC_RWRI_IMMEDIATE_MASK 0xff00 /* Immediate data */
-#define DBC_RWRI_IMMEDIATE_SHIFT 8 /* Amount to shift */
-#define DBC_RWRI_ADDRESS_MASK 0x3f0000 /* Register address */
-#define DBC_RWRI_ADDRESS_SHIFT 16
-
-
-/*
- * DMA command r/w
- */
-#define DCMD_REG 0x27
-#define DCMD_TYPE_MASK 0xc0 /* Masks off type */
-#define DCMD_TYPE_BMI 0x00 /* Indicates a Block Move instruction */
-#define DCMD_BMI_IO 0x01 /* I/O, CD, and MSG bits selecting */
-#define DCMD_BMI_CD 0x02 /* the phase for the block MOVE */
-#define DCMD_BMI_MSG 0x04 /* instruction */
-
-#define DCMD_BMI_OP_MASK 0x18 /* mask for opcode */
-#define DCMD_BMI_OP_MOVE_T 0x00 /* MOVE */
-#define DCMD_BMI_OP_MOVE_I 0x08 /* MOVE Initiator */
-
-#define DCMD_BMI_INDIRECT 0x20 /* Indirect addressing */
-
-#define DCMD_TYPE_TCI 0x80 /* Indicates a Transfer Control
- instruction */
-#define DCMD_TCI_IO 0x01 /* I/O, CD, and MSG bits selecting */
-#define DCMD_TCI_CD 0x02 /* the phase for the block MOVE */
-#define DCMD_TCI_MSG 0x04 /* instruction */
-#define DCMD_TCI_OP_MASK 0x38 /* mask for opcode */
-#define DCMD_TCI_OP_JUMP 0x00 /* JUMP */
-#define DCMD_TCI_OP_CALL 0x08 /* CALL */
-#define DCMD_TCI_OP_RETURN 0x10 /* RETURN */
-#define DCMD_TCI_OP_INT 0x18 /* INT */
-
-#define DCMD_TYPE_RWRI 0x40 /* Indicates I/O or register Read/Write
- instruction */
-#define DCMD_RWRI_OPC_MASK 0x38 /* Opcode mask */
-#define DCMD_RWRI_OPC_WRITE 0x28 /* Write SFBR to register */
-#define DCMD_RWRI_OPC_READ 0x30 /* Read register to SFBR */
-#define DCMD_RWRI_OPC_MODIFY 0x38 /* Modify in place */
-
-#define DCMD_RWRI_OP_MASK 0x07
-#define DCMD_RWRI_OP_MOVE 0x00
-#define DCMD_RWRI_OP_SHL 0x01
-#define DCMD_RWRI_OP_OR 0x02
-#define DCMD_RWRI_OP_XOR 0x03
-#define DCMD_RWRI_OP_AND 0x04
-#define DCMD_RWRI_OP_SHR 0x05
-#define DCMD_RWRI_OP_ADD 0x06
-#define DCMD_RWRI_OP_ADDC 0x07
-
-#define DCMD_TYPE_MMI 0xc0 /* Indicates a Memory Move instruction
- (three words) */
-
-
-#define DNAD_REG 0x28 /* through 0x2b DMA next address for
- data */
-#define DSP_REG 0x2c /* through 0x2f DMA SCRIPTS pointer rw */
-#define DSPS_REG 0x30 /* through 0x33 DMA SCRIPTS pointer
- save rw */
-#define DMODE_REG_00 0x34 /* DMA mode rw */
-#define DMODE_00_BL1 0x80 /* Burst length bits */
-#define DMODE_00_BL0 0x40
-#define DMODE_BL_MASK 0xc0
-/* Burst lengths (800) */
-#define DMODE_BL_2 0x00 /* 2 transfer */
-#define DMODE_BL_4 0x40 /* 4 transfers */
-#define DMODE_BL_8 0x80 /* 8 transfers */
-#define DMODE_BL_16 0xc0 /* 16 transfers */
-
-#define DMODE_700_BW16 0x20 /* Host buswidth = 16 */
-#define DMODE_700_286 0x10 /* 286 mode */
-#define DMODE_700_IOM 0x08 /* Transfer to IO port */
-#define DMODE_700_FAM 0x04 /* Fixed address mode */
-#define DMODE_700_PIPE 0x02 /* Pipeline mode disables
- * automatic fetch / exec
- */
-#define DMODE_MAN 0x01 /* Manual start mode,
- * requires a 1 to be written
- * to the start DMA bit in the DCNTL
- * register to run scripts
- */
-
-#define DMODE_700_SAVE ( DMODE_00_BL_MASK | DMODE_00_BW16 | DMODE_00_286 )
-
-/* NCR53c800 series only */
-#define SCRATCHA_REG_800 0x34 /* through 0x37 Scratch A rw */
-/* NCR53c710 only */
-#define SCRATCB_REG_10 0x34 /* through 0x37 scratch B rw */
-
-#define DMODE_REG_10 0x38 /* DMA mode rw, NCR53c710 and newer */
-#define DMODE_800_SIOM 0x20 /* Source IO = 1 */
-#define DMODE_800_DIOM 0x10 /* Destination IO = 1 */
-#define DMODE_800_ERL 0x08 /* Enable Read Line */
-
-/* 35-38 are reserved on 700 and 700-66 series chips */
-#define DIEN_REG 0x39 /* DMA interrupt enable rw */
-/* 0x80, 0x40, and 0x20 are reserved on 700-series chips */
-#define DIEN_800_MDPE 0x40 /* Master data parity error */
-#define DIEN_800_BF 0x20 /* BUS fault */
-#define DIEN_ABRT 0x10 /* Enable aborted interrupt */
-#define DIEN_SSI 0x08 /* Enable single step interrupt */
-#define DIEN_SIR 0x04 /* Enable SCRIPTS INT command
- * interrupt
- */
-/* 0x02 is reserved on 800 series chips */
-#define DIEN_700_WTD 0x02 /* Enable watchdog timeout interrupt */
-#define DIEN_700_OPC 0x01 /* Enable illegal instruction
- * interrupt
- */
-#define DIEN_800_IID 0x01 /* Same meaning, different name */
-
-/*
- * DMA watchdog timer rw
- * set in 16 CLK input periods.
- */
-#define DWT_REG 0x3a
-
-/* DMA control rw */
-#define DCNTL_REG 0x3b
-#define DCNTL_700_CF1 0x80 /* Clock divisor bits */
-#define DCNTL_700_CF0 0x40
-#define DCNTL_700_CF_MASK 0xc0
-/* Clock divisors Divisor SCLK range (MHZ) */
-#define DCNTL_700_CF_2 0x00 /* 2.0 37.51-50.00 */
-#define DCNTL_700_CF_1_5 0x40 /* 1.5 25.01-37.50 */
-#define DCNTL_700_CF_1 0x80 /* 1.0 16.67-25.00 */
-#define DCNTL_700_CF_3 0xc0 /* 3.0 50.01-66.67 (53c700-66) */
-
-#define DCNTL_700_S16 0x20 /* Load scripts 16 bits at a time */
-#define DCNTL_SSM 0x10 /* Single step mode */
-#define DCNTL_700_LLM 0x08 /* Low level mode, can only be set
- * after selection */
-#define DCNTL_800_IRQM 0x08 /* Totem pole IRQ pin */
-#define DCNTL_STD 0x04 /* Start DMA / SCRIPTS */
-/* 0x02 is reserved */
-#define DCNTL_00_RST 0x01 /* Software reset, resets everything
- * but 286 mode bit in DMODE. On the
- * NCR53c710, this bit moved to CTEST8
- */
-#define DCNTL_10_COM 0x01 /* 700 software compatibility mode */
-
-#define DCNTL_700_SAVE ( DCNTL_CF_MASK | DCNTL_S16)
-
-
-/* NCR53c700-66 only */
-#define SCRATCHB_REG_00 0x3c /* through 0x3f scratch b rw */
-#define SCRATCHB_REG_800 0x5c /* through 0x5f scratch b rw */
-/* NCR53c710 only */
-#define ADDER_REG_10 0x3c /* Adder, NCR53c710 only */
-
-#define SIEN1_REG_800 0x41
-#define SIEN1_800_STO 0x04 /* selection/reselection timeout */
-#define SIEN1_800_GEN 0x02 /* general purpose timer */
-#define SIEN1_800_HTH 0x01 /* handshake to handshake */
-
-#define SIST1_REG_800 0x43
-#define SIST1_800_STO 0x04 /* selection/reselection timeout */
-#define SIST1_800_GEN 0x02 /* general purpose timer */
-#define SIST1_800_HTH 0x01 /* handshake to handshake */
-
-#define SLPAR_REG_800 0x44 /* Parity */
-
-#define MACNTL_REG_800 0x46 /* Memory access control */
-#define MACNTL_800_TYP3 0x80
-#define MACNTL_800_TYP2 0x40
-#define MACNTL_800_TYP1 0x20
-#define MACNTL_800_TYP0 0x10
-#define MACNTL_800_DWR 0x08
-#define MACNTL_800_DRD 0x04
-#define MACNTL_800_PSCPT 0x02
-#define MACNTL_800_SCPTS 0x01
-
-#define GPCNTL_REG_800 0x47 /* General Purpose Pin Control */
-
-/* Timeouts are expressed such that 0=off, 1=100us, doubling after that */
-#define STIME0_REG_800 0x48 /* SCSI Timer Register 0 */
-#define STIME0_800_HTH_MASK 0xf0 /* Handshake to Handshake timeout */
-#define STIME0_800_HTH_SHIFT 4
-#define STIME0_800_SEL_MASK 0x0f /* Selection timeout */
-#define STIME0_800_SEL_SHIFT 0
-
-#define STIME1_REG_800 0x49
-#define STIME1_800_GEN_MASK 0x0f /* General purpose timer */
-
-#define RESPID_REG_800 0x4a /* Response ID, bit fielded. 8
- bits on narrow chips, 16 on WIDE */
-
-#define STEST0_REG_800 0x4c
-#define STEST0_800_SLT 0x08 /* Selection response logic test */
-#define STEST0_800_ART 0x04 /* Arbitration priority encoder test */
-#define STEST0_800_SOZ 0x02 /* Synchronous offset zero */
-#define STEST0_800_SOM 0x01 /* Synchronous offset maximum */
-
-#define STEST1_REG_800 0x4d
-#define STEST1_800_SCLK 0x80 /* Disable SCSI clock */
-
-#define STEST2_REG_800 0x4e
-#define STEST2_800_SCE 0x80 /* Enable SOCL/SODL */
-#define STEST2_800_ROF 0x40 /* Reset SCSI sync offset */
-#define STEST2_800_SLB 0x10 /* Enable SCSI loopback mode */
-#define STEST2_800_SZM 0x08 /* SCSI high impedance mode */
-#define STEST2_800_EXT 0x02 /* Extend REQ/ACK filter 30 to 60ns */
-#define STEST2_800_LOW 0x01 /* SCSI low level mode */
-
-#define STEST3_REG_800 0x4f
-#define STEST3_800_TE 0x80 /* Enable active negation */
-#define STEST3_800_STR 0x40 /* SCSI FIFO test read */
-#define STEST3_800_HSC 0x20 /* Halt SCSI clock */
-#define STEST3_800_DSI 0x10 /* Disable single initiator response */
-#define STEST3_800_TTM 0x04 /* Time test mode */
-#define STEST3_800_CSF 0x02 /* Clear SCSI FIFO */
-#define STEST3_800_STW 0x01 /* SCSI FIFO test write */
-
-#define OPTION_PARITY 0x1 /* Enable parity checking */
-#define OPTION_TAGGED_QUEUE 0x2 /* Enable SCSI-II tagged queuing */
-#define OPTION_700 0x8 /* Always run NCR53c700 scripts */
-#define OPTION_INTFLY 0x10 /* Use INTFLY interrupts */
-#define OPTION_DEBUG_INTR 0x20 /* Debug interrupts */
-#define OPTION_DEBUG_INIT_ONLY 0x40 /* Run initialization code and
- simple test code, return
- DID_NO_CONNECT if any SCSI
- commands are attempted. */
-#define OPTION_DEBUG_READ_ONLY 0x80 /* Return DID_ERROR if any
- SCSI write is attempted */
-#define OPTION_DEBUG_TRACE 0x100 /* Animated trace mode, print
- each address and instruction
- executed to debug buffer. */
-#define OPTION_DEBUG_SINGLE 0x200 /* stop after executing one
- instruction */
-#define OPTION_SYNCHRONOUS 0x400 /* Enable sync SCSI. */
-#define OPTION_MEMORY_MAPPED 0x800 /* NCR registers have valid
- memory mapping */
-#define OPTION_IO_MAPPED 0x1000 /* NCR registers have valid
- I/O mapping */
-#define OPTION_DEBUG_PROBE_ONLY 0x2000 /* Probe only, don't even init */
-#define OPTION_DEBUG_TESTS_ONLY 0x4000 /* Probe, init, run selected tests */
-#define OPTION_DEBUG_TEST0 0x08000 /* Run test 0 */
-#define OPTION_DEBUG_TEST1 0x10000 /* Run test 1 */
-#define OPTION_DEBUG_TEST2 0x20000 /* Run test 2 */
-#define OPTION_DEBUG_DUMP 0x40000 /* Dump commands */
-#define OPTION_DEBUG_TARGET_LIMIT 0x80000 /* Only talk to target+luns specified */
-#define OPTION_DEBUG_NCOMMANDS_LIMIT 0x100000 /* Limit the number of commands */
-#define OPTION_DEBUG_SCRIPT 0x200000 /* Print when checkpoints are passed */
-#define OPTION_DEBUG_FIXUP 0x400000 /* print fixup values */
-#define OPTION_DEBUG_DSA 0x800000
-#define OPTION_DEBUG_CORRUPTION 0x1000000 /* Detect script corruption */
-#define OPTION_DEBUG_SDTR 0x2000000 /* Debug SDTR problem */
-#define OPTION_DEBUG_MISMATCH 0x4000000 /* Debug phase mismatches */
-#define OPTION_DISCONNECT 0x8000000 /* Allow disconect */
-#define OPTION_DEBUG_DISCONNECT 0x10000000
-#define OPTION_ALWAYS_SYNCHRONOUS 0x20000000 /* Negotiate sync. transfers
- on power up */
-#define OPTION_DEBUG_QUEUES 0x80000000
-#define OPTION_DEBUG_ALLOCATION 0x100000000LL
-#define OPTION_DEBUG_SYNCHRONOUS 0x200000000LL /* Sanity check SXFER and
- SCNTL3 registers */
-#define OPTION_NO_ASYNC 0x400000000LL /* Don't automagically send
- SDTR for async transfers when
- we haven't been told to do
- a synchronous transfer. */
-#define OPTION_NO_PRINT_RACE 0x800000000LL /* Don't print message when
- the reselect/WAIT DISCONNECT
- race condition hits */
-#if !defined(PERM_OPTIONS)
-#define PERM_OPTIONS 0
-#endif
-
-struct NCR53c7x0_synchronous {
- u32 select_indirect; /* Value used for indirect selection */
- u32 script[8]; /* Size ?? Script used when target is
- reselected */
- unsigned char synchronous_want[5]; /* Per target desired SDTR */
-/*
- * Set_synchronous programs these, select_indirect and current settings after
- * int_debug_should show a match.
- */
- unsigned char sxfer_sanity, scntl3_sanity;
-};
-
-#define CMD_FLAG_SDTR 1 /* Initiating synchronous
- transfer negotiation */
-#define CMD_FLAG_WDTR 2 /* Initiating wide transfer
- negotiation */
-#define CMD_FLAG_DID_SDTR 4 /* did SDTR */
-#define CMD_FLAG_DID_WDTR 8 /* did WDTR */
-
-struct NCR53c7x0_table_indirect {
- u32 count;
- void *address;
-};
-
-enum ncr_event {
- EVENT_NONE = 0,
-/*
- * Order is IMPORTANT, since these must correspond to the event interrupts
- * in 53c7,8xx.scr
- */
-
- EVENT_ISSUE_QUEUE = 0x5000000, /* Command was added to issue queue */
- EVENT_START_QUEUE, /* Command moved to start queue */
- EVENT_SELECT, /* Command completed selection */
- EVENT_DISCONNECT, /* Command disconnected */
- EVENT_RESELECT, /* Command reselected */
- EVENT_COMPLETE, /* Command completed */
- EVENT_IDLE,
- EVENT_SELECT_FAILED,
- EVENT_BEFORE_SELECT,
- EVENT_RESELECT_FAILED
-};
-
-struct NCR53c7x0_event {
- enum ncr_event event; /* What type of event */
- unsigned char target;
- unsigned char lun;
- struct timeval time;
- u32 *dsa; /* What's in the DSA register now (virt) */
-/*
- * A few things from that SCSI pid so we know what happened after
- * the Scsi_Cmnd structure in question may have disappeared.
- */
- unsigned long pid; /* The SCSI PID which caused this
- event */
- unsigned char cmnd[12];
-};
-
-/*
- * Things in the NCR53c7x0_cmd structure are split into two parts :
- *
- * 1. A fixed portion, for things which are not accessed directly by static NCR
- * code (ie, are referenced only by the Linux side of the driver,
- * or only by dynamically genreated code).
- *
- * 2. The DSA portion, for things which are accessed directly by static NCR
- * code.
- *
- * This is a little ugly, but it
- * 1. Avoids conflicts between the NCR code's picture of the structure, and
- * Linux code's idea of what it looks like.
- *
- * 2. Minimizes the pain in the Linux side of the code needed
- * to calculate real dsa locations for things, etc.
- *
- */
-
-struct NCR53c7x0_cmd {
- void *real; /* Real, unaligned address for
- free function */
- void (* free)(void *, int); /* Command to deallocate; NULL
- for structures allocated with
- scsi_register, etc. */
- Scsi_Cmnd *cmd; /* Associated Scsi_Cmnd
- structure, Scsi_Cmnd points
- at NCR53c7x0_cmd using
- host_scribble structure */
-
- int size; /* scsi_malloc'd size of this
- structure */
-
- int flags; /* CMD_* flags */
-
-/*
- * SDTR and WIDE messages are an either/or affair
- * in this message, since we will go into message out and send
- * _the whole mess_ without dropping out of message out to
- * let the target go into message in after sending the first
- * message.
- */
-
- unsigned char select[11]; /* Select message, includes
- IDENTIFY
- (optional) QUEUE TAG
- (optional) SDTR or WDTR
- */
-
-
- volatile struct NCR53c7x0_cmd *next; /* Linux maintained lists (free,
- running, eventually finished */
-
-
- u32 *data_transfer_start; /* Start of data transfer routines */
- u32 *data_transfer_end; /* Address after end of data transfer o
- routines */
-/*
- * The following three fields were moved from the DSA propper to here
- * since only dynamically generated NCR code refers to them, meaning
- * we don't need dsa_* absolutes, and it is simpler to let the
- * host code refer to them directly.
- */
-
-/*
- * HARD CODED : residual and saved_residual need to agree with the sizes
- * used in NCR53c7,8xx.scr.
- *
- * FIXME: we want to consider the case where we have odd-length
- * scatter/gather buffers and a WIDE transfer, in which case
- * we'll need to use the CHAIN MOVE instruction. Ick.
- */
- u32 residual[6]; /* Residual data transfer which
- allows pointer code to work
- right.
-
- [0-1] : Conditional call to
- appropriate other transfer
- routine.
- [2-3] : Residual block transfer
- instruction.
- [4-5] : Jump to instruction
- after splice.
- */
- u32 saved_residual[6]; /* Copy of old residual, so we
- can get another partial
- transfer and still recover
- */
-
- u32 saved_data_pointer; /* Saved data pointer */
-
- u32 dsa_next_addr; /* _Address_ of dsa_next field
- in this dsa for RISCy
- style constant. */
-
- u32 dsa_addr; /* Address of dsa; RISCy style
- constant */
-
- u32 dsa[0]; /* Variable length (depending
- on host type, number of scatter /
- gather buffers, etc). */
-};
-
-struct NCR53c7x0_break {
- u32 *address, old_instruction[2];
- struct NCR53c7x0_break *next;
- unsigned char old_size; /* Size of old instruction */
-};
-
-/* Indicates that the NCR is not executing code */
-#define STATE_HALTED 0
-/*
- * Indicates that the NCR is executing the wait for select / reselect
- * script. Only used when running NCR53c700 compatible scripts, only
- * state during which an ABORT is _not_ considered an error condition.
- */
-#define STATE_WAITING 1
-/* Indicates that the NCR is executing other code. */
-#define STATE_RUNNING 2
-/*
- * Indicates that the NCR was being aborted.
- */
-#define STATE_ABORTING 3
-/* Indicates that the NCR was successfully aborted. */
-#define STATE_ABORTED 4
-/* Indicates that the NCR has been disabled due to a fatal error */
-#define STATE_DISABLED 5
-
-/*
- * Where knowledge of SCSI SCRIPT(tm) specified values are needed
- * in an interrupt handler, an interrupt handler exists for each
- * different SCSI script so we don't have name space problems.
- *
- * Return values of these handlers are as follows :
- */
-#define SPECIFIC_INT_NOTHING 0 /* don't even restart */
-#define SPECIFIC_INT_RESTART 1 /* restart at the next instruction */
-#define SPECIFIC_INT_ABORT 2 /* recoverable error, abort cmd */
-#define SPECIFIC_INT_PANIC 3 /* unrecoverable error, panic */
-#define SPECIFIC_INT_DONE 4 /* normal command completion */
-#define SPECIFIC_INT_BREAK 5 /* break point encountered */
-
-struct NCR53c7x0_hostdata {
- int size; /* Size of entire Scsi_Host
- structure */
- int board; /* set to board type, useful if
- we have host specific things,
- ie, a general purpose I/O
- bit is being used to enable
- termination, etc. */
-
- int chip; /* set to chip type; 700-66 is
- 700-66, rest are last three
- digits of part number */
- /*
- * PCI bus, device, function, only for NCR53c8x0 chips.
- * pci_valid indicates that the PCI configuration information
- * is valid, and we can twiddle MAX_LAT, etc. as recommended
- * for maximum performance in the NCR documentation.
- */
- unsigned char pci_bus, pci_device_fn;
- unsigned pci_valid:1;
-
- u32 *dsp; /* dsp to restart with after
- all stacked interrupts are
- handled. */
-
- unsigned dsp_changed:1; /* Has dsp changed within this
- set of stacked interrupts ? */
-
- unsigned char dstat; /* Most recent value of dstat */
- unsigned dstat_valid:1;
-
- unsigned expecting_iid:1; /* Expect IID interrupt */
- unsigned expecting_sto:1; /* Expect STO interrupt */
-
- /*
- * The code stays cleaner if we use variables with function
- * pointers and offsets that are unique for the different
- * scripts rather than having a slew of switch(hostdata->chip)
- * statements.
- *
- * It also means that the #defines from the SCSI SCRIPTS(tm)
- * don't have to be visible outside of the script-specific
- * instructions, preventing name space pollution.
- */
-
- void (* init_fixup)(struct Scsi_Host *host);
- void (* init_save_regs)(struct Scsi_Host *host);
- void (* dsa_fixup)(struct NCR53c7x0_cmd *cmd);
- void (* soft_reset)(struct Scsi_Host *host);
- int (* run_tests)(struct Scsi_Host *host);
-
- /*
- * Called when DSTAT_SIR is set, indicating an interrupt generated
- * by the INT instruction, where values are unique for each SCSI
- * script. Should return one of the SPEC_* values.
- */
-
- int (* dstat_sir_intr)(struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd);
-
- int dsa_len; /* Size of DSA structure */
-
- /*
- * Location of DSA fields for the SCSI SCRIPT corresponding to this
- * chip.
- */
-
- s32 dsa_start;
- s32 dsa_end;
- s32 dsa_next;
- s32 dsa_prev;
- s32 dsa_cmnd;
- s32 dsa_select;
- s32 dsa_msgout;
- s32 dsa_cmdout;
- s32 dsa_dataout;
- s32 dsa_datain;
- s32 dsa_msgin;
- s32 dsa_msgout_other;
- s32 dsa_write_sync;
- s32 dsa_write_resume;
- s32 dsa_check_reselect;
- s32 dsa_status;
- s32 dsa_saved_pointer;
- s32 dsa_jump_dest;
-
- /*
- * Important entry points that generic fixup code needs
- * to know about, fixed up.
- */
-
- s32 E_accept_message;
- s32 E_command_complete;
- s32 E_data_transfer;
- s32 E_dsa_code_template;
- s32 E_dsa_code_template_end;
- s32 E_end_data_transfer;
- s32 E_msg_in;
- s32 E_initiator_abort;
- s32 E_other_transfer;
- s32 E_other_in;
- s32 E_other_out;
- s32 E_target_abort;
- s32 E_debug_break;
- s32 E_reject_message;
- s32 E_respond_message;
- s32 E_select;
- s32 E_select_msgout;
- s32 E_test_0;
- s32 E_test_1;
- s32 E_test_2;
- s32 E_test_3;
- s32 E_dsa_zero;
- s32 E_cmdout_cmdout;
- s32 E_wait_reselect;
- s32 E_dsa_code_begin;
-
- long long options; /* Bitfielded set of options enabled */
- volatile u32 test_completed; /* Test completed */
- int test_running; /* Test currently running */
- s32 test_source;
- volatile s32 test_dest;
-
- volatile int state; /* state of driver, only used for
- OPTION_700 */
-
- unsigned char dmode; /*
- * set to the address of the DMODE
- * register for this chip.
- */
- unsigned char istat; /*
- * set to the address of the ISTAT
- * register for this chip.
- */
-
- int scsi_clock; /*
- * SCSI clock in HZ. 0 may be used
- * for unknown, although this will
- * disable synchronous negotiation.
- */
-
- volatile int intrs; /* Number of interrupts */
- volatile int resets; /* Number of SCSI resets */
- unsigned char saved_dmode;
- unsigned char saved_ctest4;
- unsigned char saved_ctest7;
- unsigned char saved_dcntl;
- unsigned char saved_scntl3;
-
- unsigned char this_id_mask;
-
- /* Debugger information */
- struct NCR53c7x0_break *breakpoints, /* Linked list of all break points */
- *breakpoint_current; /* Current breakpoint being stepped
- through, NULL if we are running
- normally. */
-#ifdef NCR_DEBUG
- int debug_size; /* Size of debug buffer */
- volatile int debug_count; /* Current data count */
- volatile char *debug_buf; /* Output ring buffer */
- volatile char *debug_write; /* Current write pointer */
- volatile char *debug_read; /* Current read pointer */
-#endif /* def NCR_DEBUG */
-
- /* XXX - primitive debugging junk, remove when working ? */
- int debug_print_limit; /* Number of commands to print
- out exhaustive debugging
- information for if
- OPTION_DEBUG_DUMP is set */
-
- unsigned char debug_lun_limit[16]; /* If OPTION_DEBUG_TARGET_LIMIT
- set, puke if commands are sent
- to other target/lun combinations */
-
- int debug_count_limit; /* Number of commands to execute
- before puking to limit debugging
- output */
-
-
- volatile unsigned idle:1; /* set to 1 if idle */
-
- /*
- * Table of synchronous+wide transfer parameters set on a per-target
- * basis.
- */
-
- volatile struct NCR53c7x0_synchronous sync[16];
-
- volatile Scsi_Cmnd *issue_queue;
- /* waiting to be issued by
- Linux driver */
- volatile struct NCR53c7x0_cmd *running_list;
- /* commands running, maintained
- by Linux driver */
-
- volatile struct NCR53c7x0_cmd *current; /* currently connected
- nexus, ONLY valid for
- NCR53c700/NCR53c700-66
- */
-
- volatile struct NCR53c7x0_cmd *spare; /* pointer to spare,
- allocated at probe time,
- which we can use for
- initialization */
- volatile struct NCR53c7x0_cmd *free;
- int max_cmd_size; /* Maximum size of NCR53c7x0_cmd
- based on number of
- scatter/gather segments, etc.
- */
- volatile int num_cmds; /* Number of commands
- allocated */
- volatile int extra_allocate;
- volatile unsigned char cmd_allocated[16]; /* Have we allocated commands
- for this target yet? If not,
- do so ASAP */
- volatile unsigned char busy[16][8]; /* number of commands
- executing on each target
- */
- /*
- * Eventually, I'll switch to a coroutine for calling
- * cmd->done(cmd), etc. so that we can overlap interrupt
- * processing with this code for maximum performance.
- */
-
- volatile struct NCR53c7x0_cmd *finished_queue;
-
-
- /* Shared variables between SCRIPT and host driver */
- volatile u32 *schedule; /* Array of JUMPs to dsa_begin
- routines of various DSAs.
- When not in use, replace
- with jump to next slot */
-
-
- volatile unsigned char msg_buf[16]; /* buffer for messages
- other than the command
- complete message */
-
- /* Per-target default synchronous and WIDE messages */
- volatile unsigned char synchronous_want[16][5];
- volatile unsigned char wide_want[16][4];
-
- /* Bit fielded set of targets we want to speak synchronously with */
- volatile u16 initiate_sdtr;
- /* Bit fielded set of targets we want to speak wide with */
- volatile u16 initiate_wdtr;
- /* Bit fielded list of targets we've talked to. */
- volatile u16 talked_to;
-
- /* Array of bit-fielded lun lists that we need to request_sense */
- volatile unsigned char request_sense[16];
-
- u32 addr_reconnect_dsa_head; /* RISCy style constant,
- address of following */
- volatile u32 reconnect_dsa_head;
- /* Data identifying nexus we are trying to match during reselection */
- volatile unsigned char reselected_identify; /* IDENTIFY message */
- volatile unsigned char reselected_tag; /* second byte of queue tag
- message or 0 */
- /* These were static variables before we moved them */
-
- s32 NCR53c7xx_zero;
- s32 NCR53c7xx_sink;
- u32 NOP_insn;
- char NCR53c7xx_msg_reject;
- char NCR53c7xx_msg_abort;
- char NCR53c7xx_msg_nop;
-
- volatile int event_size, event_index;
- volatile struct NCR53c7x0_event *events;
-
- /* If we need to generate code to kill off the currently connected
- command, this is where we do it. Should have a BMI instruction
- to source or sink the current data, followed by a JUMP
- to abort_connected */
-
- u32 *abort_script;
-
- int script_count; /* Size of script in words */
- u32 script[0]; /* Relocated SCSI script */
-
-};
-
-#define IRQ_NONE 255
-#define DMA_NONE 255
-#define IRQ_AUTO 254
-#define DMA_AUTO 254
-
-#define BOARD_GENERIC 0
-
-#define NCR53c7x0_insn_size(insn) \
- (((insn) & DCMD_TYPE_MASK) == DCMD_TYPE_MMI ? 3 : 2)
-
-
-#define NCR53c7x0_local_declare() \
- volatile unsigned char *NCR53c7x0_address_memory; \
- unsigned int NCR53c7x0_address_io; \
- int NCR53c7x0_memory_mapped
-
-#define NCR53c7x0_local_setup(host) \
- NCR53c7x0_address_memory = (void *) (host)->base; \
- NCR53c7x0_address_io = (unsigned int) (host)->io_port; \
- NCR53c7x0_memory_mapped = ((struct NCR53c7x0_hostdata *) \
- host->hostdata)-> options & OPTION_MEMORY_MAPPED
-
-#define NCR53c7x0_read8(address) \
- (NCR53c7x0_memory_mapped ? \
- (unsigned int)readb(NCR53c7x0_address_memory + (address)) : \
- inb(NCR53c7x0_address_io + (address)))
-
-#define NCR53c7x0_read16(address) \
- (NCR53c7x0_memory_mapped ? \
- (unsigned int)readw(NCR53c7x0_address_memory + (address)) : \
- inw(NCR53c7x0_address_io + (address)))
-
-#define NCR53c7x0_read32(address) \
- (NCR53c7x0_memory_mapped ? \
- (unsigned int) readl(NCR53c7x0_address_memory + (address)) : \
- inl(NCR53c7x0_address_io + (address)))
-
-#define NCR53c7x0_write8(address,value) \
- (NCR53c7x0_memory_mapped ? \
- ({writeb((value), NCR53c7x0_address_memory + (address)); mb();}) : \
- outb((value), NCR53c7x0_address_io + (address)))
-
-#define NCR53c7x0_write16(address,value) \
- (NCR53c7x0_memory_mapped ? \
- ({writew((value), NCR53c7x0_address_memory + (address)); mb();}) : \
- outw((value), NCR53c7x0_address_io + (address)))
-
-#define NCR53c7x0_write32(address,value) \
- (NCR53c7x0_memory_mapped ? \
- ({writel((value), NCR53c7x0_address_memory + (address)); mb();}) : \
- outl((value), NCR53c7x0_address_io + (address)))
-
-/* Patch arbitrary 32 bit words in the script */
-#define patch_abs_32(script, offset, symbol, value) \
- for (i = 0; i < (sizeof (A_##symbol##_used) / sizeof \
- (u32)); ++i) { \
- (script)[A_##symbol##_used[i] - (offset)] += (value); \
- if (hostdata->options & OPTION_DEBUG_FIXUP) \
- printk("scsi%d : %s reference %d at 0x%x in %s is now 0x%x\n",\
- host->host_no, #symbol, i, A_##symbol##_used[i] - \
- (int)(offset), #script, (script)[A_##symbol##_used[i] - \
- (offset)]); \
- }
-
-/* Patch read/write instruction immediate field */
-#define patch_abs_rwri_data(script, offset, symbol, value) \
- for (i = 0; i < (sizeof (A_##symbol##_used) / sizeof \
- (u32)); ++i) \
- (script)[A_##symbol##_used[i] - (offset)] = \
- ((script)[A_##symbol##_used[i] - (offset)] & \
- ~DBC_RWRI_IMMEDIATE_MASK) | \
- (((value) << DBC_RWRI_IMMEDIATE_SHIFT) & \
- DBC_RWRI_IMMEDIATE_MASK)
-
-/* Patch transfer control instruction data field */
-#define patch_abs_tci_data(script, offset, symbol, value) \
- for (i = 0; i < (sizeof (A_##symbol##_used) / sizeof \
- (u32)); ++i) \
- (script)[A_##symbol##_used[i] - (offset)] = \
- ((script)[A_##symbol##_used[i] - (offset)] & \
- ~DBC_TCI_DATA_MASK) | \
- (((value) << DBC_TCI_DATA_SHIFT) & \
- DBC_TCI_DATA_MASK)
-
-/* Patch field in dsa structure (assignment should be +=?) */
-#define patch_dsa_32(dsa, symbol, word, value) \
- { \
- (dsa)[(hostdata->##symbol - hostdata->dsa_start) / sizeof(u32) \
- + (word)] = (value); \
- if (hostdata->options & OPTION_DEBUG_DSA) \
- printk("scsi : dsa %s symbol %s(%d) word %d now 0x%x\n", \
- #dsa, #symbol, hostdata->##symbol, \
- (word), (u32) (value)); \
- }
-
-/* Paranoid people could use panic() here. */
-#define FATAL(host) shutdown((host));
-
-#endif /* NCR53c7x0_C */
-#endif /* NCR53c7x0_H */
diff --git a/i386/i386at/gpl/linux/scsi/53c78xx.c b/i386/i386at/gpl/linux/scsi/53c78xx.c
deleted file mode 100644
index 74350b08..00000000
--- a/i386/i386at/gpl/linux/scsi/53c78xx.c
+++ /dev/null
@@ -1,6381 +0,0 @@
-/*
- * PERM_OPTIONS are driver options which will be enabled for all NCR boards
- * in the system at driver initialization time.
- *
- * Don't THINK about touching these in PERM_OPTIONS :
- * OPTION_IO_MAPPED
- * Memory mapped IO does not work under i86 Linux.
- *
- * OPTION_DEBUG_TEST1
- * Test 1 does bus mastering and interrupt tests, which will help weed
- * out brain damaged main boards.
- *
- * These are development kernel changes. Code for them included in this
- * driver release may or may not work. If you turn them on, you should be
- * running the latest copy of the development sources from
- *
- * ftp://tsx-11.mit.edu/pub/linux/ALPHA/scsi/53c7,8xx
- *
- * and be subscribed to the ncr53c810@colorado.edu mailing list. To
- * subscribe, send mail to majordomo@colorado.edu with
- *
- * subscribe ncr53c810
- *
- * in the text.
- *
- *
- * OPTION_NOASYNC
- * Don't negotiate for asynchronous transfers on the first command
- * when OPTION_ALWAYS_SYNCHRONOUS is set. Useful for dain bramaged
- * devices which do something bad rather than sending a MESSAGE
- * REJECT back to us like they should if they can't cope.
- *
- * OPTION_SYNCHRONOUS
- * Enable support for synchronous transfers. Target negotiated
- * synchronous transfers will be responded to. To initiate
- * a synchronous transfer request, call
- *
- * request_synchronous (hostno, target)
- *
- * from within KGDB.
- *
- * OPTION_ALWAYS_SYNCHRONOUS
- * Negotiate for synchronous transfers with every target after
- * driver initialization or a SCSI bus reset. This is a bit dangerous,
- * since there are some dain bramaged SCSI devices which will accept
- * SDTR messages but keep talking asynchronously.
- *
- * OPTION_DISCONNECT
- * Enable support for disconnect/reconnect. To change the
- * default setting on a given host adapter, call
- *
- * request_disconnect (hostno, allow)
- *
- * where allow is non-zero to allow, 0 to disallow.
- *
- * If you really want to run 10MHz FAST SCSI-II transfers, you should
- * know that the NCR driver currently ignores parity information. Most
- * systems do 5MHz SCSI fine. I've seen a lot that have problems faster
- * than 8MHz. To play it safe, we only request 5MHz transfers.
- *
- * If you'd rather get 10MHz transfers, edit sdtr_message and change
- * the fourth byte from 50 to 25.
- */
-
-#define PERM_OPTIONS (OPTION_IO_MAPPED|OPTION_DEBUG_TEST1|OPTION_DISCONNECT|\
- OPTION_SYNCHRONOUS)
-
-/*
- * Sponsored by
- * iX Multiuser Multitasking Magazine
- * Hannover, Germany
- * hm@ix.de
- *
- * Copyright 1993, 1994, 1995 Drew Eckhardt
- * Visionary Computing
- * (Unix and Linux consulting and custom programming)
- * drew@PoohSticks.ORG
- * +1 (303) 786-7975
- *
- * TolerANT and SCSI SCRIPTS are registered trademarks of NCR Corporation.
- *
- * For more information, please consult
- *
- * NCR53C810
- * SCSI I/O Processor
- * Programmer's Guide
- *
- * NCR 53C810
- * PCI-SCSI I/O Processor
- * Data Manual
- *
- * NCR 53C810/53C820
- * PCI-SCSI I/O Processor Design In Guide
- *
- * For literature on Symbios Logic Inc. formerly NCR, SCSI,
- * and Communication products please call (800) 334-5454 or
- * (719) 536-3300.
- *
- * PCI BIOS Specification Revision
- * PCI Local Bus Specification
- * PCI System Design Guide
- *
- * PCI Special Interest Group
- * M/S HF3-15A
- * 5200 N.E. Elam Young Parkway
- * Hillsboro, Oregon 97124-6497
- * +1 (503) 696-2000
- * +1 (800) 433-5177
- */
-
-/*
- * Design issues :
- * The cumulative latency needed to propagate a read/write request
- * through the file system, buffer cache, driver stacks, SCSI host, and
- * SCSI device is ultimately the limiting factor in throughput once we
- * have a sufficiently fast host adapter.
- *
- * So, to maximize performance we want to keep the ratio of latency to data
- * transfer time to a minimum by
- * 1. Minimizing the total number of commands sent (typical command latency
- * including drive and bus mastering host overhead is as high as 4.5ms)
- * to transfer a given amount of data.
- *
- * This is accomplished by placing no arbitrary limit on the number
- * of scatter/gather buffers supported, since we can transfer 1K
- * per scatter/gather buffer without Eric's cluster patches,
- * 4K with.
- *
- * 2. Minimizing the number of fatal interrupts serviced, since
- * fatal interrupts halt the SCSI I/O processor. Basically,
- * this means offloading the practical maximum amount of processing
- * to the SCSI chip.
- *
- * On the NCR53c810/820/720, this is accomplished by using
- * interrupt-on-the-fly signals when commands complete,
- * and only handling fatal errors and SDTR / WDTR messages
- * in the host code.
- *
- * On the NCR53c710, interrupts are generated as on the NCR53c8x0,
- * only the lack of a interrupt-on-the-fly facility complicates
- * things. Also, SCSI ID registers and commands are
- * bit fielded rather than binary encoded.
- *
- * On the NCR53c700 and NCR53c700-66, operations that are done via
- * indirect, table mode on the more advanced chips must be
- * replaced by calls through a jump table which
- * acts as a surrogate for the DSA. Unfortunately, this
- * will mean that we must service an interrupt for each
- * disconnect/reconnect.
- *
- * 3. Eliminating latency by pipelining operations at the different levels.
- *
- * This driver allows a configurable number of commands to be enqueued
- * for each target/lun combination (experimentally, I have discovered
- * that two seems to work best) and will ultimately allow for
- * SCSI-II tagged queuing.
- *
- *
- * Architecture :
- * This driver is built around a Linux queue of commands waiting to
- * be executed, and a shared Linux/NCR array of commands to start. Commands
- * are transfered to the array by the run_process_issue_queue() function
- * which is called whenever a command completes.
- *
- * As commands are completed, the interrupt routine is triggered,
- * looks for commands in the linked list of completed commands with
- * valid status, removes these commands from a list of running commands,
- * calls the done routine, and flags their target/luns as not busy.
- *
- * Due to limitations in the intelligence of the NCR chips, certain
- * concessions are made. In many cases, it is easier to dynamically
- * generate/fix-up code rather than calculate on the NCR at run time.
- * So, code is generated or fixed up for
- *
- * - Handling data transfers, using a variable number of MOVE instructions
- * interspersed with CALL MSG_IN, WHEN MSGIN instructions.
- *
- * The DATAIN and DATAOUT routines are separate, so that an incorrect
- * direction can be trapped, and space isn't wasted.
- *
- * It may turn out that we're better off using some sort
- * of table indirect instruction in a loop with a variable
- * sized table on the NCR53c710 and newer chips.
- *
- * - Checking for reselection (NCR53c710 and better)
- *
- * - Handling the details of SCSI context switches (NCR53c710 and better),
- * such as reprogramming appropriate synchronous parameters,
- * removing the dsa structure from the NCR's queue of outstanding
- * commands, etc.
- *
- */
-
-/*
- * Accommodate differences between stock 1.2.x and 1.3.x asm-i386/types.h
- * so lusers can drop in 53c7,8xx.* and get something which compiles
- * without warnings.
- */
-
-#if !defined(LINUX_1_2) && !defined(LINUX_1_3)
-#include <linux/version.h>
-#if LINUX_VERSION_CODE > 65536 + 3 * 256
-#define LINUX_1_3
-#else
-#define LINUX_1_2
-#endif
-#endif
-
-#ifdef LINUX_1_2
-#define u32 bogus_u32
-#define s32 bogus_s32
-#include <asm/types.h>
-#undef u32
-#undef s32
-typedef __signed__ int s32;
-typedef unsigned int u32;
-#endif /* def LINUX_1_2 */
-
-#ifdef MODULE
-#include <linux/module.h>
-#endif
-
-#include <asm/dma.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include <linux/delay.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/errno.h>
-#include <linux/bios32.h>
-#include <linux/pci.h>
-#include <linux/proc_fs.h>
-#include <linux/string.h>
-#include <linux/malloc.h>
-#include <linux/mm.h>
-#include <linux/ioport.h>
-#include <linux/time.h>
-#ifdef LINUX_1_2
-#include "../block/blk.h"
-#else
-#include <linux/blk.h>
-#endif
-#undef current
-
-#include "scsi.h"
-#include "hosts.h"
-#include "53c7,8xx.h"
-#include "constants.h"
-#include "sd.h"
-#include <linux/stat.h>
-#include <linux/stddef.h>
-
-#ifndef LINUX_1_2
-struct proc_dir_entry proc_scsi_ncr53c7xx = {
- PROC_SCSI_NCR53C7xx, 9, "ncr53c7xx",
- S_IFDIR | S_IRUGO | S_IXUGO, 2
-};
-#endif
-
-static int check_address (unsigned long addr, int size);
-static void dump_events (struct Scsi_Host *host, int count);
-static Scsi_Cmnd * return_outstanding_commands (struct Scsi_Host *host,
- int free, int issue);
-static void hard_reset (struct Scsi_Host *host);
-static void ncr_scsi_reset (struct Scsi_Host *host);
-static void print_lots (struct Scsi_Host *host);
-static void set_synchronous (struct Scsi_Host *host, int target, int sxfer,
- int scntl3, int now_connected);
-static int datapath_residual (struct Scsi_Host *host);
-static const char * sbcl_to_phase (int sbcl);
-static void print_progress (Scsi_Cmnd *cmd);
-static void print_queues (struct Scsi_Host *host);
-static void process_issue_queue (unsigned long flags);
-static int shutdown (struct Scsi_Host *host);
-static void abnormal_finished (struct NCR53c7x0_cmd *cmd, int result);
-static int disable (struct Scsi_Host *host);
-static int NCR53c8xx_run_tests (struct Scsi_Host *host);
-static int NCR53c8xx_script_len;
-static int NCR53c8xx_dsa_len;
-static void NCR53c7x0_intr(int irq, struct pt_regs * regs);
-static int ncr_halt (struct Scsi_Host *host);
-static void intr_phase_mismatch (struct Scsi_Host *host, struct NCR53c7x0_cmd
- *cmd);
-static void intr_dma (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd);
-static void print_dsa (struct Scsi_Host *host, u32 *dsa,
- const char *prefix);
-static int print_insn (struct Scsi_Host *host, const u32 *insn,
- const char *prefix, int kernel);
-
-static void NCR53c8xx_dsa_fixup (struct NCR53c7x0_cmd *cmd);
-static void NCR53c8x0_init_fixup (struct Scsi_Host *host);
-static int NCR53c8x0_dstat_sir_intr (struct Scsi_Host *host, struct
- NCR53c7x0_cmd *cmd);
-static void NCR53c8x0_soft_reset (struct Scsi_Host *host);
-
-/* INSMOD variables */
-static long long perm_options = PERM_OPTIONS;
-/* 14 = .5s; 15 is max; decreasing divides by two. */
-static int selection_timeout = 14;
-/* Size of event list (per host adapter) */
-static int track_events = 0;
-
-static struct Scsi_Host *first_host = NULL; /* Head of list of NCR boards */
-static Scsi_Host_Template *the_template = NULL;
-
-/*
- * KNOWN BUGS :
- * - There is some sort of conflict when the PPP driver is compiled with
- * support for 16 channels?
- *
- * - On systems which predate the 1.3.x initialization order change,
- * the NCR driver will cause Cannot get free page messages to appear.
- * These are harmless, but I don't know of an easy way to avoid them.
- *
- * - With OPTION_DISCONNECT, on two systems under unknown circumstances,
- * we get a PHASE MISMATCH with DSA set to zero (suggests that we
- * are occurring somewhere in the reselection code) where
- * DSP=some value DCMD|DBC=same value.
- *
- * Closer inspection suggests that we may be trying to execute
- * some portion of the DSA?
- * scsi0 : handling residual transfer (+ 0 bytes from DMA FIFO)
- * scsi0 : handling residual transfer (+ 0 bytes from DMA FIFO)
- * scsi0 : no current command : unexpected phase MSGIN.
- * DSP=0x1c46cc, DCMD|DBC=0x1c46ac, DSA=0x0
- * DSPS=0x0, TEMP=0x1c3e70, DMODE=0x80
- * scsi0 : DSP->
- * 001c46cc : 0x001c46cc 0x00000000
- * 001c46d4 : 0x001c5ea0 0x000011f8
- *
- * Changed the print code in the phase_mismatch handler so
- * that we call print_lots to try and diagnose this.
- *
- */
-
-/*
- * Possible future direction of architecture for max performance :
- *
- * We're using a single start array for the NCR chip. This is
- * sub-optimal, because we cannot add a command which would conflict with
- * an executing command to this start queue, and therefore must insert the
- * next command for a given I/T/L combination after the first has completed;
- * incurring our interrupt latency between SCSI commands.
- *
- * To allow furthur pipelining of the NCR and host CPU operation, we want
- * to set things up so that immediately on termination of a command destined
- * for a given LUN, we get that LUN busy again.
- *
- * To do this, we need to add a 32 bit pointer to which is jumped to
- * on completion of a command. If no new command is available, this
- * would point to the usual DSA issue queue select routine.
- *
- * If one were, it would point to a per-NCR53c7x0_cmd select routine
- * which starts execution immediately, inserting the command at the head
- * of the start queue if the NCR chip is selected or reselected.
- *
- * We would chanage so that we keep a list of outstanding commands
- * for each unit, rather than a single running_list. We'd insert
- * a new command into the right running list; if the NCR didn't
- * have something running for that yet, we'd put it in the
- * start queue as well. Some magic needs to happen to handle the
- * race condition between the first command terminating before the
- * new one is written.
- *
- * Potential for profiling :
- * Call do_gettimeofday(struct timeval *tv) to get 800ns resolution.
- */
-
-
-/*
- * TODO :
- * 1. To support WIDE transfers, not much needs to happen. We
- * should do CHMOVE instructions instead of MOVEs when
- * we have scatter/gather segments of uneven length. When
- * we do this, we need to handle the case where we disconnect
- * between segments.
- *
- * 2. Currently, when Icky things happen we do a FATAL(). Instead,
- * we want to do an integrity check on the parts of the NCR hostdata
- * structure which were initialized at boot time; FATAL() if that
- * fails, and otherwise try to recover. Keep track of how many
- * times this has happened within a single SCSI command; if it
- * gets excessive, then FATAL().
- *
- * 3. Parity checking is currently disabled, and a few things should
- * happen here now that we support synchronous SCSI transfers :
- * 1. On soft-reset, we shuld set the EPC (Enable Parity Checking)
- * and AAP (Assert SATN/ on parity error) bits in SCNTL0.
- *
- * 2. We should enable the parity interrupt in the SIEN0 register.
- *
- * 3. intr_phase_mismatch() needs to believe that message out is
- * allways an "acceptable" phase to have a mismatch in. If
- * the old phase was MSG_IN, we should send a MESSAGE PARITY
- * error. If the old phase was something else, we should send
- * a INITIATOR_DETECTED_ERROR message. Note that this could
- * cause a RESTORE POINTERS message; so we should handle that
- * correctly first. Instead, we should probably do an
- * initiator_abort.
- *
- * 4. MPEE bit of CTEST4 should be set so we get interrupted if
- * we detect an error.
- *
- *
- * 5. The initial code has been tested on the NCR53c810. I don't
- * have access to NCR53c700, 700-66 (Forex boards), NCR53c710
- * (NCR Pentium systems), NCR53c720, NCR53c820, or NCR53c825 boards to
- * finish development on those platforms.
- *
- * NCR53c820/825/720 - need to add wide transfer support, including WDTR
- * negotiation, programming of wide transfer capabilities
- * on reselection and table indirect selection.
- *
- * NCR53c710 - need to add fatal interrupt or GEN code for
- * command completion signaling. Need to modify all
- * SDID, SCID, etc. registers, and table indirect select code
- * since these use bit fielded (ie 1<<target) instead of
- * binary encoded target ids. Need to accomodate
- * different register mappings, probably scan through
- * the SCRIPT code and change the non SFBR register operand
- * of all MOVE instructions.
- *
- * NCR53c700/700-66 - need to add code to refix addresses on
- * every nexus change, eliminate all table indirect code,
- * very messy.
- *
- * 6. The NCR53c7x0 series is very popular on other platforms that
- * could be running Linux - ie, some high performance AMIGA SCSI
- * boards use it.
- *
- * So, I should include #ifdef'd code so that it is
- * compatible with these systems.
- *
- * Specifically, the little Endian assumptions I made in my
- * bit fields need to change, and if the NCR doesn't see memory
- * the right way, we need to provide options to reverse words
- * when the scripts are relocated.
- *
- * 7. Use vremap() to access memory mapped boards.
- */
-
-/*
- * Allow for simultaneous existence of multiple SCSI scripts so we
- * can have a single driver binary for all of the family.
- *
- * - one for NCR53c700 and NCR53c700-66 chips (not yet supported)
- * - one for rest (only the NCR53c810, 815, 820, and 825 are currently
- * supported)
- *
- * So that we only need two SCSI scripts, we need to modify things so
- * that we fixup register accesses in READ/WRITE instructions, and
- * we'll also have to accomodate the bit vs. binary encoding of IDs
- * with the 7xx chips.
- */
-
-/*
- * Use pci_chips_ids to translate in both directions between PCI device ID
- * and chip numbers.
- */
-
-static struct {
- unsigned short pci_device_id;
- int chip;
-/*
- * The revision field of the PCI_CLASS_REVISION register is compared
- * against each of these fields if the field is not -1. If it
- * is less than min_revision or larger than max_revision, a warning
- * message is printed.
- */
- int max_revision;
- int min_revision;
-} pci_chip_ids[] = {
- {PCI_DEVICE_ID_NCR_53C810, 810, 2, 1},
- {PCI_DEVICE_ID_NCR_53C815, 815, 3, 2},
- {PCI_DEVICE_ID_NCR_53C820, 820, -1, -1},
- {PCI_DEVICE_ID_NCR_53C825, 825, -1, -1}
-};
-
-#define NPCI_CHIP_IDS (sizeof (pci_chip_ids) / sizeof(pci_chip_ids[0]))
-
-#define ROUNDUP(adr,type) \
- ((void *) (((long) (adr) + sizeof(type) - 1) & ~(sizeof(type) - 1)))
-
-/*
- * Forced detection and autoprobe code for various hardware. Currently,
- * entry points for these are not included in init/main.c because if the
- * PCI BIOS code isn't working right, you're not going to be able to use
- * the hardware anyways; this way we force users to solve their
- * problems rather than forcing detection and blaming us when it
- * does not work.
- */
-
-static struct override {
- int chip; /* 700, 70066, 710, 720, 810, 820 */
- int board; /* Any special board level gunk */
- unsigned pci:1;
- union {
- struct {
- int base; /* Memory address - indicates memory mapped regs */
- int io_port;/* I/O port address - indicates I/O mapped regs */
- int irq; /* IRQ line */
- int dma; /* DMA channel - often none */
- } normal;
- struct {
- int bus;
- int device;
- int function;
- } pci;
- } data;
- long long options;
-} overrides [4] = {{0,},};
-static int commandline_current = 0;
-static int no_overrides = 0;
-
-#if 0
-#define OVERRIDE_LIMIT (sizeof(overrides) / sizeof(struct override))
-#else
-#define OVERRIDE_LIMIT commandline_current
-#endif
-
-/*
- * Function: issue_to_cmd
- *
- * Purpose: convert jump instruction in issue array to NCR53c7x0_cmd
- * structure pointer.
- *
- * Inputs; issue - pointer to start of NOP or JUMP instruction
- * in issue array.
- *
- * Returns: pointer to command on success; 0 if opcode is NOP.
- */
-
-static inline struct NCR53c7x0_cmd *
-issue_to_cmd (struct Scsi_Host *host, struct NCR53c7x0_hostdata *hostdata,
- u32 *issue)
-{
- return (issue[0] != hostdata->NOP_insn) ?
- /*
- * If the IF TRUE bit is set, it's a JUMP instruction. The
- * operand is a bus pointer to the dsa_begin routine for this DSA. The
- * dsa field of the NCR53c7x0_cmd structure starts with the
- * DSA code template. By converting to a virtual address,
- * subtracting the code template size, and offset of the
- * dsa field, we end up with a pointer to the start of the
- * structure (alternatively, we could use the
- * dsa_cmnd field, an anachronism from when we weren't
- * sure what the relationship between the NCR structures
- * and host structures were going to be.
- */
- (struct NCR53c7x0_cmd *) ((char *) bus_to_virt (issue[1]) -
- (hostdata->E_dsa_code_begin - hostdata->E_dsa_code_template) -
- offsetof(struct NCR53c7x0_cmd, dsa))
- /* If the IF TRUE bit is not set, it's a NOP */
- : NULL;
-}
-
-
-/*
- * Function : static internal_setup(int board, int chip, char *str, int *ints)
- *
- * Purpose : LILO command line initialization of the overrides array,
- *
- * Inputs : board - currently, unsupported. chip - 700, 70066, 710, 720
- * 810, 815, 820, 825, although currently only the NCR53c810 is
- * supported.
- *
- */
-
-static void
-internal_setup(int board, int chip, char *str, int *ints) {
- unsigned char pci; /* Specifies a PCI override, with bus, device,
- function */
-
- pci = (str && !strcmp (str, "pci")) ? 1 : 0;
-
-/*
- * Override syntaxes are as follows :
- * ncr53c700,ncr53c700-66,ncr53c710,ncr53c720=mem,io,irq,dma
- * ncr53c810,ncr53c820,ncr53c825=mem,io,irq or pci,bus,device,function
- */
-
- if (commandline_current < OVERRIDE_LIMIT) {
- overrides[commandline_current].pci = pci ? 1 : 0;
- if (!pci) {
- overrides[commandline_current].data.normal.base = ints[1];
- overrides[commandline_current].data.normal.io_port = ints[2];
- overrides[commandline_current].data.normal.irq = ints[3];
- overrides[commandline_current].data.normal.dma = (ints[0] >= 4) ?
- ints[4] : DMA_NONE;
- /* FIXME: options is now a long long */
- overrides[commandline_current].options = (ints[0] >= 5) ?
- ints[5] : 0;
- } else {
- overrides[commandline_current].data.pci.bus = ints[1];
- overrides[commandline_current].data.pci.device = ints[2];
- overrides[commandline_current].data.pci.function = ints[3];
- /* FIXME: options is now a long long */
- overrides[commandline_current].options = (ints[0] >= 4) ?
- ints[4] : 0;
- }
- overrides[commandline_current].board = board;
- overrides[commandline_current].chip = chip;
- ++commandline_current;
- ++no_overrides;
- } else {
- printk ("53c7,7x0.c:internal_setup() : too many overrides\n");
- }
-}
-
-/*
- * XXX - we might want to implement a single override function
- * with a chip type field, revamp the command line configuration,
- * etc.
- */
-
-#define setup_wrapper(x) \
-void ncr53c##x##_setup (char *str, int *ints) { \
- internal_setup (BOARD_GENERIC, x, str, ints); \
-}
-
-setup_wrapper(700)
-setup_wrapper(70066)
-setup_wrapper(710)
-setup_wrapper(720)
-setup_wrapper(810)
-setup_wrapper(815)
-setup_wrapper(820)
-setup_wrapper(825)
-
-/*
- * FIXME: we should junk these, in favor of synchronous_want and
- * wide_want in the NCR53c7x0_hostdata structure.
- */
-
-/* Template for "preferred" synchronous transfer parameters. */
-
-static const unsigned char sdtr_message[] = {
- EXTENDED_MESSAGE, 3 /* length */, EXTENDED_SDTR, 50 /* *4ns */, 8 /* off */
-};
-
-/* Template to request asynchronous transfers */
-
-static const unsigned char async_message[] = {
- EXTENDED_MESSAGE, 3 /* length */, EXTENDED_SDTR, 0, 0 /* asynchronous */
-};
-
-/* Template for "preferred" WIDE transfer parameters */
-
-static const unsigned char wdtr_message[] = {
- EXTENDED_MESSAGE, 2 /* length */, EXTENDED_WDTR, 1 /* 2^1 bytes */
-};
-
-/*
- * Function : struct Scsi_Host *find_host (int host)
- *
- * Purpose : KGDB support function which translates a host number
- * to a host structure.
- *
- * Inputs : host - number of SCSI host
- *
- * Returns : NULL on failure, pointer to host structure on success.
- */
-
-static struct Scsi_Host *
-find_host (int host) {
- struct Scsi_Host *h;
- for (h = first_host; h && h->host_no != host; h = h->next);
- if (!h) {
- printk (KERN_ALERT "scsi%d not found\n", host);
- return NULL;
- } else if (h->hostt != the_template) {
- printk (KERN_ALERT "scsi%d is not a NCR board\n", host);
- return NULL;
- }
- return h;
-}
-
-/*
- * Function : request_synchronous (int host, int target)
- *
- * Purpose : KGDB interface which will allow us to negotiate for
- * synchronous transfers. This ill be replaced with a more
- * integrated function; perhaps a new entry in the scsi_host
- * structure, accessable via an ioctl() or perhaps /proc/scsi.
- *
- * Inputs : host - number of SCSI host; target - number of target.
- *
- * Returns : 0 when negotiation has been setup for next SCSI command,
- * -1 on failure.
- */
-
-static int
-request_synchronous (int host, int target) {
- struct Scsi_Host *h;
- struct NCR53c7x0_hostdata *hostdata;
- unsigned long flags;
- if (target < 0) {
- printk (KERN_ALERT "target %d is bogus\n", target);
- return -1;
- }
- if (!(h = find_host (host)))
- return -1;
- else if (h->this_id == target) {
- printk (KERN_ALERT "target %d is host ID\n", target);
- return -1;
- }
-#ifndef LINUX_1_2
- else if (target > h->max_id) {
- printk (KERN_ALERT "target %d exceeds maximum of %d\n", target,
- h->max_id);
- return -1;
- }
-#endif
- hostdata = (struct NCR53c7x0_hostdata *)h->hostdata;
-
- save_flags(flags);
- cli();
- if (hostdata->initiate_sdtr & (1 << target)) {
- restore_flags(flags);
- printk (KERN_ALERT "target %d allready doing SDTR\n", target);
- return -1;
- }
- hostdata->initiate_sdtr |= (1 << target);
- restore_flags(flags);
- return 0;
-}
-
-/*
- * Function : request_disconnect (int host, int on_or_off)
- *
- * Purpose : KGDB support function, tells us to allow or disallow
- * disconnections.
- *
- * Inputs : host - number of SCSI host; on_or_off - non-zero to allow,
- * zero to disallow.
- *
- * Returns : 0 on success, * -1 on failure.
- */
-
-static int
-request_disconnect (int host, int on_or_off) {
- struct Scsi_Host *h;
- struct NCR53c7x0_hostdata *hostdata;
- if (!(h = find_host (host)))
- return -1;
- hostdata = (struct NCR53c7x0_hostdata *) h->hostdata;
- if (on_or_off)
- hostdata->options |= OPTION_DISCONNECT;
- else
- hostdata->options &= ~OPTION_DISCONNECT;
- return 0;
-}
-
-/*
- * Function : static void NCR53c7x0_driver_init (struct Scsi_Host *host)
- *
- * Purpose : Initialize internal structures, as required on startup, or
- * after a SCSI bus reset.
- *
- * Inputs : host - pointer to this host adapter's structure
- */
-
-static void
-NCR53c7x0_driver_init (struct Scsi_Host *host) {
- struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
- host->hostdata;
- int i, j;
- u32 *current;
- for (i = 0; i < 16; ++i) {
- hostdata->request_sense[i] = 0;
- for (j = 0; j < 8; ++j)
- hostdata->busy[i][j] = 0;
- set_synchronous (host, i, /* sxfer */ 0, hostdata->saved_scntl3, 0);
- }
- hostdata->issue_queue = NULL;
- hostdata->running_list = hostdata->finished_queue =
- hostdata->current = NULL;
- for (i = 0, current = (u32 *) hostdata->schedule;
- i < host->can_queue; ++i, current += 2) {
- current[0] = hostdata->NOP_insn;
- current[1] = 0xdeadbeef;
- }
- current[0] = ((DCMD_TYPE_TCI|DCMD_TCI_OP_JUMP) << 24) | DBC_TCI_TRUE;
- current[1] = (u32) virt_to_bus (hostdata->script) +
- hostdata->E_wait_reselect;
- hostdata->reconnect_dsa_head = 0;
- hostdata->addr_reconnect_dsa_head = (u32)
- virt_to_bus((void *) &(hostdata->reconnect_dsa_head));
- hostdata->expecting_iid = 0;
- hostdata->expecting_sto = 0;
- if (hostdata->options & OPTION_ALWAYS_SYNCHRONOUS)
- hostdata->initiate_sdtr = 0xffff;
- else
- hostdata->initiate_sdtr = 0;
- hostdata->talked_to = 0;
- hostdata->idle = 1;
-}
-
-/*
- * Function : static int ccf_to_clock (int ccf)
- *
- * Purpose : Return the largest SCSI clock allowable for a given
- * clock conversion factor, allowing us to do synchronous periods
- * when we don't know what the SCSI clock is by taking at least
- * as long as the device says we can.
- *
- * Inputs : ccf
- *
- * Returns : clock on success, -1 on failure.
- */
-
-static int
-ccf_to_clock (int ccf) {
- switch (ccf) {
- case 1: return 25000000; /* Divide by 1.0 */
- case 2: return 37500000; /* Divide by 1.5 */
- case 3: return 50000000; /* Divide by 2.0 */
- case 0: /* Divide by 3.0 */
- case 4: return 66000000;
- default: return -1;
- }
-}
-
-/*
- * Function : static int clock_to_ccf (int clock)
- *
- * Purpose : Return the clock conversion factor for a given SCSI clock.
- *
- * Inputs : clock - SCSI clock expressed in Hz.
- *
- * Returns : ccf on success, -1 on failure.
- */
-
-static int
-clock_to_ccf (int clock) {
- if (clock < 16666666)
- return -1;
- if (clock < 25000000)
- return 1; /* Divide by 1.0 */
- else if (clock < 37500000)
- return 2; /* Divide by 1.5 */
- else if (clock < 50000000)
- return 3; /* Divide by 2.0 */
- else if (clock < 66000000)
- return 4; /* Divide by 3.0 */
- else
- return -1;
-}
-
-/*
- * Function : static int NCR53c7x0_init (struct Scsi_Host *host)
- *
- * Purpose : initialize the internal structures for a given SCSI host
- *
- * Inputs : host - pointer to this host adapter's structure
- *
- * Preconditions : when this function is called, the chip_type
- * field of the hostdata structure MUST have been set.
- *
- * Returns : 0 on success, -1 on failure.
- */
-
-static int
-NCR53c7x0_init (struct Scsi_Host *host) {
- NCR53c7x0_local_declare();
- int i, ccf, expected_ccf;
- struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
- host->hostdata;
- struct Scsi_Host *search;
- /*
- * There are some things which we need to know about in order to provide
- * a semblance of support. Print 'em if they aren't what we expect,
- * otherwise don't add to the noise.
- *
- * -1 means we don't know what to expect.
- */
- int expected_id = -1;
- int expected_clock = -1;
- int uninitialized = 0;
- /*
- * FIXME : this is only on Intel boxes. On other platforms, this
- * will differ.
- */
- int expected_mapping = OPTION_IO_MAPPED;
- NCR53c7x0_local_setup(host);
-
- switch (hostdata->chip) {
- case 820:
- case 825:
-#ifdef notyet
- host->max_id = 15;
-#endif
- /* Fall through */
- case 810:
- case 815:
- hostdata->dstat_sir_intr = NCR53c8x0_dstat_sir_intr;
- hostdata->init_save_regs = NULL;
- hostdata->dsa_fixup = NCR53c8xx_dsa_fixup;
- hostdata->init_fixup = NCR53c8x0_init_fixup;
- hostdata->soft_reset = NCR53c8x0_soft_reset;
- hostdata->run_tests = NCR53c8xx_run_tests;
-/* Is the SCSI clock ever anything else on these chips? */
- expected_clock = hostdata->scsi_clock = 40000000;
- expected_id = 7;
- break;
- default:
- printk ("scsi%d : chip type of %d is not supported yet, detaching.\n",
- host->host_no, hostdata->chip);
- scsi_unregister (host);
- return -1;
- }
-
- /* Assign constants accessed by NCR */
- hostdata->NCR53c7xx_zero = 0;
- hostdata->NCR53c7xx_msg_reject = MESSAGE_REJECT;
- hostdata->NCR53c7xx_msg_abort = ABORT;
- hostdata->NCR53c7xx_msg_nop = NOP;
- hostdata->NOP_insn = (DCMD_TYPE_TCI|DCMD_TCI_OP_JUMP) << 24;
-
- if (expected_mapping == -1 ||
- (hostdata->options & (OPTION_MEMORY_MAPPED)) !=
- (expected_mapping & OPTION_MEMORY_MAPPED))
- printk ("scsi%d : using %s mapped access\n", host->host_no,
- (hostdata->options & OPTION_MEMORY_MAPPED) ? "memory" :
- "io");
-
- hostdata->dmode = (hostdata->chip == 700 || hostdata->chip == 70066) ?
- DMODE_REG_00 : DMODE_REG_10;
- hostdata->istat = ((hostdata->chip / 100) == 8) ?
- ISTAT_REG_800 : ISTAT_REG_700;
-
-/* Only the ISTAT register is readable when the NCR is running, so make
- sure it's halted. */
- ncr_halt(host);
-
-/*
- * XXX - the NCR53c700 uses bitfielded registers for SCID, SDID, etc,
- * as does the 710 with one bit per SCSI ID. Conversely, the NCR
- * uses a normal, 3 bit binary representation of these values.
- *
- * Get the rest of the NCR documentation, and FIND OUT where the change
- * was.
- */
-#if 0
- tmp = hostdata->this_id_mask = NCR53c7x0_read8(SCID_REG);
- for (host->this_id = 0; tmp != 1; tmp >>=1, ++host->this_id);
-#else
- host->this_id = NCR53c7x0_read8(SCID_REG) & 15;
- if (host->this_id == 0)
- host->this_id = 7; /* sanitize hostid---0 doesn't make sense */
- hostdata->this_id_mask = 1 << host->this_id;
-#endif
-
-/*
- * Note : we should never encounter a board setup for ID0. So,
- * if we see ID0, assume that it was uninitialized and set it
- * to the industry standard 7.
- */
- if (!host->this_id) {
- printk("scsi%d : initiator ID was %d, changing to 7\n",
- host->host_no, host->this_id);
- host->this_id = 7;
- hostdata->this_id_mask = 1 << 7;
- uninitialized = 1;
- };
-
- if (expected_id == -1 || host->this_id != expected_id)
- printk("scsi%d : using initiator ID %d\n", host->host_no,
- host->this_id);
-
- /*
- * Save important registers to allow a soft reset.
- */
-
- if ((hostdata->chip / 100) == 8) {
- /*
- * CTEST4 controls burst mode disable.
- */
- hostdata->saved_ctest4 = NCR53c7x0_read8(CTEST4_REG_800) &
- CTEST4_800_SAVE;
- } else {
- /*
- * CTEST7 controls cache snooping, burst mode, and support for
- * external differential drivers.
- */
- hostdata->saved_ctest7 = NCR53c7x0_read8(CTEST7_REG) & CTEST7_SAVE;
- }
-
- /*
- * On NCR53c700 series chips, DCNTL controls the SCSI clock divisor,
- * on 800 series chips, it allows for a totem-pole IRQ driver.
- */
-
- hostdata->saved_dcntl = NCR53c7x0_read8(DCNTL_REG);
-
- /*
- * DCNTL_800_IRQM controls weather we are using an open drain
- * driver (reset) or totem pole driver (set). In all cases,
- * it's level active. I suppose this is an issue when we're trying to
- * wire-or the same PCI INTx line?
- */
- if ((hostdata->chip / 100) == 8)
- hostdata->saved_dcntl &= ~DCNTL_800_IRQM;
-
- /*
- * DMODE controls DMA burst length, and on 700 series chips,
- * 286 mode and bus width
- */
- hostdata->saved_dmode = NCR53c7x0_read8(hostdata->dmode);
-
- /*
- * Now that burst length and enabled/disabled status is known,
- * clue the user in on it.
- */
-
- if ((hostdata->chip / 100) == 8) {
- if (hostdata->saved_ctest4 & CTEST4_800_BDIS) {
- printk ("scsi%d : burst mode disabled\n", host->host_no);
- } else {
- switch (hostdata->saved_dmode & DMODE_BL_MASK) {
- case DMODE_BL_2: i = 2; break;
- case DMODE_BL_4: i = 4; break;
- case DMODE_BL_8: i = 8; break;
- case DMODE_BL_16: i = 16; break;
- default: i = 0;
- }
- printk ("scsi%d : burst length %d\n", host->host_no, i);
- }
- }
-
- /*
- * On NCR53c810 and NCR53c820 chips, SCNTL3 contails the synchronous
- * and normal clock conversion factors.
- */
- if (hostdata->chip / 100 == 8) {
- expected_ccf = clock_to_ccf (expected_clock);
- hostdata->saved_scntl3 = NCR53c7x0_read8(SCNTL3_REG_800);
- ccf = hostdata->saved_scntl3 & SCNTL3_800_CCF_MASK;
- if (expected_ccf != -1 && ccf != expected_ccf && !ccf) {
- hostdata->saved_scntl3 = (hostdata->saved_scntl3 &
- ~SCNTL3_800_CCF_MASK) | expected_ccf;
- if (!uninitialized) {
- printk ("scsi%d : reset ccf to %d from %d\n",
- host->host_no, expected_ccf, ccf);
- uninitialized = 1;
- }
- }
- } else
- ccf = 0;
-
- /*
- * If we don't have a SCSI clock programmed, pick one on the upper
- * bound of that allowed by NCR so that our transfers err on the
- * slow side, since transfer period must be >= the agreed
- * upon period.
- */
-
- if ((!hostdata->scsi_clock) && (hostdata->scsi_clock = ccf_to_clock (ccf))
- == -1) {
- printk ("scsi%d : clock conversion factor %d unknown.\n"
- " synchronous transfers disabled\n",
- host->host_no, ccf);
- hostdata->options &= ~OPTION_SYNCHRONOUS;
- hostdata->scsi_clock = 0;
- }
-
- if (expected_clock == -1 || hostdata->scsi_clock != expected_clock)
- printk ("scsi%d : using %dMHz SCSI clock\n", host->host_no,
- hostdata->scsi_clock / 1000000);
-
- for (i = 0; i < 16; ++i)
- hostdata->cmd_allocated[i] = 0;
-
- if (hostdata->init_save_regs)
- hostdata->init_save_regs (host);
- if (hostdata->init_fixup)
- hostdata->init_fixup (host);
-
- if (!the_template) {
- the_template = host->hostt;
- first_host = host;
- }
-
- /*
- * Linux SCSI drivers have always been plagued with initialization
- * problems - some didn't work with the BIOS disabled since they expected
- * initialization from it, some didn't work when the networking code
- * was enabled and registers got scrambled, etc.
- *
- * To avoid problems like this, in the future, we will do a soft
- * reset on the SCSI chip, taking it back to a sane state.
- */
-
- hostdata->soft_reset (host);
-
-#if 1
- hostdata->debug_count_limit = -1;
-#else
- hostdata->debug_count_limit = 1;
-#endif
- hostdata->intrs = -1;
- hostdata->resets = -1;
- memcpy ((void *) hostdata->synchronous_want, (void *) sdtr_message,
- sizeof (hostdata->synchronous_want));
-
- NCR53c7x0_driver_init (host);
-
- /*
- * Set up an interrupt handler if we aren't already sharing an IRQ
- * with another board.
- */
-
- for (search = first_host; search && !(search->hostt == the_template &&
- search->irq == host->irq && search != host); search=search->next);
-
- if (!search) {
- if (request_irq(host->irq, NCR53c7x0_intr, SA_INTERRUPT, "53c7,8xx")) {
- printk("scsi%d : IRQ%d not free, detaching\n"
- " You have either a configuration problem, or a\n"
- " broken BIOS. You may wish to manually assign\n"
- " an interrupt to the NCR board rather than using\n"
- " an automatic setting.\n",
- host->host_no, host->irq);
- scsi_unregister (host);
- return -1;
- }
- } else {
- printk("scsi%d : using interrupt handler previously installed for scsi%d\n",
- host->host_no, search->host_no);
- }
-
-
- if ((hostdata->run_tests && hostdata->run_tests(host) == -1) ||
- (hostdata->options & OPTION_DEBUG_TESTS_ONLY)) {
- /* XXX Should disable interrupts, etc. here */
- scsi_unregister (host);
- return -1;
- } else {
- if (host->io_port) {
- host->n_io_port = 128;
- request_region (host->io_port, host->n_io_port, "ncr53c7,8xx");
- }
- }
-
- if (NCR53c7x0_read8 (SBCL_REG) & SBCL_BSY) {
- printk ("scsi%d : bus wedge, doing SCSI reset\n", host->host_no);
- hard_reset (host);
- }
- return 0;
-}
-
-/*
- * Function : static int normal_init(Scsi_Host_Template *tpnt, int board,
- * int chip, u32 base, int io_port, int irq, int dma, int pcivalid,
- * unsigned char pci_bus, unsigned char pci_device_fn,
- * long long options);
- *
- * Purpose : initializes a NCR53c7,8x0 based on base addresses,
- * IRQ, and DMA channel.
- *
- * Useful where a new NCR chip is backwards compatible with
- * a supported chip, but the DEVICE ID has changed so it
- * doesn't show up when the autoprobe does a pcibios_find_device.
- *
- * Inputs : tpnt - Template for this SCSI adapter, board - board level
- * product, chip - 810, 820, or 825, bus - PCI bus, device_fn -
- * device and function encoding as used by PCI BIOS calls.
- *
- * Returns : 0 on success, -1 on failure.
- *
- */
-
-static int
-normal_init (Scsi_Host_Template *tpnt, int board, int chip,
- u32 base, int io_port, int irq, int dma, int pci_valid,
- unsigned char pci_bus, unsigned char pci_device_fn, long long options) {
- struct Scsi_Host *instance;
- struct NCR53c7x0_hostdata *hostdata;
- char chip_str[80];
- int script_len = 0, dsa_len = 0, size = 0, max_cmd_size = 0,
- schedule_size = 0, ok = 0;
- void *tmp;
-
- options |= perm_options;
-
- switch (chip) {
- case 825:
- case 820:
- case 815:
- case 810:
- schedule_size = (tpnt->can_queue + 1) * 8 /* JUMP instruction size */;
- script_len = NCR53c8xx_script_len;
- dsa_len = NCR53c8xx_dsa_len;
- options |= OPTION_INTFLY;
- sprintf (chip_str, "NCR53c%d", chip);
- break;
- default:
- printk("scsi-ncr53c7,8xx : unsupported SCSI chip %d\n", chip);
- return -1;
- }
-
- printk("scsi-ncr53c7,8xx : %s at memory 0x%x, io 0x%x, irq %d",
- chip_str, (unsigned) base, io_port, irq);
- if (dma == DMA_NONE)
- printk("\n");
- else
- printk(", dma %d\n", dma);
-
- if ((chip / 100 == 8) && !pci_valid)
- printk ("scsi-ncr53c7,8xx : for better reliability and performance, please use the\n"
- " PCI override instead.\n"
- " Syntax : ncr53c8{10,15,20,25}=pci,<bus>,<device>,<function>\n"
- " <bus> and <device> are usually 0.\n");
-
- if (options & OPTION_DEBUG_PROBE_ONLY) {
- printk ("scsi-ncr53c7,8xx : probe only enabled, aborting initialization\n");
- return -1;
- }
-
- max_cmd_size = sizeof(struct NCR53c7x0_cmd) + dsa_len +
- /* Size of dynamic part of command structure : */
- 2 * /* Worst case : we don't know if we need DATA IN or DATA out */
- ( 2 * /* Current instructions per scatter/gather segment */
- tpnt->sg_tablesize +
- 3 /* Current startup / termination required per phase */
- ) *
- 8 /* Each instruction is eight bytes */;
-
- /* Allocate fixed part of hostdata, dynamic part to hold appropriate
- SCSI SCRIPT(tm) plus a single, maximum-sized NCR53c7x0_cmd structure.
-
- We need a NCR53c7x0_cmd structure for scan_scsis() when we are
- not loaded as a module, and when we're loaded as a module, we
- can't use a non-dynamically allocated structure because modules
- are vmalloc()'d, which can allow structures to cross page
- boundaries and breaks our physical/virtual address assumptions
- for DMA.
-
- So, we stick it past the end of our hostdata structure.
-
- ASSUMPTION :
- Regardless of how many simultaneous SCSI commands we allow,
- the probe code only executes a _single_ instruction at a time,
- so we only need one here, and don't need to allocate NCR53c7x0_cmd
- structures for each target until we are no longer in scan_scsis
- and kmalloc() has become functional (memory_init() happens
- after all device driver initialization).
- */
-
- size = sizeof(struct NCR53c7x0_hostdata) + script_len +
- /* Note that alignment will be guaranteed, since we put the command
- allocated at probe time after the fixed-up SCSI script, which
- consists of 32 bit words, aligned on a 32 bit boundary. But
- on a 64bit machine we need 8 byte alignment for hostdata->free, so
- we add in another 4 bytes to take care of potential misalignment
- */
- (sizeof(void *) - sizeof(u32)) + max_cmd_size + schedule_size;
-
- instance = scsi_register (tpnt, size);
- if (!instance)
- return -1;
-
- /* FIXME : if we ever support an ISA NCR53c7xx based board, we
- need to check if the chip is running in a 16 bit mode, and if so
- unregister it if it is past the 16M (0x1000000) mark */
-
- hostdata = (struct NCR53c7x0_hostdata *)
- instance->hostdata;
- hostdata->size = size;
- hostdata->script_count = script_len / sizeof(u32);
- hostdata = (struct NCR53c7x0_hostdata *) instance->hostdata;
- hostdata->board = board;
- hostdata->chip = chip;
- if ((hostdata->pci_valid = pci_valid)) {
- hostdata->pci_bus = pci_bus;
- hostdata->pci_device_fn = pci_device_fn;
- }
-
- /*
- * Being memory mapped is more desirable, since
- *
- * - Memory accesses may be faster.
- *
- * - The destination and source address spaces are the same for
- * all instructions, meaning we don't have to twiddle dmode or
- * any other registers.
- *
- * So, we try for memory mapped, and if we don't get it,
- * we go for port mapped, and that failing we tell the user
- * it can't work.
- */
-
- if (base) {
- instance->base = (unsigned char *) (unsigned long) base;
- /* Check for forced I/O mapping */
- if (!(options & OPTION_IO_MAPPED)) {
- options |= OPTION_MEMORY_MAPPED;
- ok = 1;
- }
- } else {
- options &= ~OPTION_MEMORY_MAPPED;
- }
-
- if (io_port) {
- instance->io_port = io_port;
- options |= OPTION_IO_MAPPED;
- ok = 1;
- } else {
- options &= ~OPTION_IO_MAPPED;
- }
-
- if (!ok) {
- printk ("scsi%d : not initializing, no I/O or memory mapping known \n",
- instance->host_no);
- scsi_unregister (instance);
- return -1;
- }
- instance->irq = irq;
- instance->dma_channel = dma;
-
- hostdata->options = options;
- hostdata->dsa_len = dsa_len;
- hostdata->max_cmd_size = max_cmd_size;
- hostdata->num_cmds = 1;
- /* Initialize single command */
- tmp = (hostdata->script + hostdata->script_count);
- hostdata->free = ROUNDUP(tmp, void *);
- hostdata->free->real = tmp;
- hostdata->free->size = max_cmd_size;
- hostdata->free->free = NULL;
- hostdata->free->next = NULL;
- hostdata->extra_allocate = 0;
-
- /* Allocate command start code space */
- hostdata->schedule = (chip == 700 || chip == 70066) ?
- NULL : (u32 *) ((char *)hostdata->free + max_cmd_size);
-
-/*
- * For diagnostic purposes, we don't really care how fast things blaze.
- * For profiling, we want to access the 800ns resolution system clock,
- * using a 'C' call on the host processor.
- *
- * Therefore, there's no need for the NCR chip to directly manipulate
- * this data, and we should put it wherever is most convienient for
- * Linux.
- */
- if (track_events)
- hostdata->events = (struct NCR53c7x0_event *) (track_events ?
- vmalloc (sizeof (struct NCR53c7x0_event) * track_events) : NULL);
- else
- hostdata->events = NULL;
-
- if (hostdata->events) {
- memset ((void *) hostdata->events, 0, sizeof(struct NCR53c7x0_event) *
- track_events);
- hostdata->event_size = track_events;
- hostdata->event_index = 0;
- } else
- hostdata->event_size = 0;
-
- return NCR53c7x0_init(instance);
-}
-
-
-/*
- * Function : static int ncr_pci_init(Scsi_Host_Template *tpnt, int board,
- * int chip, int bus, int device_fn, long long options)
- *
- * Purpose : initializes a NCR53c800 family based on the PCI
- * bus, device, and function location of it. Allows
- * reprogramming of latency timer and determining addresses
- * and whether bus mastering, etc. are OK.
- *
- * Useful where a new NCR chip is backwards compatible with
- * a supported chip, but the DEVICE ID has changed so it
- * doesn't show up when the autoprobe does a pcibios_find_device.
- *
- * Inputs : tpnt - Template for this SCSI adapter, board - board level
- * product, chip - 810, 820, or 825, bus - PCI bus, device_fn -
- * device and function encoding as used by PCI BIOS calls.
- *
- * Returns : 0 on success, -1 on failure.
- *
- */
-
-static int
-ncr_pci_init (Scsi_Host_Template *tpnt, int board, int chip,
- unsigned char bus, unsigned char device_fn, long long options) {
- unsigned short vendor_id, device_id, command;
-#ifdef LINUX_1_2
- unsigned long
-#else
- unsigned int
-#endif
- base, io_port;
- unsigned char irq, revision;
- int error, expected_chip;
- int expected_id = -1, max_revision = -1, min_revision = -1;
- int i;
-
- printk("scsi-ncr53c7,8xx : at PCI bus %d, device %d, function %d\n",
- bus, (int) (device_fn & 0xf8) >> 3,
- (int) device_fn & 7);
-
- if (!pcibios_present()) {
- printk("scsi-ncr53c7,8xx : not initializing due to lack of PCI BIOS,\n"
- " try using memory, port, irq override instead.\n");
- return -1;
- }
-
- if ((error = pcibios_read_config_word (bus, device_fn, PCI_VENDOR_ID,
- &vendor_id)) ||
- (error = pcibios_read_config_word (bus, device_fn, PCI_DEVICE_ID,
- &device_id)) ||
- (error = pcibios_read_config_word (bus, device_fn, PCI_COMMAND,
- &command)) ||
- (error = pcibios_read_config_dword (bus, device_fn,
- PCI_BASE_ADDRESS_0, &io_port)) ||
- (error = pcibios_read_config_dword (bus, device_fn,
- PCI_BASE_ADDRESS_1, &base)) ||
- (error = pcibios_read_config_byte (bus, device_fn, PCI_CLASS_REVISION,
- &revision)) ||
- (error = pcibios_read_config_byte (bus, device_fn, PCI_INTERRUPT_LINE,
- &irq))) {
- printk ("scsi-ncr53c7,8xx : error %s not initializing due to error reading configuration space\n"
- " perhaps you specified an incorrect PCI bus, device, or function.\n"
- , pcibios_strerror(error));
- return -1;
- }
-
- /* If any one ever clones the NCR chips, this will have to change */
-
- if (vendor_id != PCI_VENDOR_ID_NCR) {
- printk ("scsi-ncr53c7,8xx : not initializing, 0x%04x is not NCR vendor ID\n",
- (int) vendor_id);
- return -1;
- }
-
-
- /*
- * Bit 0 is the address space indicator and must be one for I/O
- * space mappings, bit 1 is reserved, discard them after checking
- * that they have the correct value of 1.
- */
-
- if (command & PCI_COMMAND_IO) {
- if ((io_port & 3) != 1) {
- printk ("scsi-ncr53c7,8xx : disabling I/O mapping since base address 0 (0x%x)\n"
- " bits 0..1 indicate a non-IO mapping\n",
- (unsigned) io_port);
- io_port = 0;
- } else
- io_port &= PCI_BASE_ADDRESS_IO_MASK;
- } else {
- io_port = 0;
- }
-
- if (command & PCI_COMMAND_MEMORY) {
- if ((base & PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_MEMORY) {
- printk("scsi-ncr53c7,8xx : disabling memory mapping since base address 1\n"
- " contains a non-memory mapping\n");
- base = 0;
- } else
- base &= PCI_BASE_ADDRESS_MEM_MASK;
- } else {
- base = 0;
- }
-
- if (!io_port && !base) {
- printk ("scsi-ncr53c7,8xx : not initializing, both I/O and memory mappings disabled\n");
- return -1;
- }
-
- if (!(command & PCI_COMMAND_MASTER)) {
- printk ("scsi-ncr53c7,8xx : not initializing, BUS MASTERING was disabled\n");
- return -1;
- }
-
- for (i = 0; i < NPCI_CHIP_IDS; ++i) {
- if (device_id == pci_chip_ids[i].pci_device_id) {
- max_revision = pci_chip_ids[i].max_revision;
- min_revision = pci_chip_ids[i].min_revision;
- expected_chip = pci_chip_ids[i].chip;
- }
- if (chip == pci_chip_ids[i].chip)
- expected_id = pci_chip_ids[i].pci_device_id;
- }
-
- if (chip && device_id != expected_id)
- printk ("scsi-ncr53c7,8xx : warning : device id of 0x%04x doesn't\n"
- " match expected 0x%04x\n",
- (unsigned int) device_id, (unsigned int) expected_id );
-
- if (max_revision != -1 && revision > max_revision)
- printk ("scsi-ncr53c7,8xx : warning : revision of %d is greater than %d.\n",
- (int) revision, max_revision);
- else if (min_revision != -1 && revision < min_revision)
- printk ("scsi-ncr53c7,8xx : warning : revision of %d is less than %d.\n",
- (int) revision, min_revision);
-
- if (io_port && check_region (io_port, 128)) {
- printk ("scsi-ncr53c7,8xx : IO region 0x%x to 0x%x is in use\n",
- (unsigned) io_port, (unsigned) io_port + 127);
- return -1;
- }
-
- return normal_init (tpnt, board, chip, (int) base, io_port,
- (int) irq, DMA_NONE, 1, bus, device_fn, options);
-}
-
-
-/*
- * Function : int NCR53c7xx_detect(Scsi_Host_Template *tpnt)
- *
- * Purpose : detects and initializes NCR53c7,8x0 SCSI chips
- * that were autoprobed, overridden on the LILO command line,
- * or specified at compile time.
- *
- * Inputs : tpnt - template for this SCSI adapter
- *
- * Returns : number of host adapters detected
- *
- */
-
-int
-NCR53c7xx_detect(Scsi_Host_Template *tpnt) {
- int i;
- int current_override;
- int count; /* Number of boards detected */
- unsigned char pci_bus, pci_device_fn;
- static short pci_index=0; /* Device index to PCI BIOS calls */
-
-#ifndef LINUX_1_2
- tpnt->proc_dir = &proc_scsi_ncr53c7xx;
-#endif
-
- for (current_override = count = 0; current_override < OVERRIDE_LIMIT;
- ++current_override) {
- if (overrides[current_override].pci ?
- !ncr_pci_init (tpnt, overrides[current_override].board,
- overrides[current_override].chip,
- (unsigned char) overrides[current_override].data.pci.bus,
- (((overrides[current_override].data.pci.device
- << 3) & 0xf8)|(overrides[current_override].data.pci.function &
- 7)), overrides[current_override].options):
- !normal_init (tpnt, overrides[current_override].board,
- overrides[current_override].chip,
- overrides[current_override].data.normal.base,
- overrides[current_override].data.normal.io_port,
- overrides[current_override].data.normal.irq,
- overrides[current_override].data.normal.dma,
- 0 /* PCI data invalid */, 0 /* PCI bus place holder */,
- 0 /* PCI device_function place holder */,
- overrides[current_override].options)) {
- ++count;
- }
- }
-
- if (pcibios_present()) {
- for (i = 0; i < NPCI_CHIP_IDS; ++i)
- for (pci_index = 0;
- !pcibios_find_device (PCI_VENDOR_ID_NCR,
- pci_chip_ids[i].pci_device_id, pci_index, &pci_bus,
- &pci_device_fn);
- ++pci_index)
- if (!ncr_pci_init (tpnt, BOARD_GENERIC, pci_chip_ids[i].chip,
- pci_bus, pci_device_fn, /* no options */ 0))
- ++count;
- }
- return count;
-}
-
-/* NCR53c810 and NCR53c820 script handling code */
-
-#include "53c8xx_d.h"
-#ifdef A_int_debug_sync
-#define DEBUG_SYNC_INTR A_int_debug_sync
-#endif
-static int NCR53c8xx_script_len = sizeof (SCRIPT);
-static int NCR53c8xx_dsa_len = A_dsa_end + Ent_dsa_zero - Ent_dsa_code_template;
-
-/*
- * Function : static void NCR53c8x0_init_fixup (struct Scsi_Host *host)
- *
- * Purpose : copy and fixup the SCSI SCRIPTS(tm) code for this device.
- *
- * Inputs : host - pointer to this host adapter's structure
- *
- */
-
-static void
-NCR53c8x0_init_fixup (struct Scsi_Host *host) {
- NCR53c7x0_local_declare();
- struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
- host->hostdata;
- unsigned char tmp;
- int i, ncr_to_memory, memory_to_ncr;
- u32 base;
- NCR53c7x0_local_setup(host);
-
-
- /* XXX - NOTE : this code MUST be made endian aware */
- /* Copy code into buffer that was allocated at detection time. */
- memcpy ((void *) hostdata->script, (void *) SCRIPT,
- sizeof(SCRIPT));
- /* Fixup labels */
- for (i = 0; i < PATCHES; ++i)
- hostdata->script[LABELPATCHES[i]] +=
- virt_to_bus(hostdata->script);
- /* Fixup addresses of constants that used to be EXTERNAL */
-
- patch_abs_32 (hostdata->script, 0, NCR53c7xx_msg_abort,
- virt_to_bus(&(hostdata->NCR53c7xx_msg_abort)));
- patch_abs_32 (hostdata->script, 0, NCR53c7xx_msg_reject,
- virt_to_bus(&(hostdata->NCR53c7xx_msg_reject)));
- patch_abs_32 (hostdata->script, 0, NCR53c7xx_zero,
- virt_to_bus(&(hostdata->NCR53c7xx_zero)));
- patch_abs_32 (hostdata->script, 0, NCR53c7xx_sink,
- virt_to_bus(&(hostdata->NCR53c7xx_sink)));
- patch_abs_32 (hostdata->script, 0, NOP_insn,
- virt_to_bus(&(hostdata->NOP_insn)));
- patch_abs_32 (hostdata->script, 0, schedule,
- virt_to_bus((void *) hostdata->schedule));
-
- /* Fixup references to external variables: */
- for (i = 0; i < EXTERNAL_PATCHES_LEN; ++i)
- hostdata->script[EXTERNAL_PATCHES[i].offset] +=
- virt_to_bus(EXTERNAL_PATCHES[i].address);
-
- /*
- * Fixup absolutes set at boot-time.
- *
- * All non-code absolute variables suffixed with "dsa_" and "int_"
- * are constants, and need no fixup provided the assembler has done
- * it for us (I don't know what the "real" NCR assembler does in
- * this case, my assembler does the right magic).
- */
-
- patch_abs_rwri_data (hostdata->script, 0, dsa_save_data_pointer,
- Ent_dsa_code_save_data_pointer - Ent_dsa_zero);
- patch_abs_rwri_data (hostdata->script, 0, dsa_restore_pointers,
- Ent_dsa_code_restore_pointers - Ent_dsa_zero);
- patch_abs_rwri_data (hostdata->script, 0, dsa_check_reselect,
- Ent_dsa_code_check_reselect - Ent_dsa_zero);
-
- /*
- * Just for the hell of it, preserve the settings of
- * Burst Length and Enable Read Line bits from the DMODE
- * register. Make sure SCRIPTS start automagically.
- */
-
- tmp = NCR53c7x0_read8(DMODE_REG_10);
- tmp &= (DMODE_800_ERL | DMODE_BL_MASK);
-
- if (!(hostdata->options & OPTION_MEMORY_MAPPED)) {
- base = (u32) host->io_port;
- memory_to_ncr = tmp|DMODE_800_DIOM;
- ncr_to_memory = tmp|DMODE_800_SIOM;
- } else {
- base = virt_to_bus(host->base);
- memory_to_ncr = ncr_to_memory = tmp;
- }
-
- patch_abs_32 (hostdata->script, 0, addr_scratch, base + SCRATCHA_REG_800);
- patch_abs_32 (hostdata->script, 0, addr_temp, base + TEMP_REG);
-
- /*
- * I needed some variables in the script to be accessible to
- * both the NCR chip and the host processor. For these variables,
- * I made the arbitrary decision to store them directly in the
- * hostdata structure rather than in the RELATIVE area of the
- * SCRIPTS.
- */
-
-
- patch_abs_rwri_data (hostdata->script, 0, dmode_memory_to_memory, tmp);
- patch_abs_rwri_data (hostdata->script, 0, dmode_memory_to_ncr, memory_to_ncr);
- patch_abs_rwri_data (hostdata->script, 0, dmode_ncr_to_memory, ncr_to_memory);
-
- patch_abs_32 (hostdata->script, 0, msg_buf,
- virt_to_bus((void *)&(hostdata->msg_buf)));
- patch_abs_32 (hostdata->script, 0, reconnect_dsa_head,
- virt_to_bus((void *)&(hostdata->reconnect_dsa_head)));
- patch_abs_32 (hostdata->script, 0, addr_reconnect_dsa_head,
- virt_to_bus((void *)&(hostdata->addr_reconnect_dsa_head)));
- patch_abs_32 (hostdata->script, 0, reselected_identify,
- virt_to_bus((void *)&(hostdata->reselected_identify)));
-/* reselected_tag is currently unused */
-#if 0
- patch_abs_32 (hostdata->script, 0, reselected_tag,
- virt_to_bus((void *)&(hostdata->reselected_tag)));
-#endif
-
- patch_abs_32 (hostdata->script, 0, test_dest,
- virt_to_bus((void*)&hostdata->test_dest));
- patch_abs_32 (hostdata->script, 0, test_src,
- virt_to_bus(&hostdata->test_source));
-
- patch_abs_rwri_data (hostdata->script, 0, dsa_check_reselect,
- (unsigned char)(Ent_dsa_code_check_reselect - Ent_dsa_zero));
-
-/* These are for event logging; the ncr_event enum contains the
- actual interrupt numbers. */
-#ifdef A_int_EVENT_SELECT
- patch_abs_32 (hostdata->script, 0, int_EVENT_SELECT, (u32) EVENT_SELECT);
-#endif
-#ifdef A_int_EVENT_DISCONNECT
- patch_abs_32 (hostdata->script, 0, int_EVENT_DISCONNECT, (u32) EVENT_DISCONNECT);
-#endif
-#ifdef A_int_EVENT_RESELECT
- patch_abs_32 (hostdata->script, 0, int_EVENT_RESELECT, (u32) EVENT_RESELECT);
-#endif
-#ifdef A_int_EVENT_COMPLETE
- patch_abs_32 (hostdata->script, 0, int_EVENT_COMPLETE, (u32) EVENT_COMPLETE);
-#endif
-#ifdef A_int_EVENT_IDLE
- patch_abs_32 (hostdata->script, 0, int_EVENT_IDLE, (u32) EVENT_IDLE);
-#endif
-#ifdef A_int_EVENT_SELECT_FAILED
- patch_abs_32 (hostdata->script, 0, int_EVENT_SELECT_FAILED,
- (u32) EVENT_SELECT_FAILED);
-#endif
-#ifdef A_int_EVENT_BEFORE_SELECT
- patch_abs_32 (hostdata->script, 0, int_EVENT_BEFORE_SELECT,
- (u32) EVENT_BEFORE_SELECT);
-#endif
-#ifdef A_int_EVENT_RESELECT_FAILED
- patch_abs_32 (hostdata->script, 0, int_EVENT_RESELECT_FAILED,
- (u32) EVENT_RESELECT_FAILED);
-#endif
-
- /*
- * Make sure the NCR and Linux code agree on the location of
- * certain fields.
- */
-
- hostdata->E_accept_message = Ent_accept_message;
- hostdata->E_command_complete = Ent_command_complete;
- hostdata->E_cmdout_cmdout = Ent_cmdout_cmdout;
- hostdata->E_data_transfer = Ent_data_transfer;
- hostdata->E_debug_break = Ent_debug_break;
- hostdata->E_dsa_code_template = Ent_dsa_code_template;
- hostdata->E_dsa_code_template_end = Ent_dsa_code_template_end;
- hostdata->E_end_data_transfer = Ent_end_data_transfer;
- hostdata->E_initiator_abort = Ent_initiator_abort;
- hostdata->E_msg_in = Ent_msg_in;
- hostdata->E_other_transfer = Ent_other_transfer;
- hostdata->E_other_in = Ent_other_in;
- hostdata->E_other_out = Ent_other_out;
- hostdata->E_reject_message = Ent_reject_message;
- hostdata->E_respond_message = Ent_respond_message;
- hostdata->E_select = Ent_select;
- hostdata->E_select_msgout = Ent_select_msgout;
- hostdata->E_target_abort = Ent_target_abort;
-#ifdef Ent_test_0
- hostdata->E_test_0 = Ent_test_0;
-#endif
- hostdata->E_test_1 = Ent_test_1;
- hostdata->E_test_2 = Ent_test_2;
-#ifdef Ent_test_3
- hostdata->E_test_3 = Ent_test_3;
-#endif
- hostdata->E_wait_reselect = Ent_wait_reselect;
- hostdata->E_dsa_code_begin = Ent_dsa_code_begin;
-
- hostdata->dsa_cmdout = A_dsa_cmdout;
- hostdata->dsa_cmnd = A_dsa_cmnd;
- hostdata->dsa_datain = A_dsa_datain;
- hostdata->dsa_dataout = A_dsa_dataout;
- hostdata->dsa_end = A_dsa_end;
- hostdata->dsa_msgin = A_dsa_msgin;
- hostdata->dsa_msgout = A_dsa_msgout;
- hostdata->dsa_msgout_other = A_dsa_msgout_other;
- hostdata->dsa_next = A_dsa_next;
- hostdata->dsa_select = A_dsa_select;
- hostdata->dsa_start = Ent_dsa_code_template - Ent_dsa_zero;
- hostdata->dsa_status = A_dsa_status;
- hostdata->dsa_jump_dest = Ent_dsa_code_fix_jump - Ent_dsa_zero +
- 8 /* destination operand */;
-
- /* sanity check */
- if (A_dsa_fields_start != Ent_dsa_code_template_end -
- Ent_dsa_zero)
- printk("scsi%d : NCR dsa_fields start is %d not %d\n",
- host->host_no, A_dsa_fields_start, Ent_dsa_code_template_end -
- Ent_dsa_zero);
-
- printk("scsi%d : NCR code relocated to 0x%lx (virt 0x%p)\n", host->host_no,
- virt_to_bus(hostdata->script), hostdata->script);
-}
-
-/*
- * Function : static int NCR53c8xx_run_tests (struct Scsi_Host *host)
- *
- * Purpose : run various verification tests on the NCR chip,
- * including interrupt generation, and proper bus mastering
- * operation.
- *
- * Inputs : host - a properly initialized Scsi_Host structure
- *
- * Preconditions : the NCR chip must be in a halted state.
- *
- * Returns : 0 if all tests were successful, -1 on error.
- *
- */
-
-static int
-NCR53c8xx_run_tests (struct Scsi_Host *host) {
- NCR53c7x0_local_declare();
- struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
- host->hostdata;
- unsigned long timeout;
- u32 start;
- int failed, i;
- unsigned long flags;
- NCR53c7x0_local_setup(host);
-
- /* The NCR chip _must_ be idle to run the test scripts */
-
- save_flags(flags);
- cli();
- if (!hostdata->idle) {
- printk ("scsi%d : chip not idle, aborting tests\n", host->host_no);
- restore_flags(flags);
- return -1;
- }
-
- /*
- * Check for functional interrupts, this could work as an
- * autoprobe routine.
- */
-
- if ((hostdata->options & OPTION_DEBUG_TEST1) &&
- hostdata->state != STATE_DISABLED) {
- hostdata->idle = 0;
- hostdata->test_running = 1;
- hostdata->test_completed = -1;
- hostdata->test_dest = 0;
- hostdata->test_source = 0xdeadbeef;
- start = virt_to_bus (hostdata->script) + hostdata->E_test_1;
- hostdata->state = STATE_RUNNING;
- printk ("scsi%d : test 1", host->host_no);
- NCR53c7x0_write32 (DSP_REG, start);
- printk (" started\n");
- sti();
-
- /*
- * This is currently a .5 second timeout, since (in theory) no slow
- * board will take that long. In practice, we've seen one
- * pentium which ocassionally fails with this, but works with
- * 10 times as much?
- */
-
- timeout = jiffies + 5 * HZ / 10;
- while ((hostdata->test_completed == -1) && jiffies < timeout)
- barrier();
-
- failed = 1;
- if (hostdata->test_completed == -1)
- printk ("scsi%d : driver test 1 timed out%s\n",host->host_no ,
- (hostdata->test_dest == 0xdeadbeef) ?
- " due to lost interrupt.\n"
- " Please verify that the correct IRQ is being used for your board,\n"
- " and that the motherboard IRQ jumpering matches the PCI setup on\n"
- " PCI systems.\n"
- " If you are using a NCR53c810 board in a PCI system, you should\n"
- " also verify that the board is jumpered to use PCI INTA, since\n"
- " most PCI motherboards lack support for INTB, INTC, and INTD.\n"
- : "");
- else if (hostdata->test_completed != 1)
- printk ("scsi%d : test 1 bad interrupt value (%d)\n",
- host->host_no, hostdata->test_completed);
- else
- failed = (hostdata->test_dest != 0xdeadbeef);
-
- if (hostdata->test_dest != 0xdeadbeef) {
- printk ("scsi%d : driver test 1 read 0x%x instead of 0xdeadbeef indicating a\n"
- " probable cache invalidation problem. Please configure caching\n"
- " as write-through or disabled\n",
- host->host_no, hostdata->test_dest);
- }
-
- if (failed) {
- printk ("scsi%d : DSP = 0x%p (script at 0x%p, start at 0x%x)\n",
- host->host_no, bus_to_virt(NCR53c7x0_read32(DSP_REG)),
- hostdata->script, start);
- printk ("scsi%d : DSPS = 0x%x\n", host->host_no,
- NCR53c7x0_read32(DSPS_REG));
- restore_flags(flags);
- return -1;
- }
- hostdata->test_running = 0;
- }
-
- if ((hostdata->options & OPTION_DEBUG_TEST2) &&
- hostdata->state != STATE_DISABLED) {
- u32 dsa[48];
- unsigned char identify = IDENTIFY(0, 0);
- unsigned char cmd[6];
- unsigned char data[36];
- unsigned char status = 0xff;
- unsigned char msg = 0xff;
-
- cmd[0] = INQUIRY;
- cmd[1] = cmd[2] = cmd[3] = cmd[5] = 0;
- cmd[4] = sizeof(data);
-
- dsa[2] = 1;
- dsa[3] = virt_to_bus(&identify);
- dsa[4] = 6;
- dsa[5] = virt_to_bus(&cmd);
- dsa[6] = sizeof(data);
- dsa[7] = virt_to_bus(&data);
- dsa[8] = 1;
- dsa[9] = virt_to_bus(&status);
- dsa[10] = 1;
- dsa[11] = virt_to_bus(&msg);
-
- for (i = 0; i < 3; ++i) {
- cli();
- if (!hostdata->idle) {
- printk ("scsi%d : chip not idle, aborting tests\n", host->host_no);
- restore_flags(flags);
- return -1;
- }
-
- /* SCNTL3 SDID */
- dsa[0] = (0x33 << 24) | (i << 16) ;
- hostdata->idle = 0;
- hostdata->test_running = 2;
- hostdata->test_completed = -1;
- start = virt_to_bus(hostdata->script) + hostdata->E_test_2;
- hostdata->state = STATE_RUNNING;
- NCR53c7x0_write32 (DSA_REG, virt_to_bus(dsa));
- NCR53c7x0_write32 (DSP_REG, start);
- sti();
-
- timeout = jiffies + 5 * HZ; /* arbitrary */
- while ((hostdata->test_completed == -1) && jiffies < timeout)
- barrier();
- NCR53c7x0_write32 (DSA_REG, 0);
-
- if (hostdata->test_completed == 2) {
- data[35] = 0;
- printk ("scsi%d : test 2 INQUIRY to target %d, lun 0 : %s\n",
- host->host_no, i, data + 8);
- printk ("scsi%d : status ", host->host_no);
- print_status (status);
- printk ("\nscsi%d : message ", host->host_no);
- print_msg (&msg);
- printk ("\n");
- } else if (hostdata->test_completed == 3) {
- printk("scsi%d : test 2 no connection with target %d\n",
- host->host_no, i);
- if (!hostdata->idle) {
- printk("scsi%d : not idle\n", host->host_no);
- restore_flags(flags);
- return -1;
- }
- } else if (hostdata->test_completed == -1) {
- printk ("scsi%d : test 2 timed out\n", host->host_no);
- restore_flags(flags);
- return -1;
- }
- hostdata->test_running = 0;
- }
- }
-
- restore_flags(flags);
- return 0;
-}
-
-/*
- * Function : static void NCR53c8xx_dsa_fixup (struct NCR53c7x0_cmd *cmd)
- *
- * Purpose : copy the NCR53c8xx dsa structure into cmd's dsa buffer,
- * performing all necessary relocation.
- *
- * Inputs : cmd, a NCR53c7x0_cmd structure with a dsa area large
- * enough to hold the NCR53c8xx dsa.
- */
-
-static void
-NCR53c8xx_dsa_fixup (struct NCR53c7x0_cmd *cmd) {
- Scsi_Cmnd *c = cmd->cmd;
- struct Scsi_Host *host = c->host;
- struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
- host->hostdata;
- int i;
-
- memcpy (cmd->dsa, hostdata->script + (hostdata->E_dsa_code_template / 4),
- hostdata->E_dsa_code_template_end - hostdata->E_dsa_code_template);
-
- /*
- * Note : within the NCR 'C' code, dsa points to the _start_
- * of the DSA structure, and _not_ the offset of dsa_zero within
- * that structure used to facilitate shorter signed offsets
- * for the 8 bit ALU.
- *
- * The implications of this are that
- *
- * - 32 bit A_dsa_* absolute values require an additional
- * dsa_zero added to their value to be correct, since they are
- * relative to dsa_zero which is in essentially a separate
- * space from the code symbols.
- *
- * - All other symbols require no special treatment.
- */
-
- patch_abs_tci_data (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
- dsa_temp_lun, c->lun);
- patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
- dsa_temp_addr_next, virt_to_bus(&cmd->dsa_next_addr));
- patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
- dsa_temp_next, virt_to_bus(cmd->dsa) + Ent_dsa_zero -
- Ent_dsa_code_template + A_dsa_next);
- patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
- dsa_temp_sync, virt_to_bus((void *)hostdata->sync[c->target].script));
- patch_abs_tci_data (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
- dsa_temp_target, c->target);
- /* XXX - new pointer stuff */
- patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
- dsa_temp_addr_saved_pointer, virt_to_bus(&cmd->saved_data_pointer));
- patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
- dsa_temp_addr_saved_residual, virt_to_bus(&cmd->saved_residual));
- patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
- dsa_temp_addr_residual, virt_to_bus(&cmd->residual));
-
- /* XXX - new start stuff */
- patch_abs_32 (cmd->dsa, Ent_dsa_code_template / sizeof(u32),
- dsa_temp_addr_dsa_value, virt_to_bus(&cmd->dsa_addr));
-
-}
-
-/*
- * Function : run_process_issue_queue (void)
- *
- * Purpose : insure that the coroutine is running and will process our
- * request. process_issue_queue_running is checked/set here (in an
- * inline function) rather than in process_issue_queue itself to reduce
- * the chances of stack overflow.
- *
- */
-
-static volatile int process_issue_queue_running = 0;
-
-static __inline__ void
-run_process_issue_queue(void) {
- unsigned long flags;
- save_flags (flags);
- cli();
- if (!process_issue_queue_running) {
- process_issue_queue_running = 1;
- process_issue_queue(flags);
- /*
- * process_issue_queue_running is cleared in process_issue_queue
- * once it can't do more work, and process_issue_queue exits with
- * interrupts disabled.
- */
- }
- restore_flags (flags);
-}
-
-/*
- * Function : static void abnormal_finished (struct NCR53c7x0_cmd *cmd, int
- * result)
- *
- * Purpose : mark SCSI command as finished, OR'ing the host portion
- * of the result word into the result field of the corresponding
- * Scsi_Cmnd structure, and removing it from the internal queues.
- *
- * Inputs : cmd - command, result - entire result field
- *
- * Preconditions : the NCR chip should be in a halted state when
- * abnormal_finished is run, since it modifies structures which
- * the NCR expects to have exclusive access to.
- */
-
-static void
-abnormal_finished (struct NCR53c7x0_cmd *cmd, int result) {
- Scsi_Cmnd *c = cmd->cmd;
- struct Scsi_Host *host = c->host;
- struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
- host->hostdata;
- unsigned long flags;
- int left, found;
- volatile struct NCR53c7x0_cmd * linux_search;
- volatile struct NCR53c7x0_cmd * volatile *linux_prev;
- volatile u32 *ncr_prev, *current, ncr_search;
-
-#if 0
- printk ("scsi%d: abnormal finished\n", host->host_no);
-#endif
-
- save_flags(flags);
- cli();
- found = 0;
- /*
- * Traverse the NCR issue array until we find a match or run out
- * of instructions. Instructions in the NCR issue array are
- * either JUMP or NOP instructions, which are 2 words in length.
- */
-
-
- for (found = 0, left = host->can_queue, current = hostdata->schedule;
- left > 0; --left, current += 2)
- {
- if (issue_to_cmd (host, hostdata, (u32 *) current) == cmd)
- {
- current[0] = hostdata->NOP_insn;
- current[1] = 0xdeadbeef;
- ++found;
- break;
- }
- }
-
- /*
- * Traverse the NCR reconnect list of DSA structures until we find
- * a pointer to this dsa or have found too many command structures.
- * We let prev point at the next field of the previous element or
- * head of the list, so we don't do anything different for removing
- * the head element.
- */
-
- for (left = host->can_queue,
- ncr_search = hostdata->reconnect_dsa_head,
- ncr_prev = &hostdata->reconnect_dsa_head;
- left >= 0 && ncr_search &&
- ((char*)bus_to_virt(ncr_search) + hostdata->dsa_start)
- != (char *) cmd->dsa;
- ncr_prev = (u32*) ((char*)bus_to_virt(ncr_search) +
- hostdata->dsa_next), ncr_search = *ncr_prev, --left);
-
- if (left < 0)
- printk("scsi%d: loop detected in ncr reonncect list\n",
- host->host_no);
- else if (ncr_search)
- if (found)
- printk("scsi%d: scsi %ld in ncr issue array and reconnect lists\n",
- host->host_no, c->pid);
- else {
- volatile u32 * next = (u32 *)
- ((char *)bus_to_virt(ncr_search) + hostdata->dsa_next);
- *ncr_prev = *next;
-/* If we're at the tail end of the issue queue, update that pointer too. */
- found = 1;
- }
-
- /*
- * Traverse the host running list until we find this command or discover
- * we have too many elements, pointing linux_prev at the next field of the
- * linux_previous element or head of the list, search at this element.
- */
-
- for (left = host->can_queue, linux_search = hostdata->running_list,
- linux_prev = &hostdata->running_list;
- left >= 0 && linux_search && linux_search != cmd;
- linux_prev = &(linux_search->next),
- linux_search = linux_search->next, --left);
-
- if (left < 0)
- printk ("scsi%d: loop detected in host running list for scsi pid %ld\n",
- host->host_no, c->pid);
- else if (linux_search) {
- *linux_prev = linux_search->next;
- --hostdata->busy[c->target][c->lun];
- }
-
- /* Return the NCR command structure to the free list */
- cmd->next = hostdata->free;
- hostdata->free = cmd;
- c->host_scribble = NULL;
-
- /* And return */
- c->result = result;
- c->scsi_done(c);
-
- restore_flags(flags);
- run_process_issue_queue();
-}
-
-/*
- * Function : static void intr_break (struct Scsi_Host *host,
- * struct NCR53c7x0_cmd *cmd)
- *
- * Purpose : Handler for breakpoint interrupts from a SCSI script
- *
- * Inputs : host - pointer to this host adapter's structure,
- * cmd - pointer to the command (if any) dsa was pointing
- * to.
- *
- */
-
-static void
-intr_break (struct Scsi_Host *host, struct
- NCR53c7x0_cmd *cmd) {
- NCR53c7x0_local_declare();
- struct NCR53c7x0_break *bp;
-#if 0
- Scsi_Cmnd *c = cmd ? cmd->cmd : NULL;
-#endif
- u32 *dsp;
- struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
- host->hostdata;
- unsigned long flags;
- NCR53c7x0_local_setup(host);
-
- /*
- * Find the break point corresponding to this address, and
- * dump the appropriate debugging information to standard
- * output.
- */
- save_flags(flags);
- cli();
- dsp = (u32 *) bus_to_virt(NCR53c7x0_read32(DSP_REG));
- for (bp = hostdata->breakpoints; bp && bp->address != dsp;
- bp = bp->next);
- if (!bp)
- panic("scsi%d : break point interrupt from %p with no breakpoint!",
- host->host_no, dsp);
-
- /*
- * Configure the NCR chip for manual start mode, so that we can
- * point the DSP register at the instruction that follows the
- * INT int_debug_break instruction.
- */
-
- NCR53c7x0_write8 (hostdata->dmode,
- NCR53c7x0_read8(hostdata->dmode)|DMODE_MAN);
-
- /*
- * And update the DSP register, using the size of the old
- * instruction in bytes.
- */
-
- restore_flags(flags);
-}
-/*
- * Function : static void print_synchronous (const char *prefix,
- * const unsigned char *msg)
- *
- * Purpose : print a pretty, user and machine parsable representation
- * of a SDTR message, including the "real" parameters, data
- * clock so we can tell transfer rate at a glance.
- *
- * Inputs ; prefix - text to prepend, msg - SDTR message (5 bytes)
- */
-
-static void
-print_synchronous (const char *prefix, const unsigned char *msg) {
- if (msg[4]) {
- int Hz = 1000000000 / (msg[3] * 4);
- int integer = Hz / 1000000;
- int fraction = (Hz - (integer * 1000000)) / 10000;
- printk ("%speriod %dns offset %d %d.%02dMHz %s SCSI%s\n",
- prefix, (int) msg[3] * 4, (int) msg[4], integer, fraction,
- (((msg[3] * 4) < 200) ? "FAST" : "synchronous"),
- (((msg[3] * 4) < 200) ? "-II" : ""));
- } else
- printk ("%sasynchronous SCSI\n", prefix);
-}
-
-/*
- * Function : static void set_synchronous (struct Scsi_Host *host,
- * int target, int sxfer, int scntl3, int now_connected)
- *
- * Purpose : reprogram transfers between the selected SCSI initiator and
- * target with the given register values; in the indirect
- * select operand, reselection script, and chip registers.
- *
- * Inputs : host - NCR53c7,8xx SCSI host, target - number SCSI target id,
- * sxfer and scntl3 - NCR registers. now_connected - if non-zero,
- * we should reprogram the registers now too.
- */
-
-static void
-set_synchronous (struct Scsi_Host *host, int target, int sxfer, int scntl3,
- int now_connected) {
- NCR53c7x0_local_declare();
- struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
- host->hostdata;
- u32 *script;
- NCR53c7x0_local_setup(host);
-
- /* These are eight bit registers */
- sxfer &= 0xff;
- scntl3 &= 0xff;
-
- hostdata->sync[target].sxfer_sanity = sxfer;
- hostdata->sync[target].scntl3_sanity = scntl3;
-
-/*
- * HARD CODED : synchronous script is EIGHT words long. This
- * must agree with 53c7.8xx.h
- */
-
- if ((hostdata->chip != 700) && (hostdata->chip != 70066)) {
- hostdata->sync[target].select_indirect = (scntl3 << 24) |
- (target << 16) | (sxfer << 8);
-
- script = (u32 *) hostdata->sync[target].script;
-
- /* XXX - add NCR53c7x0 code to reprogram SCF bits if we want to */
- if ((hostdata->chip / 100) == 8) {
- script[0] = ((DCMD_TYPE_RWRI | DCMD_RWRI_OPC_MODIFY |
- DCMD_RWRI_OP_MOVE) << 24) |
- (SCNTL3_REG_800 << 16) | (scntl3 << 8);
- script[1] = 0;
- script += 2;
- }
-
- script[0] = ((DCMD_TYPE_RWRI | DCMD_RWRI_OPC_MODIFY |
- DCMD_RWRI_OP_MOVE) << 24) |
- (SXFER_REG << 16) | (sxfer << 8);
- script[1] = 0;
- script += 2;
-
-#ifdef DEBUG_SYNC_INTR
- if (hostdata->options & OPTION_DEBUG_DISCONNECT) {
- script[0] = ((DCMD_TYPE_TCI|DCMD_TCI_OP_INT) << 24) | DBC_TCI_TRUE;
- script[1] = DEBUG_SYNC_INTR;
- script += 2;
- }
-#endif
-
- script[0] = ((DCMD_TYPE_TCI|DCMD_TCI_OP_RETURN) << 24) | DBC_TCI_TRUE;
- script[1] = 0;
- script += 2;
- }
-
- if (hostdata->options & OPTION_DEBUG_SYNCHRONOUS)
- printk ("scsi%d : target %d sync parameters are sxfer=0x%x, scntl3=0x%x\n",
- host->host_no, target, sxfer, scntl3);
-
- if (now_connected) {
- if ((hostdata->chip / 100) == 8)
- NCR53c7x0_write8(SCNTL3_REG_800, scntl3);
- NCR53c7x0_write8(SXFER_REG, sxfer);
- }
-}
-
-
-/*
- * Function : static int asynchronous (struct Scsi_Host *host, int target)
- *
- * Purpose : reprogram between the selected SCSI Host adapter and target
- * (assumed to be currently connected) for asynchronous transfers.
- *
- * Inputs : host - SCSI host structure, target - numeric target ID.
- *
- * Preconditions : the NCR chip should be in one of the halted states
- */
-
-static void
-asynchronous (struct Scsi_Host *host, int target) {
- NCR53c7x0_local_declare();
- struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
- host->hostdata;
- NCR53c7x0_local_setup(host);
- set_synchronous (host, target, /* no offset */ 0, hostdata->saved_scntl3,
- 1);
- printk ("scsi%d : setting target %d to asynchronous SCSI\n",
- host->host_no, target);
-}
-
-/*
- * XXX - do we want to go out of our way (ie, add extra code to selection
- * in the NCR53c710/NCR53c720 script) to reprogram the synchronous
- * conversion bits, or can we be content in just setting the
- * sxfer bits?
- */
-
-/* Table for NCR53c8xx synchronous values */
-static const struct {
- int div; /* Total clock divisor * 10 */
- unsigned char scf; /* */
- unsigned char tp; /* 4 + tp = xferp divisor */
-} syncs[] = {
-/* div scf tp div scf tp div scf tp */
- { 40, 1, 0}, { 50, 1, 1}, { 60, 1, 2},
- { 70, 1, 3}, { 75, 2, 1}, { 80, 1, 4},
- { 90, 1, 5}, { 100, 1, 6}, { 105, 2, 3},
- { 110, 1, 7}, { 120, 2, 4}, { 135, 2, 5},
- { 140, 3, 3}, { 150, 2, 6}, { 160, 3, 4},
- { 165, 2, 7}, { 180, 3, 5}, { 200, 3, 6},
- { 210, 4, 3}, { 220, 3, 7}, { 240, 4, 4},
- { 270, 4, 5}, { 300, 4, 6}, { 330, 4, 7}
-};
-
-/*
- * Function : static void synchronous (struct Scsi_Host *host, int target,
- * char *msg)
- *
- * Purpose : reprogram transfers between the selected SCSI initiator and
- * target for synchronous SCSI transfers such that the synchronous
- * offset is less than that requested and period at least as long
- * as that requested. Also modify *msg such that it contains
- * an appropriate response.
- *
- * Inputs : host - NCR53c7,8xx SCSI host, target - number SCSI target id,
- * msg - synchronous transfer request.
- */
-
-
-static void
-synchronous (struct Scsi_Host *host, int target, char *msg) {
- struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
- host->hostdata;
- int desire, divisor, i, limit;
- unsigned char scntl3, sxfer;
-/* The diagnostic message fits on one line, even with max. width integers */
- char buf[80];
-
-/* Desired transfer clock in Hz */
- desire = 1000000000L / (msg[3] * 4);
-/* Scale the available SCSI clock by 10 so we get tenths */
- divisor = (hostdata->scsi_clock * 10) / desire;
-
-/* NCR chips can handle at most an offset of 8 */
- if (msg[4] > 8)
- msg[4] = 8;
-
- if (hostdata->options & OPTION_DEBUG_SDTR)
- printk("scsi%d : optimal synchronous divisor of %d.%01d\n",
- host->host_no, divisor / 10, divisor % 10);
-
- limit = (sizeof(syncs) / sizeof(syncs[0]) -1);
- for (i = 0; (i < limit) && (divisor > syncs[i].div); ++i);
-
- if (hostdata->options & OPTION_DEBUG_SDTR)
- printk("scsi%d : selected synchronous divisor of %d.%01d\n",
- host->host_no, syncs[i].div / 10, syncs[i].div % 10);
-
- msg[3] = ((1000000000L / hostdata->scsi_clock) * syncs[i].div / 10 / 4);
-
- if (hostdata->options & OPTION_DEBUG_SDTR)
- printk("scsi%d : selected synchronous period of %dns\n", host->host_no,
- msg[3] * 4);
-
- scntl3 = (hostdata->chip / 100 == 8) ? ((hostdata->saved_scntl3 &
- ~SCNTL3_800_SCF_MASK) | (syncs[i].scf << SCNTL3_800_SCF_SHIFT)) : 0;
- sxfer = (msg[4] << SXFER_MO_SHIFT) | ((syncs[i].tp) << SXFER_TP_SHIFT);
- if (hostdata->options & OPTION_DEBUG_SDTR)
- printk ("scsi%d : sxfer=0x%x scntl3=0x%x\n",
- host->host_no, (int) sxfer, (int) scntl3);
- set_synchronous (host, target, sxfer, scntl3, 1);
- sprintf (buf, "scsi%d : setting target %d to ", host->host_no, target);
- print_synchronous (buf, msg);
-}
-
-/*
- * Function : static int NCR53c8x0_dstat_sir_intr (struct Scsi_Host *host,
- * struct NCR53c7x0_cmd *cmd)
- *
- * Purpose : Handler for INT generated instructions for the
- * NCR53c810/820 SCSI SCRIPT
- *
- * Inputs : host - pointer to this host adapter's structure,
- * cmd - pointer to the command (if any) dsa was pointing
- * to.
- *
- */
-
-static int
-NCR53c8x0_dstat_sir_intr (struct Scsi_Host *host, struct
- NCR53c7x0_cmd *cmd) {
- NCR53c7x0_local_declare();
- int print;
- Scsi_Cmnd *c = cmd ? cmd->cmd : NULL;
- struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
- host->hostdata;
- u32 dsps,*dsp; /* Argument of the INT instruction */
- NCR53c7x0_local_setup(host);
- dsps = NCR53c7x0_read32(DSPS_REG);
- dsp = (u32 *) bus_to_virt(NCR53c7x0_read32(DSP_REG));
-
- if (hostdata->options & OPTION_DEBUG_INTR)
- printk ("scsi%d : DSPS = 0x%x\n", host->host_no, dsps);
-
- switch (dsps) {
- case A_int_msg_1:
- print = 1;
- switch (hostdata->msg_buf[0]) {
- /*
- * Unless we've initiated synchronous negotiation, I don't
- * think that this should happen.
- */
- case MESSAGE_REJECT:
- hostdata->dsp = hostdata->script + hostdata->E_accept_message /
- sizeof(u32);
- hostdata->dsp_changed = 1;
- if (cmd && (cmd->flags & CMD_FLAG_SDTR)) {
- printk ("scsi%d : target %d rejected SDTR\n", host->host_no,
- c->target);
- cmd->flags &= ~CMD_FLAG_SDTR;
- asynchronous (host, c->target);
- print = 0;
- }
- break;
- case INITIATE_RECOVERY:
- printk ("scsi%d : extended contingent allegiance not supported yet, rejecting\n",
- host->host_no);
- /* Fall through to default */
- hostdata->dsp = hostdata->script + hostdata->E_reject_message /
- sizeof(u32);
- hostdata->dsp_changed = 1;
- break;
- default:
- printk ("scsi%d : unsupported message, resjecting\n",
- host->host_no);
- hostdata->dsp = hostdata->script + hostdata->E_reject_message /
- sizeof(u32);
- hostdata->dsp_changed = 1;
- }
- if (print) {
- printk ("scsi%d : received message", host->host_no);
- if (c)
- printk (" from target %d lun %d ", c->target, c->lun);
- print_msg ((unsigned char *) hostdata->msg_buf);
- printk("\n");
- }
-
- return SPECIFIC_INT_NOTHING;
-
-
- case A_int_msg_sdtr:
-/*
- * At this point, hostdata->msg_buf contains
- * 0 EXTENDED MESSAGE
- * 1 length
- * 2 SDTR
- * 3 period * 4ns
- * 4 offset
- */
-
- if (cmd) {
- char buf[80];
- sprintf (buf, "scsi%d : target %d %s ", host->host_no, c->target,
- (cmd->flags & CMD_FLAG_SDTR) ? "accepting" : "requesting");
- print_synchronous (buf, (unsigned char *) hostdata->msg_buf);
-
- /*
- * Initiator initiated, won't happen unless synchronous
- * transfers are enabled. If we get a SDTR message in
- * response to our SDTR, we should program our parameters
- * such that
- * offset <= requested offset
- * period >= requested period
- */
- if (cmd->flags & CMD_FLAG_SDTR) {
- cmd->flags &= ~CMD_FLAG_SDTR;
- if (hostdata->msg_buf[4])
- synchronous (host, c->target, (unsigned char *)
- hostdata->msg_buf);
- else
- asynchronous (host, c->target);
- hostdata->dsp = hostdata->script + hostdata->E_accept_message /
- sizeof(u32);
- hostdata->dsp_changed = 1;
- return SPECIFIC_INT_NOTHING;
- } else {
- if (hostdata->options & OPTION_SYNCHRONOUS) {
- cmd->flags |= CMD_FLAG_DID_SDTR;
- synchronous (host, c->target, (unsigned char *)
- hostdata->msg_buf);
- } else {
- hostdata->msg_buf[4] = 0; /* 0 offset = async */
- asynchronous (host, c->target);
- }
- patch_dsa_32 (cmd->dsa, dsa_msgout_other, 0, 5);
- patch_dsa_32 (cmd->dsa, dsa_msgout_other, 1, (u32)
- virt_to_bus ((void *)&hostdata->msg_buf));
- hostdata->dsp = hostdata->script +
- hostdata->E_respond_message / sizeof(u32);
- hostdata->dsp_changed = 1;
- }
- return SPECIFIC_INT_NOTHING;
- }
- /* Fall through to abort if we couldn't find a cmd, and
- therefore a dsa structure to twiddle */
- case A_int_msg_wdtr:
- hostdata->dsp = hostdata->script + hostdata->E_reject_message /
- sizeof(u32);
- hostdata->dsp_changed = 1;
- return SPECIFIC_INT_NOTHING;
- case A_int_err_unexpected_phase:
- if (hostdata->options & OPTION_DEBUG_INTR)
- printk ("scsi%d : unexpected phase\n", host->host_no);
- return SPECIFIC_INT_ABORT;
- case A_int_err_selected:
- printk ("scsi%d : selected by target %d\n", host->host_no,
- (int) NCR53c7x0_read8(SDID_REG_800) &7);
- hostdata->dsp = hostdata->script + hostdata->E_target_abort /
- sizeof(u32);
- hostdata->dsp_changed = 1;
- return SPECIFIC_INT_NOTHING;
- case A_int_err_unexpected_reselect:
- printk ("scsi%d : unexpected reselect by target %d lun %d\n",
- host->host_no, (int) NCR53c7x0_read8(SDID_REG_800) & 7,
- hostdata->reselected_identify & 7);
- hostdata->dsp = hostdata->script + hostdata->E_initiator_abort /
- sizeof(u32);
- hostdata->dsp_changed = 1;
- return SPECIFIC_INT_NOTHING;
-/*
- * Since contingent allegiance conditions are cleared by the next
- * command issued to a target, we must issue a REQUEST SENSE
- * command after receiving a CHECK CONDITION status, before
- * another command is issued.
- *
- * Since this NCR53c7x0_cmd will be freed after use, we don't
- * care if we step on the various fields, so modify a few things.
- */
- case A_int_err_check_condition:
-#if 0
- if (hostdata->options & OPTION_DEBUG_INTR)
-#endif
- printk ("scsi%d : CHECK CONDITION\n", host->host_no);
- if (!c) {
- printk("scsi%d : CHECK CONDITION with no SCSI command\n",
- host->host_no);
- return SPECIFIC_INT_PANIC;
- }
-
- /*
- * FIXME : this uses the normal one-byte selection message.
- * We may want to renegotiate for synchronous & WIDE transfers
- * since these could be the crux of our problem.
- *
- hostdata->NOP_insn* FIXME : once SCSI-II tagged queuing is implemented, we'll
- * have to set this up so that the rest of the DSA
- * agrees with this being an untagged queue'd command.
- */
-
- patch_dsa_32 (cmd->dsa, dsa_msgout, 0, 1);
-
- /*
- * Modify the table indirect for COMMAND OUT phase, since
- * Request Sense is a six byte command.
- */
-
- patch_dsa_32 (cmd->dsa, dsa_cmdout, 0, 6);
-
- c->cmnd[0] = REQUEST_SENSE;
- c->cmnd[1] &= 0xe0; /* Zero all but LUN */
- c->cmnd[2] = 0;
- c->cmnd[3] = 0;
- c->cmnd[4] = sizeof(c->sense_buffer);
- c->cmnd[5] = 0;
-
- /*
- * Disable dataout phase, and program datain to transfer to the
- * sense buffer, and add a jump to other_transfer after the
- * command so overflow/underrun conditions are detected.
- */
-
- patch_dsa_32 (cmd->dsa, dsa_dataout, 0,
- virt_to_bus(hostdata->script) + hostdata->E_other_transfer);
- patch_dsa_32 (cmd->dsa, dsa_datain, 0,
- virt_to_bus(cmd->data_transfer_start));
- cmd->data_transfer_start[0] = (((DCMD_TYPE_BMI | DCMD_BMI_OP_MOVE_I |
- DCMD_BMI_IO)) << 24) | sizeof(c->sense_buffer);
- cmd->data_transfer_start[1] = (u32) virt_to_bus(c->sense_buffer);
-
- cmd->data_transfer_start[2] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_JUMP)
- << 24) | DBC_TCI_TRUE;
- cmd->data_transfer_start[3] = (u32) virt_to_bus(hostdata->script) +
- hostdata->E_other_transfer;
-
- /*
- * Currently, this command is flagged as completed, ie
- * it has valid status and message data. Reflag it as
- * incomplete. Q - need to do something so that original
- * status, etc are used.
- */
-
- cmd->cmd->result = 0xffff;
-
- /*
- * Restart command as a REQUEST SENSE.
- */
- hostdata->dsp = (u32 *) hostdata->script + hostdata->E_select /
- sizeof(u32);
- hostdata->dsp_changed = 1;
- return SPECIFIC_INT_NOTHING;
- case A_int_debug_break:
- return SPECIFIC_INT_BREAK;
- case A_int_norm_aborted:
- hostdata->dsp = (u32 *) hostdata->schedule;
- hostdata->dsp_changed = 1;
- if (cmd)
- abnormal_finished (cmd, DID_ERROR << 16);
- return SPECIFIC_INT_NOTHING;
- case A_int_test_1:
- case A_int_test_2:
- hostdata->idle = 1;
- hostdata->test_completed = (dsps - A_int_test_1) / 0x00010000 + 1;
- if (hostdata->options & OPTION_DEBUG_INTR)
- printk("scsi%d : test%d complete\n", host->host_no,
- hostdata->test_completed);
- return SPECIFIC_INT_NOTHING;
-#ifdef A_int_debug_reselected_ok
- case A_int_debug_reselected_ok:
- if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR|
- OPTION_DEBUG_DISCONNECT)) {
- /*
- * Note - this dsa is not based on location relative to
- * the command structure, but to location relative to the
- * DSA register
- */
- u32 *dsa;
- dsa = (u32 *) bus_to_virt (NCR53c7x0_read32(DSA_REG));
-
- printk("scsi%d : reselected_ok (DSA = 0x%x (virt 0x%p)\n",
- host->host_no, NCR53c7x0_read32(DSA_REG), dsa);
- printk("scsi%d : resume address is 0x%x (virt 0x%p)\n",
- host->host_no, cmd->saved_data_pointer,
- bus_to_virt(cmd->saved_data_pointer));
- print_insn (host, hostdata->script + Ent_reselected_ok /
- sizeof(u32), "", 1);
- printk ("scsi%d : sxfer=0x%x, scntl3=0x%x\n",
- host->host_no, NCR53c7x0_read8(SXFER_REG),
- NCR53c7x0_read8(SCNTL3_REG_800));
- if (c) {
- print_insn (host, (u32 *)
- hostdata->sync[c->target].script, "", 1);
- print_insn (host, (u32 *)
- hostdata->sync[c->target].script + 2, "", 1);
- }
- }
- return SPECIFIC_INT_RESTART;
-#endif
-#ifdef A_int_debug_reselect_check
- case A_int_debug_reselect_check:
- if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
- u32 *dsa;
-#if 0
- u32 *code;
-#endif
- /*
- * Note - this dsa is not based on location relative to
- * the command structure, but to location relative to the
- * DSA register
- */
- dsa = bus_to_virt (NCR53c7x0_read32(DSA_REG));
- printk("scsi%d : reselected_check_next (DSA = 0x%lx (virt 0x%p))\n",
- host->host_no, virt_to_bus(dsa), dsa);
- if (dsa) {
- printk("scsi%d : resume address is 0x%x (virt 0x%p)\n",
- host->host_no, cmd->saved_data_pointer,
- bus_to_virt (cmd->saved_data_pointer));
-#if 0
- printk("scsi%d : template code :\n", host->host_no);
- for (code = dsa + (Ent_dsa_code_check_reselect - Ent_dsa_zero)
- / sizeof(u32); code < (dsa + Ent_dsa_zero / sizeof(u32));
- code += print_insn (host, code, "", 1));
-#endif
- }
- print_insn (host, hostdata->script + Ent_reselected_ok /
- sizeof(u32), "", 1);
- }
- return SPECIFIC_INT_RESTART;
-#endif
-#ifdef A_int_debug_dsa_schedule
- case A_int_debug_dsa_schedule:
- if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
- u32 *dsa;
- /*
- * Note - this dsa is not based on location relative to
- * the command structure, but to location relative to the
- * DSA register
- */
- dsa = (u32 *) bus_to_virt (NCR53c7x0_read32(DSA_REG));
- printk("scsi%d : dsa_schedule (old DSA = 0x%lx (virt 0x%p))\n",
- host->host_no, virt_to_bus(dsa), dsa);
- if (dsa)
- printk("scsi%d : resume address is 0x%x (virt 0x%p)\n"
- " (temp was 0x%x (virt 0x%p))\n",
- host->host_no, cmd->saved_data_pointer,
- bus_to_virt (cmd->saved_data_pointer),
- NCR53c7x0_read32 (TEMP_REG),
- bus_to_virt (NCR53c7x0_read32(TEMP_REG)));
- }
- return SPECIFIC_INT_RESTART;
-#endif
-#ifdef A_int_debug_scheduled
- case A_int_debug_scheduled:
- if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
- printk("scsi%d : new I/O 0x%x (virt 0x%p) scheduled\n",
- host->host_no, NCR53c7x0_read32(DSA_REG),
- bus_to_virt(NCR53c7x0_read32(DSA_REG)));
- }
- return SPECIFIC_INT_RESTART;
-#endif
-#ifdef A_int_debug_idle
- case A_int_debug_idle:
- if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
- printk("scsi%d : idle\n", host->host_no);
- }
- return SPECIFIC_INT_RESTART;
-#endif
-#ifdef A_int_debug_cmd
- case A_int_debug_cmd:
- if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
- printk("scsi%d : command sent\n");
- }
- return SPECIFIC_INT_RESTART;
-#endif
-#ifdef A_int_debug_dsa_loaded
- case A_int_debug_dsa_loaded:
- if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
- printk("scsi%d : DSA loaded with 0x%x (virt 0x%p)\n", host->host_no,
- NCR53c7x0_read32(DSA_REG),
- bus_to_virt(NCR53c7x0_read32(DSA_REG)));
- }
- return SPECIFIC_INT_RESTART;
-#endif
-#ifdef A_int_debug_reselected
- case A_int_debug_reselected:
- if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR|
- OPTION_DEBUG_DISCONNECT)) {
- printk("scsi%d : reselected by target %d lun %d\n",
- host->host_no, (int) NCR53c7x0_read8(SDID_REG_800) & ~0x80,
- (int) hostdata->reselected_identify & 7);
- print_queues(host);
- }
- return SPECIFIC_INT_RESTART;
-#endif
-#ifdef A_int_debug_disconnect_msg
- case A_int_debug_disconnect_msg:
- if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR)) {
- if (c)
- printk("scsi%d : target %d lun %d disconnecting\n",
- host->host_no, c->target, c->lun);
- else
- printk("scsi%d : unknown target disconnecting\n",
- host->host_no);
- }
- return SPECIFIC_INT_RESTART;
-#endif
-#ifdef A_int_debug_disconnected
- case A_int_debug_disconnected:
- if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR|
- OPTION_DEBUG_DISCONNECT)) {
- printk ("scsi%d : disconnected, new queues are\n",
- host->host_no);
- print_queues(host);
-#if 0
- printk ("scsi%d : sxfer=0x%x, scntl3=0x%x\n",
- host->host_no, NCR53c7x0_read8(SXFER_REG),
- NCR53c7x0_read8(SCNTL3_REG_800));
-#endif
- if (c) {
- print_insn (host, (u32 *)
- hostdata->sync[c->target].script, "", 1);
- print_insn (host, (u32 *)
- hostdata->sync[c->target].script + 2, "", 1);
- }
- }
- return SPECIFIC_INT_RESTART;
-#endif
-#ifdef A_int_debug_panic
- case A_int_debug_panic:
- printk("scsi%d : int_debug_panic received\n", host->host_no);
- print_lots (host);
- return SPECIFIC_INT_PANIC;
-#endif
-#ifdef A_int_debug_saved
- case A_int_debug_saved:
- if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR|
- OPTION_DEBUG_DISCONNECT)) {
- printk ("scsi%d : saved data pointer 0x%x (virt 0x%p)\n",
- host->host_no, cmd->saved_data_pointer,
- bus_to_virt (cmd->saved_data_pointer));
- print_progress (c);
- }
- return SPECIFIC_INT_RESTART;
-#endif
-#ifdef A_int_debug_restored
- case A_int_debug_restored:
- if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR|
- OPTION_DEBUG_DISCONNECT)) {
- if (cmd) {
- int size;
- printk ("scsi%d : restored data pointer 0x%x (virt 0x%p)\n",
- host->host_no, cmd->saved_data_pointer, bus_to_virt (
- cmd->saved_data_pointer));
- size = print_insn (host, (u32 *)
- bus_to_virt(cmd->saved_data_pointer), "", 1);
- size = print_insn (host, (u32 *)
- bus_to_virt(cmd->saved_data_pointer) + size, "", 1);
- print_progress (c);
- }
-#if 0
- printk ("scsi%d : datapath residual %d\n",
- host->host_no, datapath_residual (host)) ;
-#endif
- }
- return SPECIFIC_INT_RESTART;
-#endif
-#ifdef A_int_debug_sync
- case A_int_debug_sync:
- if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR|
- OPTION_DEBUG_DISCONNECT|OPTION_DEBUG_SDTR)) {
- unsigned char sxfer = NCR53c7x0_read8 (SXFER_REG),
- scntl3 = NCR53c7x0_read8 (SCNTL3_REG_800);
- if (c) {
- if (sxfer != hostdata->sync[c->target].sxfer_sanity ||
- scntl3 != hostdata->sync[c->target].scntl3_sanity) {
- printk ("scsi%d : sync sanity check failed sxfer=0x%x, scntl3=0x%x",
- host->host_no, sxfer, scntl3);
- NCR53c7x0_write8 (SXFER_REG, sxfer);
- NCR53c7x0_write8 (SCNTL3_REG_800, scntl3);
- }
- } else
- printk ("scsi%d : unknown command sxfer=0x%x, scntl3=0x%x\n",
- host->host_no, (int) sxfer, (int) scntl3);
- }
- return SPECIFIC_INT_RESTART;
-#endif
-#ifdef A_int_debug_datain
- case A_int_debug_datain:
- if (hostdata->options & (OPTION_DEBUG_SCRIPT|OPTION_DEBUG_INTR|
- OPTION_DEBUG_DISCONNECT|OPTION_DEBUG_SDTR)) {
- int size;
- printk ("scsi%d : In do_datain (%s) sxfer=0x%x, scntl3=0x%x\n"
- " datapath residual=%d\n",
- host->host_no, sbcl_to_phase (NCR53c7x0_read8 (SBCL_REG)),
- (int) NCR53c7x0_read8(SXFER_REG),
- (int) NCR53c7x0_read8(SCNTL3_REG_800),
- datapath_residual (host)) ;
- print_insn (host, dsp, "", 1);
- size = print_insn (host, (u32 *) bus_to_virt(dsp[1]), "", 1);
- print_insn (host, (u32 *) bus_to_virt(dsp[1]) + size, "", 1);
- }
- return SPECIFIC_INT_RESTART;
-#endif
-/*
- * FIXME : for 7xx support, we need to read SDID_REG_700 and handle
- * the comparison as bitfielded, not binary.
- */
-#ifdef A_int_debug_check_dsa
- case A_int_debug_check_dsa:
- if (NCR53c7x0_read8 (SCNTL1_REG) & SCNTL1_CON) {
- int sdid = NCR53c7x0_read8 (SDID_REG_800) & 15;
- char *where = dsp - NCR53c7x0_insn_size(NCR53c7x0_read8
- (DCMD_REG)) == hostdata->script +
- Ent_select_check_dsa / sizeof(u32) ?
- "selection" : "reselection";
- if (c && sdid != c->target) {
- printk ("scsi%d : SDID target %d != DSA target %d at %s\n",
- host->host_no, sdid, c->target, where);
- print_lots(host);
- dump_events (host, 20);
- return SPECIFIC_INT_PANIC;
- }
- }
- return SPECIFIC_INT_RESTART;
-#endif
- default:
- if ((dsps & 0xff000000) == 0x03000000) {
- printk ("scsi%d : misc debug interrupt 0x%x\n",
- host->host_no, dsps);
- return SPECIFIC_INT_RESTART;
- } else if ((dsps & 0xff000000) == 0x05000000) {
- if (hostdata->events) {
- struct NCR53c7x0_event *event;
- ++hostdata->event_index;
- if (hostdata->event_index >= hostdata->event_size)
- hostdata->event_index = 0;
- event = (struct NCR53c7x0_event *) hostdata->events +
- hostdata->event_index;
- event->event = (enum ncr_event) dsps;
- event->dsa = bus_to_virt(NCR53c7x0_read32(DSA_REG));
- /* FIXME : this needs to change for the '7xx family */
- if (NCR53c7x0_read8 (SCNTL1_REG) & SCNTL1_CON)
- event->target = NCR53c7x0_read8(SSID_REG_800);
- else
- event->target = 255;
-
- if (event->event == EVENT_RESELECT)
- event->lun = hostdata->reselected_identify & 0xf;
- else if (c)
- event->lun = c->lun;
- else
- event->lun = 255;
- do_gettimeofday(&(event->time));
- if (c) {
- event->pid = c->pid;
- memcpy ((void *) event->cmnd, (void *) c->cmnd,
- sizeof (event->cmnd));
- } else {
- event->pid = -1;
- }
- }
- return SPECIFIC_INT_RESTART;
- }
-
- printk ("scsi%d : unknown user interrupt 0x%x\n",
- host->host_no, (unsigned) dsps);
- return SPECIFIC_INT_PANIC;
- }
-}
-
-/*
- * XXX - the stock NCR assembler won't output the scriptu.h file,
- * which undefine's all #define'd CPP symbols from the script.h
- * file, which will create problems if you use multiple scripts
- * with the same symbol names.
- *
- * If you insist on using NCR's assembler, you could generate
- * scriptu.h from script.h using something like
- *
- * grep #define script.h | \
- * sed 's/#define[ ][ ]*\([_a-zA-Z][_a-zA-Z0-9]*\).*$/#undefine \1/' \
- * > scriptu.h
- */
-
-#include "53c8xx_u.h"
-
-/* XXX - add alternate script handling code here */
-
-
-#ifdef NCR_DEBUG
-/*
- * Debugging without a debugger is no fun. So, I've provided
- * a debugging interface in the NCR53c7x0 driver. To avoid
- * kernel cruft, there's just enough here to act as an interface
- * to a user level debugger (aka, GDB).
- *
- *
- * The following restrictions apply to debugger commands :
- * 1. The command must be terminated by a newline.
- * 2. Command length must be less than 80 bytes including the
- * newline.
- * 3. The entire command must be written with one system call.
- */
-
-static const char debugger_help =
-"bc <addr> - clear breakpoint\n"
-"bl - list breakpoints\n"
-"bs <addr> - set breakpoint\n"
-"g - start\n"
-"h - halt\n"
-"? - this message\n"
-"i - info\n"
-"mp <addr> <size> - print memory\n"
-"ms <addr> <size> <value> - store memory\n"
-"rp <num> <size> - print register\n"
-"rs <num> <size> <value> - store register\n"
-"s - single step\n"
-"tb - begin trace \n"
-"te - end trace\n";
-
-/*
- * Whenever we change a break point, we should probably
- * set the NCR up so that it is in a single step mode.
- */
-
-static int debugger_fn_bc (struct Scsi_Host *host, struct debugger_token *token,
- u32 args[]) {
- struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
- instance->hostdata;
- struct NCR53c7x0_break *bp, **prev;
- unsigned long flags;
- save_flags(flags);
- cli();
- for (bp = (struct NCR53c7x0_break *) instance->breakpoints,
- prev = (struct NCR53c7x0_break **) &instance->breakpoints;
- bp; prev = (struct NCR53c7x0_break **) &(bp->next),
- bp = (struct NCR53c7x0_break *) bp->next);
-
- if (!bp) {
- restore_flags(flags);
- return -EIO;
- }
-
- /*
- * XXX - we need to insure that the processor is halted
- * here in order to prevent a race condition.
- */
-
- memcpy ((void *) bp->addr, (void *) bp->old, sizeof(bp->old));
- if (prev)
- *prev = bp->next;
-
- restore_flags(flags);
- return 0;
-}
-
-
-static int
-debugger_fn_bl (struct Scsi_Host *host, struct debugger_token *token,
- u32 args[]) {
- struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
- host->hostdata;
- struct NCR53c7x0_break *bp;
- char buf[80];
- size_t len;
- unsigned long flags;
- /*
- * XXX - we need to insure that the processor is halted
- * here in order to prevent a race condition. So, if the
- * processor isn't halted, print an error message and continue.
- */
-
- sprintf (buf, "scsi%d : bp : warning : processor not halted\b",
- host->host_no);
- debugger_kernel_write (host, buf, strlen(buf));
-
- save_flags(flags);
- cli();
- for (bp = (struct NCR53c7x0_break *) host->breakpoints;
- bp; bp = (struct NCR53c7x0_break *) bp->next); {
- sprintf (buf, "scsi%d : bp : success : at %08x, replaces %08x %08x",
- bp->addr, bp->old[0], bp->old[1]);
- len = strlen(buf);
- if ((bp->old[0] & (DCMD_TYPE_MASK << 24)) ==
- (DCMD_TYPE_MMI << 24)) {
- sprintf(buf + len, "%08x\n", * (u32 *) bp->addr);
- } else {
- sprintf(buf + len, "\n");
- }
- len = strlen(buf);
- debugger_kernel_write (host, buf, len);
- }
- restore_flags(flags);
- return 0;
-}
-
-static int
-debugger_fn_bs (struct Scsi_Host *host, struct debugger_token *token,
- u32 args[]) {
- struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
- host->hostdata;
- struct NCR53c7x0_break *bp;
- char buf[80];
- size_t len;
- unsigned long flags;
- save_flags(flags);
- cli();
-
- if (hostdata->state != STATE_HALTED) {
- sprintf (buf, "scsi%d : bs : failure : NCR not halted\n", host->host_no);
- debugger_kernel_write (host, buf, strlen(buf));
- restore_flags(flags);
- return -1;
- }
-
- if (!(bp = kmalloc (sizeof (struct NCR53c7x0_break)))) {
- printk ("scsi%d : kmalloc(%d) of breakpoint structure failed, try again\n",
- host->host_no, sizeof(struct NCR53c7x0_break));
- restore_flags(flags);
- return -1;
- }
-
- bp->address = (u32 *) args[0];
- memcpy ((void *) bp->old_instruction, (void *) bp->address, 8);
- bp->old_size = (((bp->old_instruction[0] >> 24) & DCMD_TYPE_MASK) ==
- DCMD_TYPE_MMI ? 3 : 2;
- bp->next = hostdata->breakpoints;
- hostdata->breakpoints = bp->next;
- memcpy ((void *) bp->address, (void *) hostdata->E_debug_break, 8);
-
- restore_flags(flags);
- return 0;
-}
-
-#define TOKEN(name,nargs) {#name, nargs, debugger_fn_##name}
-static const struct debugger_token {
- char *name;
- int numargs;
- int (*fn)(struct debugger_token *token, u32 args[]);
-} debugger_tokens[] = {
- TOKEN(bc,1), TOKEN(bl,0), TOKEN(bs,1), TOKEN(g,0), TOKEN(halt,0),
- {DT_help, "?", 0} , TOKEN(h,0), TOKEN(i,0), TOKEN(mp,2),
- TOKEN(ms,3), TOKEN(rp,2), TOKEN(rs,2), TOKEN(s,0), TOKEN(tb,0), TOKEN(te,0)
-};
-
-#define NDT sizeof(debugger_tokens / sizeof(struct debugger_token))
-
-static struct Scsi_Host * inode_to_host (struct inode *inode) {
- int dev;
- struct Scsi_Host *tmp;
- for (dev = MINOR(inode->rdev), host = first_host;
- (host->hostt == the_template); --dev, host = host->next)
- if (!dev) return host;
- return NULL;
-}
-
-
-static int
-debugger_user_write (struct inode *inode,struct file *filp,
- char *buf,int count) {
- struct Scsi_Host *host; /* This SCSI host */
- struct NCR53c7x0_hostadata *hostdata;
- char input_buf[80], /* Kernel space copy of buf */
- *ptr; /* Pointer to argument list */
- u32 args[3]; /* Arguments */
- int i, j, error, len;
-
- if (!(host = inode_to_host(inode)))
- return -ENXIO;
-
- hostdata = (struct NCR53c7x0_hostdata *) host->hostdata;
-
- if (error = verify_area(VERIFY_READ,buf,count))
- return error;
-
- if (count > 80)
- return -EIO;
-
- memcpy_from_fs(input_buf, buf, count);
-
- if (input_buf[count - 1] != '\n')
- return -EIO;
-
- input_buf[count - 1]=0;
-
- for (i = 0; i < NDT; ++i) {
- len = strlen (debugger_tokens[i].name);
- if (!strncmp(input_buf, debugger_tokens[i].name, len))
- break;
- };
-
- if (i == NDT)
- return -EIO;
-
- for (ptr = input_buf + len, j = 0; j < debugger_tokens[i].nargs && *ptr;) {
- if (*ptr == ' ' || *ptr == '\t') {
- ++ptr;
- } else if (isdigit(*ptr)) {
- args[j++] = simple_strtoul (ptr, &ptr, 0);
- } else {
- return -EIO;
- }
- }
-
- if (j != debugger_tokens[i].nargs)
- return -EIO;
-
- return count;
-}
-
-static int
-debugger_user_read (struct inode *inode,struct file *filp,
- char *buf,int count) {
- struct Scsi_Host *instance;
-
-}
-
-static int
-debugger_kernel_write (struct Scsi_Host *host, char *buf, size_t
- buflen) {
- struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
- host->hostdata;
- int copy, left;
- unsigned long flags;
- save_flags(flags);
- cli();
- while (buflen) {
- left = (hostdata->debug_buf + hostdata->debug_size - 1) -
- hostdata->debug_write;
- copy = (buflen <= left) ? buflen : left;
- memcpy (hostdata->debug_write, buf, copy);
- buf += copy;
- buflen -= copy;
- hostdata->debug_count += copy;
- if ((hostdata->debug_write += copy) ==
- (hostdata->debug_buf + hostdata->debug_size))
- hosdata->debug_write = hostdata->debug_buf;
- }
- restore_flags(flags);
-}
-
-#endif /* def NCRDEBUG */
-
-/*
- * Function : static void NCR538xx_soft_reset (struct Scsi_Host *host)
- *
- * Purpose : perform a soft reset of the NCR53c8xx chip
- *
- * Inputs : host - pointer to this host adapter's structure
- *
- * Preconditions : NCR53c7x0_init must have been called for this
- * host.
- *
- */
-
-static void
-NCR53c8x0_soft_reset (struct Scsi_Host *host) {
- NCR53c7x0_local_declare();
- struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
- host->hostdata;
- NCR53c7x0_local_setup(host);
-
-
- /*
- * Do a soft reset of the chip so that everything is
- * reinitialized to the power-on state.
- *
- * Basically follow the procedure outlined in the NCR53c700
- * data manual under Chapter Six, How to Use, Steps Necessary to
- * Start SCRIPTS, with the exception of actually starting the
- * script and setting up the synchronous transfer gunk.
- */
-
- NCR53c7x0_write8(ISTAT_REG_800, ISTAT_10_SRST);
- NCR53c7x0_write8(ISTAT_REG_800, 0);
- NCR53c7x0_write8(hostdata->dmode, hostdata->saved_dmode & ~DMODE_MAN);
-
-
- /*
- * Respond to reselection by targets and use our _initiator_ SCSI ID
- * for arbitration. If notyet, also respond to SCSI selection.
- *
- * XXX - Note : we must reprogram this when reselecting as
- * a target.
- */
-
-#ifdef notyet
- NCR53c7x0_write8(SCID_REG, (host->this_id & 7)|SCID_800_RRE|SCID_800_SRE);
-#else
- NCR53c7x0_write8(SCID_REG, (host->this_id & 7)|SCID_800_RRE);
-#endif
- NCR53c7x0_write8(RESPID_REG_800, hostdata->this_id_mask);
-
- /*
- * Use a maximum (1.6) second handshake to handshake timeout,
- * and SCSI recommended .5s selection timeout.
- */
-
- /*
- * The new gcc won't recognize preprocessing directives
- * within macro args.
- */
-#if 0
- NCR53c7x0_write8(STIME0_REG_800,
- ((selection_timeout << STIME0_800_SEL_SHIFT) & STIME0_800_SEL_MASK)
- | ((15 << STIME0_800_HTH_SHIFT) & STIME0_800_HTH_MASK));
-#else
-/* Disable HTH interrupt */
- NCR53c7x0_write8(STIME0_REG_800,
- ((selection_timeout << STIME0_800_SEL_SHIFT) & STIME0_800_SEL_MASK));
-#endif
-
-
- /*
- * Enable active negation for happy synchronous transfers.
- */
-
- NCR53c7x0_write8(STEST3_REG_800, STEST3_800_TE);
-
- /*
- * Enable all interrupts, except parity which we only want when
- * the user requests it.
- */
-
- NCR53c7x0_write8(DIEN_REG, DIEN_800_MDPE | DIEN_800_BF |
- DIEN_ABRT | DIEN_SSI | DIEN_SIR | DIEN_800_IID);
-
-
- NCR53c7x0_write8(SIEN0_REG_800, ((hostdata->options & OPTION_PARITY) ?
- SIEN_PAR : 0) | SIEN_RST | SIEN_UDC | SIEN_SGE | SIEN_MA);
- NCR53c7x0_write8(SIEN1_REG_800, SIEN1_800_STO | SIEN1_800_HTH);
-
- /*
- * Use saved clock frequency divisor and scripts loaded in 16 bit
- * mode flags from the saved dcntl.
- */
-
- NCR53c7x0_write8(DCNTL_REG, hostdata->saved_dcntl);
- NCR53c7x0_write8(CTEST4_REG_800, hostdata->saved_ctest4);
-
- /* Enable active negation */
- NCR53c7x0_write8(STEST3_REG_800, STEST3_800_TE);
-}
-
-/*
- * Function static struct NCR53c7x0_cmd *allocate_cmd (Scsi_Cmnd *cmd)
- *
- * Purpose : Return the first free NCR53c7x0_cmd structure (which are
- * reused in a LIFO maner to minimize cache thrashing).
- *
- * Side effects : If we haven't yet scheduled allocation of NCR53c7x0_cmd
- * structures for this device, do so. Attempt to complete all scheduled
- * allocations using kmalloc(), putting NCR53c7x0_cmd structures on
- * the free list. Teach programmers not to drink and hack.
- *
- * Inputs : cmd - SCSI command
- *
- * Returns : NCR53c7x0_cmd structure allocated on behalf of cmd;
- * NULL on failure.
- */
-
-static struct NCR53c7x0_cmd *
-allocate_cmd (Scsi_Cmnd *cmd) {
- struct Scsi_Host *host = cmd->host;
- struct NCR53c7x0_hostdata *hostdata =
- (struct NCR53c7x0_hostdata *) host->hostdata;
- void *real; /* Real address */
- int size; /* Size of *tmp */
- struct NCR53c7x0_cmd *tmp;
- unsigned long flags;
-
- if (hostdata->options & OPTION_DEBUG_ALLOCATION)
- printk ("scsi%d : num_cmds = %d, can_queue = %d\n"
- " target = %d, lun = %d, %s\n",
- host->host_no, hostdata->num_cmds, host->can_queue,
- cmd->target, cmd->lun, (hostdata->cmd_allocated[cmd->target] &
- (1 << cmd->lun)) ? "allready allocated" : "not allocated");
-
-/*
- * If we have not yet reserved commands for this I_T_L nexus, and
- * the device exists (as indicated by permanant Scsi_Cmnd structures
- * being allocated under 1.3.x, or being outside of scan_scsis in
- * 1.2.x), do so now.
- */
- if (!(hostdata->cmd_allocated[cmd->target] & (1 << cmd->lun)) &&
-#ifdef LINUX_1_2
- !in_scan_scsis
-#else
- cmd->device && cmd->device->has_cmdblocks
-#endif
- ) {
- if ((hostdata->extra_allocate + hostdata->num_cmds) < host->can_queue)
- hostdata->extra_allocate += host->cmd_per_lun;
- hostdata->cmd_allocated[cmd->target] |= (1 << cmd->lun);
- }
-
- for (; hostdata->extra_allocate > 0 ; --hostdata->extra_allocate,
- ++hostdata->num_cmds) {
- /* historically, kmalloc has returned unaligned addresses; pad so we
- have enough room to ROUNDUP */
- size = hostdata->max_cmd_size + sizeof (void *);
-/* FIXME: for ISA bus '7xx chips, we need to or GFP_DMA in here */
- real = kmalloc (size, GFP_ATOMIC);
- if (!real) {
- if (hostdata->options & OPTION_DEBUG_ALLOCATION)
- printk ("scsi%d : kmalloc(%d) failed\n",
- host->host_no, size);
- break;
- }
- tmp = ROUNDUP(real, void *);
- tmp->real = real;
- tmp->size = size;
-#ifdef LINUX_1_2
- tmp->free = ((void (*)(void *, int)) kfree_s);
-#else
- tmp->free = ((void (*)(void *, int)) kfree);
-#endif
- save_flags (flags);
- cli();
- tmp->next = hostdata->free;
- hostdata->free = tmp;
- restore_flags (flags);
- }
- save_flags(flags);
- cli();
- tmp = (struct NCR53c7x0_cmd *) hostdata->free;
- if (tmp) {
- hostdata->free = tmp->next;
- }
- restore_flags(flags);
- if (!tmp)
- printk ("scsi%d : can't allocate command for target %d lun %d\n",
- host->host_no, cmd->target, cmd->lun);
- return tmp;
-}
-
-/*
- * Function static struct NCR53c7x0_cmd *create_cmd (Scsi_Cmnd *cmd)
- *
- *
- * Purpose : allocate a NCR53c7x0_cmd structure, initialize it based on the
- * Scsi_Cmnd structure passed in cmd, including dsa and Linux field
- * initialization, and dsa code relocation.
- *
- * Inputs : cmd - SCSI command
- *
- * Returns : NCR53c7x0_cmd structure corresponding to cmd,
- * NULL on failure.
- */
-
-static struct NCR53c7x0_cmd *
-create_cmd (Scsi_Cmnd *cmd) {
- NCR53c7x0_local_declare();
- struct Scsi_Host *host = cmd->host;
- struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
- host->hostdata;
- struct NCR53c7x0_cmd *tmp; /* NCR53c7x0_cmd structure for this command */
- int datain, /* Number of instructions per phase */
- dataout;
- int data_transfer_instructions, /* Count of dynamic instructions */
- i; /* Counter */
- u32 *cmd_datain, /* Address of datain/dataout code */
- *cmd_dataout; /* Incremented as we assemble */
-#ifdef notyet
- unsigned char *msgptr; /* Current byte in select message */
- int msglen; /* Length of whole select message */
-#endif
- unsigned long flags;
- NCR53c7x0_local_setup(cmd->host);
-
- if (!(tmp = allocate_cmd (cmd)))
- return NULL;
-
-
- /*
- * Decide whether we need to generate commands for DATA IN,
- * DATA OUT, neither, or both based on the SCSI command
- */
-
- switch (cmd->cmnd[0]) {
- /* These commands do DATA IN */
- case INQUIRY:
- case MODE_SENSE:
- case READ_6:
- case READ_10:
- case READ_CAPACITY:
- case REQUEST_SENSE:
- datain = 2 * (cmd->use_sg ? cmd->use_sg : 1) + 3;
- dataout = 0;
- break;
- /* These commands do DATA OUT */
- case MODE_SELECT:
- case WRITE_6:
- case WRITE_10:
-#if 0
- printk("scsi%d : command is ", host->host_no);
- print_command(cmd->cmnd);
-#endif
-#if 0
- printk ("scsi%d : %d scatter/gather segments\n", host->host_no,
- cmd->use_sg);
-#endif
- datain = 0;
- dataout = 2 * (cmd->use_sg ? cmd->use_sg : 1) + 3;
-#if 0
- hostdata->options |= OPTION_DEBUG_INTR;
-#endif
- break;
- /*
- * These commands do no data transfer, we should force an
- * interrupt if a data phase is attempted on them.
- */
- case START_STOP:
- case TEST_UNIT_READY:
- datain = dataout = 0;
- break;
- /*
- * We don't know about these commands, so generate code to handle
- * both DATA IN and DATA OUT phases.
- */
- default:
- datain = dataout = 2 * (cmd->use_sg ? cmd->use_sg : 1) + 3;
- }
-
- /*
- * New code : so that active pointers work correctly irregardless
- * of where the saved data pointer is at, we want to immediately
- * enter the dynamic code after selection, and on a non-data
- * phase perform a CALL to the non-data phase handler, with
- * returns back to this address.
- *
- * If a phase mismatch is encountered in the middle of a
- * Block MOVE instruction, we want to _leave_ that instruction
- * unchanged as the current case is, modify a temporary buffer,
- * and point the active pointer (TEMP) at that.
- *
- * Furthermore, we want to implement a saved data pointer,
- * set by the SAVE_DATA_POINTERs message.
- *
- * So, the data transfer segments will change to
- * CALL data_transfer, WHEN NOT data phase
- * MOVE x, x, WHEN data phase
- * ( repeat )
- * JUMP other_transfer
- */
-
- data_transfer_instructions = datain + dataout;
-
- /*
- * When we perform a request sense, we overwrite various things,
- * including the data transfer code. Make sure we have enough
- * space to do that.
- */
-
- if (data_transfer_instructions < 2)
- data_transfer_instructions = 2;
-
-
- /*
- * The saved data pointer is set up so that a RESTORE POINTERS message
- * will start the data transfer over at the beggining.
- */
-
- tmp->saved_data_pointer = virt_to_bus (hostdata->script) +
- hostdata->E_data_transfer;
-
- /*
- * Initialize Linux specific fields.
- */
-
- tmp->cmd = cmd;
- tmp->next = NULL;
- tmp->flags = 0;
- tmp->dsa_next_addr = virt_to_bus(tmp->dsa) + hostdata->dsa_next -
- hostdata->dsa_start;
- tmp->dsa_addr = virt_to_bus(tmp->dsa) - hostdata->dsa_start;
-
- /*
- * Calculate addresses of dynamic code to fill in DSA
- */
-
- tmp->data_transfer_start = tmp->dsa + (hostdata->dsa_end -
- hostdata->dsa_start) / sizeof(u32);
- tmp->data_transfer_end = tmp->data_transfer_start +
- 2 * data_transfer_instructions;
-
- cmd_datain = datain ? tmp->data_transfer_start : NULL;
- cmd_dataout = dataout ? (datain ? cmd_datain + 2 * datain : tmp->
- data_transfer_start) : NULL;
-
- /*
- * Fill in the NCR53c7x0_cmd structure as follows
- * dsa, with fixed up DSA code
- * datain code
- * dataout code
- */
-
- /* Copy template code into dsa and perform all necessary fixups */
- if (hostdata->dsa_fixup)
- hostdata->dsa_fixup(tmp);
-
- patch_dsa_32(tmp->dsa, dsa_next, 0, 0);
- patch_dsa_32(tmp->dsa, dsa_cmnd, 0, virt_to_bus(cmd));
-
- if (hostdata->options & OPTION_DEBUG_SYNCHRONOUS)
- if (hostdata->sync[cmd->target].select_indirect !=
- ((hostdata->sync[cmd->target].scntl3_sanity << 24) |
- (cmd->target << 16) |
- (hostdata->sync[cmd->target].sxfer_sanity << 8))) {
- printk ("scsi%d : sanity check failed select_indirect=0x%x\n",
- host->host_no, hostdata->sync[cmd->target].select_indirect);
- FATAL(host);
-
- }
-
- patch_dsa_32(tmp->dsa, dsa_select, 0, hostdata->sync[cmd->target].
- select_indirect);
- /*
- * Right now, we'll do the WIDE and SYNCHRONOUS negotiations on
- * different commands; although it should be trivial to do them
- * both at the same time.
- */
- if (hostdata->initiate_wdtr & (1 << cmd->target)) {
- memcpy ((void *) (tmp->select + 1), (void *) wdtr_message,
- sizeof(wdtr_message));
- patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1 + sizeof(wdtr_message));
- save_flags(flags);
- cli();
- hostdata->initiate_wdtr &= ~(1 << cmd->target);
- restore_flags(flags);
- } else if (hostdata->initiate_sdtr & (1 << cmd->target)) {
- memcpy ((void *) (tmp->select + 1), (void *) sdtr_message,
- sizeof(sdtr_message));
- patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1 + sizeof(sdtr_message));
- tmp->flags |= CMD_FLAG_SDTR;
- save_flags(flags);
- cli();
- hostdata->initiate_sdtr &= ~(1 << cmd->target);
- restore_flags(flags);
-
- }
-#if 1
- else if (!(hostdata->talked_to & (1 << cmd->target)) &&
- !(hostdata->options & OPTION_NO_ASYNC)) {
- memcpy ((void *) (tmp->select + 1), (void *) async_message,
- sizeof(async_message));
- patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1 + sizeof(async_message));
- tmp->flags |= CMD_FLAG_SDTR;
- }
-#endif
- else
- patch_dsa_32(tmp->dsa, dsa_msgout, 0, 1);
- hostdata->talked_to |= (1 << cmd->target);
- tmp->select[0] = (hostdata->options & OPTION_DISCONNECT) ?
- IDENTIFY (1, cmd->lun) : IDENTIFY (0, cmd->lun);
- patch_dsa_32(tmp->dsa, dsa_msgout, 1, virt_to_bus(tmp->select));
- patch_dsa_32(tmp->dsa, dsa_cmdout, 0, cmd->cmd_len);
- patch_dsa_32(tmp->dsa, dsa_cmdout, 1, virt_to_bus(cmd->cmnd));
- patch_dsa_32(tmp->dsa, dsa_dataout, 0, cmd_dataout ?
- virt_to_bus (cmd_dataout)
- : virt_to_bus (hostdata->script) + hostdata->E_other_transfer);
- patch_dsa_32(tmp->dsa, dsa_datain, 0, cmd_datain ?
- virt_to_bus (cmd_datain)
- : virt_to_bus (hostdata->script) + hostdata->E_other_transfer);
- /*
- * XXX - need to make endian aware, should use separate variables
- * for both status and message bytes.
- */
- patch_dsa_32(tmp->dsa, dsa_msgin, 0, 1);
-/*
- * FIXME : these only works for little endian. We probably want to
- * provide message and status fields in the NCR53c7x0_cmd
- * structure, and assign them to cmd->result when we're done.
- */
- patch_dsa_32(tmp->dsa, dsa_msgin, 1, virt_to_bus(&cmd->result) + 1);
- patch_dsa_32(tmp->dsa, dsa_status, 0, 1);
- patch_dsa_32(tmp->dsa, dsa_status, 1, virt_to_bus(&cmd->result));
- patch_dsa_32(tmp->dsa, dsa_msgout_other, 0, 1);
- patch_dsa_32(tmp->dsa, dsa_msgout_other, 1,
- virt_to_bus(&(hostdata->NCR53c7xx_msg_nop)));
-
- /*
- * Generate code for zero or more of the DATA IN, DATA OUT phases
- * in the format
- *
- * CALL data_transfer, WHEN NOT phase
- * MOVE first buffer length, first buffer address, WHEN phase
- * ...
- * MOVE last buffer length, last buffer address, WHEN phase
- * JUMP other_transfer
- */
-
-/*
- * See if we're getting to data transfer by generating an unconditional
- * interrupt.
- */
-#if 0
- if (datain) {
- cmd_datain[0] = 0x98080000;
- cmd_datain[1] = 0x03ffd00d;
- cmd_datain += 2;
- }
-#endif
-
-/*
- * XXX - I'm undecided whether all of this nonsense is faster
- * in the long run, or whether I should just go and implement a loop
- * on the NCR chip using table indirect mode?
- *
- * In any case, this is how it _must_ be done for 53c700/700-66 chips,
- * so this stays even when we come up with something better.
- *
- * When we're limited to 1 simultaneous command, no overlapping processing,
- * we're seeing 630K/sec, with 7% CPU usage on a slow Syquest 45M
- * drive.
- *
- * Not bad, not good. We'll see.
- */
-
- for (i = 0; cmd->use_sg ? (i < cmd->use_sg) : !i; cmd_datain += 4,
- cmd_dataout += 4, ++i) {
- u32 buf = cmd->use_sg ?
- virt_to_bus(((struct scatterlist *)cmd->buffer)[i].address) :
- virt_to_bus(cmd->request_buffer);
- u32 count = cmd->use_sg ?
- ((struct scatterlist *)cmd->buffer)[i].length :
- cmd->request_bufflen;
-
- if (datain) {
- /* CALL other_in, WHEN NOT DATA_IN */
- cmd_datain[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_CALL |
- DCMD_TCI_IO) << 24) |
- DBC_TCI_WAIT_FOR_VALID | DBC_TCI_COMPARE_PHASE;
- cmd_datain[1] = virt_to_bus (hostdata->script) +
- hostdata->E_other_in;
- /* MOVE count, buf, WHEN DATA_IN */
- cmd_datain[2] = ((DCMD_TYPE_BMI | DCMD_BMI_OP_MOVE_I | DCMD_BMI_IO)
- << 24) | count;
- cmd_datain[3] = buf;
-#if 0
- print_insn (host, cmd_datain, "dynamic ", 1);
- print_insn (host, cmd_datain + 2, "dynamic ", 1);
-#endif
- }
- if (dataout) {
- /* CALL other_out, WHEN NOT DATA_OUT */
- cmd_dataout[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_CALL) << 24) |
- DBC_TCI_WAIT_FOR_VALID | DBC_TCI_COMPARE_PHASE;
- cmd_dataout[1] = virt_to_bus(hostdata->script) +
- hostdata->E_other_out;
- /* MOVE count, buf, WHEN DATA+OUT */
- cmd_dataout[2] = ((DCMD_TYPE_BMI | DCMD_BMI_OP_MOVE_I) << 24)
- | count;
- cmd_dataout[3] = buf;
-#if 0
- print_insn (host, cmd_dataout, "dynamic ", 1);
- print_insn (host, cmd_dataout + 2, "dynamic ", 1);
-#endif
- }
- }
-
- /*
- * Install JUMP instructions after the data transfer routines to return
- * control to the do_other_transfer routines.
- */
-
-
- if (datain) {
- cmd_datain[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_JUMP) << 24) |
- DBC_TCI_TRUE;
- cmd_datain[1] = virt_to_bus(hostdata->script) +
- hostdata->E_other_transfer;
-#if 0
- print_insn (host, cmd_datain, "dynamic jump ", 1);
-#endif
- cmd_datain += 2;
- }
-#if 0
- if (datain) {
- cmd_datain[0] = 0x98080000;
- cmd_datain[1] = 0x03ffdeed;
- cmd_datain += 2;
- }
-#endif
- if (dataout) {
- cmd_dataout[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_JUMP) << 24) |
- DBC_TCI_TRUE;
- cmd_dataout[1] = virt_to_bus(hostdata->script) +
- hostdata->E_other_transfer;
-#if 0
- print_insn (host, cmd_dataout, "dynamic jump ", 1);
-#endif
- cmd_dataout += 2;
- }
- return tmp;
-}
-
-/*
- * Function : int NCR53c7xx_queue_command (Scsi_Cmnd *cmd,
- * void (*done)(Scsi_Cmnd *))
- *
- * Purpose : enqueues a SCSI command
- *
- * Inputs : cmd - SCSI command, done - function called on completion, with
- * a pointer to the command descriptor.
- *
- * Returns : 0
- *
- * Side effects :
- * cmd is added to the per instance driver issue_queue, with major
- * twiddling done to the host specific fields of cmd. If the
- * process_issue_queue corouting isn't running, it is restarted.
- *
- * NOTE : we use the host_scribble field of the Scsi_Cmnd structure to
- * hold our own data, and pervert the ptr field of the SCp field
- * to create a linked list.
- */
-
-int
-NCR53c7xx_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *)) {
- struct Scsi_Host *host = cmd->host;
- struct NCR53c7x0_hostdata *hostdata =
- (struct NCR53c7x0_hostdata *) host->hostdata;
- unsigned long flags;
- Scsi_Cmnd *tmp;
-
- cmd->scsi_done = done;
- cmd->host_scribble = NULL;
- cmd->SCp.ptr = NULL;
- cmd->SCp.buffer = NULL;
-
- save_flags(flags);
- cli();
- if ((hostdata->options & (OPTION_DEBUG_INIT_ONLY|OPTION_DEBUG_PROBE_ONLY))
- || ((hostdata->options & OPTION_DEBUG_TARGET_LIMIT) &&
- !(hostdata->debug_lun_limit[cmd->target] & (1 << cmd->lun)))
-#ifdef LINUX_1_2
- || cmd->target > 7
-#else
- || cmd->target > host->max_id
-#endif
- || cmd->target == host->this_id
- || hostdata->state == STATE_DISABLED) {
- printk("scsi%d : disabled or bad target %d lun %d\n", host->host_no,
- cmd->target, cmd->lun);
- cmd->result = (DID_BAD_TARGET << 16);
- } else if ((hostdata->options & OPTION_DEBUG_NCOMMANDS_LIMIT) &&
- (hostdata->debug_count_limit == 0)) {
- printk("scsi%d : maximum commands exceeded\n", host->host_no);
- cmd->result = (DID_BAD_TARGET << 16);
- cmd->result = (DID_BAD_TARGET << 16);
- } else if (hostdata->options & OPTION_DEBUG_READ_ONLY) {
- switch (cmd->cmnd[0]) {
- case WRITE_6:
- case WRITE_10:
- printk("scsi%d : WRITE attempted with NO_WRITE debugging flag set\n",
- host->host_no);
- cmd->result = (DID_BAD_TARGET << 16);
- }
- } else {
- if ((hostdata->options & OPTION_DEBUG_TARGET_LIMIT) &&
- hostdata->debug_count_limit != -1)
- --hostdata->debug_count_limit;
- restore_flags (flags);
- cmd->result = 0xffff; /* The NCR will overwrite message
- and status with valid data */
- cmd->host_scribble = (unsigned char *) tmp = create_cmd (cmd);
- }
- cli();
- /*
- * REQUEST SENSE commands are inserted at the head of the queue
- * so that we do not clear the contingent allegience condition
- * they may be looking at.
- */
-
- if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) {
- cmd->SCp.ptr = (unsigned char *) hostdata->issue_queue;
- hostdata->issue_queue = cmd;
- } else {
- for (tmp = (Scsi_Cmnd *) hostdata->issue_queue; tmp->SCp.ptr;
- tmp = (Scsi_Cmnd *) tmp->SCp.ptr);
- tmp->SCp.ptr = (unsigned char *) cmd;
- }
- restore_flags (flags);
- run_process_issue_queue();
- return 0;
-}
-
-/*
- * Function : void to_schedule_list (struct Scsi_Host *host,
- * struct NCR53c7x0_hostdata * hostdata, Scsi_Cmnd *cmd)
- *
- * Purpose : takes a SCSI command which was just removed from the
- * issue queue, and deals with it by inserting it in the first
- * free slot in the schedule list or by terminating it immediately.
- *
- * Inputs :
- * host - SCSI host adater; hostdata - hostdata structure for
- * this adapter; cmd - a pointer to the command; should have
- * the host_scribble field initialized to point to a valid
- *
- * Side effects :
- * cmd is added to the per instance schedule list, with minor
- * twiddling done to the host specific fields of cmd.
- *
- */
-
-static __inline__ void
-to_schedule_list (struct Scsi_Host *host, struct NCR53c7x0_hostdata *hostdata,
- struct NCR53c7x0_cmd *cmd) {
- NCR53c7x0_local_declare();
- Scsi_Cmnd *tmp = cmd->cmd;
- unsigned long flags;
- /* dsa start is negative, so subtraction is used */
- volatile u32 *current;
-
- int i;
- NCR53c7x0_local_setup(host);
-#if 0
- printk("scsi%d : new dsa is 0x%lx (virt 0x%p)\n", host->host_no,
- virt_to_bus(dsa), dsa);
-#endif
-
- save_flags(flags);
- cli();
-
- /*
- * Work arround race condition : if an interrupt fired and we
- * got disabled forget about this command.
- */
-
- if (hostdata->state == STATE_DISABLED) {
- printk("scsi%d : driver disabled\n", host->host_no);
- tmp->result = (DID_BAD_TARGET << 16);
- cmd->next = (struct NCR53c7x0_cmd *) hostdata->free;
- hostdata->free = cmd;
- tmp->scsi_done(tmp);
- restore_flags (flags);
- return;
- }
-
- for (i = host->can_queue, current = hostdata->schedule;
- i > 0 && current[0] != hostdata->NOP_insn;
- --i, current += 2 /* JUMP instructions are two words */);
-
- if (i > 0) {
- ++hostdata->busy[tmp->target][tmp->lun];
- cmd->next = hostdata->running_list;
- hostdata->running_list = cmd;
-
- /* Restore this instruction to a NOP once the command starts */
- cmd->dsa [(hostdata->dsa_jump_dest - hostdata->dsa_start) /
- sizeof(u32)] = (u32) virt_to_bus ((void *)current);
- /* Replace the current jump operand. */
- current[1] =
- virt_to_bus ((void *) cmd->dsa) + hostdata->E_dsa_code_begin -
- hostdata->E_dsa_code_template;
- /* Replace the NOP instruction with a JUMP */
- current[0] = ((DCMD_TYPE_TCI|DCMD_TCI_OP_JUMP) << 24) |
- DBC_TCI_TRUE;
- } else {
- printk ("scsi%d: no free slot\n", host->host_no);
- disable(host);
- tmp->result = (DID_ERROR << 16);
- cmd->next = (struct NCR53c7x0_cmd *) hostdata->free;
- hostdata->free = cmd;
- tmp->scsi_done(tmp);
- restore_flags (flags);
- return;
- }
-
- /*
- * If the NCR chip is in an idle state, start it running the scheduler
- * immediately. Otherwise, signal the chip to jump to schedule as
- * soon as it is idle.
- */
- if (hostdata->idle) {
- hostdata->idle = 0;
- hostdata->state = STATE_RUNNING;
- NCR53c7x0_write32 (DSP_REG, virt_to_bus ((void *)hostdata->schedule));
- } else {
- NCR53c7x0_write8(hostdata->istat, ISTAT_10_SIGP);
- }
-
- restore_flags(flags);
-}
-
-/*
- * Function : busyp (struct Scsi_Host *host, struct NCR53c7x0_hostdata
- * *hostdata, Scsi_Cmnd *cmd)
- *
- * Purpose : decide if we can pass the given SCSI command on to the
- * device in question or not.
- *
- * Returns : non-zero when we're busy, 0 when we aren't.
- */
-
-static __inline__ int
-busyp (struct Scsi_Host *host, struct NCR53c7x0_hostdata *hostdata,
- Scsi_Cmnd *cmd) {
- /* FIXME : in the future, this needs to accomodate SCSI-II tagged
- queuing, and we may be able to play with fairness here a bit.
- */
- return hostdata->busy[cmd->target][cmd->lun];
-}
-
-/*
- * Function : process_issue_queue (void)
- *
- * Purpose : transfer commands from the issue queue to NCR start queue
- * of each NCR53c7/8xx in the system, avoiding kernel stack
- * overflows when the scsi_done() function is invoked recursively.
- *
- * NOTE : process_issue_queue exits with interrupts *disabled*, so the
- * caller must renable them if it desires.
- *
- * NOTE : process_issue_queue should be called from both
- * NCR53c7x0_queue_command() and from the interrupt handler
- * after command completion in case NCR53c7x0_queue_command()
- * isn't invoked again but we've freed up resources that are
- * needed.
- */
-
-static void
-process_issue_queue (unsigned long flags) {
- Scsi_Cmnd *tmp, *prev;
- struct Scsi_Host *host;
- struct NCR53c7x0_hostdata *hostdata;
- int done;
-
- /*
- * We run (with interrupts disabled) until we're sure that none of
- * the host adapters have anything that can be done, at which point
- * we set process_issue_queue_running to 0 and exit.
- *
- * Interrupts are enabled before doing various other internal
- * instructions, after we've decided that we need to run through
- * the loop again.
- *
- */
-
- do {
- cli(); /* Freeze request queues */
- done = 1;
- for (host = first_host; host && host->hostt == the_template;
- host = host->next) {
- hostdata = (struct NCR53c7x0_hostdata *) host->hostdata;
- cli();
- if (hostdata->issue_queue) {
- if (hostdata->state == STATE_DISABLED) {
- tmp = (Scsi_Cmnd *) hostdata->issue_queue;
- hostdata->issue_queue = (Scsi_Cmnd *) tmp->SCp.ptr;
- tmp->result = (DID_BAD_TARGET << 16);
- if (tmp->host_scribble) {
- ((struct NCR53c7x0_cmd *)tmp->host_scribble)->next =
- hostdata->free;
- hostdata->free =
- (struct NCR53c7x0_cmd *)tmp->host_scribble;
- tmp->host_scribble = NULL;
- }
- tmp->scsi_done (tmp);
- done = 0;
- } else
- for (tmp = (Scsi_Cmnd *) hostdata->issue_queue,
- prev = NULL; tmp; prev = tmp, tmp = (Scsi_Cmnd *)
- tmp->SCp.ptr)
- if (!tmp->host_scribble ||
- !busyp (host, hostdata, tmp)) {
- if (prev)
- prev->SCp.ptr = tmp->SCp.ptr;
- else
- hostdata->issue_queue = (Scsi_Cmnd *)
- tmp->SCp.ptr;
- tmp->SCp.ptr = NULL;
- if (tmp->host_scribble) {
- if (hostdata->options & OPTION_DEBUG_QUEUES)
- printk ("scsi%d : moving command for target %d lun %d to start list\n",
- host->host_no, tmp->target, tmp->lun);
-
-
- to_schedule_list (host, hostdata,
- (struct NCR53c7x0_cmd *)
- tmp->host_scribble);
- } else {
- if (((tmp->result & 0xff) == 0xff) ||
- ((tmp->result & 0xff00) == 0xff00)) {
- printk ("scsi%d : danger Will Robinson!\n",
- host->host_no);
- tmp->result = DID_ERROR << 16;
- disable (host);
- }
- tmp->scsi_done(tmp);
- }
- done = 0;
- } /* if target/lun is not busy */
- } /* if hostdata->issue_queue */
- if (!done)
- restore_flags (flags);
- } /* for host */
- } while (!done);
- process_issue_queue_running = 0;
-}
-
-/*
- * Function : static void intr_scsi (struct Scsi_Host *host,
- * struct NCR53c7x0_cmd *cmd)
- *
- * Purpose : handle all SCSI interrupts, indicated by the setting
- * of the SIP bit in the ISTAT register.
- *
- * Inputs : host, cmd - host and NCR command causing the interrupt, cmd
- * may be NULL.
- */
-
-static void
-intr_scsi (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) {
- NCR53c7x0_local_declare();
- struct NCR53c7x0_hostdata *hostdata =
- (struct NCR53c7x0_hostdata *) host->hostdata;
- unsigned char sstat0_sist0, sist1, /* Registers */
- fatal; /* Did a fatal interrupt
- occur ? */
-
- int is_8xx_chip;
- NCR53c7x0_local_setup(host);
-
- fatal = 0;
-
- is_8xx_chip = ((unsigned) (hostdata->chip - 800)) < 100;
- if (is_8xx_chip) {
- sstat0_sist0 = NCR53c7x0_read8(SIST0_REG_800);
- udelay(1);
- sist1 = NCR53c7x0_read8(SIST1_REG_800);
- } else {
- sstat0_sist0 = NCR53c7x0_read8(SSTAT0_REG);
- sist1 = 0;
- }
-
- if (hostdata->options & OPTION_DEBUG_INTR)
- printk ("scsi%d : SIST0 0x%0x, SIST1 0x%0x\n", host->host_no,
- sstat0_sist0, sist1);
-
- /* 250ms selection timeout */
- if ((is_8xx_chip && (sist1 & SIST1_800_STO)) ||
- (!is_8xx_chip && (sstat0_sist0 & SSTAT0_700_STO))) {
- fatal = 1;
- if (hostdata->options & OPTION_DEBUG_INTR) {
- printk ("scsi%d : Selection Timeout\n", host->host_no);
- if (cmd) {
- printk("scsi%d : target %d, lun %d, command ",
- host->host_no, cmd->cmd->target, cmd->cmd->lun);
- print_command (cmd->cmd->cmnd);
- printk("scsi%d : dsp = 0x%x (virt 0x%p)\n", host->host_no,
- NCR53c7x0_read32(DSP_REG),
- bus_to_virt(NCR53c7x0_read32(DSP_REG)));
- } else {
- printk("scsi%d : no command\n", host->host_no);
- }
- }
-/*
- * XXX - question : how do we want to handle the Illegal Instruction
- * interrupt, which may occur before or after the Selection Timeout
- * interrupt?
- */
-
- if (1) {
- hostdata->idle = 1;
- hostdata->expecting_sto = 0;
-
- if (hostdata->test_running) {
- hostdata->test_running = 0;
- hostdata->test_completed = 3;
- } else if (cmd) {
- abnormal_finished(cmd, DID_BAD_TARGET << 16);
- }
-#if 0
- hostdata->intrs = 0;
-#endif
- }
- }
-
-/*
- * FIXME : in theory, we can also get a UDC when a STO occurs.
- */
- if (sstat0_sist0 & SSTAT0_UDC) {
- fatal = 1;
- if (cmd) {
- printk("scsi%d : target %d lun %d unexpected disconnect\n",
- host->host_no, cmd->cmd->target, cmd->cmd->lun);
- print_lots (host);
- abnormal_finished(cmd, DID_ERROR << 16);
- } else
- printk("scsi%d : unexpected disconnect (no command)\n",
- host->host_no);
-
- hostdata->dsp = (u32 *) hostdata->schedule;
- hostdata->dsp_changed = 1;
- }
-
- /* SCSI PARITY error */
- if (sstat0_sist0 & SSTAT0_PAR) {
- fatal = 1;
- if (cmd && cmd->cmd) {
- printk("scsi%d : target %d lun %d parity error.\n",
- host->host_no, cmd->cmd->target, cmd->cmd->lun);
- abnormal_finished (cmd, DID_PARITY << 16);
- } else
- printk("scsi%d : parity error\n", host->host_no);
- /* Should send message out, parity error */
-
- /* XXX - Reduce synchronous transfer rate! */
- hostdata->dsp = hostdata->script + hostdata->E_initiator_abort /
- sizeof(u32);
- hostdata->dsp_changed = 1;
- /* SCSI GROSS error */
- }
-
- if (sstat0_sist0 & SSTAT0_SGE) {
- fatal = 1;
- printk("scsi%d : gross error\n", host->host_no);
- /* Reset SCSI offset */
- if ((hostdata->chip / 100) == 8) {
- NCR53c7x0_write8 (STEST2_REG_800, STEST2_800_ROF);
- }
-
- /*
- * A SCSI gross error may occur when we have
- *
- * - A synchronous offset which causes the SCSI FIFO to be overwritten.
- *
- * - A REQ which causes the maxmimum synchronous offset programmed in
- * the SXFER register to be exceeded.
- *
- * - A phase change with an outstanding synchronous offset.
- *
- * - Residual data in the synchronous data FIFO, with a transfer
- * other than a synchronous receive is started.$#
- */
-
-
- /* XXX Should deduce synchronous transfer rate! */
- hostdata->dsp = hostdata->script + hostdata->E_initiator_abort /
- sizeof(u32);
- hostdata->dsp_changed = 1;
- /* Phase mismatch */
- }
-
- if (sstat0_sist0 & SSTAT0_MA) {
- fatal = 1;
- if (hostdata->options & OPTION_DEBUG_INTR)
- printk ("scsi%d : SSTAT0_MA\n", host->host_no);
- intr_phase_mismatch (host, cmd);
- }
-
-#if 0
- if (sstat0_sist0 & SIST0_800_RSL)
- printk ("scsi%d : Oh no Mr. Bill!\n", host->host_no);
-#endif
-
-/*
- * If a fatal SCSI interrupt occurs, we must insure that the DMA and
- * SCSI FIFOs were flushed.
- */
-
- if (fatal) {
- if (!hostdata->dstat_valid) {
- hostdata->dstat = NCR53c7x0_read8(DSTAT_REG);
- hostdata->dstat_valid = 1;
- }
-
-/* XXX - code check for 700/800 chips */
- if (!(hostdata->dstat & DSTAT_DFE)) {
- printk ("scsi%d : DMA FIFO not empty\n", host->host_no);
- if (NCR53c7x0_read8 (CTEST2_REG_800) & CTEST2_800_DDIR) {
- printk ("scsi%d: Flushing DMA FIFO\n",
- host->host_no);
- NCR53c7x0_write8 (CTEST3_REG_800, CTEST3_800_FLF);
- while (!((hostdata->dstat = NCR53c7x0_read8(DSTAT_REG)) &
- DSTAT_DFE));
- } else {
- NCR53c7x0_write8 (CTEST3_REG_800, CTEST3_800_CLF);
- while (NCR53c7x0_read8 (CTEST3_REG_800) & CTEST3_800_CLF);
- }
- hostdata->dstat |= DSTAT_DFE;
- }
- }
-}
-
-/*
- * Function : static void NCR53c7x0_intr (int irq, struct pt_regs * regs)
- *
- * Purpose : handle NCR53c7x0 interrupts for all NCR devices sharing
- * the same IRQ line.
- *
- * Inputs : Since we're using the SA_INTERRUPT interrupt handler
- * semantics, irq indicates the interrupt which invoked
- * this handler.
- */
-
-static void
-NCR53c7x0_intr (int irq, struct pt_regs * regs) {
- NCR53c7x0_local_declare();
- struct Scsi_Host *host; /* Host we are looking at */
- unsigned char istat; /* Values of interrupt regs */
- struct NCR53c7x0_hostdata *hostdata; /* host->hostdata */
- struct NCR53c7x0_cmd *cmd, /* command which halted */
- **cmd_prev_ptr;
- u32 *dsa; /* DSA */
- int done = 1; /* Indicates when handler
- should terminate */
- int interrupted = 0; /* This HA generated
- an interrupt */
- int have_intfly; /* Don't print warning
- messages when we stack
- INTFLYs */
- unsigned long flags;
-
-#ifdef NCR_DEBUG
- char buf[80]; /* Debugging sprintf buffer */
- size_t buflen; /* Length of same */
-#endif
-
- do {
- done = 1;
- for (host = first_host; host; host = host->next)
- if (host->hostt == the_template && host->irq == irq) {
- NCR53c7x0_local_setup(host);
-
- hostdata = (struct NCR53c7x0_hostdata *) host->hostdata;
- hostdata->dsp_changed = 0;
- interrupted = 0;
- have_intfly = 0;
-
- do {
- int is_8xx_chip;
-
- hostdata->dstat_valid = 0;
- interrupted = 0;
- /*
- * Only read istat once, since reading it again will unstack
- * interrupts?
- */
- istat = NCR53c7x0_read8(hostdata->istat);
-
- /*
- * INTFLY interrupts are used by the NCR53c720, NCR53c810,
- * and NCR53c820 to signify completion of a command. Since
- * the SCSI processor continues running, we can't just look
- * at the contents of the DSA register and continue running.
- */
-/* XXX - this is too big, offends my sense of aesthetics, and should
- move to intr_intfly() */
- is_8xx_chip = ((unsigned) (hostdata->chip - 800)) < 100;
- if ((hostdata->options & OPTION_INTFLY) &&
- (is_8xx_chip && (istat & ISTAT_800_INTF))) {
- char search_found = 0; /* Got at least one ? */
- done = 0;
- interrupted = 1;
-
- /*
- * Clear the INTF bit by writing a one.
- * This reset operation is self-clearing.
- */
- NCR53c7x0_write8(hostdata->istat, istat|ISTAT_800_INTF);
-
- if (hostdata->options & OPTION_DEBUG_INTR)
- printk ("scsi%d : INTFLY\n", host->host_no);
-
- /*
- * Traverse our list of running commands, and look
- * for those with valid (non-0xff ff) status and message
- * bytes encoded in the result which signify command
- * completion.
- */
-
-
- save_flags(flags);
- cli();
-restart:
- for (cmd_prev_ptr = (struct NCR53c7x0_cmd **)
- &(hostdata->running_list), cmd =
- (struct NCR53c7x0_cmd *) hostdata->running_list; cmd ;
- cmd_prev_ptr = (struct NCR53c7x0_cmd **) &(cmd->next),
- cmd = (struct NCR53c7x0_cmd *) cmd->next) {
- Scsi_Cmnd *tmp;
-
- if (!cmd) {
- printk("scsi%d : very weird.\n", host->host_no);
- break;
- }
-
- if (!(tmp = cmd->cmd)) {
- printk("scsi%d : weird. NCR53c7x0_cmd has no Scsi_Cmnd\n",
- host->host_no);
- continue;
- }
-#if 0
- printk ("scsi%d : looking at result of 0x%x\n",
- host->host_no, cmd->cmd->result);
-#endif
-
- if (((tmp->result & 0xff) == 0xff) ||
- ((tmp->result & 0xff00) == 0xff00))
- continue;
-
- search_found = 1;
-
- /* Important - remove from list _before_ done is called */
- if (cmd_prev_ptr)
- *cmd_prev_ptr = (struct NCR53c7x0_cmd *) cmd->next;
-
- --hostdata->busy[tmp->target][tmp->lun];
- cmd->next = hostdata->free;
- hostdata->free = cmd;
-
- tmp->host_scribble = NULL;
-
- if (hostdata->options & OPTION_DEBUG_INTR) {
- printk ("scsi%d : command complete : pid %lu, id %d,lun %d result 0x%x ",
- host->host_no, tmp->pid, tmp->target, tmp->lun, tmp->result);
- print_command (tmp->cmnd);
- }
-
-#if 0
- hostdata->options &= ~OPTION_DEBUG_INTR;
-#endif
- tmp->scsi_done(tmp);
- goto restart;
-
- }
- restore_flags(flags);
-
- /*
- * I think that we're stacking INTFLY interrupts; taking care of
- * all the finished commands on the first one, and then getting
- * worried when we see the next one. The magic with have_intfly
- * should tell if this is the case..
- */
-
- if (!search_found && !have_intfly) {
- printk ("scsi%d : WARNING : INTFLY with no completed commands.\n",
- host->host_no);
- } else if (!have_intfly) {
- have_intfly = 1;
- run_process_issue_queue();
- }
- }
-
- if (istat & (ISTAT_SIP|ISTAT_DIP)) {
- done = 0;
- interrupted = 1;
- hostdata->state = STATE_HALTED;
-
- if (NCR53c7x0_read8 ((hostdata->chip / 100) == 8 ?
- SSTAT1_REG : SSTAT2_REG) & SSTAT2_FF_MASK)
- printk ("scsi%d : SCSI FIFO not empty\n",
- host->host_no);
-
- /*
- * NCR53c700 and NCR53c700-66 change the current SCSI
- * process, hostdata->current, in the Linux driver so
- * cmd = hostdata->current.
- *
- * With other chips, we must look through the commands
- * executing and find the command structure which
- * corresponds to the DSA register.
- */
-
- if (hostdata->options & OPTION_700) {
- cmd = (struct NCR53c7x0_cmd *) hostdata->current;
- } else {
- dsa = bus_to_virt(NCR53c7x0_read32(DSA_REG));
- for (cmd = (struct NCR53c7x0_cmd *)
- hostdata->running_list; cmd &&
- (dsa + (hostdata->dsa_start / sizeof(u32))) !=
- cmd->dsa;
- cmd = (struct NCR53c7x0_cmd *)(cmd->next));
- }
- if (hostdata->options & OPTION_DEBUG_INTR) {
- if (cmd) {
- printk("scsi%d : interrupt for pid %lu, id %d, lun %d ",
- host->host_no, cmd->cmd->pid, (int) cmd->cmd->target,
- (int) cmd->cmd->lun);
- print_command (cmd->cmd->cmnd);
- } else {
- printk("scsi%d : no active command\n", host->host_no);
- }
- }
-
- if (istat & ISTAT_SIP) {
- if (hostdata->options & OPTION_DEBUG_INTR)
- printk ("scsi%d : ISTAT_SIP\n", host->host_no);
- intr_scsi (host, cmd);
- }
-
- if (istat & ISTAT_DIP) {
- if (hostdata->options & OPTION_DEBUG_INTR)
- printk ("scsi%d : ISTAT_DIP\n", host->host_no);
- intr_dma (host, cmd);
- }
-
- if (!hostdata->dstat_valid) {
- hostdata->dstat = NCR53c7x0_read8(DSTAT_REG);
- hostdata->dstat_valid = 1;
- }
-
- /* XXX - code check for 700/800 chips */
- if (!(hostdata->dstat & DSTAT_DFE)) {
- printk ("scsi%d : DMA FIFO not empty\n", host->host_no);
- if (NCR53c7x0_read8 (CTEST2_REG_800) & CTEST2_800_DDIR) {
- printk ("scsi%d: Flushing DMA FIFO\n",
- host->host_no);
- NCR53c7x0_write8 (CTEST3_REG_800, CTEST3_800_FLF);
- while (!((hostdata->dstat = NCR53c7x0_read8(DSTAT_REG)) &
- DSTAT_DFE));
- } else
- {
- NCR53c7x0_write8 (CTEST3_REG_800, CTEST3_800_CLF);
- while (NCR53c7x0_read8 (CTEST3_REG_800) & CTEST3_800_CLF);
- }
- hostdata->dstat |= DSTAT_DFE;
- }
- }
- } while (interrupted);
-
-
-
- if (hostdata->intrs != -1)
- hostdata->intrs++;
-#if 0
- if (hostdata->intrs > 40) {
- printk("scsi%d : too many interrupts, halting", host->host_no);
- disable(host);
- }
-#endif
-
- if (!hostdata->idle && hostdata->state == STATE_HALTED) {
- if (!hostdata->dsp_changed) {
- hostdata->dsp = (u32 *)
- bus_to_virt(NCR53c7x0_read32(DSP_REG));
- }
-
-#if 0
- printk("scsi%d : new dsp is 0x%lx (virt 0x%p)\n",
- host->host_no, virt_to_bus(hostdata->dsp), hostdata->dsp);
-#endif
-
- hostdata->state = STATE_RUNNING;
- NCR53c7x0_write32 (DSP_REG, virt_to_bus(hostdata->dsp));
- }
- }
- } while (!done);
-}
-
-
-/*
- * Function : static int abort_connected (struct Scsi_Host *host)
- *
- * Purpose : Assuming that the NCR SCSI processor is currently
- * halted, break the currently established nexus. Clean
- * up of the NCR53c7x0_cmd and Scsi_Cmnd structures should
- * be done on receipt of the abort interrupt.
- *
- * Inputs : host - SCSI host
- *
- */
-
-static int
-abort_connected (struct Scsi_Host *host) {
-#ifdef NEW_ABORT
- NCR53c7x0_local_declare();
-#endif
- struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
- host->hostdata;
-/* FIXME : this probably should change for production kernels; at the
- least, counter sould move to a per-host structure. */
- static int counter = 5;
-#ifdef NEW_ABORT
- int sstat, phase, offset;
- u32 *script;
- NCR53c7x0_local_setup(host);
-#endif
-
- if (--counter <= 0) {
- disable(host);
- return 0;
- }
-
- printk ("scsi%d : DANGER : abort_connected() called \n",
- host->host_no);
-
-#ifdef NEW_ABORT
-
-/*
- * New strategy : Rather than using a generic abort routine,
- * we'll specifically try to source or sink the appropriate
- * amount of data for the phase we're currently in (taking into
- * account the current synchronous offset)
- */
-
- sstat = (NCR53c8x0_read8 ((chip / 100) == 8 ? SSTAT1_REG : SSTAT2_REG);
- offset = OFFSET (sstat & SSTAT2_FF_MASK) >> SSTAT2_FF_SHIFT;
- phase = sstat & SSTAT2_PHASE_MASK;
-
-/*
- * SET ATN
- * MOVE source_or_sink, WHEN CURRENT PHASE
- * < repeat for each outstanding byte >
- * JUMP send_abort_message
- */
-
- script = hostdata->abort_script = kmalloc (
- 8 /* instruction size */ * (
- 1 /* set ATN */ +
- (!offset ? 1 : offset) /* One transfer per outstanding byte */ +
- 1 /* send abort message */),
- GFP_ATOMIC);
-
-
-#else /* def NEW_ABORT */
- hostdata->dsp = hostdata->script + hostdata->E_initiator_abort /
- sizeof(u32);
-#endif /* def NEW_ABORT */
- hostdata->dsp_changed = 1;
-
-/* XXX - need to flag the command as aborted after the abort_connected
- code runs
- */
- return 0;
-}
-
-/*
- * Function : static int datapath_residual (Scsi_Host *host)
- *
- * Purpose : return residual data count of what's in the chip.
- *
- * Inputs : host - SCSI host
- */
-
-static int
-datapath_residual (struct Scsi_Host *host) {
- NCR53c7x0_local_declare();
- struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
- host->hostdata;
- int count, synchronous, sstat;
- NCR53c7x0_local_setup(host);
- /* COMPAT : the 700 and 700-66 need to use DFIFO_00_BO_MASK */
- count = ((NCR53c7x0_read8 (DFIFO_REG) & DFIFO_10_BO_MASK) -
- (NCR53c7x0_read32 (DBC_REG) & DFIFO_10_BO_MASK)) & DFIFO_10_BO_MASK;
- synchronous = NCR53c7x0_read8 (SXFER_REG) & SXFER_MO_MASK;
- /* COMPAT : DDIR is elsewhere on non-'8xx chips. */
- if (NCR53c7x0_read8 (CTEST2_REG_800) & CTEST2_800_DDIR) {
- /* Receive */
- if (synchronous)
- count += (NCR53c7x0_read8 ((hostdata->chip / 100) == 8 ?
- SSTAT1_REG : SSTAT2_REG) & SSTAT2_FF_MASK) >> SSTAT2_FF_SHIFT;
- else
- if (NCR53c7x0_read8 ((hostdata->chip / 100) == 8 ?
- SSTAT0_REG : SSTAT1_REG) & SSTAT1_ILF)
- ++count;
- } else {
- /* Send */
- sstat = ((hostdata->chip / 100) == 8) ? NCR53c7x0_read8 (SSTAT0_REG) :
- NCR53c7x0_read8 (SSTAT1_REG);
- if (sstat & SSTAT1_OLF)
- ++count;
- if (synchronous && (sstat & SSTAT1_ORF))
- ++count;
- }
- return count;
-}
-
-/*
- * Function : static const char * sbcl_to_phase (int sbcl)_
- *
- * Purpose : Convert SBCL register to user-parsable phase representation
- *
- * Inputs : sbcl - value of sbcl register
- */
-
-
-static const char *
-sbcl_to_phase (int sbcl) {
- switch (sbcl & SBCL_PHASE_MASK) {
- case SBCL_PHASE_DATAIN:
- return "DATAIN";
- case SBCL_PHASE_DATAOUT:
- return "DATAOUT";
- case SBCL_PHASE_MSGIN:
- return "MSGIN";
- case SBCL_PHASE_MSGOUT:
- return "MSGOUT";
- case SBCL_PHASE_CMDOUT:
- return "CMDOUT";
- case SBCL_PHASE_STATIN:
- return "STATUSIN";
- default:
- return "unknown";
- }
-}
-
-/*
- * Function : static const char * sstat2_to_phase (int sstat)_
- *
- * Purpose : Convert SSTAT2 register to user-parsable phase representation
- *
- * Inputs : sstat - value of sstat register
- */
-
-
-static const char *
-sstat2_to_phase (int sstat) {
- switch (sstat & SSTAT2_PHASE_MASK) {
- case SSTAT2_PHASE_DATAIN:
- return "DATAIN";
- case SSTAT2_PHASE_DATAOUT:
- return "DATAOUT";
- case SSTAT2_PHASE_MSGIN:
- return "MSGIN";
- case SSTAT2_PHASE_MSGOUT:
- return "MSGOUT";
- case SSTAT2_PHASE_CMDOUT:
- return "CMDOUT";
- case SSTAT2_PHASE_STATIN:
- return "STATUSIN";
- default:
- return "unknown";
- }
-}
-
-/*
- * Function : static void intr_phase_mismatch (struct Scsi_Host *host,
- * struct NCR53c7x0_cmd *cmd)
- *
- * Purpose : Handle phase mismatch interrupts
- *
- * Inputs : host, cmd - host and NCR command causing the interrupt, cmd
- * may be NULL.
- *
- * Side effects : The abort_connected() routine is called or the NCR chip
- * is restarted, jumping to the command_complete entry point, or
- * patching the address and transfer count of the current instruction
- * and calling the msg_in entry point as appropriate.
- */
-
-static void
-intr_phase_mismatch (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) {
- NCR53c7x0_local_declare();
- u32 dbc_dcmd, *dsp, *dsp_next;
- unsigned char dcmd, sbcl;
- struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
- host->hostdata;
- int residual;
- enum {ACTION_ABORT, ACTION_ABORT_PRINT, ACTION_CONTINUE} action =
- ACTION_ABORT_PRINT;
- const char *where = NULL;
- NCR53c7x0_local_setup(host);
-
- /*
- * Corrective action is based on where in the SCSI SCRIPT(tm) the error
- * occurred, as well as which SCSI phase we are currently in.
- */
- dsp_next = bus_to_virt(NCR53c7x0_read32(DSP_REG));
-
- /*
- * Fetch the current instruction, and remove the operands for easier
- * interpretation.
- */
- dbc_dcmd = NCR53c7x0_read32(DBC_REG);
- dcmd = (dbc_dcmd & 0xff000000) >> 24;
- /*
- * Like other processors, the NCR adjusts the instruction pointer before
- * instruction decode. Set the DSP address back to what it should
- * be for this instruction based on its size (2 or 3 32 bit words).
- */
- dsp = dsp_next - NCR53c7x0_insn_size(dcmd);
-
-
- /*
- * Read new SCSI phase from the SBCL lines. Since all of our code uses
- * a WHEN conditional instead of an IF conditional, we don't need to
- * wait for a new REQ.
- */
- sbcl = NCR53c7x0_read8(SBCL_REG) & SBCL_PHASE_MASK;
-
- if (!cmd) {
- action = ACTION_ABORT_PRINT;
- where = "no current command";
- /*
- * The way my SCSI SCRIPTS(tm) are architected, recoverable phase
- * mismatches should only occur where we're doing a multi-byte
- * BMI instruction. Specifically, this means
- *
- * - select messages (a SCSI-I target may ignore additional messages
- * after the IDENTIFY; any target may reject a SDTR or WDTR)
- *
- * - command out (targets may send a message to signal an error
- * condition, or go into STATUSIN after they've decided
- * they don't like the command.
- *
- * - reply_message (targets may reject a multi-byte message in the
- * middle)
- *
- * - data transfer routines (command completion with buffer space
- * left, disconnect message, or error message)
- */
- } else if (((dsp >= cmd->data_transfer_start &&
- dsp < cmd->data_transfer_end)) || dsp == (cmd->residual + 2)) {
- if ((dcmd & (DCMD_TYPE_MASK|DCMD_BMI_OP_MASK|DCMD_BMI_INDIRECT|
- DCMD_BMI_MSG|DCMD_BMI_CD)) == (DCMD_TYPE_BMI|
- DCMD_BMI_OP_MOVE_I)) {
- residual = datapath_residual (host);
- if (hostdata->options & OPTION_DEBUG_DISCONNECT)
- printk ("scsi%d : handling residual transfer (+ %d bytes from DMA FIFO)\n",
- host->host_no, residual);
-
- /*
- * The first instruction is a CALL to the alternate handler for
- * this data transfer phase, so we can do calls to
- * munge_msg_restart as we would if control were passed
- * from normal dynamic code.
- */
- if (dsp != cmd->residual + 2) {
- cmd->residual[0] = ((DCMD_TYPE_TCI | DCMD_TCI_OP_CALL |
- ((dcmd & DCMD_BMI_IO) ? DCMD_TCI_IO : 0)) << 24) |
- DBC_TCI_WAIT_FOR_VALID | DBC_TCI_COMPARE_PHASE;
- cmd->residual[1] = virt_to_bus(hostdata->script)
- + ((dcmd & DCMD_BMI_IO)
- ? hostdata->E_other_in : hostdata->E_other_out);
- }
-
- /*
- * The second instruction is the a data transfer block
- * move instruction, reflecting the pointer and count at the
- * time of the phase mismatch.
- */
- cmd->residual[2] = dbc_dcmd + residual;
- cmd->residual[3] = NCR53c7x0_read32(DNAD_REG) - residual;
-
- /*
- * The third and final instruction is a jump to the instruction
- * which follows the instruction which had to be 'split'
- */
- if (dsp != cmd->residual + 2) {
- cmd->residual[4] = ((DCMD_TYPE_TCI|DCMD_TCI_OP_JUMP)
- << 24) | DBC_TCI_TRUE;
- cmd->residual[5] = virt_to_bus(dsp_next);
- }
-
- /*
- * For the sake of simplicity, transfer control to the
- * conditional CALL at the start of the residual buffer.
- */
- hostdata->dsp = cmd->residual;
- hostdata->dsp_changed = 1;
- action = ACTION_CONTINUE;
- } else {
- where = "non-BMI dynamic DSA code";
- action = ACTION_ABORT_PRINT;
- }
- } else if (dsp == (hostdata->script + hostdata->E_select_msgout / 4)) {
- /* Release ATN */
- NCR53c7x0_write8 (SOCL_REG, 0);
- switch (sbcl) {
- /*
- * Some devices (SQ555 come to mind) grab the IDENTIFY message
- * sent on selection, and decide to go into COMMAND OUT phase
- * rather than accepting the rest of the messages or rejecting
- * them. Handle these devices gracefully.
- */
- case SBCL_PHASE_CMDOUT:
- hostdata->dsp = dsp + 2 /* two _words_ */;
- hostdata->dsp_changed = 1;
- printk ("scsi%d : target %d ignored SDTR and went into COMMAND OUT\n",
- host->host_no, cmd->cmd->target);
- cmd->flags &= ~CMD_FLAG_SDTR;
- action = ACTION_CONTINUE;
- break;
- case SBCL_PHASE_MSGIN:
- hostdata->dsp = hostdata->script + hostdata->E_msg_in /
- sizeof(u32);
- hostdata->dsp_changed = 1;
- action = ACTION_CONTINUE;
- break;
- default:
- where="select message out";
- action = ACTION_ABORT_PRINT;
- }
- /*
- * Some SCSI devices will interpret a command as they read the bytes
- * off the SCSI bus, and may decide that the command is Bogus before
- * they've read the entire commad off the bus.
- */
- } else if (dsp == hostdata->script + hostdata->E_cmdout_cmdout / sizeof
- (u32)) {
- hostdata->dsp = hostdata->script + hostdata->E_data_transfer /
- sizeof (u32);
- hostdata->dsp_changed = 1;
- action = ACTION_CONTINUE;
- /* FIXME : we need to handle message reject, etc. within msg_respond. */
-#ifdef notyet
- } else if (dsp == hostdata->script + hostdata->E_reply_message) {
- switch (sbcl) {
- /* Any other phase mismatches abort the currently executing command. */
-#endif
- } else {
- where = "unknown location";
- action = ACTION_ABORT_PRINT;
- }
-
- /* Flush DMA FIFO */
- if (!hostdata->dstat_valid) {
- hostdata->dstat = NCR53c7x0_read8(DSTAT_REG);
- hostdata->dstat_valid = 1;
- }
- if (!(hostdata->dstat & DSTAT_DFE)) {
- if (NCR53c7x0_read8 (CTEST2_REG_800) & CTEST2_800_DDIR) {
- printk ("scsi%d: Flushing DMA FIFO\n",
- host->host_no);
- NCR53c7x0_write8 (CTEST3_REG_800, CTEST3_800_FLF);
- /* FIXME : what about stacked DMA interrupts? */
- while (!((hostdata->dstat = NCR53c7x0_read8(DSTAT_REG)) &
- DSTAT_DFE));
- } else {
- NCR53c7x0_write8 (CTEST3_REG_800, CTEST3_800_CLF);
- while (NCR53c7x0_read8 (CTEST3_REG_800) & CTEST3_800_CLF);
- }
- hostdata->dstat |= DSTAT_DFE;
- }
-
- switch (action) {
- case ACTION_ABORT_PRINT:
- printk("scsi%d : %s : unexpected phase %s.\n",
- host->host_no, where ? where : "unknown location",
- sbcl_to_phase(sbcl));
- print_lots (host);
- /* Fall through to ACTION_ABORT */
- case ACTION_ABORT:
- abort_connected (host);
- break;
- case ACTION_CONTINUE:
- break;
- }
-
-#if 0
- if (hostdata->dsp_changed) {
- printk("scsi%d: new dsp 0x%p\n", host->host_no, hostdata->dsp);
- print_insn (host, hostdata->dsp, "", 1);
- }
-#endif
-
-}
-
-/*
- * Function : static void intr_bf (struct Scsi_Host *host,
- * struct NCR53c7x0_cmd *cmd)
- *
- * Purpose : handle BUS FAULT interrupts
- *
- * Inputs : host, cmd - host and NCR command causing the interrupt, cmd
- * may be NULL.
- */
-
-static void
-intr_bf (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) {
- NCR53c7x0_local_declare();
- struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
- host->hostdata;
- u32 *dsp,
- *next_dsp, /* Current dsp */
- *dsa,
- dbc_dcmd; /* DCMD (high eight bits) + DBC */
- unsigned short pci_status;
- int tmp;
- unsigned long flags;
- char *reason = NULL;
- /* Default behavior is for a silent error, with a retry until we've
- exhausted retries. */
- enum {MAYBE, ALWAYS, NEVER} retry = MAYBE;
- int report = 0;
- NCR53c7x0_local_setup(host);
-
- dbc_dcmd = NCR53c7x0_read32 (DBC_REG);
- next_dsp = bus_to_virt (NCR53c7x0_read32(DSP_REG));
- dsp = next_dsp - NCR53c7x0_insn_size ((dbc_dcmd >> 24) & 0xff);
-/* FIXME - check chip type */
- dsa = bus_to_virt (NCR53c7x0_read32(DSA_REG));
-
- /*
- * Bus faults can be caused by either a Bad Address or
- * Target Abort. We should check the Received Target Abort
- * bit of the PCI status register and Master Abort Bit.
- *
- * - Master Abort bit indicates that no device claimed
- * the address with DEVSEL within five clocks
- *
- * - Target Abort bit indicates that a target claimed it,
- * but changed its mind once it saw the byte enables.
- *
- */
-
- if ((hostdata->chip / 100) == 8) {
- save_flags (flags);
- cli();
- tmp = pcibios_read_config_word (hostdata->pci_bus,
- hostdata->pci_device_fn, PCI_STATUS, &pci_status);
- restore_flags (flags);
- if (tmp == PCIBIOS_SUCCESSFUL) {
- if (pci_status & PCI_STATUS_REC_TARGET_ABORT) {
- reason = "PCI target abort";
- pci_status &= ~PCI_STATUS_REC_TARGET_ABORT;
- } else if (pci_status & PCI_STATUS_REC_MASTER_ABORT) {
- reason = "No device asserted PCI DEVSEL within five bus clocks";
- pci_status &= ~PCI_STATUS_REC_MASTER_ABORT;
- } else if (pci_status & PCI_STATUS_PARITY) {
- report = 1;
- pci_status &= ~PCI_STATUS_PARITY;
- }
- } else {
- printk ("scsi%d : couldn't read status register : %s\n",
- host->host_no, pcibios_strerror (tmp));
- retry = NEVER;
- }
- }
-
-#ifndef notyet
- report = 1;
-#endif
- if (report && reason) {
- printk(KERN_ALERT "scsi%d : BUS FAULT reason = %s\n",
- host->host_no, reason ? reason : "unknown");
- print_lots (host);
- }
-
-#ifndef notyet
- retry = NEVER;
-#endif
-
- /*
- * TODO : we should attempt to recover from any spurious bus
- * faults. After X retries, we should figure that things are
- * sufficiently wedged, and call NCR53c7xx_reset.
- *
- * This code should only get executed once we've decided that we
- * cannot retry.
- */
-
- if (retry == NEVER) {
- printk(KERN_ALERT " mail drew@PoohSticks.ORG\n");
- FATAL (host);
- }
-}
-
-/*
- * Function : static void intr_dma (struct Scsi_Host *host,
- * struct NCR53c7x0_cmd *cmd)
- *
- * Purpose : handle all DMA interrupts, indicated by the setting
- * of the DIP bit in the ISTAT register.
- *
- * Inputs : host, cmd - host and NCR command causing the interrupt, cmd
- * may be NULL.
- */
-
-static void
-intr_dma (struct Scsi_Host *host, struct NCR53c7x0_cmd *cmd) {
- NCR53c7x0_local_declare();
- struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
- host->hostdata;
- unsigned char dstat; /* DSTAT */
- u32 *dsp,
- *next_dsp, /* Current dsp */
- *dsa,
- dbc_dcmd; /* DCMD (high eight bits) + DBC */
- int tmp;
- unsigned long flags;
- NCR53c7x0_local_setup(host);
-
- if (!hostdata->dstat_valid) {
- hostdata->dstat = NCR53c7x0_read8(DSTAT_REG);
- hostdata->dstat_valid = 1;
- }
-
- dstat = hostdata->dstat;
-
- if (hostdata->options & OPTION_DEBUG_INTR)
- printk("scsi%d : DSTAT=0x%x\n", host->host_no, (int) dstat);
-
- dbc_dcmd = NCR53c7x0_read32 (DBC_REG);
- next_dsp = bus_to_virt(NCR53c7x0_read32(DSP_REG));
- dsp = next_dsp - NCR53c7x0_insn_size ((dbc_dcmd >> 24) & 0xff);
-/* XXX - check chip type */
- dsa = bus_to_virt(NCR53c7x0_read32(DSA_REG));
-
- /*
- * DSTAT_ABRT is the aborted interrupt. This is set whenever the
- * SCSI chip is aborted.
- *
- * With NCR53c700 and NCR53c700-66 style chips, we should only
- * get this when the chip is currently running the accept
- * reselect/select code and we have set the abort bit in the
- * ISTAT register.
- *
- */
-
- if (dstat & DSTAT_ABRT) {
-#if 0
- /* XXX - add code here to deal with normal abort */
- if ((hostdata->options & OPTION_700) && (hostdata->state ==
- STATE_ABORTING)) {
- } else
-#endif
- {
- printk(KERN_ALERT "scsi%d : unexpected abort interrupt at\n"
- " ", host->host_no);
- print_insn (host, dsp, KERN_ALERT "s ", 1);
- FATAL (host);
- }
- }
-
- /*
- * DSTAT_SSI is the single step interrupt. Should be generated
- * whenever we have single stepped or are tracing.
- */
-
- if (dstat & DSTAT_SSI) {
- if (hostdata->options & OPTION_DEBUG_TRACE) {
- } else if (hostdata->options & OPTION_DEBUG_SINGLE) {
- print_insn (host, dsp, "s ", 0);
- save_flags(flags);
- cli();
-/* XXX - should we do this, or can we get away with writing dsp? */
-
- NCR53c7x0_write8 (DCNTL_REG, (NCR53c7x0_read8(DCNTL_REG) &
- ~DCNTL_SSM) | DCNTL_STD);
- restore_flags(flags);
- } else {
- printk(KERN_ALERT "scsi%d : unexpected single step interrupt at\n"
- " ", host->host_no);
- print_insn (host, dsp, KERN_ALERT "", 1);
- printk(KERN_ALERT " mail drew@PoohSticks.ORG\n");
- FATAL (host);
- }
- }
-
- /*
- * DSTAT_IID / DSTAT_OPC (same bit, same meaning, only the name
- * is different) is generated whenever an illegal instruction is
- * encountered.
- *
- * XXX - we may want to emulate INTFLY here, so we can use
- * the same SCSI SCRIPT (tm) for NCR53c710 through NCR53c810
- * chips.
- */
-
- if (dstat & DSTAT_OPC) {
- /*
- * Ascertain if this IID interrupts occurred before or after a STO
- * interrupt. Since the interrupt handling code now leaves
- * DSP unmodified until _after_ all stacked interrupts have been
- * processed, reading the DSP returns the original DSP register.
- * This means that if dsp lies between the select code, and
- * message out following the selection code (where the IID interrupt
- * would have to have occurred by due to the implicit wait for REQ),
- * we have an IID interrupt resulting from a STO condition and
- * can ignore it.
- */
-
- if (((dsp >= (hostdata->script + hostdata->E_select / sizeof(u32))) &&
- (dsp <= (hostdata->script + hostdata->E_select_msgout /
- sizeof(u32) + 8))) || (hostdata->test_running == 2)) {
- if (hostdata->options & OPTION_DEBUG_INTR)
- printk ("scsi%d : ignoring DSTAT_IID for SSTAT_STO\n",
- host->host_no);
- if (hostdata->expecting_iid) {
- hostdata->expecting_iid = 0;
- hostdata->idle = 1;
- if (hostdata->test_running == 2) {
- hostdata->test_running = 0;
- hostdata->test_completed = 3;
- } else if (cmd)
- abnormal_finished (cmd, DID_BAD_TARGET << 16);
- } else {
- hostdata->expecting_sto = 1;
- }
- /*
- * We can't guarantee we'll be able to execute the WAIT DISCONNECT
- * instruction within the 3.4us of bus free and arbitration delay
- * that a target can RESELECT in and assert REQ after we've dropped
- * ACK. If this happens, we'll get an illegal instruction interrupt.
- * Doing away with the WAIT DISCONNECT instructions broke everything,
- * so instead I'll settle for moving one WAIT DISCONNECT a few
- * instructions closer to the CLEAR ACK before it to minimize the
- * chances of this happening, and handle it if it occurs anyway.
- *
- * Simply continue with what we were doing, and control should
- * be transfered to the schedule routine which will ultimately
- * pass control onto the reselection or selection (not yet)
- * code.
- */
- } else if (dbc_dcmd == 0x48000000 && (NCR53c7x0_read8 (SBCL_REG) &
- SBCL_REQ)) {
- if (!(hostdata->options & OPTION_NO_PRINT_RACE))
- {
- printk("scsi%d: REQ before WAIT DISCONNECT IID\n",
- host->host_no);
- hostdata->options |= OPTION_NO_PRINT_RACE;
- }
- } else {
- printk(KERN_ALERT "scsi%d : illegal instruction\n", host->host_no);
- print_lots (host);
- printk(KERN_ALERT " mail drew@PoohSticks.ORG with ALL\n"
- " boot messages and diagnostic output\n");
- FATAL (host);
- }
- }
-
- /*
- * DSTAT_BF are bus fault errors
- */
-
- if (dstat & DSTAT_800_BF) {
- intr_bf (host, cmd);
- }
-
-
- /*
- * DSTAT_SIR interrupts are generated by the execution of
- * the INT instruction. Since the exact values available
- * are determined entirely by the SCSI script running,
- * and are local to a particular script, a unique handler
- * is called for each script.
- */
-
- if (dstat & DSTAT_SIR) {
- if (hostdata->options & OPTION_DEBUG_INTR)
- printk ("scsi%d : DSTAT_SIR\n", host->host_no);
- switch ((tmp = hostdata->dstat_sir_intr (host, cmd))) {
- case SPECIFIC_INT_NOTHING:
- case SPECIFIC_INT_RESTART:
- break;
- case SPECIFIC_INT_ABORT:
- abort_connected(host);
- break;
- case SPECIFIC_INT_PANIC:
- printk(KERN_ALERT "scsi%d : failure at ", host->host_no);
- print_insn (host, dsp, KERN_ALERT "", 1);
- printk(KERN_ALERT " dstat_sir_intr() returned SPECIFIC_INT_PANIC\n");
- FATAL (host);
- break;
- case SPECIFIC_INT_BREAK:
- intr_break (host, cmd);
- break;
- default:
- printk(KERN_ALERT "scsi%d : failure at ", host->host_no);
- print_insn (host, dsp, KERN_ALERT "", 1);
- printk(KERN_ALERT" dstat_sir_intr() returned unknown value %d\n",
- tmp);
- FATAL (host);
- }
- }
-
- if ((hostdata->chip / 100) == 8 && (dstat & DSTAT_800_MDPE)) {
- printk(KERN_ALERT "scsi%d : Master Data Parity Error\n",
- host->host_no);
- FATAL (host);
- }
-}
-
-/*
- * Function : static int print_insn (struct Scsi_Host *host,
- * u32 *insn, int kernel)
- *
- * Purpose : print numeric representation of the instruction pointed
- * to by insn to the debugging or kernel message buffer
- * as appropriate.
- *
- * If desired, a user level program can interpret this
- * information.
- *
- * Inputs : host, insn - host, pointer to instruction, prefix -
- * string to prepend, kernel - use printk instead of debugging buffer.
- *
- * Returns : size, in u32s, of instruction printed.
- */
-
-/*
- * FIXME: should change kernel parameter so that it takes an ENUM
- * specifying severity - either KERN_ALERT or KERN_PANIC so
- * all panic messages are output with the same severity.
- */
-
-static int
-print_insn (struct Scsi_Host *host, const u32 *insn,
- const char *prefix, int kernel) {
- char buf[160], /* Temporary buffer and pointer. ICKY
- arbitrary length. */
-
-
- *tmp;
- unsigned char dcmd; /* dcmd register for *insn */
- int size;
-
- /*
- * Check to see if the instruction pointer is not bogus before
- * indirecting through it; avoiding red-zone at start of
- * memory.
- *
- * FIXME: icky magic needs to happen here on non-intel boxes which
- * don't have kernel memory mapped in like this. Might be reasonable
- * to use vverify()?
- */
-
- if (MAP_NR(insn) < 1 || MAP_NR(insn + 8) > MAP_NR(high_memory) ||
- ((((dcmd = (insn[0] >> 24) & 0xff) & DCMD_TYPE_MMI) == DCMD_TYPE_MMI) &&
- MAP_NR(insn + 12) > MAP_NR(high_memory))) {
- size = 0;
- sprintf (buf, "%s%p: address out of range\n",
- prefix, insn);
- } else {
-/*
- * FIXME : (void *) cast in virt_to_bus should be unecessary, because
- * it should take const void * as argument.
- */
- sprintf(buf, "%s0x%lx (virt 0x%p) : 0x%08x 0x%08x (virt 0x%p)",
- (prefix ? prefix : ""), virt_to_bus((void *) insn), insn,
- insn[0], insn[1], bus_to_virt (insn[1]));
- tmp = buf + strlen(buf);
- if ((dcmd & DCMD_TYPE_MASK) == DCMD_TYPE_MMI) {
- sprintf (tmp, " 0x%08x (virt 0x%p)\n", insn[2],
- bus_to_virt(insn[2]));
- size = 3;
- } else {
- sprintf (tmp, "\n");
- size = 2;
- }
- }
-
- if (kernel)
- printk ("%s", buf);
-#ifdef NCR_DEBUG
- else {
- size_t len = strlen(buf);
- debugger_kernel_write(host, buf, len);
- }
-#endif
- return size;
-}
-
-/*
- * Function : static const char *ncr_state (int state)
- *
- * Purpose : convert state (probably from hostdata->state) to a string
- *
- * Inputs : state
- *
- * Returns : char * representation of state, "unknown" on error.
- */
-
-static const char *
-ncr_state (int state) {
- switch (state) {
- case STATE_HALTED: return "halted";
- case STATE_WAITING: return "waiting";
- case STATE_RUNNING: return "running";
- case STATE_ABORTING: return "aborting";
- case STATE_DISABLED: return "disabled";
- default: return "unknown";
- }
-}
-
-/*
- * Function : int NCR53c7xx_abort (Scsi_Cmnd *cmd)
- *
- * Purpose : Abort an errant SCSI command, doing all necessary
- * cleanup of the issue_queue, running_list, shared Linux/NCR
- * dsa issue and reconnect queues.
- *
- * Inputs : cmd - command to abort, code - entire result field
- *
- * Returns : 0 on success, -1 on failure.
- */
-
-int
-NCR53c7xx_abort (Scsi_Cmnd *cmd) {
- NCR53c7x0_local_declare();
- struct Scsi_Host *host = cmd->host;
- struct NCR53c7x0_hostdata *hostdata = host ? (struct NCR53c7x0_hostdata *)
- host->hostdata : NULL;
- unsigned long flags;
- struct NCR53c7x0_cmd *curr, **prev;
- Scsi_Cmnd *me, **last;
-#if 0
- static long cache_pid = -1;
-#endif
-
-
- if (!host) {
- printk ("Bogus SCSI command pid %ld; no host structure\n",
- cmd->pid);
- return SCSI_ABORT_ERROR;
- } else if (!hostdata) {
- printk ("Bogus SCSI host %d; no hostdata\n", host->host_no);
- return SCSI_ABORT_ERROR;
- }
- NCR53c7x0_local_setup(host);
-
-/*
- * CHECK : I don't think that reading ISTAT will unstack any interrupts,
- * since we need to write the INTF bit to clear it, and SCSI/DMA
- * interrupts don't clear until we read SSTAT/SIST and DSTAT registers.
- *
- * See that this is the case.
- *
- * I suspect that several of our failures may be coming from a new fatal
- * interrupt (possibly due to a phase mismatch) happening after we've left
- * the interrupt handler, but before the PIC has had the interrupt condition
- * cleared.
- */
-
- if (NCR53c7x0_read8(hostdata->istat) &
- (ISTAT_DIP|ISTAT_SIP|
- (hostdata->chip / 100 == 8 ? ISTAT_800_INTF : 0))) {
- printk ("scsi%d : dropped interrupt for command %ld\n", host->host_no,
- cmd->pid);
- NCR53c7x0_intr (host->irq, NULL);
- return SCSI_ABORT_BUSY;
- }
-
- save_flags(flags);
- cli();
-#if 0
- if (cache_pid == cmd->pid)
- panic ("scsi%d : bloody fetus %d\n", host->host_no, cmd->pid);
- else
- cache_pid = cmd->pid;
-#endif
-
-
-/*
- * The command could be hiding in the issue_queue. This would be very
- * nice, as commands can't be moved from the high level driver's issue queue
- * into the shared queue until an interrupt routine is serviced, and this
- * moving is atomic.
- *
- * If this is the case, we don't have to worry about anything - we simply
- * pull the command out of the old queue, and call it aborted.
- */
-
- for (me = (Scsi_Cmnd *) hostdata->issue_queue,
- last = (Scsi_Cmnd **) &(hostdata->issue_queue);
- me && me != cmd; last = (Scsi_Cmnd **)&(me->SCp.ptr),
- me = (Scsi_Cmnd *)me->SCp.ptr);
-
- if (me) {
- *last = (Scsi_Cmnd *) me->SCp.ptr;
- if (me->host_scribble) {
- ((struct NCR53c7x0_cmd *)me->host_scribble)->next = hostdata->free;
- hostdata->free = (struct NCR53c7x0_cmd *) me->host_scribble;
- me->host_scribble = NULL;
- }
- cmd->result = DID_ABORT << 16;
- cmd->scsi_done(cmd);
- printk ("scsi%d : found command %ld in Linux issue queue\n",
- host->host_no, me->pid);
- restore_flags(flags);
- run_process_issue_queue();
- return SCSI_ABORT_SUCCESS;
- }
-
-/*
- * That failing, the command could be in our list of already executing
- * commands. If this is the case, drastic measures are called for.
- */
-
- for (curr = (struct NCR53c7x0_cmd *) hostdata->running_list,
- prev = (struct NCR53c7x0_cmd **) &(hostdata->running_list);
- curr && curr->cmd != cmd; prev = (struct NCR53c7x0_cmd **)
- &(curr->next), curr = (struct NCR53c7x0_cmd *) curr->next);
-
- if (curr) {
- if ((cmd->result & 0xff) != 0xff && (cmd->result & 0xff00) != 0xff00) {
- if (prev)
- *prev = (struct NCR53c7x0_cmd *) curr->next;
- curr->next = (struct NCR53c7x0_cmd *) hostdata->free;
- cmd->host_scribble = NULL;
- hostdata->free = curr;
- cmd->scsi_done(cmd);
- printk ("scsi%d : found finished command %ld in running list\n",
- host->host_no, cmd->pid);
- restore_flags(flags);
- return SCSI_ABORT_NOT_RUNNING;
- } else {
- printk ("scsi%d : DANGER : command running, can not abort.\n",
- cmd->host->host_no);
- restore_flags(flags);
- return SCSI_ABORT_BUSY;
- }
- }
-
-/*
- * And if we couldn't find it in any of our queues, it must have been
- * a dropped interrupt.
- */
-
- curr = (struct NCR53c7x0_cmd *) cmd->host_scribble;
- if (curr) {
- curr->next = hostdata->free;
- hostdata->free = curr;
- cmd->host_scribble = NULL;
- }
-
- if (((cmd->result & 0xff00) == 0xff00) ||
- ((cmd->result & 0xff) == 0xff)) {
- printk ("scsi%d : did this command ever run?\n", host->host_no);
- cmd->result = DID_ABORT << 16;
- } else {
- printk ("scsi%d : probably lost INTFLY, normal completion\n",
- host->host_no);
-/*
- * FIXME : We need to add an additional flag which indicates if a
- * command was ever counted as BUSY, so if we end up here we can
- * decrement the busy count if and only if it is necessary.
- */
- --hostdata->busy[cmd->target][cmd->lun];
- }
- restore_flags(flags);
- cmd->scsi_done(cmd);
-
-/*
- * We need to run process_issue_queue since termination of this command
- * may allow another queued command to execute first?
- */
- return SCSI_ABORT_NOT_RUNNING;
-}
-
-/*
- * Function : int NCR53c7xx_reset (Scsi_Cmnd *cmd)
- *
- * Purpose : perform a hard reset of the SCSI bus and NCR
- * chip.
- *
- * Inputs : cmd - command which caused the SCSI RESET
- *
- * Returns : 0 on success.
- */
-
-int
-NCR53c7xx_reset (Scsi_Cmnd *cmd) {
- NCR53c7x0_local_declare();
- unsigned long flags;
- int found = 0;
- struct NCR53c7x0_cmd * c;
- Scsi_Cmnd *tmp;
- /*
- * When we call scsi_done(), it's going to wake up anything sleeping on the
- * resources which were in use by the aborted commands, and we'll start to
- * get new commands.
- *
- * We can't let this happen until after we've re-initialized the driver
- * structures, and can't reinitilize those structures until after we've
- * dealt with their contents.
- *
- * So, we need to find all of the commands which were running, stick
- * them on a linked list of completed commands (we'll use the host_scribble
- * pointer), do our reinitialization, and then call the done function for
- * each command.
- */
- Scsi_Cmnd *nuke_list = NULL;
- struct Scsi_Host *host = cmd->host;
- struct NCR53c7x0_hostdata *hostdata =
- (struct NCR53c7x0_hostdata *) host->hostdata;
-
- NCR53c7x0_local_setup(host);
- save_flags(flags);
- cli();
- ncr_halt (host);
- print_lots (host);
- dump_events (host, 30);
- ncr_scsi_reset (host);
- for (tmp = nuke_list = return_outstanding_commands (host, 1 /* free */,
- 0 /* issue */ ); tmp; tmp = (Scsi_Cmnd *) tmp->SCp.buffer)
- if (tmp == cmd) {
- found = 1;
- break;
- }
-
- /*
- * If we didn't find the command which caused this reset in our running
- * list, then we've lost it. See that it terminates normally anyway.
- */
- if (!found) {
- c = (struct NCR53c7x0_cmd *) cmd->host_scribble;
- if (c) {
- cmd->host_scribble = NULL;
- c->next = hostdata->free;
- hostdata->free = c;
- } else
- printk ("scsi%d: lost command %ld\n", host->host_no, cmd->pid);
- cmd->SCp.buffer = (struct scatterlist *) nuke_list;
- nuke_list = cmd;
- }
-
- NCR53c7x0_driver_init (host);
- hostdata->soft_reset (host);
- if (hostdata->resets == 0)
- disable(host);
- else if (hostdata->resets != -1)
- --hostdata->resets;
- sti();
- for (; nuke_list; nuke_list = tmp) {
- tmp = (Scsi_Cmnd *) nuke_list->SCp.buffer;
- nuke_list->result = DID_RESET << 16;
- nuke_list->scsi_done (nuke_list);
- }
- restore_flags(flags);
- return SCSI_RESET_SUCCESS;
-}
-
-/*
- * The NCR SDMS bios follows Annex A of the SCSI-CAM draft, and
- * therefore shares the scsicam_bios_param function.
- */
-
-/*
- * Function : int insn_to_offset (Scsi_Cmnd *cmd, u32 *insn)
- *
- * Purpose : convert instructions stored at NCR pointer into data
- * pointer offset.
- *
- * Inputs : cmd - SCSI command; insn - pointer to instruction. Either current
- * DSP, or saved data pointer.
- *
- * Returns : offset on success, -1 on failure.
- */
-
-
-static int
-insn_to_offset (Scsi_Cmnd *cmd, u32 *insn) {
- struct NCR53c7x0_hostdata *hostdata =
- (struct NCR53c7x0_hostdata *) cmd->host->hostdata;
- struct NCR53c7x0_cmd *ncmd =
- (struct NCR53c7x0_cmd *) cmd->host_scribble;
- int offset = 0, buffers;
- struct scatterlist *segment;
- char *ptr;
- int found = 0;
-
-/*
- * With the current code implementation, if the insn is inside dynamically
- * generated code, the data pointer will be the instruction preceeding
- * the next transfer segment.
- */
-
- if (!check_address ((unsigned long) ncmd, sizeof (struct NCR53c7x0_cmd)) &&
- ((insn >= ncmd->data_transfer_start &&
- insn < ncmd->data_transfer_end) ||
- (insn >= ncmd->residual &&
- insn < (ncmd->residual +
- sizeof(ncmd->residual))))) {
- ptr = bus_to_virt(insn[3]);
-
- if ((buffers = cmd->use_sg)) {
- for (offset = 0,
- segment = (struct scatterlist *) cmd->buffer;
- buffers && !((found = ((ptr >= segment->address) &&
- (ptr < (segment->address + segment->length)))));
- --buffers, offset += segment->length, ++segment)
-#if 0
- printk("scsi%d: comparing 0x%p to 0x%p\n",
- cmd->host->host_no, saved, segment->address);
-#else
- ;
-#endif
- offset += ptr - segment->address;
- } else {
- found = 1;
- offset = ptr - (char *) (cmd->request_buffer);
- }
- } else if ((insn >= hostdata->script +
- hostdata->E_data_transfer / sizeof(u32)) &&
- (insn <= hostdata->script +
- hostdata->E_end_data_transfer / sizeof(u32))) {
- found = 1;
- offset = 0;
- }
- return found ? offset : -1;
-}
-
-
-
-/*
- * Function : void print_progress (Scsi_Cmnd *cmd)
- *
- * Purpose : print the current location of the saved data pointer
- *
- * Inputs : cmd - command we are interested in
- *
- */
-
-static void
-print_progress (Scsi_Cmnd *cmd) {
- NCR53c7x0_local_declare();
- struct NCR53c7x0_cmd *ncmd =
- (struct NCR53c7x0_cmd *) cmd->host_scribble;
- int offset, i;
- char *where;
- u32 *ptr;
- NCR53c7x0_local_setup (cmd->host);
- for (i = 0; i < 2; ++i) {
- if (check_address ((unsigned long) ncmd,
- sizeof (struct NCR53c7x0_cmd)) == -1)
- continue;
- if (!i) {
- where = "saved";
- ptr = bus_to_virt(ncmd->saved_data_pointer);
- } else {
- where = "active";
- ptr = bus_to_virt (NCR53c7x0_read32 (DSP_REG) -
- NCR53c7x0_insn_size (NCR53c7x0_read8 (DCMD_REG)) *
- sizeof(u32));
- }
- offset = insn_to_offset (cmd, ptr);
-
- if (offset != -1)
- printk ("scsi%d : %s data pointer at offset %d\n",
- cmd->host->host_no, where, offset);
- else {
- int size;
- printk ("scsi%d : can't determine %s data pointer offset\n",
- cmd->host->host_no, where);
- if (ncmd) {
- size = print_insn (cmd->host,
- bus_to_virt(ncmd->saved_data_pointer), "", 1);
- print_insn (cmd->host,
- bus_to_virt(ncmd->saved_data_pointer) + size * sizeof(u32),
- "", 1);
- }
- }
- }
-}
-
-
-static void
-print_dsa (struct Scsi_Host *host, u32 *dsa, const char *prefix) {
- struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
- host->hostdata;
- int i, len;
- char *ptr;
- Scsi_Cmnd *cmd;
-
- if (check_address ((unsigned long) dsa, hostdata->dsa_end -
- hostdata->dsa_start) == -1) {
- printk("scsi%d : bad dsa virt 0x%p\n", host->host_no, dsa);
- return;
- }
- printk("%sscsi%d : dsa at phys 0x%lx (virt 0x%p)\n"
- " + %d : dsa_msgout length = %u, data = 0x%x (virt 0x%p)\n" ,
- prefix ? prefix : "",
- host->host_no, virt_to_bus (dsa), dsa, hostdata->dsa_msgout,
- dsa[hostdata->dsa_msgout / sizeof(u32)],
- dsa[hostdata->dsa_msgout / sizeof(u32) + 1],
- bus_to_virt (dsa[hostdata->dsa_msgout / sizeof(u32) + 1]));
-
- /*
- * Only print messages if they're sane in length so we don't
- * blow the kernel printk buffer on something which won't buy us
- * anything.
- */
-
- if (dsa[hostdata->dsa_msgout / sizeof(u32)] <
- sizeof (hostdata->free->select))
- for (i = dsa[hostdata->dsa_msgout / sizeof(u32)],
- ptr = bus_to_virt (dsa[hostdata->dsa_msgout / sizeof(u32) + 1]);
- i > 0 && !check_address ((unsigned long) ptr, 1);
- ptr += len, i -= len) {
- printk(" ");
- len = print_msg (ptr);
- printk("\n");
- if (!len)
- break;
- }
-
- printk(" + %d : select_indirect = 0x%x\n",
- hostdata->dsa_select, dsa[hostdata->dsa_select / sizeof(u32)]);
- cmd = (Scsi_Cmnd *) bus_to_virt(dsa[hostdata->dsa_cmnd / sizeof(u32)]);
- printk(" + %d : dsa_cmnd = 0x%x ", hostdata->dsa_cmnd,
- (u32) virt_to_bus(cmd));
- if (cmd) {
- printk(" result = 0x%x, target = %d, lun = %d, cmd = ",
- cmd->result, cmd->target, cmd->lun);
- print_command(cmd->cmnd);
- } else
- printk("\n");
- printk(" + %d : dsa_next = 0x%x\n", hostdata->dsa_next,
- dsa[hostdata->dsa_next / sizeof(u32)]);
- if (cmd) {
- printk("scsi%d target %d : sxfer_sanity = 0x%x, scntl3_sanity = 0x%x\n"
- " script : ",
- host->host_no, cmd->target,
- hostdata->sync[cmd->target].sxfer_sanity,
- hostdata->sync[cmd->target].scntl3_sanity);
- for (i = 0; i < (sizeof(hostdata->sync[cmd->target].script) / 4); ++i)
- printk ("0x%x ", hostdata->sync[cmd->target].script[i]);
- printk ("\n");
- print_progress (cmd);
- }
-}
-/*
- * Function : void print_queues (Scsi_Host *host)
- *
- * Purpose : print the contents of the NCR issue and reconnect queues
- *
- * Inputs : host - SCSI host we are interested in
- *
- */
-
-static void
-print_queues (struct Scsi_Host *host) {
- struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
- host->hostdata;
- u32 *dsa, *next_dsa;
- volatile u32 *current;
- int left;
- Scsi_Cmnd *cmd, *next_cmd;
- unsigned long flags;
-
- printk ("scsi%d : issue queue\n", host->host_no);
-
- for (left = host->can_queue, cmd = (Scsi_Cmnd *) hostdata->issue_queue;
- left >= 0 && cmd;
- cmd = next_cmd) {
- next_cmd = (Scsi_Cmnd *) cmd->SCp.ptr;
- save_flags(flags);
- cli();
- if (cmd->host_scribble) {
- if (check_address ((unsigned long) (cmd->host_scribble),
- sizeof (cmd->host_scribble)) == -1)
- printk ("scsi%d: scsi pid %ld bad pointer to NCR53c7x0_cmd\n",
- host->host_no, cmd->pid);
- /* print_dsa does sanity check on address, no need to check */
- else
- print_dsa (host, ((struct NCR53c7x0_cmd *) cmd->host_scribble)
- -> dsa, "");
- } else
- printk ("scsi%d : scsi pid %ld for target %d lun %d has no NCR53c7x0_cmd\n",
- host->host_no, cmd->pid, cmd->target, cmd->lun);
- restore_flags(flags);
- }
-
- if (left <= 0) {
- printk ("scsi%d : loop detected in issue queue\n",
- host->host_no);
- }
-
- /*
- * Traverse the NCR reconnect and start DSA structures, printing out
- * each element until we hit the end or detect a loop. Currently,
- * the reconnect structure is a linked list; and the start structure
- * is an array. Eventually, the reconnect structure will become a
- * list as well, since this simplifies the code.
- */
-
- printk ("scsi%d : schedule dsa array :\n", host->host_no);
- for (left = host->can_queue, current = hostdata->schedule;
- left > 0; current += 2, --left)
- if (current[0] != hostdata->NOP_insn)
-/* FIXME : convert pointer to dsa_begin to pointer to dsa. */
- print_dsa (host, bus_to_virt (current[1] -
- (hostdata->E_dsa_code_begin -
- hostdata->E_dsa_code_template)), "");
- printk ("scsi%d : end schedule dsa array\n", host->host_no);
-
- printk ("scsi%d : reconnect_dsa_head :\n", host->host_no);
-
- for (left = host->can_queue,
- dsa = bus_to_virt (hostdata->reconnect_dsa_head);
- left >= 0 && dsa;
- dsa = next_dsa) {
- save_flags (flags);
- cli();
- if (check_address ((unsigned long) dsa, sizeof(dsa)) == -1) {
- printk ("scsi%d: bad DSA pointer 0x%p", host->host_no,
- dsa);
- next_dsa = NULL;
- }
- else
- {
- next_dsa = bus_to_virt(dsa[hostdata->dsa_next / sizeof(u32)]);
- print_dsa (host, dsa, "");
- }
- restore_flags(flags);
- }
- printk ("scsi%d : end reconnect_dsa_head\n", host->host_no);
- if (left < 0)
- printk("scsi%d: possible loop in ncr reconnect list\n",
- host->host_no);
-}
-
-static void
-print_lots (struct Scsi_Host *host) {
- NCR53c7x0_local_declare();
- struct NCR53c7x0_hostdata *hostdata =
- (struct NCR53c7x0_hostdata *) host->hostdata;
- u32 *dsp_next, *dsp, *dsa, dbc_dcmd;
- unsigned char dcmd, sbcl;
- int i, size;
- NCR53c7x0_local_setup(host);
-
- if ((dsp_next = bus_to_virt(NCR53c7x0_read32 (DSP_REG)))) {
- dbc_dcmd = NCR53c7x0_read32(DBC_REG);
- dcmd = (dbc_dcmd & 0xff000000) >> 24;
- dsp = dsp_next - NCR53c7x0_insn_size(dcmd);
- dsa = bus_to_virt(NCR53c7x0_read32(DSA_REG));
- sbcl = NCR53c7x0_read8 (SBCL_REG);
-
-
- printk ("scsi%d : DCMD|DBC=0x%x, DNAD=0x%x (virt 0x%p)\n"
- " DSA=0x%lx (virt 0x%p)\n"
- " DSPS=0x%x, TEMP=0x%x (virt 0x%p), DMODE=0x%x\n"
- " SXFER=0x%x, SCNTL3=0x%x\n"
- " %s%s%sphase=%s, %d bytes in SCSI FIFO\n"
- " STEST0=0x%x\n",
- host->host_no, dbc_dcmd, NCR53c7x0_read32(DNAD_REG),
- bus_to_virt(NCR53c7x0_read32(DNAD_REG)),
- virt_to_bus(dsa), dsa,
- NCR53c7x0_read32(DSPS_REG), NCR53c7x0_read32(TEMP_REG),
- bus_to_virt (NCR53c7x0_read32(TEMP_REG)),
- (int) NCR53c7x0_read8(hostdata->dmode),
- (int) NCR53c7x0_read8(SXFER_REG),
- (int) NCR53c7x0_read8(SCNTL3_REG_800),
- (sbcl & SBCL_BSY) ? "BSY " : "",
- (sbcl & SBCL_SEL) ? "SEL " : "",
- (sbcl & SBCL_REQ) ? "REQ " : "",
- sstat2_to_phase(NCR53c7x0_read8 (((hostdata->chip / 100) == 8) ?
- SSTAT1_REG : SSTAT2_REG)),
- (NCR53c7x0_read8 ((hostdata->chip / 100) == 8 ?
- SSTAT1_REG : SSTAT2_REG) & SSTAT2_FF_MASK) >> SSTAT2_FF_SHIFT,
- NCR53c7x0_read8 (STEST0_REG_800));
- printk ("scsi%d : DSP 0x%lx (virt 0x%p) ->\n", host->host_no,
- virt_to_bus(dsp), dsp);
- for (i = 6; i > 0; --i, dsp += size)
- size = print_insn (host, dsp, "", 1);
- if (NCR53c7x0_read8 (SCNTL1_REG) & SCNTL1_CON) {
- printk ("scsi%d : connected (SDID=0x%x, SSID=0x%x)\n",
- host->host_no, NCR53c7x0_read8 (SDID_REG_800),
- NCR53c7x0_read8 (SSID_REG_800));
- print_dsa (host, dsa, "");
- }
-
-#if 1
- print_queues (host);
-#endif
- }
-}
-
-/*
- * Function : static int shutdown (struct Scsi_Host *host)
- *
- * Purpose : does a clean (we hope) shutdown of the NCR SCSI
- * chip. Use prior to dumping core, unloading the NCR driver,
- *
- * Returns : 0 on success
- */
-static int
-shutdown (struct Scsi_Host *host) {
- NCR53c7x0_local_declare();
- unsigned long flags;
- struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
- host->hostdata;
- NCR53c7x0_local_setup(host);
- save_flags (flags);
- cli();
-/* Get in a state where we can reset the SCSI bus */
- ncr_halt (host);
- ncr_scsi_reset (host);
- hostdata->soft_reset(host);
-
- disable (host);
- restore_flags (flags);
- return 0;
-}
-
-/*
- * Function : void ncr_scsi_reset (struct Scsi_Host *host)
- *
- * Purpose : reset the SCSI bus.
- */
-
-static void
-ncr_scsi_reset (struct Scsi_Host *host) {
- NCR53c7x0_local_declare();
- struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
- host->hostdata;
- unsigned long flags;
- int sien = 0;
- NCR53c7x0_local_setup(host);
- save_flags (flags);
- cli();
- if ((hostdata->chip / 100) == 8) {
- sien = NCR53c7x0_read8(SIEN0_REG_800);
- NCR53c7x0_write8(SIEN0_REG_800, sien & ~SIEN_RST);
- }
- NCR53c7x0_write8(SCNTL1_REG, SCNTL1_RST);
- udelay(25); /* Minimum amount of time to assert RST */
- NCR53c7x0_write8(SCNTL1_REG, 0);
- if ((hostdata->chip / 100) == 8) {
- NCR53c7x0_write8(SIEN0_REG_800, sien);
- }
- restore_flags (flags);
-}
-
-/*
- * Function : void hard_reset (struct Scsi_Host *host)
- *
- */
-
-static void
-hard_reset (struct Scsi_Host *host) {
- struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
- host->hostdata;
- unsigned long flags;
- save_flags (flags);
- cli();
- ncr_scsi_reset(host);
- NCR53c7x0_driver_init (host);
- if (hostdata->soft_reset)
- hostdata->soft_reset (host);
- restore_flags(flags);
-}
-
-
-/*
- * Function : Scsi_Cmnd *return_outstanding_commands (struct Scsi_Host *host,
- * int free, int issue)
- *
- * Purpose : return a linked list (using the SCp.buffer field as next,
- * so we don't perturb hostdata. We don't use a field of the
- * NCR53c7x0_cmd structure since we may not have allocated one
- * for the command causing the reset.) of Scsi_Cmnd structures that
- * had propogated bellow the Linux issue queue level. If free is set,
- * free the NCR53c7x0_cmd structures which are associated with
- * the Scsi_Cmnd structures, and clean up any internal
- * NCR lists that the commands were on. If issue is set,
- * also return commands in the issue queue.
- *
- * Returns : linked list of commands
- *
- * NOTE : the caller should insure that the NCR chip is halted
- * if the free flag is set.
- */
-
-static Scsi_Cmnd *
-return_outstanding_commands (struct Scsi_Host *host, int free, int issue) {
- struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
- host->hostdata;
- struct NCR53c7x0_cmd *c;
- int i;
- u32 *current;
- Scsi_Cmnd *list = NULL, *tmp;
- for (c = (struct NCR53c7x0_cmd *) hostdata->running_list; c;
- c = (struct NCR53c7x0_cmd *) c->next) {
- if (c->cmd->SCp.buffer) {
- printk ("scsi%d : loop detected in running list!\n", host->host_no);
- break;
- } else {
- printk ("The sti() implicit in a printk() prevents hangs\n");
- break;
- }
-
- c->cmd->SCp.buffer = (struct scatterlist *) list;
- list = c->cmd;
- if (free) {
- c->next = hostdata->free;
- hostdata->free = c;
- }
- }
-
- if (free) {
- for (i = 0, current = (u32 *) hostdata->schedule;
- i < host->can_queue; ++i, current += 2) {
- current[0] = hostdata->NOP_insn;
- current[1] = 0xdeadbeef;
- }
- hostdata->current = NULL;
- }
-
- if (issue) {
- for (tmp = (Scsi_Cmnd *) hostdata->issue_queue; tmp; tmp = tmp->next) {
- if (tmp->SCp.buffer) {
- printk ("scsi%d : loop detected in issue queue!\n",
- host->host_no);
- break;
- }
- tmp->SCp.buffer = (struct scatterlist *) list;
- list = tmp;
- }
- if (free)
- hostdata->issue_queue = NULL;
-
- }
- return list;
-}
-
-/*
- * Function : static int disable (struct Scsi_Host *host)
- *
- * Purpose : disables the given NCR host, causing all commands
- * to return a driver error. Call this so we can unload the
- * module during development and try again. Eventually,
- * we should be able to find clean workarrounds for these
- * problems.
- *
- * Inputs : host - hostadapter to twiddle
- *
- * Returns : 0 on success.
- */
-
-static int
-disable (struct Scsi_Host *host) {
- struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
- host->hostdata;
- unsigned long flags;
- Scsi_Cmnd *nuke_list, *tmp;
- save_flags(flags);
- cli();
- if (hostdata->state != STATE_HALTED)
- ncr_halt (host);
- nuke_list = return_outstanding_commands (host, 1 /* free */, 1 /* issue */);
- hard_reset (host);
- hostdata->state = STATE_DISABLED;
- restore_flags(flags);
- printk ("scsi%d : nuking commands\n", host->host_no);
- for (; nuke_list; nuke_list = tmp) {
- tmp = (Scsi_Cmnd *) nuke_list->SCp.buffer;
- nuke_list->result = DID_ERROR << 16;
- nuke_list->scsi_done(nuke_list);
- }
- printk ("scsi%d : done. \n", host->host_no);
- printk (KERN_ALERT "scsi%d : disabled. Unload and reload\n",
- host->host_no);
- return 0;
-}
-
-/*
- * Function : static int ncr_halt (struct Scsi_Host *host)
- *
- * Purpose : halts the SCSI SCRIPTS(tm) processor on the NCR chip
- *
- * Inputs : host - SCSI chip to halt
- *
- * Returns : 0 on success
- */
-
-static int
-ncr_halt (struct Scsi_Host *host) {
- NCR53c7x0_local_declare();
- unsigned long flags;
- unsigned char istat, tmp;
- struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
- host->hostdata;
- int stage;
- NCR53c7x0_local_setup(host);
-
- save_flags(flags);
- cli();
- /* Stage 0 : eat all interrupts
- Stage 1 : set ABORT
- Stage 2 : eat all but abort interrupts
- Stage 3 : eat all interrupts
- */
- for (stage = 0;;) {
- if (stage == 1) {
- NCR53c7x0_write8(hostdata->istat, ISTAT_ABRT);
- ++stage;
- }
- istat = NCR53c7x0_read8 (hostdata->istat);
- if (istat & ISTAT_SIP) {
- if ((hostdata->chip / 100) == 8) {
- tmp = NCR53c7x0_read8(SIST0_REG_800);
- udelay(1);
- tmp = NCR53c7x0_read8(SIST1_REG_800);
- } else {
- tmp = NCR53c7x0_read8(SSTAT0_REG);
- }
- } else if (istat & ISTAT_DIP) {
- tmp = NCR53c7x0_read8(DSTAT_REG);
- if (stage == 2) {
- if (tmp & DSTAT_ABRT) {
- NCR53c7x0_write8(hostdata->istat, 0);
- ++stage;
- } else {
- printk(KERN_ALERT "scsi%d : could not halt NCR chip\n",
- host->host_no);
- disable (host);
- }
- }
- }
- if (!(istat & (ISTAT_SIP|ISTAT_DIP)))
- if (stage == 0)
- ++stage;
- else if (stage == 3)
- break;
- }
- hostdata->state = STATE_HALTED;
- restore_flags(flags);
-#if 0
- print_lots (host);
-#endif
- return 0;
-}
-
-/*
- * Function: event_name (int event)
- *
- * Purpose: map event enum into user-readable strings.
- */
-
-static const char *
-event_name (int event) {
- switch (event) {
- case EVENT_NONE: return "none";
- case EVENT_ISSUE_QUEUE: return "to issue queue";
- case EVENT_START_QUEUE: return "to start queue";
- case EVENT_SELECT: return "selected";
- case EVENT_DISCONNECT: return "disconnected";
- case EVENT_RESELECT: return "reselected";
- case EVENT_COMPLETE: return "completed";
- case EVENT_IDLE: return "idle";
- case EVENT_SELECT_FAILED: return "select failed";
- case EVENT_BEFORE_SELECT: return "before select";
- case EVENT_RESELECT_FAILED: return "reselect failed";
- default: return "unknown";
- }
-}
-
-/*
- * Function : void dump_events (struct Scsi_Host *host, count)
- *
- * Purpose : print last count events which have occurred.
- */
-static void
-dump_events (struct Scsi_Host *host, int count) {
- struct NCR53c7x0_hostdata *hostdata = (struct NCR53c7x0_hostdata *)
- host->hostdata;
- struct NCR53c7x0_event event;
- int i;
- unsigned long flags;
- if (hostdata->events) {
- if (count > hostdata->event_size)
- count = hostdata->event_size;
- for (i = hostdata->event_index; count > 0;
- i = (i ? i - 1 : hostdata->event_size -1), --count) {
- save_flags(flags);
-/*
- * By copying the event we're currently examinging with interrupts
- * disabled, we can do multiple printk(), etc. operations and
- * still be guaranteed that they're happening on the same
- * event structure.
- */
- cli();
-#if 0
- event = hostdata->events[i];
-#else
- memcpy ((void *) &event, (void *) &(hostdata->events[i]),
- sizeof(event));
-#endif
-
- restore_flags(flags);
- printk ("scsi%d : %s event %d at %ld secs %ld usecs target %d lun %d\n",
- host->host_no, event_name (event.event), count,
- (long) event.time.tv_sec, (long) event.time.tv_usec,
- event.target, event.lun);
- if (event.dsa)
- printk (" event for dsa 0x%lx (virt 0x%p)\n",
- virt_to_bus(event.dsa), event.dsa);
- if (event.pid != -1) {
- printk (" event for pid %ld ", event.pid);
- print_command (event.cmnd);
- }
- }
- }
-}
-
-/*
- * Function: check_address
- *
- * Purpose: Check to see if a possibly corrupt pointer will fault the
- * kernel.
- *
- * Inputs: addr - address; size - size of area
- *
- * Returns: 0 if area is OK, -1 on error.
- *
- * NOTES: should be implemented in terms of vverify on kernels
- * that have it.
- */
-
-static int
-check_address (unsigned long addr, int size) {
- return (MAP_NR(addr) < 1 || MAP_NR(addr + size) > MAP_NR(high_memory) ?
- -1 : 0);
-}
-
-#ifdef MODULE
-int
-NCR53c7x0_release(struct Scsi_Host *host) {
- struct NCR53c7x0_hostdata *hostdata =
- (struct NCR53c7x0_hostdata *) host->hostdata;
- struct NCR53c7x0_cmd *cmd, *tmp;
- shutdown (host);
- if (host->irq != IRQ_NONE)
- {
- int irq_count;
- struct Scsi_Host *tmp;
- for (irq_count = 0, tmp = first_host; tmp; tmp = tmp->next)
- if (tmp->hostt == the_template && tmp->irq == host->irq)
- ++irq_count;
- if (irq_count == 1)
- free_irq(host->irq);
- }
- if (host->dma_channel != DMA_NONE)
- free_dma(host->dma_channel);
- if (host->io_port)
- release_region(host->io_port, host->n_io_port);
-
- for (cmd = (struct NCR53c7x0_cmd *) hostdata->free; cmd; cmd = tmp,
- --hostdata->num_cmds) {
- tmp = (struct NCR53c7x0_cmd *) cmd->next;
- /*
- * If we're going to loop, try to stop it to get a more accurate
- * count of the leaked commands.
- */
- cmd->next = NULL;
- if (cmd->free)
- cmd->free ((void *) cmd->real, cmd->size);
- }
- if (hostdata->num_cmds)
- printk ("scsi%d : leaked %d NCR53c7x0_cmd structures\n",
- host->host_no, hostdata->num_cmds);
- if (hostdata->events)
- vfree ((void *)hostdata->events);
- return 1;
-}
-Scsi_Host_Template driver_template = NCR53c7xx;
-#include "scsi_module.c"
-#endif /* def MODULE */
diff --git a/i386/i386at/gpl/linux/scsi/53c8xx_d.h b/i386/i386at/gpl/linux/scsi/53c8xx_d.h
deleted file mode 100644
index dd45baee..00000000
--- a/i386/i386at/gpl/linux/scsi/53c8xx_d.h
+++ /dev/null
@@ -1,2677 +0,0 @@
-u32 SCRIPT[] = {
-/*
-
-
-; NCR 53c810 driver, main script
-; Sponsored by
-; iX Multiuser Multitasking Magazine
-; hm@ix.de
-;
-; Copyright 1993, 1994, 1995 Drew Eckhardt
-; Visionary Computing
-; (Unix and Linux consulting and custom programming)
-; drew@PoohSticks.ORG
-; +1 (303) 786-7975
-;
-; TolerANT and SCSI SCRIPTS are registered trademarks of NCR Corporation.
-;
-; PRE-ALPHA
-;
-; For more information, please consult
-;
-; NCR 53C810
-; PCI-SCSI I/O Processor
-; Data Manual
-;
-; NCR 53C710
-; SCSI I/O Processor
-; Programmers Guide
-;
-; NCR Microelectronics
-; 1635 Aeroplaza Drive
-; Colorado Springs, CO 80916
-; 1+ (719) 578-3400
-;
-; Toll free literature number
-; +1 (800) 334-5454
-;
-; IMPORTANT : This code is self modifying due to the limitations of
-; the NCR53c7,8xx series chips. Persons debugging this code with
-; the remote debugger should take this into account, and NOT set
-; breakpoints in modified instructions.
-;
-; Design:
-; The NCR53c7,8xx family of SCSI chips are busmasters with an onboard
-; microcontroller using a simple instruction set.
-;
-; So, to minimize the effects of interrupt latency, and to maximize
-; throughput, this driver offloads the practical maximum amount
-; of processing to the SCSI chip while still maintaining a common
-; structure.
-;
-; Where tradeoffs were needed between efficiency on the older
-; chips and the newer NCR53c800 series, the NCR53c800 series
-; was chosen.
-;
-; While the NCR53c700 and NCR53c700-66 lacked the facilities to fully
-; automate SCSI transfers without host processor intervention, this
-; isn't the case with the NCR53c710 and newer chips which allow
-;
-; - reads and writes to the internal registers from within the SCSI
-; scripts, allowing the SCSI SCRIPTS(tm) code to save processor
-; state so that multiple threads of execution are possible, and also
-; provide an ALU for loop control, etc.
-;
-; - table indirect addressing for some instructions. This allows
-; pointers to be located relative to the DSA ((Data Structure
-; Address) register.
-;
-; These features make it possible to implement a mailbox style interface,
-; where the same piece of code is run to handle I/O for multiple threads
-; at once minimizing our need to relocate code. Since the NCR53c700/
-; NCR53c800 series have a unique combination of features, making a
-; a standard ingoing/outgoing mailbox system, costly, I've modified it.
-;
-; - Mailboxes are a mixture of code and data. This lets us greatly
-; simplify the NCR53c810 code and do things that would otherwise
-; not be possible.
-;
-; The saved data pointer is now implemented as follows :
-;
-; Control flow has been architected such that if control reaches
-; munge_save_data_pointer, on a restore pointers message or
-; reconnection, a jump to the address formerly in the TEMP register
-; will allow the SCSI command to resume execution.
-;
-
-;
-; Note : the DSA structures must be aligned on 32 bit boundaries,
-; since the source and destination of MOVE MEMORY instructions
-; must share the same alignment and this is the alignment of the
-; NCR registers.
-;
-
-ABSOLUTE dsa_temp_lun = 0 ; Patch to lun for current dsa
-ABSOLUTE dsa_temp_next = 0 ; Patch to dsa next for current dsa
-ABSOLUTE dsa_temp_addr_next = 0 ; Patch to address of dsa next address
- ; for current dsa
-ABSOLUTE dsa_temp_sync = 0 ; Patch to address of per-target
- ; sync routine
-ABSOLUTE dsa_temp_target = 0 ; Patch to id for current dsa
-ABSOLUTE dsa_temp_addr_saved_pointer = 0; Patch to address of per-command
- ; saved data pointer
-ABSOLUTE dsa_temp_addr_residual = 0 ; Patch to address of per-command
- ; current residual code
-ABSOLUTE dsa_temp_addr_saved_residual = 0; Patch to address of per-command
- ; saved residual code
-ABSOLUTE dsa_temp_addr_new_value = 0 ; Address of value for JUMP operand
-ABSOLUTE dsa_temp_addr_array_value = 0 ; Address to copy to
-ABSOLUTE dsa_temp_addr_dsa_value = 0 ; Address of this DSA value
-
-;
-; Once a device has initiated reselection, we need to compare it
-; against the singly linked list of commands which have disconnected
-; and are pending reselection. These commands are maintained in
-; an unordered singly linked list of DSA structures, through the
-; DSA pointers at their 'centers' headed by the reconnect_dsa_head
-; pointer.
-;
-; To avoid complications in removing commands from the list,
-; I minimize the amount of expensive (at eight operations per
-; addition @ 500-600ns each) pointer operations which must
-; be done in the NCR driver by precomputing them on the
-; host processor during dsa structure generation.
-;
-; The fixed-up per DSA code knows how to recognize the nexus
-; associated with the corresponding SCSI command, and modifies
-; the source and destination pointers for the MOVE MEMORY
-; instruction which is executed when reselected_ok is called
-; to remove the command from the list. Similarly, DSA is
-; loaded with the address of the next DSA structure and
-; reselected_check_next is called if a failure occurs.
-;
-; Perhaps more conscisely, the net effect of the mess is
-;
-; for (dsa = reconnect_dsa_head, dest = &reconnect_dsa_head,
-; src = NULL; dsa; dest = &dsa->next, dsa = dsa->next) {
-; src = &dsa->next;
-; if (target_id == dsa->id && target_lun == dsa->lun) {
-; *dest = *src;
-; break;
-; }
-; }
-;
-; if (!dsa)
-; error (int_err_unexpected_reselect);
-; else
-; longjmp (dsa->jump_resume, 0);
-;
-;
-
-
-; Define DSA structure used for mailboxes
-ENTRY dsa_code_template
-dsa_code_template:
-ENTRY dsa_code_begin
-dsa_code_begin:
- MOVE dmode_memory_to_ncr TO DMODE
-
-at 0x00000000 : */ 0x78380000,0x00000000,
-/*
- MOVE MEMORY 4, dsa_temp_addr_dsa_value, addr_scratch
-
-at 0x00000002 : */ 0xc0000004,0x00000000,0x00000000,
-/*
- MOVE dmode_memory_to_memory TO DMODE
-
-at 0x00000005 : */ 0x78380000,0x00000000,
-/*
- CALL scratch_to_dsa
-
-at 0x00000007 : */ 0x88080000,0x00000980,
-/*
- CALL select
-
-at 0x00000009 : */ 0x88080000,0x000001fc,
-/*
-; Handle the phase mismatch which may have resulted from the
-; MOVE FROM dsa_msgout if we returned here. The CLEAR ATN
-; may or may not be necessary, and we should update script_asm.pl
-; to handle multiple pieces.
- CLEAR ATN
-
-at 0x0000000b : */ 0x60000008,0x00000000,
-/*
- CLEAR ACK
-
-at 0x0000000d : */ 0x60000040,0x00000000,
-/*
-
-; Replace second operand with address of JUMP instruction dest operand
-; in schedule table for this DSA. Becomes dsa_jump_dest in 53c7,8xx.c.
-ENTRY dsa_code_fix_jump
-dsa_code_fix_jump:
- MOVE MEMORY 4, NOP_insn, 0
-
-at 0x0000000f : */ 0xc0000004,0x00000000,0x00000000,
-/*
- JUMP select_done
-
-at 0x00000012 : */ 0x80080000,0x00000224,
-/*
-
-; wrong_dsa loads the DSA register with the value of the dsa_next
-; field.
-;
-wrong_dsa:
-; Patch the MOVE MEMORY INSTRUCTION such that
-; the destination address is the address of the OLD
-; next pointer.
-;
- MOVE MEMORY 4, dsa_temp_addr_next, reselected_ok + 8
-
-at 0x00000014 : */ 0xc0000004,0x00000000,0x00000758,
-/*
- MOVE dmode_memory_to_ncr TO DMODE
-
-at 0x00000017 : */ 0x78380000,0x00000000,
-/*
-;
-; Move the _contents_ of the next pointer into the DSA register as
-; the next I_T_L or I_T_L_Q tupple to check against the established
-; nexus.
-;
- MOVE MEMORY 4, dsa_temp_next, addr_scratch
-
-at 0x00000019 : */ 0xc0000004,0x00000000,0x00000000,
-/*
- MOVE dmode_memory_to_memory TO DMODE
-
-at 0x0000001c : */ 0x78380000,0x00000000,
-/*
- CALL scratch_to_dsa
-
-at 0x0000001e : */ 0x88080000,0x00000980,
-/*
- JUMP reselected_check_next
-
-at 0x00000020 : */ 0x80080000,0x000006a4,
-/*
-
-ABSOLUTE dsa_save_data_pointer = 0
-ENTRY dsa_code_save_data_pointer
-dsa_code_save_data_pointer:
- MOVE dmode_ncr_to_memory TO DMODE
-
-at 0x00000022 : */ 0x78380000,0x00000000,
-/*
- MOVE MEMORY 4, addr_temp, dsa_temp_addr_saved_pointer
-
-at 0x00000024 : */ 0xc0000004,0x00000000,0x00000000,
-/*
- MOVE dmode_memory_to_memory TO DMODE
-
-at 0x00000027 : */ 0x78380000,0x00000000,
-/*
-; HARD CODED : 24 bytes needs to agree with 53c7,8xx.h
- MOVE MEMORY 24, dsa_temp_addr_residual, dsa_temp_addr_saved_residual
-
-at 0x00000029 : */ 0xc0000018,0x00000000,0x00000000,
-/*
- CLEAR ACK
-
-at 0x0000002c : */ 0x60000040,0x00000000,
-/*
-
-
-
- RETURN
-
-at 0x0000002e : */ 0x90080000,0x00000000,
-/*
-ABSOLUTE dsa_restore_pointers = 0
-ENTRY dsa_code_restore_pointers
-dsa_code_restore_pointers:
- MOVE dmode_memory_to_ncr TO DMODE
-
-at 0x00000030 : */ 0x78380000,0x00000000,
-/*
- MOVE MEMORY 4, dsa_temp_addr_saved_pointer, addr_temp
-
-at 0x00000032 : */ 0xc0000004,0x00000000,0x00000000,
-/*
- MOVE dmode_memory_to_memory TO DMODE
-
-at 0x00000035 : */ 0x78380000,0x00000000,
-/*
-; HARD CODED : 24 bytes needs to agree with 53c7,8xx.h
- MOVE MEMORY 24, dsa_temp_addr_saved_residual, dsa_temp_addr_residual
-
-at 0x00000037 : */ 0xc0000018,0x00000000,0x00000000,
-/*
- CLEAR ACK
-
-at 0x0000003a : */ 0x60000040,0x00000000,
-/*
-
-
-
- RETURN
-
-at 0x0000003c : */ 0x90080000,0x00000000,
-/*
-
-ABSOLUTE dsa_check_reselect = 0
-; dsa_check_reselect determines whether or not the current target and
-; lun match the current DSA
-ENTRY dsa_code_check_reselect
-dsa_code_check_reselect:
- MOVE SSID TO SFBR ; SSID contains 3 bit target ID
-
-at 0x0000003e : */ 0x720a0000,0x00000000,
-/*
-; FIXME : we need to accomodate bit fielded and binary here for '7xx/'8xx chips
- JUMP REL (wrong_dsa), IF NOT dsa_temp_target, AND MASK 0xf8
-
-at 0x00000040 : */ 0x8084f800,0x00ffff48,
-/*
-;
-; Hack - move to scratch first, since SFBR is not writeable
-; via the CPU and hence a MOVE MEMORY instruction.
-;
- MOVE dmode_memory_to_ncr TO DMODE
-
-at 0x00000042 : */ 0x78380000,0x00000000,
-/*
- MOVE MEMORY 1, reselected_identify, addr_scratch
-
-at 0x00000044 : */ 0xc0000001,0x00000000,0x00000000,
-/*
- MOVE dmode_memory_to_memory TO DMODE
-
-at 0x00000047 : */ 0x78380000,0x00000000,
-/*
- MOVE SCRATCH0 TO SFBR
-
-at 0x00000049 : */ 0x72340000,0x00000000,
-/*
-; FIXME : we need to accomodate bit fielded and binary here for '7xx/'8xx chips
- JUMP REL (wrong_dsa), IF NOT dsa_temp_lun, AND MASK 0xf8
-
-at 0x0000004b : */ 0x8084f800,0x00ffff1c,
-/*
-; Patch the MOVE MEMORY INSTRUCTION such that
-; the source address is the address of this dsa's
-; next pointer.
- MOVE MEMORY 4, dsa_temp_addr_next, reselected_ok + 4
-
-at 0x0000004d : */ 0xc0000004,0x00000000,0x00000754,
-/*
- CALL reselected_ok
-
-at 0x00000050 : */ 0x88080000,0x00000750,
-/*
- CALL dsa_temp_sync
-
-at 0x00000052 : */ 0x88080000,0x00000000,
-/*
-; Release ACK on the IDENTIFY message _after_ we've set the synchronous
-; transfer parameters!
- CLEAR ACK
-
-at 0x00000054 : */ 0x60000040,0x00000000,
-/*
-; Implicitly restore pointers on reselection, so a RETURN
-; will transfer control back to the right spot.
- CALL REL (dsa_code_restore_pointers)
-
-at 0x00000056 : */ 0x88880000,0x00ffff60,
-/*
- RETURN
-
-at 0x00000058 : */ 0x90080000,0x00000000,
-/*
-ENTRY dsa_zero
-dsa_zero:
-ENTRY dsa_code_template_end
-dsa_code_template_end:
-
-; Perform sanity check for dsa_fields_start == dsa_code_template_end -
-; dsa_zero, puke.
-
-ABSOLUTE dsa_fields_start = 0 ; Sanity marker
- ; pad 48 bytes (fix this RSN)
-ABSOLUTE dsa_next = 48 ; len 4 Next DSA
- ; del 4 Previous DSA address
-ABSOLUTE dsa_cmnd = 56 ; len 4 Scsi_Cmnd * for this thread.
-ABSOLUTE dsa_select = 60 ; len 4 Device ID, Period, Offset for
- ; table indirect select
-ABSOLUTE dsa_msgout = 64 ; len 8 table indirect move parameter for
- ; select message
-ABSOLUTE dsa_cmdout = 72 ; len 8 table indirect move parameter for
- ; command
-ABSOLUTE dsa_dataout = 80 ; len 4 code pointer for dataout
-ABSOLUTE dsa_datain = 84 ; len 4 code pointer for datain
-ABSOLUTE dsa_msgin = 88 ; len 8 table indirect move for msgin
-ABSOLUTE dsa_status = 96 ; len 8 table indirect move for status byte
-ABSOLUTE dsa_msgout_other = 104 ; len 8 table indirect for normal message out
- ; (Synchronous transfer negotiation, etc).
-ABSOLUTE dsa_end = 112
-
-ABSOLUTE schedule = 0 ; Array of JUMP dsa_begin or JUMP (next),
- ; terminated by a call to JUMP wait_reselect
-
-; Linked lists of DSA structures
-ABSOLUTE reconnect_dsa_head = 0 ; Link list of DSAs which can reconnect
-ABSOLUTE addr_reconnect_dsa_head = 0 ; Address of variable contataining
- ; address of reconnect_dsa_head
-
-; These select the source and destination of a MOVE MEMORY instruction
-ABSOLUTE dmode_memory_to_memory = 0x0
-ABSOLUTE dmode_memory_to_ncr = 0x0
-ABSOLUTE dmode_ncr_to_memory = 0x0
-
-ABSOLUTE addr_scratch = 0x0
-ABSOLUTE addr_temp = 0x0
-
-
-; Interrupts -
-; MSB indicates type
-; 0 handle error condition
-; 1 handle message
-; 2 handle normal condition
-; 3 debugging interrupt
-; 4 testing interrupt
-; Next byte indicates specific error
-
-; XXX not yet implemented, I'm not sure if I want to -
-; Next byte indicates the routine the error occurred in
-; The LSB indicates the specific place the error occurred
-
-ABSOLUTE int_err_unexpected_phase = 0x00000000 ; Unexpected phase encountered
-ABSOLUTE int_err_selected = 0x00010000 ; SELECTED (nee RESELECTED)
-ABSOLUTE int_err_unexpected_reselect = 0x00020000
-ABSOLUTE int_err_check_condition = 0x00030000
-ABSOLUTE int_err_no_phase = 0x00040000
-ABSOLUTE int_msg_wdtr = 0x01000000 ; WDTR message received
-ABSOLUTE int_msg_sdtr = 0x01010000 ; SDTR received
-ABSOLUTE int_msg_1 = 0x01020000 ; single byte special message
- ; received
-
-ABSOLUTE int_norm_select_complete = 0x02000000 ; Select complete, reprogram
- ; registers.
-ABSOLUTE int_norm_reselect_complete = 0x02010000 ; Nexus established
-ABSOLUTE int_norm_command_complete = 0x02020000 ; Command complete
-ABSOLUTE int_norm_disconnected = 0x02030000 ; Disconnected
-ABSOLUTE int_norm_aborted =0x02040000 ; Aborted *dsa
-ABSOLUTE int_norm_reset = 0x02050000 ; Generated BUS reset.
-ABSOLUTE int_debug_break = 0x03000000 ; Break point
-
-ABSOLUTE int_debug_panic = 0x030b0000 ; Panic driver
-
-
-ABSOLUTE int_test_1 = 0x04000000 ; Test 1 complete
-ABSOLUTE int_test_2 = 0x04010000 ; Test 2 complete
-ABSOLUTE int_test_3 = 0x04020000 ; Test 3 complete
-
-
-; These should start with 0x05000000, with low bits incrementing for
-; each one.
-
-
-
-ABSOLUTE NCR53c7xx_msg_abort = 0 ; Pointer to abort message
-ABSOLUTE NCR53c7xx_msg_reject = 0 ; Pointer to reject message
-ABSOLUTE NCR53c7xx_zero = 0 ; long with zero in it, use for source
-ABSOLUTE NCR53c7xx_sink = 0 ; long to dump worthless data in
-ABSOLUTE NOP_insn = 0 ; NOP instruction
-
-; Pointer to message, potentially multi-byte
-ABSOLUTE msg_buf = 0
-
-; Pointer to holding area for reselection information
-ABSOLUTE reselected_identify = 0
-ABSOLUTE reselected_tag = 0
-
-; Request sense command pointer, it's a 6 byte command, should
-; be constant for all commands since we always want 16 bytes of
-; sense and we don't need to change any fields as we did under
-; SCSI-I when we actually cared about the LUN field.
-;EXTERNAL NCR53c7xx_sense ; Request sense command
-
-
-; dsa_schedule
-; PURPOSE : after a DISCONNECT message has been received, and pointers
-; saved, insert the current DSA structure at the head of the
-; disconnected queue and fall through to the scheduler.
-;
-; CALLS : OK
-;
-; INPUTS : dsa - current DSA structure, reconnect_dsa_head - list
-; of disconnected commands
-;
-; MODIFIES : SCRATCH, reconnect_dsa_head
-;
-; EXITS : always passes control to schedule
-
-ENTRY dsa_schedule
-dsa_schedule:
-
-
-
-
-;
-; Calculate the address of the next pointer within the DSA
-; structure of the command that is currently disconnecting
-;
- CALL dsa_to_scratch
-
-at 0x0000005a : */ 0x88080000,0x00000938,
-/*
- MOVE SCRATCH0 + dsa_next TO SCRATCH0
-
-at 0x0000005c : */ 0x7e343000,0x00000000,
-/*
- MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY
-
-at 0x0000005e : */ 0x7f350000,0x00000000,
-/*
- MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY
-
-at 0x00000060 : */ 0x7f360000,0x00000000,
-/*
- MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY
-
-at 0x00000062 : */ 0x7f370000,0x00000000,
-/*
-
-; Point the next field of this DSA structure at the current disconnected
-; list
- MOVE dmode_ncr_to_memory TO DMODE
-
-at 0x00000064 : */ 0x78380000,0x00000000,
-/*
- MOVE MEMORY 4, addr_scratch, dsa_schedule_insert + 8
-
-at 0x00000066 : */ 0xc0000004,0x00000000,0x000001b4,
-/*
- MOVE dmode_memory_to_memory TO DMODE
-
-at 0x00000069 : */ 0x78380000,0x00000000,
-/*
-dsa_schedule_insert:
- MOVE MEMORY 4, reconnect_dsa_head, 0
-
-at 0x0000006b : */ 0xc0000004,0x00000000,0x00000000,
-/*
-
-; And update the head pointer.
- CALL dsa_to_scratch
-
-at 0x0000006e : */ 0x88080000,0x00000938,
-/*
- MOVE dmode_ncr_to_memory TO DMODE
-
-at 0x00000070 : */ 0x78380000,0x00000000,
-/*
- MOVE MEMORY 4, addr_scratch, reconnect_dsa_head
-
-at 0x00000072 : */ 0xc0000004,0x00000000,0x00000000,
-/*
- MOVE dmode_memory_to_memory TO DMODE
-
-at 0x00000075 : */ 0x78380000,0x00000000,
-/*
-
-
- MOVE SCNTL2 & 0x7f TO SCNTL2
-
-at 0x00000077 : */ 0x7c027f00,0x00000000,
-/*
- CLEAR ACK
-
-at 0x00000079 : */ 0x60000040,0x00000000,
-/*
-
- WAIT DISCONNECT
-
-at 0x0000007b : */ 0x48000000,0x00000000,
-/*
-
-
-
-
-
-
- JUMP schedule
-
-at 0x0000007d : */ 0x80080000,0x00000000,
-/*
-
-
-;
-; select
-;
-; PURPOSE : establish a nexus for the SCSI command referenced by DSA.
-; On success, the current DSA structure is removed from the issue
-; queue. Usually, this is entered as a fall-through from schedule,
-; although the contingent allegiance handling code will write
-; the select entry address to the DSP to restart a command as a
-; REQUEST SENSE. A message is sent (usually IDENTIFY, although
-; additional SDTR or WDTR messages may be sent). COMMAND OUT
-; is handled.
-;
-; INPUTS : DSA - SCSI command, issue_dsa_head
-;
-; CALLS : NOT OK
-;
-; MODIFIES : SCRATCH, issue_dsa_head
-;
-; EXITS : on reselection or selection, go to select_failed
-; otherwise, RETURN so control is passed back to
-; dsa_begin.
-;
-
-ENTRY select
-select:
-
-
-
-
-
-
-
-
-
-
-
-
- CLEAR TARGET
-
-at 0x0000007f : */ 0x60000200,0x00000000,
-/*
-
-; XXX
-;
-; In effect, SELECTION operations are backgrounded, with execution
-; continuing until code which waits for REQ or a fatal interrupt is
-; encountered.
-;
-; So, for more performance, we could overlap the code which removes
-; the command from the NCRs issue queue with the selection, but
-; at this point I don't want to deal with the error recovery.
-;
-
-
- SELECT ATN FROM dsa_select, select_failed
-
-at 0x00000081 : */ 0x4300003c,0x000007a4,
-/*
- JUMP select_msgout, WHEN MSG_OUT
-
-at 0x00000083 : */ 0x860b0000,0x00000214,
-/*
-ENTRY select_msgout
-select_msgout:
- MOVE FROM dsa_msgout, WHEN MSG_OUT
-
-at 0x00000085 : */ 0x1e000000,0x00000040,
-/*
-
-
-
-
-
-
-
-
-
-
- RETURN
-
-at 0x00000087 : */ 0x90080000,0x00000000,
-/*
-
-;
-; select_done
-;
-; PURPOSE: continue on to normal data transfer; called as the exit
-; point from dsa_begin.
-;
-; INPUTS: dsa
-;
-; CALLS: OK
-;
-;
-
-select_done:
-
-
-
-
-
-
-
-; After a successful selection, we should get either a CMD phase or
-; some transfer request negotiation message.
-
- JUMP cmdout, WHEN CMD
-
-at 0x00000089 : */ 0x820b0000,0x00000244,
-/*
- INT int_err_unexpected_phase, WHEN NOT MSG_IN
-
-at 0x0000008b : */ 0x9f030000,0x00000000,
-/*
-
-select_msg_in:
- CALL msg_in, WHEN MSG_IN
-
-at 0x0000008d : */ 0x8f0b0000,0x00000404,
-/*
- JUMP select_msg_in, WHEN MSG_IN
-
-at 0x0000008f : */ 0x870b0000,0x00000234,
-/*
-
-cmdout:
- INT int_err_unexpected_phase, WHEN NOT CMD
-
-at 0x00000091 : */ 0x9a030000,0x00000000,
-/*
-
-
-
-ENTRY cmdout_cmdout
-cmdout_cmdout:
-
- MOVE FROM dsa_cmdout, WHEN CMD
-
-at 0x00000093 : */ 0x1a000000,0x00000048,
-/*
-
-
-
-
-;
-; data_transfer
-; other_out
-; other_in
-; other_transfer
-;
-; PURPOSE : handle the main data transfer for a SCSI command in
-; several parts. In the first part, data_transfer, DATA_IN
-; and DATA_OUT phases are allowed, with the user provided
-; code (usually dynamically generated based on the scatter/gather
-; list associated with a SCSI command) called to handle these
-; phases.
-;
-; After control has passed to one of the user provided
-; DATA_IN or DATA_OUT routines, back calls are made to
-; other_tranfer_in or other_transfer_out to handle non-DATA IN
-; and DATA OUT phases respectively, with the state of the active
-; data pointer being preserved in TEMP.
-;
-; On completion, the user code passes control to other_transfer
-; which causes DATA_IN and DATA_OUT to result in unexpected_phase
-; interrupts so that data overruns may be trapped.
-;
-; INPUTS : DSA - SCSI command
-;
-; CALLS : OK in data_transfer_start, not ok in other_out and other_in, ok in
-; other_transfer
-;
-; MODIFIES : SCRATCH
-;
-; EXITS : if STATUS IN is detected, signifying command completion,
-; the NCR jumps to command_complete. If MSG IN occurs, a
-; CALL is made to msg_in. Otherwise, other_transfer runs in
-; an infinite loop.
-;
-
-ENTRY data_transfer
-data_transfer:
- JUMP cmdout_cmdout, WHEN CMD
-
-at 0x00000095 : */ 0x820b0000,0x0000024c,
-/*
- CALL msg_in, WHEN MSG_IN
-
-at 0x00000097 : */ 0x8f0b0000,0x00000404,
-/*
- INT int_err_unexpected_phase, WHEN MSG_OUT
-
-at 0x00000099 : */ 0x9e0b0000,0x00000000,
-/*
- JUMP do_dataout, WHEN DATA_OUT
-
-at 0x0000009b : */ 0x800b0000,0x0000028c,
-/*
- JUMP do_datain, WHEN DATA_IN
-
-at 0x0000009d : */ 0x810b0000,0x000002e4,
-/*
- JUMP command_complete, WHEN STATUS
-
-at 0x0000009f : */ 0x830b0000,0x0000060c,
-/*
- JUMP data_transfer
-
-at 0x000000a1 : */ 0x80080000,0x00000254,
-/*
-ENTRY end_data_transfer
-end_data_transfer:
-
-;
-; FIXME: On NCR53c700 and NCR53c700-66 chips, do_dataout/do_datain
-; should be fixed up whenever the nexus changes so it can point to the
-; correct routine for that command.
-;
-
-
-; Nasty jump to dsa->dataout
-do_dataout:
- CALL dsa_to_scratch
-
-at 0x000000a3 : */ 0x88080000,0x00000938,
-/*
- MOVE SCRATCH0 + dsa_dataout TO SCRATCH0
-
-at 0x000000a5 : */ 0x7e345000,0x00000000,
-/*
- MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY
-
-at 0x000000a7 : */ 0x7f350000,0x00000000,
-/*
- MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY
-
-at 0x000000a9 : */ 0x7f360000,0x00000000,
-/*
- MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY
-
-at 0x000000ab : */ 0x7f370000,0x00000000,
-/*
- MOVE dmode_ncr_to_memory TO DMODE
-
-at 0x000000ad : */ 0x78380000,0x00000000,
-/*
- MOVE MEMORY 4, addr_scratch, dataout_to_jump + 4
-
-at 0x000000af : */ 0xc0000004,0x00000000,0x000002d4,
-/*
- MOVE dmode_memory_to_memory TO DMODE
-
-at 0x000000b2 : */ 0x78380000,0x00000000,
-/*
-dataout_to_jump:
- MOVE MEMORY 4, 0, dataout_jump + 4
-
-at 0x000000b4 : */ 0xc0000004,0x00000000,0x000002e0,
-/*
-dataout_jump:
- JUMP 0
-
-at 0x000000b7 : */ 0x80080000,0x00000000,
-/*
-
-; Nasty jump to dsa->dsain
-do_datain:
- CALL dsa_to_scratch
-
-at 0x000000b9 : */ 0x88080000,0x00000938,
-/*
- MOVE SCRATCH0 + dsa_datain TO SCRATCH0
-
-at 0x000000bb : */ 0x7e345400,0x00000000,
-/*
- MOVE SCRATCH1 + 0 TO SCRATCH1 WITH CARRY
-
-at 0x000000bd : */ 0x7f350000,0x00000000,
-/*
- MOVE SCRATCH2 + 0 TO SCRATCH2 WITH CARRY
-
-at 0x000000bf : */ 0x7f360000,0x00000000,
-/*
- MOVE SCRATCH3 + 0 TO SCRATCH3 WITH CARRY
-
-at 0x000000c1 : */ 0x7f370000,0x00000000,
-/*
- MOVE dmode_ncr_to_memory TO DMODE
-
-at 0x000000c3 : */ 0x78380000,0x00000000,
-/*
- MOVE MEMORY 4, addr_scratch, datain_to_jump + 4
-
-at 0x000000c5 : */ 0xc0000004,0x00000000,0x0000032c,
-/*
- MOVE dmode_memory_to_memory TO DMODE
-
-at 0x000000c8 : */ 0x78380000,0x00000000,
-/*
-ENTRY datain_to_jump
-datain_to_jump:
- MOVE MEMORY 4, 0, datain_jump + 4
-
-at 0x000000ca : */ 0xc0000004,0x00000000,0x00000338,
-/*
-
-
-
-datain_jump:
- JUMP 0
-
-at 0x000000cd : */ 0x80080000,0x00000000,
-/*
-
-
-
-; Note that other_out and other_in loop until a non-data phase
-; is discoverred, so we only execute return statements when we
-; can go on to the next data phase block move statement.
-
-ENTRY other_out
-other_out:
-
-
-
- INT int_err_unexpected_phase, WHEN CMD
-
-at 0x000000cf : */ 0x9a0b0000,0x00000000,
-/*
- JUMP msg_in_restart, WHEN MSG_IN
-
-at 0x000000d1 : */ 0x870b0000,0x000003e4,
-/*
- INT int_err_unexpected_phase, WHEN MSG_OUT
-
-at 0x000000d3 : */ 0x9e0b0000,0x00000000,
-/*
- INT int_err_unexpected_phase, WHEN DATA_IN
-
-at 0x000000d5 : */ 0x990b0000,0x00000000,
-/*
- JUMP command_complete, WHEN STATUS
-
-at 0x000000d7 : */ 0x830b0000,0x0000060c,
-/*
- JUMP other_out, WHEN NOT DATA_OUT
-
-at 0x000000d9 : */ 0x80030000,0x0000033c,
-/*
- RETURN
-
-at 0x000000db : */ 0x90080000,0x00000000,
-/*
-
-ENTRY other_in
-other_in:
-
-
-
- INT int_err_unexpected_phase, WHEN CMD
-
-at 0x000000dd : */ 0x9a0b0000,0x00000000,
-/*
- JUMP msg_in_restart, WHEN MSG_IN
-
-at 0x000000df : */ 0x870b0000,0x000003e4,
-/*
- INT int_err_unexpected_phase, WHEN MSG_OUT
-
-at 0x000000e1 : */ 0x9e0b0000,0x00000000,
-/*
- INT int_err_unexpected_phase, WHEN DATA_OUT
-
-at 0x000000e3 : */ 0x980b0000,0x00000000,
-/*
- JUMP command_complete, WHEN STATUS
-
-at 0x000000e5 : */ 0x830b0000,0x0000060c,
-/*
- JUMP other_in, WHEN NOT DATA_IN
-
-at 0x000000e7 : */ 0x81030000,0x00000374,
-/*
- RETURN
-
-at 0x000000e9 : */ 0x90080000,0x00000000,
-/*
-
-
-ENTRY other_transfer
-other_transfer:
- INT int_err_unexpected_phase, WHEN CMD
-
-at 0x000000eb : */ 0x9a0b0000,0x00000000,
-/*
- CALL msg_in, WHEN MSG_IN
-
-at 0x000000ed : */ 0x8f0b0000,0x00000404,
-/*
- INT int_err_unexpected_phase, WHEN MSG_OUT
-
-at 0x000000ef : */ 0x9e0b0000,0x00000000,
-/*
- INT int_err_unexpected_phase, WHEN DATA_OUT
-
-at 0x000000f1 : */ 0x980b0000,0x00000000,
-/*
- INT int_err_unexpected_phase, WHEN DATA_IN
-
-at 0x000000f3 : */ 0x990b0000,0x00000000,
-/*
- JUMP command_complete, WHEN STATUS
-
-at 0x000000f5 : */ 0x830b0000,0x0000060c,
-/*
- JUMP other_transfer
-
-at 0x000000f7 : */ 0x80080000,0x000003ac,
-/*
-
-;
-; msg_in_restart
-; msg_in
-; munge_msg
-;
-; PURPOSE : process messages from a target. msg_in is called when the
-; caller hasn't read the first byte of the message. munge_message
-; is called when the caller has read the first byte of the message,
-; and left it in SFBR. msg_in_restart is called when the caller
-; hasnt read the first byte of the message, and wishes RETURN
-; to transfer control back to the address of the conditional
-; CALL instruction rather than to the instruction after it.
-;
-; Various int_* interrupts are generated when the host system
-; needs to intervene, as is the case with SDTR, WDTR, and
-; INITIATE RECOVERY messages.
-;
-; When the host system handles one of these interrupts,
-; it can respond by reentering at reject_message,
-; which rejects the message and returns control to
-; the caller of msg_in or munge_msg, accept_message
-; which clears ACK and returns control, or reply_message
-; which sends the message pointed to by the DSA
-; msgout_other table indirect field.
-;
-; DISCONNECT messages are handled by moving the command
-; to the reconnect_dsa_queue.
-;
-; INPUTS : DSA - SCSI COMMAND, SFBR - first byte of message (munge_msg
-; only)
-;
-; CALLS : NO. The TEMP register isn't backed up to allow nested calls.
-;
-; MODIFIES : SCRATCH, DSA on DISCONNECT
-;
-; EXITS : On receipt of SAVE DATA POINTER, RESTORE POINTERS,
-; and normal return from message handlers running under
-; Linux, control is returned to the caller. Receipt
-; of DISCONNECT messages pass control to dsa_schedule.
-;
-ENTRY msg_in_restart
-msg_in_restart:
-; XXX - hackish
-;
-; Since it's easier to debug changes to the statically
-; compiled code, rather than the dynamically generated
-; stuff, such as
-;
-; MOVE x, y, WHEN data_phase
-; CALL other_z, WHEN NOT data_phase
-; MOVE x, y, WHEN data_phase
-;
-; I'd like to have certain routines (notably the message handler)
-; restart on the conditional call rather than the next instruction.
-;
-; So, subtract 8 from the return address
-
- MOVE TEMP0 + 0xf8 TO TEMP0
-
-at 0x000000f9 : */ 0x7e1cf800,0x00000000,
-/*
- MOVE TEMP1 + 0xff TO TEMP1 WITH CARRY
-
-at 0x000000fb : */ 0x7f1dff00,0x00000000,
-/*
- MOVE TEMP2 + 0xff TO TEMP2 WITH CARRY
-
-at 0x000000fd : */ 0x7f1eff00,0x00000000,
-/*
- MOVE TEMP3 + 0xff TO TEMP3 WITH CARRY
-
-at 0x000000ff : */ 0x7f1fff00,0x00000000,
-/*
-
-ENTRY msg_in
-msg_in:
- MOVE 1, msg_buf, WHEN MSG_IN
-
-at 0x00000101 : */ 0x0f000001,0x00000000,
-/*
-
-munge_msg:
- JUMP munge_extended, IF 0x01 ; EXTENDED MESSAGE
-
-at 0x00000103 : */ 0x800c0001,0x00000524,
-/*
- JUMP munge_2, IF 0x20, AND MASK 0xdf ; two byte message
-
-at 0x00000105 : */ 0x800cdf20,0x0000044c,
-/*
-;
-; XXX - I've seen a handful of broken SCSI devices which fail to issue
-; a SAVE POINTERS message before disconnecting in the middle of
-; a transfer, assuming that the DATA POINTER will be implicitly
-; restored.
-;
-; Historically, I've often done an implicit save when the DISCONNECT
-; message is processed. We may want to consider having the option of
-; doing that here.
-;
- JUMP munge_save_data_pointer, IF 0x02 ; SAVE DATA POINTER
-
-at 0x00000107 : */ 0x800c0002,0x00000454,
-/*
- JUMP munge_restore_pointers, IF 0x03 ; RESTORE POINTERS
-
-at 0x00000109 : */ 0x800c0003,0x000004b8,
-/*
- JUMP munge_disconnect, IF 0x04 ; DISCONNECT
-
-at 0x0000010b : */ 0x800c0004,0x0000051c,
-/*
- INT int_msg_1, IF 0x07 ; MESSAGE REJECT
-
-at 0x0000010d : */ 0x980c0007,0x01020000,
-/*
- INT int_msg_1, IF 0x0f ; INITIATE RECOVERY
-
-at 0x0000010f : */ 0x980c000f,0x01020000,
-/*
-
-
-
- JUMP reject_message
-
-at 0x00000111 : */ 0x80080000,0x000005b4,
-/*
-
-munge_2:
- JUMP reject_message
-
-at 0x00000113 : */ 0x80080000,0x000005b4,
-/*
-;
-; The SCSI standard allows targets to recover from transient
-; error conditions by backing up the data pointer with a
-; RESTORE POINTERS message.
-;
-; So, we must save and restore the _residual_ code as well as
-; the current instruction pointer. Because of this messiness,
-; it is simpler to put dynamic code in the dsa for this and to
-; just do a simple jump down there.
-;
-
-munge_save_data_pointer:
- MOVE DSA0 + dsa_save_data_pointer TO SFBR
-
-at 0x00000115 : */ 0x76100000,0x00000000,
-/*
- MOVE SFBR TO SCRATCH0
-
-at 0x00000117 : */ 0x6a340000,0x00000000,
-/*
- MOVE DSA1 + 0xff TO SFBR WITH CARRY
-
-at 0x00000119 : */ 0x7711ff00,0x00000000,
-/*
- MOVE SFBR TO SCRATCH1
-
-at 0x0000011b : */ 0x6a350000,0x00000000,
-/*
- MOVE DSA2 + 0xff TO SFBR WITH CARRY
-
-at 0x0000011d : */ 0x7712ff00,0x00000000,
-/*
- MOVE SFBR TO SCRATCH2
-
-at 0x0000011f : */ 0x6a360000,0x00000000,
-/*
- MOVE DSA3 + 0xff TO SFBR WITH CARRY
-
-at 0x00000121 : */ 0x7713ff00,0x00000000,
-/*
- MOVE SFBR TO SCRATCH3
-
-at 0x00000123 : */ 0x6a370000,0x00000000,
-/*
-
- MOVE dmode_ncr_to_memory TO DMODE
-
-at 0x00000125 : */ 0x78380000,0x00000000,
-/*
- MOVE MEMORY 4, addr_scratch, jump_dsa_save + 4
-
-at 0x00000127 : */ 0xc0000004,0x00000000,0x000004b4,
-/*
- MOVE dmode_memory_to_memory TO DMODE
-
-at 0x0000012a : */ 0x78380000,0x00000000,
-/*
-jump_dsa_save:
- JUMP 0
-
-at 0x0000012c : */ 0x80080000,0x00000000,
-/*
-
-munge_restore_pointers:
- MOVE DSA0 + dsa_restore_pointers TO SFBR
-
-at 0x0000012e : */ 0x76100000,0x00000000,
-/*
- MOVE SFBR TO SCRATCH0
-
-at 0x00000130 : */ 0x6a340000,0x00000000,
-/*
- MOVE DSA1 + 0xff TO SFBR WITH CARRY
-
-at 0x00000132 : */ 0x7711ff00,0x00000000,
-/*
- MOVE SFBR TO SCRATCH1
-
-at 0x00000134 : */ 0x6a350000,0x00000000,
-/*
- MOVE DSA2 + 0xff TO SFBR WITH CARRY
-
-at 0x00000136 : */ 0x7712ff00,0x00000000,
-/*
- MOVE SFBR TO SCRATCH2
-
-at 0x00000138 : */ 0x6a360000,0x00000000,
-/*
- MOVE DSA3 + 0xff TO SFBR WITH CARRY
-
-at 0x0000013a : */ 0x7713ff00,0x00000000,
-/*
- MOVE SFBR TO SCRATCH3
-
-at 0x0000013c : */ 0x6a370000,0x00000000,
-/*
-
- MOVE dmode_ncr_to_memory TO DMODE
-
-at 0x0000013e : */ 0x78380000,0x00000000,
-/*
- MOVE MEMORY 4, addr_scratch, jump_dsa_restore + 4
-
-at 0x00000140 : */ 0xc0000004,0x00000000,0x00000518,
-/*
- MOVE dmode_memory_to_memory TO DMODE
-
-at 0x00000143 : */ 0x78380000,0x00000000,
-/*
-jump_dsa_restore:
- JUMP 0
-
-at 0x00000145 : */ 0x80080000,0x00000000,
-/*
-
-
-munge_disconnect:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- JUMP dsa_schedule
-
-at 0x00000147 : */ 0x80080000,0x00000168,
-/*
-
-
-
-
-
-munge_extended:
- CLEAR ACK
-
-at 0x00000149 : */ 0x60000040,0x00000000,
-/*
- INT int_err_unexpected_phase, WHEN NOT MSG_IN
-
-at 0x0000014b : */ 0x9f030000,0x00000000,
-/*
- MOVE 1, msg_buf + 1, WHEN MSG_IN
-
-at 0x0000014d : */ 0x0f000001,0x00000001,
-/*
- JUMP munge_extended_2, IF 0x02
-
-at 0x0000014f : */ 0x800c0002,0x00000554,
-/*
- JUMP munge_extended_3, IF 0x03
-
-at 0x00000151 : */ 0x800c0003,0x00000584,
-/*
- JUMP reject_message
-
-at 0x00000153 : */ 0x80080000,0x000005b4,
-/*
-
-munge_extended_2:
- CLEAR ACK
-
-at 0x00000155 : */ 0x60000040,0x00000000,
-/*
- MOVE 1, msg_buf + 2, WHEN MSG_IN
-
-at 0x00000157 : */ 0x0f000001,0x00000002,
-/*
- JUMP reject_message, IF NOT 0x02 ; Must be WDTR
-
-at 0x00000159 : */ 0x80040002,0x000005b4,
-/*
- CLEAR ACK
-
-at 0x0000015b : */ 0x60000040,0x00000000,
-/*
- MOVE 1, msg_buf + 3, WHEN MSG_IN
-
-at 0x0000015d : */ 0x0f000001,0x00000003,
-/*
- INT int_msg_wdtr
-
-at 0x0000015f : */ 0x98080000,0x01000000,
-/*
-
-munge_extended_3:
- CLEAR ACK
-
-at 0x00000161 : */ 0x60000040,0x00000000,
-/*
- MOVE 1, msg_buf + 2, WHEN MSG_IN
-
-at 0x00000163 : */ 0x0f000001,0x00000002,
-/*
- JUMP reject_message, IF NOT 0x01 ; Must be SDTR
-
-at 0x00000165 : */ 0x80040001,0x000005b4,
-/*
- CLEAR ACK
-
-at 0x00000167 : */ 0x60000040,0x00000000,
-/*
- MOVE 2, msg_buf + 3, WHEN MSG_IN
-
-at 0x00000169 : */ 0x0f000002,0x00000003,
-/*
- INT int_msg_sdtr
-
-at 0x0000016b : */ 0x98080000,0x01010000,
-/*
-
-ENTRY reject_message
-reject_message:
- SET ATN
-
-at 0x0000016d : */ 0x58000008,0x00000000,
-/*
- CLEAR ACK
-
-at 0x0000016f : */ 0x60000040,0x00000000,
-/*
- MOVE 1, NCR53c7xx_msg_reject, WHEN MSG_OUT
-
-at 0x00000171 : */ 0x0e000001,0x00000000,
-/*
- RETURN
-
-at 0x00000173 : */ 0x90080000,0x00000000,
-/*
-
-ENTRY accept_message
-accept_message:
- CLEAR ATN
-
-at 0x00000175 : */ 0x60000008,0x00000000,
-/*
- CLEAR ACK
-
-at 0x00000177 : */ 0x60000040,0x00000000,
-/*
- RETURN
-
-at 0x00000179 : */ 0x90080000,0x00000000,
-/*
-
-ENTRY respond_message
-respond_message:
- SET ATN
-
-at 0x0000017b : */ 0x58000008,0x00000000,
-/*
- CLEAR ACK
-
-at 0x0000017d : */ 0x60000040,0x00000000,
-/*
- MOVE FROM dsa_msgout_other, WHEN MSG_OUT
-
-at 0x0000017f : */ 0x1e000000,0x00000068,
-/*
- RETURN
-
-at 0x00000181 : */ 0x90080000,0x00000000,
-/*
-
-;
-; command_complete
-;
-; PURPOSE : handle command termination when STATUS IN is detected by reading
-; a status byte followed by a command termination message.
-;
-; Normal termination results in an INTFLY instruction, and
-; the host system can pick out which command terminated by
-; examining the MESSAGE and STATUS buffers of all currently
-; executing commands;
-;
-; Abnormal (CHECK_CONDITION) termination results in an
-; int_err_check_condition interrupt so that a REQUEST SENSE
-; command can be issued out-of-order so that no other command
-; clears the contingent allegiance condition.
-;
-;
-; INPUTS : DSA - command
-;
-; CALLS : OK
-;
-; EXITS : On successful termination, control is passed to schedule.
-; On abnormal termination, the user will usually modify the
-; DSA fields and corresponding buffers and return control
-; to select.
-;
-
-ENTRY command_complete
-command_complete:
- MOVE FROM dsa_status, WHEN STATUS
-
-at 0x00000183 : */ 0x1b000000,0x00000060,
-/*
-
- MOVE SFBR TO SCRATCH0 ; Save status
-
-at 0x00000185 : */ 0x6a340000,0x00000000,
-/*
-
-ENTRY command_complete_msgin
-command_complete_msgin:
- MOVE FROM dsa_msgin, WHEN MSG_IN
-
-at 0x00000187 : */ 0x1f000000,0x00000058,
-/*
-; Indicate that we should be expecting a disconnect
- MOVE SCNTL2 & 0x7f TO SCNTL2
-
-at 0x00000189 : */ 0x7c027f00,0x00000000,
-/*
- CLEAR ACK
-
-at 0x0000018b : */ 0x60000040,0x00000000,
-/*
-
- WAIT DISCONNECT
-
-at 0x0000018d : */ 0x48000000,0x00000000,
-/*
-
-;
-; The SCSI specification states that when a UNIT ATTENTION condition
-; is pending, as indicated by a CHECK CONDITION status message,
-; the target shall revert to asynchronous transfers. Since
-; synchronous transfers parameters are maintained on a per INITIATOR/TARGET
-; basis, and returning control to our scheduler could work on a command
-; running on another lun on that target using the old parameters, we must
-; interrupt the host processor to get them changed, or change them ourselves.
-;
-; Once SCSI-II tagged queueing is implemented, things will be even more
-; hairy, since contingent allegiance conditions exist on a per-target/lun
-; basis, and issuing a new command with a different tag would clear it.
-; In these cases, we must interrupt the host processor to get a request
-; added to the HEAD of the queue with the request sense command, or we
-; must automatically issue the request sense command.
-
-
-
-
-
- INTFLY
-
-at 0x0000018f : */ 0x98180000,0x00000000,
-/*
-
-
-
-
-
- JUMP schedule
-
-at 0x00000191 : */ 0x80080000,0x00000000,
-/*
-command_failed:
- INT int_err_check_condition
-
-at 0x00000193 : */ 0x98080000,0x00030000,
-/*
-
-
-
-
-;
-; wait_reselect
-;
-; PURPOSE : This is essentially the idle routine, where control lands
-; when there are no new processes to schedule. wait_reselect
-; waits for reselection, selection, and new commands.
-;
-; When a successful reselection occurs, with the aid
-; of fixed up code in each DSA, wait_reselect walks the
-; reconnect_dsa_queue, asking each dsa if the target ID
-; and LUN match its.
-;
-; If a match is found, a call is made back to reselected_ok,
-; which through the miracles of self modifying code, extracts
-; the found DSA from the reconnect_dsa_queue and then
-; returns control to the DSAs thread of execution.
-;
-; INPUTS : NONE
-;
-; CALLS : OK
-;
-; MODIFIES : DSA,
-;
-; EXITS : On successful reselection, control is returned to the
-; DSA which called reselected_ok. If the WAIT RESELECT
-; was interrupted by a new commands arrival signaled by
-; SIG_P, control is passed to schedule. If the NCR is
-; selected, the host system is interrupted with an
-; int_err_selected which is usually responded to by
-; setting DSP to the target_abort address.
-
-ENTRY wait_reselect
-wait_reselect:
-
-
-
-
-
-
- WAIT RESELECT wait_reselect_failed
-
-at 0x00000195 : */ 0x50000000,0x0000076c,
-/*
-
-reselected:
-
-
-
- CLEAR TARGET
-
-at 0x00000197 : */ 0x60000200,0x00000000,
-/*
- MOVE dmode_memory_to_memory TO DMODE
-
-at 0x00000199 : */ 0x78380000,0x00000000,
-/*
- ; Read all data needed to reestablish the nexus -
- MOVE 1, reselected_identify, WHEN MSG_IN
-
-at 0x0000019b : */ 0x0f000001,0x00000000,
-/*
- ; We used to CLEAR ACK here.
-
-
-
-
-
- ; Point DSA at the current head of the disconnected queue.
- MOVE dmode_memory_to_ncr TO DMODE
-
-at 0x0000019d : */ 0x78380000,0x00000000,
-/*
- MOVE MEMORY 4, reconnect_dsa_head, addr_scratch
-
-at 0x0000019f : */ 0xc0000004,0x00000000,0x00000000,
-/*
- MOVE dmode_memory_to_memory TO DMODE
-
-at 0x000001a2 : */ 0x78380000,0x00000000,
-/*
- CALL scratch_to_dsa
-
-at 0x000001a4 : */ 0x88080000,0x00000980,
-/*
-
- ; Fix the update-next pointer so that the reconnect_dsa_head
- ; pointer is the one that will be updated if this DSA is a hit
- ; and we remove it from the queue.
-
- MOVE MEMORY 4, addr_reconnect_dsa_head, reselected_ok + 8
-
-at 0x000001a6 : */ 0xc0000004,0x00000000,0x00000758,
-/*
-
-ENTRY reselected_check_next
-reselected_check_next:
-
-
-
- ; Check for a NULL pointer.
- MOVE DSA0 TO SFBR
-
-at 0x000001a9 : */ 0x72100000,0x00000000,
-/*
- JUMP reselected_not_end, IF NOT 0
-
-at 0x000001ab : */ 0x80040000,0x000006ec,
-/*
- MOVE DSA1 TO SFBR
-
-at 0x000001ad : */ 0x72110000,0x00000000,
-/*
- JUMP reselected_not_end, IF NOT 0
-
-at 0x000001af : */ 0x80040000,0x000006ec,
-/*
- MOVE DSA2 TO SFBR
-
-at 0x000001b1 : */ 0x72120000,0x00000000,
-/*
- JUMP reselected_not_end, IF NOT 0
-
-at 0x000001b3 : */ 0x80040000,0x000006ec,
-/*
- MOVE DSA3 TO SFBR
-
-at 0x000001b5 : */ 0x72130000,0x00000000,
-/*
- JUMP reselected_not_end, IF NOT 0
-
-at 0x000001b7 : */ 0x80040000,0x000006ec,
-/*
- INT int_err_unexpected_reselect
-
-at 0x000001b9 : */ 0x98080000,0x00020000,
-/*
-
-reselected_not_end:
- ;
- ; XXX the ALU is only eight bits wide, and the assembler
- ; wont do the dirt work for us. As long as dsa_check_reselect
- ; is negative, we need to sign extend with 1 bits to the full
- ; 32 bit width of the address.
- ;
- ; A potential work around would be to have a known alignment
- ; of the DSA structure such that the base address plus
- ; dsa_check_reselect doesn't require carrying from bytes
- ; higher than the LSB.
- ;
-
- MOVE DSA0 TO SFBR
-
-at 0x000001bb : */ 0x72100000,0x00000000,
-/*
- MOVE SFBR + dsa_check_reselect TO SCRATCH0
-
-at 0x000001bd : */ 0x6e340000,0x00000000,
-/*
- MOVE DSA1 TO SFBR
-
-at 0x000001bf : */ 0x72110000,0x00000000,
-/*
- MOVE SFBR + 0xff TO SCRATCH1 WITH CARRY
-
-at 0x000001c1 : */ 0x6f35ff00,0x00000000,
-/*
- MOVE DSA2 TO SFBR
-
-at 0x000001c3 : */ 0x72120000,0x00000000,
-/*
- MOVE SFBR + 0xff TO SCRATCH2 WITH CARRY
-
-at 0x000001c5 : */ 0x6f36ff00,0x00000000,
-/*
- MOVE DSA3 TO SFBR
-
-at 0x000001c7 : */ 0x72130000,0x00000000,
-/*
- MOVE SFBR + 0xff TO SCRATCH3 WITH CARRY
-
-at 0x000001c9 : */ 0x6f37ff00,0x00000000,
-/*
-
- MOVE dmode_ncr_to_memory TO DMODE
-
-at 0x000001cb : */ 0x78380000,0x00000000,
-/*
- MOVE MEMORY 4, addr_scratch, reselected_check + 4
-
-at 0x000001cd : */ 0xc0000004,0x00000000,0x0000074c,
-/*
- MOVE dmode_memory_to_memory TO DMODE
-
-at 0x000001d0 : */ 0x78380000,0x00000000,
-/*
-reselected_check:
- JUMP 0
-
-at 0x000001d2 : */ 0x80080000,0x00000000,
-/*
-
-
-;
-;
-ENTRY reselected_ok
-reselected_ok:
- MOVE MEMORY 4, 0, 0 ; Patched : first word
-
-at 0x000001d4 : */ 0xc0000004,0x00000000,0x00000000,
-/*
- ; is address of
- ; successful dsa_next
- ; Second word is last
- ; unsuccessful dsa_next,
- ; starting with
- ; dsa_reconnect_head
- ; We used to CLEAR ACK here.
-
-
-
-
-
-
- RETURN ; Return control to where
-
-at 0x000001d7 : */ 0x90080000,0x00000000,
-/*
-
-
-
-
-selected:
- INT int_err_selected;
-
-at 0x000001d9 : */ 0x98080000,0x00010000,
-/*
-
-;
-; A select or reselect failure can be caused by one of two conditions :
-; 1. SIG_P was set. This will be the case if the user has written
-; a new value to a previously NULL head of the issue queue.
-;
-; 2. The NCR53c810 was selected or reselected by another device.
-;
-; 3. The bus was allready busy since we were selected or reselected
-; before starting the command.
-
-wait_reselect_failed:
-
-
-
-; Check selected bit.
- MOVE SIST0 & 0x20 TO SFBR
-
-at 0x000001db : */ 0x74422000,0x00000000,
-/*
- JUMP selected, IF 0x20
-
-at 0x000001dd : */ 0x800c0020,0x00000764,
-/*
-; Reading CTEST2 clears the SIG_P bit in the ISTAT register.
- MOVE CTEST2 & 0x40 TO SFBR
-
-at 0x000001df : */ 0x741a4000,0x00000000,
-/*
- JUMP schedule, IF 0x40
-
-at 0x000001e1 : */ 0x800c0040,0x00000000,
-/*
-; Check connected bit.
-; FIXME: this needs to change if we support target mode
- MOVE ISTAT & 0x08 TO SFBR
-
-at 0x000001e3 : */ 0x74140800,0x00000000,
-/*
- JUMP reselected, IF 0x08
-
-at 0x000001e5 : */ 0x800c0008,0x0000065c,
-/*
-; FIXME : Something bogus happened, and we shouldn't fail silently.
-
-
-
- INT int_debug_panic
-
-at 0x000001e7 : */ 0x98080000,0x030b0000,
-/*
-
-
-
-select_failed:
-
-
-
-; Otherwise, mask the selected and reselected bits off SIST0
- MOVE SIST0 & 0x30 TO SFBR
-
-at 0x000001e9 : */ 0x74423000,0x00000000,
-/*
- JUMP selected, IF 0x20
-
-at 0x000001eb : */ 0x800c0020,0x00000764,
-/*
- JUMP reselected, IF 0x10
-
-at 0x000001ed : */ 0x800c0010,0x0000065c,
-/*
-; If SIGP is set, the user just gave us another command, and
-; we should restart or return to the scheduler.
-; Reading CTEST2 clears the SIG_P bit in the ISTAT register.
- MOVE CTEST2 & 0x40 TO SFBR
-
-at 0x000001ef : */ 0x741a4000,0x00000000,
-/*
- JUMP select, IF 0x40
-
-at 0x000001f1 : */ 0x800c0040,0x000001fc,
-/*
-; Check connected bit.
-; FIXME: this needs to change if we support target mode
-; FIXME: is this really necessary?
- MOVE ISTAT & 0x08 TO SFBR
-
-at 0x000001f3 : */ 0x74140800,0x00000000,
-/*
- JUMP reselected, IF 0x08
-
-at 0x000001f5 : */ 0x800c0008,0x0000065c,
-/*
-; FIXME : Something bogus happened, and we shouldn't fail silently.
-
-
-
- INT int_debug_panic
-
-at 0x000001f7 : */ 0x98080000,0x030b0000,
-/*
-
-
-;
-; test_1
-; test_2
-;
-; PURPOSE : run some verification tests on the NCR. test_1
-; copies test_src to test_dest and interrupts the host
-; processor, testing for cache coherency and interrupt
-; problems in the processes.
-;
-; test_2 runs a command with offsets relative to the
-; DSA on entry, and is useful for miscellaneous experimentation.
-;
-
-; Verify that interrupts are working correctly and that we don't
-; have a cache invalidation problem.
-
-ABSOLUTE test_src = 0, test_dest = 0
-ENTRY test_1
-test_1:
- MOVE MEMORY 4, test_src, test_dest
-
-at 0x000001f9 : */ 0xc0000004,0x00000000,0x00000000,
-/*
- INT int_test_1
-
-at 0x000001fc : */ 0x98080000,0x04000000,
-/*
-
-;
-; Run arbitrary commands, with test code establishing a DSA
-;
-
-ENTRY test_2
-test_2:
- CLEAR TARGET
-
-at 0x000001fe : */ 0x60000200,0x00000000,
-/*
- SELECT ATN FROM 0, test_2_fail
-
-at 0x00000200 : */ 0x43000000,0x00000850,
-/*
- JUMP test_2_msgout, WHEN MSG_OUT
-
-at 0x00000202 : */ 0x860b0000,0x00000810,
-/*
-ENTRY test_2_msgout
-test_2_msgout:
- MOVE FROM 8, WHEN MSG_OUT
-
-at 0x00000204 : */ 0x1e000000,0x00000008,
-/*
- MOVE FROM 16, WHEN CMD
-
-at 0x00000206 : */ 0x1a000000,0x00000010,
-/*
- MOVE FROM 24, WHEN DATA_IN
-
-at 0x00000208 : */ 0x19000000,0x00000018,
-/*
- MOVE FROM 32, WHEN STATUS
-
-at 0x0000020a : */ 0x1b000000,0x00000020,
-/*
- MOVE FROM 40, WHEN MSG_IN
-
-at 0x0000020c : */ 0x1f000000,0x00000028,
-/*
- MOVE SCNTL2 & 0x7f TO SCNTL2
-
-at 0x0000020e : */ 0x7c027f00,0x00000000,
-/*
- CLEAR ACK
-
-at 0x00000210 : */ 0x60000040,0x00000000,
-/*
- WAIT DISCONNECT
-
-at 0x00000212 : */ 0x48000000,0x00000000,
-/*
-test_2_fail:
- INT int_test_2
-
-at 0x00000214 : */ 0x98080000,0x04010000,
-/*
-
-ENTRY debug_break
-debug_break:
- INT int_debug_break
-
-at 0x00000216 : */ 0x98080000,0x03000000,
-/*
-
-;
-; initiator_abort
-; target_abort
-;
-; PURPOSE : Abort the currently established nexus from with initiator
-; or target mode.
-;
-;
-
-ENTRY target_abort
-target_abort:
- SET TARGET
-
-at 0x00000218 : */ 0x58000200,0x00000000,
-/*
- DISCONNECT
-
-at 0x0000021a : */ 0x48000000,0x00000000,
-/*
- CLEAR TARGET
-
-at 0x0000021c : */ 0x60000200,0x00000000,
-/*
- JUMP schedule
-
-at 0x0000021e : */ 0x80080000,0x00000000,
-/*
-
-ENTRY initiator_abort
-initiator_abort:
- SET ATN
-
-at 0x00000220 : */ 0x58000008,0x00000000,
-/*
-;
-; The SCSI-I specification says that targets may go into MSG out at
-; their leisure upon receipt of the ATN single. On all versions of the
-; specification, we can't change phases until REQ transitions true->false,
-; so we need to sink/source one byte of data to allow the transition.
-;
-; For the sake of safety, we'll only source one byte of data in all
-; cases, but to accomodate the SCSI-I dain bramage, we'll sink an
-; arbitrary number of bytes.
- JUMP spew_cmd, WHEN CMD
-
-at 0x00000222 : */ 0x820b0000,0x000008b8,
-/*
- JUMP eat_msgin, WHEN MSG_IN
-
-at 0x00000224 : */ 0x870b0000,0x000008c8,
-/*
- JUMP eat_datain, WHEN DATA_IN
-
-at 0x00000226 : */ 0x810b0000,0x000008f8,
-/*
- JUMP eat_status, WHEN STATUS
-
-at 0x00000228 : */ 0x830b0000,0x000008e0,
-/*
- JUMP spew_dataout, WHEN DATA_OUT
-
-at 0x0000022a : */ 0x800b0000,0x00000910,
-/*
- JUMP sated
-
-at 0x0000022c : */ 0x80080000,0x00000918,
-/*
-spew_cmd:
- MOVE 1, NCR53c7xx_zero, WHEN CMD
-
-at 0x0000022e : */ 0x0a000001,0x00000000,
-/*
- JUMP sated
-
-at 0x00000230 : */ 0x80080000,0x00000918,
-/*
-eat_msgin:
- MOVE 1, NCR53c7xx_sink, WHEN MSG_IN
-
-at 0x00000232 : */ 0x0f000001,0x00000000,
-/*
- JUMP eat_msgin, WHEN MSG_IN
-
-at 0x00000234 : */ 0x870b0000,0x000008c8,
-/*
- JUMP sated
-
-at 0x00000236 : */ 0x80080000,0x00000918,
-/*
-eat_status:
- MOVE 1, NCR53c7xx_sink, WHEN STATUS
-
-at 0x00000238 : */ 0x0b000001,0x00000000,
-/*
- JUMP eat_status, WHEN STATUS
-
-at 0x0000023a : */ 0x830b0000,0x000008e0,
-/*
- JUMP sated
-
-at 0x0000023c : */ 0x80080000,0x00000918,
-/*
-eat_datain:
- MOVE 1, NCR53c7xx_sink, WHEN DATA_IN
-
-at 0x0000023e : */ 0x09000001,0x00000000,
-/*
- JUMP eat_datain, WHEN DATA_IN
-
-at 0x00000240 : */ 0x810b0000,0x000008f8,
-/*
- JUMP sated
-
-at 0x00000242 : */ 0x80080000,0x00000918,
-/*
-spew_dataout:
- MOVE 1, NCR53c7xx_zero, WHEN DATA_OUT
-
-at 0x00000244 : */ 0x08000001,0x00000000,
-/*
-sated:
- MOVE SCNTL2 & 0x7f TO SCNTL2
-
-at 0x00000246 : */ 0x7c027f00,0x00000000,
-/*
- MOVE 1, NCR53c7xx_msg_abort, WHEN MSG_OUT
-
-at 0x00000248 : */ 0x0e000001,0x00000000,
-/*
- WAIT DISCONNECT
-
-at 0x0000024a : */ 0x48000000,0x00000000,
-/*
- INT int_norm_aborted
-
-at 0x0000024c : */ 0x98080000,0x02040000,
-/*
-
-;
-; dsa_to_scratch
-; scratch_to_dsa
-;
-; PURPOSE :
-; The NCR chips cannot do a move memory instruction with the DSA register
-; as the source or destination. So, we provide a couple of subroutines
-; that let us switch between the DSA register and scratch register.
-;
-; Memory moves to/from the DSPS register also don't work, but we
-; don't use them.
-;
-;
-
-
-dsa_to_scratch:
- MOVE DSA0 TO SFBR
-
-at 0x0000024e : */ 0x72100000,0x00000000,
-/*
- MOVE SFBR TO SCRATCH0
-
-at 0x00000250 : */ 0x6a340000,0x00000000,
-/*
- MOVE DSA1 TO SFBR
-
-at 0x00000252 : */ 0x72110000,0x00000000,
-/*
- MOVE SFBR TO SCRATCH1
-
-at 0x00000254 : */ 0x6a350000,0x00000000,
-/*
- MOVE DSA2 TO SFBR
-
-at 0x00000256 : */ 0x72120000,0x00000000,
-/*
- MOVE SFBR TO SCRATCH2
-
-at 0x00000258 : */ 0x6a360000,0x00000000,
-/*
- MOVE DSA3 TO SFBR
-
-at 0x0000025a : */ 0x72130000,0x00000000,
-/*
- MOVE SFBR TO SCRATCH3
-
-at 0x0000025c : */ 0x6a370000,0x00000000,
-/*
- RETURN
-
-at 0x0000025e : */ 0x90080000,0x00000000,
-/*
-
-scratch_to_dsa:
- MOVE SCRATCH0 TO SFBR
-
-at 0x00000260 : */ 0x72340000,0x00000000,
-/*
- MOVE SFBR TO DSA0
-
-at 0x00000262 : */ 0x6a100000,0x00000000,
-/*
- MOVE SCRATCH1 TO SFBR
-
-at 0x00000264 : */ 0x72350000,0x00000000,
-/*
- MOVE SFBR TO DSA1
-
-at 0x00000266 : */ 0x6a110000,0x00000000,
-/*
- MOVE SCRATCH2 TO SFBR
-
-at 0x00000268 : */ 0x72360000,0x00000000,
-/*
- MOVE SFBR TO DSA2
-
-at 0x0000026a : */ 0x6a120000,0x00000000,
-/*
- MOVE SCRATCH3 TO SFBR
-
-at 0x0000026c : */ 0x72370000,0x00000000,
-/*
- MOVE SFBR TO DSA3
-
-at 0x0000026e : */ 0x6a130000,0x00000000,
-/*
- RETURN
-
-at 0x00000270 : */ 0x90080000,0x00000000,
-};
-
-#define A_NCR53c7xx_msg_abort 0x00000000
-u32 A_NCR53c7xx_msg_abort_used[] = {
- 0x00000249,
-};
-
-#define A_NCR53c7xx_msg_reject 0x00000000
-u32 A_NCR53c7xx_msg_reject_used[] = {
- 0x00000172,
-};
-
-#define A_NCR53c7xx_sink 0x00000000
-u32 A_NCR53c7xx_sink_used[] = {
- 0x00000233,
- 0x00000239,
- 0x0000023f,
-};
-
-#define A_NCR53c7xx_zero 0x00000000
-u32 A_NCR53c7xx_zero_used[] = {
- 0x0000022f,
- 0x00000245,
-};
-
-#define A_NOP_insn 0x00000000
-u32 A_NOP_insn_used[] = {
- 0x00000010,
-};
-
-#define A_addr_reconnect_dsa_head 0x00000000
-u32 A_addr_reconnect_dsa_head_used[] = {
- 0x000001a7,
-};
-
-#define A_addr_scratch 0x00000000
-u32 A_addr_scratch_used[] = {
- 0x00000004,
- 0x0000001b,
- 0x00000046,
- 0x00000067,
- 0x00000073,
- 0x000000b0,
- 0x000000c6,
- 0x00000128,
- 0x00000141,
- 0x000001a1,
- 0x000001ce,
-};
-
-#define A_addr_temp 0x00000000
-u32 A_addr_temp_used[] = {
- 0x00000025,
- 0x00000034,
-};
-
-#define A_dmode_memory_to_memory 0x00000000
-u32 A_dmode_memory_to_memory_used[] = {
- 0x00000005,
- 0x0000001c,
- 0x00000027,
- 0x00000035,
- 0x00000047,
- 0x00000069,
- 0x00000075,
- 0x000000b2,
- 0x000000c8,
- 0x0000012a,
- 0x00000143,
- 0x00000199,
- 0x000001a2,
- 0x000001d0,
-};
-
-#define A_dmode_memory_to_ncr 0x00000000
-u32 A_dmode_memory_to_ncr_used[] = {
- 0x00000000,
- 0x00000017,
- 0x00000030,
- 0x00000042,
- 0x0000019d,
-};
-
-#define A_dmode_ncr_to_memory 0x00000000
-u32 A_dmode_ncr_to_memory_used[] = {
- 0x00000022,
- 0x00000064,
- 0x00000070,
- 0x000000ad,
- 0x000000c3,
- 0x00000125,
- 0x0000013e,
- 0x000001cb,
-};
-
-#define A_dsa_check_reselect 0x00000000
-u32 A_dsa_check_reselect_used[] = {
- 0x000001bd,
-};
-
-#define A_dsa_cmdout 0x00000048
-u32 A_dsa_cmdout_used[] = {
- 0x00000094,
-};
-
-#define A_dsa_cmnd 0x00000038
-u32 A_dsa_cmnd_used[] = {
-};
-
-#define A_dsa_datain 0x00000054
-u32 A_dsa_datain_used[] = {
- 0x000000bb,
-};
-
-#define A_dsa_dataout 0x00000050
-u32 A_dsa_dataout_used[] = {
- 0x000000a5,
-};
-
-#define A_dsa_end 0x00000070
-u32 A_dsa_end_used[] = {
-};
-
-#define A_dsa_fields_start 0x00000000
-u32 A_dsa_fields_start_used[] = {
-};
-
-#define A_dsa_msgin 0x00000058
-u32 A_dsa_msgin_used[] = {
- 0x00000188,
-};
-
-#define A_dsa_msgout 0x00000040
-u32 A_dsa_msgout_used[] = {
- 0x00000086,
-};
-
-#define A_dsa_msgout_other 0x00000068
-u32 A_dsa_msgout_other_used[] = {
- 0x00000180,
-};
-
-#define A_dsa_next 0x00000030
-u32 A_dsa_next_used[] = {
- 0x0000005c,
-};
-
-#define A_dsa_restore_pointers 0x00000000
-u32 A_dsa_restore_pointers_used[] = {
- 0x0000012e,
-};
-
-#define A_dsa_save_data_pointer 0x00000000
-u32 A_dsa_save_data_pointer_used[] = {
- 0x00000115,
-};
-
-#define A_dsa_select 0x0000003c
-u32 A_dsa_select_used[] = {
- 0x00000081,
-};
-
-#define A_dsa_status 0x00000060
-u32 A_dsa_status_used[] = {
- 0x00000184,
-};
-
-#define A_dsa_temp_addr_array_value 0x00000000
-u32 A_dsa_temp_addr_array_value_used[] = {
-};
-
-#define A_dsa_temp_addr_dsa_value 0x00000000
-u32 A_dsa_temp_addr_dsa_value_used[] = {
- 0x00000003,
-};
-
-#define A_dsa_temp_addr_new_value 0x00000000
-u32 A_dsa_temp_addr_new_value_used[] = {
-};
-
-#define A_dsa_temp_addr_next 0x00000000
-u32 A_dsa_temp_addr_next_used[] = {
- 0x00000015,
- 0x0000004e,
-};
-
-#define A_dsa_temp_addr_residual 0x00000000
-u32 A_dsa_temp_addr_residual_used[] = {
- 0x0000002a,
- 0x00000039,
-};
-
-#define A_dsa_temp_addr_saved_pointer 0x00000000
-u32 A_dsa_temp_addr_saved_pointer_used[] = {
- 0x00000026,
- 0x00000033,
-};
-
-#define A_dsa_temp_addr_saved_residual 0x00000000
-u32 A_dsa_temp_addr_saved_residual_used[] = {
- 0x0000002b,
- 0x00000038,
-};
-
-#define A_dsa_temp_lun 0x00000000
-u32 A_dsa_temp_lun_used[] = {
- 0x0000004b,
-};
-
-#define A_dsa_temp_next 0x00000000
-u32 A_dsa_temp_next_used[] = {
- 0x0000001a,
-};
-
-#define A_dsa_temp_sync 0x00000000
-u32 A_dsa_temp_sync_used[] = {
- 0x00000053,
-};
-
-#define A_dsa_temp_target 0x00000000
-u32 A_dsa_temp_target_used[] = {
- 0x00000040,
-};
-
-#define A_int_debug_break 0x03000000
-u32 A_int_debug_break_used[] = {
- 0x00000217,
-};
-
-#define A_int_debug_panic 0x030b0000
-u32 A_int_debug_panic_used[] = {
- 0x000001e8,
- 0x000001f8,
-};
-
-#define A_int_err_check_condition 0x00030000
-u32 A_int_err_check_condition_used[] = {
- 0x00000194,
-};
-
-#define A_int_err_no_phase 0x00040000
-u32 A_int_err_no_phase_used[] = {
-};
-
-#define A_int_err_selected 0x00010000
-u32 A_int_err_selected_used[] = {
- 0x000001da,
-};
-
-#define A_int_err_unexpected_phase 0x00000000
-u32 A_int_err_unexpected_phase_used[] = {
- 0x0000008c,
- 0x00000092,
- 0x0000009a,
- 0x000000d0,
- 0x000000d4,
- 0x000000d6,
- 0x000000de,
- 0x000000e2,
- 0x000000e4,
- 0x000000ec,
- 0x000000f0,
- 0x000000f2,
- 0x000000f4,
- 0x0000014c,
-};
-
-#define A_int_err_unexpected_reselect 0x00020000
-u32 A_int_err_unexpected_reselect_used[] = {
- 0x000001ba,
-};
-
-#define A_int_msg_1 0x01020000
-u32 A_int_msg_1_used[] = {
- 0x0000010e,
- 0x00000110,
-};
-
-#define A_int_msg_sdtr 0x01010000
-u32 A_int_msg_sdtr_used[] = {
- 0x0000016c,
-};
-
-#define A_int_msg_wdtr 0x01000000
-u32 A_int_msg_wdtr_used[] = {
- 0x00000160,
-};
-
-#define A_int_norm_aborted 0x02040000
-u32 A_int_norm_aborted_used[] = {
- 0x0000024d,
-};
-
-#define A_int_norm_command_complete 0x02020000
-u32 A_int_norm_command_complete_used[] = {
-};
-
-#define A_int_norm_disconnected 0x02030000
-u32 A_int_norm_disconnected_used[] = {
-};
-
-#define A_int_norm_reselect_complete 0x02010000
-u32 A_int_norm_reselect_complete_used[] = {
-};
-
-#define A_int_norm_reset 0x02050000
-u32 A_int_norm_reset_used[] = {
-};
-
-#define A_int_norm_select_complete 0x02000000
-u32 A_int_norm_select_complete_used[] = {
-};
-
-#define A_int_test_1 0x04000000
-u32 A_int_test_1_used[] = {
- 0x000001fd,
-};
-
-#define A_int_test_2 0x04010000
-u32 A_int_test_2_used[] = {
- 0x00000215,
-};
-
-#define A_int_test_3 0x04020000
-u32 A_int_test_3_used[] = {
-};
-
-#define A_msg_buf 0x00000000
-u32 A_msg_buf_used[] = {
- 0x00000102,
- 0x0000014e,
- 0x00000158,
- 0x0000015e,
- 0x00000164,
- 0x0000016a,
-};
-
-#define A_reconnect_dsa_head 0x00000000
-u32 A_reconnect_dsa_head_used[] = {
- 0x0000006c,
- 0x00000074,
- 0x000001a0,
-};
-
-#define A_reselected_identify 0x00000000
-u32 A_reselected_identify_used[] = {
- 0x00000045,
- 0x0000019c,
-};
-
-#define A_reselected_tag 0x00000000
-u32 A_reselected_tag_used[] = {
-};
-
-#define A_schedule 0x00000000
-u32 A_schedule_used[] = {
- 0x0000007e,
- 0x00000192,
- 0x000001e2,
- 0x0000021f,
-};
-
-#define A_test_dest 0x00000000
-u32 A_test_dest_used[] = {
- 0x000001fb,
-};
-
-#define A_test_src 0x00000000
-u32 A_test_src_used[] = {
- 0x000001fa,
-};
-
-#define Ent_accept_message 0x000005d4
-#define Ent_cmdout_cmdout 0x0000024c
-#define Ent_command_complete 0x0000060c
-#define Ent_command_complete_msgin 0x0000061c
-#define Ent_data_transfer 0x00000254
-#define Ent_datain_to_jump 0x00000328
-#define Ent_debug_break 0x00000858
-#define Ent_dsa_code_begin 0x00000000
-#define Ent_dsa_code_check_reselect 0x000000f8
-#define Ent_dsa_code_fix_jump 0x0000003c
-#define Ent_dsa_code_restore_pointers 0x000000c0
-#define Ent_dsa_code_save_data_pointer 0x00000088
-#define Ent_dsa_code_template 0x00000000
-#define Ent_dsa_code_template_end 0x00000168
-#define Ent_dsa_schedule 0x00000168
-#define Ent_dsa_zero 0x00000168
-#define Ent_end_data_transfer 0x0000028c
-#define Ent_initiator_abort 0x00000880
-#define Ent_msg_in 0x00000404
-#define Ent_msg_in_restart 0x000003e4
-#define Ent_other_in 0x00000374
-#define Ent_other_out 0x0000033c
-#define Ent_other_transfer 0x000003ac
-#define Ent_reject_message 0x000005b4
-#define Ent_reselected_check_next 0x000006a4
-#define Ent_reselected_ok 0x00000750
-#define Ent_respond_message 0x000005ec
-#define Ent_select 0x000001fc
-#define Ent_select_msgout 0x00000214
-#define Ent_target_abort 0x00000860
-#define Ent_test_1 0x000007e4
-#define Ent_test_2 0x000007f8
-#define Ent_test_2_msgout 0x00000810
-#define Ent_wait_reselect 0x00000654
-u32 LABELPATCHES[] = {
- 0x00000008,
- 0x0000000a,
- 0x00000013,
- 0x00000016,
- 0x0000001f,
- 0x00000021,
- 0x0000004f,
- 0x00000051,
- 0x0000005b,
- 0x00000068,
- 0x0000006f,
- 0x00000082,
- 0x00000084,
- 0x0000008a,
- 0x0000008e,
- 0x00000090,
- 0x00000096,
- 0x00000098,
- 0x0000009c,
- 0x0000009e,
- 0x000000a0,
- 0x000000a2,
- 0x000000a4,
- 0x000000b1,
- 0x000000b6,
- 0x000000ba,
- 0x000000c7,
- 0x000000cc,
- 0x000000d2,
- 0x000000d8,
- 0x000000da,
- 0x000000e0,
- 0x000000e6,
- 0x000000e8,
- 0x000000ee,
- 0x000000f6,
- 0x000000f8,
- 0x00000104,
- 0x00000106,
- 0x00000108,
- 0x0000010a,
- 0x0000010c,
- 0x00000112,
- 0x00000114,
- 0x00000129,
- 0x00000142,
- 0x00000148,
- 0x00000150,
- 0x00000152,
- 0x00000154,
- 0x0000015a,
- 0x00000166,
- 0x00000196,
- 0x000001a5,
- 0x000001a8,
- 0x000001ac,
- 0x000001b0,
- 0x000001b4,
- 0x000001b8,
- 0x000001cf,
- 0x000001de,
- 0x000001e6,
- 0x000001ec,
- 0x000001ee,
- 0x000001f2,
- 0x000001f6,
- 0x00000201,
- 0x00000203,
- 0x00000223,
- 0x00000225,
- 0x00000227,
- 0x00000229,
- 0x0000022b,
- 0x0000022d,
- 0x00000231,
- 0x00000235,
- 0x00000237,
- 0x0000023b,
- 0x0000023d,
- 0x00000241,
- 0x00000243,
-};
-
-struct {
- u32 offset;
- void *address;
-} EXTERNAL_PATCHES[] = {
-};
-
-u32 INSTRUCTIONS = 301;
-u32 PATCHES = 81;
-u32 EXTERNAL_PATCHES_LEN = 0;
diff --git a/i386/i386at/gpl/linux/scsi/53c8xx_u.h b/i386/i386at/gpl/linux/scsi/53c8xx_u.h
deleted file mode 100644
index c3d486fe..00000000
--- a/i386/i386at/gpl/linux/scsi/53c8xx_u.h
+++ /dev/null
@@ -1,97 +0,0 @@
-#undef A_NCR53c7xx_msg_abort
-#undef A_NCR53c7xx_msg_reject
-#undef A_NCR53c7xx_sink
-#undef A_NCR53c7xx_zero
-#undef A_NOP_insn
-#undef A_addr_reconnect_dsa_head
-#undef A_addr_scratch
-#undef A_addr_temp
-#undef A_dmode_memory_to_memory
-#undef A_dmode_memory_to_ncr
-#undef A_dmode_ncr_to_memory
-#undef A_dsa_check_reselect
-#undef A_dsa_cmdout
-#undef A_dsa_cmnd
-#undef A_dsa_datain
-#undef A_dsa_dataout
-#undef A_dsa_end
-#undef A_dsa_fields_start
-#undef A_dsa_msgin
-#undef A_dsa_msgout
-#undef A_dsa_msgout_other
-#undef A_dsa_next
-#undef A_dsa_restore_pointers
-#undef A_dsa_save_data_pointer
-#undef A_dsa_select
-#undef A_dsa_status
-#undef A_dsa_temp_addr_array_value
-#undef A_dsa_temp_addr_dsa_value
-#undef A_dsa_temp_addr_new_value
-#undef A_dsa_temp_addr_next
-#undef A_dsa_temp_addr_residual
-#undef A_dsa_temp_addr_saved_pointer
-#undef A_dsa_temp_addr_saved_residual
-#undef A_dsa_temp_lun
-#undef A_dsa_temp_next
-#undef A_dsa_temp_sync
-#undef A_dsa_temp_target
-#undef A_int_debug_break
-#undef A_int_debug_panic
-#undef A_int_err_check_condition
-#undef A_int_err_no_phase
-#undef A_int_err_selected
-#undef A_int_err_unexpected_phase
-#undef A_int_err_unexpected_reselect
-#undef A_int_msg_1
-#undef A_int_msg_sdtr
-#undef A_int_msg_wdtr
-#undef A_int_norm_aborted
-#undef A_int_norm_command_complete
-#undef A_int_norm_disconnected
-#undef A_int_norm_reselect_complete
-#undef A_int_norm_reset
-#undef A_int_norm_select_complete
-#undef A_int_test_1
-#undef A_int_test_2
-#undef A_int_test_3
-#undef A_msg_buf
-#undef A_reconnect_dsa_head
-#undef A_reselected_identify
-#undef A_reselected_tag
-#undef A_schedule
-#undef A_test_dest
-#undef A_test_src
-#undef Ent_accept_message
-#undef Ent_cmdout_cmdout
-#undef Ent_command_complete
-#undef Ent_command_complete_msgin
-#undef Ent_data_transfer
-#undef Ent_datain_to_jump
-#undef Ent_debug_break
-#undef Ent_dsa_code_begin
-#undef Ent_dsa_code_check_reselect
-#undef Ent_dsa_code_fix_jump
-#undef Ent_dsa_code_restore_pointers
-#undef Ent_dsa_code_save_data_pointer
-#undef Ent_dsa_code_template
-#undef Ent_dsa_code_template_end
-#undef Ent_dsa_schedule
-#undef Ent_dsa_zero
-#undef Ent_end_data_transfer
-#undef Ent_initiator_abort
-#undef Ent_msg_in
-#undef Ent_msg_in_restart
-#undef Ent_other_in
-#undef Ent_other_out
-#undef Ent_other_transfer
-#undef Ent_reject_message
-#undef Ent_reselected_check_next
-#undef Ent_reselected_ok
-#undef Ent_respond_message
-#undef Ent_select
-#undef Ent_select_msgout
-#undef Ent_target_abort
-#undef Ent_test_1
-#undef Ent_test_2
-#undef Ent_test_2_msgout
-#undef Ent_wait_reselect
diff --git a/i386/i386at/gpl/linux/scsi/AM53C974.c b/i386/i386at/gpl/linux/scsi/AM53C974.c
deleted file mode 100644
index 5d092c9a..00000000
--- a/i386/i386at/gpl/linux/scsi/AM53C974.c
+++ /dev/null
@@ -1,2249 +0,0 @@
-#include <linux/config.h>
-#include <linux/delay.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/errno.h>
-#include <linux/bios32.h>
-#include <linux/pci.h>
-#include <linux/string.h>
-#include <linux/blk.h>
-
-#include <asm/io.h>
-#include <asm/system.h>
-
-#include "scsi.h"
-#include "hosts.h"
-#include "AM53C974.h"
-#include "constants.h"
-#include "sd.h"
-
-/* AM53/79C974 (PCscsi) driver release 0.5
- *
- * The architecture and much of the code of this device
- * driver was originally developed by Drew Eckhardt for
- * the NCR5380. The following copyrights apply:
- * For the architecture and all pieces of code which can also be found
- * in the NCR5380 device driver:
- * Copyright 1993, Drew Eckhardt
- * Visionary Computing
- * (Unix and Linux consulting and custom programming)
- * drew@colorado.edu
- * +1 (303) 666-5836
- *
- * The AM53C974_nobios_detect code was origininally developed by
- * Robin Cutshaw (robin@xfree86.org) and is used here in a
- * slightly modified form.
- *
- * For the remaining code:
- * Copyright 1994, D. Frieauff
- * EMail: fri@rsx42sun0.dofn.de
- * Phone: x49-7545-8-2256 , x49-7541-42305
- */
-
-/*
- * $Log: AM53C974.c,v $
- * Revision 1.1.1.1 1996/10/30 01:39:58 thomas
- * Imported from UK22
- *
- * Revision 1.1 1996/03/25 20:25:05 goel
- * Linux driver merge.
- *
- */
-
-#ifdef AM53C974_DEBUG
- #define DEB(x) x
- #ifdef AM53C974_DEBUG_KEYWAIT
- #define KEYWAIT() AM53C974_keywait()
- #else
- #define KEYWAIT()
- #endif
- #ifdef AM53C974_DEBUG_INIT
- #define DEB_INIT(x) x
- #else
- #define DEB_INIT(x)
- #endif
- #ifdef AM53C974_DEBUG_MSG
- #define DEB_MSG(x) x
- #else
- #define DEB_MSG(x)
- #endif
- #ifdef AM53C974_DEB_RESEL
- #define DEB_RESEL(x) x
- #else
- #define DEB_RESEL(x)
- #endif
- #ifdef AM53C974_DEBUG_QUEUE
- #define DEB_QUEUE(x) x
- #define LIST(x,y) {printk("LINE:%d Adding %p to %p\n", __LINE__, (void*)(x), (void*)(y)); if ((x)==(y)) udelay(5); }
- #define REMOVE(w,x,y,z) {printk("LINE:%d Removing: %p->%p %p->%p \n", __LINE__, (void*)(w), (void*)(x), (void*)(y), (void*)(z)); if ((x)==(y)) udelay(5); }
- #else
- #define DEB_QUEUE(x)
- #define LIST(x,y)
- #define REMOVE(w,x,y,z)
- #endif
- #ifdef AM53C974_DEBUG_INFO
- #define DEB_INFO(x) x
- #else
- #define DEB_INFO(x)
- #endif
- #ifdef AM53C974_DEBUG_LINKED
- #define DEB_LINKED(x) x
- #else
- #define DEB_LINKED(x)
- #endif
- #ifdef AM53C974_DEBUG_INTR
- #define DEB_INTR(x) x
- #else
- #define DEB_INTR(x)
- #endif
-#else
- #define DEB_INIT(x)
- #define DEB(x)
- #define DEB_QUEUE(x)
- #define LIST(x,y)
- #define REMOVE(w,x,y,z)
- #define DEB_INFO(x)
- #define DEB_LINKED(x)
- #define DEB_INTR(x)
- #define DEB_MSG(x)
- #define DEB_RESEL(x)
- #define KEYWAIT()
-#endif
- #ifdef AM53C974_DEBUG_ABORT
- #define DEB_ABORT(x) x
- #else
- #define DEB_ABORT(x)
- #endif
-
-#ifdef VERBOSE_AM53C974_DEBUG
-#define VDEB(x) x
-#else
-#define VDEB(x)
-#endif
-
-#define INSIDE(x,l,h) ( ((x) >= (l)) && ((x) <= (h)) )
-
-#ifdef AM53C974_DEBUG
-static void AM53C974_print_pci(struct Scsi_Host *instance);
-static void AM53C974_print_phase(struct Scsi_Host *instance);
-static void AM53C974_print_queues(struct Scsi_Host *instance);
-#endif /* AM53C974_DEBUG */
-static void AM53C974_print(struct Scsi_Host *instance);
-static void AM53C974_keywait(void);
-static int AM53C974_bios_detect(Scsi_Host_Template *tpnt);
-static int AM53C974_nobios_detect(Scsi_Host_Template *tpnt);
-static int AM53C974_init(Scsi_Host_Template *tpnt, pci_config_t pci_config);
-static void AM53C974_config_after_reset(struct Scsi_Host *instance);
-static __inline__ void initialize_SCp(Scsi_Cmnd *cmd);
-static __inline__ void run_main(void);
-static void AM53C974_main (void);
-static void AM53C974_intr(int irq, struct pt_regs *regs);
-static void AM53C974_intr_disconnect(struct Scsi_Host *instance);
-static int AM53C974_sync_neg(struct Scsi_Host *instance, int target, unsigned char *msg);
-static __inline__ void AM53C974_set_async(struct Scsi_Host *instance, int target);
-static __inline__ void AM53C974_set_sync(struct Scsi_Host *instance, int target);
-static void AM53C974_information_transfer(struct Scsi_Host *instance,
- unsigned char statreg, unsigned char isreg,
- unsigned char instreg, unsigned char cfifo,
- unsigned char dmastatus);
-static int AM53C974_message(struct Scsi_Host *instance, Scsi_Cmnd *cmd, unsigned char msg);
-static void AM53C974_select(struct Scsi_Host *instance, Scsi_Cmnd *cmd, int tag);
-static void AM53C974_intr_reselect(struct Scsi_Host *instance, unsigned char statreg);
-static __inline__ void AM53C974_transfer_dma(struct Scsi_Host *instance, short dir,
- unsigned long length, char *data);
-static void AM53C974_dma_blast(struct Scsi_Host *instance, unsigned char dmastatus,
- unsigned char statreg);
-static void AM53C974_intr_bus_reset(struct Scsi_Host *instance);
-
-static struct Scsi_Host *first_instance = NULL;
-static Scsi_Host_Template *the_template = NULL;
-static struct Scsi_Host *first_host = NULL; /* Head of list of AMD boards */
-static volatile int main_running = 0;
-static int commandline_current = 0;
-override_t overrides[7] = { {-1, 0, 0, 0}, }; /* LILO overrides */
-
-#ifdef AM53C974_DEBUG
-static int deb_stop = 1;
-
-/**************************************************************************
- * Function : void AM53C974_print_pci(struct Scsi_Host *instance)
- *
- * Purpose : dump the PCI registers for debugging purposes
- *
- * Input : instance - which AM53C974
- **************************************************************************/
-static void AM53C974_print_pci(struct Scsi_Host *instance)
-{
-int i;
-unsigned short vendor_id, device_id, command, status, scratch[8];
-unsigned long class_revision, base;
-unsigned char irq, cache_line_size, latency_timer, header_type;
-
-AM53C974_PCIREG_OPEN();
-
-for (i = 0; i < 8; i++) *(scratch + i) = AM53C974_PCIREG_READ_WORD(instance, PCI_SCRATCH_REG_0 + 2*i);
-vendor_id = AM53C974_PCIREG_READ_WORD(instance, PCI_VENDOR_ID);
-device_id = AM53C974_PCIREG_READ_WORD(instance, PCI_DEVICE_ID);
-command = AM53C974_PCIREG_READ_WORD(instance, PCI_COMMAND);
-status = AM53C974_PCIREG_READ_WORD(instance, PCI_STATUS);
-class_revision = AM53C974_PCIREG_READ_DWORD(instance, PCI_CLASS_REVISION);
-cache_line_size = AM53C974_PCIREG_READ_BYTE(instance, PCI_CACHE_LINE_SIZE);
-latency_timer = AM53C974_PCIREG_READ_BYTE(instance, PCI_LATENCY_TIMER);
-header_type = AM53C974_PCIREG_READ_BYTE(instance, PCI_HEADER_TYPE);
-base = AM53C974_PCIREG_READ_DWORD(instance, PCI_BASE_ADDRESS_0);
-irq = AM53C974_PCIREG_READ_BYTE(instance, PCI_INTERRUPT_LINE);
-
-AM53C974_PCIREG_CLOSE();
-
-
-printk("------------- start of PCI register dump -------------\n");
-printk("PCI_VENDOR_ID: 0x%x\n", vendor_id);
-printk("PCI_DEVICE_ID: 0x%x\n", device_id);
-printk("PCI_COMMAND: 0x%x\n", command);
-printk("PCI_STATUS: 0x%x\n", status);
-printk("PCI_CLASS_REVISION: 0x%lx\n", class_revision);
-printk("PCI_CACHE_LINE_SIZE: 0x%x\n", cache_line_size);
-printk("PCI_LATENCY_TIMER: 0x%x\n", latency_timer);
-printk("PCI_HEADER_TYPE: 0x%x\n", header_type);
-printk("PCI_BASE_ADDRESS_0: 0x%lx\n", base);
-printk("PCI_INTERRUPT_LINE: %d\n", irq);
-for (i = 0; i < 8; i++) printk("PCI_SCRATCH_%d: 0x%x\n", i, scratch[i]);
-printk("------------- end of PCI register dump -------------\n\n");
-}
-
-static struct {
- unsigned char value;
- char *name;
-} phases[] = {
-{PHASE_DATAOUT, "DATAOUT"}, {PHASE_DATAIN, "DATAIN"}, {PHASE_CMDOUT, "CMDOUT"},
-{PHASE_STATIN, "STATIN"}, {PHASE_MSGOUT, "MSGOUT"}, {PHASE_MSGIN, "MSGIN"},
-{PHASE_RES_0, "RESERVED 0"}, {PHASE_RES_1, "RESERVED 1"}};
-
-/**************************************************************************
- * Function : void AM53C974_print_phase(struct Scsi_Host *instance)
- *
- * Purpose : print the current SCSI phase for debugging purposes
- *
- * Input : instance - which AM53C974
- **************************************************************************/
-static void AM53C974_print_phase(struct Scsi_Host *instance)
-{
-AM53C974_local_declare();
-unsigned char statreg, latched;
-int i;
-AM53C974_setio(instance);
-
-latched = (AM53C974_read_8(CNTLREG2)) & CNTLREG2_ENF;
-statreg = AM53C974_read_8(STATREG);
-for (i = 0; (phases[i].value != PHASE_RES_1) &&
- (phases[i].value != (statreg & STATREG_PHASE)); ++i);
-if (latched)
- printk("scsi%d : phase %s, latched at end of last command\n", instance->host_no, phases[i].name);
- else
- printk("scsi%d : phase %s, real time\n", instance->host_no, phases[i].name);
-}
-
-/**************************************************************************
- * Function : void AM53C974_print_queues(struct Scsi_Host *instance)
- *
- * Purpose : print commands in the various queues
- *
- * Inputs : instance - which AM53C974
- **************************************************************************/
-static void AM53C974_print_queues(struct Scsi_Host *instance)
-{
-struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *)instance->hostdata;
-Scsi_Cmnd *ptr;
-
-printk("AM53C974: coroutine is%s running.\n", main_running ? "" : "n't");
-
-cli();
-
-if (!hostdata->connected) {
- printk ("scsi%d: no currently connected command\n", instance->host_no); }
- else {
- print_Scsi_Cmnd ((Scsi_Cmnd *)hostdata->connected); }
-if (!hostdata->sel_cmd) {
- printk ("scsi%d: no currently arbitrating command\n", instance->host_no); }
- else {
- print_Scsi_Cmnd ((Scsi_Cmnd *)hostdata->sel_cmd); }
-
-printk ("scsi%d: issue_queue ", instance->host_no);
-if (!hostdata->issue_queue)
- printk("empty\n");
- else {
- printk(":\n");
- for (ptr = (Scsi_Cmnd *)hostdata->issue_queue; ptr; ptr = (Scsi_Cmnd *)ptr->host_scribble)
- print_Scsi_Cmnd (ptr); }
-
-printk ("scsi%d: disconnected_queue ", instance->host_no);
-if (!hostdata->disconnected_queue)
- printk("empty\n");
- else {
- printk(":\n");
- for (ptr = (Scsi_Cmnd *) hostdata->disconnected_queue; ptr; ptr = (Scsi_Cmnd *)ptr->host_scribble)
- print_Scsi_Cmnd (ptr); }
-
-sti();
-}
-
-#endif /* AM53C974_DEBUG */
-
-/**************************************************************************
- * Function : void AM53C974_print(struct Scsi_Host *instance)
- *
- * Purpose : dump the chip registers for debugging purposes
- *
- * Input : instance - which AM53C974
- **************************************************************************/
-static void AM53C974_print(struct Scsi_Host *instance)
-{
-AM53C974_local_declare();
-unsigned long ctcreg, dmastc, dmaspa, dmawbc, dmawac;
-unsigned char cmdreg, statreg, isreg, cfireg, cntlreg[4], dmacmd, dmastatus;
-AM53C974_setio(instance);
-
-cli();
-ctcreg = AM53C974_read_8(CTCHREG) << 16;
-ctcreg |= AM53C974_read_8(CTCMREG) << 8;
-ctcreg |= AM53C974_read_8(CTCLREG);
-cmdreg = AM53C974_read_8(CMDREG);
-statreg = AM53C974_read_8(STATREG);
-isreg = AM53C974_read_8(ISREG);
-cfireg = AM53C974_read_8(CFIREG);
-cntlreg[0] = AM53C974_read_8(CNTLREG1);
-cntlreg[1] = AM53C974_read_8(CNTLREG2);
-cntlreg[2] = AM53C974_read_8(CNTLREG3);
-cntlreg[3] = AM53C974_read_8(CNTLREG4);
-dmacmd = AM53C974_read_8(DMACMD);
-dmastc = AM53C974_read_32(DMASTC);
-dmaspa = AM53C974_read_32(DMASPA);
-dmawbc = AM53C974_read_32(DMAWBC);
-dmawac = AM53C974_read_32(DMAWAC);
-dmastatus = AM53C974_read_8(DMASTATUS);
-sti();
-
-printk("AM53C974 register dump:\n");
-printk("IO base: 0x%04lx; CTCREG: 0x%04lx; CMDREG: 0x%02x; STATREG: 0x%02x; ISREG: 0x%02x\n",
- io_port, ctcreg, cmdreg, statreg, isreg);
-printk("CFIREG: 0x%02x; CNTLREG1-4: 0x%02x; 0x%02x; 0x%02x; 0x%02x\n",
- cfireg, cntlreg[0], cntlreg[1], cntlreg[2], cntlreg[3]);
-printk("DMACMD: 0x%02x; DMASTC: 0x%04lx; DMASPA: 0x%04lx\n", dmacmd, dmastc, dmaspa);
-printk("DMAWBC: 0x%04lx; DMAWAC: 0x%04lx; DMASTATUS: 0x%02x\n", dmawbc, dmawac, dmastatus);
-printk("---------------------------------------------------------\n");
-}
-
-/**************************************************************************
-* Function : void AM53C974_keywait(void)
-*
-* Purpose : wait until a key is pressed, if it was the 'r' key leave singlestep mode;
-* this function is used for debugging only
-*
-* Input : none
-**************************************************************************/
-static void AM53C974_keywait(void)
-{
-#ifdef AM53C974_DEBUG
-int key;
-
-if (!deb_stop) return;
-#endif
-
-cli();
-while ((inb_p(0x64) & 0x01) != 0x01) ;
-#ifdef AM53C974_DEBUG
-key = inb(0x60);
-if (key == 0x93) deb_stop = 0; /* don't stop if 'r' was pressed */
-#endif
-sti();
-}
-
-/**************************************************************************
-* Function : AM53C974_setup(char *str, int *ints)
-*
-* Purpose : LILO command line initialization of the overrides array,
-*
-* Inputs : str - unused, ints - array of integer parameters with ints[0]
-* equal to the number of ints.
-*
-* NOTE : this function needs to be declared as an external function
-* in init/main.c and included there in the bootsetups list
-***************************************************************************/
-void AM53C974_setup(char *str, int *ints)
-{
-if (ints[0] < 4)
- printk("AM53C974_setup: wrong number of parameters;\n correct syntax is: AM53C974=host-scsi-id, target-scsi-id, max-rate, max-offset\n");
- else {
- if (commandline_current < (sizeof(overrides) / sizeof(override_t))) {
- if ((ints[1] < 0) || (ints[1] > 7) ||
- (ints[2] < 0) || (ints[2] > 7) ||
- (ints[1] == ints[2]) ||
- (ints[3] < (DEF_CLK / MAX_PERIOD)) || (ints[3] > (DEF_CLK / MIN_PERIOD)) ||
- (ints[4] < 0) || (ints[4] > MAX_OFFSET))
- printk("AM53C974_setup: illegal parameter\n");
- else {
- overrides[commandline_current].host_scsi_id = ints[1];
- overrides[commandline_current].target_scsi_id = ints[2];
- overrides[commandline_current].max_rate = ints[3];
- overrides[commandline_current].max_offset = ints[4];
- commandline_current++; }
- }
- else
- printk("AM53C974_setup: too many overrides\n");
- }
-}
-
-#if defined (CONFIG_PCI)
-/**************************************************************************
-* Function : int AM53C974_bios_detect(Scsi_Host_Template *tpnt)
-*
-* Purpose : detects and initializes AM53C974 SCSI chips with PCI Bios
-*
-* Inputs : tpnt - host template
-*
-* Returns : number of host adapters detected
-**************************************************************************/
-int AM53C974_bios_detect(Scsi_Host_Template *tpnt)
-{
-int count = 0; /* number of boards detected */
-int pci_index;
-pci_config_t pci_config;
-
-for (pci_index = 0; pci_index <= 16; ++pci_index) {
- unsigned char pci_bus, pci_device_fn;
- if (pcibios_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_SCSI, pci_index, &pci_bus, &pci_device_fn) != 0)
- break;
-
- pcibios_read_config_word(pci_bus, pci_device_fn, PCI_VENDOR_ID, &pci_config._vendor);
- pcibios_read_config_word(pci_bus, pci_device_fn, PCI_DEVICE_ID, &pci_config._device);
- pcibios_read_config_word(pci_bus, pci_device_fn, PCI_COMMAND, &pci_config._command);
- pcibios_read_config_word(pci_bus, pci_device_fn, PCI_STATUS, &pci_config._status);
- pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_CLASS_REVISION, &pci_config._class_revision);
- pcibios_read_config_byte(pci_bus, pci_device_fn, PCI_CACHE_LINE_SIZE, &pci_config._cache_line_size);
- pcibios_read_config_byte(pci_bus, pci_device_fn, PCI_LATENCY_TIMER, &pci_config._latency_timer);
- pcibios_read_config_byte(pci_bus, pci_device_fn, PCI_HEADER_TYPE, &pci_config._header_type);
- pcibios_read_config_byte(pci_bus, pci_device_fn, PCI_BIST, &pci_config._bist);
- pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_BASE_ADDRESS_0, &pci_config._base0);
- pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_BASE_ADDRESS_1, &pci_config._base1);
- pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_BASE_ADDRESS_2, &pci_config._base2);
- pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_BASE_ADDRESS_3, &pci_config._base3);
- pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_BASE_ADDRESS_4, &pci_config._base4);
- pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_BASE_ADDRESS_5, &pci_config._base5);
- pcibios_read_config_dword(pci_bus, pci_device_fn, PCI_ROM_ADDRESS, &pci_config._baserom);
- pcibios_read_config_byte(pci_bus, pci_device_fn, PCI_INTERRUPT_LINE, &pci_config._int_line);
- pcibios_read_config_byte(pci_bus, pci_device_fn, PCI_INTERRUPT_PIN, &pci_config._int_pin);
- pcibios_read_config_byte(pci_bus, pci_device_fn, PCI_MIN_GNT, &pci_config._min_gnt);
- pcibios_read_config_byte(pci_bus, pci_device_fn, PCI_MAX_LAT, &pci_config._max_lat);
- pci_config._pcibus = 0xFFFFFFFF;
- pci_config._cardnum = 0xFFFFFFFF;
-
- /* check whether device is I/O mapped -- should be */
- if (!(pci_config._command & PCI_COMMAND_IO)) continue;
-
- /* PCI Spec 2.1 states that it is either the driver's or the PCI card's responsibility
- to set the PCI Master Enable Bit if needed.
- (from Mark Stockton <marks@schooner.sys.hou.compaq.com>) */
- if (!(pci_config._command & PCI_COMMAND_MASTER)) {
- pci_config._command |= PCI_COMMAND_MASTER;
- printk("PCI Master Bit has not been set. Setting...\n");
- pcibios_write_config_word(pci_bus, pci_device_fn, PCI_COMMAND, pci_config._command); }
-
- /* everything seems OK now, so initialize */
- if (AM53C974_init(tpnt, pci_config)) count++ ;
- }
-return (count);
-}
-#endif
-
-/**************************************************************************
-* Function : int AM53C974_nobios_detect(Scsi_Host_Template *tpnt)
-*
-* Purpose : detects and initializes AM53C974 SCSI chips using PCI config 2
-*
-* Inputs : tpnt - host template
-*
-* Returns : number of host adapters detected
-*
-* NOTE : This code assumes the controller on PCI bus 0.
-*
-* Origin: Robin Cutshaw (robin@xfree86.org)
-**************************************************************************/
-int AM53C974_nobios_detect(Scsi_Host_Template *tpnt)
-{
-int count = 0; /* number of boards detected */
-pci_config_t pci_config;
-
-/* first try PCI config method 1 */
-for (pci_config._pcibus = 0; pci_config._pcibus < 0x10; pci_config._pcibus++) {
- for (pci_config._cardnum = 0; pci_config._cardnum < 0x20; pci_config._cardnum++) {
- unsigned long config_cmd;
- config_cmd = 0x80000000 | (pci_config._pcibus<<16) | (pci_config._cardnum<<11);
-
- outl(config_cmd, 0xCF8); /* ioreg 0 */
- pci_config._device_vendor = inl(0xCFC);
-
- if ((pci_config._vendor == PCI_VENDOR_ID_AMD) && (pci_config._device == PCI_DEVICE_ID_AMD_SCSI)) {
- outl(config_cmd | PCI_COMMAND, 0xCF8); pci_config._status_command = inl(0xCFC);
- outl(config_cmd | PCI_CLASS_REVISION, 0xCF8); pci_config._class_revision = inl(0xCFC);
- outl(config_cmd | PCI_CACHE_LINE_SIZE, 0xCF8); pci_config._bist_header_latency_cache = inl(0xCFC);
- outl(config_cmd | PCI_BASE_ADDRESS_0, 0xCF8); pci_config._base0 = inl(0xCFC);
- outl(config_cmd | PCI_BASE_ADDRESS_1, 0xCF8); pci_config._base1 = inl(0xCFC);
- outl(config_cmd | PCI_BASE_ADDRESS_2, 0xCF8); pci_config._base2 = inl(0xCFC);
- outl(config_cmd | PCI_BASE_ADDRESS_3, 0xCF8); pci_config._base3 = inl(0xCFC);
- outl(config_cmd | PCI_BASE_ADDRESS_4, 0xCF8); pci_config._base4 = inl(0xCFC);
- outl(config_cmd | PCI_BASE_ADDRESS_5, 0xCF8); pci_config._base5 = inl(0xCFC);
- outl(config_cmd | PCI_ROM_ADDRESS, 0xCF8); pci_config._baserom = inl(0xCFC);
- outl(config_cmd | PCI_INTERRUPT_LINE, 0xCF8); pci_config._max_min_ipin_iline = inl(0xCFC);
-
- /* check whether device is I/O mapped -- should be */
- if (!(pci_config._command & PCI_COMMAND_IO)) continue;
-
- /* PCI Spec 2.1 states that it is either the driver's or the PCI card's responsibility
- to set the PCI Master Enable Bit if needed.
- From Mark Stockton <marks@schooner.sys.hou.compaq.com> */
- if (!(pci_config._command & PCI_COMMAND_MASTER)) {
- pci_config._command |= PCI_COMMAND_MASTER;
- printk("Config 1; PCI Master Bit has not been set. Setting...\n");
- outl(config_cmd | PCI_COMMAND, 0xCF8); outw(pci_config._command, 0xCFC); }
-
- /* everything seems OK now, so initialize */
- if (AM53C974_init(tpnt, pci_config)) count++ ;
- }
- }
- }
-outb(0, 0xCF8); /* is this really necessary? */
-
-/* try PCI config method 2, if no device was detected by method 1 */
-if (!count) {
- AM53C974_PCIREG_OPEN();
-
- pci_config._pcibus = 0xFFFFFFFF;
- pci_config._cardnum = 0xFFFFFFFF;
-
- for (pci_config._ioaddr = 0xC000; pci_config._ioaddr < 0xD000; pci_config._ioaddr += 0x0100) {
- pci_config._device_vendor = inl(pci_config._ioaddr);
-
- if ((pci_config._vendor == PCI_VENDOR_ID_AMD) && (pci_config._device == PCI_DEVICE_ID_AMD_SCSI)) {
- pci_config._status_command = inl(pci_config._ioaddr + PCI_COMMAND);
- pci_config._class_revision = inl(pci_config._ioaddr + PCI_CLASS_REVISION);
- pci_config._bist_header_latency_cache = inl(pci_config._ioaddr + PCI_CACHE_LINE_SIZE);
- pci_config._base0 = inl(pci_config._ioaddr + PCI_BASE_ADDRESS_0);
- pci_config._base1 = inl(pci_config._ioaddr + PCI_BASE_ADDRESS_1);
- pci_config._base2 = inl(pci_config._ioaddr + PCI_BASE_ADDRESS_2);
- pci_config._base3 = inl(pci_config._ioaddr + PCI_BASE_ADDRESS_3);
- pci_config._base4 = inl(pci_config._ioaddr + PCI_BASE_ADDRESS_4);
- pci_config._base5 = inl(pci_config._ioaddr + PCI_BASE_ADDRESS_5);
- pci_config._baserom = inl(pci_config._ioaddr + PCI_ROM_ADDRESS);
- pci_config._max_min_ipin_iline = inl(pci_config._ioaddr + PCI_INTERRUPT_LINE);
-
- /* check whether device is I/O mapped -- should be */
- if (!(pci_config._command & PCI_COMMAND_IO)) continue;
-
- /* PCI Spec 2.1 states that it is either the driver's or the PCI card's responsibility
- to set the PCI Master Enable Bit if needed.
- From Mark Stockton <marks@schooner.sys.hou.compaq.com> */
- if (!(pci_config._command & PCI_COMMAND_MASTER)) {
- pci_config._command |= PCI_COMMAND_MASTER;
- printk("Config 2; PCI Master Bit has not been set. Setting...\n");
- outw(pci_config._command, pci_config._ioaddr + PCI_COMMAND); }
-
- /* everything seems OK now, so initialize */
- if (AM53C974_init(tpnt, pci_config)) count++ ;
- }
- }
- AM53C974_PCIREG_CLOSE();
- }
-
-return(count);
-}
-
-/**************************************************************************
-* Function : int AM53C974_detect(Scsi_Host_Template *tpnt)
-*
-* Purpose : detects and initializes AM53C974 SCSI chips
-*
-* Inputs : tpnt - host template
-*
-* Returns : number of host adapters detected
-**************************************************************************/
-int AM53C974_detect(Scsi_Host_Template *tpnt)
-{
-int count; /* number of boards detected */
-
-#if defined (CONFIG_PCI)
-if (pcibios_present())
- count = AM53C974_bios_detect(tpnt);
- else
-#endif
-count = AM53C974_nobios_detect(tpnt);
-return (count);
-}
-
-/**************************************************************************
-* Function : int AM53C974_init(Scsi_Host_Template *tpnt, pci_config_t pci_config)
-*
-* Purpose : initializes instance and corresponding AM53/79C974 chip,
-*
-* Inputs : tpnt - template, pci_config - PCI configuration,
-*
-* Returns : 1 on success, 0 on failure.
-*
-* NOTE: If no override for the controller's SCSI id is given and AM53C974_SCSI_ID
-* is not defined we assume that the SCSI address of this controller is correctly
-* set up by the BIOS (as reflected by contents of register CNTLREG1).
-* This is the only BIOS assistance we need.
-**************************************************************************/
-static int AM53C974_init(Scsi_Host_Template *tpnt, pci_config_t pci_config)
-{
-AM53C974_local_declare();
-int i, j;
-struct Scsi_Host *instance, *search;
-struct AM53C974_hostdata *hostdata;
-
-#ifdef AM53C974_OPTION_DEBUG_PROBE_ONLY
- printk ("AM53C974: probe only enabled, aborting initialization\n");
- return -1;
-#endif
-
-instance = scsi_register(tpnt, sizeof(struct AM53C974_hostdata));
-hostdata = (struct AM53C974_hostdata *)instance->hostdata;
-instance->base = NULL;
-instance->io_port = pci_config._base0 & (pci_config._base0 & 0x1 ?
- 0xFFFFFFFC : 0xFFFFFFF0);
-instance->irq = pci_config._int_line;
-instance->dma_channel = -1;
-AM53C974_setio(instance);
-
-#ifdef AM53C974_SCSI_ID
-instance->this_id = AM53C974_SCSI_ID;
-AM53C974_write_8(CNTLREG1, instance->this_id & CNTLREG1_SID);
-#else
-instance->this_id = AM53C974_read_8(CNTLREG1) & CNTLREG1_SID;
-if (instance->this_id != 7)
- printk("scsi%d: WARNING: unusual hostadapter SCSI id %d; please verify!\n",
- instance->host_no, instance->this_id);
-#endif
-
-for (i = 0; i < sizeof(hostdata->msgout); i++) {
- hostdata->msgout[i] = NOP;
- hostdata->last_message[i] = NOP; }
-for (i = 0; i < 8; i++) {
- hostdata->busy[i] = 0;
- hostdata->sync_per[i] = DEF_STP;
- hostdata->sync_off[i] = 0;
- hostdata->sync_neg[i] = 0;
- hostdata->sync_en[i] = DEFAULT_SYNC_NEGOTIATION_ENABLED;
- hostdata->max_rate[i] = DEFAULT_RATE;
- hostdata->max_offset[i] = DEFAULT_SYNC_OFFSET; }
-
-/* overwrite defaults by LILO overrides */
-for (i = 0; i < commandline_current; i++) {
- if (overrides[i].host_scsi_id == instance->this_id) {
- j = overrides[i].target_scsi_id;
- hostdata->sync_en[j] = 1;
- hostdata->max_rate[j] = overrides[i].max_rate;
- hostdata->max_offset[j] = overrides[i].max_offset;
- }
- }
-
-hostdata->sel_cmd = NULL;
-hostdata->connected = NULL;
-hostdata->issue_queue = NULL;
-hostdata->disconnected_queue = NULL;
-hostdata->in_reset = 0;
-hostdata->aborted = 0;
-hostdata->selecting = 0;
-hostdata->disconnecting = 0;
-hostdata->dma_busy = 0;
-
-/* Set up an interrupt handler if we aren't already sharing an IRQ with another board */
-for (search = first_host;
- search && ( ((the_template != NULL) && (search->hostt != the_template)) ||
- (search->irq != instance->irq) || (search == instance) );
- search = search->next);
-if (!search) {
- if (request_irq(instance->irq, AM53C974_intr, SA_INTERRUPT, "AM53C974")) {
- printk("scsi%d: IRQ%d not free, detaching\n", instance->host_no, instance->irq);
- scsi_unregister(instance);
- return -1; }
- }
- else {
- printk("scsi%d: using interrupt handler previously installed for scsi%d\n",
- instance->host_no, search->host_no); }
-
-if (!the_template) {
- the_template = instance->hostt;
- first_instance = instance; }
-
-/* do hard reset */
-AM53C974_write_8(CMDREG, CMDREG_RDEV); /* reset device */
-udelay(5);
-AM53C974_write_8(CMDREG, CMDREG_NOP);
-AM53C974_write_8(CNTLREG1, CNTLREG1_DISR | instance->this_id);
-AM53C974_write_8(CMDREG, CMDREG_RBUS); /* reset SCSI bus */
-udelay(10);
-AM53C974_config_after_reset(instance);
-
-return(0);
-}
-
-/*********************************************************************
-* Function : AM53C974_config_after_reset(struct Scsi_Host *instance) *
-* *
-* Purpose : initializes chip registers after reset *
-* *
-* Inputs : instance - which AM53C974 *
-* *
-* Returns : nothing *
-**********************************************************************/
-static void AM53C974_config_after_reset(struct Scsi_Host *instance)
-{
-AM53C974_local_declare();
-AM53C974_setio(instance);
-
-/* clear SCSI FIFO */
-AM53C974_write_8(CMDREG, CMDREG_CFIFO);
-
-/* configure device */
-AM53C974_write_8(STIMREG, DEF_SCSI_TIMEOUT);
-AM53C974_write_8(STPREG, DEF_STP & STPREG_STP);
-AM53C974_write_8(SOFREG, (DEF_SOF_RAD<<6) | (DEF_SOF_RAA<<4));
-AM53C974_write_8(CLKFREG, DEF_CLKF & CLKFREG_MASK);
-AM53C974_write_8(CNTLREG1, (DEF_ETM<<7) | CNTLREG1_DISR | (DEF_PERE<<4) | instance->this_id);
-AM53C974_write_8(CNTLREG2, (DEF_ENF<<6));
-AM53C974_write_8(CNTLREG3, (DEF_ADIDCHK<<7) | (DEF_FASTSCSI<<4) | (DEF_FASTCLK<<3));
-AM53C974_write_8(CNTLREG4, (DEF_GLITCH<<6) | (DEF_PWD<<5) | (DEF_RAE<<3) | (DEF_RADE<<2) | CNTLREG4_RES);
-}
-
-/***********************************************************************
-* Function : const char *AM53C974_info(struct Scsi_Host *instance) *
-* *
-* Purpose : return device driver information *
-* *
-* Inputs : instance - which AM53C974 *
-* *
-* Returns : info string *
-************************************************************************/
-const char *AM53C974_info(struct Scsi_Host *instance)
-{
-static char info[100];
-
-sprintf(info, "AM53/79C974 PCscsi driver rev. %d.%d; host I/O address: 0x%x; irq: %d\n",
- AM53C974_DRIVER_REVISION_MAJOR, AM53C974_DRIVER_REVISION_MINOR,
- instance->io_port, instance->irq);
-return (info);
-}
-
-/**************************************************************************
-* Function : int AM53C974_command (Scsi_Cmnd *SCpnt) *
-* *
-* Purpose : the unqueued SCSI command function, replaced by the *
-* AM53C974_queue_command function *
-* *
-* Inputs : SCpnt - pointer to command structure *
-* *
-* Returns :status, see hosts.h for details *
-***************************************************************************/
-int AM53C974_command(Scsi_Cmnd *SCpnt)
-{
-DEB(printk("AM53C974_command called\n"));
-return 0;
-}
-
-/**************************************************************************
-* Function : void initialize_SCp(Scsi_Cmnd *cmd) *
-* *
-* Purpose : initialize the saved data pointers for cmd to point to the *
-* start of the buffer. *
-* *
-* Inputs : cmd - Scsi_Cmnd structure to have pointers reset. *
-* *
-* Returns : nothing *
-**************************************************************************/
-static __inline__ void initialize_SCp(Scsi_Cmnd *cmd)
-{
-if (cmd->use_sg) {
- cmd->SCp.buffer = (struct scatterlist *)cmd->buffer;
- cmd->SCp.buffers_residual = cmd->use_sg - 1;
- cmd->SCp.ptr = (char *)cmd->SCp.buffer->address;
- cmd->SCp.this_residual = cmd->SCp.buffer->length; }
- else {
- cmd->SCp.buffer = NULL;
- cmd->SCp.buffers_residual = 0;
- cmd->SCp.ptr = (char *)cmd->request_buffer;
- cmd->SCp.this_residual = cmd->request_bufflen; }
-}
-
-/**************************************************************************
-* Function : run_main(void) *
-* *
-* Purpose : insure that the coroutine is running and will process our *
-* request. main_running is checked/set here (in an inline *
-* function rather than in AM53C974_main itself to reduce the *
-* chances of stack overflow. *
-* *
-* *
-* Inputs : none *
-* *
-* Returns : nothing *
-**************************************************************************/
-static __inline__ void run_main(void)
-{
-cli();
-if (!main_running) {
- /* main_running is cleared in AM53C974_main once it can't do
- more work, and AM53C974_main exits with interrupts disabled. */
- main_running = 1;
- AM53C974_main();
- sti(); }
- else
- sti();
-}
-
-/**************************************************************************
-* Function : int AM53C974_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
-*
-* Purpose : writes SCSI command into AM53C974 FIFO
-*
-* Inputs : cmd - SCSI command, done - function called on completion, with
-* a pointer to the command descriptor.
-*
-* Returns : status, see hosts.h for details
-*
-* Side effects :
-* cmd is added to the per instance issue_queue, with minor
-* twiddling done to the host specific fields of cmd. If the
-* main coroutine is not running, it is restarted.
-**************************************************************************/
-int AM53C974_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
-{
-struct Scsi_Host *instance = cmd->host;
-struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *)instance->hostdata;
-Scsi_Cmnd *tmp;
-
-cli();
-DEB_QUEUE(printk(SEPARATOR_LINE));
-DEB_QUEUE(printk("scsi%d: AM53C974_queue_command called\n", instance->host_no));
-DEB_QUEUE(printk("cmd=%02x target=%02x lun=%02x bufflen=%d use_sg = %02x\n",
- cmd->cmnd[0], cmd->target, cmd->lun, cmd->request_bufflen, cmd->use_sg));
-
-/* We use the host_scribble field as a pointer to the next command in a queue */
-cmd->host_scribble = NULL;
-cmd->scsi_done = done;
-cmd->result = 0;
-cmd->device->disconnect = 0;
-
-/* Insert the cmd into the issue queue. Note that REQUEST SENSE
- * commands are added to the head of the queue since any command will
- * clear the contingent allegiance condition that exists and the
- * sense data is only guaranteed to be valid while the condition exists. */
-if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) {
- LIST(cmd, hostdata->issue_queue);
- cmd->host_scribble = (unsigned char *)hostdata->issue_queue;
- hostdata->issue_queue = cmd; }
- else {
- for (tmp = (Scsi_Cmnd *)hostdata->issue_queue; tmp->host_scribble;
- tmp = (Scsi_Cmnd *)tmp->host_scribble);
- LIST(cmd, tmp);
- tmp->host_scribble = (unsigned char *)cmd; }
-
-DEB_QUEUE(printk("scsi%d : command added to %s of queue\n", instance->host_no,
- (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail"));
-
-/* Run the coroutine if it isn't already running. */
-run_main();
-return 0;
-}
-
-/**************************************************************************
- * Function : AM53C974_main (void)
- *
- * Purpose : AM53C974_main is a coroutine that runs as long as more work can
- * be done on the AM53C974 host adapters in a system. Both
- * AM53C974_queue_command() and AM53C974_intr() will try to start it
- * in case it is not running.
- *
- * NOTE : AM53C974_main exits with interrupts *disabled*, the caller should
- * reenable them. This prevents reentrancy and kernel stack overflow.
- **************************************************************************/
-static void AM53C974_main(void)
-{
-AM53C974_local_declare();
-Scsi_Cmnd *tmp, *prev;
-struct Scsi_Host *instance;
-struct AM53C974_hostdata *hostdata;
-int done;
-
-/* We run (with interrupts disabled) until we're sure that none of
- * the host adapters have anything that can be done, at which point
- * we set main_running to 0 and exit. */
-
-do {
- cli(); /* Freeze request queues */
- done = 1;
- for (instance = first_instance; instance && instance->hostt == the_template;
- instance = instance->next) {
- hostdata = (struct AM53C974_hostdata *)instance->hostdata;
- AM53C974_setio(instance);
- /* start to select target if we are not connected and not in the
- selection process */
- if (!hostdata->connected && !hostdata->sel_cmd) {
- /* Search through the issue_queue for a command destined for a target
- that is not busy. */
- for (tmp = (Scsi_Cmnd *)hostdata->issue_queue, prev = NULL; tmp;
- prev = tmp, tmp = (Scsi_Cmnd *)tmp->host_scribble) {
- /* When we find one, remove it from the issue queue. */
- if (!(hostdata->busy[tmp->target] & (1 << tmp->lun))) {
- if (prev) {
- REMOVE(prev, (Scsi_Cmnd *)(prev->host_scribble), tmp,
- (Scsi_Cmnd *)(tmp->host_scribble));
- prev->host_scribble = tmp->host_scribble; }
- else {
- REMOVE(-1, hostdata->issue_queue, tmp, tmp->host_scribble);
- hostdata->issue_queue = (Scsi_Cmnd *)tmp->host_scribble; }
- tmp->host_scribble = NULL;
-
- /* go into selection mode, disable reselection and wait for
- SO interrupt which will continue with the selection process */
- hostdata->selecting = 1;
- hostdata->sel_cmd = tmp;
- AM53C974_write_8(CMDREG, CMDREG_DSR);
- break;
- } /* if target/lun is not busy */
-
- } /* for */
- } /* if (!hostdata->connected) */
- else {
- DEB(printk("main: connected; cmd = 0x%lx, sel_cmd = 0x%lx\n",
- (long)hostdata->connected, (long)hostdata->sel_cmd));
- }
- } /* for instance */
- } while (!done);
-main_running = 0;
-}
-
-/*********************************************************************
-* Function : AM53C974_intr(int irq, struct pt_regs *regs) *
-* *
-* Purpose : interrupt handler *
-* *
-* Inputs : irq - interrupt line, regs - ? *
-* *
-* Returns : nothing *
-**********************************************************************/
-static void AM53C974_intr(int irq, struct pt_regs *regs)
-{
-AM53C974_local_declare();
-struct Scsi_Host *instance;
-struct AM53C974_hostdata *hostdata;
-unsigned char cmdreg, dmastatus, statreg, isreg, instreg, cfifo;
-
-/* find AM53C974 hostadapter responsible for this interrupt */
-for (instance = first_instance; instance; instance = instance->next)
- if ((instance->irq == irq) && (instance->hostt == the_template)) goto FOUND;
-sti();
-return;
-
-/* found; now decode and process */
-FOUND:
-hostdata = (struct AM53C974_hostdata *)instance->hostdata;
-AM53C974_setio(instance);
-dmastatus = AM53C974_read_8(DMASTATUS);
-
-DEB_INTR(printk(SEPARATOR_LINE));
-DEB_INTR(printk("AM53C974 interrupt; dmastatus=0x%02x\n", dmastatus));
-KEYWAIT();
-
-/*** DMA related interrupts ***/
-if (hostdata->connected && (dmastatus & (DMASTATUS_ERROR | DMASTATUS_PWDN |
- DMASTATUS_ABORT))) {
- /* DMA error or POWERDOWN */
- printk("scsi%d: DMA error or powerdown; dmastatus: 0x%02x\n",
- instance->host_no, dmastatus);
-#ifdef AM53C974_DEBUG
- deb_stop = 1;
-#endif
- panic("scsi%d: cannot recover\n", instance->host_no); }
-
-if (hostdata->connected && (dmastatus & DMASTATUS_DONE)) {
- /* DMA transfer done */
- unsigned long residual;
- cli();
- if (!(AM53C974_read_8(DMACMD) & DMACMD_DIR)) {
- do {
- dmastatus = AM53C974_read_8(DMASTATUS);
- residual = AM53C974_read_8(CTCLREG) | (AM53C974_read_8(CTCMREG) << 8) |
- (AM53C974_read_8(CTCHREG) << 16);
- residual += AM53C974_read_8(CFIREG) & CFIREG_CF;
- } while (!(dmastatus & DMASTATUS_SCSIINT) && residual);
- residual = AM53C974_read_8(CTCLREG) | (AM53C974_read_8(CTCMREG) << 8) |
- (AM53C974_read_8(CTCHREG) << 16);
- residual += AM53C974_read_8(CFIREG) & CFIREG_CF;
- }
- else
- residual = 0;
- hostdata->connected->SCp.ptr += hostdata->connected->SCp.this_residual - residual;
- hostdata->connected->SCp.this_residual = residual;
-
- AM53C974_write_8(DMACMD, DMACMD_IDLE);
-
- /* if service request missed before, process it now (ugly) */
- if (hostdata->dma_busy) {
- hostdata->dma_busy = 0;
- cmdreg = AM53C974_read_8(CMDREG);
- statreg = AM53C974_read_8(STATREG);
- isreg = AM53C974_read_8(ISREG);
- instreg = AM53C974_read_8(INSTREG);
- cfifo = AM53C974_cfifo();
- AM53C974_information_transfer(instance, statreg, isreg, instreg, cfifo,
- dmastatus); }
- sti();
- }
-
-if (!(dmastatus & DMASTATUS_SCSIINT)) {
- sti();
- return; }
-
-/*** SCSI related interrupts ***/
-cmdreg = AM53C974_read_8(CMDREG);
-statreg = AM53C974_read_8(STATREG);
-isreg = AM53C974_read_8(ISREG);
-instreg = AM53C974_read_8(INSTREG);
-cfifo = AM53C974_cfifo();
-
-DEB_INTR(printk("scsi%d: statreg: 0x%02x; isreg: 0x%02x; instreg: 0x%02x; cfifo: 0x%02x\n",
- instance->host_no, statreg, isreg, instreg, cfifo));
-
-if (statreg & STATREG_PE) {
- /* parity error */
-#ifdef AM53C974_DEBUG
- deb_stop = 1;
-#endif
- printk("scsi%d : PARITY error\n", instance->host_no);
- if (hostdata->connected) hostdata->sync_off[hostdata->connected->target] = 0; /* setup asynchronous transfer */
- hostdata->aborted = 1; }
-
-if (statreg & STATREG_IOE) {
- /* illegal operation error */
-#ifdef AM53C974_DEBUG
- deb_stop = 1;
-#endif
- printk("scsi%d : ILLEGAL OPERATION error\n", instance->host_no);
- printk("cmdreg: 0x%02x; dmacmd: 0x%02x; statreg: 0x%02x; \n"
- "isreg: 0x%02x; instreg: 0x%02x; cfifo: 0x%02x\n",
- cmdreg, AM53C974_read_8(DMACMD), statreg, isreg, instreg, cfifo); }
-if (hostdata->in_reset && (instreg & INSTREG_SRST)) {
- /* RESET INTERRUPT */
-#ifdef AM53C974_DEBUG
- deb_stop = 1;
-#endif
- DEB(printk("Bus reset interrupt received\n"));
- AM53C974_intr_bus_reset(instance);
- cli();
- if (hostdata->connected) {
- hostdata->connected->result = DID_RESET << 16;
- hostdata->connected->scsi_done((Scsi_Cmnd *)hostdata->connected);
- hostdata->connected = NULL; }
- else {
- if (hostdata->sel_cmd) {
- hostdata->sel_cmd->result = DID_RESET << 16;
- hostdata->sel_cmd->scsi_done((Scsi_Cmnd *)hostdata->sel_cmd);
- hostdata->sel_cmd = NULL; }
- }
- sti();
- if (hostdata->in_reset == 1) goto EXIT;
- else return;
- }
-
-if (instreg & INSTREG_ICMD) {
- /* INVALID COMMAND INTERRUPT */
-#ifdef AM53C974_DEBUG
- deb_stop = 1;
-#endif
- printk("scsi%d: Invalid command interrupt\n", instance->host_no);
- printk("cmdreg: 0x%02x; dmacmd: 0x%02x; statreg: 0x%02x; dmastatus: 0x%02x; \n"
- "isreg: 0x%02x; instreg: 0x%02x; cfifo: 0x%02x\n",
- cmdreg, AM53C974_read_8(DMACMD), statreg, dmastatus, isreg, instreg, cfifo);
- panic("scsi%d: cannot recover\n", instance->host_no); }
-
-if (instreg & INSTREG_DIS) {
- /* DISCONNECT INTERRUPT */
- DEB_INTR(printk("Disconnect interrupt received; "));
- cli();
- AM53C974_intr_disconnect(instance);
- sti();
- goto EXIT; }
-
-if (instreg & INSTREG_RESEL) {
- /* RESELECTION INTERRUPT */
- DEB_INTR(printk("Reselection interrupt received\n"));
- cli();
- AM53C974_intr_reselect(instance, statreg);
- sti();
- goto EXIT; }
-
-if (instreg & INSTREG_SO) {
- DEB_INTR(printk("Successful operation interrupt received\n"));
- if (hostdata->selecting) {
- DEB_INTR(printk("DSR completed, starting select\n"));
- cli();
- AM53C974_select(instance, (Scsi_Cmnd *)hostdata->sel_cmd,
- (hostdata->sel_cmd->cmnd[0] == REQUEST_SENSE) ?
- TAG_NONE : TAG_NEXT);
- hostdata->selecting = 0;
- AM53C974_set_sync(instance, hostdata->sel_cmd->target);
- sti();
- return; }
-
- if (hostdata->sel_cmd != NULL) {
- if ( ((isreg & ISREG_IS) != ISREG_OK_NO_STOP) &&
- ((isreg & ISREG_IS) != ISREG_OK_STOP) ) {
- /* UNSUCCESSFUL SELECTION */
- DEB_INTR(printk("unsuccessful selection\n"));
- cli();
- hostdata->dma_busy = 0;
- LIST(hostdata->sel_cmd, hostdata->issue_queue);
- hostdata->sel_cmd->host_scribble = (unsigned char *)hostdata->issue_queue;
- hostdata->issue_queue = hostdata->sel_cmd;
- hostdata->sel_cmd = NULL;
- hostdata->selecting = 0;
- sti();
- goto EXIT; }
- else {
- /* SUCCESSFUL SELECTION */
- DEB(printk("successful selection; cmd=0x%02lx\n", (long)hostdata->sel_cmd));
- cli();
- hostdata->dma_busy = 0;
- hostdata->disconnecting = 0;
- hostdata->connected = hostdata->sel_cmd;
- hostdata->sel_cmd = NULL;
- hostdata->selecting = 0;
-#ifdef SCSI2
- if (!hostdata->connected->device->tagged_queue)
-#endif
- hostdata->busy[hostdata->connected->target] |= (1 << hostdata->connected->lun);
- /* very strange -- use_sg is sometimes nonzero for request sense commands !! */
- if ((hostdata->connected->cmnd[0] == REQUEST_SENSE) && hostdata->connected->use_sg) {
- DEB(printk("scsi%d: REQUEST_SENSE command with nonzero use_sg\n", instance->host_no));
- KEYWAIT();
- hostdata->connected->use_sg = 0; }
- initialize_SCp((Scsi_Cmnd *)hostdata->connected);
- hostdata->connected->SCp.phase = PHASE_CMDOUT;
- AM53C974_information_transfer(instance, statreg, isreg, instreg, cfifo, dmastatus);
- sti();
- return; }
- }
- else {
- cli();
- AM53C974_information_transfer(instance, statreg, isreg, instreg, cfifo, dmastatus);
- sti();
- return; }
- }
-
-if (instreg & INSTREG_SR) {
- DEB_INTR(printk("Service request interrupt received, "));
- if (hostdata->connected) {
- DEB_INTR(printk("calling information_transfer\n"));
- cli();
- AM53C974_information_transfer(instance, statreg, isreg, instreg, cfifo, dmastatus);
- sti(); }
- else {
- printk("scsi%d: weird: service request when no command connected\n", instance->host_no);
- AM53C974_write_8(CMDREG, CMDREG_CFIFO); } /* clear FIFO */
- return;
- }
-
-EXIT:
- DEB_INTR(printk("intr: starting main\n"));
- run_main();
- DEB_INTR(printk("end of intr\n"));
-}
-
-/**************************************************************************
-* Function : AM53C974_intr_disconnect(struct Scsi_Host *instance)
-*
-* Purpose : manage target disconnection
-*
-* Inputs : instance -- which AM53C974
-*
-* Returns : nothing
-**************************************************************************/
-static void AM53C974_intr_disconnect(struct Scsi_Host *instance)
-{
-AM53C974_local_declare();
-struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *)instance->hostdata;
-Scsi_Cmnd *cmd;
-AM53C974_setio(instance);
-
-if (hostdata->sel_cmd != NULL) {
- /* normal selection timeout, typical for nonexisting targets */
- cmd = (Scsi_Cmnd *)hostdata->sel_cmd;
- DEB_INTR(printk("bad target\n"));
- cmd->result = DID_BAD_TARGET << 16;
- goto EXIT_FINISHED; }
-
-if (!hostdata->connected) {
- /* can happen if controller was reset, a device tried to reconnect,
- failed and disconnects now */
- AM53C974_write_8(CMDREG, CMDREG_CFIFO);
- return; }
-
-if (hostdata->disconnecting) {
- /* target sent disconnect message, so we are prepared */
- cmd = (Scsi_Cmnd *)hostdata->connected;
- AM53C974_set_async(instance, cmd->target);
- DEB_INTR(printk("scsi%d : disc. from cmnd %d for ta %d, lun %d\n",
- instance->host_no, cmd->cmnd[0], cmd->target, cmd->lun));
- if (cmd->device->disconnect) {
- /* target wants to reselect later */
- DEB_INTR(printk("ok, re-enabling selection\n"));
- LIST(cmd,hostdata->disconnected_queue);
- cmd->host_scribble = (unsigned char *)hostdata->disconnected_queue;
- hostdata->disconnected_queue = cmd;
- DEB_QUEUE(printk("scsi%d : command for target %d lun %d this %d was moved from connected to"
- " the disconnected_queue\n", instance->host_no, cmd->target,
- cmd->lun, hostdata->disconnected_queue->SCp.this_residual));
- DEB_QUEUE(AM53C974_print_queues(instance));
- goto EXIT_UNFINISHED; }
- else {
- /* target does not want to reselect later, we are really finished */
-#ifdef AM53C974_DEBUG
- if (cmd->cmnd[0] == REQUEST_SENSE) {
- int i;
- printk("Request sense data dump:\n");
- for (i = 0; i < cmd->request_bufflen; i++) {
- printk("%02x ", *((char *)(cmd->request_buffer) + i));
- if (i && !(i % 16)) printk("\n"); }
- printk("\n"); }
-#endif
- goto EXIT_FINISHED; } /* !cmd->device->disconnect */
- } /* if (hostdata->disconnecting) */
-
-/* no disconnect message received; unexpected disconnection */
-cmd = (Scsi_Cmnd *)hostdata->connected;
-if (cmd) {
-#ifdef AM53C974_DEBUG
- deb_stop = 1;
-#endif
- AM53C974_set_async(instance, cmd->target);
- printk("scsi%d: Unexpected disconnect; phase: %d; target: %d; this_residual: %d; buffers_residual: %d; message: %d\n",
- instance->host_no, cmd->SCp.phase, cmd->target, cmd->SCp.this_residual, cmd->SCp.buffers_residual,
- cmd->SCp.Message);
- printk("cmdreg: 0x%02x; statreg: 0x%02x; isreg: 0x%02x; cfifo: 0x%02x\n",
- AM53C974_read_8(CMDREG), AM53C974_read_8(STATREG), AM53C974_read_8(ISREG),
- AM53C974_read_8(CFIREG) & CFIREG_CF);
-
- if ((hostdata->last_message[0] == EXTENDED_MESSAGE) &&
- (hostdata->last_message[2] == EXTENDED_SDTR)) {
- /* sync. negotiation was aborted, setup asynchronous transfer with target */
- hostdata->sync_off[cmd->target] = 0; }
- if (hostdata->aborted || hostdata->msgout[0] == ABORT)
- cmd->result = DID_ABORT << 16;
- else
- cmd->result = DID_ERROR << 16;
- goto EXIT_FINISHED; }
-
-EXIT_FINISHED:
-hostdata->aborted = 0;
-hostdata->msgout[0] = NOP;
-hostdata->sel_cmd = NULL;
-hostdata->connected = NULL;
-hostdata->selecting = 0;
-hostdata->disconnecting = 0;
-hostdata->dma_busy = 0;
-hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
-AM53C974_write_8(CMDREG, CMDREG_CFIFO);
-DEB(printk("disconnect; issue_queue: 0x%lx, disconnected_queue: 0x%lx\n",
- (long)hostdata->issue_queue, (long)hostdata->disconnected_queue));
-cmd->scsi_done(cmd);
-
-if (!hostdata->selecting) {
- AM53C974_set_async(instance, cmd->target);
- AM53C974_write_8(CMDREG, CMDREG_ESR); } /* allow reselect */
-return;
-
-EXIT_UNFINISHED:
-hostdata->msgout[0] = NOP;
-hostdata->sel_cmd = NULL;
-hostdata->connected = NULL;
-hostdata->aborted = 0;
-hostdata->selecting = 0;
-hostdata->disconnecting = 0;
-hostdata->dma_busy = 0;
-DEB(printk("disconnect; issue_queue: 0x%lx, disconnected_queue: 0x%lx\n",
- (long)hostdata->issue_queue, (long)hostdata->disconnected_queue));
-if (!hostdata->selecting) {
- AM53C974_set_async(instance, cmd->target);
- AM53C974_write_8(CMDREG, CMDREG_ESR); } /* allow reselect */
-return;
-}
-
-/**************************************************************************
-* Function : int AM53C974_sync_neg(struct Scsi_Host *instance, int target, unsigned char *msg)
-*
-* Purpose : setup message string for sync. negotiation
-*
-* Inputs : instance -- which AM53C974
-* target -- which SCSI target to deal with
-* msg -- input message string
-*
-* Returns : 0 if parameters accepted or 1 if not accepted
-*
-* Side effects: hostdata is changed
-*
-* Note: we assume here that fastclk is enabled
-**************************************************************************/
-static int AM53C974_sync_neg(struct Scsi_Host *instance, int target, unsigned char *msg)
-{
-AM53C974_local_declare();
-struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *)instance->hostdata;
-int period, offset, i, rate, rate_rem;
-AM53C974_setio(instance);
-
-period = (DEF_CLK * msg[3] * 8 + 1000) / 2000;
-if (period < MIN_PERIOD) {
- period = MIN_PERIOD;
- hostdata->msgout[3] = period / 4; }
- else
- if (period > MAX_PERIOD) {
- period = MAX_PERIOD;
- hostdata->msgout[3] = period / 4; }
- else
- hostdata->msgout[3] = msg[3];
-offset = msg[4];
-if (offset > MAX_OFFSET) offset = MAX_OFFSET;
-hostdata->msgout[4] = offset;
-hostdata->sync_per[target] = period;
-hostdata->sync_off[target] = offset;
-for (i = 0; i < 3; i++) hostdata->msgout[i] = msg[i];
-if ((hostdata->msgout[3] != msg[3]) || (msg[4] != offset)) return(1);
-
-rate = DEF_CLK / period;
-rate_rem = 10 * (DEF_CLK - period * rate) / period;
-
-if (offset)
- printk("\ntarget %d: rate=%d.%d Mhz, synchronous, sync offset=%d bytes\n",
- target, rate, rate_rem, offset);
- else
- printk("\ntarget %d: rate=%d.%d Mhz, asynchronous\n", target, rate, rate_rem);
-
-return(0);
-}
-
-/**************************************************************************
-* Function : AM53C974_set_async(struct Scsi_Host *instance, int target)
-*
-* Purpose : put controller into async. mode
-*
-* Inputs : instance -- which AM53C974
-* target -- which SCSI target to deal with
-*
-* Returns : nothing
-**************************************************************************/
-static __inline__ void AM53C974_set_async(struct Scsi_Host *instance, int target)
-{
-AM53C974_local_declare();
-struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *)instance->hostdata;
-AM53C974_setio(instance);
-
-AM53C974_write_8(STPREG, hostdata->sync_per[target]);
-AM53C974_write_8(SOFREG, (DEF_SOF_RAD<<6) | (DEF_SOF_RAA<<4));
-}
-
-/**************************************************************************
-* Function : AM53C974_set_sync(struct Scsi_Host *instance, int target)
-*
-* Purpose : put controller into sync. mode
-*
-* Inputs : instance -- which AM53C974
-* target -- which SCSI target to deal with
-*
-* Returns : nothing
-**************************************************************************/
-static __inline__ void AM53C974_set_sync(struct Scsi_Host *instance, int target)
-{
-AM53C974_local_declare();
-struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *)instance->hostdata;
-AM53C974_setio(instance);
-
-AM53C974_write_8(STPREG, hostdata->sync_per[target]);
-AM53C974_write_8(SOFREG, (SOFREG_SO & hostdata->sync_off[target]) |
- (DEF_SOF_RAD<<6) | (DEF_SOF_RAA<<4));
-}
-
-/***********************************************************************
-* Function : AM53C974_information_transfer(struct Scsi_Host *instance, *
-* unsigned char statreg, unsigned char isreg, *
-* unsigned char instreg, unsigned char cfifo, *
-* unsigned char dmastatus) *
-* *
-* Purpose : handle phase changes *
-* *
-* Inputs : instance - which AM53C974 *
-* statreg - stus register *
-* isreg - internal state register *
-* instreg - interrupt status register *
-* cfifo - number of bytes in FIFO *
-* dmastatus - dma status register *
-* *
-* Returns : nothing *
-************************************************************************/
-static void AM53C974_information_transfer(struct Scsi_Host *instance,
- unsigned char statreg, unsigned char isreg,
- unsigned char instreg, unsigned char cfifo,
- unsigned char dmastatus)
-{
-AM53C974_local_declare();
-struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *)instance->hostdata;
-Scsi_Cmnd *cmd = (Scsi_Cmnd *)hostdata->connected;
-int ret, i, len, residual=-1;
-AM53C974_setio(instance);
-
-DEB_INFO(printk(SEPARATOR_LINE));
-switch (statreg & STATREG_PHASE) { /* scsi phase */
- case PHASE_DATAOUT:
- DEB_INFO(printk("Dataout phase; cmd=0x%lx, sel_cmd=0x%lx, this_residual=%d, buffers_residual=%d\n",
- (long)hostdata->connected, (long)hostdata->sel_cmd, cmd->SCp.this_residual, cmd->SCp.buffers_residual));
- cmd->SCp.phase = PHASE_DATAOUT;
- goto PHASE_DATA_IO;
-
- case PHASE_DATAIN:
- DEB_INFO(printk("Datain phase; cmd=0x%lx, sel_cmd=0x%lx, this_residual=%d, buffers_residual=%d\n",
- (long)hostdata->connected, (long)hostdata->sel_cmd, cmd->SCp.this_residual, cmd->SCp.buffers_residual));
- cmd->SCp.phase = PHASE_DATAIN;
- PHASE_DATA_IO:
- if (hostdata->aborted) {
- AM53C974_write_8(DMACMD, DMACMD_IDLE);
- AM53C974_write_8(CMDREG, CMDREG_CFIFO);
- AM53C974_write_8(CMDREG, CMDREG_SATN);
- return; }
- if ((!cmd->SCp.this_residual) && cmd->SCp.buffers_residual) {
- cmd->SCp.buffer++;
- cmd->SCp.buffers_residual--;
- cmd->SCp.ptr = (unsigned char *)cmd->SCp.buffer->address;
- cmd->SCp.this_residual = cmd->SCp.buffer->length; }
- if (cmd->SCp.this_residual) {
- if (!(AM53C974_read_8(DMACMD) & DMACMD_START)) {
- hostdata->dma_busy = 0;
- AM53C974_transfer_dma(instance, statreg & STATREG_IO,
- (unsigned long)cmd->SCp.this_residual,
- cmd->SCp.ptr); }
- else
- hostdata->dma_busy = 1;
- }
- return;
-
- case PHASE_MSGIN:
- DEB_INFO(printk("Message-In phase; cmd=0x%lx, sel_cmd=0x%lx\n",
- (long)hostdata->connected, (long)hostdata->sel_cmd));
- AM53C974_set_async(instance, cmd->target);
- if (cmd->SCp.phase == PHASE_DATAIN)
- AM53C974_dma_blast(instance, dmastatus, statreg);
- if ((cmd->SCp.phase == PHASE_DATAOUT) && (AM53C974_read_8(DMACMD) & DMACMD_START)) {
- AM53C974_write_8(DMACMD, DMACMD_IDLE);
- residual = cfifo + (AM53C974_read_8(CTCLREG) | (AM53C974_read_8(CTCMREG) << 8) |
- (AM53C974_read_8(CTCHREG) << 16));
- cmd->SCp.ptr += cmd->SCp.this_residual - residual;
- cmd->SCp.this_residual = residual;
- if (cfifo) { AM53C974_write_8(CMDREG, CMDREG_CFIFO); cfifo = 0; }
- }
- if (cmd->SCp.phase == PHASE_STATIN) {
- while ((AM53C974_read_8(CFIREG) & CFIREG_CF) < 2) ;
- cmd->SCp.Status = AM53C974_read_8(FFREG);
- cmd->SCp.Message = AM53C974_read_8(FFREG);
- DEB_INFO(printk("Message-In phase; status=0x%02x, message=0x%02x\n",
- cmd->SCp.Status, cmd->SCp.Message));
- ret = AM53C974_message(instance, cmd, cmd->SCp.Message); }
- else {
- if (!cfifo) {
- AM53C974_write_8(CMDREG, CMDREG_IT);
- AM53C974_poll_int();
- cmd->SCp.Message = AM53C974_read_8(FFREG);
- }
- ret = AM53C974_message(instance, cmd, cmd->SCp.Message);
- }
- cmd->SCp.phase = PHASE_MSGIN;
- AM53C974_set_sync(instance, cmd->target);
- break;
- case PHASE_MSGOUT:
- DEB_INFO(printk("Message-Out phase; cfifo=%d; msgout[0]=0x%02x\n",
- AM53C974_read_8(CFIREG) & CFIREG_CF, hostdata->msgout[0]));
- AM53C974_write_8(DMACMD, DMACMD_IDLE);
- AM53C974_set_async(instance, cmd->target);
- for (i = 0; i < sizeof(hostdata->last_message); i++)
- hostdata->last_message[i] = hostdata->msgout[i];
- if ((hostdata->msgout[0] == 0) || INSIDE(hostdata->msgout[0], 0x02, 0x1F) ||
- INSIDE(hostdata->msgout[0], 0x80, 0xFF))
- len = 1;
- else {
- if (hostdata->msgout[0] == EXTENDED_MESSAGE) {
-#ifdef AM53C974_DEBUG_INFO
- printk("Extended message dump:\n");
- for (i = 0; i < hostdata->msgout[1] + 2; i++) {
- printk("%02x ", hostdata->msgout[i]);
- if (i && !(i % 16)) printk("\n"); }
- printk("\n");
-#endif
- len = hostdata->msgout[1] + 2; }
- else
- len = 2;
- }
- for (i = 0; i < len; i++) AM53C974_write_8(FFREG, hostdata->msgout[i]);
- AM53C974_write_8(CMDREG, CMDREG_IT);
- cmd->SCp.phase = PHASE_MSGOUT;
- hostdata->msgout[0] = NOP;
- AM53C974_set_sync(instance, cmd->target);
- break;
-
- case PHASE_CMDOUT:
- DEB_INFO(printk("Command-Out phase\n"));
- AM53C974_set_async(instance, cmd->target);
- for (i = 0; i < cmd->cmd_len; i++) AM53C974_write_8(FFREG, cmd->cmnd[i]);
- AM53C974_write_8(CMDREG, CMDREG_IT);
- cmd->SCp.phase = PHASE_CMDOUT;
- AM53C974_set_sync(instance, cmd->target);
- break;
-
- case PHASE_STATIN:
- DEB_INFO(printk("Status phase\n"));
- if (cmd->SCp.phase == PHASE_DATAIN)
- AM53C974_dma_blast(instance, dmastatus, statreg);
- AM53C974_set_async(instance, cmd->target);
- if (cmd->SCp.phase == PHASE_DATAOUT) {
- unsigned long residual;
-
- if (AM53C974_read_8(DMACMD) & DMACMD_START) {
- AM53C974_write_8(DMACMD, DMACMD_IDLE);
- residual = cfifo + (AM53C974_read_8(CTCLREG) | (AM53C974_read_8(CTCMREG) << 8) |
- (AM53C974_read_8(CTCHREG) << 16));
- cmd->SCp.ptr += cmd->SCp.this_residual - residual;
- cmd->SCp.this_residual = residual; }
- if (cfifo) { AM53C974_write_8(CMDREG, CMDREG_CFIFO); cfifo = 0; }
- }
- cmd->SCp.phase = PHASE_STATIN;
- AM53C974_write_8(CMDREG, CMDREG_ICCS); /* command complete */
- break;
-
- case PHASE_RES_0:
- case PHASE_RES_1:
-#ifdef AM53C974_DEBUG
- deb_stop = 1;
-#endif
- DEB_INFO(printk("Reserved phase\n"));
- break;
- }
-KEYWAIT();
-}
-
-/******************************************************************************
-* Function : int AM53C974_message(struct Scsi_Host *instance, Scsi_Cmnd *cmd,
-* unsigned char msg)
-*
-* Purpose : handle SCSI messages
-*
-* Inputs : instance -- which AM53C974
-* cmd -- SCSI command the message belongs to
-* msg -- message id byte
-*
-* Returns : 1 on success, 0 on failure.
-**************************************************************************/
-static int AM53C974_message(struct Scsi_Host *instance, Scsi_Cmnd *cmd,
- unsigned char msg)
-{
-AM53C974_local_declare();
-static unsigned char extended_msg[10];
-unsigned char statreg;
-int len, ret = 0;
-unsigned char *p;
-#ifdef AM53C974_DEBUG_MSG
-int j;
-#endif
-struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *)instance->hostdata;
-AM53C974_setio(instance);
-
-DEB_MSG(printk(SEPARATOR_LINE));
-
-/* Linking lets us reduce the time required to get the
- * next command out to the device, hopefully this will
- * mean we don't waste another revolution due to the delays
- * required by ARBITRATION and another SELECTION.
- * In the current implementation proposal, low level drivers
- * merely have to start the next command, pointed to by
- * next_link, done() is called as with unlinked commands. */
-switch (msg) {
-#ifdef LINKED
- case LINKED_CMD_COMPLETE:
- case LINKED_FLG_CMD_COMPLETE:
- /* Accept message by releasing ACK */
- DEB_LINKED(printk("scsi%d : target %d lun %d linked command complete.\n",
- instance->host_no, cmd->target, cmd->lun));
- /* Sanity check : A linked command should only terminate with
- * one of these messages if there are more linked commands available. */
- if (!cmd->next_link) {
- printk("scsi%d : target %d lun %d linked command complete, no next_link\n"
- instance->host_no, cmd->target, cmd->lun);
- hostdata->aborted = 1;
- AM53C974_write_8(CMDREG, CMDREG_SATN);
- AM53C974_write_8(CMDREG, CMDREG_MA);
- break; }
- if (hostdata->aborted) {
- DEB_ABORT(printk("ATN set for cmnd %d upon reception of LINKED_CMD_COMPLETE or"
- "LINKED_FLG_CMD_COMPLETE message\n", cmd->cmnd[0]));
- AM53C974_write_8(CMDREG, CMDREG_SATN); }
- AM53C974_write_8(CMDREG, CMDREG_MA);
-
- initialize_SCp(cmd->next_link);
- /* The next command is still part of this process */
- cmd->next_link->tag = cmd->tag;
- cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
- DEB_LINKED(printk("scsi%d : target %d lun %d linked request done, calling scsi_done().\n",
- instance->host_no, cmd->target, cmd->lun));
- cmd->scsi_done(cmd);
- cmd = hostdata->connected;
- break;
-
-#endif /* def LINKED */
-
- case ABORT:
- case COMMAND_COMPLETE:
- DEB_MSG(printk("scsi%d: command complete message received; cmd %d for target %d, lun %d\n",
- instance->host_no, cmd->cmnd[0], cmd->target, cmd->lun));
- hostdata->disconnecting = 1;
- cmd->device->disconnect = 0;
-
- /* I'm not sure what the correct thing to do here is :
- *
- * If the command that just executed is NOT a request
- * sense, the obvious thing to do is to set the result
- * code to the values of the stored parameters.
- * If it was a REQUEST SENSE command, we need some way
- * to differentiate between the failure code of the original
- * and the failure code of the REQUEST sense - the obvious
- * case is success, where we fall through and leave the result
- * code unchanged.
- *
- * The non-obvious place is where the REQUEST SENSE failed */
- if (cmd->cmnd[0] != REQUEST_SENSE)
- cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
- else if (cmd->SCp.Status != GOOD)
- cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16);
- if (hostdata->aborted) {
- AM53C974_write_8(CMDREG, CMDREG_SATN);
- AM53C974_write_8(CMDREG, CMDREG_MA);
- DEB_ABORT(printk("ATN set for cmnd %d upon reception of ABORT or"
- "COMMAND_COMPLETE message\n", cmd->cmnd[0]));
- break; }
- if ((cmd->cmnd[0] != REQUEST_SENSE) && (cmd->SCp.Status == CHECK_CONDITION)) {
- DEB_MSG(printk("scsi%d : performing request sense\n", instance->host_no));
- cmd->cmnd[0] = REQUEST_SENSE;
- cmd->cmnd[1] &= 0xe0;
- cmd->cmnd[2] = 0;
- cmd->cmnd[3] = 0;
- cmd->cmnd[4] = sizeof(cmd->sense_buffer);
- cmd->cmnd[5] = 0;
- cmd->SCp.buffer = NULL;
- cmd->SCp.buffers_residual = 0;
- cmd->SCp.ptr = (char *)cmd->sense_buffer;
- cmd->SCp.this_residual = sizeof(cmd->sense_buffer);
- LIST(cmd,hostdata->issue_queue);
- cmd->host_scribble = (unsigned char *)hostdata->issue_queue;
- hostdata->issue_queue = (Scsi_Cmnd *)cmd;
- DEB_MSG(printk("scsi%d : REQUEST SENSE added to head of issue queue\n",instance->host_no));
- }
-
- /* Accept message by clearing ACK */
- AM53C974_write_8(CMDREG, CMDREG_MA);
- break;
-
- case MESSAGE_REJECT:
- DEB_MSG(printk("scsi%d: reject message received; cmd %d for target %d, lun %d\n",
- instance->host_no, cmd->cmnd[0], cmd->target, cmd->lun));
- switch (hostdata->last_message[0]) {
- case EXTENDED_MESSAGE:
- if (hostdata->last_message[2] == EXTENDED_SDTR) {
- /* sync. negotiation was rejected, setup asynchronous transfer with target */
- printk("\ntarget %d: rate=%d Mhz, asynchronous (sync. negotiation rejected)\n",
- cmd->target, DEF_CLK / DEF_STP);
- hostdata->sync_off[cmd->target] = 0;
- hostdata->sync_per[cmd->target] = DEF_STP; }
- break;
- case HEAD_OF_QUEUE_TAG:
- case ORDERED_QUEUE_TAG:
- case SIMPLE_QUEUE_TAG:
- cmd->device->tagged_queue = 0;
- hostdata->busy[cmd->target] |= (1 << cmd->lun);
- break;
- default:
- break;
- }
- if (hostdata->aborted) AM53C974_write_8(CMDREG, CMDREG_SATN);
- AM53C974_write_8(CMDREG, CMDREG_MA);
- break;
-
- case DISCONNECT:
- DEB_MSG(printk("scsi%d: disconnect message received; cmd %d for target %d, lun %d\n",
- instance->host_no, cmd->cmnd[0], cmd->target, cmd->lun));
- cmd->device->disconnect = 1;
- hostdata->disconnecting = 1;
- AM53C974_write_8(CMDREG, CMDREG_MA); /* Accept message by clearing ACK */
- break;
-
- case SAVE_POINTERS:
- case RESTORE_POINTERS:
- DEB_MSG(printk("scsi%d: save/restore pointers message received; cmd %d for target %d, lun %d\n",
- instance->host_no, cmd->cmnd[0], cmd->target, cmd->lun));
- /* The SCSI data pointer is *IMPLICITLY* saved on a disconnect
- * operation, in violation of the SCSI spec so we can safely
- * ignore SAVE/RESTORE pointers calls.
- *
- * Unfortunately, some disks violate the SCSI spec and
- * don't issue the required SAVE_POINTERS message before
- * disconnecting, and we have to break spec to remain
- * compatible. */
- if (hostdata->aborted) {
- DEB_ABORT(printk("ATN set for cmnd %d upon reception of SAVE/REST. POINTERS message\n",
- cmd->cmnd[0]));
- AM53C974_write_8(CMDREG, CMDREG_SATN); }
- AM53C974_write_8(CMDREG, CMDREG_MA);
- break;
-
- case EXTENDED_MESSAGE:
- DEB_MSG(printk("scsi%d: extended message received; cmd %d for target %d, lun %d\n",
- instance->host_no, cmd->cmnd[0], cmd->target, cmd->lun));
- /* Extended messages are sent in the following format :
- * Byte
- * 0 EXTENDED_MESSAGE == 1
- * 1 length (includes one byte for code, doesn't include first two bytes)
- * 2 code
- * 3..length+1 arguments
- */
- /* BEWARE!! THIS CODE IS EXTREMELY UGLY */
- extended_msg[0] = EXTENDED_MESSAGE;
- AM53C974_read_8(INSTREG) ; /* clear int */
- AM53C974_write_8(CMDREG, CMDREG_MA); /* ack. msg byte, then wait for SO */
- AM53C974_poll_int();
- /* get length */
- AM53C974_write_8(CMDREG, CMDREG_IT);
- AM53C974_poll_int();
- AM53C974_write_8(CMDREG, CMDREG_MA); /* ack. msg byte, then wait for SO */
- AM53C974_poll_int();
- extended_msg[1] = len = AM53C974_read_8(FFREG); /* get length */
- p = extended_msg+2;
- /* read the remaining (len) bytes */
- while (len) {
- AM53C974_write_8(CMDREG, CMDREG_IT);
- AM53C974_poll_int();
- if (len > 1) {
- AM53C974_write_8(CMDREG, CMDREG_MA); /* ack. msg byte, then wait for SO */
- AM53C974_poll_int(); }
- *p = AM53C974_read_8(FFREG);
- p++; len--; }
-
-#ifdef AM53C974_DEBUG_MSG
- printk("scsi%d: received extended message: ", instance->host_no);
- for (j = 0; j < extended_msg[1] + 2; j++) {
- printk("0x%02x ", extended_msg[j]);
- if (j && !(j % 16)) printk("\n"); }
- printk("\n");
-#endif
-
- /* check message */
- if (extended_msg[2] == EXTENDED_SDTR)
- ret = AM53C974_sync_neg(instance, cmd->target, extended_msg);
- if (ret || hostdata->aborted) AM53C974_write_8(CMDREG, CMDREG_SATN);
-
- AM53C974_write_8(CMDREG, CMDREG_MA);
- break;
-
- default:
- printk("scsi%d: unknown message 0x%02x received\n",instance->host_no, msg);
-#ifdef AM53C974_DEBUG
- deb_stop = 1;
-#endif
- /* reject message */
- hostdata->msgout[0] = MESSAGE_REJECT;
- AM53C974_write_8(CMDREG, CMDREG_SATN);
- AM53C974_write_8(CMDREG, CMDREG_MA);
- return(0);
- break;
-
- } /* switch (msg) */
-KEYWAIT();
-return(1);
-}
-
-/**************************************************************************
-* Function : AM53C974_select(struct Scsi_Host *instance, Scsi_Cmnd *cmd, int tag)
-*
-* Purpose : try to establish nexus for the command;
-* start sync negotiation via start stop and transfer the command in
-* cmdout phase in case of an inquiry or req. sense command with no
-* sync. neg. performed yet
-*
-* Inputs : instance -- which AM53C974
-* cmd -- command which requires the selection
-* tag -- tagged queueing
-*
-* Returns : nothing
-*
-* Note: this function initializes the selection process, which is continued
-* in the interrupt handler
-**************************************************************************/
-static void AM53C974_select(struct Scsi_Host *instance, Scsi_Cmnd *cmd, int tag)
-{
-AM53C974_local_declare();
-struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *)instance->hostdata;
-unsigned char cfifo, tmp[3];
-unsigned int i, len, cmd_size = COMMAND_SIZE(cmd->cmnd[0]);
-AM53C974_setio(instance);
-
-cfifo = AM53C974_cfifo();
-if (cfifo) {
- printk("scsi%d: select error; %d residual bytes in FIFO\n", instance->host_no, cfifo);
- AM53C974_write_8(CMDREG, CMDREG_CFIFO); /* clear FIFO */
- }
-
-tmp[0] = IDENTIFY(1, cmd->lun);
-
-#ifdef SCSI2
-if (cmd->device->tagged_queue && (tag != TAG_NONE)) {
- tmp[1] = SIMPLE_QUEUE_TAG;
- if (tag == TAG_NEXT) {
- /* 0 is TAG_NONE, used to imply no tag for this command */
- if (cmd->device->current_tag == 0) cmd->device->current_tag = 1;
- cmd->tag = cmd->device->current_tag;
- cmd->device->current_tag++; }
- else
- cmd->tag = (unsigned char)tag;
- tmp[2] = cmd->tag;
- hostdata->last_message[0] = SIMPLE_QUEUE_TAG;
- len = 3;
- AM53C974_write_8(FFREG, tmp[0]);
- AM53C974_write_8(FFREG, tmp[1]);
- AM53C974_write_8(FFREG, tmp[2]);
- }
- else
-#endif /* def SCSI2 */
- {
- len = 1;
- AM53C974_write_8(FFREG, tmp[0]);
- cmd->tag = 0; }
-
-/* in case of an inquiry or req. sense command with no sync. neg performed yet, we start
- sync negotiation via start stops and transfer the command in cmdout phase */
-if (((cmd->cmnd[0] == INQUIRY) || (cmd->cmnd[0] == REQUEST_SENSE)) &&
- !(hostdata->sync_neg[cmd->target]) && hostdata->sync_en[cmd->target]) {
- hostdata->sync_neg[cmd->target] = 1;
- hostdata->msgout[0] = EXTENDED_MESSAGE;
- hostdata->msgout[1] = 3;
- hostdata->msgout[2] = EXTENDED_SDTR;
- hostdata->msgout[3] = 250 / (int)hostdata->max_rate[cmd->target];
- hostdata->msgout[4] = hostdata->max_offset[cmd->target];
- len += 5; }
-
-AM53C974_write_8(SDIDREG, SDIREG_MASK & cmd->target); /* setup dest. id */
-AM53C974_write_8(STIMREG, DEF_SCSI_TIMEOUT); /* setup timeout reg */
-switch (len) {
- case 1:
- for (i = 0; i < cmd_size; i++) AM53C974_write_8(FFREG, cmd->cmnd[i]);
- AM53C974_write_8(CMDREG, CMDREG_SAS); /* select with ATN, 1 msg byte */
- hostdata->msgout[0] = NOP;
- break;
- case 3:
- for (i = 0; i < cmd_size; i++) AM53C974_write_8(FFREG, cmd->cmnd[i]);
- AM53C974_write_8(CMDREG, CMDREG_SA3S); /* select with ATN, 3 msg bytes */
- hostdata->msgout[0] = NOP;
- break;
- default:
- AM53C974_write_8(CMDREG, CMDREG_SASS); /* select with ATN, stop steps; continue in message out phase */
- break;
- }
-}
-
-/**************************************************************************
-* Function : AM53C974_intr_select(struct Scsi_Host *instance, unsigned char statreg)
-*
-* Purpose : handle reselection
-*
-* Inputs : instance -- which AM53C974
-* statreg -- status register
-*
-* Returns : nothing
-*
-* side effects: manipulates hostdata
-**************************************************************************/
-static void AM53C974_intr_reselect(struct Scsi_Host *instance, unsigned char statreg)
-{
-AM53C974_local_declare();
-struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *)instance->hostdata;
-unsigned char cfifo, msg[3], lun, t, target = 0;
-#ifdef SCSI2
- unsigned char tag;
-#endif
-Scsi_Cmnd *tmp = NULL, *prev;
-AM53C974_setio(instance);
-
-cfifo = AM53C974_cfifo();
-
-if (hostdata->selecting) {
- /* caught reselect interrupt in selection process;
- put selecting command back into the issue queue and continue with the
- reselecting command */
- DEB_RESEL(printk("AM53C974_intr_reselect: in selection process\n"));
- LIST(hostdata->sel_cmd, hostdata->issue_queue);
- hostdata->sel_cmd->host_scribble = (unsigned char *)hostdata->issue_queue;
- hostdata->issue_queue = hostdata->sel_cmd;
- hostdata->sel_cmd = NULL;
- hostdata->selecting = 0; }
-
-/* 2 bytes must be in the FIFO now */
-if (cfifo != 2) {
- printk("scsi %d: error: %d bytes in fifo, 2 expected\n", instance->host_no, cfifo);
- hostdata->aborted = 1;
- goto EXIT_ABORT; }
-
-/* determine target which reselected */
-t = AM53C974_read_8(FFREG);
-if (!(t & (1 << instance->this_id))) {
- printk("scsi %d: error: invalid host id\n", instance->host_no);
- hostdata->aborted = 1;
- goto EXIT_ABORT; }
-t ^= (1 << instance->this_id);
-target = 0; while (t != 1) { t >>= 1; target++; }
-DEB_RESEL(printk("scsi %d: reselect; target: %d\n", instance->host_no, target));
-
-if (hostdata->aborted) goto EXIT_ABORT;
-
-if ((statreg & STATREG_PHASE) != PHASE_MSGIN) {
- printk("scsi %d: error: upon reselection interrupt not in MSGIN\n", instance->host_no);
- hostdata->aborted = 1;
- goto EXIT_ABORT; }
-
-msg[0] = AM53C974_read_8(FFREG);
-if (!msg[0] & 0x80) {
- printk("scsi%d: error: expecting IDENTIFY message, got ", instance->host_no);
- print_msg(msg);
- hostdata->aborted = 1;
- goto EXIT_ABORT; }
-
-lun = (msg[0] & 0x07);
-
-/* We need to add code for SCSI-II to track which devices have
- * I_T_L_Q nexuses established, and which have simple I_T_L
- * nexuses so we can chose to do additional data transfer. */
-#ifdef SCSI2
-#error "SCSI-II tagged queueing is not supported yet"
-#endif
-
-/* Find the command corresponding to the I_T_L or I_T_L_Q nexus we
- * just reestablished, and remove it from the disconnected queue. */
-for (tmp = (Scsi_Cmnd *)hostdata->disconnected_queue, prev = NULL;
- tmp; prev = tmp, tmp = (Scsi_Cmnd *)tmp->host_scribble)
- if ((target == tmp->target) && (lun == tmp->lun)
-#ifdef SCSI2
- && (tag == tmp->tag)
-#endif
- ) {
- if (prev) {
- REMOVE(prev, (Scsi_Cmnd *)(prev->host_scribble), tmp,
- (Scsi_Cmnd *)(tmp->host_scribble));
- prev->host_scribble = tmp->host_scribble; }
- else {
- REMOVE(-1, hostdata->disconnected_queue, tmp, tmp->host_scribble);
- hostdata->disconnected_queue = (Scsi_Cmnd *)tmp->host_scribble; }
- tmp->host_scribble = NULL;
- hostdata->connected = tmp;
- break; }
-
-if (!tmp) {
-#ifdef SCSI2
- printk("scsi%d: warning : target %d lun %d tag %d not in disconnect_queue.\n",
- instance->host_no, target, lun, tag);
-#else
- printk("scsi%d: warning : target %d lun %d not in disconnect_queue.\n",
- instance->host_no, target, lun);
-#endif
- /* Since we have an established nexus that we can't do anything with, we must abort it. */
- hostdata->aborted = 1;
- DEB(AM53C974_keywait());
- goto EXIT_ABORT; }
- else
- goto EXIT_OK;
-
-EXIT_ABORT:
-AM53C974_write_8(CMDREG, CMDREG_SATN);
-AM53C974_write_8(CMDREG, CMDREG_MA);
-return;
-
-EXIT_OK:
-DEB_RESEL(printk("scsi%d: nexus established, target = %d, lun = %d, tag = %d\n",
- instance->host_no, target, tmp->lun, tmp->tag));
-AM53C974_set_sync(instance, target);
-AM53C974_write_8(SDIDREG, SDIREG_MASK & target); /* setup dest. id */
-AM53C974_write_8(CMDREG, CMDREG_MA);
-hostdata->dma_busy = 0;
-hostdata->connected->SCp.phase = PHASE_CMDOUT;
-}
-
-/**************************************************************************
-* Function : AM53C974_transfer_dma(struct Scsi_Host *instance, short dir,
-* unsigned long length, char *data)
-*
-* Purpose : setup DMA transfer
-*
-* Inputs : instance -- which AM53C974
-* dir -- direction flag, 0: write to device, read from memory;
-* 1: read from device, write to memory
-* length -- number of bytes to transfer to from buffer
-* data -- pointer to data buffer
-*
-* Returns : nothing
-**************************************************************************/
-static __inline__ void AM53C974_transfer_dma(struct Scsi_Host *instance, short dir,
- unsigned long length, char *data)
-{
-AM53C974_local_declare();
-AM53C974_setio(instance);
-
-AM53C974_write_8(CMDREG, CMDREG_NOP);
-AM53C974_write_8(DMACMD, (dir << 7) | DMACMD_INTE_D); /* idle command */
-AM53C974_write_8(STCLREG, (unsigned char)(length & 0xff));
-AM53C974_write_8(STCMREG, (unsigned char)((length & 0xff00) >> 8));
-AM53C974_write_8(STCHREG, (unsigned char)((length & 0xff0000) >> 16));
-AM53C974_write_32(DMASTC, length & 0xffffff);
-AM53C974_write_32(DMASPA, (unsigned long)data);
-AM53C974_write_8(CMDREG, CMDREG_IT | CMDREG_DMA);
-AM53C974_write_8(DMACMD, (dir << 7) | DMACMD_INTE_D | DMACMD_START);
-}
-
-/**************************************************************************
-* Function : AM53C974_dma_blast(struct Scsi_Host *instance, unsigned char dmastatus,
-* unsigned char statreg)
-*
-* Purpose : cleanup DMA transfer
-*
-* Inputs : instance -- which AM53C974
-* dmastatus -- dma status register
-* statreg -- status register
-*
-* Returns : nothing
-**************************************************************************/
-static void AM53C974_dma_blast(struct Scsi_Host *instance, unsigned char dmastatus,
- unsigned char statreg)
-{
-AM53C974_local_declare();
-struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *)instance->hostdata;
-unsigned long ctcreg;
-int dir = statreg & STATREG_IO;
-int cfifo, pio, i = 0;
-AM53C974_setio(instance);
-
-do {
- cfifo = AM53C974_cfifo();
- i++;
- } while (cfifo && (i < 50000));
-pio = (i == 50000) ? 1: 0;
-
-if (statreg & STATREG_CTZ) { AM53C974_write_8(DMACMD, DMACMD_IDLE); return; }
-
-if (dmastatus & DMASTATUS_DONE) { AM53C974_write_8(DMACMD, DMACMD_IDLE); return; }
-
-AM53C974_write_8(DMACMD, ((dir << 7) & DMACMD_DIR) | DMACMD_BLAST);
-while(!(AM53C974_read_8(DMASTATUS) & DMASTATUS_BCMPLT)) ;
-AM53C974_write_8(DMACMD, DMACMD_IDLE);
-
-if (pio) {
- /* transfer residual bytes via PIO */
- unsigned char *wac = (unsigned char *)AM53C974_read_32(DMAWAC);
- printk("pio mode, residual=%d\n", AM53C974_read_8(CFIREG) & CFIREG_CF);
- while (AM53C974_read_8(CFIREG) & CFIREG_CF) *(wac++) = AM53C974_read_8(FFREG);
- }
-
-ctcreg = AM53C974_read_8(CTCLREG) | (AM53C974_read_8(CTCMREG) << 8) |
- (AM53C974_read_8(CTCHREG) << 16);
-
-hostdata->connected->SCp.ptr += hostdata->connected->SCp.this_residual - ctcreg;
-hostdata->connected->SCp.this_residual = ctcreg;
-}
-
-/**************************************************************************
-* Function : AM53C974_intr_bus_reset(struct Scsi_Host *instance)
-*
-* Purpose : handle bus reset interrupt
-*
-* Inputs : instance -- which AM53C974
-*
-* Returns : nothing
-**************************************************************************/
-static void AM53C974_intr_bus_reset(struct Scsi_Host *instance)
-{
-AM53C974_local_declare();
-unsigned char cntlreg1;
-AM53C974_setio(instance);
-
-AM53C974_write_8(CMDREG, CMDREG_CFIFO);
-AM53C974_write_8(CMDREG, CMDREG_NOP);
-
-cntlreg1 = AM53C974_read_8(CNTLREG1);
-AM53C974_write_8(CNTLREG1, cntlreg1 | CNTLREG1_DISR);
-}
-
-/**************************************************************************
-* Function : int AM53C974_abort(Scsi_Cmnd *cmd)
-*
-* Purpose : abort a command
-*
-* Inputs : cmd - the Scsi_Cmnd to abort, code - code to set the
-* host byte of the result field to, if zero DID_ABORTED is
-* used.
-*
-* Returns : 0 - success, -1 on failure.
- **************************************************************************/
-int AM53C974_abort(Scsi_Cmnd *cmd)
-{
-AM53C974_local_declare();
-struct Scsi_Host *instance = cmd->host;
-struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *)instance->hostdata;
-Scsi_Cmnd *tmp, **prev;
-
-#ifdef AM53C974_DEBUG
- deb_stop = 1;
-#endif
-cli();
-AM53C974_setio(instance);
-
-DEB_ABORT(printk(SEPARATOR_LINE));
-DEB_ABORT(printk("scsi%d : AM53C974_abort called -- trouble starts!!\n", instance->host_no));
-DEB_ABORT(AM53C974_print(instance));
-DEB_ABORT(AM53C974_keywait());
-
-/* Case 1 : If the command is the currently executing command,
- we'll set the aborted flag and return control so that the
- information transfer routine can exit cleanly. */
-if ((hostdata->connected == cmd) || (hostdata->sel_cmd == cmd)) {
- DEB_ABORT(printk("scsi%d: aborting connected command\n", instance->host_no));
- hostdata->aborted = 1;
- hostdata->msgout[0] = ABORT;
- sti();
- return(SCSI_ABORT_PENDING); }
-
-/* Case 2 : If the command hasn't been issued yet,
- we simply remove it from the issue queue. */
-for (prev = (Scsi_Cmnd **)&(hostdata->issue_queue),
- tmp = (Scsi_Cmnd *)hostdata->issue_queue; tmp;
- prev = (Scsi_Cmnd **)&(tmp->host_scribble),
- tmp = (Scsi_Cmnd *)tmp->host_scribble) {
- if (cmd == tmp) {
- DEB_ABORT(printk("scsi%d : abort removed command from issue queue.\n", instance->host_no));
- REMOVE(5, *prev, tmp, tmp->host_scribble);
- (*prev) = (Scsi_Cmnd *)tmp->host_scribble;
- tmp->host_scribble = NULL;
- tmp->result = DID_ABORT << 16;
- sti();
- tmp->done(tmp);
- return(SCSI_ABORT_SUCCESS); }
-#ifdef AM53C974_DEBUG_ABORT
- else {
- if (prev == (Scsi_Cmnd **)tmp)
- printk("scsi%d : LOOP\n", instance->host_no);
- }
-#endif
- }
-
-/* Case 3 : If any commands are connected, we're going to fail the abort
- * and let the high level SCSI driver retry at a later time or
- * issue a reset.
- *
- * Timeouts, and therefore aborted commands, will be highly unlikely
- * and handling them cleanly in this situation would make the common
- * case of noresets less efficient, and would pollute our code. So,
- * we fail. */
-if (hostdata->connected || hostdata->sel_cmd) {
- DEB_ABORT(printk("scsi%d : abort failed, other command connected.\n", instance->host_no));
- sti();
- return(SCSI_ABORT_NOT_RUNNING); }
-
-/* Case 4: If the command is currently disconnected from the bus, and
- * there are no connected commands, we reconnect the I_T_L or
- * I_T_L_Q nexus associated with it, go into message out, and send
- * an abort message. */
-for (tmp = (Scsi_Cmnd *)hostdata->disconnected_queue; tmp;
- tmp = (Scsi_Cmnd *)tmp->host_scribble) {
- if (cmd == tmp) {
- DEB_ABORT(printk("scsi%d: aborting disconnected command\n", instance->host_no));
- hostdata->aborted = 1;
- hostdata->msgout[0] = ABORT;
- hostdata->selecting = 1;
- hostdata->sel_cmd = tmp;
- AM53C974_write_8(CMDREG, CMDREG_DSR);
- sti();
- return(SCSI_ABORT_PENDING); }
- }
-
-/* Case 5 : If we reached this point, the command was not found in any of
- * the queues.
- *
- * We probably reached this point because of an unlikely race condition
- * between the command completing successfully and the abortion code,
- * so we won't panic, but we will notify the user in case something really
- * broke. */
-DEB_ABORT(printk("scsi%d : abort failed, command not found.\n", instance->host_no));
-sti();
-return(SCSI_ABORT_NOT_RUNNING);
-}
-
-/**************************************************************************
-* Function : int AM53C974_reset(Scsi_Cmnd *cmd)
-*
-* Purpose : reset the SCSI controller and bus
-*
-* Inputs : cmd -- which command within the command block was responsible for the reset
-*
-* Returns : status (SCSI_ABORT_SUCCESS)
-**************************************************************************/
-int AM53C974_reset(Scsi_Cmnd *cmd)
-{
-AM53C974_local_declare();
-int i;
-struct Scsi_Host *instance = cmd->host;
-struct AM53C974_hostdata *hostdata = (struct AM53C974_hostdata *)instance->hostdata;
-AM53C974_setio(instance);
-
-cli();
-DEB(printk("AM53C974_reset called; "));
-
-printk("AM53C974_reset called\n");
-AM53C974_print(instance);
-AM53C974_keywait();
-
-/* do hard reset */
-AM53C974_write_8(CMDREG, CMDREG_RDEV);
-AM53C974_write_8(CMDREG, CMDREG_NOP);
-hostdata->msgout[0] = NOP;
-for (i = 0; i < 8; i++) {
- hostdata->busy[i] = 0;
- hostdata->sync_per[i] = DEF_STP;
- hostdata->sync_off[i] = 0;
- hostdata->sync_neg[i] = 0; }
-hostdata->last_message[0] = NOP;
-hostdata->sel_cmd = NULL;
-hostdata->connected = NULL;
-hostdata->issue_queue = NULL;
-hostdata->disconnected_queue = NULL;
-hostdata->in_reset = 0;
-hostdata->aborted = 0;
-hostdata->selecting = 0;
-hostdata->disconnecting = 0;
-hostdata->dma_busy = 0;
-
-/* reset bus */
-AM53C974_write_8(CNTLREG1, CNTLREG1_DISR | instance->this_id); /* disable interrupt upon SCSI RESET */
-AM53C974_write_8(CMDREG, CMDREG_RBUS); /* reset SCSI bus */
-udelay(40);
-AM53C974_config_after_reset(instance);
-
-sti();
-cmd->result = DID_RESET << 16;
-cmd->scsi_done(cmd);
-return SCSI_ABORT_SUCCESS;
-}
diff --git a/i386/i386at/gpl/linux/scsi/AM53C974.h b/i386/i386at/gpl/linux/scsi/AM53C974.h
deleted file mode 100644
index 2a07a5a4..00000000
--- a/i386/i386at/gpl/linux/scsi/AM53C974.h
+++ /dev/null
@@ -1,419 +0,0 @@
-/* AM53/79C974 (PCscsi) driver release 0.5
- *
- * The architecture and much of the code of this device
- * driver was originally developed by Drew Eckhardt for
- * the NCR5380. The following copyrights apply:
- * For the architecture and all parts similar to the NCR5380:
- * Copyright 1993, Drew Eckhardt
- * Visionary Computing
- * (Unix and Linux consulting and custom programming)
- * drew@colorado.edu
- * +1 (303) 666-5836
- *
- * The AM53C974_nobios_detect code was origininally developed by
- * Robin Cutshaw (robin@xfree86.org) and is used here in a
- * modified form.
- *
- * For the other parts:
- * Copyright 1994, D. Frieauff
- * EMail: fri@rsx42sun0.dofn.de
- * Phone: x49-7545-8-2256 , x49-7541-42305
- */
-
-/*
- * $Log: AM53C974.h,v $
- * Revision 1.1.1.1 1996/10/30 01:39:58 thomas
- * Imported from UK22
- *
- * Revision 1.1 1996/03/25 20:25:06 goel
- * Linux driver merge.
- *
- */
-
-#ifndef AM53C974_H
-#define AM53C974_H
-
-#include <linux/scsicam.h>
-
-/***************************************************************************************
-* Default setting of the controller's SCSI id. Edit and uncomment this only if your *
-* BIOS does not correctly initialize the controller's SCSI id. *
-* If you don't get a warning during boot, it is correctly initialized. *
-****************************************************************************************/
-/* #define AM53C974_SCSI_ID 7 */
-
-/***************************************************************************************
-* Default settings for sync. negotiation enable, transfer rate and sync. offset. *
-* These settings can be replaced by LILO overrides (append) with the following syntax: *
-* AM53C974=host-scsi-id, target-scsi-id, max-rate, max-offset *
-* Sync. negotiation is disabled by default and will be enabled for those targets which *
-* are specified in the LILO override *
-****************************************************************************************/
-#define DEFAULT_SYNC_NEGOTIATION_ENABLED 0 /* 0 or 1 */
-#define DEFAULT_RATE 5 /* MHz, min: 3; max: 10 */
-#define DEFAULT_SYNC_OFFSET 0 /* bytes, min: 0; max: 15; use 0 for async. mode */
-
-
-/* --------------------- don't edit below here --------------------- */
-
-#define AM53C974_DRIVER_REVISION_MAJOR 0
-#define AM53C974_DRIVER_REVISION_MINOR 5
-#define SEPARATOR_LINE \
-"--------------------------------------------------------------------------\n"
-
-/* debug control */
-/* #define AM53C974_DEBUG */
-/* #define AM53C974_DEBUG_MSG */
-/* #define AM53C974_DEBUG_KEYWAIT */
-/* #define AM53C974_DEBUG_INIT */
-/* #define AM53C974_DEBUG_QUEUE */
-/* #define AM53C974_DEBUG_INFO */
-/* #define AM53C974_DEBUG_LINKED */
-/* #define VERBOSE_AM53C974_DEBUG */
-/* #define AM53C974_DEBUG_INTR */
-/* #define AM53C974_DEB_RESEL */
-#define AM53C974_DEBUG_ABORT
-/* #define AM53C974_OPTION_DEBUG_PROBE_ONLY */
-
-/* special options/constants */
-#define DEF_CLK 40 /* chip clock freq. in MHz */
-#define MIN_PERIOD 4 /* for negotiation: min. number of clocks per cycle */
-#define MAX_PERIOD 13 /* for negotiation: max. number of clocks per cycle */
-#define MAX_OFFSET 15 /* for negotiation: max. offset (0=async) */
-
-#define DEF_SCSI_TIMEOUT 245 /* STIMREG value, 40 Mhz */
-#define DEF_STP 8 /* STPREG value assuming 5.0 MB/sec, FASTCLK, FASTSCSI */
-#define DEF_SOF_RAD 0 /* REQ/ACK deassertion delay */
-#define DEF_SOF_RAA 0 /* REQ/ACK assertion delay */
-#define DEF_ETM 0 /* CNTLREG1, ext. timing mode */
-#define DEF_PERE 1 /* CNTLREG1, parity error reporting */
-#define DEF_CLKF 0 /* CLKFREG, 0=40 Mhz */
-#define DEF_ENF 1 /* CNTLREG2, enable features */
-#define DEF_ADIDCHK 0 /* CNTLREG3, additional ID check */
-#define DEF_FASTSCSI 1 /* CNTLREG3, fast SCSI */
-#define DEF_FASTCLK 1 /* CNTLREG3, fast clocking, 5 MB/sec at 40MHz chip clk */
-#define DEF_GLITCH 1 /* CNTLREG4, glitch eater, 0=12ns, 1=35ns, 2=25ns, 3=off */
-#define DEF_PWD 0 /* CNTLREG4, reduced power feature */
-#define DEF_RAE 0 /* CNTLREG4, RAE active negation on REQ, ACK only */
-#define DEF_RADE 1 /* 1CNTLREG4, active negation on REQ, ACK and data */
-
-/*** PCI block ***/
-/* standard registers are defined in <linux/pci.h> */
-#ifndef PCI_VENDOR_ID_AMD
-#define PCI_VENDOR_ID_AMD 0x1022
-#define PCI_DEVICE_ID_AMD_SCSI 0x2020
-#endif
-#define PCI_BASE_MASK 0xFFFFFFE0
-#define PCI_COMMAND_PERREN 0x40
-#define PCI_SCRATCH_REG_0 0x40 /* 16 bits */
-#define PCI_SCRATCH_REG_1 0x42 /* 16 bits */
-#define PCI_SCRATCH_REG_2 0x44 /* 16 bits */
-#define PCI_SCRATCH_REG_3 0x46 /* 16 bits */
-#define PCI_SCRATCH_REG_4 0x48 /* 16 bits */
-#define PCI_SCRATCH_REG_5 0x4A /* 16 bits */
-#define PCI_SCRATCH_REG_6 0x4C /* 16 bits */
-#define PCI_SCRATCH_REG_7 0x4E /* 16 bits */
-
-/*** SCSI block ***/
-#define CTCLREG 0x00 /* r current transf. count, low byte */
-#define CTCMREG 0x04 /* r current transf. count, middle byte */
-#define CTCHREG 0x38 /* r current transf. count, high byte */
-#define STCLREG 0x00 /* w start transf. count, low byte */
-#define STCMREG 0x04 /* w start transf. count, middle byte */
-#define STCHREG 0x38 /* w start transf. count, high byte */
-#define FFREG 0x08 /* rw SCSI FIFO reg. */
-#define STIMREG 0x14 /* w SCSI timeout reg. */
-
-#define SDIDREG 0x10 /* w SCSI destination ID reg. */
-#define SDIREG_MASK 0x07 /* mask */
-
-#define STPREG 0x18 /* w synchronous transf. period reg. */
-#define STPREG_STP 0x1F /* synchr. transfer period */
-
-#define CLKFREG 0x24 /* w clock factor reg. */
-#define CLKFREG_MASK 0x07 /* mask */
-
-#define CMDREG 0x0C /* rw SCSI command reg. */
-#define CMDREG_DMA 0x80 /* set DMA mode (set together with opcodes below) */
-#define CMDREG_IT 0x10 /* information transfer */
-#define CMDREG_ICCS 0x11 /* initiator command complete steps */
-#define CMDREG_MA 0x12 /* message accepted */
-#define CMDREG_TPB 0x98 /* transfer pad bytes, DMA mode only */
-#define CMDREG_SATN 0x1A /* set ATN */
-#define CMDREG_RATN 0x1B /* reset ATN */
-#define CMDREG_SOAS 0x41 /* select without ATN steps */
-#define CMDREG_SAS 0x42 /* select with ATN steps (1 msg byte) */
-#define CMDREG_SASS 0x43 /* select with ATN and stop steps */
-#define CMDREG_ESR 0x44 /* enable selection/reselection */
-#define CMDREG_DSR 0x45 /* disable selection/reselection */
-#define CMDREG_SA3S 0x46 /* select with ATN 3 steps (3 msg bytes) */
-#define CMDREG_NOP 0x00 /* no operation */
-#define CMDREG_CFIFO 0x01 /* clear FIFO */
-#define CMDREG_RDEV 0x02 /* reset device */
-#define CMDREG_RBUS 0x03 /* reset SCSI bus */
-
-#define STATREG 0x10 /* r SCSI status reg. */
-#define STATREG_INT 0x80 /* SCSI interrupt condition detected */
-#define STATREG_IOE 0x40 /* SCSI illegal operation error detected */
-#define STATREG_PE 0x20 /* SCSI parity error detected */
-#define STATREG_CTZ 0x10 /* CTC reg decremented to zero */
-#define STATREG_MSG 0x04 /* SCSI MSG phase (latched?) */
-#define STATREG_CD 0x02 /* SCSI C/D phase (latched?) */
-#define STATREG_IO 0x01 /* SCSI I/O phase (latched?) */
-#define STATREG_PHASE 0x07 /* SCSI phase mask */
-
-#define INSTREG 0x14 /* r interrupt status reg. */
-#define INSTREG_SRST 0x80 /* SCSI reset detected */
-#define INSTREG_ICMD 0x40 /* SCSI invalid command detected */
-#define INSTREG_DIS 0x20 /* target disconnected or sel/resel timeout*/
-#define INSTREG_SR 0x10 /* device on bus has service request */
-#define INSTREG_SO 0x08 /* successful operation */
-#define INSTREG_RESEL 0x04 /* device reselected as initiator */
-
-#define ISREG 0x18 /* r internal state reg. */
-#define ISREG_SOF 0x08 /* synchronous offset flag (act. low) */
-#define ISREG_IS 0x07 /* status of intermediate op. */
-#define ISREG_OK_NO_STOP 0x04 /* selection successful */
-#define ISREG_OK_STOP 0x01 /* selection successful */
-
-#define CFIREG 0x1C /* r current FIFO/internal state reg. */
-#define CFIREG_IS 0xE0 /* status of intermediate op. */
-#define CFIREG_CF 0x1F /* number of bytes in SCSI FIFO */
-
-#define SOFREG 0x1C /* w synchr. offset reg. */
-#define SOFREG_RAD 0xC0 /* REQ/ACK deassertion delay (sync.) */
-#define SOFREG_RAA 0x30 /* REQ/ACK assertion delay (sync.) */
-#define SOFREG_SO 0x0F /* synch. offset (sync.) */
-
-#define CNTLREG1 0x20 /* rw control register one */
-#define CNTLREG1_ETM 0x80 /* set extended timing mode */
-#define CNTLREG1_DISR 0x40 /* disable interrupt on SCSI reset */
-#define CNTLREG1_PERE 0x10 /* enable parity error reporting */
-#define CNTLREG1_SID 0x07 /* host adapter SCSI ID */
-
-#define CNTLREG2 0x2C /* rw control register two */
-#define CNTLREG2_ENF 0x40 /* enable features */
-
-#define CNTLREG3 0x30 /* rw control register three */
-#define CNTLREG3_ADIDCHK 0x80 /* additional ID check */
-#define CNTLREG3_FASTSCSI 0x10 /* fast SCSI */
-#define CNTLREG3_FASTCLK 0x08 /* fast SCSI clocking */
-
-#define CNTLREG4 0x34 /* rw control register four */
-#define CNTLREG4_GLITCH 0xC0 /* glitch eater */
-#define CNTLREG4_PWD 0x20 /* reduced power feature */
-#define CNTLREG4_RAE 0x08 /* write only, active negot. ctrl. */
-#define CNTLREG4_RADE 0x04 /* active negot. ctrl. */
-#define CNTLREG4_RES 0x10 /* reserved bit, must be 1 */
-
-/*** DMA block ***/
-#define DMACMD 0x40 /* rw command */
-#define DMACMD_DIR 0x80 /* transfer direction (1=read from device) */
-#define DMACMD_INTE_D 0x40 /* DMA transfer interrupt enable */
-#define DMACMD_INTE_P 0x20 /* page transfer interrupt enable */
-#define DMACMD_MDL 0x10 /* map to memory descriptor list */
-#define DMACMD_DIAG 0x04 /* diagnostics, set to 0 */
-#define DMACMD_IDLE 0x00 /* idle cmd */
-#define DMACMD_BLAST 0x01 /* flush FIFO to memory */
-#define DMACMD_ABORT 0x02 /* terminate DMA */
-#define DMACMD_START 0x03 /* start DMA */
-
-#define DMASTATUS 0x54 /* r status register */
-#define DMASTATUS_BCMPLT 0x20 /* BLAST complete */
-#define DMASTATUS_SCSIINT 0x10 /* SCSI interrupt pending */
-#define DMASTATUS_DONE 0x08 /* DMA transfer terminated */
-#define DMASTATUS_ABORT 0x04 /* DMA transfer aborted */
-#define DMASTATUS_ERROR 0x02 /* DMA transfer error */
-#define DMASTATUS_PWDN 0x02 /* power down indicator */
-
-#define DMASTC 0x44 /* rw starting transfer count */
-#define DMASPA 0x48 /* rw starting physical address */
-#define DMAWBC 0x4C /* r working byte counter */
-#define DMAWAC 0x50 /* r working address counter */
-#define DMASMDLA 0x58 /* rw starting MDL address */
-#define DMAWMAC 0x5C /* r working MDL counter */
-
-/*** SCSI phases ***/
-#define PHASE_MSGIN 0x07
-#define PHASE_MSGOUT 0x06
-#define PHASE_RES_1 0x05
-#define PHASE_RES_0 0x04
-#define PHASE_STATIN 0x03
-#define PHASE_CMDOUT 0x02
-#define PHASE_DATAIN 0x01
-#define PHASE_DATAOUT 0x00
-
-struct AM53C974_hostdata {
- volatile unsigned in_reset:1; /* flag, says bus reset pending */
- volatile unsigned aborted:1; /* flag, says aborted */
- volatile unsigned selecting:1; /* selection started, but not yet finished */
- volatile unsigned disconnecting: 1; /* disconnection started, but not yet finished */
- volatile unsigned dma_busy:1; /* dma busy when service request for info transfer received */
- volatile unsigned char msgout[10]; /* message to output in MSGOUT_PHASE */
- volatile unsigned char last_message[10]; /* last message OUT */
- volatile Scsi_Cmnd *issue_queue; /* waiting to be issued */
- volatile Scsi_Cmnd *disconnected_queue; /* waiting for reconnect */
- volatile Scsi_Cmnd *sel_cmd; /* command for selection */
- volatile Scsi_Cmnd *connected; /* currently connected command */
- volatile unsigned char busy[8]; /* index = target, bit = lun */
- unsigned char sync_per[8]; /* synchronous transfer period (in effect) */
- unsigned char sync_off[8]; /* synchronous offset (in effect) */
- unsigned char sync_neg[8]; /* sync. negotiation performed (in effect) */
- unsigned char sync_en[8]; /* sync. negotiation performed (in effect) */
- unsigned char max_rate[8]; /* max. transfer rate (setup) */
- unsigned char max_offset[8]; /* max. sync. offset (setup), only valid if corresponding sync_en is nonzero */
- };
-
-#define AM53C974 { \
- NULL, /* pointer to next in list */ \
- NULL, /* long * usage_count */ \
- NULL, /* struct proc_dir_entry *proc_dir */ \
- NULL, /* int (*proc_info)(char *, char **, off_t, int, int, int); */ \
- "AM53C974", /* name */ \
- AM53C974_detect, /* int (* detect)(struct SHT *) */ \
- NULL, /* int (*release)(struct Scsi_Host *) */ \
- AM53C974_info, /* const char *(* info)(struct Scsi_Host *) */ \
- AM53C974_command, /* int (* command)(Scsi_Cmnd *) */ \
- AM53C974_queue_command, /* int (* queuecommand)(Scsi_Cmnd *, \
- void (*done)(Scsi_Cmnd *)) */ \
- AM53C974_abort, /* int (* abort)(Scsi_Cmnd *) */ \
- AM53C974_reset, /* int (* reset)(Scsi_Cmnd *) */ \
- NULL, /* int (* slave_attach)(int, int) */ \
- scsicam_bios_param, /* int (* bios_param)(Disk *, int, int[]) */ \
- 12, /* can_queue */ \
- -1, /* this_id */ \
- SG_ALL, /* sg_tablesize */ \
- 1, /* cmd_per_lun */ \
- 0, /* present, i.e. how many adapters of this kind */ \
- 0, /* unchecked_isa_dma */ \
- DISABLE_CLUSTERING /* use_clustering */ \
- }
-
-void AM53C974_setup(char *str, int *ints);
-int AM53C974_detect(Scsi_Host_Template *tpnt);
-int AM53C974_biosparm(Disk *disk, int dev, int *info_array);
-const char *AM53C974_info(struct Scsi_Host *);
-int AM53C974_command(Scsi_Cmnd *SCpnt);
-int AM53C974_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *));
-int AM53C974_abort(Scsi_Cmnd *cmd);
-int AM53C974_reset (Scsi_Cmnd *cmd);
-
-#define AM53C974_local_declare() unsigned long io_port
-#define AM53C974_setio(instance) io_port = instance->io_port
-#define AM53C974_read_8(addr) inb(io_port + (addr))
-#define AM53C974_write_8(addr,x) outb((x), io_port + (addr))
-#define AM53C974_read_16(addr) inw(io_port + (addr))
-#define AM53C974_write_16(addr,x) outw((x), io_port + (addr))
-#define AM53C974_read_32(addr) inl(io_port + (addr))
-#define AM53C974_write_32(addr,x) outl((x), io_port + (addr))
-
-#define AM53C974_poll_int() { do { statreg = AM53C974_read_8(STATREG); } \
- while (!(statreg & STATREG_INT)) ; \
- AM53C974_read_8(INSTREG) ; } /* clear int */
-#define AM53C974_cfifo() (AM53C974_read_8(CFIREG) & CFIREG_CF)
-
-/* These are "special" values for the tag parameter passed to AM53C974_select. */
-#define TAG_NEXT -1 /* Use next free tag */
-#define TAG_NONE -2 /* Establish I_T_L nexus instead of I_T_L_Q
- * even on SCSI-II devices */
-
-/************ LILO overrides *************/
-typedef struct _override_t {
- int host_scsi_id; /* SCSI id of the bus controller */
- int target_scsi_id; /* SCSI id of target */
- int max_rate; /* max. transfer rate */
- int max_offset; /* max. sync. offset, 0 = asynchronous */
- } override_t;
-
-/************ PCI stuff *************/
-#define AM53C974_PCIREG_OPEN() outb(0xF1, 0xCF8); outb(0, 0xCFA)
-#define AM53C974_PCIREG_CLOSE() outb(0, 0xCF8)
-#define AM53C974_PCIREG_READ_BYTE(instance,a) ( inb((a) + (instance)->io_port) )
-#define AM53C974_PCIREG_READ_WORD(instance,a) ( inw((a) + (instance)->io_port) )
-#define AM53C974_PCIREG_READ_DWORD(instance,a) ( inl((a) + (instance)->io_port) )
-#define AM53C974_PCIREG_WRITE_BYTE(instance,x,a) ( outb((x), (a) + (instance)->io_port) )
-#define AM53C974_PCIREG_WRITE_WORD(instance,x,a) ( outw((x), (a) + (instance)->io_port) )
-#define AM53C974_PCIREG_WRITE_DWORD(instance,x,a) ( outl((x), (a) + (instance)->io_port) )
-
-typedef struct _pci_config_t {
- /* start of official PCI config space header */
- union {
- unsigned int device_vendor;
- struct {
- unsigned short vendor;
- unsigned short device;
- } dv;
- } dv_id;
-#define _device_vendor dv_id.device_vendor
-#define _vendor dv_id.dv.vendor
-#define _device dv_id.dv.device
- union {
- unsigned int status_command;
- struct {
- unsigned short command;
- unsigned short status;
- } sc;
- } stat_cmd;
-#define _status_command stat_cmd.status_command
-#define _command stat_cmd.sc.command
-#define _status stat_cmd.sc.status
- union {
- unsigned int class_revision;
- struct {
- unsigned char rev_id;
- unsigned char prog_if;
- unsigned char sub_class;
- unsigned char base_class;
- } cr;
- } class_rev;
-#define _class_revision class_rev.class_revision
-#define _rev_id class_rev.cr.rev_id
-#define _prog_if class_rev.cr.prog_if
-#define _sub_class class_rev.cr.sub_class
-#define _base_class class_rev.cr.base_class
- union {
- unsigned int bist_header_latency_cache;
- struct {
- unsigned char cache_line_size;
- unsigned char latency_timer;
- unsigned char header_type;
- unsigned char bist;
- } bhlc;
- } bhlc;
-#define _bist_header_latency_cache bhlc.bist_header_latency_cache
-#define _cache_line_size bhlc.bhlc.cache_line_size
-#define _latency_timer bhlc.bhlc.latency_timer
-#define _header_type bhlc.bhlc.header_type
-#define _bist bhlc.bhlc.bist
- unsigned int _base0;
- unsigned int _base1;
- unsigned int _base2;
- unsigned int _base3;
- unsigned int _base4;
- unsigned int _base5;
- unsigned int rsvd1;
- unsigned int rsvd2;
- unsigned int _baserom;
- unsigned int rsvd3;
- unsigned int rsvd4;
- union {
- unsigned int max_min_ipin_iline;
- struct {
- unsigned char int_line;
- unsigned char int_pin;
- unsigned char min_gnt;
- unsigned char max_lat;
- } mmii;
- } mmii;
-#define _max_min_ipin_iline mmii.max_min_ipin_iline
-#define _int_line mmii.mmii.int_line
-#define _int_pin mmii.mmii.int_pin
-#define _min_gnt mmii.mmii.min_gnt
-#define _max_lat mmii.mmii.max_lat
- /* end of official PCI config space header */
- unsigned short _ioaddr; /* config type 1 - private I/O addr */
- unsigned int _pcibus; /* config type 2 - private bus id */
- unsigned int _cardnum; /* config type 2 - private card number */
-} pci_config_t;
-
-#endif /* AM53C974_H */
diff --git a/i386/i386at/gpl/linux/scsi/BusLogic.c b/i386/i386at/gpl/linux/scsi/BusLogic.c
deleted file mode 100644
index 7472dc3d..00000000
--- a/i386/i386at/gpl/linux/scsi/BusLogic.c
+++ /dev/null
@@ -1,2779 +0,0 @@
-/*
-
- Linux Driver for BusLogic MultiMaster SCSI Host Adapters
-
- Copyright 1995 by Leonard N. Zubkoff <lnz@dandelion.com>
-
- This program is free software; you may redistribute and/or modify it under
- the terms of the GNU General Public License Version 2 as published by the
- Free Software Foundation, provided that none of the source code or runtime
- copyright notices are removed or modified.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- for complete details.
-
- The author respectfully requests that all modifications to this software be
- sent directly to him for evaluation and testing.
-
- Special thanks to Alex T. Win of BusLogic, whose advice has been invaluable,
- to David B. Gentzel, for writing the original Linux BusLogic driver, and to
- Paul Gortmaker, for being such a dedicated test site.
-
-*/
-
-
-#define BusLogic_DriverVersion "1.3.1"
-#define BusLogic_DriverDate "31 December 1995"
-
-
-#include <linux/module.h>
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/blkdev.h>
-#include <linux/delay.h>
-#include <linux/ioport.h>
-#include <linux/kernel_stat.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/stat.h>
-#include <linux/pci.h>
-#include <linux/bios32.h>
-#include <asm/dma.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include "scsi.h"
-#include "hosts.h"
-#include "sd.h"
-#include "BusLogic.h"
-
-
-/*
- BusLogic_CommandLineEntryCount is a count of the number of "BusLogic="
- entries provided on the Linux Kernel Command Line.
-*/
-
-static int
- BusLogic_CommandLineEntryCount = 0;
-
-
-/*
- BusLogic_CommandLineEntries is an array of Command Line Entry structures
- representing the "BusLogic=" entries provided on the Linux Kernel Command
- Line.
-*/
-
-static BusLogic_CommandLineEntry_T
- BusLogic_CommandLineEntries[BusLogic_MaxHostAdapters];
-
-
-/*
- BusLogic_GlobalOptions is a bit mask of Global Options to be applied
- across all Host Adapters.
-*/
-
-static int
- BusLogic_GlobalOptions = 0;
-
-
-/*
- BusLogic_RegisteredHostAdapters is a linked list of all the registered
- BusLogic Host Adapters.
-*/
-
-static BusLogic_HostAdapter_T
- *BusLogic_RegisteredHostAdapters = NULL;
-
-
-/*
- BusLogic_Standard_IO_Addresses is the list of standard I/O Addresses at which
- BusLogic Host Adapters may potentially be found.
-*/
-
-static unsigned short
- BusLogic_IO_StandardAddresses[] =
- { 0x330, 0x334, 0x230, 0x234, 0x130, 0x134, 0 };
-
-
-/*
- BusLogic_IO_AddressProbeList is the list of I/O Addresses to be probed for
- potential BusLogic Host Adapters. It is initialized by interrogating the
- PCI Configuration Space on PCI machines as well as from the list of
- standard BusLogic I/O Addresses.
-*/
-
-static unsigned short
- BusLogic_IO_AddressProbeList[BusLogic_IO_MaxProbeAddresses+1] = { 0 };
-
-
-/*
- BusLogic_IRQ_UsageCount stores a count of the number of Host Adapters using
- a given IRQ Channel, which is necessary to support PCI, EISA, or MCA shared
- interrupts. Only IRQ Channels 9, 10, 11, 12, 14, and 15 are supported by
- BusLogic Host Adapters.
-*/
-
-static short
- BusLogic_IRQ_UsageCount[7] = { 0 };
-
-
-/*
- BusLogic_CommandFailureReason holds a string identifying the reason why a
- call to BusLogic_Command failed. It is only valid when BusLogic_Command
- returns a failure code.
-*/
-
-static char
- *BusLogic_CommandFailureReason;
-
-
-/*
- BusLogic_ProcDirectoryEntry is the BusLogic /proc/scsi directory entry.
-*/
-
-static struct proc_dir_entry
- BusLogic_ProcDirectoryEntry =
- { PROC_SCSI_BUSLOGIC, 8, "BusLogic", S_IFDIR | S_IRUGO | S_IXUGO, 2 };
-
-
-/*
- BusLogic_AnnounceDriver announces the Driver Version and Date, Author's
- Name, Copyright Notice, and Contact Address.
-*/
-
-static void BusLogic_AnnounceDriver(void)
-{
- static boolean DriverAnnouncementPrinted = false;
- if (DriverAnnouncementPrinted) return;
- printk("scsi: ***** BusLogic SCSI Driver Version "
- BusLogic_DriverVersion " of " BusLogic_DriverDate " *****\n");
- printk("scsi: Copyright 1995 by Leonard N. Zubkoff <lnz@dandelion.com>\n");
- DriverAnnouncementPrinted = true;
-}
-
-
-/*
- BusLogic_DriverInfo returns the Board Name to identify this SCSI Driver
- and Host Adapter.
-*/
-
-const char *BusLogic_DriverInfo(SCSI_Host_T *Host)
-{
- BusLogic_HostAdapter_T *HostAdapter =
- (BusLogic_HostAdapter_T *) Host->hostdata;
- return HostAdapter->BoardName;
-}
-
-
-/*
- BusLogic_InitializeAddressProbeList initializes the list of I/O Addresses
- to be probed for potential BusLogic SCSI Host Adapters by interrogating the
- PCI Configuration Space on PCI machines as well as from the list of standard
- BusLogic I/O Addresses.
-*/
-
-static void BusLogic_InitializeAddressProbeList(void)
-{
- int DestinationIndex = 0, SourceIndex = 0;
- /*
- If BusLogic_Setup has been called, do not override the Kernel Command
- Line specifications.
- */
- if (BusLogic_IO_AddressProbeList[0] != 0) return;
-#ifdef CONFIG_PCI
- /*
- Interrogate PCI Configuration Space for any BusLogic SCSI Host Adapters.
- */
- if (pcibios_present())
- {
- unsigned short Index = 0, VendorID;
- unsigned char Bus, DeviceAndFunction;
- unsigned int BaseAddress0;
- while (pcibios_find_class(PCI_CLASS_STORAGE_SCSI<<8, Index++,
- &Bus, &DeviceAndFunction) == 0)
- if (pcibios_read_config_word(Bus, DeviceAndFunction,
- PCI_VENDOR_ID, &VendorID) == 0 &&
- VendorID == PCI_VENDOR_ID_BUSLOGIC &&
- pcibios_read_config_dword(Bus, DeviceAndFunction,
- PCI_BASE_ADDRESS_0, &BaseAddress0) == 0 &&
- (BaseAddress0 & PCI_BASE_ADDRESS_SPACE) ==
- PCI_BASE_ADDRESS_SPACE_IO)
- {
- BusLogic_IO_AddressProbeList[DestinationIndex++] =
- BaseAddress0 & PCI_BASE_ADDRESS_IO_MASK;
- }
- }
-#endif
- /*
- Append the list of standard BusLogic I/O Addresses.
- */
- while (DestinationIndex < BusLogic_IO_MaxProbeAddresses &&
- BusLogic_IO_StandardAddresses[SourceIndex] > 0)
- BusLogic_IO_AddressProbeList[DestinationIndex++] =
- BusLogic_IO_StandardAddresses[SourceIndex++];
- BusLogic_IO_AddressProbeList[DestinationIndex] = 0;
-}
-
-
-/*
- BusLogic_RegisterHostAdapter adds Host Adapter to the list of registered
- BusLogic Host Adapters.
-*/
-
-static void BusLogic_RegisterHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
-{
- HostAdapter->Next = NULL;
- if (BusLogic_RegisteredHostAdapters != NULL)
- {
- BusLogic_HostAdapter_T *LastHostAdapter = BusLogic_RegisteredHostAdapters;
- BusLogic_HostAdapter_T *NextHostAdapter;
- while ((NextHostAdapter = LastHostAdapter->Next) != NULL)
- LastHostAdapter = NextHostAdapter;
- LastHostAdapter->Next = HostAdapter;
- }
- else BusLogic_RegisteredHostAdapters = HostAdapter;
-}
-
-
-/*
- BusLogic_UnregisterHostAdapter removes Host Adapter from the list of
- registered BusLogic Host Adapters.
-*/
-
-static void BusLogic_UnregisterHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
-{
- if (BusLogic_RegisteredHostAdapters != HostAdapter)
- {
- BusLogic_HostAdapter_T *LastHostAdapter = BusLogic_RegisteredHostAdapters;
- while (LastHostAdapter != NULL && LastHostAdapter->Next != HostAdapter)
- LastHostAdapter = LastHostAdapter->Next;
- if (LastHostAdapter != NULL)
- LastHostAdapter->Next = HostAdapter->Next;
- }
- else BusLogic_RegisteredHostAdapters = HostAdapter->Next;
- HostAdapter->Next = NULL;
-}
-
-
-/*
- BusLogic_CreateCCBs allocates the initial Command Control Blocks (CCBs)
- for Host Adapter.
-*/
-
-static boolean BusLogic_CreateCCBs(BusLogic_HostAdapter_T *HostAdapter)
-{
- int i;
- for (i = 0; i < BusLogic_InitialCCBs; i++)
- {
- BusLogic_CCB_T *CCB = (BusLogic_CCB_T *)
- scsi_init_malloc(sizeof(BusLogic_CCB_T), GFP_ATOMIC | GFP_DMA);
- if (CCB == NULL)
- {
- printk("scsi%d: UNABLE TO ALLOCATE CCB %d - DETACHING\n",
- HostAdapter->HostNumber, i);
- return false;
- }
- memset(CCB, 0, sizeof(BusLogic_CCB_T));
- CCB->HostAdapter = HostAdapter;
- CCB->Status = BusLogic_CCB_Free;
- CCB->Next = HostAdapter->Free_CCBs;
- CCB->NextAll = HostAdapter->All_CCBs;
- HostAdapter->Free_CCBs = CCB;
- HostAdapter->All_CCBs = CCB;
- }
- return true;
-}
-
-
-/*
- BusLogic_DestroyCCBs deallocates the CCBs for Host Adapter.
-*/
-
-static void BusLogic_DestroyCCBs(BusLogic_HostAdapter_T *HostAdapter)
-{
- BusLogic_CCB_T *NextCCB = HostAdapter->All_CCBs, *CCB;
- HostAdapter->All_CCBs = NULL;
- HostAdapter->Free_CCBs = NULL;
- while ((CCB = NextCCB) != NULL)
- {
- NextCCB = CCB->NextAll;
- scsi_init_free((char *) CCB, sizeof(BusLogic_CCB_T));
- }
-}
-
-
-/*
- BusLogic_AllocateCCB allocates a CCB from the Host Adapter's free list,
- allocating more memory from the Kernel if necessary.
-*/
-
-static BusLogic_CCB_T *BusLogic_AllocateCCB(BusLogic_HostAdapter_T *HostAdapter)
-{
- static unsigned int SerialNumber = 0;
- BusLogic_CCB_T *CCB;
- BusLogic_LockHostAdapter(HostAdapter);
- CCB = HostAdapter->Free_CCBs;
- if (CCB != NULL)
- {
- CCB->SerialNumber = ++SerialNumber;
- HostAdapter->Free_CCBs = CCB->Next;
- CCB->Next = NULL;
- BusLogic_UnlockHostAdapter(HostAdapter);
- return CCB;
- }
- BusLogic_UnlockHostAdapter(HostAdapter);
- CCB = (BusLogic_CCB_T *) scsi_init_malloc(sizeof(BusLogic_CCB_T),
- GFP_ATOMIC | GFP_DMA);
- if (CCB == NULL)
- {
- printk("scsi%d: Failed to allocate an additional CCB\n",
- HostAdapter->HostNumber);
- return NULL;
- }
- printk("scsi%d: Allocated an additional CCB\n", HostAdapter->HostNumber);
- memset(CCB, 0, sizeof(BusLogic_CCB_T));
- CCB->HostAdapter = HostAdapter;
- CCB->Status = BusLogic_CCB_Free;
- BusLogic_LockHostAdapter(HostAdapter);
- CCB->SerialNumber = ++SerialNumber;
- CCB->NextAll = HostAdapter->All_CCBs;
- HostAdapter->All_CCBs = CCB;
- BusLogic_UnlockHostAdapter(HostAdapter);
- return CCB;
-}
-
-
-/*
- BusLogic_DeallocateCCB deallocates a CCB, returning it to the Host Adapter's
- free list.
-*/
-
-static void BusLogic_DeallocateCCB(BusLogic_CCB_T *CCB)
-{
- BusLogic_HostAdapter_T *HostAdapter = CCB->HostAdapter;
- BusLogic_LockHostAdapter(HostAdapter);
- CCB->Command = NULL;
- CCB->Status = BusLogic_CCB_Free;
- CCB->Next = HostAdapter->Free_CCBs;
- HostAdapter->Free_CCBs = CCB;
- BusLogic_UnlockHostAdapter(HostAdapter);
-}
-
-
-/*
- BusLogic_Command sends the command OperationCode to HostAdapter, optionally
- providing ParameterLength bytes of ParameterData and receiving at most
- ReplyLength bytes of ReplyData; any excess reply data is received but
- discarded.
-
- On success, this function returns the number of reply bytes read from
- the Host Adapter (including any discarded data); on failure, it returns
- -1 if the command was invalid, or -2 if a timeout occurred.
-
- This function is only called during board detection and initialization, so
- performance and latency are not critical, and exclusive access to the Host
- Adapter hardware is assumed. Once the board and driver are initialized, the
- only Host Adapter command that is issued is the single byte Start Mailbox
- Scan command, which does not require waiting for the Host Adapter Ready bit
- to be set in the Status Register.
-*/
-
-static int BusLogic_Command(BusLogic_HostAdapter_T *HostAdapter,
- BusLogic_OperationCode_T OperationCode,
- void *ParameterData,
- int ParameterLength,
- void *ReplyData,
- int ReplyLength)
-{
- unsigned char *ParameterPointer = (unsigned char *) ParameterData;
- unsigned char *ReplyPointer = (unsigned char *) ReplyData;
- unsigned char StatusRegister = 0, InterruptRegister;
- long TimeoutCounter;
- int ReplyBytes = 0;
- /*
- Clear out the Reply Data if provided.
- */
- if (ReplyLength > 0)
- memset(ReplyData, 0, ReplyLength);
- /*
- Wait for the Host Adapter Ready bit to be set and the Command/Parameter
- Register Busy bit to be reset in the Status Register.
- */
- TimeoutCounter = loops_per_sec >> 3;
- while (--TimeoutCounter >= 0)
- {
- StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
- if ((StatusRegister & BusLogic_HostAdapterReady) &&
- !(StatusRegister & BusLogic_CommandParameterRegisterBusy))
- break;
- }
- BusLogic_CommandFailureReason = "Timeout waiting for Host Adapter Ready";
- if (TimeoutCounter < 0) return -2;
- /*
- Write the OperationCode to the Command/Parameter Register.
- */
- HostAdapter->HostAdapterCommandCompleted = false;
- BusLogic_WriteCommandParameterRegister(HostAdapter, OperationCode);
- /*
- Write any additional Parameter Bytes.
- */
- TimeoutCounter = 10000;
- while (ParameterLength > 0 && --TimeoutCounter >= 0)
- {
- /*
- Wait 100 microseconds to give the Host Adapter enough time to determine
- whether the last value written to the Command/Parameter Register was
- valid or not. If the Command Complete bit is set in the Interrupt
- Register, then the Command Invalid bit in the Status Register will be
- reset if the Operation Code or Parameter was valid and the command
- has completed, or set if the Operation Code or Parameter was invalid.
- If the Data In Register Ready bit is set in the Status Register, then
- the Operation Code was valid, and data is waiting to be read back
- from the Host Adapter. Otherwise, wait for the Command/Parameter
- Register Busy bit in the Status Register to be reset.
- */
- udelay(100);
- InterruptRegister = BusLogic_ReadInterruptRegister(HostAdapter);
- StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
- if (InterruptRegister & BusLogic_CommandComplete) break;
- if (HostAdapter->HostAdapterCommandCompleted) break;
- if (StatusRegister & BusLogic_DataInRegisterReady) break;
- if (StatusRegister & BusLogic_CommandParameterRegisterBusy) continue;
- BusLogic_WriteCommandParameterRegister(HostAdapter, *ParameterPointer++);
- ParameterLength--;
- }
- BusLogic_CommandFailureReason = "Timeout waiting for Parameter Acceptance";
- if (TimeoutCounter < 0) return -2;
- /*
- The Modify I/O Address command does not cause a Command Complete Interrupt.
- */
- if (OperationCode == BusLogic_ModifyIOAddress)
- {
- StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
- BusLogic_CommandFailureReason = "Modify I/O Address Invalid";
- if (StatusRegister & BusLogic_CommandInvalid) return -1;
- BusLogic_CommandFailureReason = NULL;
- return 0;
- }
- /*
- Select an appropriate timeout value for awaiting command completion.
- */
- switch (OperationCode)
- {
- case BusLogic_InquireInstalledDevicesID0to7:
- case BusLogic_InquireInstalledDevicesID8to15:
- /* Approximately 60 seconds. */
- TimeoutCounter = loops_per_sec << 2;
- break;
- default:
- /* Approximately 1 second. */
- TimeoutCounter = loops_per_sec >> 4;
- break;
- }
- /*
- Receive any Reply Bytes, waiting for either the Command Complete bit to
- be set in the Interrupt Register, or for the Interrupt Handler to set the
- Host Adapter Command Completed bit in the Host Adapter structure.
- */
- while (--TimeoutCounter >= 0)
- {
- InterruptRegister = BusLogic_ReadInterruptRegister(HostAdapter);
- StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
- if (InterruptRegister & BusLogic_CommandComplete) break;
- if (HostAdapter->HostAdapterCommandCompleted) break;
- if (StatusRegister & BusLogic_DataInRegisterReady)
- if (++ReplyBytes <= ReplyLength)
- *ReplyPointer++ = BusLogic_ReadDataInRegister(HostAdapter);
- else BusLogic_ReadDataInRegister(HostAdapter);
- }
- BusLogic_CommandFailureReason = "Timeout waiting for Command Complete";
- if (TimeoutCounter < 0) return -2;
- /*
- If testing Command Complete Interrupts, wait a short while in case the
- loop immediately above terminated due to the Command Complete bit being
- set in the Interrupt Register, but the interrupt hasn't actually been
- processed yet. Otherwise, acknowledging the interrupt here could prevent
- the interrupt test from succeeding.
- */
- if (OperationCode == BusLogic_TestCommandCompleteInterrupt)
- udelay(10000);
- /*
- Clear any pending Command Complete Interrupt.
- */
- BusLogic_WriteControlRegister(HostAdapter, BusLogic_InterruptReset);
- if (BusLogic_GlobalOptions & BusLogic_TraceConfiguration)
- if (OperationCode != BusLogic_TestCommandCompleteInterrupt)
- {
- int i;
- printk("BusLogic_Command(%02X) Status = %02X: %2d ==> %2d:",
- OperationCode, StatusRegister, ReplyLength, ReplyBytes);
- if (ReplyLength > ReplyBytes) ReplyLength = ReplyBytes;
- for (i = 0; i < ReplyLength; i++)
- printk(" %02X", ((unsigned char *) ReplyData)[i]);
- printk("\n");
- }
- /*
- Process Command Invalid conditions.
- */
- if (StatusRegister & BusLogic_CommandInvalid)
- {
- /*
- Some early BusLogic Host Adapters may not recover properly from
- a Command Invalid condition, so if this appears to be the case,
- a Soft Reset is issued to the Host Adapter. Potentially invalid
- commands are never attempted after Mailbox Initialization is
- performed, so there should be no Host Adapter state lost by a
- Soft Reset in response to a Command Invalid condition.
- */
- udelay(1000);
- StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
- if (StatusRegister != (BusLogic_HostAdapterReady |
- BusLogic_InitializationRequired))
- {
- BusLogic_WriteControlRegister(HostAdapter, BusLogic_SoftReset);
- udelay(1000);
- }
- BusLogic_CommandFailureReason = "Command Invalid";
- return -1;
- }
- /*
- Handle Excess Parameters Supplied conditions.
- */
- BusLogic_CommandFailureReason = "Excess Parameters Supplied";
- if (ParameterLength > 0) return -1;
- /*
- Indicate the command completed successfully.
- */
- BusLogic_CommandFailureReason = NULL;
- return ReplyBytes;
-}
-
-
-/*
- BusLogic_Failure prints a standardized error message, and then returns false.
-*/
-
-static boolean BusLogic_Failure(BusLogic_HostAdapter_T *HostAdapter,
- char *ErrorMessage)
-{
- BusLogic_AnnounceDriver();
- printk("While configuring BusLogic Host Adapter at I/O Address 0x%X:\n",
- HostAdapter->IO_Address);
- printk("%s FAILED - DETACHING\n", ErrorMessage);
- if (BusLogic_CommandFailureReason != NULL)
- printk("ADDITIONAL FAILURE INFO - %s\n", BusLogic_CommandFailureReason);
- return false;
-}
-
-
-/*
- BusLogic_ProbeHostAdapter probes for a BusLogic Host Adapter.
-*/
-
-static boolean BusLogic_ProbeHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
-{
- boolean TraceProbe = (BusLogic_GlobalOptions & BusLogic_TraceProbe);
- unsigned char StatusRegister, GeometryRegister;
- /*
- Read the Status Register to test if there is an I/O port that responds. A
- nonexistent I/O port will return 0xFF, in which case there is definitely no
- BusLogic Host Adapter at this base I/O Address.
- */
- StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
- if (TraceProbe)
- printk("BusLogic_Probe(0x%X): Status 0x%02X\n",
- HostAdapter->IO_Address, StatusRegister);
- if (StatusRegister == 0xFF) return false;
- /*
- Read the undocumented BusLogic Geometry Register to test if there is an I/O
- port that responds. Adaptec Host Adapters do not implement the Geometry
- Register, so this test helps serve to avoid incorrectly recognizing an
- Adaptec 1542A or 1542B as a BusLogic. Unfortunately, the Adaptec 1542C
- series does respond to the Geometry Register I/O port, but it will be
- rejected later when the Inquire Extended Setup Information command is
- issued in BusLogic_CheckHostAdapter. The AMI FastDisk Host Adapter is a
- BusLogic clone that implements the same interface as earlier BusLogic
- boards, including the undocumented commands, and is therefore supported by
- this driver. However, the AMI FastDisk always returns 0x00 upon reading
- the Geometry Register, so the extended translation option should always be
- left disabled on the AMI FastDisk.
- */
- GeometryRegister = BusLogic_ReadGeometryRegister(HostAdapter);
- if (TraceProbe)
- printk("BusLogic_Probe(0x%X): Geometry 0x%02X\n",
- HostAdapter->IO_Address, GeometryRegister);
- if (GeometryRegister == 0xFF) return false;
- /*
- Indicate the Host Adapter Probe completed successfully.
- */
- return true;
-}
-
-
-/*
- BusLogic_HardResetHostAdapter issues a Hard Reset to the Host Adapter,
- and waits for Host Adapter Diagnostics to complete.
-*/
-
-static boolean BusLogic_HardResetHostAdapter(BusLogic_HostAdapter_T
- *HostAdapter)
-{
- boolean TraceHardReset = (BusLogic_GlobalOptions & BusLogic_TraceHardReset);
- long TimeoutCounter = loops_per_sec >> 2;
- unsigned char StatusRegister = 0;
- /*
- Issue a Hard Reset Command to the Host Adapter. The Host Adapter should
- respond by setting Diagnostic Active in the Status Register.
- */
- BusLogic_WriteControlRegister(HostAdapter, BusLogic_HardReset);
- /*
- Wait until Diagnostic Active is set in the Status Register.
- */
- while (--TimeoutCounter >= 0)
- {
- StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
- if ((StatusRegister & BusLogic_DiagnosticActive)) break;
- }
- if (TraceHardReset)
- printk("BusLogic_HardReset(0x%X): Diagnostic Active, Status 0x%02X\n",
- HostAdapter->IO_Address, StatusRegister);
- if (TimeoutCounter < 0) return false;
- /*
- Wait 100 microseconds to allow completion of any initial diagnostic
- activity which might leave the contents of the Status Register
- unpredictable.
- */
- udelay(100);
- /*
- Wait until Diagnostic Active is reset in the Status Register.
- */
- while (--TimeoutCounter >= 0)
- {
- StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
- if (!(StatusRegister & BusLogic_DiagnosticActive)) break;
- }
- if (TraceHardReset)
- printk("BusLogic_HardReset(0x%X): Diagnostic Completed, Status 0x%02X\n",
- HostAdapter->IO_Address, StatusRegister);
- if (TimeoutCounter < 0) return false;
- /*
- Wait until at least one of the Diagnostic Failure, Host Adapter Ready,
- or Data In Register Ready bits is set in the Status Register.
- */
- while (--TimeoutCounter >= 0)
- {
- StatusRegister = BusLogic_ReadStatusRegister(HostAdapter);
- if (StatusRegister & (BusLogic_DiagnosticFailure |
- BusLogic_HostAdapterReady |
- BusLogic_DataInRegisterReady))
- break;
- }
- if (TraceHardReset)
- printk("BusLogic_HardReset(0x%X): Host Adapter Ready, Status 0x%02X\n",
- HostAdapter->IO_Address, StatusRegister);
- if (TimeoutCounter < 0) return false;
- /*
- If Diagnostic Failure is set or Host Adapter Ready is reset, then an
- error occurred during the Host Adapter diagnostics. If Data In Register
- Ready is set, then there is an Error Code available.
- */
- if ((StatusRegister & BusLogic_DiagnosticFailure) ||
- !(StatusRegister & BusLogic_HostAdapterReady))
- {
- BusLogic_CommandFailureReason = NULL;
- BusLogic_Failure(HostAdapter, "HARD RESET DIAGNOSTICS");
- printk("HOST ADAPTER STATUS REGISTER = %02X\n", StatusRegister);
- if (StatusRegister & BusLogic_DataInRegisterReady)
- {
- unsigned char ErrorCode = BusLogic_ReadDataInRegister(HostAdapter);
- printk("HOST ADAPTER ERROR CODE = %d\n", ErrorCode);
- }
- return false;
- }
- /*
- Indicate the Host Adapter Hard Reset completed successfully.
- */
- return true;
-}
-
-
-/*
- BusLogic_CheckHostAdapter checks to be sure this really is a BusLogic
- Host Adapter.
-*/
-
-static boolean BusLogic_CheckHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
-{
- BusLogic_ExtendedSetupInformation_T ExtendedSetupInformation;
- BusLogic_RequestedReplyLength_T RequestedReplyLength;
- unsigned long ProcessorFlags;
- int Result;
- /*
- Issue the Inquire Extended Setup Information command. Only genuine
- BusLogic Host Adapters and true clones support this command. Adaptec 1542C
- series Host Adapters that respond to the Geometry Register I/O port will
- fail this command. Interrupts must be disabled around the call to
- BusLogic_Command since a Command Complete interrupt could occur if the IRQ
- Channel was previously enabled for another BusLogic Host Adapter sharing
- the same IRQ Channel.
- */
- save_flags(ProcessorFlags);
- cli();
- RequestedReplyLength = sizeof(ExtendedSetupInformation);
- Result = BusLogic_Command(HostAdapter,
- BusLogic_InquireExtendedSetupInformation,
- &RequestedReplyLength, sizeof(RequestedReplyLength),
- &ExtendedSetupInformation,
- sizeof(ExtendedSetupInformation));
- restore_flags(ProcessorFlags);
- if (BusLogic_GlobalOptions & BusLogic_TraceProbe)
- printk("BusLogic_Check(0x%X): Result %d\n",
- HostAdapter->IO_Address, Result);
- return (Result == sizeof(ExtendedSetupInformation));
-}
-
-
-/*
- BusLogic_ReadHostAdapterConfiguration reads the Configuration Information
- from Host Adapter.
-*/
-
-static boolean BusLogic_ReadHostAdapterConfiguration(BusLogic_HostAdapter_T
- *HostAdapter)
-{
- BusLogic_BoardID_T BoardID;
- BusLogic_Configuration_T Configuration;
- BusLogic_SetupInformation_T SetupInformation;
- BusLogic_ExtendedSetupInformation_T ExtendedSetupInformation;
- BusLogic_BoardModelNumber_T BoardModelNumber;
- BusLogic_FirmwareVersion3rdDigit_T FirmwareVersion3rdDigit;
- BusLogic_FirmwareVersionLetter_T FirmwareVersionLetter;
- BusLogic_RequestedReplyLength_T RequestedReplyLength;
- unsigned char GeometryRegister, *TargetPointer, Character;
- unsigned short AllTargetsMask, DisconnectPermitted;
- unsigned short TaggedQueuingPermitted, TaggedQueuingPermittedDefault;
- boolean CommonErrorRecovery;
- int TargetID, i;
- /*
- Issue the Inquire Board ID command.
- */
- if (BusLogic_Command(HostAdapter, BusLogic_InquireBoardID, NULL, 0,
- &BoardID, sizeof(BoardID)) != sizeof(BoardID))
- return BusLogic_Failure(HostAdapter, "INQUIRE BOARD ID");
- /*
- Issue the Inquire Configuration command.
- */
- if (BusLogic_Command(HostAdapter, BusLogic_InquireConfiguration, NULL, 0,
- &Configuration, sizeof(Configuration))
- != sizeof(Configuration))
- return BusLogic_Failure(HostAdapter, "INQUIRE CONFIGURATION");
- /*
- Issue the Inquire Setup Information command.
- */
- RequestedReplyLength = sizeof(SetupInformation);
- if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation,
- &RequestedReplyLength, sizeof(RequestedReplyLength),
- &SetupInformation, sizeof(SetupInformation))
- != sizeof(SetupInformation))
- return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION");
- /*
- Issue the Inquire Extended Setup Information command.
- */
- RequestedReplyLength = sizeof(ExtendedSetupInformation);
- if (BusLogic_Command(HostAdapter, BusLogic_InquireExtendedSetupInformation,
- &RequestedReplyLength, sizeof(RequestedReplyLength),
- &ExtendedSetupInformation,
- sizeof(ExtendedSetupInformation))
- != sizeof(ExtendedSetupInformation))
- return BusLogic_Failure(HostAdapter, "INQUIRE EXTENDED SETUP INFORMATION");
- /*
- Issue the Inquire Board Model Number command.
- */
- if (!(BoardID.FirmwareVersion1stDigit == '2' &&
- ExtendedSetupInformation.BusType == 'A'))
- {
- RequestedReplyLength = sizeof(BoardModelNumber);
- if (BusLogic_Command(HostAdapter, BusLogic_InquireBoardModelNumber,
- &RequestedReplyLength, sizeof(RequestedReplyLength),
- &BoardModelNumber, sizeof(BoardModelNumber))
- != sizeof(BoardModelNumber))
- return BusLogic_Failure(HostAdapter, "INQUIRE BOARD MODEL NUMBER");
- }
- else strcpy(BoardModelNumber, "542B");
- /*
- Issue the Inquire Firmware Version 3rd Digit command.
- */
- if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersion3rdDigit,
- NULL, 0, &FirmwareVersion3rdDigit,
- sizeof(FirmwareVersion3rdDigit))
- != sizeof(FirmwareVersion3rdDigit))
- return BusLogic_Failure(HostAdapter, "INQUIRE FIRMWARE 3RD DIGIT");
- /*
- Issue the Inquire Firmware Version Letter command.
- */
- FirmwareVersionLetter = '\0';
- if (BoardID.FirmwareVersion1stDigit > '3' ||
- (BoardID.FirmwareVersion1stDigit == '3' &&
- BoardID.FirmwareVersion2ndDigit >= '3'))
- if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersionLetter,
- NULL, 0, &FirmwareVersionLetter,
- sizeof(FirmwareVersionLetter))
- != sizeof(FirmwareVersionLetter))
- return BusLogic_Failure(HostAdapter, "INQUIRE FIRMWARE VERSION LETTER");
- /*
- BusLogic Host Adapters can be identified by their model number and
- the major version number of their firmware as follows:
-
- 4.xx BusLogic "C" Series Host Adapters:
- BT-946C/956C/956CD/747C/757C/757CD/445C/545C/540CF
- 3.xx BusLogic "S" Series Host Adapters:
- BT-747S/747D/757S/757D/445S/545S/542D
- BT-542B/742A (revision H)
- 2.xx BusLogic "A" Series Host Adapters:
- BT-542B/742A (revision G and below)
- 0.xx AMI FastDisk VLB/EISA BusLogic Clone Host Adapter
- */
- /*
- Save the Model Name and Board Name in the Host Adapter structure.
- */
- TargetPointer = HostAdapter->ModelName;
- *TargetPointer++ = 'B';
- *TargetPointer++ = 'T';
- *TargetPointer++ = '-';
- for (i = 0; i < sizeof(BoardModelNumber); i++)
- {
- Character = BoardModelNumber[i];
- if (Character == ' ' || Character == '\0') break;
- *TargetPointer++ = Character;
- }
- *TargetPointer++ = '\0';
- strcpy(HostAdapter->BoardName, "BusLogic ");
- strcat(HostAdapter->BoardName, HostAdapter->ModelName);
- strcpy(HostAdapter->InterruptLabel, HostAdapter->BoardName);
- /*
- Save the Firmware Version in the Host Adapter structure.
- */
- TargetPointer = HostAdapter->FirmwareVersion;
- *TargetPointer++ = BoardID.FirmwareVersion1stDigit;
- *TargetPointer++ = '.';
- *TargetPointer++ = BoardID.FirmwareVersion2ndDigit;
- if (FirmwareVersion3rdDigit != ' ' && FirmwareVersion3rdDigit != '\0')
- *TargetPointer++ = FirmwareVersion3rdDigit;
- if (FirmwareVersionLetter != ' ' && FirmwareVersionLetter != '\0')
- *TargetPointer++ = FirmwareVersionLetter;
- *TargetPointer++ = '\0';
- /*
- Determine the IRQ Channel and save it in the Host Adapter structure.
- */
- if (Configuration.IRQ_Channel9)
- HostAdapter->IRQ_Channel = 9;
- else if (Configuration.IRQ_Channel10)
- HostAdapter->IRQ_Channel = 10;
- else if (Configuration.IRQ_Channel11)
- HostAdapter->IRQ_Channel = 11;
- else if (Configuration.IRQ_Channel12)
- HostAdapter->IRQ_Channel = 12;
- else if (Configuration.IRQ_Channel14)
- HostAdapter->IRQ_Channel = 14;
- else if (Configuration.IRQ_Channel15)
- HostAdapter->IRQ_Channel = 15;
- /*
- Determine the DMA Channel and save it in the Host Adapter structure.
- */
- if (Configuration.DMA_Channel5)
- HostAdapter->DMA_Channel = 5;
- else if (Configuration.DMA_Channel6)
- HostAdapter->DMA_Channel = 6;
- else if (Configuration.DMA_Channel7)
- HostAdapter->DMA_Channel = 7;
- /*
- Save the Host Adapter SCSI ID in the Host Adapter structure.
- */
- HostAdapter->SCSI_ID = Configuration.HostAdapterID;
- /*
- Save the Synchronous Initiation flag and SCSI Parity Checking flag
- in the Host Adapter structure.
- */
- HostAdapter->SynchronousInitiation =
- SetupInformation.SynchronousInitiationEnabled;
- HostAdapter->ParityChecking = SetupInformation.ParityCheckEnabled;
- /*
- Determine the Bus Type and save it in the Host Adapter structure,
- overriding the DMA Channel if it is inappropriate for the bus type.
- */
- if (ExtendedSetupInformation.BusType == 'A')
- HostAdapter->BusType = BusLogic_ISA_Bus;
- else
- switch (HostAdapter->ModelName[3])
- {
- case '4':
- HostAdapter->BusType = BusLogic_VESA_Bus;
- HostAdapter->DMA_Channel = 0;
- break;
- case '5':
- HostAdapter->BusType = BusLogic_ISA_Bus;
- break;
- case '6':
- HostAdapter->BusType = BusLogic_MCA_Bus;
- HostAdapter->DMA_Channel = 0;
- break;
- case '7':
- HostAdapter->BusType = BusLogic_EISA_Bus;
- HostAdapter->DMA_Channel = 0;
- break;
- case '9':
- HostAdapter->BusType = BusLogic_PCI_Bus;
- HostAdapter->DMA_Channel = 0;
- break;
- }
- /*
- Determine whether Extended Translation is enabled and save it in
- the Host Adapter structure.
- */
- GeometryRegister = BusLogic_ReadGeometryRegister(HostAdapter);
- if (GeometryRegister & BusLogic_ExtendedTranslationEnabled)
- HostAdapter->ExtendedTranslation = true;
- /*
- Save the Disconnect/Reconnect Permitted flag bits in the Host Adapter
- structure. The Disconnect Permitted information is only valid on "C"
- Series boards, but Disconnect/Reconnect is always permitted on "S" and
- "A" Series boards.
- */
- if (HostAdapter->FirmwareVersion[0] >= '4')
- HostAdapter->DisconnectPermitted =
- (SetupInformation.DisconnectPermittedID8to15 << 8)
- | SetupInformation.DisconnectPermittedID0to7;
- else HostAdapter->DisconnectPermitted = 0xFF;
- /*
- Save the Scatter Gather Limits, Level Sensitive Interrupts flag,
- Wide SCSI flag, and Differential SCSI flag in the Host Adapter structure.
- */
- HostAdapter->HostAdapterScatterGatherLimit =
- ExtendedSetupInformation.ScatterGatherLimit;
- HostAdapter->DriverScatterGatherLimit =
- HostAdapter->HostAdapterScatterGatherLimit;
- if (HostAdapter->HostAdapterScatterGatherLimit > BusLogic_ScatterGatherLimit)
- HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit;
- if (ExtendedSetupInformation.Misc.LevelSensitiveInterrupts)
- HostAdapter->LevelSensitiveInterrupts = true;
- if (ExtendedSetupInformation.HostWideSCSI)
- {
- HostAdapter->HostWideSCSI = true;
- HostAdapter->MaxTargetIDs = 16;
- HostAdapter->MaxLogicalUnits = 64;
- }
- else
- {
- HostAdapter->HostWideSCSI = false;
- HostAdapter->MaxTargetIDs = 8;
- HostAdapter->MaxLogicalUnits = 8;
- }
- HostAdapter->HostDifferentialSCSI =
- ExtendedSetupInformation.HostDifferentialSCSI;
- /*
- Determine the Host Adapter BIOS Address if the BIOS is enabled and
- save it in the Host Adapter structure. The BIOS is disabled if the
- BIOS_Address is 0.
- */
- HostAdapter->BIOS_Address = ExtendedSetupInformation.BIOS_Address << 12;
- /*
- BusLogic BT-445S Host Adapters prior to board revision D have a hardware
- bug whereby when the BIOS is enabled, transfers to/from the same address
- range the BIOS occupies modulo 16MB are handled incorrectly. Only properly
- functioning BT-445S boards have firmware version 3.37, so we require that
- ISA bounce buffers be used for the buggy BT-445S models as well as for all
- ISA models.
- */
- if (HostAdapter->BusType == BusLogic_ISA_Bus ||
- (HostAdapter->BIOS_Address > 0 &&
- strcmp(HostAdapter->ModelName, "BT-445S") == 0 &&
- strcmp(HostAdapter->FirmwareVersion, "3.37") < 0))
- HostAdapter->BounceBuffersRequired = true;
- /*
- Select an appropriate value for Concurrency (Commands per Logical Unit)
- either from a Command Line Entry, or based on whether this Host Adapter
- requires that ISA bounce buffers be used.
- */
- if (HostAdapter->CommandLineEntry != NULL &&
- HostAdapter->CommandLineEntry->Concurrency > 0)
- HostAdapter->Concurrency = HostAdapter->CommandLineEntry->Concurrency;
- else if (HostAdapter->BounceBuffersRequired)
- HostAdapter->Concurrency = BusLogic_Concurrency_BB;
- else HostAdapter->Concurrency = BusLogic_Concurrency;
- /*
- Select an appropriate value for Bus Settle Time either from a Command
- Line Entry, or from BusLogic_DefaultBusSettleTime.
- */
- if (HostAdapter->CommandLineEntry != NULL &&
- HostAdapter->CommandLineEntry->BusSettleTime > 0)
- HostAdapter->BusSettleTime = HostAdapter->CommandLineEntry->BusSettleTime;
- else HostAdapter->BusSettleTime = BusLogic_DefaultBusSettleTime;
- /*
- Select an appropriate value for Local Options from a Command Line Entry.
- */
- if (HostAdapter->CommandLineEntry != NULL)
- HostAdapter->LocalOptions = HostAdapter->CommandLineEntry->LocalOptions;
- /*
- Select appropriate values for the Error Recovery Option array either from
- a Command Line Entry, or using BusLogic_ErrorRecoveryDefault.
- */
- if (HostAdapter->CommandLineEntry != NULL)
- memcpy(HostAdapter->ErrorRecoveryOption,
- HostAdapter->CommandLineEntry->ErrorRecoveryOption,
- sizeof(HostAdapter->ErrorRecoveryOption));
- else memset(HostAdapter->ErrorRecoveryOption,
- BusLogic_ErrorRecoveryDefault,
- sizeof(HostAdapter->ErrorRecoveryOption));
- /*
- Tagged Queuing support is available and operates properly only on "C"
- Series boards with firmware version 4.22 and above and on "S" Series
- boards with firmware version 3.35 and above. Tagged Queuing is disabled
- by default when the Concurrency value is 1 since queuing multiple commands
- is not possible.
- */
- TaggedQueuingPermittedDefault = 0;
- if (HostAdapter->Concurrency > 1)
- switch (HostAdapter->FirmwareVersion[0])
- {
- case '5':
- TaggedQueuingPermittedDefault = 0xFFFF;
- break;
- case '4':
- if (strcmp(HostAdapter->FirmwareVersion, "4.22") >= 0)
- TaggedQueuingPermittedDefault = 0xFFFF;
- break;
- case '3':
- if (strcmp(HostAdapter->FirmwareVersion, "3.35") >= 0)
- TaggedQueuingPermittedDefault = 0xFFFF;
- break;
- }
- /*
- Tagged Queuing is only useful if Disconnect/Reconnect is permitted.
- Therefore, mask the Tagged Queuing Permitted Default bits with the
- Disconnect/Reconnect Permitted bits.
- */
- TaggedQueuingPermittedDefault &= HostAdapter->DisconnectPermitted;
- /*
- Combine the default Tagged Queuing Permitted Default bits with any
- Command Line Entry Tagged Queuing specification.
- */
- if (HostAdapter->CommandLineEntry != NULL)
- HostAdapter->TaggedQueuingPermitted =
- (HostAdapter->CommandLineEntry->TaggedQueuingPermitted &
- HostAdapter->CommandLineEntry->TaggedQueuingPermittedMask) |
- (TaggedQueuingPermittedDefault &
- ~HostAdapter->CommandLineEntry->TaggedQueuingPermittedMask);
- else HostAdapter->TaggedQueuingPermitted = TaggedQueuingPermittedDefault;
- /*
- Announce the Host Adapter Configuration.
- */
- printk("scsi%d: Configuring BusLogic Model %s %s%s%s SCSI Host Adapter\n",
- HostAdapter->HostNumber, HostAdapter->ModelName,
- BusLogic_BusNames[HostAdapter->BusType],
- (HostAdapter->HostWideSCSI ? " Wide" : ""),
- (HostAdapter->HostDifferentialSCSI ? " Differential" : ""));
- printk("scsi%d: Firmware Version: %s, I/O Address: 0x%X, "
- "IRQ Channel: %d/%s\n",
- HostAdapter->HostNumber, HostAdapter->FirmwareVersion,
- HostAdapter->IO_Address, HostAdapter->IRQ_Channel,
- (HostAdapter->LevelSensitiveInterrupts ? "Level" : "Edge"));
- printk("scsi%d: DMA Channel: ", HostAdapter->HostNumber);
- if (HostAdapter->DMA_Channel > 0)
- printk("%d, ", HostAdapter->DMA_Channel);
- else printk("None, ");
- if (HostAdapter->BIOS_Address > 0)
- printk("BIOS Address: 0x%lX, ", HostAdapter->BIOS_Address);
- else printk("BIOS Address: None, ");
- printk("Host Adapter SCSI ID: %d\n", HostAdapter->SCSI_ID);
- printk("scsi%d: Scatter/Gather Limit: %d segments, "
- "Synchronous Initiation: %s\n", HostAdapter->HostNumber,
- HostAdapter->HostAdapterScatterGatherLimit,
- (HostAdapter->SynchronousInitiation ? "Enabled" : "Disabled"));
- printk("scsi%d: SCSI Parity Checking: %s, "
- "Extended Disk Translation: %s\n", HostAdapter->HostNumber,
- (HostAdapter->ParityChecking ? "Enabled" : "Disabled"),
- (HostAdapter->ExtendedTranslation ? "Enabled" : "Disabled"));
- AllTargetsMask = (1 << HostAdapter->MaxTargetIDs) - 1;
- DisconnectPermitted = HostAdapter->DisconnectPermitted & AllTargetsMask;
- printk("scsi%d: Disconnect/Reconnect: ", HostAdapter->HostNumber);
- if (DisconnectPermitted == 0)
- printk("Disabled");
- else if (DisconnectPermitted == AllTargetsMask)
- printk("Enabled");
- else
- for (TargetID = 0; TargetID < HostAdapter->MaxTargetIDs; TargetID++)
- printk("%c", (DisconnectPermitted & (1 << TargetID)) ? 'Y' : 'N');
- printk(", Tagged Queuing: ");
- TaggedQueuingPermitted =
- HostAdapter->TaggedQueuingPermitted & AllTargetsMask;
- if (TaggedQueuingPermitted == 0)
- printk("Disabled");
- else if (TaggedQueuingPermitted == AllTargetsMask)
- printk("Enabled");
- else
- for (TargetID = 0; TargetID < HostAdapter->MaxTargetIDs; TargetID++)
- printk("%c", (TaggedQueuingPermitted & (1 << TargetID)) ? 'Y' : 'N');
- printk("\n");
- CommonErrorRecovery = true;
- for (TargetID = 1; TargetID < HostAdapter->MaxTargetIDs; TargetID++)
- if (HostAdapter->ErrorRecoveryOption[TargetID] !=
- HostAdapter->ErrorRecoveryOption[0])
- {
- CommonErrorRecovery = false;
- break;
- }
- printk("scsi%d: Error Recovery: ", HostAdapter->HostNumber);
- if (CommonErrorRecovery)
- printk("%s", BusLogic_ErrorRecoveryOptions[
- HostAdapter->ErrorRecoveryOption[0]]);
- else
- for (TargetID = 0; TargetID < HostAdapter->MaxTargetIDs; TargetID++)
- printk("%s", BusLogic_ErrorRecoveryOptions2[
- HostAdapter->ErrorRecoveryOption[TargetID]]);
- printk(", Mailboxes: %d, Initial CCBs: %d\n",
- BusLogic_MailboxCount, BusLogic_InitialCCBs);
- printk("scsi%d: Driver Scatter/Gather Limit: %d segments, "
- "Concurrency: %d\n", HostAdapter->HostNumber,
- HostAdapter->DriverScatterGatherLimit, HostAdapter->Concurrency);
- /*
- Indicate reading the Host Adapter Configuration completed successfully.
- */
- return true;
-}
-
-
-/*
- BusLogic_AcquireResources acquires the system resources necessary to use Host
- Adapter, and initializes the fields in the SCSI Host structure. The base,
- io_port, n_io_ports, irq, and dma_channel fields in the SCSI Host structure
- are intentionally left uninitialized, as this driver handles acquisition and
- release of these resources explicitly, as well as ensuring exclusive access
- to the Host Adapter hardware and data structures through explicit locking.
-*/
-
-static boolean BusLogic_AcquireResources(BusLogic_HostAdapter_T *HostAdapter,
- SCSI_Host_T *Host)
-{
- /*
- Acquire exclusive or shared access to the IRQ Channel. A usage count is
- maintained so that PCI, EISA, or MCA shared Interrupts can be supported.
- */
- if (BusLogic_IRQ_UsageCount[HostAdapter->IRQ_Channel - 9]++ == 0)
- {
- if (request_irq(HostAdapter->IRQ_Channel, BusLogic_InterruptHandler,
- SA_INTERRUPT, HostAdapter->InterruptLabel) < 0)
- {
- BusLogic_IRQ_UsageCount[HostAdapter->IRQ_Channel - 9]--;
- printk("scsi%d: UNABLE TO ACQUIRE IRQ CHANNEL %d - DETACHING\n",
- HostAdapter->HostNumber, HostAdapter->IRQ_Channel);
- return false;
- }
- }
- else
- {
- BusLogic_HostAdapter_T *FirstHostAdapter =
- BusLogic_RegisteredHostAdapters;
- while (FirstHostAdapter != NULL)
- {
- if (FirstHostAdapter->IRQ_Channel == HostAdapter->IRQ_Channel)
- {
- if (strlen(FirstHostAdapter->InterruptLabel) + 11
- < sizeof(FirstHostAdapter->InterruptLabel))
- {
- strcat(FirstHostAdapter->InterruptLabel, " + ");
- strcat(FirstHostAdapter->InterruptLabel,
- HostAdapter->ModelName);
- }
- break;
- }
- FirstHostAdapter = FirstHostAdapter->Next;
- }
- }
- HostAdapter->IRQ_ChannelAcquired = true;
- /*
- Acquire exclusive access to the DMA Channel.
- */
- if (HostAdapter->DMA_Channel > 0)
- {
- if (request_dma(HostAdapter->DMA_Channel, HostAdapter->BoardName) < 0)
- {
- printk("scsi%d: UNABLE TO ACQUIRE DMA CHANNEL %d - DETACHING\n",
- HostAdapter->HostNumber, HostAdapter->DMA_Channel);
- return false;
- }
- set_dma_mode(HostAdapter->DMA_Channel, DMA_MODE_CASCADE);
- enable_dma(HostAdapter->DMA_Channel);
- HostAdapter->DMA_ChannelAcquired = true;
- }
- /*
- Initialize necessary fields in the SCSI Host structure.
- */
- Host->max_id = HostAdapter->MaxTargetIDs;
- Host->max_lun = HostAdapter->MaxLogicalUnits;
- Host->max_channel = 0;
- Host->this_id = HostAdapter->SCSI_ID;
- Host->can_queue = BusLogic_MailboxCount;
- Host->cmd_per_lun = HostAdapter->Concurrency;
- Host->sg_tablesize = HostAdapter->DriverScatterGatherLimit;
- Host->unchecked_isa_dma = HostAdapter->BounceBuffersRequired;
- /*
- Indicate the System Resource Acquisition completed successfully,
- */
- return true;
-}
-
-
-/*
- BusLogic_ReleaseResources releases any system resources previously acquired
- by BusLogic_AcquireResources.
-*/
-
-static void BusLogic_ReleaseResources(BusLogic_HostAdapter_T *HostAdapter)
-{
- /*
- Release exclusive or shared access to the IRQ Channel.
- */
- if (HostAdapter->IRQ_ChannelAcquired)
- if (--BusLogic_IRQ_UsageCount[HostAdapter->IRQ_Channel - 9] == 0)
- free_irq(HostAdapter->IRQ_Channel);
- /*
- Release exclusive access to the DMA Channel.
- */
- if (HostAdapter->DMA_ChannelAcquired)
- free_dma(HostAdapter->DMA_Channel);
-}
-
-
-/*
- BusLogic_TestInterrupts tests for proper functioning of the Host Adapter
- Interrupt Register and that interrupts generated by the Host Adapter are
- getting through to the Interrupt Handler. A large proportion of initial
- problems with installing PCI Host Adapters are due to configuration problems
- where either the Host Adapter or Motherboard is configured incorrectly, and
- interrupts do not get through as a result.
-*/
-
-static boolean BusLogic_TestInterrupts(BusLogic_HostAdapter_T *HostAdapter)
-{
- unsigned int InitialInterruptCount, FinalInterruptCount;
- int TestCount = 5, i;
- InitialInterruptCount = kstat.interrupts[HostAdapter->IRQ_Channel];
- /*
- Issue the Test Command Complete Interrupt commands.
- */
- for (i = 0; i < TestCount; i++)
- BusLogic_Command(HostAdapter, BusLogic_TestCommandCompleteInterrupt,
- NULL, 0, NULL, 0);
- /*
- Verify that BusLogic_InterruptHandler was called at least TestCount times.
- Shared IRQ Channels could cause more than TestCount interrupts to occur,
- but there should never be fewer than TestCount.
- */
- FinalInterruptCount = kstat.interrupts[HostAdapter->IRQ_Channel];
- if (FinalInterruptCount < InitialInterruptCount + TestCount)
- {
- BusLogic_Failure(HostAdapter, "HOST ADAPTER INTERRUPT TEST");
- printk("\n\
-Interrupts are not getting through from the Host Adapter to the BusLogic\n\
-Driver Interrupt Handler. The most likely cause is that either the Host\n\
-Adapter or Motherboard is configured incorrectly. Please check the Host\n\
-Adapter configuration with AutoSCSI or by examining any dip switch and\n\
-jumper settings on the Host Adapter, and verify that no other device is\n\
-attempting to use the same IRQ Channel. For PCI Host Adapters, it may also\n\
-be necessary to investigate and manually set the PCI interrupt assignments\n\
-and edge/level interrupt type selection in the BIOS Setup Program or with\n\
-Motherboard jumpers.\n\n");
- return false;
- }
- /*
- Indicate the Host Adapter Interrupt Test completed successfully.
- */
- return true;
-}
-
-
-/*
- BusLogic_InitializeHostAdapter initializes Host Adapter. This is the only
- function called during SCSI Host Adapter detection which modifies the state
- of the Host Adapter from its initial power on or hard reset state.
-*/
-
-static boolean BusLogic_InitializeHostAdapter(BusLogic_HostAdapter_T
- *HostAdapter)
-{
- BusLogic_ExtendedMailboxRequest_T ExtendedMailboxRequest;
- BusLogic_RoundRobinModeRequest_T RoundRobinModeRequest;
- BusLogic_WideModeCCBRequest_T WideModeCCBRequest;
- BusLogic_ModifyIOAddressRequest_T ModifyIOAddressRequest;
- /*
- Initialize the Command Successful Flag, Read/Write Operation Count,
- and Queued Operation Count for each Target.
- */
- memset(HostAdapter->CommandSuccessfulFlag, false,
- sizeof(HostAdapter->CommandSuccessfulFlag));
- memset(HostAdapter->ReadWriteOperationCount, 0,
- sizeof(HostAdapter->ReadWriteOperationCount));
- memset(HostAdapter->QueuedOperationCount, 0,
- sizeof(HostAdapter->QueuedOperationCount));
- /*
- Initialize the Outgoing and Incoming Mailbox structures.
- */
- memset(HostAdapter->OutgoingMailboxes, 0,
- sizeof(HostAdapter->OutgoingMailboxes));
- memset(HostAdapter->IncomingMailboxes, 0,
- sizeof(HostAdapter->IncomingMailboxes));
- /*
- Initialize the pointers to the First, Last, and Next Mailboxes.
- */
- HostAdapter->FirstOutgoingMailbox = &HostAdapter->OutgoingMailboxes[0];
- HostAdapter->LastOutgoingMailbox =
- &HostAdapter->OutgoingMailboxes[BusLogic_MailboxCount-1];
- HostAdapter->NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
- HostAdapter->FirstIncomingMailbox = &HostAdapter->IncomingMailboxes[0];
- HostAdapter->LastIncomingMailbox =
- &HostAdapter->IncomingMailboxes[BusLogic_MailboxCount-1];
- HostAdapter->NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
- /*
- Initialize the Host Adapter's Pointer to the Outgoing/Incoming Mailboxes.
- */
- ExtendedMailboxRequest.MailboxCount = BusLogic_MailboxCount;
- ExtendedMailboxRequest.BaseMailboxAddress = HostAdapter->OutgoingMailboxes;
- if (BusLogic_Command(HostAdapter, BusLogic_InitializeExtendedMailbox,
- &ExtendedMailboxRequest,
- sizeof(ExtendedMailboxRequest), NULL, 0) < 0)
- return BusLogic_Failure(HostAdapter, "MAILBOX INITIALIZATION");
- /*
- Enable Strict Round Robin Mode if supported by the Host Adapter. In Strict
- Round Robin Mode, the Host Adapter only looks at the next Outgoing Mailbox
- for each new command, rather than scanning through all the Outgoing
- Mailboxes to find any that have new commands in them. BusLogic indicates
- that Strict Round Robin Mode is significantly more efficient.
- */
- if (strcmp(HostAdapter->FirmwareVersion, "3.31") >= 0)
- {
- RoundRobinModeRequest = BusLogic_StrictRoundRobinMode;
- if (BusLogic_Command(HostAdapter, BusLogic_EnableStrictRoundRobinMode,
- &RoundRobinModeRequest,
- sizeof(RoundRobinModeRequest), NULL, 0) < 0)
- return BusLogic_Failure(HostAdapter, "ENABLE STRICT ROUND ROBIN MODE");
- }
- /*
- For Wide SCSI Host Adapters, issue the Enable Wide Mode CCB command to
- allow more than 8 Logical Units per Target to be supported.
- */
- if (HostAdapter->HostWideSCSI)
- {
- WideModeCCBRequest = BusLogic_WideModeCCB;
- if (BusLogic_Command(HostAdapter, BusLogic_EnableWideModeCCB,
- &WideModeCCBRequest,
- sizeof(WideModeCCBRequest), NULL, 0) < 0)
- return BusLogic_Failure(HostAdapter, "ENABLE WIDE MODE CCB");
- }
- /*
- For PCI Host Adapters being accessed through the PCI compliant I/O
- Address, disable the ISA compatible I/O Address to avoid detecting the
- same Host Adapter at both I/O Addresses.
- */
- if (HostAdapter->BusType == BusLogic_PCI_Bus)
- {
- int Index;
- for (Index = 0; BusLogic_IO_StandardAddresses[Index] > 0; Index++)
- if (HostAdapter->IO_Address == BusLogic_IO_StandardAddresses[Index])
- break;
- if (BusLogic_IO_StandardAddresses[Index] == 0)
- {
- ModifyIOAddressRequest = BusLogic_ModifyIO_Disable;
- if (BusLogic_Command(HostAdapter, BusLogic_ModifyIOAddress,
- &ModifyIOAddressRequest,
- sizeof(ModifyIOAddressRequest), NULL, 0) < 0)
- return BusLogic_Failure(HostAdapter, "MODIFY I/O ADDRESS");
- }
- }
- /*
- Announce Successful Initialization.
- */
- printk("scsi%d: *** %s Initialized Successfully ***\n",
- HostAdapter->HostNumber, HostAdapter->BoardName);
- /*
- Indicate the Host Adapter Initialization completed successfully.
- */
- return true;
-}
-
-
-/*
- BusLogic_InquireTargetDevices inquires about the Target Devices accessible
- through Host Adapter and reports on the results.
-*/
-
-static boolean BusLogic_InquireTargetDevices(BusLogic_HostAdapter_T
- *HostAdapter)
-{
- BusLogic_InstalledDevices8_T InstalledDevicesID0to7;
- BusLogic_InstalledDevices8_T InstalledDevicesID8to15;
- BusLogic_SetupInformation_T SetupInformation;
- BusLogic_SynchronousPeriod_T SynchronousPeriod;
- BusLogic_RequestedReplyLength_T RequestedReplyLength;
- int TargetDevicesFound = 0, TargetID;
- /*
- Wait a few seconds between the Host Adapter Hard Reset which initiates
- a SCSI Bus Reset and issuing any SCSI commands. Some SCSI devices get
- confused if they receive SCSI commands too soon after a SCSI Bus Reset.
- */
- BusLogic_Delay(HostAdapter->BusSettleTime);
- /*
- Inhibit the Target Devices Inquiry if requested.
- */
- if (HostAdapter->LocalOptions & BusLogic_InhibitTargetInquiry)
- {
- printk("scsi%d: Target Device Inquiry Inhibited\n",
- HostAdapter->HostNumber);
- return true;
- }
- /*
- Issue the Inquire Installed Devices ID 0 to 7 command, and for Wide SCSI
- Host Adapters the Inquire Installed Devices ID 8 to 15 command. This is
- necessary to force Synchronous Transfer Negotiation so that the Inquire
- Setup Information and Inquire Synchronous Period commands will return
- valid data.
- */
- if (BusLogic_Command(HostAdapter, BusLogic_InquireInstalledDevicesID0to7,
- NULL, 0, &InstalledDevicesID0to7,
- sizeof(InstalledDevicesID0to7))
- != sizeof(InstalledDevicesID0to7))
- return BusLogic_Failure(HostAdapter, "INQUIRE INSTALLED DEVICES ID 0 TO 7");
- if (HostAdapter->HostWideSCSI)
- if (BusLogic_Command(HostAdapter, BusLogic_InquireInstalledDevicesID8to15,
- NULL, 0, &InstalledDevicesID8to15,
- sizeof(InstalledDevicesID8to15))
- != sizeof(InstalledDevicesID8to15))
- return BusLogic_Failure(HostAdapter,
- "INQUIRE INSTALLED DEVICES ID 8 TO 15");
- /*
- Issue the Inquire Setup Information command.
- */
- RequestedReplyLength = sizeof(SetupInformation);
- if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation,
- &RequestedReplyLength, sizeof(RequestedReplyLength),
- &SetupInformation, sizeof(SetupInformation))
- != sizeof(SetupInformation))
- return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION");
- /*
- Issue the Inquire Synchronous Period command.
- */
- if (HostAdapter->FirmwareVersion[0] >= '3')
- {
- RequestedReplyLength = sizeof(SynchronousPeriod);
- if (BusLogic_Command(HostAdapter, BusLogic_InquireSynchronousPeriod,
- &RequestedReplyLength, sizeof(RequestedReplyLength),
- &SynchronousPeriod, sizeof(SynchronousPeriod))
- != sizeof(SynchronousPeriod))
- return BusLogic_Failure(HostAdapter, "INQUIRE SYNCHRONOUS PERIOD");
- }
- else
- for (TargetID = 0; TargetID < HostAdapter->MaxTargetIDs; TargetID++)
- if (SetupInformation.SynchronousValuesID0to7[TargetID].Offset > 0)
- SynchronousPeriod[TargetID] =
- 20 + 5 * SetupInformation.SynchronousValuesID0to7[TargetID]
- .TransferPeriod;
- else SynchronousPeriod[TargetID] = 0;
- /*
- Save the Installed Devices, Synchronous Values, and Synchronous Period
- information in the Host Adapter structure.
- */
- memcpy(HostAdapter->InstalledDevices, InstalledDevicesID0to7,
- sizeof(BusLogic_InstalledDevices8_T));
- memcpy(HostAdapter->SynchronousValues,
- SetupInformation.SynchronousValuesID0to7,
- sizeof(BusLogic_SynchronousValues8_T));
- if (HostAdapter->HostWideSCSI)
- {
- memcpy(&HostAdapter->InstalledDevices[8], InstalledDevicesID8to15,
- sizeof(BusLogic_InstalledDevices8_T));
- memcpy(&HostAdapter->SynchronousValues[8],
- SetupInformation.SynchronousValuesID8to15,
- sizeof(BusLogic_SynchronousValues8_T));
- }
- memcpy(HostAdapter->SynchronousPeriod, SynchronousPeriod,
- sizeof(BusLogic_SynchronousPeriod_T));
- for (TargetID = 0; TargetID < HostAdapter->MaxTargetIDs; TargetID++)
- if (HostAdapter->InstalledDevices[TargetID] != 0)
- {
- int SynchronousPeriod = HostAdapter->SynchronousPeriod[TargetID];
- if (SynchronousPeriod > 10)
- {
- int SynchronousTransferRate = 100000000 / SynchronousPeriod;
- int RoundedSynchronousTransferRate =
- (SynchronousTransferRate + 5000) / 10000;
- printk("scsi%d: Target %d: Synchronous at "
- "%d.%02d mega-transfers/second, offset %d\n",
- HostAdapter->HostNumber, TargetID,
- RoundedSynchronousTransferRate / 100,
- RoundedSynchronousTransferRate % 100,
- HostAdapter->SynchronousValues[TargetID].Offset);
- }
- else if (SynchronousPeriod > 0)
- {
- int SynchronousTransferRate = 100000000 / SynchronousPeriod;
- int RoundedSynchronousTransferRate =
- (SynchronousTransferRate + 50000) / 100000;
- printk("scsi%d: Target %d: Synchronous at "
- "%d.%01d mega-transfers/second, offset %d\n",
- HostAdapter->HostNumber, TargetID,
- RoundedSynchronousTransferRate / 10,
- RoundedSynchronousTransferRate % 10,
- HostAdapter->SynchronousValues[TargetID].Offset);
- }
- else printk("scsi%d: Target %d: Asynchronous\n",
- HostAdapter->HostNumber, TargetID);
- TargetDevicesFound++;
- }
- if (TargetDevicesFound == 0)
- printk("scsi%d: No Target Devices Found\n", HostAdapter->HostNumber);
- /*
- Indicate the Target Device Inquiry completed successfully.
- */
- return true;
-}
-
-
-/*
- BusLogic_DetectHostAdapter probes for BusLogic Host Adapters at the standard
- I/O Addresses where they may be located, initializing, registering, and
- reporting the configuration of each BusLogic Host Adapter it finds. It
- returns the number of BusLogic Host Adapters successfully initialized and
- registered.
-*/
-
-int BusLogic_DetectHostAdapter(SCSI_Host_Template_T *HostTemplate)
-{
- int BusLogicHostAdapterCount = 0, CommandLineEntryIndex = 0;
- int AddressProbeIndex = 0;
- BusLogic_InitializeAddressProbeList();
- while (BusLogic_IO_AddressProbeList[AddressProbeIndex] > 0)
- {
- BusLogic_HostAdapter_T HostAdapterPrototype;
- BusLogic_HostAdapter_T *HostAdapter = &HostAdapterPrototype;
- SCSI_Host_T *Host;
- memset(HostAdapter, 0, sizeof(BusLogic_HostAdapter_T));
- HostAdapter->IO_Address =
- BusLogic_IO_AddressProbeList[AddressProbeIndex++];
- /*
- Initialize the Command Line Entry field if an explicit I/O Address
- was specified.
- */
- if (CommandLineEntryIndex < BusLogic_CommandLineEntryCount &&
- BusLogic_CommandLineEntries[CommandLineEntryIndex].IO_Address ==
- HostAdapter->IO_Address)
- HostAdapter->CommandLineEntry =
- &BusLogic_CommandLineEntries[CommandLineEntryIndex++];
- /*
- Check whether the I/O Address range is already in use.
- */
- if (check_region(HostAdapter->IO_Address, BusLogic_IO_PortCount) < 0)
- continue;
- /*
- Probe the Host Adapter. If unsuccessful, abort further initialization.
- */
- if (!BusLogic_ProbeHostAdapter(HostAdapter)) continue;
- /*
- Hard Reset the Host Adapter. If unsuccessful, abort further
- initialization.
- */
- if (!BusLogic_HardResetHostAdapter(HostAdapter)) continue;
- /*
- Check the Host Adapter. If unsuccessful, abort further initialization.
- */
- if (!BusLogic_CheckHostAdapter(HostAdapter)) continue;
- /*
- Initialize the Command Line Entry field if an explicit I/O Address
- was not specified.
- */
- if (CommandLineEntryIndex < BusLogic_CommandLineEntryCount &&
- BusLogic_CommandLineEntries[CommandLineEntryIndex].IO_Address == 0)
- HostAdapter->CommandLineEntry =
- &BusLogic_CommandLineEntries[CommandLineEntryIndex++];
- /*
- Announce the Driver Version and Date, Author's Name, Copyright Notice,
- and Contact Address.
- */
- BusLogic_AnnounceDriver();
- /*
- Register usage of the I/O Address range. From this point onward, any
- failure will be assumed to be due to a problem with the Host Adapter,
- rather than due to having mistakenly identified this port as belonging
- to a BusLogic Host Adapter. The I/O Address range will not be
- released, thereby preventing it from being incorrectly identified as
- any other type of Host Adapter.
- */
- request_region(HostAdapter->IO_Address, BusLogic_IO_PortCount,
- "BusLogic");
- /*
- Register the SCSI Host structure.
- */
- HostTemplate->proc_dir = &BusLogic_ProcDirectoryEntry;
- Host = scsi_register(HostTemplate, sizeof(BusLogic_HostAdapter_T));
- HostAdapter = (BusLogic_HostAdapter_T *) Host->hostdata;
- memcpy(HostAdapter, &HostAdapterPrototype,
- sizeof(BusLogic_HostAdapter_T));
- HostAdapter->SCSI_Host = Host;
- HostAdapter->HostNumber = Host->host_no;
- /*
- Add Host Adapter to the end of the list of registered BusLogic
- Host Adapters. In order for Command Complete Interrupts to be
- properly dismissed by BusLogic_InterruptHandler, the Host Adapter
- must be registered. This must be done before the IRQ Channel is
- acquired, and in a shared IRQ Channel environment, must be done
- before any Command Complete Interrupts occur, since the IRQ Channel
- may have already been acquired by a previous BusLogic Host Adapter.
- */
- BusLogic_RegisterHostAdapter(HostAdapter);
- /*
- Read the Host Adapter Configuration, Acquire the System Resources
- necessary to use Host Adapter and initialize the fields in the SCSI
- Host structure, then Test Interrupts, Create the CCBs, Initialize
- the Host Adapter, and finally Inquire about the Target Devices.
- */
- if (BusLogic_ReadHostAdapterConfiguration(HostAdapter) &&
- BusLogic_AcquireResources(HostAdapter, Host) &&
- BusLogic_TestInterrupts(HostAdapter) &&
- BusLogic_CreateCCBs(HostAdapter) &&
- BusLogic_InitializeHostAdapter(HostAdapter) &&
- BusLogic_InquireTargetDevices(HostAdapter))
- {
- /*
- Initialization has been completed successfully. Release and
- re-register usage of the I/O Address range so that the Model
- Name of the Host Adapter will appear.
- */
- release_region(HostAdapter->IO_Address, BusLogic_IO_PortCount);
- request_region(HostAdapter->IO_Address, BusLogic_IO_PortCount,
- HostAdapter->BoardName);
- BusLogicHostAdapterCount++;
- }
- else
- {
- /*
- An error occurred during Host Adapter Configuration Querying,
- Resource Acquisition, Interrupt Testing, CCB Creation, Host
- Adapter Initialization, or Target Device Inquiry, so remove
- Host Adapter from the list of registered BusLogic Host Adapters,
- destroy the CCBs, Release the System Resources, and Unregister
- the SCSI Host.
- */
- BusLogic_DestroyCCBs(HostAdapter);
- BusLogic_ReleaseResources(HostAdapter);
- BusLogic_UnregisterHostAdapter(HostAdapter);
- scsi_unregister(Host);
- }
- }
- return BusLogicHostAdapterCount;
-}
-
-
-/*
- BusLogic_ReleaseHostAdapter releases all resources previously acquired to
- support a specific Host Adapter, including the I/O Address range, and
- unregisters the BusLogic Host Adapter.
-*/
-
-int BusLogic_ReleaseHostAdapter(SCSI_Host_T *Host)
-{
- BusLogic_HostAdapter_T *HostAdapter =
- (BusLogic_HostAdapter_T *) Host->hostdata;
- /*
- Destroy the CCBs and release any system resources acquired to use
- Host Adapter.
- */
- BusLogic_DestroyCCBs(HostAdapter);
- BusLogic_ReleaseResources(HostAdapter);
- /*
- Release usage of the I/O Address range.
- */
- release_region(HostAdapter->IO_Address, BusLogic_IO_PortCount);
- /*
- Remove Host Adapter from the list of registered BusLogic Host Adapters.
- */
- BusLogic_UnregisterHostAdapter(HostAdapter);
- return 0;
-}
-
-
-/*
- BusLogic_ComputeResultCode computes a SCSI Subsystem Result Code from
- the Host Adapter Status and Target Device Status.
-*/
-
-static int BusLogic_ComputeResultCode(BusLogic_HostAdapterStatus_T
- HostAdapterStatus,
- BusLogic_TargetDeviceStatus_T
- TargetDeviceStatus)
-{
- int HostStatus;
- switch (HostAdapterStatus)
- {
- case BusLogic_CommandCompletedNormally:
- case BusLogic_LinkedCommandCompleted:
- case BusLogic_LinkedCommandCompletedWithFlag:
- HostStatus = DID_OK;
- break;
- case BusLogic_SCSISelectionTimeout:
- HostStatus = DID_TIME_OUT;
- break;
- case BusLogic_InvalidOutgoingMailboxActionCode:
- case BusLogic_InvalidCommandOperationCode:
- case BusLogic_InvalidCommandParameter:
- printk("BusLogic: BusLogic Driver Protocol Error 0x%02X\n",
- HostAdapterStatus);
- case BusLogic_DataOverUnderRun:
- case BusLogic_UnexpectedBusFree:
- case BusLogic_LinkedCCBhasInvalidLUN:
- case BusLogic_AutoRequestSenseFailed:
- case BusLogic_TaggedQueuingMessageRejected:
- case BusLogic_UnsupportedMessageReceived:
- case BusLogic_HostAdapterHardwareFailed:
- case BusLogic_TargetDeviceReconnectedImproperly:
- case BusLogic_AbortQueueGenerated:
- case BusLogic_HostAdapterSoftwareError:
- case BusLogic_HostAdapterHardwareTimeoutError:
- case BusLogic_SCSIParityErrorDetected:
- HostStatus = DID_ERROR;
- break;
- case BusLogic_InvalidBusPhaseRequested:
- case BusLogic_TargetFailedResponseToATN:
- case BusLogic_HostAdapterAssertedRST:
- case BusLogic_OtherDeviceAssertedRST:
- case BusLogic_HostAdapterAssertedBusDeviceReset:
- HostStatus = DID_RESET;
- break;
- default:
- printk("BusLogic: unknown Host Adapter Status 0x%02X\n",
- HostAdapterStatus);
- HostStatus = DID_ERROR;
- break;
- }
- return (HostStatus << 16) | TargetDeviceStatus;
-}
-
-
-/*
- BusLogic_InterruptHandler handles hardware interrupts from BusLogic Host
- Adapters. To simplify handling shared IRQ Channels, all installed BusLogic
- Host Adapters are scanned whenever any one of them signals a hardware
- interrupt.
-*/
-
-static void BusLogic_InterruptHandler(int IRQ_Channel,
- Registers_T *InterruptRegisters)
-{
- BusLogic_CCB_T *FirstCompletedCCB = NULL, *LastCompletedCCB = NULL;
- BusLogic_HostAdapter_T *HostAdapter;
- int HostAdapterResetPendingCount = 0;
- /*
- Iterate over the installed BusLogic Host Adapters accepting any Incoming
- Mailbox entries and saving the completed CCBs for processing. This
- interrupt handler is installed with SA_INTERRUPT, so interrupts are
- disabled when the interrupt handler is entered.
- */
- for (HostAdapter = BusLogic_RegisteredHostAdapters;
- HostAdapter != NULL;
- HostAdapter = HostAdapter->Next)
- {
- unsigned char InterruptRegister;
- /*
- Acquire exclusive access to Host Adapter.
- */
- BusLogic_LockHostAdapterID(HostAdapter);
- /*
- Read the Host Adapter Interrupt Register.
- */
- InterruptRegister = BusLogic_ReadInterruptRegister(HostAdapter);
- if (InterruptRegister & BusLogic_InterruptValid)
- {
- /*
- Acknowledge the interrupt and reset the Host Adapter
- Interrupt Register.
- */
- BusLogic_WriteControlRegister(HostAdapter, BusLogic_InterruptReset);
- /*
- Process valid SCSI Reset State and Incoming Mailbox Loaded
- interrupts. Command Complete interrupts are noted, and
- Outgoing Mailbox Available interrupts are ignored, as they
- are never enabled.
- */
- if (InterruptRegister & BusLogic_SCSIResetState)
- {
- HostAdapter->HostAdapterResetPending = true;
- HostAdapterResetPendingCount++;
- }
- else if (InterruptRegister & BusLogic_IncomingMailboxLoaded)
- {
- /*
- Scan through the Incoming Mailboxes in Strict Round Robin
- fashion, saving any completed CCBs for further processing.
- It is essential that for each CCB and SCSI Command issued,
- command completion processing is performed exactly once.
- Therefore, only Incoming Mailboxes with completion code
- Command Completed Without Error, Command Completed With
- Error, or Command Aborted At Host Request are saved for
- completion processing. When an Incoming Mailbox has a
- completion code of Aborted Command Not Found, the CCB had
- already completed or been aborted before the current Abort
- request was processed, and so completion processing has
- already occurred and no further action should be taken.
- */
- BusLogic_IncomingMailbox_T *NextIncomingMailbox =
- HostAdapter->NextIncomingMailbox;
- BusLogic_CompletionCode_T MailboxCompletionCode;
- while ((MailboxCompletionCode =
- NextIncomingMailbox->CompletionCode) !=
- BusLogic_IncomingMailboxFree)
- {
- BusLogic_CCB_T *CCB = NextIncomingMailbox->CCB;
- if (MailboxCompletionCode != BusLogic_AbortedCommandNotFound)
- if (CCB->Status == BusLogic_CCB_Active)
- {
- /*
- Mark this CCB as completed and add it to the end
- of the list of completed CCBs.
- */
- CCB->Status = BusLogic_CCB_Completed;
- CCB->MailboxCompletionCode = MailboxCompletionCode;
- CCB->Next = NULL;
- if (FirstCompletedCCB == NULL)
- {
- FirstCompletedCCB = CCB;
- LastCompletedCCB = CCB;
- }
- else
- {
- LastCompletedCCB->Next = CCB;
- LastCompletedCCB = CCB;
- }
- HostAdapter->QueuedOperationCount[CCB->TargetID]--;
- }
- else
- {
- /*
- If a CCB ever appears in an Incoming Mailbox and
- is not marked as status Active, then there is
- most likely a bug in the Host Adapter firmware.
- */
- printk("scsi%d: Illegal CCB #%d status %d in "
- "Incoming Mailbox\n", HostAdapter->HostNumber,
- CCB->SerialNumber, CCB->Status);
- }
- else printk("scsi%d: Aborted CCB #%d to Target %d "
- "Not Found\n", HostAdapter->HostNumber,
- CCB->SerialNumber, CCB->TargetID);
- NextIncomingMailbox->CompletionCode =
- BusLogic_IncomingMailboxFree;
- if (++NextIncomingMailbox > HostAdapter->LastIncomingMailbox)
- NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
- }
- HostAdapter->NextIncomingMailbox = NextIncomingMailbox;
- }
- else if (InterruptRegister & BusLogic_CommandComplete)
- HostAdapter->HostAdapterCommandCompleted = true;
- }
- /*
- Release exclusive access to Host Adapter.
- */
- BusLogic_UnlockHostAdapterID(HostAdapter);
- }
- /*
- Enable interrupts while the completed CCBs are processed.
- */
- sti();
- /*
- Iterate over the Host Adapters performing any pending Host Adapter Resets.
- */
- if (HostAdapterResetPendingCount > 0)
- for (HostAdapter = BusLogic_RegisteredHostAdapters;
- HostAdapter != NULL;
- HostAdapter = HostAdapter->Next)
- if (HostAdapter->HostAdapterResetPending)
- {
- BusLogic_ResetHostAdapter(HostAdapter, NULL);
- HostAdapter->HostAdapterResetPending = false;
- scsi_mark_host_bus_reset(HostAdapter->SCSI_Host);
- }
- /*
- Iterate over the completed CCBs setting the SCSI Command Result Codes,
- deallocating the CCBs, and calling the Completion Routines.
- */
- while (FirstCompletedCCB != NULL)
- {
- BusLogic_CCB_T *CCB = FirstCompletedCCB;
- SCSI_Command_T *Command = CCB->Command;
- FirstCompletedCCB = FirstCompletedCCB->Next;
- HostAdapter = CCB->HostAdapter;
- /*
- Bus Device Reset CCBs have the Command field non-NULL only when a Bus
- Device Reset was requested for a command that was not currently active
- in the Host Adapter, and hence would not have its Completion Routine
- called otherwise.
- */
- if (CCB->Opcode == BusLogic_SCSIBusDeviceReset)
- {
- printk("scsi%d: Bus Device Reset CCB #%d to Target %d Completed\n",
- HostAdapter->HostNumber, CCB->SerialNumber, CCB->TargetID);
- if (Command != NULL) Command->result = DID_RESET << 16;
- }
- else
- /*
- Translate the Mailbox Completion Code, Host Adapter Status, and
- Target Device Status into a SCSI Subsystem Result Code.
- */
- switch (CCB->MailboxCompletionCode)
- {
- case BusLogic_IncomingMailboxFree:
- case BusLogic_AbortedCommandNotFound:
- printk("scsi%d: CCB #%d to Target %d Impossible State\n",
- HostAdapter->HostNumber, CCB->SerialNumber, CCB->TargetID);
- break;
- case BusLogic_CommandCompletedWithoutError:
- HostAdapter->CommandSuccessfulFlag[CCB->TargetID] = true;
- Command->result = DID_OK << 16;
- break;
- case BusLogic_CommandAbortedAtHostRequest:
- printk("scsi%d: CCB #%d to Target %d Aborted\n",
- HostAdapter->HostNumber, CCB->SerialNumber, CCB->TargetID);
- Command->result = DID_ABORT << 16;
- break;
- case BusLogic_CommandCompletedWithError:
- Command->result =
- BusLogic_ComputeResultCode(CCB->HostAdapterStatus,
- CCB->TargetDeviceStatus);
- if (BusLogic_GlobalOptions & BusLogic_TraceErrors)
- if (CCB->HostAdapterStatus != BusLogic_SCSISelectionTimeout)
- {
- int i;
- printk("scsi%d: CCB #%d Target %d: Result %X "
- "Host Adapter Status %02X Target Status %02X\n",
- HostAdapter->HostNumber, CCB->SerialNumber,
- CCB->TargetID, Command->result,
- CCB->HostAdapterStatus, CCB->TargetDeviceStatus);
- printk("scsi%d: CDB ", HostAdapter->HostNumber);
- for (i = 0; i < CCB->CDB_Length; i++)
- printk(" %02X", CCB->CDB[i]);
- printk("\n");
- printk("scsi%d: Sense ", HostAdapter->HostNumber);
- for (i = 0; i < CCB->SenseDataLength; i++)
- printk(" %02X", (*CCB->SenseDataPointer)[i]);
- printk("\n");
- }
- break;
- }
- /*
- Place CCB back on the Host Adapter's free list.
- */
- BusLogic_DeallocateCCB(CCB);
- /*
- Call the SCSI Command Completion Routine if appropriate.
- */
- if (Command != NULL) Command->scsi_done(Command);
- }
-}
-
-
-/*
- BusLogic_WriteOutgoingMailbox places CCB and Action Code into an Outgoing
- Mailbox for execution by Host Adapter.
-*/
-
-static boolean BusLogic_WriteOutgoingMailbox(BusLogic_HostAdapter_T
- *HostAdapter,
- BusLogic_ActionCode_T ActionCode,
- BusLogic_CCB_T *CCB)
-{
- BusLogic_OutgoingMailbox_T *NextOutgoingMailbox;
- boolean Result = false;
- BusLogic_LockHostAdapter(HostAdapter);
- NextOutgoingMailbox = HostAdapter->NextOutgoingMailbox;
- if (NextOutgoingMailbox->ActionCode == BusLogic_OutgoingMailboxFree)
- {
- CCB->Status = BusLogic_CCB_Active;
- /*
- The CCB field must be written before the Action Code field since
- the Host Adapter is operating asynchronously and the locking code
- does not protect against simultaneous access by the Host Adapter.
- */
- NextOutgoingMailbox->CCB = CCB;
- NextOutgoingMailbox->ActionCode = ActionCode;
- BusLogic_StartMailboxScan(HostAdapter);
- if (++NextOutgoingMailbox > HostAdapter->LastOutgoingMailbox)
- NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
- HostAdapter->NextOutgoingMailbox = NextOutgoingMailbox;
- if (ActionCode == BusLogic_MailboxStartCommand)
- HostAdapter->QueuedOperationCount[CCB->TargetID]++;
- Result = true;
- }
- BusLogic_UnlockHostAdapter(HostAdapter);
- return Result;
-}
-
-
-/*
- BusLogic_QueueCommand creates a CCB for Command and places it into an
- Outgoing Mailbox for execution by the associated Host Adapter.
-*/
-
-int BusLogic_QueueCommand(SCSI_Command_T *Command,
- void (*CompletionRoutine)(SCSI_Command_T *))
-{
- BusLogic_HostAdapter_T *HostAdapter =
- (BusLogic_HostAdapter_T *) Command->host->hostdata;
- unsigned char *CDB = Command->cmnd;
- unsigned char CDB_Length = Command->cmd_len;
- unsigned char TargetID = Command->target;
- unsigned char LogicalUnit = Command->lun;
- void *BufferPointer = Command->request_buffer;
- int BufferLength = Command->request_bufflen;
- int SegmentCount = Command->use_sg;
- BusLogic_CCB_T *CCB;
- long EnableTQ;
- /*
- SCSI REQUEST_SENSE commands will be executed automatically by the Host
- Adapter for any errors, so they should not be executed explicitly unless
- the Sense Data is zero indicating that no error occurred.
- */
- if (CDB[0] == REQUEST_SENSE && Command->sense_buffer[0] != 0)
- {
- Command->result = DID_OK << 16;
- CompletionRoutine(Command);
- return 0;
- }
- /*
- Allocate a CCB from the Host Adapter's free list. If there are none
- available and memory allocation fails, return a result code of Bus Busy
- so that this Command will be retried.
- */
- CCB = BusLogic_AllocateCCB(HostAdapter);
- if (CCB == NULL)
- {
- Command->result = DID_BUS_BUSY << 16;
- CompletionRoutine(Command);
- return 0;
- }
- /*
- Initialize the fields in the BusLogic Command Control Block (CCB).
- */
- if (SegmentCount == 0)
- {
- CCB->Opcode = BusLogic_InitiatorCCB;
- CCB->DataLength = BufferLength;
- CCB->DataPointer = BufferPointer;
- }
- else
- {
- SCSI_ScatterList_T *ScatterList = (SCSI_ScatterList_T *) BufferPointer;
- int Segment;
- CCB->Opcode = BusLogic_InitiatorCCB_ScatterGather;
- CCB->DataLength = SegmentCount * sizeof(BusLogic_ScatterGatherSegment_T);
- CCB->DataPointer = CCB->ScatterGatherList;
- for (Segment = 0; Segment < SegmentCount; Segment++)
- {
- CCB->ScatterGatherList[Segment].SegmentByteCount =
- ScatterList[Segment].length;
- CCB->ScatterGatherList[Segment].SegmentDataPointer =
- ScatterList[Segment].address;
- }
- }
- switch (CDB[0])
- {
- case READ_6:
- case READ_10:
- CCB->DataDirection = BusLogic_DataInLengthChecked;
- HostAdapter->ReadWriteOperationCount[TargetID]++;
- break;
- case WRITE_6:
- case WRITE_10:
- CCB->DataDirection = BusLogic_DataOutLengthChecked;
- HostAdapter->ReadWriteOperationCount[TargetID]++;
- break;
- default:
- CCB->DataDirection = BusLogic_UncheckedDataTransfer;
- break;
- }
- CCB->CDB_Length = CDB_Length;
- CCB->SenseDataLength = sizeof(Command->sense_buffer);
- CCB->HostAdapterStatus = 0;
- CCB->TargetDeviceStatus = 0;
- CCB->TargetID = TargetID;
- CCB->LogicalUnit = LogicalUnit;
- /*
- For Wide SCSI Host Adapters, Wide Mode CCBs are used to support more than
- 8 Logical Units per Target, and this requires setting the overloaded
- TagEnable field to Logical Unit bit 5.
- */
- if (HostAdapter->HostWideSCSI)
- {
- CCB->TagEnable = LogicalUnit >> 5;
- CCB->WideModeTagEnable = false;
- }
- else CCB->TagEnable = false;
- /*
- BusLogic recommends that after a Reset the first couple of commands that
- are sent to a Target be sent in a non Tagged Queue fashion so that the Host
- Adapter and Target can establish Synchronous Transfer before Queue Tag
- messages can interfere with the Synchronous Negotiation message. By
- waiting to enable tagged Queuing until after the first 16 read/write
- commands have been sent, it is assured that the Tagged Queuing message
- will not occur while the partition table is printed.
- */
- if ((HostAdapter->TaggedQueuingPermitted & (1 << TargetID)) &&
- Command->device->tagged_supported &&
- (EnableTQ = HostAdapter->ReadWriteOperationCount[TargetID] - 16) >= 0)
- {
- BusLogic_QueueTag_T QueueTag = BusLogic_SimpleQueueTag;
- unsigned long CurrentTime = jiffies;
- if (EnableTQ == 0)
- printk("scsi%d: Tagged Queuing now active for Target %d\n",
- HostAdapter->HostNumber, TargetID);
- /*
- When using Tagged Queuing with Simple Queue Tags, it appears that disk
- drive controllers do not guarantee that a queued command will not
- remain in a disconnected state indefinitely if commands that read or
- write nearer the head position continue to arrive without interruption.
- Therefore, for each Target Device this driver keeps track of the last
- time either the queue was empty or an Ordered Queue Tag was issued. If
- more than 2 seconds have elapsed since this last sequence point, this
- command will be issued with an Ordered Queue Tag rather than a Simple
- Queue Tag, which forces the Target Device to complete all previously
- queued commands before this command may be executed.
- */
- if (HostAdapter->QueuedOperationCount[TargetID] == 0)
- HostAdapter->LastSequencePoint[TargetID] = CurrentTime;
- else if (CurrentTime - HostAdapter->LastSequencePoint[TargetID] > 2*HZ)
- {
- HostAdapter->LastSequencePoint[TargetID] = CurrentTime;
- QueueTag = BusLogic_OrderedQueueTag;
- }
- if (HostAdapter->HostWideSCSI)
- {
- CCB->WideModeTagEnable = true;
- CCB->WideModeQueueTag = QueueTag;
- }
- else
- {
- CCB->TagEnable = true;
- CCB->QueueTag = QueueTag;
- }
- }
- memcpy(CCB->CDB, CDB, CDB_Length);
- CCB->SenseDataPointer = (SCSI_SenseData_T *) &Command->sense_buffer;
- CCB->Command = Command;
- Command->scsi_done = CompletionRoutine;
- /*
- Place the CCB in an Outgoing Mailbox. If there are no Outgoing
- Mailboxes available, return a result code of Bus Busy so that this
- Command will be retried.
- */
- if (!(BusLogic_WriteOutgoingMailbox(HostAdapter,
- BusLogic_MailboxStartCommand, CCB)))
- {
- printk("scsi%d: cannot write Outgoing Mailbox\n",
- HostAdapter->HostNumber);
- BusLogic_DeallocateCCB(CCB);
- Command->result = DID_BUS_BUSY << 16;
- CompletionRoutine(Command);
- }
- return 0;
-}
-
-
-/*
- BusLogic_AbortCommand aborts Command if possible.
-*/
-
-int BusLogic_AbortCommand(SCSI_Command_T *Command)
-{
- BusLogic_HostAdapter_T *HostAdapter =
- (BusLogic_HostAdapter_T *) Command->host->hostdata;
- unsigned long CommandPID = Command->pid;
- unsigned char InterruptRegister;
- BusLogic_CCB_T *CCB;
- int Result;
- /*
- If the Host Adapter has posted an interrupt but the Interrupt Handler
- has not been called for some reason (i.e. the interrupt was lost), try
- calling the Interrupt Handler directly to process the commands that
- have been completed.
- */
- InterruptRegister = BusLogic_ReadInterruptRegister(HostAdapter);
- if (InterruptRegister & BusLogic_InterruptValid)
- {
- unsigned long ProcessorFlags;
- printk("scsi%d: Recovering Lost/Delayed Interrupt for IRQ Channel %d\n",
- HostAdapter->HostNumber, HostAdapter->IRQ_Channel);
- save_flags(ProcessorFlags);
- cli();
- BusLogic_InterruptHandler(HostAdapter->IRQ_Channel, NULL);
- restore_flags(ProcessorFlags);
- return SCSI_ABORT_SNOOZE;
- }
- /*
- Find the CCB to be aborted if possible.
- */
- BusLogic_LockHostAdapter(HostAdapter);
- for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
- if (CCB->Command == Command) break;
- BusLogic_UnlockHostAdapter(HostAdapter);
- if (CCB == NULL)
- {
- printk("scsi%d: Unable to Abort Command to Target %d - No CCB Found\n",
- HostAdapter->HostNumber, Command->target);
- return SCSI_ABORT_NOT_RUNNING;
- }
- /*
- Briefly pause to see if this command will complete.
- */
- printk("scsi%d: Pausing briefly to see if CCB #%d "
- "to Target %d will complete\n",
- HostAdapter->HostNumber, CCB->SerialNumber, CCB->TargetID);
- BusLogic_Delay(2);
- /*
- If this CCB is still Active and still refers to the same Command, then
- actually aborting this Command is necessary.
- */
- BusLogic_LockHostAdapter(HostAdapter);
- Result = SCSI_ABORT_NOT_RUNNING;
- if (CCB->Status == BusLogic_CCB_Active &&
- CCB->Command == Command && Command->pid == CommandPID)
- {
- /*
- Attempt to abort this CCB.
- */
- if (BusLogic_WriteOutgoingMailbox(HostAdapter,
- BusLogic_MailboxAbortCommand, CCB))
- {
- printk("scsi%d: Aborting CCB #%d to Target %d\n",
- HostAdapter->HostNumber, CCB->SerialNumber, CCB->TargetID);
- Result = SCSI_ABORT_PENDING;
- }
- else
- {
- printk("scsi%d: Unable to Abort CCB #%d to Target %d - "
- "No Outgoing Mailboxes\n", HostAdapter->HostNumber,
- CCB->SerialNumber, CCB->TargetID);
- Result = SCSI_ABORT_BUSY;
- }
- }
- else printk("scsi%d: CCB #%d to Target %d completed\n",
- HostAdapter->HostNumber, CCB->SerialNumber, CCB->TargetID);
- BusLogic_UnlockHostAdapter(HostAdapter);
- return Result;
-}
-
-
-/*
- BusLogic_ResetHostAdapter resets Host Adapter if possible, marking all
- currently executing SCSI commands as having been reset, as well as
- the specified Command if non-NULL.
-*/
-
-static int BusLogic_ResetHostAdapter(BusLogic_HostAdapter_T *HostAdapter,
- SCSI_Command_T *Command)
-{
- BusLogic_CCB_T *CCB;
- if (Command == NULL)
- printk("scsi%d: Resetting %s due to SCSI Reset State Interrupt\n",
- HostAdapter->HostNumber, HostAdapter->BoardName);
- else printk("scsi%d: Resetting %s due to Target %d\n",
- HostAdapter->HostNumber, HostAdapter->BoardName, Command->target);
- /*
- Attempt to Reset and Reinitialize the Host Adapter.
- */
- BusLogic_LockHostAdapter(HostAdapter);
- if (!(BusLogic_HardResetHostAdapter(HostAdapter) &&
- BusLogic_InitializeHostAdapter(HostAdapter)))
- {
- printk("scsi%d: Resetting %s Failed\n",
- HostAdapter->HostNumber, HostAdapter->BoardName);
- BusLogic_UnlockHostAdapter(HostAdapter);
- return SCSI_RESET_ERROR;
- }
- BusLogic_UnlockHostAdapter(HostAdapter);
- /*
- Wait a few seconds between the Host Adapter Hard Reset which initiates
- a SCSI Bus Reset and issuing any SCSI commands. Some SCSI devices get
- confused if they receive SCSI commands too soon after a SCSI Bus Reset.
- */
- BusLogic_Delay(HostAdapter->BusSettleTime);
- /*
- Mark all currently executing CCBs as having been reset.
- */
- BusLogic_LockHostAdapter(HostAdapter);
- for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
- if (CCB->Status == BusLogic_CCB_Active)
- {
- CCB->Status = BusLogic_CCB_Reset;
- if (CCB->Command == Command)
- {
- CCB->Command = NULL;
- /*
- Disable Tagged Queuing if it was active for this Target Device.
- */
- if (((HostAdapter->HostWideSCSI && CCB->WideModeTagEnable) ||
- (!HostAdapter->HostWideSCSI && CCB->TagEnable)) &&
- (HostAdapter->TaggedQueuingPermitted & (1 << CCB->TargetID)))
- {
- HostAdapter->TaggedQueuingPermitted &= ~(1 << CCB->TargetID);
- printk("scsi%d: Tagged Queuing now disabled for Target %d\n",
- HostAdapter->HostNumber, CCB->TargetID);
- }
- }
- }
- BusLogic_UnlockHostAdapter(HostAdapter);
- /*
- Perform completion processing for the Command being Reset.
- */
- if (Command != NULL)
- {
- Command->result = DID_RESET << 16;
- Command->scsi_done(Command);
- }
- /*
- Perform completion processing for any other active CCBs.
- */
- for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
- if (CCB->Status == BusLogic_CCB_Reset)
- {
- Command = CCB->Command;
- BusLogic_DeallocateCCB(CCB);
- if (Command != NULL)
- {
- Command->result = DID_RESET << 16;
- Command->scsi_done(Command);
- }
- }
- return SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET;
-}
-
-
-/*
- BusLogic_BusDeviceReset sends a Bus Device Reset to the Target
- associated with Command.
-*/
-
-static int BusLogic_BusDeviceReset(BusLogic_HostAdapter_T *HostAdapter,
- SCSI_Command_T *Command)
-{
- BusLogic_CCB_T *CCB = BusLogic_AllocateCCB(HostAdapter), *XCCB;
- unsigned char TargetID = Command->target;
- /*
- If sending a Bus Device Reset is impossible, attempt a full Host
- Adapter Hard Reset and SCSI Bus Reset.
- */
- if (CCB == NULL)
- return BusLogic_ResetHostAdapter(HostAdapter, Command);
- printk("scsi%d: Sending Bus Device Reset CCB #%d to Target %d\n",
- HostAdapter->HostNumber, CCB->SerialNumber, TargetID);
- CCB->Opcode = BusLogic_SCSIBusDeviceReset;
- CCB->TargetID = TargetID;
- CCB->Command = Command;
- /*
- If there is a currently executing CCB in the Host Adapter for this Command,
- then an Incoming Mailbox entry will be made with a completion code of
- BusLogic_HostAdapterAssertedBusDeviceReset. Otherwise, the CCB's Command
- field will be left pointing to the Command so that the interrupt for the
- completion of the Bus Device Reset can call the Completion Routine for the
- Command.
- */
- BusLogic_LockHostAdapter(HostAdapter);
- for (XCCB = HostAdapter->All_CCBs; XCCB != NULL; XCCB = XCCB->NextAll)
- if (XCCB->Command == Command && XCCB->Status == BusLogic_CCB_Active)
- {
- CCB->Command = NULL;
- /*
- Disable Tagged Queuing if it was active for this Target Device.
- */
- if (((HostAdapter->HostWideSCSI && XCCB->WideModeTagEnable) ||
- (!HostAdapter->HostWideSCSI && XCCB->TagEnable)) &&
- (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)))
- {
- HostAdapter->TaggedQueuingPermitted &= ~(1 << TargetID);
- printk("scsi%d: Tagged Queuing now disabled for Target %d\n",
- HostAdapter->HostNumber, TargetID);
- }
- break;
- }
- BusLogic_UnlockHostAdapter(HostAdapter);
- /*
- Attempt to write an Outgoing Mailbox with the Bus Device Reset CCB.
- If sending a Bus Device Reset is impossible, attempt a full Host
- Adapter Hard Reset and SCSI Bus Reset.
- */
- if (!(BusLogic_WriteOutgoingMailbox(HostAdapter,
- BusLogic_MailboxStartCommand, CCB)))
- {
- printk("scsi%d: cannot write Outgoing Mailbox for Bus Device Reset\n",
- HostAdapter->HostNumber);
- BusLogic_DeallocateCCB(CCB);
- return BusLogic_ResetHostAdapter(HostAdapter, Command);
- }
- HostAdapter->ReadWriteOperationCount[TargetID] = 0;
- HostAdapter->QueuedOperationCount[TargetID] = 0;
- return SCSI_RESET_PENDING;
-}
-
-
-/*
- BusLogic_ResetCommand takes appropriate action to reset Command.
-*/
-
-int BusLogic_ResetCommand(SCSI_Command_T *Command)
-{
- BusLogic_HostAdapter_T *HostAdapter =
- (BusLogic_HostAdapter_T *) Command->host->hostdata;
- unsigned char TargetID = Command->target;
- unsigned char ErrorRecoveryOption =
- HostAdapter->ErrorRecoveryOption[TargetID];
- if (ErrorRecoveryOption == BusLogic_ErrorRecoveryDefault)
- if (Command->host->suggest_bus_reset)
- ErrorRecoveryOption = BusLogic_ErrorRecoveryHardReset;
- else ErrorRecoveryOption = BusLogic_ErrorRecoveryBusDeviceReset;
- switch (ErrorRecoveryOption)
- {
- case BusLogic_ErrorRecoveryHardReset:
- return BusLogic_ResetHostAdapter(HostAdapter, Command);
- case BusLogic_ErrorRecoveryBusDeviceReset:
- if (HostAdapter->CommandSuccessfulFlag[TargetID])
- {
- HostAdapter->CommandSuccessfulFlag[TargetID] = false;
- return BusLogic_BusDeviceReset(HostAdapter, Command);
- }
- else return BusLogic_ResetHostAdapter(HostAdapter, Command);
- }
- printk("scsi%d: Error Recovery for Target %d Suppressed\n",
- HostAdapter->HostNumber, TargetID);
- return SCSI_RESET_PUNT;
-}
-
-
-/*
- BusLogic_BIOSDiskParameters returns the Heads/Sectors/Cylinders BIOS Disk
- Parameters for Disk. The default disk geometry is 64 heads, 32 sectors, and
- the appropriate number of cylinders so as not to exceed drive capacity. In
- order for disks equal to or larger than 1 GB to be addressable by the BIOS
- without exceeding the BIOS limitation of 1024 cylinders, Extended Translation
- may be enabled in AutoSCSI on "C" Series boards or by a dip switch setting
- on older boards. With Extended Translation enabled, drives between 1 GB
- inclusive and 2 GB exclusive are given a disk geometry of 128 heads and 32
- sectors, and drives between 2 GB inclusive and 8 GB exclusive are given a
- disk geometry of 255 heads and 63 sectors. On "C" Series boards the firmware
- can be queried for the precise translation in effect for each drive
- individually, but there is really no need to do so since we know the total
- capacity of the drive and whether Extended Translation is enabled, hence we
- can deduce the BIOS disk geometry that must be in effect.
-*/
-
-int BusLogic_BIOSDiskParameters(SCSI_Disk_T *Disk, KernelDevice_T Device,
- int *Parameters)
-{
- BusLogic_HostAdapter_T *HostAdapter =
- (BusLogic_HostAdapter_T *) Disk->device->host->hostdata;
- BIOS_DiskParameters_T *DiskParameters = (BIOS_DiskParameters_T *) Parameters;
- if (HostAdapter->ExtendedTranslation &&
- Disk->capacity >= 2*1024*1024 /* 1 GB in 512 byte sectors */)
- if (Disk->capacity >= 4*1024*1024 /* 2 GB in 512 byte sectors */)
- {
- DiskParameters->Heads = 255;
- DiskParameters->Sectors = 63;
- }
- else
- {
- DiskParameters->Heads = 128;
- DiskParameters->Sectors = 32;
- }
- else
- {
- DiskParameters->Heads = 64;
- DiskParameters->Sectors = 32;
- }
- DiskParameters->Cylinders =
- Disk->capacity / (DiskParameters->Heads * DiskParameters->Sectors);
- return 0;
-}
-
-
-/*
- BusLogic_Setup handles processing of Kernel Command Line Arguments.
-
- For the BusLogic driver, a kernel command line entry comprises the driver
- identifier "BusLogic=" optionally followed by a comma-separated sequence of
- integers and then optionally followed by a comma-separated sequence of
- strings. Each command line entry applies to one BusLogic Host Adapter.
- Multiple command line entries may be used in systems which contain multiple
- BusLogic Host Adapters.
-
- The first integer specified is the I/O Address at which the Host Adapter is
- located. If unspecified, it defaults to 0 which means to apply this entry to
- the first BusLogic Host Adapter found during the default probe sequence. If
- any I/O Address parameters are provided on the command line, then the default
- probe sequence is omitted.
-
- The second integer specified is the number of Concurrent Commands per Logical
- Unit to allow for Target Devices on the Host Adapter. If unspecified, it
- defaults to 0 which means to use the value of BusLogic_Concurrency for
- non-ISA Host Adapters, or BusLogic_Concurrency_ISA for ISA Host Adapters.
-
- The third integer specified is the Bus Settle Time in seconds. This is
- the amount of time to wait between a Host Adapter Hard Reset which initiates
- a SCSI Bus Reset and issuing any SCSI commands. If unspecified, it defaults
- to 0 which means to use the value of BusLogic_DefaultBusSettleTime.
-
- The fourth integer specified is the Local Options. If unspecified, it
- defaults to 0. Note that Local Options are only applied to a specific Host
- Adapter.
-
- The fifth integer specified is the Global Options. If unspecified, it
- defaults to 0. Note that Global Options are applied across all Host
- Adapters.
-
- The string options are used to provide control over Tagged Queuing and Error
- Recovery. If both Tagged Queuing and Error Recovery strings are provided, the
- Tagged Queuing specification string must come first.
-
- The Tagged Queuing specification begins with "TQ:" and allows for explicitly
- specifying whether Tagged Queuing is permitted on Target Devices that support
- it. The following specification options are available:
-
- TQ:Default Tagged Queuing will be permitted based on the firmware
- version of the BusLogic Host Adapter and based on
- whether the Concurrency value allows queuing multiple
- commands.
-
- TQ:Enable Tagged Queuing will be enabled for all Target Devices
- on this Host Adapter overriding any limitation that
- would otherwise be imposed based on the Host Adapter
- firmware version.
-
- TQ:Disable Tagged Queuing will be disabled for all Target Devices
- on this Host Adapter.
-
- TQ:<Per-Target-Spec> Tagged Queuing will be controlled individually for each
- Target Device. <Per-Target-Spec> is a sequence of "Y",
- "N", and "X" characters. "Y" enabled Tagged Queuing,
- "N" disables Tagged Queuing, and "X" accepts the
- default based on the firmware version. The first
- character refers to Target 0, the second to Target 1,
- and so on; if the sequence of "Y", "N", and "X"
- characters does not cover all the Target Devices,
- unspecified characters are assumed to be "X".
-
- Note that explicitly requesting Tagged Queuing may lead to problems; this
- facility is provided primarily to allow disabling Tagged Queuing on Target
- Devices that do not implement it correctly.
-
- The Error Recovery specification begins with "ER:" and allows for explicitly
- specifying the Error Recovery action to be performed when ResetCommand is
- called due to a SCSI Command failing to complete successfully. The following
- specification options are available:
-
- ER:Default Error Recovery will select between the Hard Reset and
- Bus Device Reset options based on the recommendation
- of the SCSI Subsystem.
-
- ER:HardReset Error Recovery will initiate a Host Adapter Hard Reset
- which also causes a SCSI Bus Reset.
-
- ER:BusDeviceReset Error Recovery will send a Bus Device Reset message to
- the individual Target Device causing the error. If
- Error Recovery is again initiated for this Target
- Device and no SCSI Command to this Target Device has
- completed successfully since the Bus Device Reset
- message was sent, then a Hard Reset will be attempted.
-
- ER:None Error Recovery will be suppressed. This option should
- only be selected if a SCSI Bus Reset or Bus Device
- Reset will cause the Target Device to fail completely
- and unrecoverably.
-
- ER:<Per-Target-Spec> Error Recovery will be controlled individually for each
- Target Device. <Per-Target-Spec> is a sequence of "D",
- "H", "B", and "N" characters. "D" selects Default, "H"
- selects Hard Reset, "B" selects Bus Device Reset, and
- "N" selects None. The first character refers to Target
- 0, the second to Target 1, and so on; if the sequence
- of "D", "H", "B", and "N" characters does not cover all
- the Target Devices, unspecified characters are assumed
- to be "D".
-*/
-
-void BusLogic_Setup(char *Strings, int *Integers)
-{
- BusLogic_CommandLineEntry_T *CommandLineEntry =
- &BusLogic_CommandLineEntries[BusLogic_CommandLineEntryCount++];
- static int ProbeListIndex = 0;
- int IntegerCount = Integers[0], TargetID, i;
- CommandLineEntry->IO_Address = 0;
- CommandLineEntry->Concurrency = 0;
- CommandLineEntry->BusSettleTime = 0;
- CommandLineEntry->LocalOptions = 0;
- CommandLineEntry->TaggedQueuingPermitted = 0;
- CommandLineEntry->TaggedQueuingPermittedMask = 0;
- memset(CommandLineEntry->ErrorRecoveryOption,
- BusLogic_ErrorRecoveryDefault,
- sizeof(CommandLineEntry->ErrorRecoveryOption));
- if (IntegerCount > 5)
- printk("BusLogic: Unexpected Command Line Integers ignored\n");
- if (IntegerCount >= 1)
- {
- unsigned short IO_Address = Integers[1];
- if (IO_Address > 0)
- {
- for (i = 0; ; i++)
- if (BusLogic_IO_StandardAddresses[i] == 0)
- {
- printk("BusLogic: Invalid Command Line Entry "
- "(illegal I/O Address 0x%X)\n", IO_Address);
- return;
- }
- else if (i < ProbeListIndex &&
- IO_Address == BusLogic_IO_AddressProbeList[i])
- {
- printk("BusLogic: Invalid Command Line Entry "
- "(duplicate I/O Address 0x%X)\n", IO_Address);
- return;
- }
- else if (IO_Address >= 0x1000 ||
- IO_Address == BusLogic_IO_StandardAddresses[i]) break;
- BusLogic_IO_AddressProbeList[ProbeListIndex++] = IO_Address;
- BusLogic_IO_AddressProbeList[ProbeListIndex] = 0;
- }
- CommandLineEntry->IO_Address = IO_Address;
- }
- if (IntegerCount >= 2)
- {
- unsigned short Concurrency = Integers[2];
- if (Concurrency > BusLogic_MailboxCount)
- {
- printk("BusLogic: Invalid Command Line Entry "
- "(illegal Concurrency %d)\n", Concurrency);
- return;
- }
- CommandLineEntry->Concurrency = Concurrency;
- }
- if (IntegerCount >= 3)
- CommandLineEntry->BusSettleTime = Integers[3];
- if (IntegerCount >= 4)
- CommandLineEntry->LocalOptions = Integers[4];
- if (IntegerCount >= 5)
- BusLogic_GlobalOptions |= Integers[5];
- if (!(BusLogic_CommandLineEntryCount == 0 || ProbeListIndex == 0 ||
- BusLogic_CommandLineEntryCount == ProbeListIndex))
- {
- printk("BusLogic: Invalid Command Line Entry "
- "(all or no I/O Addresses must be specified)\n");
- return;
- }
- if (Strings == NULL) return;
- if (strncmp(Strings, "TQ:", 3) == 0)
- {
- Strings += 3;
- if (strncmp(Strings, "Default", 7) == 0)
- Strings += 7;
- else if (strncmp(Strings, "Enable", 6) == 0)
- {
- Strings += 6;
- CommandLineEntry->TaggedQueuingPermitted = 0xFFFF;
- CommandLineEntry->TaggedQueuingPermittedMask = 0xFFFF;
- }
- else if (strncmp(Strings, "Disable", 7) == 0)
- {
- Strings += 7;
- CommandLineEntry->TaggedQueuingPermitted = 0x0000;
- CommandLineEntry->TaggedQueuingPermittedMask = 0xFFFF;
- }
- else
- for (TargetID = 0; TargetID < BusLogic_MaxTargetIDs; TargetID++)
- switch (*Strings++)
- {
- case 'Y':
- CommandLineEntry->TaggedQueuingPermitted |= 1 << TargetID;
- CommandLineEntry->TaggedQueuingPermittedMask |= 1 << TargetID;
- break;
- case 'N':
- CommandLineEntry->TaggedQueuingPermittedMask |= 1 << TargetID;
- break;
- case 'X':
- break;
- default:
- Strings--;
- TargetID = BusLogic_MaxTargetIDs;
- break;
- }
- }
- if (*Strings == ',') Strings++;
- if (strncmp(Strings, "ER:", 3) == 0)
- {
- Strings += 3;
- if (strncmp(Strings, "Default", 7) == 0)
- Strings += 7;
- else if (strncmp(Strings, "HardReset", 9) == 0)
- {
- Strings += 9;
- memset(CommandLineEntry->ErrorRecoveryOption,
- BusLogic_ErrorRecoveryHardReset,
- sizeof(CommandLineEntry->ErrorRecoveryOption));
- }
- else if (strncmp(Strings, "BusDeviceReset", 14) == 0)
- {
- Strings += 14;
- memset(CommandLineEntry->ErrorRecoveryOption,
- BusLogic_ErrorRecoveryBusDeviceReset,
- sizeof(CommandLineEntry->ErrorRecoveryOption));
- }
- else if (strncmp(Strings, "None", 4) == 0)
- {
- Strings += 4;
- memset(CommandLineEntry->ErrorRecoveryOption,
- BusLogic_ErrorRecoveryNone,
- sizeof(CommandLineEntry->ErrorRecoveryOption));
- }
- else
- for (TargetID = 0; TargetID < BusLogic_MaxTargetIDs; TargetID++)
- switch (*Strings++)
- {
- case 'D':
- CommandLineEntry->ErrorRecoveryOption[TargetID] =
- BusLogic_ErrorRecoveryDefault;
- break;
- case 'H':
- CommandLineEntry->ErrorRecoveryOption[TargetID] =
- BusLogic_ErrorRecoveryHardReset;
- break;
- case 'B':
- CommandLineEntry->ErrorRecoveryOption[TargetID] =
- BusLogic_ErrorRecoveryBusDeviceReset;
- break;
- case 'N':
- CommandLineEntry->ErrorRecoveryOption[TargetID] =
- BusLogic_ErrorRecoveryNone;
- break;
- default:
- Strings--;
- TargetID = BusLogic_MaxTargetIDs;
- break;
- }
- }
- if (*Strings != '\0')
- printk("BusLogic: Unexpected Command Line String '%s' ignored\n", Strings);
-}
-
-
-/*
- Include Module support if requested.
-*/
-
-
-#ifdef MODULE
-
-SCSI_Host_Template_T driver_template = BUSLOGIC;
-
-#include "scsi_module.c"
-
-#endif
diff --git a/i386/i386at/gpl/linux/scsi/BusLogic.h b/i386/i386at/gpl/linux/scsi/BusLogic.h
deleted file mode 100644
index 69048e9f..00000000
--- a/i386/i386at/gpl/linux/scsi/BusLogic.h
+++ /dev/null
@@ -1,977 +0,0 @@
-/*
-
- Linux Driver for BusLogic MultiMaster SCSI Host Adapters
-
- Copyright 1995 by Leonard N. Zubkoff <lnz@dandelion.com>
-
- See BusLogic.c for licensing information.
-
-*/
-
-
-/*
- Define types for some of the structures that interface with the rest
- of the Linux Kernel and SCSI Subsystem.
-*/
-
-typedef struct pt_regs Registers_T;
-typedef Scsi_Host_Template SCSI_Host_Template_T;
-typedef struct Scsi_Host SCSI_Host_T;
-typedef struct scsi_disk SCSI_Disk_T;
-typedef struct scsi_cmnd SCSI_Command_T;
-typedef struct scatterlist SCSI_ScatterList_T;
-typedef kdev_t KernelDevice_T;
-
-
-/*
- Define prototypes for the BusLogic Driver Interface Functions.
-*/
-
-const char *BusLogic_DriverInfo(SCSI_Host_T *);
-int BusLogic_DetectHostAdapter(SCSI_Host_Template_T *);
-int BusLogic_ReleaseHostAdapter(SCSI_Host_T *);
-int BusLogic_QueueCommand(SCSI_Command_T *,
- void (*CompletionRoutine)(SCSI_Command_T *));
-int BusLogic_AbortCommand(SCSI_Command_T *);
-int BusLogic_ResetCommand(SCSI_Command_T *);
-int BusLogic_BIOSDiskParameters(SCSI_Disk_T *, KernelDevice_T, int *);
-
-
-/*
- Define the BusLogic SCSI Host Template structure.
-*/
-
-#define BUSLOGIC \
- { NULL, /* Next */ \
- NULL, /* Usage Count Pointer */ \
- NULL, /* /proc Directory Entry */ \
- NULL, /* /proc Info Function */ \
- "BusLogic", /* Driver Name */ \
- BusLogic_DetectHostAdapter, /* Detect Host Adapter */ \
- BusLogic_ReleaseHostAdapter, /* Release Host Adapter */ \
- BusLogic_DriverInfo, /* Driver Info Function */ \
- NULL, /* Command Function */ \
- BusLogic_QueueCommand, /* Queue Command Function */ \
- BusLogic_AbortCommand, /* Abort Command Function */ \
- BusLogic_ResetCommand, /* Reset Command Function */ \
- NULL, /* Slave Attach Function */ \
- BusLogic_BIOSDiskParameters, /* Disk BIOS Parameters */ \
- 0, /* Can Queue */ \
- 0, /* This ID */ \
- 0, /* Scatter/Gather Table Size */ \
- 0, /* SCSI Commands per LUN */ \
- 0, /* Present */ \
- 1, /* Default Unchecked ISA DMA */ \
- ENABLE_CLUSTERING } /* Enable Clustering */
-
-
-/*
- BusLogic_DriverVersion protects the private portion of this file.
-*/
-
-#ifdef BusLogic_DriverVersion
-
-
-/*
- Define the maximum number of BusLogic Host Adapters that are supported.
-*/
-
-#define BusLogic_MaxHostAdapters 10
-
-
-/*
- Define the maximum number of I/O Addresses that may be probed.
-*/
-
-#define BusLogic_IO_MaxProbeAddresses 16
-
-
-/*
- Define the maximum number of Target IDs supported by this driver.
-*/
-
-#define BusLogic_MaxTargetIDs 16
-
-
-/*
- Define the number of Incoming and Outgoing Mailboxes used by this driver.
- The maximum possible value is 255, since the MailboxCount parameter to the
- Initialize Extended Mailbox command is limited to a single byte.
-*/
-
-#define BusLogic_MailboxCount 64
-
-
-/*
- Define the number of Command Control Blocks (CCBs) to create during
- initialization for each Host Adapter. Additional CCBs will be allocated
- if necessary as commands are queued.
-*/
-
-#define BusLogic_InitialCCBs 32
-
-
-/*
- Define the maximum number of Scatter/Gather Segments used by this driver.
- For maximum performance, it is important that this limit be at least as
- large as the maximum single request generated by the routine make_request.
-*/
-
-#define BusLogic_ScatterGatherLimit 128
-
-
-/*
- Define the default number of Concurrent Commands per Logical Unit to allow
- for Target Devices depending on whether or not ISA bounce buffers are
- required.
-*/
-
-#define BusLogic_Concurrency 7
-#define BusLogic_Concurrency_BB 1
-
-
-/*
- Define the default amount of time in seconds to wait between a Host Adapter
- Hard Reset which initiates a SCSI Bus Reset and issuing any SCSI commands.
- Some SCSI devices get confused if they receive SCSI commands too soon after
- a SCSI Bus Reset.
-*/
-
-#define BusLogic_DefaultBusSettleTime 2
-
-
-/*
- Define the possible Local Options.
-*/
-
-#define BusLogic_InhibitTargetInquiry 1
-
-
-/*
- Define the possible Global Options.
-*/
-
-#define BusLogic_TraceProbe 1
-#define BusLogic_TraceHardReset 2
-#define BusLogic_TraceConfiguration 4
-#define BusLogic_TraceErrors 8
-
-
-/*
- Define the possible Error Recovery Options.
-*/
-
-#define BusLogic_ErrorRecoveryDefault 0
-#define BusLogic_ErrorRecoveryHardReset 1
-#define BusLogic_ErrorRecoveryBusDeviceReset 2
-#define BusLogic_ErrorRecoveryNone 3
-
-static char
- *BusLogic_ErrorRecoveryOptions[] =
- { "Default", "Hard Reset", "Bus Device Reset", "None" },
- *BusLogic_ErrorRecoveryOptions2[] =
- { "D", "H", "B", "N" };
-
-
-/*
- Define a boolean data type.
-*/
-
-#define false 0
-#define true 1
-typedef unsigned char boolean;
-
-
-/*
- Define the BusLogic SCSI Host Adapter I/O Register Offsets.
-*/
-
-#define BusLogic_IO_PortCount 4 /* I/O Registers */
-#define BusLogic_ControlRegister 0 /* WO register */
-#define BusLogic_StatusRegister 0 /* RO register */
-#define BusLogic_CommandParameterRegister 1 /* WO register */
-#define BusLogic_DataInRegister 1 /* RO register */
-#define BusLogic_InterruptRegister 2 /* RO register */
-#define BusLogic_GeometryRegister 3 /* RO, undocumented */
-
-
-/*
- Define the bits in the write-only Control Register.
-*/
-
-#define BusLogic_ReservedCR 0x0F
-#define BusLogic_SCSIBusReset 0x10
-#define BusLogic_InterruptReset 0x20
-#define BusLogic_SoftReset 0x40
-#define BusLogic_HardReset 0x80
-
-
-/*
- Define the bits in the read-only Status Register.
-*/
-
-#define BusLogic_CommandInvalid 0x01
-#define BusLogic_ReservedSR 0x02
-#define BusLogic_DataInRegisterReady 0x04
-#define BusLogic_CommandParameterRegisterBusy 0x08
-#define BusLogic_HostAdapterReady 0x10
-#define BusLogic_InitializationRequired 0x20
-#define BusLogic_DiagnosticFailure 0x40
-#define BusLogic_DiagnosticActive 0x80
-
-
-/*
- Define the bits in the read-only Interrupt Register.
-*/
-
-#define BusLogic_IncomingMailboxLoaded 0x01
-#define BusLogic_OutgoingMailboxAvailable 0x02
-#define BusLogic_CommandComplete 0x04
-#define BusLogic_SCSIResetState 0x08
-#define BusLogic_ReservedIR 0x70
-#define BusLogic_InterruptValid 0x80
-
-
-/*
- Define the bits in the undocumented read-only Geometry Register.
-*/
-
-#define BusLogic_Drive0Geometry 0x03
-#define BusLogic_Drive1Geometry 0x0C
-#define BusLogic_ReservedGR 0x70
-#define BusLogic_ExtendedTranslationEnabled 0x80
-
-
-/*
- Define the BusLogic SCSI Host Adapter Command Register Operation Codes.
-*/
-
-typedef enum
-{
- BusLogic_TestCommandCompleteInterrupt = 0x00, /* documented */
- BusLogic_InitializeMailbox = 0x01, /* documented */
- BusLogic_StartMailboxCommand = 0x02, /* documented */
- BusLogic_StartBIOSCommand = 0x03, /* documented */
- BusLogic_InquireBoardID = 0x04, /* documented */
- BusLogic_EnableOutgoingMailboxAvailableIRQ = 0x05, /* documented */
- BusLogic_SetSCSISelectionTimeout = 0x06, /* documented */
- BusLogic_SetPreemptTimeOnBus = 0x07, /* documented */
- BusLogic_SetTimeOffBus = 0x08, /* ISA Bus only */
- BusLogic_SetBusTransferRate = 0x09, /* ISA Bus only */
- BusLogic_InquireInstalledDevicesID0to7 = 0x0A, /* documented */
- BusLogic_InquireConfiguration = 0x0B, /* documented */
- BusLogic_SetTargetMode = 0x0C, /* now undocumented */
- BusLogic_InquireSetupInformation = 0x0D, /* documented */
- BusLogic_WriteAdapterLocalRAM = 0x1A, /* documented */
- BusLogic_ReadAdapterLocalRAM = 0x1B, /* documented */
- BusLogic_WriteBusMasterChipFIFO = 0x1C, /* documented */
- BusLogic_ReadBusMasterChipFIFO = 0x1D, /* documented */
- BusLogic_EchoCommandData = 0x1F, /* documented */
- BusLogic_HostAdapterDiagnostic = 0x20, /* documented */
- BusLogic_SetAdapterOptions = 0x21, /* documented */
- BusLogic_InquireInstalledDevicesID8to15 = 0x23, /* Wide only */
- BusLogic_InitializeExtendedMailbox = 0x81, /* documented */
- BusLogic_InquireFirmwareVersion3rdDigit = 0x84, /* undocumented */
- BusLogic_InquireFirmwareVersionLetter = 0x85, /* undocumented */
- BusLogic_InquireBoardModelNumber = 0x8B, /* undocumented */
- BusLogic_InquireSynchronousPeriod = 0x8C, /* undocumented */
- BusLogic_InquireExtendedSetupInformation = 0x8D, /* documented */
- BusLogic_EnableStrictRoundRobinMode = 0x8F, /* documented */
- BusLogic_ModifyIOAddress = 0x95, /* PCI only */
- BusLogic_EnableWideModeCCB = 0x96 /* Wide only */
-}
-BusLogic_OperationCode_T;
-
-
-/*
- Define the Inquire Board ID reply structure.
-*/
-
-typedef struct BusLogic_BoardID
-{
- unsigned char BoardType;
- unsigned char CustomFeatures;
- unsigned char FirmwareVersion1stDigit;
- unsigned char FirmwareVersion2ndDigit;
-}
-BusLogic_BoardID_T;
-
-
-/*
- Define the Inquire Installed Devices ID 0 to 7 and Inquire Installed
- Devices ID 8 to 15 reply type. For each Target ID, a byte is returned
- where bit 0 set indicates that Logical Unit 0 exists, bit 1 set indicates
- that Logical Unit 1 exists, and so on.
-*/
-
-typedef unsigned char BusLogic_InstalledDevices8_T[8];
-
-typedef unsigned char BusLogic_InstalledDevices_T[BusLogic_MaxTargetIDs];
-
-
-/*
- Define the Inquire Configuration reply structure.
-*/
-
-typedef struct BusLogic_Configuration
-{
- unsigned char :5; /* Byte 0: DMA Channel */
- boolean DMA_Channel5:1;
- boolean DMA_Channel6:1;
- boolean DMA_Channel7:1;
- boolean IRQ_Channel9:1; /* Byte 1: IRQ Channel */
- boolean IRQ_Channel10:1;
- boolean IRQ_Channel11:1;
- boolean IRQ_Channel12:1;
- unsigned char :1;
- boolean IRQ_Channel14:1;
- boolean IRQ_Channel15:1;
- unsigned char :1;
- unsigned char HostAdapterID:4; /* Byte 2: Host Adapter ID */
- unsigned char :4;
-}
-BusLogic_Configuration_T;
-
-
-/*
- Define the Inquire Setup Information reply structure.
-*/
-
-typedef struct BusLogic_SynchronousValue
-{
- unsigned char Offset:4;
- unsigned char TransferPeriod:3;
- boolean Synchronous:1;
-}
-BusLogic_SynchronousValue_T;
-
-typedef BusLogic_SynchronousValue_T
- BusLogic_SynchronousValues8_T[8];
-
-typedef BusLogic_SynchronousValue_T
- BusLogic_SynchronousValues_T[BusLogic_MaxTargetIDs];
-
-typedef struct BusLogic_SetupInformation
-{
- boolean SynchronousInitiationEnabled:1; /* Byte 0 */
- boolean ParityCheckEnabled:1;
- unsigned char :6;
- unsigned char BusTransferRate; /* Byte 1 */
- unsigned char PreemptTimeOnBus; /* Byte 2 */
- unsigned char TimeOffBus; /* Byte 3 */
- unsigned char MailboxCount; /* Byte 4 */
- unsigned char MailboxAddress[3]; /* Bytes 5-7 */
- BusLogic_SynchronousValues8_T SynchronousValuesID0to7; /* Bytes 8-15 */
- unsigned char DisconnectPermittedID0to7; /* Byte 16 */
- unsigned char Signature; /* Byte 17 */
- unsigned char CharacterD; /* Byte 18 */
- unsigned char BusLetter; /* Byte 19 */
- unsigned char :8; /* Byte 20 */
- unsigned char :8; /* Byte 21 */
- BusLogic_SynchronousValues8_T SynchronousValuesID8to15; /* Bytes 22-29 */
- unsigned char DisconnectPermittedID8to15; /* Byte 30 */
-}
-BusLogic_SetupInformation_T;
-
-
-/*
- Define the Initialize Extended Mailbox request structure.
-*/
-
-typedef struct BusLogic_ExtendedMailboxRequest
-{
- unsigned char MailboxCount;
- void *BaseMailboxAddress __attribute__ ((packed));
-}
-BusLogic_ExtendedMailboxRequest_T;
-
-
-/*
- Define the Inquire Firmware Version 3rd Digit reply type.
-*/
-
-typedef unsigned char BusLogic_FirmwareVersion3rdDigit_T;
-
-
-/*
- Define the Inquire Firmware Version Letter reply type.
-*/
-
-typedef unsigned char BusLogic_FirmwareVersionLetter_T;
-
-
-/*
- Define the Inquire Board Model Number reply type.
-*/
-
-typedef unsigned char BusLogic_BoardModelNumber_T[5];
-
-
-/*
- Define the Inquire Synchronous Period reply type. For each Target ID, a byte
- is returned which represents the Synchronous Transfer Period in units of 10
- nanoseconds.
-*/
-
-typedef unsigned char BusLogic_SynchronousPeriod_T[BusLogic_MaxTargetIDs];
-
-
-/*
- Define the Inquire Extended Setup Information reply structure.
-*/
-
-typedef struct BusLogic_ExtendedSetupInformation
-{
- unsigned char BusType; /* Byte 0 */
- unsigned char BIOS_Address; /* Byte 1 */
- unsigned short ScatterGatherLimit; /* Bytes 2-3 */
- unsigned char MailboxCount; /* Byte 4 */
- void *BaseMailboxAddress __attribute__ ((packed)); /* Bytes 5-8 */
- struct { unsigned char :6; /* Byte 9 */
- boolean LevelSensitiveInterrupts:1;
- unsigned char :1; } Misc;
- unsigned char FirmwareRevision[3]; /* Bytes 10-12 */
- boolean HostWideSCSI:1; /* Byte 13 Bit 0 */
- boolean HostDifferentialSCSI:1; /* Byte 13 Bit 1 */
- unsigned char :6;
-}
-BusLogic_ExtendedSetupInformation_T;
-
-
-/*
- Define the Enable Strict Round Robin Mode request type.
-*/
-
-#define BusLogic_AggressiveRoundRobinMode 0x00
-#define BusLogic_StrictRoundRobinMode 0x01
-
-typedef unsigned char BusLogic_RoundRobinModeRequest_T;
-
-
-/*
- Define the Modify I/O Address request type. On PCI Host Adapters, the
- Modify I/O Address command allows modification of the ISA compatible I/O
- Address that the Host Adapter responds to; it does not affect the PCI
- compliant I/O Address assigned at system initialization.
-*/
-
-#define BusLogic_ModifyIO_330 0x00
-#define BusLogic_ModifyIO_334 0x01
-#define BusLogic_ModifyIO_230 0x02
-#define BusLogic_ModifyIO_234 0x03
-#define BusLogic_ModifyIO_130 0x04
-#define BusLogic_ModifyIO_134 0x05
-#define BusLogic_ModifyIO_Disable 0x06
-#define BusLogic_ModifyIO_Disable2 0x07
-
-typedef unsigned char BusLogic_ModifyIOAddressRequest_T;
-
-
-/*
- Define the Enable Wide Mode SCSI CCB request type. Wide Mode CCBs are
- necessary to support more than 8 Logical Units per Target.
-*/
-
-#define BusLogic_NormalModeCCB 0x00
-#define BusLogic_WideModeCCB 0x01
-
-typedef unsigned char BusLogic_WideModeCCBRequest_T;
-
-
-/*
- Define the Requested Reply Length type used by the Inquire Setup Information,
- Inquire Board Model Number, Inquire Synchronous Period, and Inquire Extended
- Setup Information commands.
-*/
-
-typedef unsigned char BusLogic_RequestedReplyLength_T;
-
-
-/*
- Define a Lock data structure. Until a true symmetric multiprocessing kernel
- is available, locking is implemented as saving the processor flags and
- disabling interrupts, and unlocking restores the saved processor flags.
-*/
-
-typedef unsigned long BusLogic_Lock_T;
-
-
-/*
- Define the Outgoing Mailbox Action Codes.
-*/
-
-typedef enum
-{
- BusLogic_OutgoingMailboxFree = 0,
- BusLogic_MailboxStartCommand = 1,
- BusLogic_MailboxAbortCommand = 2
-}
-BusLogic_ActionCode_T;
-
-
-/*
- Define the Incoming Mailbox Completion Codes.
-*/
-
-typedef enum
-{
- BusLogic_IncomingMailboxFree = 0,
- BusLogic_CommandCompletedWithoutError = 1,
- BusLogic_CommandAbortedAtHostRequest = 2,
- BusLogic_AbortedCommandNotFound = 3,
- BusLogic_CommandCompletedWithError = 4
-}
-BusLogic_CompletionCode_T;
-
-
-/*
- Define the Command Control Block (CCB) Opcodes.
-*/
-
-typedef enum
-{
- BusLogic_InitiatorCCB = 0x00,
- BusLogic_TargetCCB = 0x01,
- BusLogic_InitiatorCCB_ScatterGather = 0x02,
- BusLogic_InitiatorCCB_ResidualDataLength = 0x03,
- BusLogic_InitiatorCCB_ScatterGatherResidual = 0x04,
- BusLogic_SCSIBusDeviceReset = 0x81
-}
-BusLogic_CCB_Opcode_T;
-
-
-/*
- Define the CCB Data Direction Codes.
-*/
-
-typedef enum
-{
- BusLogic_UncheckedDataTransfer = 0x00,
- BusLogic_DataInLengthChecked = 0x01,
- BusLogic_DataOutLengthChecked = 0x02,
- BusLogic_NoDataTransfer = 0x03
-}
-BusLogic_DataDirection_T;
-
-
-/*
- Define the Host Adapter Status Codes.
-*/
-
-typedef enum
-{
- BusLogic_CommandCompletedNormally = 0x00,
- BusLogic_LinkedCommandCompleted = 0x0A,
- BusLogic_LinkedCommandCompletedWithFlag = 0x0B,
- BusLogic_SCSISelectionTimeout = 0x11,
- BusLogic_DataOverUnderRun = 0x12,
- BusLogic_UnexpectedBusFree = 0x13,
- BusLogic_InvalidBusPhaseRequested = 0x14,
- BusLogic_InvalidOutgoingMailboxActionCode = 0x15,
- BusLogic_InvalidCommandOperationCode = 0x16,
- BusLogic_LinkedCCBhasInvalidLUN = 0x17,
- BusLogic_InvalidCommandParameter = 0x1A,
- BusLogic_AutoRequestSenseFailed = 0x1B,
- BusLogic_TaggedQueuingMessageRejected = 0x1C,
- BusLogic_UnsupportedMessageReceived = 0x1D,
- BusLogic_HostAdapterHardwareFailed = 0x20,
- BusLogic_TargetFailedResponseToATN = 0x21,
- BusLogic_HostAdapterAssertedRST = 0x22,
- BusLogic_OtherDeviceAssertedRST = 0x23,
- BusLogic_TargetDeviceReconnectedImproperly = 0x24,
- BusLogic_HostAdapterAssertedBusDeviceReset = 0x25,
- BusLogic_AbortQueueGenerated = 0x26,
- BusLogic_HostAdapterSoftwareError = 0x27,
- BusLogic_HostAdapterHardwareTimeoutError = 0x30,
- BusLogic_SCSIParityErrorDetected = 0x34
-}
-BusLogic_HostAdapterStatus_T;
-
-
-/*
- Define the SCSI Target Device Status Codes.
-*/
-
-typedef enum
-{
- BusLogic_OperationGood = 0x00,
- BusLogic_CheckCondition = 0x02,
- BusLogic_DeviceBusy = 0x08
-}
-BusLogic_TargetDeviceStatus_T;
-
-
-/*
- Define the Queue Tag Codes.
-*/
-
-typedef enum
-{
- BusLogic_SimpleQueueTag = 0x00,
- BusLogic_HeadOfQueueTag = 0x01,
- BusLogic_OrderedQueueTag = 0x02,
- BusLogic_ReservedQT = 0x03
-}
-BusLogic_QueueTag_T;
-
-
-/*
- Define the SCSI Command Descriptor Block (CDB).
-*/
-
-#define BusLogic_CDB_MaxLength 12
-
-typedef unsigned char SCSI_CDB_T[BusLogic_CDB_MaxLength];
-
-
-/*
- Define the SCSI Sense Data.
-*/
-
-#define BusLogic_SenseDataMaxLength 255
-
-typedef unsigned char SCSI_SenseData_T[BusLogic_SenseDataMaxLength];
-
-
-/*
- Define the Scatter/Gather Segment structure required by the Host Adapter
- Firmware Interface.
-*/
-
-typedef struct BusLogic_ScatterGatherSegment
-{
- unsigned long SegmentByteCount;
- void *SegmentDataPointer;
-}
-BusLogic_ScatterGatherSegment_T;
-
-
-/*
- Define the 32 Bit Mode Command Control Block (CCB) structure. The first 40
- bytes are defined by the Host Adapter Firmware Interface. The remaining
- components are defined by the Linux BusLogic Driver. Wide Mode CCBs differ
- from standard 32 Bit Mode CCBs only in having the TagEnable and QueueTag
- fields moved from byte 17 to byte 1, and the Logical Unit field in byte 17
- expanded to 6 bits; unfortunately, using a union of structs containing
- enumeration type bitfields to provide both definitions leads to packing
- problems, so the following definition is used which requires setting
- TagEnable to Logical Unit bit 5 in Wide Mode CCBs.
-*/
-
-typedef struct BusLogic_CCB
-{
- /*
- BusLogic Host Adapter Firmware Portion.
- */
- BusLogic_CCB_Opcode_T Opcode:8; /* Byte 0 */
- unsigned char :3; /* Byte 1 Bits 0-2 */
- BusLogic_DataDirection_T DataDirection:2; /* Byte 1 Bits 3-4 */
- boolean WideModeTagEnable:1; /* Byte 1 Bit 5 */
- BusLogic_QueueTag_T WideModeQueueTag:2; /* Byte 1 Bits 6-7 */
- unsigned char CDB_Length; /* Byte 2 */
- unsigned char SenseDataLength; /* Byte 3 */
- unsigned long DataLength; /* Bytes 4-7 */
- void *DataPointer; /* Bytes 8-11 */
- unsigned char :8; /* Byte 12 */
- unsigned char :8; /* Byte 13 */
- BusLogic_HostAdapterStatus_T HostAdapterStatus:8; /* Byte 14 */
- BusLogic_TargetDeviceStatus_T TargetDeviceStatus:8; /* Byte 15 */
- unsigned char TargetID; /* Byte 16 */
- unsigned char LogicalUnit:5; /* Byte 17 Bits 0-4 */
- boolean TagEnable:1; /* Byte 17 Bit 5 */
- BusLogic_QueueTag_T QueueTag:2; /* Byte 17 Bits 6-7 */
- SCSI_CDB_T CDB; /* Bytes 18-29 */
- unsigned char :8; /* Byte 30 */
- unsigned char :8; /* Byte 31 */
- unsigned long :32; /* Bytes 32-35 */
- SCSI_SenseData_T *SenseDataPointer; /* Bytes 36-39 */
- /*
- BusLogic Linux Driver Portion.
- */
- struct BusLogic_HostAdapter *HostAdapter;
- SCSI_Command_T *Command;
- enum { BusLogic_CCB_Free = 0,
- BusLogic_CCB_Active = 1,
- BusLogic_CCB_Completed = 2,
- BusLogic_CCB_Reset = 3 } Status;
- BusLogic_CompletionCode_T MailboxCompletionCode;
- unsigned int SerialNumber;
- struct BusLogic_CCB *Next;
- struct BusLogic_CCB *NextAll;
- BusLogic_ScatterGatherSegment_T
- ScatterGatherList[BusLogic_ScatterGatherLimit];
-}
-BusLogic_CCB_T;
-
-
-/*
- Define the 32 Bit Mode Outgoing Mailbox structure.
-*/
-
-typedef struct BusLogic_OutgoingMailbox
-{
- BusLogic_CCB_T *CCB;
- unsigned long :24;
- BusLogic_ActionCode_T ActionCode:8;
-}
-BusLogic_OutgoingMailbox_T;
-
-
-/*
- Define the 32 Bit Mode Incoming Mailbox structure.
-*/
-
-typedef struct BusLogic_IncomingMailbox
-{
- BusLogic_CCB_T *CCB;
- BusLogic_HostAdapterStatus_T HostAdapterStatus:8;
- BusLogic_TargetDeviceStatus_T TargetDeviceStatus:8;
- unsigned char :8;
- BusLogic_CompletionCode_T CompletionCode:8;
-}
-BusLogic_IncomingMailbox_T;
-
-
-/*
- Define the possible Bus Types.
-*/
-
-typedef enum
-{
- BusLogic_Unknown_Bus = 0,
- BusLogic_ISA_Bus = 1,
- BusLogic_MCA_Bus = 2,
- BusLogic_EISA_Bus = 3,
- BusLogic_VESA_Bus = 4,
- BusLogic_PCI_Bus = 5
-}
-BusLogic_BusType_T;
-
-static char
- *BusLogic_BusNames[] =
- { "Unknown", "ISA", "MCA", "EISA", "VESA", "PCI" };
-
-
-/*
- Define the Linux BusLogic Driver Command Line Entry structure.
-*/
-
-typedef struct BusLogic_CommandLineEntry
-{
- unsigned short IO_Address;
- unsigned short Concurrency;
- unsigned short BusSettleTime;
- unsigned short LocalOptions;
- unsigned short TaggedQueuingPermitted;
- unsigned short TaggedQueuingPermittedMask;
- unsigned char ErrorRecoveryOption[BusLogic_MaxTargetIDs];
-}
-BusLogic_CommandLineEntry_T;
-
-
-/*
- Define the Linux BusLogic Driver Host Adapter structure.
-*/
-
-typedef struct BusLogic_HostAdapter
-{
- SCSI_Host_T *SCSI_Host;
- unsigned char HostNumber;
- unsigned char ModelName[9];
- unsigned char FirmwareVersion[6];
- unsigned char BoardName[18];
- unsigned char InterruptLabel[62];
- unsigned short IO_Address;
- unsigned char IRQ_Channel;
- unsigned char DMA_Channel;
- unsigned char SCSI_ID;
- BusLogic_BusType_T BusType:3;
- boolean IRQ_ChannelAcquired:1;
- boolean DMA_ChannelAcquired:1;
- boolean SynchronousInitiation:1;
- boolean ParityChecking:1;
- boolean ExtendedTranslation:1;
- boolean LevelSensitiveInterrupts:1;
- boolean HostWideSCSI:1;
- boolean HostDifferentialSCSI:1;
- boolean HostAdapterResetPending:1;
- boolean BounceBuffersRequired:1;
- volatile boolean HostAdapterCommandCompleted:1;
- unsigned short HostAdapterScatterGatherLimit;
- unsigned short DriverScatterGatherLimit;
- unsigned short MaxTargetIDs;
- unsigned short MaxLogicalUnits;
- unsigned short Concurrency;
- unsigned short BusSettleTime;
- unsigned short LocalOptions;
- unsigned short DisconnectPermitted;
- unsigned short TaggedQueuingPermitted;
- unsigned long BIOS_Address;
- BusLogic_InstalledDevices_T InstalledDevices;
- BusLogic_SynchronousValues_T SynchronousValues;
- BusLogic_SynchronousPeriod_T SynchronousPeriod;
- BusLogic_Lock_T Lock;
- struct BusLogic_HostAdapter *Next;
- BusLogic_CommandLineEntry_T *CommandLineEntry;
- BusLogic_CCB_T *All_CCBs;
- BusLogic_CCB_T *Free_CCBs;
- unsigned char ErrorRecoveryOption[BusLogic_MaxTargetIDs];
- unsigned char CommandSuccessfulFlag[BusLogic_MaxTargetIDs];
- unsigned long ReadWriteOperationCount[BusLogic_MaxTargetIDs];
- unsigned char QueuedOperationCount[BusLogic_MaxTargetIDs];
- unsigned long LastSequencePoint[BusLogic_MaxTargetIDs];
- BusLogic_OutgoingMailbox_T *FirstOutgoingMailbox;
- BusLogic_OutgoingMailbox_T *LastOutgoingMailbox;
- BusLogic_OutgoingMailbox_T *NextOutgoingMailbox;
- BusLogic_IncomingMailbox_T *FirstIncomingMailbox;
- BusLogic_IncomingMailbox_T *LastIncomingMailbox;
- BusLogic_IncomingMailbox_T *NextIncomingMailbox;
- BusLogic_OutgoingMailbox_T OutgoingMailboxes[BusLogic_MailboxCount];
- BusLogic_IncomingMailbox_T IncomingMailboxes[BusLogic_MailboxCount];
-}
-BusLogic_HostAdapter_T;
-
-
-/*
- Define a symbolic structure for the BIOS Disk Parameters.
-*/
-
-typedef struct BIOS_DiskParameters
-{
- int Heads;
- int Sectors;
- int Cylinders;
-}
-BIOS_DiskParameters_T;
-
-
-/*
- BusLogic_LockHostAdapter acquires exclusive access to Host Adapter.
-*/
-
-static inline
-void BusLogic_LockHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
-{
- save_flags(HostAdapter->Lock);
- cli();
-}
-
-
-/*
- BusLogic_UnlockHostAdapter releases exclusive access to Host Adapter.
-*/
-
-static inline
-void BusLogic_UnlockHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
-{
- restore_flags(HostAdapter->Lock);
-}
-
-
-/*
- BusLogic_LockHostAdapterID acquires exclusive access to Host Adapter,
- but is only called when interrupts are disabled.
-*/
-
-static inline
-void BusLogic_LockHostAdapterID(BusLogic_HostAdapter_T *HostAdapter)
-{
-}
-
-
-/*
- BusLogic_UnlockHostAdapterID releases exclusive access to Host Adapter,
- but is only called when interrupts are disabled.
-*/
-
-static inline
-void BusLogic_UnlockHostAdapterID(BusLogic_HostAdapter_T *HostAdapter)
-{
-}
-
-
-/*
- Define functions to provide an abstraction for reading and writing the
- Host Adapter I/O Registers.
-*/
-
-static inline
-void BusLogic_WriteControlRegister(BusLogic_HostAdapter_T *HostAdapter,
- unsigned char Value)
-{
- outb(Value, HostAdapter->IO_Address + BusLogic_ControlRegister);
-}
-
-static inline
-unsigned char BusLogic_ReadStatusRegister(BusLogic_HostAdapter_T *HostAdapter)
-{
- return inb(HostAdapter->IO_Address + BusLogic_StatusRegister);
-}
-
-static inline
-void BusLogic_WriteCommandParameterRegister(BusLogic_HostAdapter_T *HostAdapter,
- unsigned char Value)
-{
- outb(Value, HostAdapter->IO_Address + BusLogic_CommandParameterRegister);
-}
-
-static inline
-unsigned char BusLogic_ReadDataInRegister(BusLogic_HostAdapter_T *HostAdapter)
-{
- return inb(HostAdapter->IO_Address + BusLogic_DataInRegister);
-}
-
-static inline
-unsigned char BusLogic_ReadInterruptRegister(BusLogic_HostAdapter_T
- *HostAdapter)
-{
- return inb(HostAdapter->IO_Address + BusLogic_InterruptRegister);
-}
-
-static inline
-unsigned char BusLogic_ReadGeometryRegister(BusLogic_HostAdapter_T *HostAdapter)
-{
- return inb(HostAdapter->IO_Address + BusLogic_GeometryRegister);
-}
-
-
-/*
- BusLogic_StartMailboxScan issues a Start Mailbox Scan command, which
- notifies the Host Adapter that an entry has been made in an Outgoing
- Mailbox.
-*/
-
-static inline
-void BusLogic_StartMailboxScan(BusLogic_HostAdapter_T *HostAdapter)
-{
- BusLogic_WriteCommandParameterRegister(HostAdapter,
- BusLogic_StartMailboxCommand);
-}
-
-
-/*
- BusLogic_Delay waits for Seconds to elapse.
-*/
-
-static inline void BusLogic_Delay(int Seconds)
-{
- unsigned long TimeoutJiffies = jiffies + Seconds * HZ;
- unsigned long ProcessorFlags;
- save_flags(ProcessorFlags);
- sti();
- while (jiffies < TimeoutJiffies) ;
- restore_flags(ProcessorFlags);
-}
-
-
-/*
- Define prototypes for the forward referenced BusLogic Driver
- Internal Functions.
-*/
-
-static void BusLogic_InterruptHandler(int, Registers_T *);
-static int BusLogic_ResetHostAdapter(BusLogic_HostAdapter_T *,
- SCSI_Command_T *);
-
-
-#endif /* BusLogic_DriverVersion */
diff --git a/i386/i386at/gpl/linux/scsi/NCR5380.h b/i386/i386at/gpl/linux/scsi/NCR5380.h
deleted file mode 100644
index 3a121810..00000000
--- a/i386/i386at/gpl/linux/scsi/NCR5380.h
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * NCR 5380 defines
- *
- * Copyright 1993, Drew Eckhardt
- * Visionary Computing
- * (Unix consulting and custom programming)
- * drew@colorado.edu
- * +1 (303) 666-5836
- *
- * DISTRIBUTION RELEASE 6
- *
- * For more information, please consult
- *
- * NCR 5380 Family
- * SCSI Protocol Controller
- * Databook
- * NCR Microelectronics
- * 1635 Aeroplaza Drive
- * Colorado Springs, CO 80916
- * 1+ (719) 578-3400
- * 1+ (800) 334-5454
- */
-
-/*
- * $Log: NCR5380.h,v $
- * Revision 1.1.1.1 1996/10/30 01:39:59 thomas
- * Imported from UK22
- *
- * Revision 1.1 1996/03/25 20:25:09 goel
- * Linux driver merge.
- *
- */
-
-#ifndef NCR5380_H
-#define NCR5380_H
-
-#define NCR5380_PUBLIC_RELEASE 6
-#define NCR53C400_PUBLIC_RELEASE 2
-
-#define NDEBUG_ARBITRATION 0x1
-#define NDEBUG_AUTOSENSE 0x2
-#define NDEBUG_DMA 0x4
-#define NDEBUG_HANDSHAKE 0x8
-#define NDEBUG_INFORMATION 0x10
-#define NDEBUG_INIT 0x20
-#define NDEBUG_INTR 0x40
-#define NDEBUG_LINKED 0x80
-#define NDEBUG_MAIN 0x100
-#define NDEBUG_NO_DATAOUT 0x200
-#define NDEBUG_NO_WRITE 0x400
-#define NDEBUG_PIO 0x800
-#define NDEBUG_PSEUDO_DMA 0x1000
-#define NDEBUG_QUEUES 0x2000
-#define NDEBUG_RESELECTION 0x4000
-#define NDEBUG_SELECTION 0x8000
-#define NDEBUG_USLEEP 0x10000
-#define NDEBUG_LAST_BYTE_SENT 0x20000
-#define NDEBUG_RESTART_SELECT 0x40000
-#define NDEBUG_EXTENDED 0x80000
-#define NDEBUG_C400_PREAD 0x100000
-#define NDEBUG_C400_PWRITE 0x200000
-#define NDEBUG_LISTS 0x400000
-
-/*
- * The contents of the OUTPUT DATA register are asserted on the bus when
- * either arbitration is occurring or the phase-indicating signals (
- * IO, CD, MSG) in the TARGET COMMAND register and the ASSERT DATA
- * bit in the INITIATOR COMMAND register is set.
- */
-
-#define OUTPUT_DATA_REG 0 /* wo DATA lines on SCSI bus */
-#define CURRENT_SCSI_DATA_REG 0 /* ro same */
-
-#define INITIATOR_COMMAND_REG 1 /* rw */
-#define ICR_ASSERT_RST 0x80 /* rw Set to assert RST */
-#define ICR_ARBITRATION_PROGRESS 0x40 /* ro Indicates arbitration complete */
-#define ICR_TRI_STATE 0x40 /* wo Set to tri-state drivers */
-#define ICR_ARBITRATION_LOST 0x20 /* ro Indicates arbitration lost */
-#define ICR_DIFF_ENABLE 0x20 /* wo Set to enable diff. drivers */
-#define ICR_ASSERT_ACK 0x10 /* rw ini Set to assert ACK */
-#define ICR_ASSERT_BSY 0x08 /* rw Set to assert BSY */
-#define ICR_ASSERT_SEL 0x04 /* rw Set to assert SEL */
-#define ICR_ASSERT_ATN 0x02 /* rw Set to assert ATN */
-#define ICR_ASSERT_DATA 0x01 /* rw SCSI_DATA_REG is asserted */
-
-#ifdef DIFFERENTIAL
-#define ICR_BASE ICR_DIFF_ENABLE
-#else
-#define ICR_BASE 0
-#endif
-
-#define MODE_REG 2
-/*
- * Note : BLOCK_DMA code will keep DRQ asserted for the duration of the
- * transfer, causing the chip to hog the bus. You probably don't want
- * this.
- */
-#define MR_BLOCK_DMA_MODE 0x80 /* rw block mode DMA */
-#define MR_TARGET 0x40 /* rw target mode */
-#define MR_ENABLE_PAR_CHECK 0x20 /* rw enable parity checking */
-#define MR_ENABLE_PAR_INTR 0x10 /* rw enable bad parity interrupt */
-#define MR_ENABLE_EOP_INTR 0x08 /* rw enable eop interrupt */
-#define MR_MONITOR_BSY 0x04 /* rw enable int on unexpected bsy fail */
-#define MR_DMA_MODE 0x02 /* rw DMA / pseudo DMA mode */
-#define MR_ARBITRATE 0x01 /* rw start arbitration */
-
-#ifdef PARITY
-#define MR_BASE MR_ENABLE_PAR_CHECK
-#else
-#define MR_BASE 0
-#endif
-
-#define TARGET_COMMAND_REG 3
-#define TCR_LAST_BYTE_SENT 0x80 /* ro DMA done */
-#define TCR_ASSERT_REQ 0x08 /* tgt rw assert REQ */
-#define TCR_ASSERT_MSG 0x04 /* tgt rw assert MSG */
-#define TCR_ASSERT_CD 0x02 /* tgt rw assert CD */
-#define TCR_ASSERT_IO 0x01 /* tgt rw assert IO */
-
-#define STATUS_REG 4 /* ro */
-/*
- * Note : a set bit indicates an active signal, driven by us or another
- * device.
- */
-#define SR_RST 0x80
-#define SR_BSY 0x40
-#define SR_REQ 0x20
-#define SR_MSG 0x10
-#define SR_CD 0x08
-#define SR_IO 0x04
-#define SR_SEL 0x02
-#define SR_DBP 0x01
-
-/*
- * Setting a bit in this register will cause an interrupt to be generated when
- * BSY is false and SEL true and this bit is asserted on the bus.
- */
-#define SELECT_ENABLE_REG 4 /* wo */
-
-#define BUS_AND_STATUS_REG 5 /* ro */
-#define BASR_END_DMA_TRANSFER 0x80 /* ro set on end of transfer */
-#define BASR_DRQ 0x40 /* ro mirror of DRQ pin */
-#define BASR_PARITY_ERROR 0x20 /* ro parity error detected */
-#define BASR_IRQ 0x10 /* ro mirror of IRQ pin */
-#define BASR_PHASE_MATCH 0x08 /* ro Set when MSG CD IO match TCR */
-#define BASR_BUSY_ERROR 0x04 /* ro Unexpected change to inactive state */
-#define BASR_ATN 0x02 /* ro BUS status */
-#define BASR_ACK 0x01 /* ro BUS status */
-
-/* Write any value to this register to start a DMA send */
-#define START_DMA_SEND_REG 5 /* wo */
-
-/*
- * Used in DMA transfer mode, data is latched from the SCSI bus on
- * the falling edge of REQ (ini) or ACK (tgt)
- */
-#define INPUT_DATA_REG 6 /* ro */
-
-/* Write any value to this register to start a DMA receive */
-#define START_DMA_TARGET_RECEIVE_REG 6 /* wo */
-
-/* Read this register to clear interrupt conditions */
-#define RESET_PARITY_INTERRUPT_REG 7 /* ro */
-
-/* Write any value to this register to start an ini mode DMA receive */
-#define START_DMA_INITIATOR_RECEIVE_REG 7 /* wo */
-
-#define C400_CONTROL_STATUS_REG NCR53C400_register_offset-8 /* rw */
-
-#define CSR_RESET 0x80 /* wo Resets 53c400 */
-#define CSR_53C80_REG 0x80 /* ro 5380 registers busy */
-#define CSR_TRANS_DIR 0x40 /* rw Data transfer direction */
-#define CSR_SCSI_BUFF_INTR 0x20 /* rw Enable int on transfer ready */
-#define CSR_53C80_INTR 0x10 /* rw Enable 53c80 interrupts */
-#define CSR_SHARED_INTR 0x08 /* rw Interrupt sharing */
-#define CSR_HOST_BUF_NOT_RDY 0x04 /* ro Is Host buffer ready */
-#define CSR_SCSI_BUF_RDY 0x02 /* ro SCSI buffer read */
-#define CSR_GATED_53C80_IRQ 0x01 /* ro Last block xferred */
-
-#if 0
-#define CSR_BASE CSR_SCSI_BUFF_INTR | CSR_53C80_INTR
-#else
-#define CSR_BASE CSR_53C80_INTR
-#endif
-
-/* Number of 128-byte blocks to be transferred */
-#define C400_BLOCK_COUNTER_REG NCR53C400_register_offset-7 /* rw */
-
-/* Resume transfer after disconnect */
-#define C400_RESUME_TRANSFER_REG NCR53C400_register_offset-6 /* wo */
-
-/* Access to host buffer stack */
-#define C400_HOST_BUFFER NCR53C400_register_offset-4 /* rw */
-
-
-/* Note : PHASE_* macros are based on the values of the STATUS register */
-#define PHASE_MASK (SR_MSG | SR_CD | SR_IO)
-
-#define PHASE_DATAOUT 0
-#define PHASE_DATAIN SR_IO
-#define PHASE_CMDOUT SR_CD
-#define PHASE_STATIN (SR_CD | SR_IO)
-#define PHASE_MSGOUT (SR_MSG | SR_CD)
-#define PHASE_MSGIN (SR_MSG | SR_CD | SR_IO)
-#define PHASE_UNKNOWN 0xff
-
-/*
- * Convert status register phase to something we can use to set phase in
- * the target register so we can get phase mismatch interrupts on DMA
- * transfers.
- */
-
-#define PHASE_SR_TO_TCR(phase) ((phase) >> 2)
-
-/*
- * The internal should_disconnect() function returns these based on the
- * expected length of a disconnect if a device supports disconnect/
- * reconnect.
- */
-
-#define DISCONNECT_NONE 0
-#define DISCONNECT_TIME_TO_DATA 1
-#define DISCONNECT_LONG 2
-
-/*
- * These are "special" values for the tag parameter passed to NCR5380_select.
- */
-
-#define TAG_NEXT -1 /* Use next free tag */
-#define TAG_NONE -2 /*
- * Establish I_T_L nexus instead of I_T_L_Q
- * even on SCSI-II devices.
- */
-
-/*
- * These are "special" values for the irq and dma_channel fields of the
- * Scsi_Host structure
- */
-
-#define IRQ_NONE 255
-#define DMA_NONE 255
-#define IRQ_AUTO 254
-#define DMA_AUTO 254
-
-#define FLAG_HAS_LAST_BYTE_SENT 1 /* NCR53c81 or better */
-#define FLAG_CHECK_LAST_BYTE_SENT 2 /* Only test once */
-#define FLAG_NCR53C400 4 /* NCR53c400 */
-#define FLAG_NO_PSEUDO_DMA 8 /* Inhibit DMA */
-
-#ifndef ASM
-struct NCR5380_hostdata {
- NCR5380_implementation_fields; /* implementation specific */
- unsigned char id_mask, id_higher_mask; /* 1 << id, all bits greater */
- unsigned char targets_present; /* targets we have connected
- to, so we can call a select
- failure a retryable condition */
- volatile unsigned char busy[8]; /* index = target, bit = lun */
-#if defined(REAL_DMA) || defined(REAL_DMA_POLL)
- volatile int dma_len; /* requested length of DMA */
-#endif
- volatile unsigned char last_message; /* last message OUT */
- volatile Scsi_Cmnd *connected; /* currently connected command */
- volatile Scsi_Cmnd *issue_queue; /* waiting to be issued */
- volatile Scsi_Cmnd *disconnected_queue; /* waiting for reconnect */
- volatile int restart_select; /* we have disconnected,
- used to restart
- NCR5380_select() */
- volatile unsigned aborted:1; /* flag, says aborted */
- int flags;
-#ifdef USLEEP
- unsigned long time_expires; /* in jiffies, set prior to sleeping */
- struct Scsi_Host *next_timer;
-#endif
-};
-
-#ifdef __KERNEL__
-static struct Scsi_Host *first_instance; /* linked list of 5380's */
-
-#if defined(AUTOPROBE_IRQ)
-static int NCR5380_probe_irq (struct Scsi_Host *instance, int possible);
-#endif
-static void NCR5380_init (struct Scsi_Host *instance, int flags);
-static void NCR5380_information_transfer (struct Scsi_Host *instance);
-static void NCR5380_intr (int irq, struct pt_regs * regs);
-static void NCR5380_main (void);
-static void NCR5380_print_options (struct Scsi_Host *instance);
-static void NCR5380_print_phase (struct Scsi_Host *instance);
-static void NCR5380_print (struct Scsi_Host *instance);
-#ifndef NCR5380_abort
-static
-#endif
-int NCR5380_abort (Scsi_Cmnd *cmd);
-#ifndef NCR5380_reset
-static
-#endif
-int NCR5380_reset (Scsi_Cmnd *cmd);
-#ifndef NCR5380_queue_command
-static
-#endif
-int NCR5380_queue_command (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *));
-
-
-static void NCR5380_reselect (struct Scsi_Host *instance);
-static int NCR5380_select (struct Scsi_Host *instance, Scsi_Cmnd *cmd, int tag);
-#if defined(PSEUDO_DMA) || defined(REAL_DMA) || defined(REAL_DMA_POLL)
-static int NCR5380_transfer_dma (struct Scsi_Host *instance,
- unsigned char *phase, int *count, unsigned char **data);
-#endif
-static int NCR5380_transfer_pio (struct Scsi_Host *instance,
- unsigned char *phase, int *count, unsigned char **data);
-
-#if (defined(REAL_DMA) || defined(REAL_DMA_POLL)) && defined(i386)
-static __inline__ int NCR5380_i386_dma_setup (struct Scsi_Host *instance,
- unsigned char *ptr, unsigned int count, unsigned char mode) {
- unsigned limit;
-
- if (instance->dma_channel <=3) {
- if (count > 65536)
- count = 65536;
- limit = 65536 - (((unsigned) ptr) & 0xFFFF);
- } else {
- if (count > 65536 * 2)
- count = 65536 * 2;
- limit = 65536* 2 - (((unsigned) ptr) & 0x1FFFF);
- }
-
- if (count > limit) count = limit;
-
- if ((count & 1) || (((unsigned) ptr) & 1))
- panic ("scsi%d : attempted unaligned DMA transfer\n", instance->host_no);
- cli();
- disable_dma(instance->dma_channel);
- clear_dma_ff(instance->dma_channel);
- set_dma_addr(instance->dma_channel, (unsigned int) ptr);
- set_dma_count(instance->dma_channel, count);
- set_dma_mode(instance->dma_channel, mode);
- enable_dma(instance->dma_channel);
- sti();
- return count;
-}
-
-static __inline__ int NCR5380_i386_dma_write_setup (struct Scsi_Host *instance,
- unsigned char *src, unsigned int count) {
- return NCR5380_i386_dma_setup (instance, src, count, DMA_MODE_WRITE);
-}
-
-static __inline__ int NCR5380_i386_dma_read_setup (struct Scsi_Host *instance,
- unsigned char *src, unsigned int count) {
- return NCR5380_i386_dma_setup (instance, src, count, DMA_MODE_READ);
-}
-
-static __inline__ int NCR5380_i386_dma_residual (struct Scsi_Host *instance) {
- register int tmp;
- cli();
- clear_dma_ff(instance->dma_channel);
- tmp = get_dma_residue(instance->dma_channel);
- sti();
- return tmp;
-}
-#endif /* defined(REAL_DMA) && defined(i386) */
-#endif __KERNEL_
-#endif /* ndef ASM */
-#endif /* NCR5380_H */
diff --git a/i386/i386at/gpl/linux/scsi/NCR5380.src b/i386/i386at/gpl/linux/scsi/NCR5380.src
deleted file mode 100644
index 64beb813..00000000
--- a/i386/i386at/gpl/linux/scsi/NCR5380.src
+++ /dev/null
@@ -1,3035 +0,0 @@
-#ifndef NDEBUG
-#define NDEBUG (NDEBUG_RESTART_SELECT | NDEBUG_ABORT)
-#endif
-/*
- * NCR 5380 generic driver routines. These should make it *trivial*
- * to implement 5380 SCSI drivers under Linux with a non-trantor
- * architecture.
- *
- * Note that these routines also work with NR53c400 family chips.
- *
- * Copyright 1993, Drew Eckhardt
- * Visionary Computing
- * (Unix and Linux consulting and custom programming)
- * drew@colorado.edu
- * +1 (303) 666-5836
- *
- * DISTRIBUTION RELEASE 6.
- *
- * For more information, please consult
- *
- * NCR 5380 Family
- * SCSI Protocol Controller
- * Databook
- *
- * NCR Microelectronics
- * 1635 Aeroplaza Drive
- * Colorado Springs, CO 80916
- * 1+ (719) 578-3400
- * 1+ (800) 334-5454
- */
-
-/*
- * $Log: NCR5380.src,v $
- * Revision 1.1.1.1 1996/10/30 01:39:59 thomas
- * Imported from UK22
- *
-# Revision 1.1 1996/03/25 20:25:10 goel
-# Linux driver merge.
-#
- * Revision 1.5 1994/01/19 09:14:57 drew
- * Fixed udelay() hack that was being used on DATAOUT phases
- * instead of a proper wait for the final handshake.
- *
- * Revision 1.4 1994/01/19 06:44:25 drew
- * *** empty log message ***
- *
- * Revision 1.3 1994/01/19 05:24:40 drew
- * Added support for TCR LAST_BYTE_SENT bit.
- *
- * Revision 1.2 1994/01/15 06:14:11 drew
- * REAL DMA support, bug fixes.
- *
- * Revision 1.1 1994/01/15 06:00:54 drew
- * Initial revision
- *
- */
-
-/*
- * Further development / testing that should be done :
- * 1. Cleanup the NCR5380_transfer_dma function and DMA operation complete
- * code so that everything does the same thing that's done at the
- * end of a pseudo-DMA read operation.
- *
- * 2. Fix REAL_DMA (interrupt driven, polled works fine) -
- * basically, transfer size needs to be reduced by one
- * and the last byte read as is done with PSEUDO_DMA.
- *
- * 3. Test USLEEP code
- *
- * 4. Test SCSI-II tagged queueing (I have no devices which support
- * tagged queueing)
- *
- * 5. Test linked command handling code after Eric is ready with
- * the high level code.
- */
-
-#if (NDEBUG & NDEBUG_LISTS)
-#define LIST(x,y) {printk("LINE:%d Adding %p to %p\n", __LINE__, (void*)(x), (void*)(y)); if ((x)==(y)) udelay(5); }
-#define REMOVE(w,x,y,z) {printk("LINE:%d Removing: %p->%p %p->%p \n", __LINE__, (void*)(w), (void*)(x), (void*)(y), (void*)(z)); if ((x)==(y)) udelay(5); }
-#else
-#define LIST(x,y)
-#define REMOVE(w,x,y,z)
-#endif
-
-#ifndef notyet
-#undef LINKED
-#undef USLEEP
-#undef REAL_DMA
-#endif
-
-#ifdef REAL_DMA_POLL
-#undef READ_OVERRUNS
-#define READ_OVERRUNS
-#endif
-
-/*
- * Design
- * Issues :
- *
- * The other Linux SCSI drivers were written when Linux was Intel PC-only,
- * and specifically for each board rather than each chip. This makes their
- * adaptation to platforms like the Mac (Some of which use NCR5380's)
- * more difficult than it has to be.
- *
- * Also, many of the SCSI drivers were written before the command queuing
- * routines were implemented, meaning their implementations of queued
- * commands were hacked on rather than designed in from the start.
- *
- * When I designed the Linux SCSI drivers I figured that
- * while having two different SCSI boards in a system might be useful
- * for debugging things, two of the same type wouldn't be used.
- * Well, I was wrong and a number of users have mailed me about running
- * multiple high-performance SCSI boards in a server.
- *
- * Finally, when I get questions from users, I have no idea what
- * revision of my driver they are running.
- *
- * This driver attempts to address these problems :
- * This is a generic 5380 driver. To use it on a different platform,
- * one simply writes appropriate system specific macros (ie, data
- * transfer - some PC's will use the I/O bus, 68K's must use
- * memory mapped) and drops this file in their 'C' wrapper.
- *
- * As far as command queueing, two queues are maintained for
- * each 5380 in the system - commands that haven't been issued yet,
- * and commands that are currently executing. This means that an
- * unlimited number of commands may be queued, letting
- * more commands propagate from the higher driver levels giving higher
- * throughput. Note that both I_T_L and I_T_L_Q nexuses are supported,
- * allowing multiple commands to propagate all the way to a SCSI-II device
- * while a command is already executing.
- *
- * To solve the multiple-boards-in-the-same-system problem,
- * there is a separate instance structure for each instance
- * of a 5380 in the system. So, multiple NCR5380 drivers will
- * be able to coexist with appropriate changes to the high level
- * SCSI code.
- *
- * A NCR5380_PUBLIC_REVISION macro is provided, with the release
- * number (updated for each public release) printed by the
- * NCR5380_print_options command, which should be called from the
- * wrapper detect function, so that I know what release of the driver
- * users are using.
- *
- * Issues specific to the NCR5380 :
- *
- * When used in a PIO or pseudo-dma mode, the NCR5380 is a braindead
- * piece of hardware that requires you to sit in a loop polling for
- * the REQ signal as long as you are connected. Some devices are
- * brain dead (ie, many TEXEL CD ROM drives) and won't disconnect
- * while doing long seek operations.
- *
- * The workaround for this is to keep track of devices that have
- * disconnected. If the device hasn't disconnected, for commands that
- * should disconnect, we do something like
- *
- * while (!REQ is asserted) { sleep for N usecs; poll for M usecs }
- *
- * Some tweaking of N and M needs to be done. An algorithm based
- * on "time to data" would give the best results as long as short time
- * to datas (ie, on the same track) were considered, however these
- * broken devices are the exception rather than the rule and I'd rather
- * spend my time optimizing for the normal case.
- *
- * Architecture :
- *
- * At the heart of the design is a coroutine, NCR5380_main,
- * which is started when not running by the interrupt handler,
- * timer, and queue command function. It attempts to establish
- * I_T_L or I_T_L_Q nexuses by removing the commands from the
- * issue queue and calling NCR5380_select() if a nexus
- * is not established.
- *
- * Once a nexus is established, the NCR5380_information_transfer()
- * phase goes through the various phases as instructed by the target.
- * if the target goes into MSG IN and sends a DISCONNECT message,
- * the command structure is placed into the per instance disconnected
- * queue, and NCR5380_main tries to find more work. If USLEEP
- * was defined, and the target is idle for too long, the system
- * will try to sleep.
- *
- * If a command has disconnected, eventually an interrupt will trigger,
- * calling NCR5380_intr() which will in turn call NCR5380_reselect
- * to reestablish a nexus. This will run main if necessary.
- *
- * On command termination, the done function will be called as
- * appropriate.
- *
- * SCSI pointers are maintained in the SCp field of SCSI command
- * structures, being initialized after the command is connected
- * in NCR5380_select, and set as appropriate in NCR5380_information_transfer.
- * Note that in violation of the standard, an implicit SAVE POINTERS operation
- * is done, since some BROKEN disks fail to issue an explicit SAVE POINTERS.
- */
-
-/*
- * Using this file :
- * This file a skeleton Linux SCSI driver for the NCR 5380 series
- * of chips. To use it, you write a architecture specific functions
- * and macros and include this file in your driver.
- *
- * These macros control options :
- * AUTOPROBE_IRQ - if defined, the NCR5380_probe_irq() function will be
- * defined.
- *
- * AUTOSENSE - if defined, REQUEST SENSE will be performed automatically
- * for commands that return with a CHECK CONDITION status.
- *
- * DIFFERENTIAL - if defined, NCR53c81 chips will use external differential
- * transceivers.
- *
- * LIMIT_TRANSFERSIZE - if defined, limit the pseudo-dma transfers to 512
- * bytes at a time. Since interrupts are disabled by default during
- * these transfers, we might need this to give reasonable interrupt
- * service time if the transfer size gets too large.
- *
- * LINKED - if defined, linked commands are supported.
- *
- * PSEUDO_DMA - if defined, PSEUDO DMA is used during the data transfer phases.
- *
- * REAL_DMA - if defined, REAL DMA is used during the data transfer phases.
- *
- * REAL_DMA_POLL - if defined, REAL DMA is used but the driver doesn't
- * rely on phase mismatch and EOP interrupts to determine end
- * of phase.
- *
- * SCSI2 - if defined, SCSI-2 tagged queuing is used where possible
- *
- * UNSAFE - leave interrupts enabled during pseudo-DMA transfers. You
- * only really want to use this if you're having a problem with
- * dropped characters during high speed communications, and even
- * then, you're going to be better off twiddling with transfersize
- * in the high level code.
- *
- * USLEEP - if defined, on devices that aren't disconnecting from the
- * bus, we will go to sleep so that the CPU can get real work done
- * when we run a command that won't complete immediately.
- *
- * Note that if USLEEP is defined, NCR5380_TIMER *must* also be
- * defined.
- *
- * Defaults for these will be provided if USLEEP is defined, although
- * the user may want to adjust these to allocate CPU resources to
- * the SCSI driver or "real" code.
- *
- * USLEEP_SLEEP - amount of time, in jiffies, to sleep
- *
- * USLEEP_POLL - amount of time, in jiffies, to poll
- *
- * These macros MUST be defined :
- * NCR5380_local_declare() - declare any local variables needed for your transfer
- * routines.
- *
- * NCR5380_setup(instance) - initialize any local variables needed from a given
- * instance of the host adapter for NCR5380_{read,write,pread,pwrite}
- *
- * NCR5380_read(register) - read from the specified register
- *
- * NCR5380_write(register, value) - write to the specific register
- *
- * NCR5380_implementation_fields - additional fields needed for this
- * specific implementation of the NCR5380
- *
- * Either real DMA *or* pseudo DMA may be implemented
- * REAL functions :
- * NCR5380_REAL_DMA should be defined if real DMA is to be used.
- * Note that the DMA setup functions should return the number of bytes
- * that they were able to program the controller for.
- *
- * Also note that generic i386/PC versions of these macros are
- * available as NCR5380_i386_dma_write_setup,
- * NCR5380_i386_dma_read_setup, and NCR5380_i386_dma_residual.
- *
- * NCR5380_dma_write_setup(instance, src, count) - initialize
- * NCR5380_dma_read_setup(instance, dst, count) - initialize
- * NCR5380_dma_residual(instance); - residual count
- *
- * PSEUDO functions :
- * NCR5380_pwrite(instance, src, count)
- * NCR5380_pread(instance, dst, count);
- *
- * If nothing specific to this implementation needs doing (ie, with external
- * hardware), you must also define
- *
- * NCR5380_queue_command
- * NCR5380_reset
- * NCR5380_abort
- *
- * to be the global entry points into the specific driver, ie
- * #define NCR5380_queue_command t128_queue_command.
- *
- * If this is not done, the routines will be defined as static functions
- * with the NCR5380* names and the user must provide a globally
- * accessible wrapper function.
- *
- * The generic driver is initialized by calling NCR5380_init(instance),
- * after setting the appropriate host specific fields and ID. If the
- * driver wishes to autoprobe for an IRQ line, the NCR5380_probe_irq(instance,
- * possible) function may be used. Before the specific driver initialization
- * code finishes, NCR5380_print_options should be called.
- */
-
-static int do_abort (struct Scsi_Host *host);
-static void do_reset (struct Scsi_Host *host);
-static struct Scsi_Host *first_instance = NULL;
-static Scsi_Host_Template *the_template = NULL;
-
-/*
- * Function : void initialize_SCp(Scsi_Cmnd *cmd)
- *
- * Purpose : initialize the saved data pointers for cmd to point to the
- * start of the buffer.
- *
- * Inputs : cmd - Scsi_Cmnd structure to have pointers reset.
- */
-
-static __inline__ void initialize_SCp(Scsi_Cmnd *cmd) {
- /*
- * Initialize the Scsi Pointer field so that all of the commands in the
- * various queues are valid.
- */
-
- if (cmd->use_sg) {
- cmd->SCp.buffer = (struct scatterlist *) cmd->buffer;
- cmd->SCp.buffers_residual = cmd->use_sg - 1;
- cmd->SCp.ptr = (char *) cmd->SCp.buffer->address;
- cmd->SCp.this_residual = cmd->SCp.buffer->length;
- } else {
- cmd->SCp.buffer = NULL;
- cmd->SCp.buffers_residual = 0;
- cmd->SCp.ptr = (char *) cmd->request_buffer;
- cmd->SCp.this_residual = cmd->request_bufflen;
- }
-}
-
-#include <linux/delay.h>
-
-#ifdef NDEBUG
-static struct {
- unsigned char mask;
- const char * name;}
-signals[] = {{ SR_DBP, "PARITY"}, { SR_RST, "RST" }, { SR_BSY, "BSY" },
- { SR_REQ, "REQ" }, { SR_MSG, "MSG" }, { SR_CD, "CD" }, { SR_IO, "IO" },
- { SR_SEL, "SEL" }, {0, NULL}},
-basrs[] = {{BASR_ATN, "ATN"}, {BASR_ACK, "ACK"}, {0, NULL}},
-icrs[] = {{ICR_ASSERT_RST, "ASSERT RST"},{ICR_ASSERT_ACK, "ASSERT ACK"},
- {ICR_ASSERT_BSY, "ASSERT BSY"}, {ICR_ASSERT_SEL, "ASSERT SEL"},
- {ICR_ASSERT_ATN, "ASSERT ATN"}, {ICR_ASSERT_DATA, "ASSERT DATA"},
- {0, NULL}},
-mrs[] = {{MR_BLOCK_DMA_MODE, "MODE BLOCK DMA"}, {MR_TARGET, "MODE TARGET"},
- {MR_ENABLE_PAR_CHECK, "MODE PARITY CHECK"}, {MR_ENABLE_PAR_INTR,
- "MODE PARITY INTR"}, {MR_MONITOR_BSY, "MODE MONITOR BSY"},
- {MR_DMA_MODE, "MODE DMA"}, {MR_ARBITRATE, "MODE ARBITRATION"},
- {0, NULL}};
-
-/*
- * Function : void NCR5380_print(struct Scsi_Host *instance)
- *
- * Purpose : print the SCSI bus signals for debugging purposes
- *
- * Input : instance - which NCR5380
- */
-
-static void NCR5380_print(struct Scsi_Host *instance) {
- NCR5380_local_declare();
- unsigned char status, data, basr, mr, icr, i;
- NCR5380_setup(instance);
- cli();
- data = NCR5380_read(CURRENT_SCSI_DATA_REG);
- status = NCR5380_read(STATUS_REG);
- mr = NCR5380_read(MODE_REG);
- icr = NCR5380_read(INITIATOR_COMMAND_REG);
- basr = NCR5380_read(BUS_AND_STATUS_REG);
- sti();
- printk("STATUS_REG: %02x ", status);
- for (i = 0; signals[i].mask ; ++i)
- if (status & signals[i].mask)
- printk(",%s", signals[i].name);
- printk("\nBASR: %02x ", basr);
- for (i = 0; basrs[i].mask ; ++i)
- if (basr & basrs[i].mask)
- printk(",%s", basrs[i].name);
- printk("\nICR: %02x ", icr);
- for (i = 0; icrs[i].mask; ++i)
- if (icr & icrs[i].mask)
- printk(",%s", icrs[i].name);
- printk("\nMODE: %02x ", mr);
- for (i = 0; mrs[i].mask; ++i)
- if (mr & mrs[i].mask)
- printk(",%s", mrs[i].name);
- printk("\n");
-}
-
-static struct {
- unsigned char value;
- const char *name;
-} phases[] = {
-{PHASE_DATAOUT, "DATAOUT"}, {PHASE_DATAIN, "DATAIN"}, {PHASE_CMDOUT, "CMDOUT"},
-{PHASE_STATIN, "STATIN"}, {PHASE_MSGOUT, "MSGOUT"}, {PHASE_MSGIN, "MSGIN"},
-{PHASE_UNKNOWN, "UNKNOWN"}};
-
-/*
- * Function : void NCR5380_print_phase(struct Scsi_Host *instance)
- *
- * Purpose : print the current SCSI phase for debugging purposes
- *
- * Input : instance - which NCR5380
- */
-
-static void NCR5380_print_phase(struct Scsi_Host *instance) {
- NCR5380_local_declare();
- unsigned char status;
- int i;
- NCR5380_setup(instance);
-
- status = NCR5380_read(STATUS_REG);
- if (!(status & SR_REQ))
- printk("scsi%d : REQ not asserted, phase unknown.\n",
- instance->host_no);
- else {
- for (i = 0; (phases[i].value != PHASE_UNKNOWN) &&
- (phases[i].value != (status & PHASE_MASK)); ++i);
- printk("scsi%d : phase %s\n", instance->host_no, phases[i].name);
- }
-}
-#endif
-
-/*
- * We need to have our coroutine active given these constraints :
- * 1. The mutex flag, main_running, can only be set when the main
- * routine can actually process data, otherwise SCSI commands
- * will never get issued.
- *
- * 2. NCR5380_main() shouldn't be called before it has exited, because
- * other drivers have had kernel stack overflows in similar
- * situations.
- *
- * 3. We don't want to inline NCR5380_main() because of space concerns,
- * even though it is only called in two places.
- *
- * So, the solution is to set the mutex in an inline wrapper for the
- * main coroutine, and have the main coroutine exit with interrupts
- * disabled after the final search through the queues so that no race
- * conditions are possible.
- */
-
-static volatile int main_running = 0;
-
-/*
- * Function : run_main(void)
- *
- * Purpose : insure that the coroutine is running and will process our
- * request. main_running is checked/set here (in an inline function)
- * rather than in NCR5380_main itself to reduce the chances of stack
- * overflow.
- *
- */
-
-static __inline__ void run_main(void) {
- cli();
- if (!main_running) {
- main_running = 1;
- NCR5380_main();
- /*
- * main_running is cleared in NCR5380_main once it can't do
- * more work, and NCR5380_main exits with interrupts disabled.
- */
- sti();
- } else
- sti();
-}
-
-#ifdef USLEEP
-#ifndef NCR5380_TIMER
-#error "NCR5380_TIMER must be defined so that this type of NCR5380 driver gets a unique timer."
-#endif
-
-/*
- * These need tweaking, and would probably work best as per-device
- * flags initialized differently for disk, tape, cd, etc devices.
- * People with broken devices are free to experiment as to what gives
- * the best results for them.
- *
- * USLEEP_SLEEP should be a minimum seek time.
- *
- * USLEEP_POLL should be a maximum rotational latency.
- */
-#ifndef USLEEP_SLEEP
-/* 20 ms (reasonable hard disk speed) */
-#define USLEEP_SLEEP 2
-#endif
-/* 300 RPM (floppy speed) */
-#ifndef USLEEP_POLL
-#define USLEEP_POLL 20
-#endif
-
-static struct Scsi_Host * expires_first = NULL;
-
-/*
- * Function : int should_disconnect (unsigned char cmd)
- *
- * Purpose : decide weather a command would normally disconnect or
- * not, since if it won't disconnect we should go to sleep.
- *
- * Input : cmd - opcode of SCSI command
- *
- * Returns : DISCONNECT_LONG if we should disconnect for a really long
- * time (ie always, sleep, look for REQ active, sleep),
- * DISCONNECT_TIME_TO_DATA if we would only disconnect for a normal
- * time-to-data delay, DISCONNECT_NONE if this command would return
- * immediately.
- *
- * Future sleep algorithms based on time to data can exploit
- * something like this so they can differentiate between "normal"
- * (ie, read, write, seek) and unusual commands (ie, * format).
- *
- * Note : We don't deal with commands that handle an immediate disconnect,
- *
- */
-
-static int should_disconnect (unsigned char cmd) {
- switch (cmd) {
- case READ_6:
- case WRITE_6:
- case SEEK_6:
- case READ_10:
- case WRITE_10:
- case SEEK_10:
- return DISCONNECT_TIME_TO_DATA;
- case FORMAT_UNIT:
- case SEARCH_HIGH:
- case SEARCH_LOW:
- case SEARCH_EQUAL:
- return DISCONNECT_LONG;
- default:
- return DISCONNECT_NONE;
- }
-}
-
-/*
- * Assumes instance->time_expires has been set in higher level code.
- */
-
-static int NCR5380_set_timer (struct Scsi_Host *instance) {
- struct Scsi_Host *tmp, **prev;
-
- cli();
- if (((struct NCR5380_hostdata *) (instance->host_data))->next_timer) {
- sti();
- return -1;
- }
-
- for (prev = &expires_first, tmp = expires_first; tmp;
- prev = &(((struct NCR5380_hostdata *) tmp->host_data)->next_timer),
- tmp = ((struct NCR5380_hostdata *) tmp->host_data)->next_timer)
- if (instance->time_expires < tmp->time_expires)
- break;
-
- instance->next_timer = tmp;
- *prev = instance;
- timer_table[NCR5380_TIMER].expires = expires_first->time_expires;
- timer_active |= 1 << NCR5380_TIMER;
- sti();
- return 0;
-}
-
-/* Doing something about unwanted reentrancy here might be useful */
-void NCR5380_timer_fn(void) {
- struct Scsi_Host *instance;
- cli();
- for (; expires_first && expires_first->time_expires >= jiffies; ) {
- instance = ((NCR5380_hostdata *) expires_first->host_data)->
- expires_next;
- ((NCR5380_hostdata *) expires_first->host_data)->expires_next =
- NULL;
- ((NCR5380_hostdata *) expires_first->host_data)->time_expires =
- 0;
- expires_first = instance;
- }
-
- if (expires_first) {
- timer_table[NCR5380_TIMER].expires = ((NCR5380_hostdata *)
- expires_first->host_data)->time_expires;
- timer_active |= (1 << NCR5380_TIMER);
- } else {
- timer_table[NCR5380_TIMER].expires = 0;
- timer_active &= ~(1 << MCR5380_TIMER);
- }
- sti();
-
- run_main();
-}
-#endif /* def USLEEP */
-
-static void NCR5380_all_init (void) {
- static int done = 0;
- if (!done) {
-#if (NDEBUG & NDEBUG_INIT)
- printk("scsi : NCR5380_all_init()\n");
-#endif
- done = 1;
-#ifdef USLEEP
- timer_table[NCR5380_TIMER].expires = 0;
- timer_table[NCR5380_TIMER].fn = NCR5380_timer_fn;
-#endif
- }
-}
-
-#ifdef AUTOPROBE_IRQ
-/*
- * Function : int NCR5380_probe_irq (struct Scsi_Host *instance, int possible)
- *
- * Purpose : autoprobe for the IRQ line used by the NCR5380.
- *
- * Inputs : instance - pointer to this instance of the NCR5380 driver,
- * possible - bitmask of permissible interrupts.
- *
- * Returns : number of the IRQ selected, IRQ_NONE if no interrupt fired.
- *
- * XXX no effort is made to deal with spurious interrupts.
- */
-
-
-static int probe_irq;
-static void probe_intr (int irq, struct pt_regs * regs) {
- probe_irq = irq;
-};
-
-static int NCR5380_probe_irq (struct Scsi_Host *instance, int possible) {
- NCR5380_local_declare();
- struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *)
- instance->hostdata;
- unsigned long timeout;
- int trying_irqs, i, mask;
- NCR5380_setup(instance);
-
- for (trying_irqs = i = 0, mask = 1; i < 16; ++i, mask <<= 1)
- if ((mask & possible) && (request_irq(i, &probe_intr, SA_INTERRUPT, "NCR-probe")
- == 0))
- trying_irqs |= mask;
-
- timeout = jiffies + 25;
- probe_irq = IRQ_NONE;
-
-/*
- * A interrupt is triggered whenever BSY = false, SEL = true
- * and a bit set in the SELECT_ENABLE_REG is asserted on the
- * SCSI bus.
- *
- * Note that the bus is only driven when the phase control signals
- * (I/O, C/D, and MSG) match those in the TCR, so we must reset that
- * to zero.
- */
-
- NCR5380_write(TARGET_COMMAND_REG, 0);
- NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
- NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask);
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA |
- ICR_ASSERT_SEL);
-
- while (probe_irq == IRQ_NONE && jiffies < timeout)
- barrier();
-
- NCR5380_write(SELECT_ENABLE_REG, 0);
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-
- for (i = 0, mask = 1; i < 16; ++i, mask <<= 1)
- if (trying_irqs & mask)
- free_irq(i);
-
- return probe_irq;
-}
-#endif /* AUTOPROBE_IRQ */
-
-/*
- * Function : void NCR58380_print_options (struct Scsi_Host *instance)
- *
- * Purpose : called by probe code indicating the NCR5380 driver
- * options that were selected.
- *
- * Inputs : instance, pointer to this instance. Unused.
- */
-
-static void NCR5380_print_options (struct Scsi_Host *instance) {
- printk(" generic options"
-#ifdef AUTOPROBE_IRQ
- " AUTOPROBE_IRQ"
-#endif
-#ifdef AUTOSENSE
- " AUTOSENSE"
-#endif
-#ifdef DIFFERENTIAL
- " DIFFERENTIAL"
-#endif
-#ifdef REAL_DMA
- " REAL DMA"
-#endif
-#ifdef REAL_DMA_POLL
- " REAL DMA POLL"
-#endif
-#ifdef PARITY
- " PARITY"
-#endif
-#ifdef PSEUDO_DMA
- " PSEUDO DMA"
-#endif
-#ifdef SCSI2
- " SCSI-2"
-#endif
-#ifdef UNSAFE
- " UNSAFE "
-#endif
- );
-#ifdef USLEEP
- printk(" USLEEP, USLEEP_POLL=%d USLEEP_SLEEP=%d", USLEEP_POLL, USLEEP_SLEEP);
-#endif
- printk(" generic release=%d", NCR5380_PUBLIC_RELEASE);
- if (((struct NCR5380_hostdata *)instance->hostdata)->flags & FLAG_NCR53C400) {
- printk(" ncr53c400 release=%d", NCR53C400_PUBLIC_RELEASE);
- }
-}
-
-/*
- * Function : void NCR5380_print_status (struct Scsi_Host *instance)
- *
- * Purpose : print commands in the various queues, called from
- * NCR5380_abort and NCR5380_debug to aid debugging.
- *
- * Inputs : instance, pointer to this instance.
- */
-
-static void NCR5380_print_status (struct Scsi_Host *instance) {
- struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *)
- instance->hostdata;
- Scsi_Cmnd *ptr;
-
-
- printk("NCR5380 : coroutine is%s running.\n",
- main_running ? "" : "n't");
-
-#ifdef NDEBUG
- NCR5380_print (instance);
- NCR5380_print_phase (instance);
-#endif
-
- cli();
- if (!hostdata->connected) {
- printk ("scsi%d: no currently connected command\n",
- instance->host_no);
- } else {
- print_Scsi_Cmnd ((Scsi_Cmnd *) hostdata->connected);
- }
-
- printk ("scsi%d: issue_queue\n", instance->host_no);
-
- for (ptr = (Scsi_Cmnd *) hostdata->issue_queue; ptr;
- ptr = (Scsi_Cmnd *) ptr->host_scribble)
- print_Scsi_Cmnd (ptr);
-
- printk ("scsi%d: disconnected_queue\n", instance->host_no);
-
- for (ptr = (Scsi_Cmnd *) hostdata->disconnected_queue; ptr;
- ptr = (Scsi_Cmnd *) ptr->host_scribble)
- print_Scsi_Cmnd (ptr);
-
- sti();
-}
-
-
-/*
- * Function : void NCR5380_init (struct Scsi_Host *instance, flags)
- *
- * Purpose : initializes *instance and corresponding 5380 chip,
- * with flags OR'd into the initial flags value.
- *
- * Inputs : instance - instantiation of the 5380 driver.
- *
- * Notes : I assume that the host, hostno, and id bits have been
- * set correctly. I don't care about the irq and other fields.
- *
- */
-
-static void NCR5380_init (struct Scsi_Host *instance, int flags) {
- NCR5380_local_declare();
- int i, pass;
- unsigned long timeout;
- struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *)
- instance->hostdata;
-
- /*
- * On NCR53C400 boards, NCR5380 registers are mapped 8 past
- * the base address.
- */
-
-#ifdef NCR53C400
- if (flags & FLAG_NCR53C400)
- instance->NCR5380_instance_name += NCR53C400_address_adjust;
-#endif
-
- NCR5380_setup(instance);
-
- NCR5380_all_init();
-
- hostdata->aborted = 0;
- hostdata->id_mask = 1 << instance->this_id;
- for (i = hostdata->id_mask; i <= 0x80; i <<= 1)
- if (i > hostdata->id_mask)
- hostdata->id_higher_mask |= i;
- for (i = 0; i < 8; ++i)
- hostdata->busy[i] = 0;
-#ifdef REAL_DMA
- hostdata->dmalen = 0;
-#endif
- hostdata->targets_present = 0;
- hostdata->connected = NULL;
- hostdata->issue_queue = NULL;
- hostdata->disconnected_queue = NULL;
-
- /* The CHECK code seems to break the 53C400. Will check it later maybe */
- if (flags & FLAG_NCR53C400)
- hostdata->flags = FLAG_HAS_LAST_BYTE_SENT | flags;
- else
- hostdata->flags = FLAG_CHECK_LAST_BYTE_SENT | flags;
-
- if (!the_template) {
- the_template = instance->hostt;
- first_instance = instance;
- }
-
-
-#ifdef USLEEP
- hostdata->time_expires = 0;
- hostdata->next_timer = NULL;
-#endif
-
-#ifndef AUTOSENSE
- if ((instance->cmd_per_lun > 1) || instance->can_queue > 1))
- printk("scsi%d : WARNING : support for multiple outstanding commands enabled\n"
- " without AUTOSENSE option, contingent allegiance conditions may\n"
- " be incorrectly cleared.\n", instance->host_no);
-#endif /* def AUTOSENSE */
-
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
- NCR5380_write(MODE_REG, MR_BASE);
- NCR5380_write(TARGET_COMMAND_REG, 0);
- NCR5380_write(SELECT_ENABLE_REG, 0);
-
-#ifdef NCR53C400
- if (hostdata->flags & FLAG_NCR53C400) {
- NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
- }
-#endif
-
- /*
- * Detect and correct bus wedge problems.
- *
- * If the system crashed, it may have crashed in a state
- * where a SCSI command was still executing, and the
- * SCSI bus is not in a BUS FREE STATE.
- *
- * If this is the case, we'll try to abort the currently
- * established nexus which we know nothing about, and that
- * failing, do a hard reset of the SCSI bus
- */
-
- for (pass = 1; (NCR5380_read(STATUS_REG) & SR_BSY) &&
- pass <= 6 ; ++pass) {
- switch (pass) {
- case 1:
- case 3:
- case 5:
- printk("scsi%d: SCSI bus busy, waiting up to five seconds\n",
- instance->host_no);
- timeout = jiffies + 500;
- while (jiffies < timeout && (NCR5380_read(STATUS_REG) & SR_BSY));
- break;
- case 2:
- printk("scsi%d: bus busy, attempting abort\n",
- instance->host_no);
- do_abort (instance);
- break;
- case 4:
- printk("scsi%d: bus busy, attempting reset\n",
- instance->host_no);
- do_reset (instance);
- break;
- case 6:
- printk("scsi%d: bus locked solid or invalid override\n",
- instance->host_no);
- }
- }
-}
-
-/*
- * Function : int NCR5380_queue_command (Scsi_Cmnd *cmd,
- * void (*done)(Scsi_Cmnd *))
- *
- * Purpose : enqueues a SCSI command
- *
- * Inputs : cmd - SCSI command, done - function called on completion, with
- * a pointer to the command descriptor.
- *
- * Returns : 0
- *
- * Side effects :
- * cmd is added to the per instance issue_queue, with minor
- * twiddling done to the host specific fields of cmd. If the
- * main coroutine is not running, it is restarted.
- *
- */
-
-/* Only make static if a wrapper function is used */
-#ifndef NCR5380_queue_command
-static
-#endif
-int NCR5380_queue_command (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)) {
- struct Scsi_Host *instance = cmd->host;
- struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *)
- instance->hostdata;
- Scsi_Cmnd *tmp;
-
-#if (NDEBUG & NDEBUG_NO_WRITE)
- switch (cmd->cmnd[0]) {
- case WRITE:
- case WRITE_10:
- printk("scsi%d : WRITE attempted with NO_WRITE debugging flag set\n",
- instance->host_no);
- cmd->result = (DID_ERROR << 16);
- done(cmd);
- return 0;
- }
-#endif /* (NDEBUG & NDEBUG_NO_WRITE) */
-
-
- /*
- * We use the host_scribble field as a pointer to the next command
- * in a queue
- */
-
- cmd->host_scribble = NULL;
- cmd->scsi_done = done;
-
- cmd->result = 0;
-
-
- /*
- * Insert the cmd into the issue queue. Note that REQUEST SENSE
- * commands are added to the head of the queue since any command will
- * clear the contingent allegiance condition that exists and the
- * sense data is only guaranteed to be valid while the condition exists.
- */
-
- cli();
- if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) {
- LIST(cmd, hostdata->issue_queue);
- cmd->host_scribble = (unsigned char *) hostdata->issue_queue;
- hostdata->issue_queue = cmd;
- } else {
- for (tmp = (Scsi_Cmnd *) hostdata->issue_queue; tmp->host_scribble;
- tmp = (Scsi_Cmnd *) tmp->host_scribble);
- LIST(cmd, tmp);
- tmp->host_scribble = (unsigned char *) cmd;
- }
-#if (NDEBUG & NDEBUG_QUEUES)
- printk("scsi%d : command added to %s of queue\n", instance->host_no,
- (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail");
-#endif
-
-/* Run the coroutine if it isn't already running. */
- run_main();
- return 0;
-}
-
-/*
- * Function : NCR5380_main (void)
- *
- * Purpose : NCR5380_main is a coroutine that runs as long as more work can
- * be done on the NCR5380 host adapters in a system. Both
- * NCR5380_queue_command() and NCR5380_intr() will try to start it
- * in case it is not running.
- *
- * NOTE : NCR5380_main exits with interrupts *disabled*, the caller should
- * reenable them. This prevents reentrancy and kernel stack overflow.
- */
-
-static void NCR5380_main (void) {
- Scsi_Cmnd *tmp, *prev;
- struct Scsi_Host *instance;
- struct NCR5380_hostdata *hostdata;
- int done;
-
- /*
- * We run (with interrupts disabled) until we're sure that none of
- * the host adapters have anything that can be done, at which point
- * we set main_running to 0 and exit.
- *
- * Interrupts are enabled before doing various other internal
- * instructions, after we've decided that we need to run through
- * the loop again.
- *
- * this should prevent any race conditions.
- */
-
- do {
- cli(); /* Freeze request queues */
- done = 1;
- for (instance = first_instance; instance &&
- instance->hostt == the_template; instance=instance->next) {
- hostdata = (struct NCR5380_hostdata *) instance->hostdata;
- cli();
- if (!hostdata->connected) {
-#if (NDEBUG & NDEBUG_MAIN)
- printk("scsi%d : not connected\n", instance->host_no);
-#endif
- /*
- * Search through the issue_queue for a command destined
- * for a target that's not busy.
- */
-#if (NDEBUG & NDEBUG_LISTS)
- for (tmp= (Scsi_Cmnd *) hostdata->issue_queue, prev=NULL; tmp && (tmp != prev); prev=tmp, tmp=(Scsi_Cmnd*)tmp->host_scribble)
- ;
- /*printk("%p ", tmp);*/
- if ((tmp == prev) && tmp) printk(" LOOP\n");/* else printk("\n");*/
-#endif
- for (tmp = (Scsi_Cmnd *) hostdata->issue_queue,
- prev = NULL; tmp; prev = tmp, tmp = (Scsi_Cmnd *)
- tmp->host_scribble) {
-
-#if (NDEBUG & NDEBUG_LISTS)
- if (prev != tmp)
- printk("MAIN tmp=%p target=%d busy=%d lun=%d\n", tmp, tmp->target, hostdata->busy[tmp->target], tmp->lun);
-#endif
- /* When we find one, remove it from the issue queue. */
- if (!(hostdata->busy[tmp->target] & (1 << tmp->lun))) {
- if (prev) {
- REMOVE(prev,prev->host_scribble,tmp,tmp->host_scribble);
- prev->host_scribble = tmp->host_scribble;
- } else {
- REMOVE(-1,hostdata->issue_queue,tmp,tmp->host_scribble);
- hostdata->issue_queue = (Scsi_Cmnd *) tmp->host_scribble;
- }
- tmp->host_scribble = NULL;
-
- /* reenable interrupts after finding one */
- sti();
-
- /*
- * Attempt to establish an I_T_L nexus here.
- * On success, instance->hostdata->connected is set.
- * On failure, we must add the command back to the
- * issue queue so we can keep trying.
- */
-#if (NDEBUG & (NDEBUG_MAIN | NDEBUG_QUEUES))
- printk("scsi%d : main() : command for target %d lun %d removed from issue_queue\n",
- instance->host_no, tmp->target, tmp->lun);
-#endif
-
- /*
- * A successful selection is defined as one that
- * leaves us with the command connected and
- * in hostdata->connected, OR has terminated the
- * command.
- *
- * With successfull commands, we fall through
- * and see if we can do an information transfer,
- * with failures we will restart.
- */
-
- if (!NCR5380_select(instance, tmp,
- /*
- * REQUEST SENSE commands are issued without tagged
- * queueing, even on SCSI-II devices because the
- * contingent allegiance condition exists for the
- * entire unit.
- */
- (tmp->cmnd[0] == REQUEST_SENSE) ? TAG_NONE :
- TAG_NEXT)) {
- break;
- } else {
- cli();
- LIST(tmp, hostdata->issue_queue);
- tmp->host_scribble = (unsigned char *)
- hostdata->issue_queue;
- hostdata->issue_queue = tmp;
- done = 0;
- sti();
-#if (NDEBUG & (NDEBUG_MAIN | NDEBUG_QUEUES))
- printk("scsi%d : main(): select() failed, returned to issue_queue\n",
- instance->host_no);
-#endif
- }
- } /* if target/lun is not busy */
- } /* for */
- } /* if (!hostdata->connected) */
-
- if (hostdata->connected
-#ifdef REAL_DMA
- && !hostdata->dmalen
-#endif
-#ifdef USLEEP
- && (!hostdata->time_expires || hostdata->time_expires >= jiffies)
-#endif
- ) {
- sti();
-#if (NDEBUG & NDEBUG_MAIN)
- printk("scsi%d : main() : performing information transfer\n",
- instance->host_no);
-#endif
- NCR5380_information_transfer(instance);
-#if (NDEBUG & NDEBUG_MAIN)
- printk("scsi%d : main() : done set false\n", instance->host_no);
-#endif
- done = 0;
- } else
- break;
- } /* for instance */
- } while (!done);
- main_running = 0;
-}
-
-/*
- * Function : void NCR5380_intr (int irq)
- *
- * Purpose : handle interrupts, reestablishing I_T_L or I_T_L_Q nexuses
- * from the disconnected queue, and restarting NCR5380_main()
- * as required.
- *
- * Inputs : int irq, irq that caused this interrupt.
- *
- */
-
-static void NCR5380_intr (int irq, struct pt_regs * regs) {
- NCR5380_local_declare();
- struct Scsi_Host *instance;
- int done;
- unsigned char basr;
-#if (NDEBUG & NDEBUG_INTR)
- printk("scsi : NCR5380 irq %d triggered\n", irq);
-#endif
- do {
- done = 1;
- for (instance = first_instance; instance && (instance->hostt ==
- the_template); instance = instance->next)
- if (instance->irq == irq) {
-
- /* Look for pending interrupts */
- NCR5380_setup(instance);
- basr = NCR5380_read(BUS_AND_STATUS_REG);
- /* XXX dispatch to appropriate routine if found and done=0 */
- if (basr & BASR_IRQ) {
-#if (NDEBUG & NDEBUG_INTR)
- NCR5380_print(instance);
-#endif
- if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) ==
- (SR_SEL | SR_IO)) {
- done = 0;
- sti();
-#if (NDEBUG & NDEBUG_INTR)
- printk("scsi%d : SEL interrupt\n", instance->host_no);
-#endif
- NCR5380_reselect(instance);
- (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
- } else if (basr & BASR_PARITY_ERROR) {
-#if (NDEBUG & NDEBUG_INTR)
- printk("scsi%d : PARITY interrupt\n", instance->host_no);
-#endif
- (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
- } else if ((NCR5380_read(STATUS_REG) & SR_RST) == SR_RST) {
-#if (NDEBUG & NDEBUG_INTR)
- printk("scsi%d : RESET interrupt\n", instance->host_no);
-#endif
- (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
- } else {
-/*
- * XXX the rest of the interrupt conditions should *only* occur during a
- * DMA transfer, which I haven't gotten around to fixing yet.
- */
-
-#if defined(REAL_DMA)
- /*
- * We should only get PHASE MISMATCH and EOP interrupts
- * if we have DMA enabled, so do a sanity check based on
- * the current setting of the MODE register.
- */
-
- if ((NCR5380_read(MODE_REG) & MR_DMA) && ((basr &
- BASR_END_DMA_TRANSFER) ||
- !(basr & BASR_PHASE_MATCH))) {
- int transfered;
-
- if (!hostdata->connected)
- panic("scsi%d : received end of DMA interrupt with no connected cmd\n",
- instance->hostno);
-
- transfered = (hostdata->dmalen - NCR5380_dma_residual(instance));
- hostdata->connected->SCp.this_residual -= transferred;
- hostdata->connected->SCp.ptr += transferred;
- hostdata->dmalen = 0;
-
- (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-#if NCR_TIMEOUT
- {
- unsigned long timeout = jiffies + NCR_TIMEOUT;
-
- while (NCR5380_read(BUS_AND_STATUS_REG) & BASR_ACK
- && jiffies < timeout)
- ;
- if (jiffies >= timeout)
- printk("scsi%d: timeout at NCR5380.c:%d\n",
- host->host_no, __LINE__);
- }
-#else /* NCR_TIMEOUT */
- while (NCR5380_read(BUS_AND_STATUS_REG) & BASR_ACK);
-#endif
-
- NCR5380_write(MODE_REG, MR_BASE);
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
- }
-#else
-#if (NDEBUG & NDEBUG_INTR)
- printk("scsi : unknown interrupt, BASR 0x%X, MR 0x%X, SR 0x%x\n", basr, NCR5380_read(MODE_REG), NCR5380_read(STATUS_REG));
-#endif
- (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-#endif
- }
- } /* if BASR_IRQ */
- if (!done)
- run_main();
- } /* if (instance->irq == irq) */
- } while (!done);
-}
-
-/*
- * Function : int NCR5380_select (struct Scsi_Host *instance, Scsi_Cmnd *cmd,
- * int tag);
- *
- * Purpose : establishes I_T_L or I_T_L_Q nexus for new or existing command,
- * including ARBITRATION, SELECTION, and initial message out for
- * IDENTIFY and queue messages.
- *
- * Inputs : instance - instantiation of the 5380 driver on which this
- * target lives, cmd - SCSI command to execute, tag - set to TAG_NEXT for
- * new tag, TAG_NONE for untagged queueing, otherwise set to the tag for
- * the command that is presently connected.
- *
- * Returns : -1 if selection could not execute for some reason,
- * 0 if selection succeeded or failed because the target
- * did not respond.
- *
- * Side effects :
- * If bus busy, arbitration failed, etc, NCR5380_select() will exit
- * with registers as they should have been on entry - ie
- * SELECT_ENABLE will be set appropriately, the NCR5380
- * will cease to drive any SCSI bus signals.
- *
- * If successful : I_T_L or I_T_L_Q nexus will be established,
- * instance->connected will be set to cmd.
- * SELECT interrupt will be disabled.
- *
- * If failed (no target) : cmd->scsi_done() will be called, and the
- * cmd->result host byte set to DID_BAD_TARGET.
- */
-
-static int NCR5380_select (struct Scsi_Host *instance, Scsi_Cmnd *cmd,
- int tag) {
- NCR5380_local_declare();
- struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata*)
- instance->hostdata;
- unsigned char tmp[3], phase;
- unsigned char *data;
- int len;
- unsigned long timeout;
- NCR5380_setup(instance);
-
- hostdata->restart_select = 0;
-#if defined (NDEBUG) && (NDEBUG & NDEBUG_ARBITRATION)
- NCR5380_print(instance);
- printk("scsi%d : starting arbitration, id = %d\n", instance->host_no,
- instance->this_id);
-#endif
- cli();
-
- /*
- * Set the phase bits to 0, otherwise the NCR5380 won't drive the
- * data bus during SELECTION.
- */
-
- NCR5380_write(TARGET_COMMAND_REG, 0);
-
-
- /*
- * Start arbitration.
- */
-
- NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask);
- NCR5380_write(MODE_REG, MR_ARBITRATE);
-
- sti();
-
- /* Wait for arbitration logic to complete */
-#if NCR_TIMEOUT
- {
- unsigned long timeout = jiffies + 2*NCR_TIMEOUT;
-
- while (!(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS)
- && jiffies < timeout)
- ;
- if (jiffies >= timeout)
- {
- printk("scsi: arbitration timeout at %d\n", __LINE__);
- NCR5380_write(MODE_REG, MR_BASE);
- NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
- return -1;
- }
- }
-#else /* NCR_TIMEOUT */
- while (!(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS));
-#endif
-
-#if (NDEBUG & NDEBUG_ARBITRATION)
- printk("scsi%d : arbitration complete\n", instance->host_no);
-/* Avoid GCC 2.4.5 asm needs to many reloads error */
- __asm__("nop");
-#endif
-
- /*
- * The arbitration delay is 2.2us, but this is a minimum and there is
- * no maximum so we can safely sleep for ceil(2.2) usecs to accommodate
- * the integral nature of udelay().
- *
- */
-
- udelay(3);
-
- /* Check for lost arbitration */
- if ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) ||
- (NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_higher_mask) ||
- (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
- NCR5380_write(MODE_REG, MR_BASE);
-#if (NDEBUG & NDEBUG_ARBITRATION)
- printk("scsi%d : lost arbitration, deasserting MR_ARBITRATE\n",
- instance->host_no);
-#endif
- return -1;
- }
-
-
-
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_SEL);
-
- if (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) {
- NCR5380_write(MODE_REG, MR_BASE);
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-#if (NDEBUG & NDEBUG_ARBITRATION)
- printk("scsi%d : lost arbitration, deasserting ICR_ASSERT_SEL\n",
- instance->host_no);
-#endif
- return -1;
- }
-
- /*
- * Again, bus clear + bus settle time is 1.2us, however, this is
- * a minimum so we'll udelay ceil(1.2)
- */
-
- udelay(2);
-
-#if (NDEBUG & NDEBUG_ARBITRATION)
- printk("scsi%d : won arbitration\n", instance->host_no);
-#endif
-
-
- /*
- * Now that we have won arbitration, start Selection process, asserting
- * the host and target ID's on the SCSI bus.
- */
-
- NCR5380_write(OUTPUT_DATA_REG, (hostdata->id_mask | (1 << cmd->target)));
-
- /*
- * Raise ATN while SEL is true before BSY goes false from arbitration,
- * since this is the only way to guarantee that we'll get a MESSAGE OUT
- * phase immediately after selection.
- */
-
- NCR5380_write(INITIATOR_COMMAND_REG, (ICR_BASE | ICR_ASSERT_BSY |
- ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_SEL ));
- NCR5380_write(MODE_REG, MR_BASE);
-
- /*
- * Reselect interrupts must be turned off prior to the dropping of BSY,
- * otherwise we will trigger an interrupt.
- */
- NCR5380_write(SELECT_ENABLE_REG, 0);
-
- /*
- * The initiator shall then wait at least two deskew delays and release
- * the BSY signal.
- */
- udelay(1); /* wingel -- wait two bus deskew delay >2*45ns */
-
- /* Reset BSY */
- NCR5380_write(INITIATOR_COMMAND_REG, (ICR_BASE | ICR_ASSERT_DATA |
- ICR_ASSERT_ATN | ICR_ASSERT_SEL));
-
- /*
- * Something weird happens when we cease to drive BSY - looks
- * like the board/chip is letting us do another read before the
- * appropriate propagation delay has expired, and we're confusing
- * a BSY signal from ourselves as the target's response to SELECTION.
- *
- * A small delay (the 'C++' frontend breaks the pipeline with an
- * unnecessary jump, making it work on my 386-33/Trantor T128, the
- * tighter 'C' code breaks and requires this) solves the problem -
- * the 1 us delay is arbitrary, and only used because this delay will
- * be the same on other platforms and since it works here, it should
- * work there.
- *
- * wingel suggests that this could be due to failing to wait
- * one deskew delay.
- */
-
- udelay(1);
-
-#if (NDEBUG & NDEBUG_SELECTION)
- printk("scsi%d : selecting target %d\n", instance->host_no, cmd->target);
-#endif
-
- /*
- * The SCSI specification calls for a 250 ms timeout for the actual
- * selection.
- */
-
- timeout = jiffies + 25;
-
- /*
- * XXX very interesting - we're seeing a bounce where the BSY we
- * asserted is being reflected / still asserted (propagation delay?)
- * and it's detecting as true. Sigh.
- */
-
- while ((jiffies < timeout) && !(NCR5380_read(STATUS_REG) &
- (SR_BSY | SR_IO)));
-
- if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) ==
- (SR_SEL | SR_IO)) {
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
- NCR5380_reselect(instance);
- printk ("scsi%d : reselection after won arbitration?\n",
- instance->host_no);
- NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
- return -1;
- }
-
- /*
- * No less than two deskew delays after the initiator detects the
- * BSY signal is true, it shall release the SEL signal and may
- * change the DATA BUS. -wingel
- */
-
- udelay(1);
-
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
-
- if (!(NCR5380_read(STATUS_REG) & SR_BSY)) {
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
- if (hostdata->targets_present & (1 << cmd->target)) {
- printk("scsi%d : weirdness\n", instance->host_no);
- if (hostdata->restart_select)
- printk("\trestart select\n");
-#ifdef NDEBUG
- NCR5380_print (instance);
-#endif
- NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
- return -1;
- }
- cmd->result = DID_BAD_TARGET << 16;
- cmd->scsi_done(cmd);
- NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-#if (NDEBUG & NDEBUG_SELECTION)
- printk("scsi%d : target did not respond within 250ms\n",
- instance->host_no);
-#endif
- NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
- return 0;
- }
-
- hostdata->targets_present |= (1 << cmd->target);
-
- /*
- * Since we followed the SCSI spec, and raised ATN while SEL
- * was true but before BSY was false during selection, the information
- * transfer phase should be a MESSAGE OUT phase so that we can send the
- * IDENTIFY message.
- *
- * If SCSI-II tagged queuing is enabled, we also send a SIMPLE_QUEUE_TAG
- * message (2 bytes) with a tag ID that we increment with every command
- * until it wraps back to 0.
- *
- * XXX - it turns out that there are some broken SCSI-II devices,
- * which claim to support tagged queuing but fail when more than
- * some number of commands are issued at once.
- */
-
- /* Wait for start of REQ/ACK handshake */
-#ifdef NCR_TIMEOUT
- {
- unsigned long timeout = jiffies + NCR_TIMEOUT;
-
- while (!(NCR5380_read(STATUS_REG) & SR_REQ) && jiffies < timeout);
-
- if (jiffies >= timeout) {
- printk("scsi%d: timeout at NCR5380.c:%d\n", __LINE__);
- NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
- return -1;
- }
- }
-#else /* NCR_TIMEOUT */
- while (!(NCR5380_read(STATUS_REG) & SR_REQ));
-#endif /* def NCR_TIMEOUT */
-
-#if (NDEBUG & NDEBUG_SELECTION)
- printk("scsi%d : target %d selected, going into MESSAGE OUT phase.\n",
- instance->host_no, cmd->target);
-#endif
- tmp[0] = IDENTIFY(((instance->irq == IRQ_NONE) ? 0 : 1), cmd->lun);
-#ifdef SCSI2
- if (cmd->device->tagged_queue && (tag != TAG_NONE)) {
- tmp[1] = SIMPLE_QUEUE_TAG;
- if (tag == TAG_NEXT) {
- /* 0 is TAG_NONE, used to imply no tag for this command */
- if (cmd->device->current_tag == 0)
- cmd->device->current_tag = 1;
-
- cmd->tag = cmd->device->current_tag;
- cmd->device->current_tag++;
- } else
- cmd->tag = (unsigned char) tag;
-
- tmp[2] = cmd->tag;
- hostdata->last_message = SIMPLE_QUEUE_TAG;
- len = 3;
- } else
-#endif /* def SCSI2 */
- {
- len = 1;
- cmd->tag=0;
- }
-
- /* Send message(s) */
- data = tmp;
- phase = PHASE_MSGOUT;
- NCR5380_transfer_pio(instance, &phase, &len, &data);
-#if (NDEBUG & NDEBUG_SELECTION)
- printk("scsi%d : nexus established.\n", instance->host_no);
-#endif
- /* XXX need to handle errors here */
- hostdata->connected = cmd;
-#ifdef SCSI2
- if (!cmd->device->tagged_queue)
-#endif
- hostdata->busy[cmd->target] |= (1 << cmd->lun);
-
- initialize_SCp(cmd);
-
-
- return 0;
-}
-
-/*
- * Function : int NCR5380_transfer_pio (struct Scsi_Host *instance,
- * unsigned char *phase, int *count, unsigned char **data)
- *
- * Purpose : transfers data in given phase using polled I/O
- *
- * Inputs : instance - instance of driver, *phase - pointer to
- * what phase is expected, *count - pointer to number of
- * bytes to transfer, **data - pointer to data pointer.
- *
- * Returns : -1 when different phase is entered without transferring
- * maximum number of bytes, 0 if all bytes or transfered or exit
- * is in same phase.
- *
- * Also, *phase, *count, *data are modified in place.
- *
- * XXX Note : handling for bus free may be useful.
- */
-
-/*
- * Note : this code is not as quick as it could be, however it
- * IS 100% reliable, and for the actual data transfer where speed
- * counts, we will always do a pseudo DMA or DMA transfer.
- */
-
-static int NCR5380_transfer_pio (struct Scsi_Host *instance,
- unsigned char *phase, int *count, unsigned char **data) {
- NCR5380_local_declare();
- register unsigned char p = *phase, tmp;
- register int c = *count;
- register unsigned char *d = *data;
- NCR5380_setup(instance);
-
-#if (NDEBUG & NDEBUG_PIO)
- if (!(p & SR_IO))
- printk("scsi%d : pio write %d bytes\n", instance->host_no, c);
- else
- printk("scsi%d : pio read %d bytes\n", instance->host_no, c);
-#endif
-
- /*
- * The NCR5380 chip will only drive the SCSI bus when the
- * phase specified in the appropriate bits of the TARGET COMMAND
- * REGISTER match the STATUS REGISTER
- */
-
- NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
-
- do {
- /*
- * Wait for assertion of REQ, after which the phase bits will be
- * valid
- */
- while (!((tmp = NCR5380_read(STATUS_REG)) & SR_REQ));
-
-#if (NDEBUG & NDEBUG_HANDSHAKE)
- printk("scsi%d : REQ detected\n", instance->host_no);
-#endif
-
- /* Check for phase mismatch */
- if ((tmp & PHASE_MASK) != p) {
-#if (NDEBUG & NDEBUG_PIO)
- printk("scsi%d : phase mismatch\n", instance->host_no);
- NCR5380_print_phase(instance);
-#endif
- break;
- }
-
- /* Do actual transfer from SCSI bus to / from memory */
- if (!(p & SR_IO))
- NCR5380_write(OUTPUT_DATA_REG, *d);
- else
- *d = NCR5380_read(CURRENT_SCSI_DATA_REG);
-
- ++d;
-
- /*
- * The SCSI standard suggests that in MSGOUT phase, the initiator
- * should drop ATN on the last byte of the message phase
- * after REQ has been asserted for the handshake but before
- * the initiator raises ACK.
- */
-
- if (!(p & SR_IO)) {
- if (!((p & SR_MSG) && c > 1)) {
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
- ICR_ASSERT_DATA);
-#if (NDEBUG & NDEBUG_PIO)
- NCR5380_print(instance);
-#endif
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
- ICR_ASSERT_DATA | ICR_ASSERT_ACK);
- } else {
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
- ICR_ASSERT_DATA | ICR_ASSERT_ATN);
-#if (NDEBUG & NDEBUG_PIO)
- NCR5380_print(instance);
-#endif
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
- ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
- }
- } else {
-#if (NDEBUG & NDEBUG_PIO)
- NCR5380_print(instance);
-#endif
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ACK);
- }
-
- while (NCR5380_read(STATUS_REG) & SR_REQ);
-
-#if (NDEBUG & NDEBUG_HANDSHAKE)
- printk("scsi%d : req false, handshake complete\n", instance->host_no);
-#endif
-
-/*
- * We have several special cases to consider during REQ/ACK handshaking :
- * 1. We were in MSGOUT phase, and we are on the last byte of the
- * message. ATN must be dropped as ACK is dropped.
- *
- * 2. We are in a MSGIN phase, and we are on the last byte of the
- * message. We must exit with ACK asserted, so that the calling
- * code may raise ATN before dropping ACK to reject the message.
- *
- * 3. ACK and ATN are clear and the target may proceed as normal.
- */
- if (!(p == PHASE_MSGIN && c == 1)) {
- if (p == PHASE_MSGOUT && c > 1)
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
- else
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
- }
- } while (--c);
-
-#if (NDEBUG & NDEBUG_PIO)
- printk("scsi%d : residual %d\n", instance->host_no, c);
-#endif
-
- *count = c;
- *data = d;
- tmp = NCR5380_read(STATUS_REG);
- if (tmp & SR_REQ)
- *phase = tmp & PHASE_MASK;
- else
- *phase = PHASE_UNKNOWN;
-
- if (!c || (*phase == p))
- return 0;
- else
- return -1;
-}
-
-static void do_reset (struct Scsi_Host *host) {
- NCR5380_local_declare();
- NCR5380_setup(host);
-
- cli();
- NCR5380_write(TARGET_COMMAND_REG,
- PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG) & PHASE_MASK));
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST);
- udelay(25);
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
- sti();
-}
-
-/*
- * Function : do_abort (Scsi_Host *host)
- *
- * Purpose : abort the currently established nexus. Should only be
- * called from a routine which can drop into a
- *
- * Returns : 0 on success, -1 on failure.
- */
-
-static int do_abort (struct Scsi_Host *host) {
- NCR5380_local_declare();
- unsigned char tmp, *msgptr, phase;
- int len;
- NCR5380_setup(host);
-
-
- /* Request message out phase */
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
-
- /*
- * Wait for the target to indicate a valid phase by asserting
- * REQ. Once this happens, we'll have either a MSGOUT phase
- * and can immediately send the ABORT message, or we'll have some
- * other phase and will have to source/sink data.
- *
- * We really don't care what value was on the bus or what value
- * the target see's, so we just handshake.
- */
-
- while (!(tmp = NCR5380_read(STATUS_REG)) & SR_REQ);
-
- NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp));
-
- if ((tmp & PHASE_MASK) != PHASE_MSGOUT) {
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN |
- ICR_ASSERT_ACK);
- while (NCR5380_read(STATUS_REG) & SR_REQ);
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
- }
-
- tmp = ABORT;
- msgptr = &tmp;
- len = 1;
- phase = PHASE_MSGOUT;
- NCR5380_transfer_pio (host, &phase, &len, &msgptr);
-
- /*
- * If we got here, and the command completed successfully,
- * we're about to go into bus free state.
- */
-
- return len ? -1 : 0;
-}
-
-#if defined(REAL_DMA) || defined(PSEUDO_DMA) || defined (REAL_DMA_POLL)
-/*
- * Function : int NCR5380_transfer_dma (struct Scsi_Host *instance,
- * unsigned char *phase, int *count, unsigned char **data)
- *
- * Purpose : transfers data in given phase using either real
- * or pseudo DMA.
- *
- * Inputs : instance - instance of driver, *phase - pointer to
- * what phase is expected, *count - pointer to number of
- * bytes to transfer, **data - pointer to data pointer.
- *
- * Returns : -1 when different phase is entered without transferring
- * maximum number of bytes, 0 if all bytes or transfered or exit
- * is in same phase.
- *
- * Also, *phase, *count, *data are modified in place.
- *
- */
-
-
-static int NCR5380_transfer_dma (struct Scsi_Host *instance,
- unsigned char *phase, int *count, unsigned char **data) {
- NCR5380_local_declare();
- register int c = *count;
- register unsigned char p = *phase;
- register unsigned char *d = *data;
- unsigned char tmp;
- int foo;
-#if defined(REAL_DMA_POLL)
- int cnt, toPIO;
- unsigned char saved_data = 0, overrun = 0, residue;
-#endif
-
- struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *)
- instance->hostdata;
-
- NCR5380_setup(instance);
-
- if ((tmp = (NCR5380_read(STATUS_REG) & PHASE_MASK)) != p) {
- *phase = tmp;
- return -1;
- }
-#if defined(REAL_DMA) || defined(REAL_DMA_POLL)
-#ifdef READ_OVERRUNS
- if (p & SR_IO) {
- c -= 2;
- }
-#endif
-#if (NDEBUG & NDEBUG_DMA)
- printk("scsi%d : initializing DMA channel %d for %s, %d bytes %s %0x\n",
- instance->host_no, instance->dma_channel, (p & SR_IO) ? "reading" :
- "writing", c, (p & SR_IO) ? "to" : "from", (unsigned) d);
-#endif
- hostdata->dma_len = (p & SR_IO) ?
- NCR5380_dma_read_setup(instance, d, c) :
- NCR5380_dma_write_setup(instance, d, c);
-#endif
-
- NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
-
-#ifdef REAL_DMA
- NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_ENABLE_EOP_INTR | MR_MONITOR_BSY);
-#elif defined(REAL_DMA_POLL)
- NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE);
-#else
- /*
- * Note : on my sample board, watch-dog timeouts occurred when interrupts
- * were not disabled for the duration of a single DMA transfer, from
- * before the setting of DMA mode to after transfer of the last byte.
- */
-
-#if defined(PSEUDO_DMA) && !defined(UNSAFE)
- cli();
-#endif
- /* KLL May need eop and parity in 53c400 */
- if (hostdata->flags & FLAG_NCR53C400)
- NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_ENABLE_PAR_CHECK
- | MR_ENABLE_PAR_INTR | MR_ENABLE_EOP_INTR | MR_DMA_MODE
- | MR_MONITOR_BSY);
- else
- NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE);
-#endif /* def REAL_DMA */
-
-#if (NDEBUG & NDEBUG_DMA) & 0
- printk("scsi%d : mode reg = 0x%X\n", instance->host_no, NCR5380_read(MODE_REG));
-#endif
-
-/*
- * FOO stuff. For some UNAPPARENT reason, I'm getting
- * watchdog timers fired on bootup for NO APPARENT REASON, meaning it's
- * probably a timing problem.
- *
- * Since this is the only place I have back-to-back writes, perhaps this
- * is the problem?
- */
-
- if (p & SR_IO) {
-#ifndef FOO
- udelay(1);
-#endif
- NCR5380_write(START_DMA_INITIATOR_RECEIVE_REG, 0);
- } else {
-#ifndef FOO
- udelay(1);
-#endif
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA);
-#ifndef FOO
- udelay(1);
-#endif
- NCR5380_write(START_DMA_SEND_REG, 0);
-#ifndef FOO
- udelay(1);
-#endif
- }
-
-#if defined(REAL_DMA_POLL)
- do {
- tmp = NCR5380_read(BUS_AND_STATUS_REG);
- } while ((tmp & BASR_PHASE_MATCH) && !(tmp & (BASR_BUSY_ERROR |
- BASR_END_DMA_TRANSFER)));
-
-/*
- At this point, either we've completed DMA, or we have a phase mismatch,
- or we've unexpectedly lost BUSY (which is a real error).
-
- For write DMAs, we want to wait until the last byte has been
- transferred out over the bus before we turn off DMA mode. Alas, there
- seems to be no terribly good way of doing this on a 5380 under all
- conditions. For non-scatter-gather operations, we can wait until REQ
- and ACK both go false, or until a phase mismatch occurs. Gather-writes
- are nastier, since the device will be expecting more data than we
- are prepared to send it, and REQ will remain asserted. On a 53C8[01] we
- could test LAST BIT SENT to assure transfer (I imagine this is precisely
- why this signal was added to the newer chips) but on the older 538[01]
- this signal does not exist. The workaround for this lack is a watchdog;
- we bail out of the wait-loop after a modest amount of wait-time if
- the usual exit conditions are not met. Not a terribly clean or
- correct solution :-%
-
- Reads are equally tricky due to a nasty characteristic of the NCR5380.
- If the chip is in DMA mode for an READ, it will respond to a target's
- REQ by latching the SCSI data into the INPUT DATA register and asserting
- ACK, even if it has _already_ been notified by the DMA controller that
- the current DMA transfer has completed! If the NCR5380 is then taken
- out of DMA mode, this already-acknowledged byte is lost.
-
- This is not a problem for "one DMA transfer per command" reads, because
- the situation will never arise... either all of the data is DMA'ed
- properly, or the target switches to MESSAGE IN phase to signal a
- disconnection (either operation bringing the DMA to a clean halt).
- However, in order to handle scatter-reads, we must work around the
- problem. The chosen fix is to DMA N-2 bytes, then check for the
- condition before taking the NCR5380 out of DMA mode. One or two extra
- bytes are transferred via PIO as necessary to fill out the original
- request.
-*/
-
- if (p & SR_IO) {
-#ifdef READ_OVERRUNS
- udelay(10);
- if (((NCR5380_read(BUS_AND_STATUS_REG) & (BASR_PHASE_MATCH|BASR_ACK)) ==
- (BASR_PHASE_MATCH | BASR_ACK))) {
- saved_data = NCR5380_read(INPUT_DATA_REGISTER);
- overrun = 1;
- }
-#endif
- } else {
- int limit = 100;
- while (((tmp = NCR5380_read(BUS_AND_STATUS_REG)) & BASR_ACK) ||
- (NCR5380_read(STATUS_REG) & SR_REQ)) {
- if (!(tmp & BASR_PHASE_MATCH)) break;
- if (--limit < 0) break;
- }
- }
-
-
-#if (NDEBUG & NDEBUG_DMA)
- printk("scsi%d : polled DMA transfer complete, basr 0x%X, sr 0x%X\n",
- instance->host_no, tmp, NCR5380_read(STATUS_REG));
-#endif
-
- NCR5380_write(MODE_REG, MR_BASE);
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-
- residue = NCR5380_dma_residual(instance);
- c -= residue;
- *count -= c;
- *data += c;
- *phase = NCR5380_read(STATUS_REG) & PHASE_MASK;
-
-#ifdef READ_OVERRUNS
- if (*phase == p && (p & SR_IO) && residue == 0) {
- if (overrun) {
-#if (NDEBUG & NDEBUG_DMA)
- printk("Got an input overrun, using saved byte\n");
-#endif
- **data = saved_data;
- *data += 1;
- *count -= 1;
- cnt = toPIO = 1;
- } else {
- printk("No overrun??\n");
- cnt = toPIO = 2;
- }
-#if (NDEBUG & NDEBUG_DMA)
- printk("Doing %d-byte PIO to 0x%X\n", cnt, *data);
-#endif
- NCR5380_transfer_pio(instance, phase, &cnt, data);
- *count -= toPIO - cnt;
- }
-#endif
-
-#if (NDEBUG & NDEBUG_DMA)
- printk("Return with data ptr = 0x%X, count %d, last 0x%X, next 0x%X\n",
- *data, *count, *(*data+*count-1), *(*data+*count));
-#endif
- return 0;
-
-#elif defined(REAL_DMA)
- return 0;
-#else /* defined(REAL_DMA_POLL) */
- if (p & SR_IO) {
- int diff = 1;
- if (hostdata->flags & FLAG_NCR53C400) {
- diff=0;
- }
-
- if (!(foo = NCR5380_pread(instance, d, c - diff))) {
- /*
- * We can't disable DMA mode after successfully transferring
- * what we plan to be the last byte, since that would open up
- * a race condition where if the target asserted REQ before
- * we got the DMA mode reset, the NCR5380 would have latched
- * an additional byte into the INPUT DATA register and we'd
- * have dropped it.
- *
- * The workaround was to transfer one fewer bytes than we
- * intended to with the pseudo-DMA read function, wait for
- * the chip to latch the last byte, read it, and then disable
- * pseudo-DMA mode.
- *
- * After REQ is asserted, the NCR5380 asserts DRQ and ACK.
- * REQ is deasserted when ACK is asserted, and not reasserted
- * until ACK goes false. Since the NCR5380 won't lower ACK
- * until DACK is asserted, which won't happen unless we twiddle
- * the DMA port or we take the NCR5380 out of DMA mode, we
- * can guarantee that we won't handshake another extra
- * byte.
- */
-
- if (!(hostdata->flags & FLAG_NCR53C400)) {
- while (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ));
- /* Wait for clean handshake */
- while (NCR5380_read(STATUS_REG) & SR_REQ);
- d[c - 1] = NCR5380_read(INPUT_DATA_REG);
- }
- }
- } else {
- int timeout;
-#if (NDEBUG & NDEBUG_C400_PWRITE)
- printk("About to pwrite %d bytes\n", c);
-#endif
- if (!(foo = NCR5380_pwrite(instance, d, c))) {
- /*
- * Wait for the last byte to be sent. If REQ is being asserted for
- * the byte we're interested, we'll ACK it and it will go false.
- */
- if (!(hostdata->flags & FLAG_HAS_LAST_BYTE_SENT)) {
- timeout = 20000;
-#if 1
-#if 1
- while (!(NCR5380_read(BUS_AND_STATUS_REG) &
- BASR_DRQ) && (NCR5380_read(BUS_AND_STATUS_REG) &
- BASR_PHASE_MATCH));
-#else
- if (NCR5380_read(STATUS_REG) & SR_REQ) {
- for (; timeout &&
- !(NCR5380_read(BUS_AND_STATUS_REG) & BASR_ACK);
- --timeout);
- for (; timeout && (NCR5380_read(STATUS_REG) & SR_REQ);
- --timeout);
- }
-#endif
-
-
-#if (NDEBUG & NDEBUG_LAST_BYTE_SENT)
- if (!timeout)
- printk("scsi%d : timed out on last byte\n",
- instance->host_no);
-#endif
-
-
- if (hostdata->flags & FLAG_CHECK_LAST_BYTE_SENT) {
- hostdata->flags &= ~FLAG_CHECK_LAST_BYTE_SENT;
- if (NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT) {
- hostdata->flags |= FLAG_HAS_LAST_BYTE_SENT;
-#if (NDEBUG & NDEBUG_LAST_BYTE_SENT)
- printk("scsi%d : last bit sent works\n",
- instance->host_no);
-#endif
- }
- }
- } else {
-#if (NDEBUG & NDEBUG_C400_PWRITE)
- printk("Waiting for LASTBYTE\n");
-#endif
- while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT));
-#if (NDEBUG & NDEBUG_C400_PWRITE)
- printk("Got LASTBYTE\n");
-#endif
- }
-#else
- udelay (5);
-#endif
- }
- }
-
- NCR5380_write(MODE_REG, MR_BASE);
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-
- if ((!(p & SR_IO)) && (hostdata->flags & FLAG_NCR53C400)) {
-#if (NDEBUG & NDEBUG_C400_PWRITE)
- printk("53C400w: Checking for IRQ\n");
-#endif
- if (NCR5380_read(BUS_AND_STATUS_REG) & BASR_IRQ) {
-#if (NDEBUG & NDEBUG_C400_PWRITE)
- printk("53C400w: got it, reading reset interupt reg\n");
-#endif
- NCR5380_read(RESET_PARITY_INTERRUPT_REG);
- } else {
- printk("53C400w: IRQ NOT THERE!\n");
- }
- }
-
- *data = d + c;
- *count = 0;
- *phase = (NCR5380_read(STATUS_REG & PHASE_MASK));
-#if 0
- NCR5380_print_phase(instance);
-#endif
-#if defined(PSEUDO_DMA) && !defined(UNSAFE)
- sti();
-#endif /* defined(REAL_DMA_POLL) */
- return foo;
-#endif /* def REAL_DMA */
-}
-#endif /* defined(REAL_DMA) | defined(PSEUDO_DMA) */
-
-/*
- * Function : NCR5380_information_transfer (struct Scsi_Host *instance)
- *
- * Purpose : run through the various SCSI phases and do as the target
- * directs us to. Operates on the currently connected command,
- * instance->connected.
- *
- * Inputs : instance, instance for which we are doing commands
- *
- * Side effects : SCSI things happen, the disconnected queue will be
- * modified if a command disconnects, *instance->connected will
- * change.
- *
- * XXX Note : we need to watch for bus free or a reset condition here
- * to recover from an unexpected bus free condition.
- */
-
-static void NCR5380_information_transfer (struct Scsi_Host *instance) {
- NCR5380_local_declare();
- struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *)
- instance->hostdata;
- unsigned char msgout = NOP;
- int sink = 0;
- int len;
-#if defined(PSEUDO_DMA) || defined(REAL_DMA_POLL)
- int transfersize;
-#endif
- unsigned char *data;
- unsigned char phase, tmp, extended_msg[10], old_phase=0xff;
- Scsi_Cmnd *cmd = (Scsi_Cmnd *) hostdata->connected;
- NCR5380_setup(instance);
-
- while (1) {
- tmp = NCR5380_read(STATUS_REG);
- /* We only have a valid SCSI phase when REQ is asserted */
- if (tmp & SR_REQ) {
- phase = (tmp & PHASE_MASK);
- if (phase != old_phase) {
- old_phase = phase;
-#if (NDEBUG & NDEBUG_INFORMATION)
- NCR5380_print_phase(instance);
-#endif
- }
-
- if (sink && (phase != PHASE_MSGOUT)) {
- NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp));
-
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN |
- ICR_ASSERT_ACK);
- while (NCR5380_read(STATUS_REG) & SR_REQ);
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
- ICR_ASSERT_ATN);
- sink = 0;
- continue;
- }
-
- switch (phase) {
- case PHASE_DATAIN:
- case PHASE_DATAOUT:
-#if (NDEBUG & NDEBUG_NO_DATAOUT)
- printk("scsi%d : NDEBUG_NO_DATAOUT set, attempted DATAOUT aborted\n",
- instance->host_no);
- sink = 1;
- do_abort(instance);
- cmd->result = DID_ERROR << 16;
- cmd->done(cmd);
- return;
-#endif
- /*
- * If there is no room left in the current buffer in the
- * scatter-gather list, move onto the next one.
- */
-
- if (!cmd->SCp.this_residual && cmd->SCp.buffers_residual) {
- ++cmd->SCp.buffer;
- --cmd->SCp.buffers_residual;
- cmd->SCp.this_residual = cmd->SCp.buffer->length;
- cmd->SCp.ptr = cmd->SCp.buffer->address;
-#if (NDEBUG & NDEBUG_INFORMATION)
- printk("scsi%d : %d bytes and %d buffers left\n",
- instance->host_no, cmd->SCp.this_residual,
- cmd->SCp.buffers_residual);
-#endif
- }
-
- /*
- * The preferred transfer method is going to be
- * PSEUDO-DMA for systems that are strictly PIO,
- * since we can let the hardware do the handshaking.
- *
- * For this to work, we need to know the transfersize
- * ahead of time, since the pseudo-DMA code will sit
- * in an unconditional loop.
- */
-
-#if defined(PSEUDO_DMA) || defined(REAL_DMA_POLL)
- /* KLL
- * PSEUDO_DMA is defined here. If this is the g_NCR5380
- * driver then it will always be defined, so the
- * FLAG_NO_PSEUDO_DMA is used to inhibit PDMA in the base
- * NCR5380 case. I think this is a fairly clean solution.
- * We supplement these 2 if's with the flag.
- */
-#ifdef NCR5380_dma_xfer_len
- if (!cmd->device->borken &&
- !(hostdata->flags & FLAG_NO_PSEUDO_DMA) &&
- (transfersize = NCR5380_dma_xfer_len(instance, cmd)) != 0) {
-#else
- transfersize = cmd->transfersize;
-
-#ifdef LIMIT_TRANSFERSIZE /* If we have problems with interrupt service */
- if( transfersize > 512 )
- transfersize = 512;
-#endif /* LIMIT_TRANSFERSIZE */
-
- if (!cmd->device->borken && transfersize &&
- !(hostdata->flags & FLAG_NO_PSEUDO_DMA) &&
- cmd->SCp.this_residual && !(cmd->SCp.this_residual %
- transfersize)) {
-#endif
- len = transfersize;
- if (NCR5380_transfer_dma(instance, &phase,
- &len, (unsigned char **) &cmd->SCp.ptr)) {
- /*
- * If the watchdog timer fires, all future accesses to this
- * device will use the polled-IO.
- */
- printk("scsi%d : switching target %d lun %d to slow handshake\n",
- instance->host_no, cmd->target, cmd->lun);
- cmd->device->borken = 1;
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
- ICR_ASSERT_ATN);
- sink = 1;
- do_abort(instance);
- cmd->result = DID_ERROR << 16;
- cmd->done(cmd);
- /* XXX - need to source or sink data here, as appropriate */
- } else
- cmd->SCp.this_residual -= transfersize - len;
- } else
-#endif /* defined(PSEUDO_DMA) || defined(REAL_DMA_POLL) */
- NCR5380_transfer_pio(instance, &phase,
- (int *) &cmd->SCp.this_residual, (unsigned char **)
- &cmd->SCp.ptr);
- break;
- case PHASE_MSGIN:
- len = 1;
- data = &tmp;
- NCR5380_transfer_pio(instance, &phase, &len, &data);
- cmd->SCp.Message = tmp;
-
- switch (tmp) {
- /*
- * Linking lets us reduce the time required to get the
- * next command out to the device, hopefully this will
- * mean we don't waste another revolution due to the delays
- * required by ARBITRATION and another SELECTION.
- *
- * In the current implementation proposal, low level drivers
- * merely have to start the next command, pointed to by
- * next_link, done() is called as with unlinked commands.
- */
-#ifdef LINKED
- case LINKED_CMD_COMPLETE:
- case LINKED_FLG_CMD_COMPLETE:
- /* Accept message by clearing ACK */
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-
-#if (NDEBUG & NDEBUG_LINKED)
- printk("scsi%d : target %d lun %d linked command complete.\n",
- instance->host_no, cmd->target, cmd->lun);
-#endif
- /*
- * Sanity check : A linked command should only terminate with
- * one of these messages if there are more linked commands
- * available.
- */
-
- if (!cmd->next_link) {
- printk("scsi%d : target %d lun %d linked command complete, no next_link\n"
- instance->host_no, cmd->target, cmd->lun);
- sink = 1;
- do_abort (instance);
- return;
- }
-
- initialize_SCp(cmd->next_link);
- /* The next command is still part of this process */
- cmd->next_link->tag = cmd->tag;
- cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
-#if (NDEBUG & NDEBUG_LINKED)
- printk("scsi%d : target %d lun %d linked request done, calling scsi_done().\n",
- instance->host_no, cmd->target, cmd->lun);
-#endif
- cmd->scsi_done(cmd);
- cmd = hostdata->connected;
- break;
-#endif /* def LINKED */
- case ABORT:
- case COMMAND_COMPLETE:
- /* Accept message by clearing ACK */
- sink = 1;
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
- hostdata->connected = NULL;
-#if (NDEBUG & NDEBUG_QUEUES)
- printk("scsi%d : command for target %d, lun %d completed\n",
- instance->host_no, cmd->target, cmd->lun);
-#endif
- hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
-
- /*
- * I'm not sure what the correct thing to do here is :
- *
- * If the command that just executed is NOT a request
- * sense, the obvious thing to do is to set the result
- * code to the values of the stored parameters.
- *
- * If it was a REQUEST SENSE command, we need some way
- * to differentiate between the failure code of the original
- * and the failure code of the REQUEST sense - the obvious
- * case is success, where we fall through and leave the result
- * code unchanged.
- *
- * The non-obvious place is where the REQUEST SENSE failed
- */
-
- if (cmd->cmnd[0] != REQUEST_SENSE)
- cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
- else if (cmd->SCp.Status != GOOD)
- cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16);
-
-#ifdef AUTOSENSE
- if ((cmd->cmnd[0] != REQUEST_SENSE) &&
- (cmd->SCp.Status == CHECK_CONDITION)) {
-#if (NDEBUG & NDEBUG_AUTOSENSE)
- printk("scsi%d : performing request sense\n",
- instance->host_no);
-#endif
- cmd->cmnd[0] = REQUEST_SENSE;
- cmd->cmnd[1] &= 0xe0;
- cmd->cmnd[2] = 0;
- cmd->cmnd[3] = 0;
- cmd->cmnd[4] = sizeof(cmd->sense_buffer);
- cmd->cmnd[5] = 0;
-
- cmd->SCp.buffer = NULL;
- cmd->SCp.buffers_residual = 0;
- cmd->SCp.ptr = (char *) cmd->sense_buffer;
- cmd->SCp.this_residual = sizeof(cmd->sense_buffer);
-
- cli();
- LIST(cmd,hostdata->issue_queue);
- cmd->host_scribble = (unsigned char *)
- hostdata->issue_queue;
- hostdata->issue_queue = (Scsi_Cmnd *) cmd;
- sti();
-#if (NDEBUG & NDEBUG_QUEUES)
- printk("scsi%d : REQUEST SENSE added to head of issue queue\n",instance->host_no);
-#endif
- } else
-#endif /* def AUTOSENSE */
- cmd->scsi_done(cmd);
-
- NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
- /*
- * Restore phase bits to 0 so an interrupted selection,
- * arbitration can resume.
- */
- NCR5380_write(TARGET_COMMAND_REG, 0);
-
- while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected)
- barrier();
- return;
- case MESSAGE_REJECT:
- /* Accept message by clearing ACK */
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
- switch (hostdata->last_message) {
- case HEAD_OF_QUEUE_TAG:
- case ORDERED_QUEUE_TAG:
- case SIMPLE_QUEUE_TAG:
- cmd->device->tagged_queue = 0;
- hostdata->busy[cmd->target] |= (1 << cmd->lun);
- break;
- default:
- break;
- }
- case DISCONNECT:
- /* Accept message by clearing ACK */
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
- cmd->device->disconnect = 1;
- cli();
- LIST(cmd,hostdata->disconnected_queue);
- cmd->host_scribble = (unsigned char *)
- hostdata->disconnected_queue;
- hostdata->connected = NULL;
- hostdata->disconnected_queue = cmd;
- sti();
-#if (NDEBUG & NDEBUG_QUEUES)
- printk("scsi%d : command for target %d lun %d was moved from connected to"
- " the disconnected_queue\n", instance->host_no,
- cmd->target, cmd->lun);
-#endif
- /*
- * Restore phase bits to 0 so an interrupted selection,
- * arbitration can resume.
- */
- NCR5380_write(TARGET_COMMAND_REG, 0);
-
- /* Enable reselect interrupts */
- NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
- /* Wait for bus free to avoid nasty timeouts */
- while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected)
- barrier();
-#if 0
- NCR5380_print_status(instance);
-#endif
- return;
- /*
- * The SCSI data pointer is *IMPLICITLY* saved on a disconnect
- * operation, in violation of the SCSI spec so we can safely
- * ignore SAVE/RESTORE pointers calls.
- *
- * Unfortunately, some disks violate the SCSI spec and
- * don't issue the required SAVE_POINTERS message before
- * disconnecting, and we have to break spec to remain
- * compatible.
- */
- case SAVE_POINTERS:
- case RESTORE_POINTERS:
- /* Accept message by clearing ACK */
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
- break;
- case EXTENDED_MESSAGE:
-/*
- * Extended messages are sent in the following format :
- * Byte
- * 0 EXTENDED_MESSAGE == 1
- * 1 length (includes one byte for code, doesn't
- * include first two bytes)
- * 2 code
- * 3..length+1 arguments
- *
- * Start the extended message buffer with the EXTENDED_MESSAGE
- * byte, since print_msg() wants the whole thing.
- */
- extended_msg[0] = EXTENDED_MESSAGE;
- /* Accept first byte by clearing ACK */
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-
-#if (NDEBUG & NDEBUG_EXTENDED)
- printk("scsi%d : receiving extended message\n",
- instance->host_no);
-#endif
-
- len = 2;
- data = extended_msg + 1;
- phase = PHASE_MSGIN;
- NCR5380_transfer_pio(instance, &phase, &len, &data);
-
-#if (NDEBUG & NDEBUG_EXTENDED)
- printk("scsi%d : length=%d, code=0x%02x\n",
- instance->host_no, (int) extended_msg[1],
- (int) extended_msg[2]);
-#endif
-
- if (!len && extended_msg[1] <=
- (sizeof (extended_msg) - 1)) {
- /* Accept third byte by clearing ACK */
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
- len = extended_msg[1] - 1;
- data = extended_msg + 3;
- phase = PHASE_MSGIN;
-
- NCR5380_transfer_pio(instance, &phase, &len, &data);
-
-#if (NDEBUG & NDEBUG_EXTENDED)
- printk("scsi%d : message received, residual %d\n",
- instance->host_no, len);
-#endif
-
- switch (extended_msg[2]) {
- case EXTENDED_SDTR:
- case EXTENDED_WDTR:
- case EXTENDED_MODIFY_DATA_POINTER:
- case EXTENDED_EXTENDED_IDENTIFY:
- tmp = 0;
- }
- } else if (len) {
- printk("scsi%d: error receiving extended message\n",
- instance->host_no);
- tmp = 0;
- } else {
- printk("scsi%d: extended message code %02x length %d is too long\n",
- instance->host_no, extended_msg[2], extended_msg[1]);
- tmp = 0;
- }
- /* Fall through to reject message */
-
- /*
- * If we get something weird that we aren't expecting,
- * reject it.
- */
- default:
- if (!tmp) {
- printk("scsi%d: rejecting message ", instance->host_no);
- print_msg (extended_msg);
- printk("\n");
- } else if (tmp != EXTENDED_MESSAGE)
- printk("scsi%d: rejecting unknown message %02x from target %d, lun %d\n",
- instance->host_no, tmp, cmd->target, cmd->lun);
- else
- printk("scsi%d: rejecting unknown extended message code %02x, length %d from target %d, lun %d\n",
- instance->host_no, extended_msg[1], extended_msg[0], cmd->target, cmd->lun);
-
- msgout = MESSAGE_REJECT;
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
- ICR_ASSERT_ATN);
- break;
- } /* switch (tmp) */
- break;
- case PHASE_MSGOUT:
- len = 1;
- data = &msgout;
- hostdata->last_message = msgout;
- NCR5380_transfer_pio(instance, &phase, &len, &data);
- if (msgout == ABORT) {
- hostdata->busy[cmd->target] &= ~(1 << cmd->lun);
- hostdata->connected = NULL;
- cmd->result = DID_ERROR << 16;
- cmd->scsi_done(cmd);
- NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
- return;
- }
- msgout = NOP;
- break;
- case PHASE_CMDOUT:
- len = cmd->cmd_len;
- data = cmd->cmnd;
- /*
- * XXX for performance reasons, on machines with a
- * PSEUDO-DMA architecture we should probably
- * use the dma transfer function.
- */
- NCR5380_transfer_pio(instance, &phase, &len,
- &data);
-#ifdef USLEEP
- if (!disconnect && should_disconnect(cmd->cmnd[0])) {
- hostdata->time_expires = jiffies + USLEEP_SLEEP;
-#if (NDEBUG & NDEBUG_USLEEP)
- printk("scsi%d : issued command, sleeping until %ul\n", instance->host_no,
- hostdata->time_expires);
-#endif
- NCR5380_set_timer (instance);
- return;
- }
-#endif /* def USLEEP */
- break;
- case PHASE_STATIN:
- len = 1;
- data = &tmp;
- NCR5380_transfer_pio(instance, &phase, &len, &data);
- cmd->SCp.Status = tmp;
- break;
- default:
- printk("scsi%d : unknown phase\n", instance->host_no);
-#ifdef NDEBUG
- NCR5380_print(instance);
-#endif
- } /* switch(phase) */
- } /* if (tmp * SR_REQ) */
-#ifdef USLEEP
- else {
- if (!disconnect && hostdata->time_expires && jiffies >
- hostdata->time_expires) {
- hostdata->time_expires = jiffies + USLEEP_SLEEP;
-#if (NDEBUG & NDEBUG_USLEEP)
- printk("scsi%d : poll timed out, sleeping until %ul\n", instance->host_no,
- hostdata->time_expires);
-#endif
- NCR5380_set_timer (instance);
- return;
- }
- }
-#endif
- } /* while (1) */
-}
-
-/*
- * Function : void NCR5380_reselect (struct Scsi_Host *instance)
- *
- * Purpose : does reselection, initializing the instance->connected
- * field to point to the Scsi_Cmnd for which the I_T_L or I_T_L_Q
- * nexus has been reestablished,
- *
- * Inputs : instance - this instance of the NCR5380.
- *
- */
-
-
-static void NCR5380_reselect (struct Scsi_Host *instance) {
- NCR5380_local_declare();
- struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *)
- instance->hostdata;
- unsigned char target_mask;
- unsigned char lun, phase;
- int len;
-#ifdef SCSI2
- unsigned char tag;
-#endif
- unsigned char msg[3];
- unsigned char *data;
- Scsi_Cmnd *tmp = NULL, *prev;
- int abort = 0;
- NCR5380_setup(instance);
-
- /*
- * Disable arbitration, etc. since the host adapter obviously
- * lost, and tell an interrupted NCR5380_select() to restart.
- */
-
- NCR5380_write(MODE_REG, MR_BASE);
- hostdata->restart_select = 1;
-
- target_mask = NCR5380_read(CURRENT_SCSI_DATA_REG) & ~(hostdata->id_mask);
-
-#if (NDEBUG & NDEBUG_RESELECTION)
- printk("scsi%d : reselect\n", instance->host_no);
-#endif
-
- /*
- * At this point, we have detected that our SCSI ID is on the bus,
- * SEL is true and BSY was false for at least one bus settle delay
- * (400 ns).
- *
- * We must assert BSY ourselves, until the target drops the SEL
- * signal.
- */
-
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_BSY);
-
- while (NCR5380_read(STATUS_REG) & SR_SEL);
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-
- /*
- * Wait for target to go into MSGIN.
- */
-
- while (!(NCR5380_read(STATUS_REG) & SR_REQ));
-
- len = 1;
- data = msg;
- phase = PHASE_MSGIN;
- NCR5380_transfer_pio(instance, &phase, &len, &data);
-
-
- if (!msg[0] & 0x80) {
- printk("scsi%d : expecting IDENTIFY message, got ",
- instance->host_no);
- print_msg(msg);
- abort = 1;
- } else {
- /* Accept message by clearing ACK */
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
- lun = (msg[0] & 0x07);
-
- /*
- * We need to add code for SCSI-II to track which devices have
- * I_T_L_Q nexuses established, and which have simple I_T_L
- * nexuses so we can chose to do additional data transfer.
- */
-
-#ifdef SCSI2
-#error "SCSI-II tagged queueing is not supported yet"
-#endif
-
- /*
- * Find the command corresponding to the I_T_L or I_T_L_Q nexus we
- * just reestablished, and remove it from the disconnected queue.
- */
-
-
- for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue, prev = NULL;
- tmp; prev = tmp, tmp = (Scsi_Cmnd *) tmp->host_scribble)
- if ((target_mask == (1 << tmp->target)) && (lun == tmp->lun)
-#ifdef SCSI2
- && (tag == tmp->tag)
-#endif
-) {
- if (prev) {
- REMOVE(prev,prev->host_scribble,tmp,tmp->host_scribble);
- prev->host_scribble = tmp->host_scribble;
- } else {
- REMOVE(-1,hostdata->disconnected_queue,tmp,tmp->host_scribble);
- hostdata->disconnected_queue = (Scsi_Cmnd *) tmp->host_scribble;
- }
- tmp->host_scribble = NULL;
- break;
- }
-
- if (!tmp) {
-#ifdef SCSI2
- printk("scsi%d : warning : target bitmask %02x lun %d tag %d not in disconnect_queue.\n",
- instance->host_no, target_mask, lun, tag);
-#else
- printk("scsi%d : warning : target bitmask %02x lun %d not in disconnect_queue.\n",
- instance->host_no, target_mask, lun);
-#endif
- /*
- * Since we have an established nexus that we can't do anything with,
- * we must abort it.
- */
- abort = 1;
- }
- }
-
- if (abort) {
- do_abort (instance);
- } else {
- hostdata->connected = tmp;
-#if (NDEBUG & NDEBUG_RESELECTION)
- printk("scsi%d : nexus established, target = %d, lun = %d, tag = %d\n",
- instance->host_no, tmp->target, tmp->lun, tmp->tag);
-#endif
- }
-}
-
-/*
- * Function : void NCR5380_dma_complete (struct Scsi_Host *instance)
- *
- * Purpose : called by interrupt handler when DMA finishes or a phase
- * mismatch occurs (which would finish the DMA transfer).
- *
- * Inputs : instance - this instance of the NCR5380.
- *
- * Returns : pointer to the Scsi_Cmnd structure for which the I_T_L
- * nexus has been reestablished, on failure NULL is returned.
- */
-
-#ifdef REAL_DMA
-static void NCR5380_dma_complete (NCR5380_instance *instance) {
- NCR5380_local_declare();
- struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *
- instance->hostdata);
- int transferred;
- NCR5380_setup(instance);
-
- /*
- * XXX this might not be right.
- *
- * Wait for final byte to transfer, ie wait for ACK to go false.
- *
- * We should use the Last Byte Sent bit, unfortunately this is
- * not available on the 5380/5381 (only the various CMOS chips)
- */
-
- while (NCR5380_read(BUS_AND_STATUS_REG) & BASR_ACK);
-
- NCR5380_write(MODE_REG, MR_BASE);
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-
- /*
- * The only places we should see a phase mismatch and have to send
- * data from the same set of pointers will be the data transfer
- * phases. So, residual, requested length are only important here.
- */
-
- if (!(hostdata->connected->SCp.phase & SR_CD)) {
- transferred = instance->dmalen - NCR5380_dma_residual();
- hostdata->connected->SCp.this_residual -= transferred;
- hostdata->connected->SCp.ptr += transferred;
- }
-}
-#endif /* def REAL_DMA */
-
-/*
- * Function : int NCR5380_abort (Scsi_Cmnd *cmd)
- *
- * Purpose : abort a command
- *
- * Inputs : cmd - the Scsi_Cmnd to abort, code - code to set the
- * host byte of the result field to, if zero DID_ABORTED is
- * used.
- *
- * Returns : 0 - success, -1 on failure.
- *
- * XXX - there is no way to abort the command that is currently
- * connected, you have to wait for it to complete. If this is
- * a problem, we could implement longjmp() / setjmp(), setjmp()
- * called where the loop started in NCR5380_main().
- */
-
-#ifndef NCR5380_abort
-static
-#endif
-int NCR5380_abort (Scsi_Cmnd *cmd) {
- NCR5380_local_declare();
- struct Scsi_Host *instance = cmd->host;
- struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *)
- instance->hostdata;
- Scsi_Cmnd *tmp, **prev;
-
- printk("scsi%d : aborting command\n", instance->host_no);
- print_Scsi_Cmnd (cmd);
-
- NCR5380_print_status (instance);
-
- printk("scsi%d : aborting command\n", instance->host_no);
- print_Scsi_Cmnd (cmd);
-
- NCR5380_print_status (instance);
-
- cli();
- NCR5380_setup(instance);
-
-#if (NDEBUG & NDEBUG_ABORT)
- printk("scsi%d : abort called\n", instance->host_no);
- printk(" basr 0x%X, sr 0x%X\n",
- NCR5380_read(BUS_AND_STATUS_REG), NCR5380_read(STATUS_REG));
-#endif
-
-#if 0
-/*
- * Case 1 : If the command is the currently executing command,
- * we'll set the aborted flag and return control so that
- * information transfer routine can exit cleanly.
- */
-
- if (hostdata->connected == cmd) {
-#if (NDEBUG & NDEBUG_ABORT)
- printk("scsi%d : aborting connected command\n", instance->host_no);
-#endif
- hostdata->aborted = 1;
-/*
- * We should perform BSY checking, and make sure we haven't slipped
- * into BUS FREE.
- */
-
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_ASSERT_ATN);
-/*
- * Since we can't change phases until we've completed the current
- * handshake, we have to source or sink a byte of data if the current
- * phase is not MSGOUT.
- */
-
-/*
- * Return control to the executing NCR drive so we can clear the
- * aborted flag and get back into our main loop.
- */
-
- return 0;
- }
-#endif
-
-/*
- * Case 2 : If the command hasn't been issued yet, we simply remove it
- * from the issue queue.
- */
-#if (NDEBUG & NDEBUG_ABORT)
- /* KLL */
- printk("scsi%d : abort going into loop.\n", instance->host_no);
-#endif
- for (prev = (Scsi_Cmnd **) &(hostdata->issue_queue),
- tmp = (Scsi_Cmnd *) hostdata->issue_queue;
- tmp; prev = (Scsi_Cmnd **) &(tmp->host_scribble), tmp =
- (Scsi_Cmnd *) tmp->host_scribble)
- if (cmd == tmp) {
- REMOVE(5,*prev,tmp,tmp->host_scribble);
- (*prev) = (Scsi_Cmnd *) tmp->host_scribble;
- tmp->host_scribble = NULL;
- tmp->result = DID_ABORT << 16;
- sti();
-#if (NDEBUG & NDEBUG_ABORT)
- printk("scsi%d : abort removed command from issue queue.\n",
- instance->host_no);
-#endif
- tmp->done(tmp);
- return SCSI_ABORT_SUCCESS;
- }
-#if (NDEBUG & NDEBUG_ABORT)
- /* KLL */
- else if (prev == tmp) printk("scsi%d : LOOP\n", instance->host_no);
-#endif
-
-/*
- * Case 3 : If any commands are connected, we're going to fail the abort
- * and let the high level SCSI driver retry at a later time or
- * issue a reset.
- *
- * Timeouts, and therefore aborted commands, will be highly unlikely
- * and handling them cleanly in this situation would make the common
- * case of noresets less efficient, and would pollute our code. So,
- * we fail.
- */
-
- if (hostdata->connected) {
- sti();
-#if (NDEBUG & NDEBUG_ABORT)
- printk("scsi%d : abort failed, command connected.\n", instance->host_no);
-#endif
- return SCSI_ABORT_NOT_RUNNING;
- }
-
-/*
- * Case 4: If the command is currently disconnected from the bus, and
- * there are no connected commands, we reconnect the I_T_L or
- * I_T_L_Q nexus associated with it, go into message out, and send
- * an abort message.
- *
- * This case is especially ugly. In order to reestablish the nexus, we
- * need to call NCR5380_select(). The easiest way to implement this
- * function was to abort if the bus was busy, and let the interrupt
- * handler triggered on the SEL for reselect take care of lost arbitrations
- * where necessary, meaning interrupts need to be enabled.
- *
- * When interrupts are enabled, the queues may change - so we
- * can't remove it from the disconnected queue before selecting it
- * because that could cause a failure in hashing the nexus if that
- * device reselected.
- *
- * Since the queues may change, we can't use the pointers from when we
- * first locate it.
- *
- * So, we must first locate the command, and if NCR5380_select()
- * succeeds, then issue the abort, relocate the command and remove
- * it from the disconnected queue.
- */
-
- for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue; tmp;
- tmp = (Scsi_Cmnd *) tmp->host_scribble)
- if (cmd == tmp) {
- sti();
-#if (NDEBUG & NDEBUG_ABORT)
- printk("scsi%d : aborting disconnected command.\n", instance->host_no);
-#endif
-
- if (NCR5380_select (instance, cmd, (int) cmd->tag))
- return SCSI_ABORT_BUSY;
-
-#if (NDEBUG & NDEBUG_ABORT)
- printk("scsi%d : nexus reestablished.\n", instance->host_no);
-#endif
-
- do_abort (instance);
-
- cli();
- for (prev = (Scsi_Cmnd **) &(hostdata->disconnected_queue),
- tmp = (Scsi_Cmnd *) hostdata->disconnected_queue;
- tmp; prev = (Scsi_Cmnd **) &(tmp->host_scribble), tmp =
- (Scsi_Cmnd *) tmp->host_scribble)
- if (cmd == tmp) {
- REMOVE(5,*prev,tmp,tmp->host_scribble);
- *prev = (Scsi_Cmnd *) tmp->host_scribble;
- tmp->host_scribble = NULL;
- tmp->result = DID_ABORT << 16;
- sti();
- tmp->done(tmp);
- return SCSI_ABORT_SUCCESS;
- }
- }
-
-/*
- * Case 5 : If we reached this point, the command was not found in any of
- * the queues.
- *
- * We probably reached this point because of an unlikely race condition
- * between the command completing successfully and the abortion code,
- * so we won't panic, but we will notify the user in case something really
- * broke.
- */
-
- sti();
- printk("scsi%d : warning : SCSI command probably completed successfully\n"
- " before abortion\n", instance->host_no);
- return SCSI_ABORT_NOT_RUNNING;
-}
-
-
-/*
- * Function : int NCR5380_reset (Scsi_Cmnd *cmd)
- *
- * Purpose : reset the SCSI bus.
- *
- * Returns : SCSI_RESET_WAKEUP
- *
- */
-
-#ifndef NCR5380_reset
-static
-#endif
-int NCR5380_reset (Scsi_Cmnd *cmd) {
- NCR5380_local_declare();
- NCR5380_setup(cmd->host);
-
- NCR5380_print_status (cmd->host);
- do_reset (cmd->host);
-
- return SCSI_RESET_WAKEUP;
-}
-
diff --git a/i386/i386at/gpl/linux/scsi/NCR53c406a.c b/i386/i386at/gpl/linux/scsi/NCR53c406a.c
deleted file mode 100644
index 3105b1bb..00000000
--- a/i386/i386at/gpl/linux/scsi/NCR53c406a.c
+++ /dev/null
@@ -1,1079 +0,0 @@
-/*
- * NCR53c406.c
- * Low-level SCSI driver for NCR53c406a chip.
- * Copyright (C) 1994, 1995, 1996 Normunds Saumanis (normunds@fi.ibm.com)
- *
- * LILO command line usage: ncr53c406a=<PORTBASE>[,<IRQ>[,<FASTPIO>]]
- * Specify IRQ = 0 for non-interrupt driven mode.
- * FASTPIO = 1 for fast pio mode, 0 for slow mode.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- */
-
-#define NCR53C406A_DEBUG 0
-#define VERBOSE_NCR53C406A_DEBUG 0
-
-/* Set this to 1 for PIO mode (recommended) or to 0 for DMA mode */
-#define USE_PIO 1
-
-#define USE_BIOS 0
-/* #define BIOS_ADDR 0xD8000 */ /* define this if autoprobe fails */
-/* #define PORT_BASE 0x330 */ /* define this if autoprobe fails */
-/* #define IRQ_LEV 0 */ /* define this if autoprobe fails */
-#define DMA_CHAN 5 /* this is ignored if DMA is disabled */
-
-/* Set this to 0 if you encounter kernel lockups while transferring
- * data in PIO mode */
-#define USE_FAST_PIO 1
-
-/* ============= End of user configurable parameters ============= */
-
-#include <linux/module.h>
-
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/proc_fs.h>
-#include <linux/stat.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <asm/bitops.h>
-#include <asm/irq.h>
-
-#include <linux/blk.h>
-#include "scsi.h"
-#include "hosts.h"
-#include "sd.h"
-
-#include "NCR53c406a.h"
-
-/* ============================================================= */
-
-#define WATCHDOG 5000000
-
-#define SYNC_MODE 0 /* Synchrounous transfer mode */
-
-#if DEBUG
-#undef NCR53C406A_DEBUG
-#define NCR53C406A_DEBUG 1
-#endif
-
-#if USE_PIO
-#define USE_DMA 0
-#else
-#define USE_DMA 1
-#endif
-
-/* Default configuration */
-#define C1_IMG 0x07 /* ID=7 */
-#define C2_IMG 0x48 /* FE SCSI2 */
-#if USE_DMA
-#define C3_IMG 0x21 /* CDB TE */
-#else
-#define C3_IMG 0x20 /* CDB */
-#endif
-#define C4_IMG 0x04 /* ANE */
-#define C5_IMG 0xb6 /* AA PI SIE POL */
-
-#define REG0 (outb(C4_IMG, CONFIG4))
-#define REG1 (outb(C5_IMG, CONFIG5))
-
-#if NCR53C406A_DEBUG
-#define DEB(x) x
-#else
-#define DEB(x)
-#endif
-
-#if VERBOSE_NCR53C406A_DEBUG
-#define VDEB(x) x
-#else
-#define VDEB(x)
-#endif
-
-#define LOAD_DMA_COUNT(count) \
- outb(count & 0xff, TC_LSB); \
- outb((count >> 8) & 0xff, TC_MSB); \
- outb((count >> 16) & 0xff, TC_HIGH);
-
-/* Chip commands */
-#define DMA_OP 0x80
-
-#define SCSI_NOP 0x00
-#define FLUSH_FIFO 0x01
-#define CHIP_RESET 0x02
-#define SCSI_RESET 0x03
-#define RESELECT 0x40
-#define SELECT_NO_ATN 0x41
-#define SELECT_ATN 0x42
-#define SELECT_ATN_STOP 0x43
-#define ENABLE_SEL 0x44
-#define DISABLE_SEL 0x45
-#define SELECT_ATN3 0x46
-#define RESELECT3 0x47
-#define TRANSFER_INFO 0x10
-#define INIT_CMD_COMPLETE 0x11
-#define MSG_ACCEPT 0x12
-#define TRANSFER_PAD 0x18
-#define SET_ATN 0x1a
-#define RESET_ATN 0x1b
-#define SEND_MSG 0x20
-#define SEND_STATUS 0x21
-#define SEND_DATA 0x22
-#define DISCONN_SEQ 0x23
-#define TERMINATE_SEQ 0x24
-#define TARG_CMD_COMPLETE 0x25
-#define DISCONN 0x27
-#define RECV_MSG 0x28
-#define RECV_CMD 0x29
-#define RECV_DATA 0x2a
-#define RECV_CMD_SEQ 0x2b
-#define TARGET_ABORT_DMA 0x04
-
-/*----------------------------------------------------------------*/
-/* the following will set the monitor border color (useful to find
- where something crashed or gets stuck at */
-/* 1 = blue
- 2 = green
- 3 = cyan
- 4 = red
- 5 = magenta
- 6 = yellow
- 7 = white
-*/
-
-#if NCR53C406A_DEBUG
-#define rtrc(i) {inb(0x3da);outb(0x31,0x3c0);outb((i),0x3c0);}
-#else
-#define rtrc(i) {}
-#endif
-/*----------------------------------------------------------------*/
-
-enum Phase {
- idle,
- data_out,
- data_in,
- command_ph,
- status_ph,
- message_out,
- message_in
-};
-
-/* Static function prototypes */
-static void NCR53c406a_intr(int, struct pt_regs *);
-static void internal_done(Scsi_Cmnd *);
-static void wait_intr(void);
-static void chip_init(void);
-static void calc_port_addr(void);
-#ifndef IRQ_LEV
-static int irq_probe(void);
-#endif
-
-/* ================================================================= */
-
-#if USE_BIOS
-static void *bios_base = (void *)0;
-#endif
-
-#if PORT_BASE
-static int port_base = PORT_BASE;
-#else
-static int port_base = 0;
-#endif
-
-#if IRQ_LEV
-static int irq_level = IRQ_LEV;
-#else
-static int irq_level = -1; /* 0 is 'no irq', so use -1 for 'uninitialized'*/
-#endif
-
-#if USE_DMA
-static int dma_chan = 0;
-#endif
-
-#if USE_PIO
-static int fast_pio = USE_FAST_PIO;
-#endif
-
-static Scsi_Cmnd *current_SC = NULL;
-static volatile int internal_done_flag = 0;
-static volatile int internal_done_errcode = 0;
-static char info_msg[256];
-
-struct proc_dir_entry proc_scsi_NCR53c406a = {
- PROC_SCSI_NCR53C406A, 7, "NCR53c406a",
- S_IFDIR | S_IRUGO | S_IXUGO, 2
-};
-/* ================================================================= */
-
-/* possible BIOS locations */
-#if USE_BIOS
-static void *addresses[] = {
- (void *)0xd8000,
- (void *)0xc8000
-};
-#define ADDRESS_COUNT (sizeof( addresses ) / sizeof( unsigned ))
-#endif USE_BIOS
-
-/* possible i/o port addresses */
-static unsigned short ports[] = { 0x230, 0x330 };
-#define PORT_COUNT (sizeof( ports ) / sizeof( unsigned short ))
-
-/* possible interrupt channels */
-static unsigned short intrs[] = { 10, 11, 12, 15 };
-#define INTR_COUNT (sizeof( intrs ) / sizeof( unsigned short ))
-
-/* signatures for NCR 53c406a based controllers */
-#if USE_BIOS
-struct signature {
- char *signature;
- int sig_offset;
- int sig_length;
-} signatures[] = {
- /* 1 2 3 4 5 6 */
- /* 123456789012345678901234567890123456789012345678901234567890 */
- { "Copyright (C) Acculogic, Inc.\r\n2.8M Diskette Extension Bios ver 4.04.03 03/01/1993", 61, 82 },
-};
-#define SIGNATURE_COUNT (sizeof( signatures ) / sizeof( struct signature ))
-#endif USE_BIOS
-
-/* ============================================================ */
-
-/* Control Register Set 0 */
-static int TC_LSB; /* transfer counter lsb */
-static int TC_MSB; /* transfer counter msb */
-static int SCSI_FIFO; /* scsi fifo register */
-static int CMD_REG; /* command register */
-static int STAT_REG; /* status register */
-static int DEST_ID; /* selection/reselection bus id */
-static int INT_REG; /* interrupt status register */
-static int SRTIMOUT; /* select/reselect timeout reg */
-static int SEQ_REG; /* sequence step register */
-static int SYNCPRD; /* synchronous transfer period */
-static int FIFO_FLAGS; /* indicates # of bytes in fifo */
-static int SYNCOFF; /* synchronous offset register */
-static int CONFIG1; /* configuration register */
-static int CLKCONV; /* clock conversion reg */
-/*static int TESTREG;*/ /* test mode register */
-static int CONFIG2; /* Configuration 2 Register */
-static int CONFIG3; /* Configuration 3 Register */
-static int CONFIG4; /* Configuration 4 Register */
-static int TC_HIGH; /* Transfer Counter High */
-/*static int FIFO_BOTTOM;*/ /* Reserve FIFO byte register */
-
-/* Control Register Set 1 */
-/*static int JUMPER_SENSE;*/ /* Jumper sense port reg (r/w) */
-/*static int SRAM_PTR;*/ /* SRAM address pointer reg (r/w) */
-/*static int SRAM_DATA;*/ /* SRAM data register (r/w) */
-static int PIO_FIFO; /* PIO FIFO registers (r/w) */
-/*static int PIO_FIFO1;*/ /* */
-/*static int PIO_FIFO2;*/ /* */
-/*static int PIO_FIFO3;*/ /* */
-static int PIO_STATUS; /* PIO status (r/w) */
-/*static int ATA_CMD;*/ /* ATA command/status reg (r/w) */
-/*static int ATA_ERR;*/ /* ATA features/error register (r/w)*/
-static int PIO_FLAG; /* PIO flag interrupt enable (r/w) */
-static int CONFIG5; /* Configuration 5 register (r/w) */
-/*static int SIGNATURE;*/ /* Signature Register (r) */
-/*static int CONFIG6;*/ /* Configuration 6 register (r) */
-
-/* ============================================================== */
-
-#if USE_DMA
-static __inline__ int
-NCR53c406a_dma_setup (unsigned char *ptr,
- unsigned int count,
- unsigned char mode) {
- unsigned limit;
- unsigned long flags = 0;
-
- VDEB(printk("dma: before count=%d ", count));
- if (dma_chan <=3) {
- if (count > 65536)
- count = 65536;
- limit = 65536 - (((unsigned) ptr) & 0xFFFF);
- } else {
- if (count > (65536<<1))
- count = (65536<<1);
- limit = (65536<<1) - (((unsigned) ptr) & 0x1FFFF);
- }
-
- if (count > limit) count = limit;
-
- VDEB(printk("after count=%d\n", count));
- if ((count & 1) || (((unsigned) ptr) & 1))
- panic ("NCR53c406a: attempted unaligned DMA transfer\n");
-
- save_flags(flags);
- cli();
- disable_dma(dma_chan);
- clear_dma_ff(dma_chan);
- set_dma_addr(dma_chan, (long) ptr);
- set_dma_count(dma_chan, count);
- set_dma_mode(dma_chan, mode);
- enable_dma(dma_chan);
- restore_flags(flags);
-
- return count;
-}
-
-static __inline__ int
-NCR53c406a_dma_write(unsigned char *src, unsigned int count) {
- return NCR53c406a_dma_setup (src, count, DMA_MODE_WRITE);
-}
-
-static __inline__ int
-NCR53c406a_dma_read(unsigned char *src, unsigned int count) {
- return NCR53c406a_dma_setup (src, count, DMA_MODE_READ);
-}
-
-static __inline__ int
-NCR53c406a_dma_residual (void) {
- register int tmp;
- unsigned long flags = 0;
- save_flags(flags);
- cli();
- clear_dma_ff(dma_chan);
- tmp = get_dma_residue(dma_chan);
- restore_flags(flags);
-
- return tmp;
-}
-#endif USE_DMA
-
-#if USE_PIO
-static __inline__ int NCR53c406a_pio_read(unsigned char *request,
- unsigned int reqlen)
-{
- int i;
- int len; /* current scsi fifo size */
- unsigned long flags = 0;
-
- REG1;
- while (reqlen) {
- i = inb(PIO_STATUS);
- /* VDEB(printk("pio_status=%x\n", i)); */
- if (i & 0x80)
- return 0;
-
- switch( i & 0x1e ) {
- default:
- case 0x10:
- len=0; break;
- case 0x0:
- len=1; break;
- case 0x8:
- len=42; break;
- case 0xc:
- len=84; break;
- case 0xe:
- len=128; break;
- }
-
- if ((i & 0x40) && len == 0) { /* fifo empty and interrupt occured */
- return 0;
- }
-
- if (len) {
- if( len > reqlen )
- len = reqlen;
-
- save_flags(flags);
- cli();
- if( fast_pio && len > 3 ) {
- insl(PIO_FIFO,request,len>>2);
- request += len & 0xfc;
- reqlen -= len & 0xfc;
- }
- else {
- while(len--) {
- *request++ = inb(PIO_FIFO);
- reqlen--;
- }
- }
- restore_flags(flags);
- }
- }
- return 0;
-}
-
-static __inline__ int NCR53c406a_pio_write(unsigned char *request,
- unsigned int reqlen)
-{
- int i = 0;
- int len; /* current scsi fifo size */
- unsigned long flags = 0;
-
- REG1;
- while (reqlen && !(i&0x40)) {
- i = inb(PIO_STATUS);
- /* VDEB(printk("pio_status=%x\n", i)); */
- if (i & 0x80) /* error */
- return 0;
-
- switch( i & 0x1e ) {
- case 0x10:
- len=128; break;
- case 0x0:
- len=84; break;
- case 0x8:
- len=42; break;
- case 0xc:
- len=1; break;
- default:
- case 0xe:
- len=0; break;
- }
-
- if (len) {
- if( len > reqlen )
- len = reqlen;
-
- save_flags(flags);
- cli();
- if( fast_pio && len > 3 ) {
- outsl(PIO_FIFO,request,len>>2);
- request += len & 0xfc;
- reqlen -= len & 0xfc;
- }
- else {
- while(len--) {
- outb(*request++, PIO_FIFO);
- reqlen--;
- }
- }
- restore_flags(flags);
- }
- }
- return 0;
-}
-#endif USE_PIO
-
-int
-NCR53c406a_detect(Scsi_Host_Template * tpnt){
- struct Scsi_Host *shpnt;
-#ifndef PORT_BASE
- int i;
-#endif
-
-#if USE_BIOS
- int ii, jj;
- bios_base = 0;
- /* look for a valid signature */
- for( ii=0; ii < ADDRESS_COUNT && !bios_base; ii++)
- for( jj=0; (jj < SIGNATURE_COUNT) && !bios_base; jj++)
- if(!memcmp((void *) addresses[ii]+signatures[jj].sig_offset,
- (void *) signatures[jj].signature,
- (int) signatures[jj].sig_length))
- bios_base=addresses[ii];
-
- if(!bios_base){
- printk("NCR53c406a: BIOS signature not found\n");
- return 0;
- }
-
- DEB(printk("NCR53c406a BIOS found at %X\n", (unsigned int) bios_base););
-#endif USE_BIOS
-
-#ifdef PORT_BASE
- if (check_region(port_base, 0x10)) /* ports already snatched */
- port_base = 0;
-
-#else /* autodetect */
- if (port_base) { /* LILO override */
- if (check_region(port_base, 0x10))
- port_base = 0;
- }
- else {
- for(i=0; i<PORT_COUNT && !port_base; i++){
- if(check_region(ports[i], 0x10)){
- DEB(printk("NCR53c406a: port %x in use\n", ports[i]));
- }
- else {
- VDEB(printk("NCR53c406a: port %x available\n", ports[i]));
- outb(C5_IMG, ports[i] + 0x0d); /* reg set 1 */
- if( (inb(ports[i] + 0x0e) ^ inb(ports[i] + 0x0e)) == 7
- && (inb(ports[i] + 0x0e) ^ inb(ports[i] + 0x0e)) == 7
- && (inb(ports[i] + 0x0e) & 0xf8) == 0x58 ) {
- VDEB(printk("NCR53c406a: Sig register valid\n"));
- VDEB(printk("port_base=%x\n", port_base));
- port_base = ports[i];
- }
- }
- }
- }
-#endif PORT_BASE
-
- if(!port_base){ /* no ports found */
- printk("NCR53c406a: no available ports found\n");
- return 0;
- }
-
- DEB(printk("NCR53c406a detected\n"));
-
- calc_port_addr();
- chip_init();
-
-#ifndef IRQ_LEV
- if (irq_level < 0) { /* LILO override if >= 0*/
- irq_level=irq_probe();
- if (irq_level < 0) { /* Trouble */
- printk("NCR53c406a: IRQ problem, irq_level=%d, giving up\n", irq_level);
- return 0;
- }
- }
-#endif
-
- DEB(printk("NCR53c406a: using port_base %x\n", port_base));
- request_region(port_base, 0x10, "NCR53c406a");
-
- if(irq_level > 0) {
- if(request_irq(irq_level, NCR53c406a_intr, 0, "NCR53c406a")){
- printk("NCR53c406a: unable to allocate IRQ %d\n", irq_level);
- return 0;
- }
- tpnt->can_queue = 1;
- DEB(printk("NCR53c406a: allocated IRQ %d\n", irq_level));
- }
- else if (irq_level == 0) {
- tpnt->can_queue = 0;
- DEB(printk("NCR53c406a: No interrupts detected\n"));
-#if USE_DMA
- printk("NCR53c406a: No interrupts found and DMA mode defined. Giving up.\n");
- return 0;
-#endif USE_DMA
- }
- else {
- DEB(printk("NCR53c406a: Shouldn't get here!\n"));
- return 0;
- }
-
-#if USE_DMA
- dma_chan = DMA_CHAN;
- if(request_dma(dma_chan, "NCR53c406a") != 0){
- printk("NCR53c406a: unable to allocate DMA channel %d\n", dma_chan);
- return 0;
- }
-
- DEB(printk("Allocated DMA channel %d\n", dma_chan));
-#endif USE_DMA
-
- tpnt->present = 1;
- tpnt->proc_dir = &proc_scsi_NCR53c406a;
-
- shpnt = scsi_register(tpnt, 0);
- shpnt->irq = irq_level;
- shpnt->io_port = port_base;
- shpnt->n_io_port = 0x10;
-#if USE_DMA
- shpnt->dma = dma_chan;
-#endif
-
-#if USE_DMA
- sprintf(info_msg, "NCR53c406a at 0x%x, IRQ %d, DMA channel %d.",
- port_base, irq_level, dma_chan);
-#else
- sprintf(info_msg, "NCR53c406a at 0x%x, IRQ %d, %s PIO mode.",
- port_base, irq_level, fast_pio ? "fast" : "slow");
-#endif
-
- return (tpnt->present);
-}
-
-/* called from init/main.c */
-void NCR53c406a_setup(char *str, int *ints)
-{
- static size_t setup_idx = 0;
- size_t i;
-
- DEB(printk("NCR53c406a: Setup called\n"););
-
- if (setup_idx >= PORT_COUNT - 1) {
- printk("NCR53c406a: Setup called too many times. Bad LILO params?\n");
- return;
- }
- if (ints[0] < 1 || ints[0] > 3) {
- printk("NCR53c406a: Malformed command line\n");
- printk("NCR53c406a: Usage: ncr53c406a=<PORTBASE>[,<IRQ>[,<FASTPIO>]]\n");
- return;
- }
- for (i = 0; i < PORT_COUNT && !port_base; i++)
- if (ports[i] == ints[1]) {
- port_base = ints[1];
- DEB(printk("NCR53c406a: Specified port_base 0x%X\n", port_base);)
- }
- if (!port_base) {
- printk("NCR53c406a: Invalid PORTBASE 0x%X specified\n", ints[1]);
- return;
- }
-
- if (ints[0] > 1) {
- if (ints[2] == 0) {
- irq_level = 0;
- DEB(printk("NCR53c406a: Specified irq %d\n", irq_level);)
- }
- else
- for (i = 0; i < INTR_COUNT && irq_level < 0; i++)
- if (intrs[i] == ints[2]) {
- irq_level = ints[2];
- DEB(printk("NCR53c406a: Specified irq %d\n", port_base);)
- }
- if (irq_level < 0)
- printk("NCR53c406a: Invalid IRQ %d specified\n", ints[2]);
- }
-
- if (ints[0] > 2)
- fast_pio = ints[3];
-
- DEB(printk("NCR53c406a: port_base=0x%X, irq=%d, fast_pio=%d\n",
- port_base, irq_level, fast_pio);)
-}
-
-const char*
-NCR53c406a_info(struct Scsi_Host *SChost){
- DEB(printk("NCR53c406a_info called\n"));
- return (info_msg);
-}
-
-static void internal_done(Scsi_Cmnd *SCpnt) {
- internal_done_errcode = SCpnt->result;
- ++internal_done_flag;
-}
-
-
-static void wait_intr() {
- int i = jiffies + WATCHDOG;
-
- while(i>jiffies && !(inb(STAT_REG)&0xe0)) /* wait for a pseudo-interrupt */
- barrier();
-
- if (i <= jiffies) { /* Timed out */
- rtrc(0);
- current_SC->result = DID_TIME_OUT << 16;
- current_SC->SCp.phase = idle;
- current_SC->scsi_done(current_SC);
- return;
- }
-
- NCR53c406a_intr(0, NULL);
-}
-
-int NCR53c406a_command(Scsi_Cmnd *SCpnt){
- DEB(printk("NCR53c406a_command called\n"));
- NCR53c406a_queue(SCpnt, internal_done);
- if(irq_level)
- while (!internal_done_flag);
- else /* interrupts not supported */
- while (!internal_done_flag)
- wait_intr();
-
- internal_done_flag = 0;
- return internal_done_errcode;
-}
-
-
-int
-NCR53c406a_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)){
- int i;
- unsigned long flags = 0;
-
- VDEB(printk("NCR53c406a_queue called\n"));
- DEB(printk("cmd=%02x, cmd_len=%02x, target=%02x, lun=%02x, bufflen=%d\n",
- SCpnt->cmnd[0],
- SCpnt->cmd_len,
- SCpnt->target,
- SCpnt->lun,
- SCpnt->request_bufflen));
-
-#if 0
- VDEB(for(i=0; i<SCpnt->cmd_len; i++)
- printk("cmd[%d]=%02x ", i, SCpnt->cmnd[i]));
- VDEB(printk("\n"));
-#endif
-
- current_SC = SCpnt;
- current_SC->scsi_done = done;
- current_SC->SCp.phase = command_ph;
- current_SC->SCp.Status = 0;
- current_SC->SCp.Message = 0;
-
- save_flags(flags);
- cli();
- REG0;
- outb(SCpnt->target, DEST_ID); /* set destination */
- outb(FLUSH_FIFO, CMD_REG); /* reset the fifos */
-
- for(i=0; i<SCpnt->cmd_len; i++){
- outb(SCpnt->cmnd[i], SCSI_FIFO);
- }
- outb(SELECT_NO_ATN, CMD_REG);
- restore_flags(flags);
-
- rtrc(1);
- return 0;
-}
-
-int
-NCR53c406a_abort(Scsi_Cmnd *SCpnt){
- DEB(printk("NCR53c406a_abort called\n"));
- return SCSI_ABORT_SNOOZE; /* Don't know how to abort */
-}
-
-int
-NCR53c406a_reset(Scsi_Cmnd *SCpnt){
- DEB(printk("NCR53c406a_reset called\n"));
- outb(C4_IMG, CONFIG4); /* Select reg set 0 */
- outb(CHIP_RESET, CMD_REG);
- outb(SCSI_NOP, CMD_REG); /* required after reset */
- outb(SCSI_RESET, CMD_REG);
- chip_init();
-
- rtrc(2);
- if (irq_level)
- return SCSI_RESET_PENDING; /* should get an interrupt */
- else
- return SCSI_RESET_WAKEUP; /* won't get any interrupts */
-}
-
-int
-NCR53c406a_biosparm(Scsi_Disk *disk, kdev_t dev, int* info_array){
- int size;
-
- DEB(printk("NCR53c406a_biosparm called\n"));
-
- size = disk->capacity;
- info_array[0] = 64; /* heads */
- info_array[1] = 32; /* sectors */
- info_array[2] = size>>11; /* cylinders */
- if (info_array[2] > 1024) { /* big disk */
- info_array[0] = 255;
- info_array[1] = 63;
- info_array[2] = size / (255*63);
- }
- return 0;
- }
-
- static void
-NCR53c406a_intr(int unused, struct pt_regs *regs){
- DEB(unsigned char fifo_size;)
- DEB(unsigned char seq_reg;)
- unsigned char status, int_reg;
- unsigned long flags = 0;
-#if USE_PIO
- unsigned char pio_status;
- struct scatterlist *sglist;
- unsigned int sgcount;
-#endif
-
- VDEB(printk("NCR53c406a_intr called\n"));
-
- save_flags(flags);
- cli();
-#if USE_PIO
- REG1;
- pio_status = inb(PIO_STATUS);
-#endif
- REG0;
- status = inb(STAT_REG);
- DEB(seq_reg = inb(SEQ_REG));
- int_reg = inb(INT_REG);
- DEB(fifo_size = inb(FIFO_FLAGS) & 0x1f);
- restore_flags(flags);
-
-#if NCR53C406A_DEBUG
- printk("status=%02x, seq_reg=%02x, int_reg=%02x, fifo_size=%02x",
- status, seq_reg, int_reg, fifo_size);
-#if (USE_DMA)
- printk("\n");
-#else
- printk(", pio=%02x\n", pio_status);
-#endif USE_DMA
-#endif NCR53C406A_DEBUG
-
- if(int_reg & 0x80){ /* SCSI reset intr */
- rtrc(3);
- DEB(printk("NCR53c406a: reset intr received\n"));
- current_SC->SCp.phase = idle;
- current_SC->result = DID_RESET << 16;
- current_SC->scsi_done(current_SC);
- return;
- }
-
-#if USE_PIO
- if(pio_status & 0x80) {
- printk("NCR53C406A: Warning: PIO error!\n");
- current_SC->SCp.phase = idle;
- current_SC->result = DID_ERROR << 16;
- current_SC->scsi_done(current_SC);
- return;
- }
-#endif USE_PIO
-
- if(status & 0x20) { /* Parity error */
- printk("NCR53c406a: Warning: parity error!\n");
- current_SC->SCp.phase = idle;
- current_SC->result = DID_PARITY << 16;
- current_SC->scsi_done(current_SC);
- return;
- }
-
- if(status & 0x40) { /* Gross error */
- printk("NCR53c406a: Warning: gross error!\n");
- current_SC->SCp.phase = idle;
- current_SC->result = DID_ERROR << 16;
- current_SC->scsi_done(current_SC);
- return;
- }
-
- if(int_reg & 0x20){ /* Disconnect */
- DEB(printk("NCR53c406a: disconnect intr received\n"));
- if(current_SC->SCp.phase != message_in){ /* Unexpected disconnect */
- current_SC->result = DID_NO_CONNECT << 16;
- }
- else{ /* Command complete, return status and message */
- current_SC->result = (current_SC->SCp.Status & 0xff)
- | ((current_SC->SCp.Message & 0xff) << 8) | (DID_OK << 16);
- }
-
- rtrc(0);
- current_SC->SCp.phase = idle;
- current_SC->scsi_done( current_SC );
- return;
- }
-
- switch(status & 0x07){ /* scsi phase */
- case 0x00: /* DATA-OUT */
- if(int_reg & 0x10){ /* Target requesting info transfer */
- rtrc(5);
- current_SC->SCp.phase = data_out;
- VDEB(printk("NCR53c406a: Data-Out phase\n"));
- outb(FLUSH_FIFO, CMD_REG);
- LOAD_DMA_COUNT(current_SC->request_bufflen); /* Max transfer size */
-#if USE_DMA /* No s/g support for DMA */
- NCR53c406a_dma_write(current_SC->request_buffer,
- current_SC->request_bufflen);
-#endif USE_DMA
- outb(TRANSFER_INFO | DMA_OP, CMD_REG);
-#if USE_PIO
- if (!current_SC->use_sg) /* Don't use scatter-gather */
- NCR53c406a_pio_write(current_SC->request_buffer,
- current_SC->request_bufflen);
- else { /* use scatter-gather */
- sgcount = current_SC->use_sg;
- sglist = current_SC->request_buffer;
- while( sgcount-- ) {
- NCR53c406a_pio_write(sglist->address, sglist->length);
- sglist++;
- }
- }
- REG0;
-#endif USE_PIO
- }
- break;
-
- case 0x01: /* DATA-IN */
- if(int_reg & 0x10){ /* Target requesting info transfer */
- rtrc(6);
- current_SC->SCp.phase = data_in;
- VDEB(printk("NCR53c406a: Data-In phase\n"));
- outb(FLUSH_FIFO, CMD_REG);
- LOAD_DMA_COUNT(current_SC->request_bufflen); /* Max transfer size */
-#if USE_DMA /* No s/g support for DMA */
- NCR53c406a_dma_read(current_SC->request_buffer,
- current_SC->request_bufflen);
-#endif USE_DMA
- outb(TRANSFER_INFO | DMA_OP, CMD_REG);
-#if USE_PIO
- if (!current_SC->use_sg) /* Don't use scatter-gather */
- NCR53c406a_pio_read(current_SC->request_buffer,
- current_SC->request_bufflen);
- else { /* Use scatter-gather */
- sgcount = current_SC->use_sg;
- sglist = current_SC->request_buffer;
- while( sgcount-- ) {
- NCR53c406a_pio_read(sglist->address, sglist->length);
- sglist++;
- }
- }
- REG0;
-#endif USE_PIO
- }
- break;
-
- case 0x02: /* COMMAND */
- current_SC->SCp.phase = command_ph;
- printk("NCR53c406a: Warning: Unknown interupt occured in command phase!\n");
- break;
-
- case 0x03: /* STATUS */
- rtrc(7);
- current_SC->SCp.phase = status_ph;
- VDEB(printk("NCR53c406a: Status phase\n"));
- outb(FLUSH_FIFO, CMD_REG);
- outb(INIT_CMD_COMPLETE, CMD_REG);
- break;
-
- case 0x04: /* Reserved */
- case 0x05: /* Reserved */
- printk("NCR53c406a: WARNING: Reserved phase!!!\n");
- break;
-
- case 0x06: /* MESSAGE-OUT */
- DEB(printk("NCR53c406a: Message-Out phase\n"));
- current_SC->SCp.phase = message_out;
- outb(SET_ATN, CMD_REG); /* Reject the message */
- outb(MSG_ACCEPT, CMD_REG);
- break;
-
- case 0x07: /* MESSAGE-IN */
- rtrc(4);
- VDEB(printk("NCR53c406a: Message-In phase\n"));
- current_SC->SCp.phase = message_in;
-
- current_SC->SCp.Status = inb(SCSI_FIFO);
- current_SC->SCp.Message = inb(SCSI_FIFO);
-
- VDEB(printk("SCSI FIFO size=%d\n", inb(FIFO_FLAGS) & 0x1f));
- DEB(printk("Status = %02x Message = %02x\n",
- current_SC->SCp.Status, current_SC->SCp.Message));
-
- if(current_SC->SCp.Message == SAVE_POINTERS ||
- current_SC->SCp.Message == DISCONNECT) {
- outb(SET_ATN, CMD_REG); /* Reject message */
- DEB(printk("Discarding SAVE_POINTERS message\n"));
- }
- outb(MSG_ACCEPT, CMD_REG);
- break;
- }
-}
-
-#ifndef IRQ_LEV
-static int irq_probe()
-{
- int irqs, irq;
- int i;
-
- inb(INT_REG); /* clear the interrupt register */
- sti();
- irqs = probe_irq_on();
-
- /* Invalid command will cause an interrupt */
- REG0;
- outb(0xff, CMD_REG);
-
- /* Wait for the interrupt to occur */
- i = jiffies + WATCHDOG;
- while(i > jiffies && !(inb(STAT_REG) & 0x80))
- barrier();
- if (i <= jiffies) { /* Timed out, must be hardware trouble */
- probe_irq_off(irqs);
- return -1;
- }
-
- irq = probe_irq_off(irqs);
-
- /* Kick the chip */
- outb(CHIP_RESET, CMD_REG);
- outb(SCSI_NOP, CMD_REG);
- chip_init();
-
- return irq;
-}
-#endif IRQ_LEV
-
-static void chip_init()
-{
- REG1;
-#if USE_DMA
- outb(0x00, PIO_STATUS);
-#else /* USE_PIO */
- outb(0x01, PIO_STATUS);
-#endif
- outb(0x00, PIO_FLAG);
-
- outb(C4_IMG, CONFIG4); /* REG0; */
- outb(C3_IMG, CONFIG3);
- outb(C2_IMG, CONFIG2);
- outb(C1_IMG, CONFIG1);
-
- outb(0x05, CLKCONV); /* clock conversion factor */
- outb(0x9C, SRTIMOUT); /* Selection timeout */
- outb(0x05, SYNCPRD); /* Synchronous transfer period */
- outb(SYNC_MODE, SYNCOFF); /* synchronous mode */
-}
-
-void calc_port_addr()
-{
- /* Control Register Set 0 */
- TC_LSB = (port_base+0x00);
- TC_MSB = (port_base+0x01);
- SCSI_FIFO = (port_base+0x02);
- CMD_REG = (port_base+0x03);
- STAT_REG = (port_base+0x04);
- DEST_ID = (port_base+0x04);
- INT_REG = (port_base+0x05);
- SRTIMOUT = (port_base+0x05);
- SEQ_REG = (port_base+0x06);
- SYNCPRD = (port_base+0x06);
- FIFO_FLAGS = (port_base+0x07);
- SYNCOFF = (port_base+0x07);
- CONFIG1 = (port_base+0x08);
- CLKCONV = (port_base+0x09);
- /* TESTREG = (port_base+0x0A); */
- CONFIG2 = (port_base+0x0B);
- CONFIG3 = (port_base+0x0C);
- CONFIG4 = (port_base+0x0D);
- TC_HIGH = (port_base+0x0E);
- /* FIFO_BOTTOM = (port_base+0x0F); */
-
- /* Control Register Set 1 */
- /* JUMPER_SENSE = (port_base+0x00);*/
- /* SRAM_PTR = (port_base+0x01);*/
- /* SRAM_DATA = (port_base+0x02);*/
- PIO_FIFO = (port_base+0x04);
- /* PIO_FIFO1 = (port_base+0x05);*/
- /* PIO_FIFO2 = (port_base+0x06);*/
- /* PIO_FIFO3 = (port_base+0x07);*/
- PIO_STATUS = (port_base+0x08);
- /* ATA_CMD = (port_base+0x09);*/
- /* ATA_ERR = (port_base+0x0A);*/
- PIO_FLAG = (port_base+0x0B);
- CONFIG5 = (port_base+0x0D);
- /* SIGNATURE = (port_base+0x0E);*/
- /* CONFIG6 = (port_base+0x0F);*/
-}
-
-#ifdef MODULE
-/* Eventually this will go into an include file, but this will be later */
-Scsi_Host_Template driver_template = NCR53c406a;
-
-#include "scsi_module.c"
-#endif
-
-/*
- * Overrides for Emacs so that we get a uniform tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 4
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * c-continued-statement-offset: 4
- * c-continued-brace-offset: 0
- * indent-tabs-mode: nil
- * tab-width: 8
- * End:
- */
diff --git a/i386/i386at/gpl/linux/scsi/NCR53c406a.h b/i386/i386at/gpl/linux/scsi/NCR53c406a.h
deleted file mode 100644
index dcb48870..00000000
--- a/i386/i386at/gpl/linux/scsi/NCR53c406a.h
+++ /dev/null
@@ -1,83 +0,0 @@
-#ifndef _NCR53C406A_H
-#define _NCR53C406A_H
-
-/*
- * NCR53c406a.h
- *
- * Copyright (C) 1994 Normunds Saumanis (normunds@rx.tech.swh.lv)
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- */
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-/* NOTE: scatter-gather support only works in PIO mode.
- * Use SG_NONE if DMA mode is enabled!
- */
-#define NCR53c406a { \
- NULL /* next */, \
- NULL /* usage count */, \
- &proc_scsi_NCR53c406a /* proc_dir */, \
- NULL /* proc_info */, \
- "NCR53c406a" /* name */, \
- NCR53c406a_detect /* detect */, \
- NULL /* release */, \
- NCR53c406a_info /* info */, \
- NCR53c406a_command /* command */, \
- NCR53c406a_queue /* queuecommand */, \
- NCR53c406a_abort /* abort */, \
- NCR53c406a_reset /* reset */, \
- NULL /* slave_attach */, \
- NCR53c406a_biosparm /* biosparm */, \
- 1 /* can_queue */, \
- 7 /* SCSI ID of the chip */, \
- 32 /*SG_ALL*/ /*SG_NONE*/, \
- 1 /* commands per lun */, \
- 0 /* number of boards in system */, \
- 1 /* unchecked_isa_dma */, \
- ENABLE_CLUSTERING \
-}
-
-extern struct proc_dir_entry proc_scsi_NCR53c406a;
-
-int NCR53c406a_detect(Scsi_Host_Template *);
-const char* NCR53c406a_info(struct Scsi_Host *);
-
-int NCR53c406a_command(Scsi_Cmnd *);
-int NCR53c406a_queue(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-int NCR53c406a_abort(Scsi_Cmnd *);
-int NCR53c406a_reset(Scsi_Cmnd *);
-int NCR53c406a_biosparm(Disk *, kdev_t, int []);
-
-#endif /* _NCR53C406A_H */
-
-/*
- * Overrides for Emacs so that we get a uniform tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 4
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * c-continued-statement-offset: 4
- * c-continued-brace-offset: 0
- * indent-tabs-mode: nil
- * tab-width: 8
- * End:
- */
-
diff --git a/i386/i386at/gpl/linux/scsi/advansys.c b/i386/i386at/gpl/linux/scsi/advansys.c
deleted file mode 100644
index 3f8efe3d..00000000
--- a/i386/i386at/gpl/linux/scsi/advansys.c
+++ /dev/null
@@ -1,9061 +0,0 @@
-/* $Id: advansys.c,v 1.1.1.1 1997/02/25 21:27:45 thomas Exp $ */
-/*
- * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters
- *
- * Copyright (c) 1995-1996 Advanced System Products, Inc.
- * All Rights Reserved.
- *
- * This driver may be modified and freely distributed provided that
- * the above copyright message and this comment are included in the
- * distribution. The latest version of this driver is available at
- * the AdvanSys FTP and BBS sites listed below.
- *
- * Please send questions, comments, bug reports to:
- * bobf@advansys.com (Bob Frey)
- */
-
-/* The driver has been tested with Linux 1.2.1 and 1.3.57 kernels. */
-#define ASC_VERSION "1.2" /* AdvanSys Driver Version */
-
-/*
-
- Documentation for the AdvanSys Driver
-
- A. Adapters Supported by this Driver
- B. Linux 1.2.X - Directions for Adding the AdvanSys Driver
- C. Linux 1.3.X - Directions for Adding the AdvanSys Driver
- D. Source Comments
- E. Driver Compile Time Options and Debugging
- F. Driver LILO Option
- G. Release History
- H. Known Problems or Issues
- I. Credits
- J. AdvanSys Contact Information
-
-
- A. Adapters Supported by this Driver
-
- AdvanSys (Advanced System Products, Inc.) manufactures the following
- Bus-Mastering SCSI-2 Host Adapters for the ISA, EISA, VL, and PCI
- buses. This Linux driver supports all of these adapters.
-
- The CDB counts below indicate the number of SCSI CDB (Command
- Descriptor Block) requests that can be stored in the RISC chip
- cache and board LRAM. The driver detect routine will display the
- number of CDBs available for each adapter detected. This value
- can be lowered in the BIOS by changing the 'Host Queue Size'
- adapter setting.
-
- Connectivity Products:
- ABP920 - Bus-Master PCI 16 CDB
- ABP930 - Bus-Master PCI 16 CDB
- ABP5140 - Bus-Master PnP ISA 16 CDB
-
- Single Channel Products:
- ABP542 - Bus-Master ISA 240 CDB
- ABP5150 - Bus-Master ISA 240 CDB *
- ABP742 - Bus-Master EISA 240 CDB
- ABP842 - Bus-Master VL 240 CDB
- ABP940 - Bus-Master PCI 240 CDB
-
- Dual Channel Products:
- ABP950 - Dual Channel Bus-Master PCI 240 CDB Per Channel
- ABP852 - Dual Channel Bus-Master VL 240 CDB Per Channel
- ABP752 - Dual Channel Bus-Master EISA 240 CDB Per Channel
-
- * This board is shipped by HP with the 4020i CD-R drive. It has
- no BIOS so it cannot control a boot device, but it can control
- any secondary devices.
-
- B. Linux 1.2.X - Directions for Adding the AdvanSys Driver
-
- There are two source files: advansys.h and advansys.c. Copy
- both of these files to the directory /usr/src/linux/drivers/scsi.
-
- 1. Add the following line to /usr/src/linux/arch/i386/config.in
- after "comment 'SCSI low-level drivers'":
-
- bool 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS y
-
- 2. Add the following lines to /usr/src/linux/drivers/scsi/hosts.c
- after "#include "hosts.h"":
-
- #ifdef CONFIG_SCSI_ADVANSYS
- #include "advansys.h"
- #endif
-
- and after "static Scsi_Host_Template builtin_scsi_hosts[] =":
-
- #ifdef CONFIG_SCSI_ADVANSYS
- ADVANSYS,
- #endif
-
- 3. Add the following lines to /usr/src/linux/drivers/scsi/Makefile:
-
- ifdef CONFIG_SCSI_ADVANSYS
- SCSI_SRCS := $(SCSI_SRCS) advansys.c
- SCSI_OBJS := $(SCSI_OBJS) advansys.o
- else
- SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) advansys.o
- endif
-
- 4. (Optional) If you would like to enable the LILO command line
- and /etc/lilo.conf 'advansys' option, make the following changes.
- This option can be used to disable I/O port scanning or to limit
- I/O port scanning to specific addresses. Refer to the 'Driver
- LILO Option' section below. Add the following lines to
- /usr/src/linux/init/main.c in the prototype section:
-
- extern void advansys_setup(char *str, int *ints);
-
- and add the following lines to the bootsetups[] array.
-
- #ifdef CONFIG_SCSI_ADVANSYS
- { "advansys=", advansys_setup },
- #endif
-
- 5. If you have the HP 4020i CD-R driver and Linux 1.2.X you should
- add a fix to the CD-ROM target driver. This fix will allow
- you to mount CDs with the iso9660 file system. Linux 1.3.X
- already has this fix. In the file /usr/src/linux/drivers/scsi/sr.c
- and function get_sectorsize() after the line:
-
- if(scsi_CDs[i].sector_size == 0) scsi_CDs[i].sector_size = 2048;
-
- add the following line:
-
- if(scsi_CDs[i].sector_size == 2340) scsi_CDs[i].sector_size = 2048;
-
- 6. In the directory /usr/src/linux run 'make config' to configure
- the AdvanSys driver, then run 'make vmlinux' or 'make zlilo' to
- make the kernel. If the AdvanSys driver is not configured, then
- a loadable module can be built by running 'make modules' and
- 'make modules_install'. Use 'insmod' and 'rmmod' to install
- and remove advansys.o.
-
- C. Linux 1.3.X - Directions for Adding the AdvanSys Driver
-
- There are two source files: advansys.h and advansys.c. Copy
- both of these files to the directory /usr/src/linux/drivers/scsi.
-
- 1. Add the following line to /usr/src/linux/drivers/scsi/Config.in
- after "comment 'SCSI low-level drivers'":
-
- dep_tristate 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS $CONFIG_SCSI
-
- 2. Add the following lines to /usr/src/linux/drivers/scsi/hosts.c
- after "#include "hosts.h"":
-
- #ifdef CONFIG_SCSI_ADVANSYS
- #include "advansys.h"
- #endif
-
- and after "static Scsi_Host_Template builtin_scsi_hosts[] =":
-
- #ifdef CONFIG_SCSI_ADVANSYS
- ADVANSYS,
- #endif
-
- 3. Add the following lines to /usr/src/linux/drivers/scsi/Makefile:
-
- ifeq ($(CONFIG_SCSI_ADVANSYS),y)
- L_OBJS += advansys.o
- else
- ifeq ($(CONFIG_SCSI_ADVANSYS),m)
- M_OBJS += advansys.o
- endif
- endif
-
- 4. Add the following line to /usr/src/linux/include/linux/proc_fs.h
- in the enum scsi_directory_inos array:
-
- PROC_SCSI_ADVANSYS,
-
- 5. (Optional) If you would like to enable the LILO command line
- and /etc/lilo.conf 'advansys' option, make the following changes.
- This option can be used to disable I/O port scanning or to limit
- I/O port scanning to specific addresses. Refer to the 'Driver
- LILO Option' section below. Add the following lines to
- /usr/src/linux/init/main.c in the prototype section:
-
- extern void advansys_setup(char *str, int *ints);
-
- and add the following lines to the bootsetups[] array.
-
- #ifdef CONFIG_SCSI_ADVANSYS
- { "advansys=", advansys_setup },
- #endif
-
- 6. In the directory /usr/src/linux run 'make config' to configure
- the AdvanSys driver, then run 'make vmlinux' or 'make zlilo' to
- make the kernel. If the AdvanSys driver is not configured, then
- a loadable module can be built by running 'make modules' and
- 'make modules_install'. Use 'insmod' and 'rmmod' to install
- and remove advansys.o.
-
- D. Source Comments
-
- 1. Use tab stops set to 4 for the source files. For vi use 'se tabstops=4'.
-
- 2. This driver should be maintained in multiple files. But to make
- it easier to include with Linux and to follow Linux conventions,
- the whole driver is maintained in the source files advansys.h and
- advansys.c. In this file logical sections of the driver begin with
- a comment that contains '---'. The following are the logical sections
- of the driver below.
-
- --- Linux Version
- --- Linux Include Files
- --- Driver Options
- --- Asc Library Constants and Macros
- --- Debugging Header
- --- Driver Constants
- --- Driver Macros
- --- Driver Structures
- --- Driver Data
- --- Driver Function Prototypes
- --- Linux 'Scsi_Host_Template' and advansys_setup() Functions
- --- Loadable Driver Support
- --- Miscellaneous Driver Functions
- --- Functions Required by the Asc Library
- --- Tracing and Debugging Functions
- --- Asc Library Functions
-
- 3. The string 'XXX' is used to flag code that needs to be re-written
- or that contains a problem that needs to be addressed.
-
- 4. I have stripped comments from and reformatted the source for the
- Asc Library which is included in this file. I haven't done this
- to obfuscate the code. Actually I have done this to deobfuscate
- the code. The Asc Library source can be found under the following
- headings.
-
- --- Asc Library Constants and Macros
- --- Asc Library Functions
-
- E. Driver Compile Time Options and Debugging
-
- In this source file the following constants can be defined. They are
- defined in the source below. Both of these options are enabled by
- default.
-
- 1. ADVANSYS_DEBUG - enable for debugging and assertions
-
- The amount of debugging output can be controlled with the global
- variable 'asc_dbglvl'. The higher the number the more output. By
- default the debug level is 0.
-
- If the driver is loaded at boot time and the LILO Driver Option
- is included in the system, the debug level can be changed by
- specifying a 5th (ASC_NUM_BOARD_SUPPORTED + 1) I/O Port. The
- first three hex digits of the pseudo I/O Port must be set to
- 'deb' and the fourth hex digit specifies the debug level: 0 - F.
- The following command line will look for an adapter at 0x330
- and set the debug level to 2.
-
- linux advansys=0x330,0x0,0x0,0x0,0xdeb2
-
- If the driver is built as a loadable module this variable can be
- defined when the driver is loaded. The following insmod command
- will set the debug level to one.
-
- insmod advansys.o asc_dbglvl=1
-
-
- Debugging Message Levels:
- 0: Errors Only
- 1: High-Level Tracing
- 2-N: Verbose Tracing
-
- I don't know the approved way for turning on printk()s to the
- console. Here's a program I use to do this. Debug output is
- logged in /var/adm/messages.
-
- main()
- {
- syscall(103, 7, 0, 0);
- }
-
- I found that increasing LOG_BUF_LEN to 40960 in kernel/printk.c
- prevents most level 1 debug messages from being lost.
-
- 2. ADVANSYS_STATS - enable statistics and tracing
-
- For Linux 1.2.X if ADVANSYS_STATS_1_2_PRINT is defined every
- 10,000 I/O operations the driver will print statistics to the
- console. This value can be changed by modifying the constant
- used in advansys_queuecommand(). ADVANSYS_STATS_1_2_PRINT is
- off by default.
-
- For Linux 1.3.X statistics can be accessed by reading the
- /proc/scsi/advansys/[0-9] files.
-
- Note: these statistics are currently maintained on a global driver
- basis and not per board.
-
- F. Driver LILO Option
-
- If init/main.c is modified as described in the 'Directions for Adding
- the AdvanSys Driver to Linux' section (B.4.) above, the driver will
- recognize the 'advansys' LILO command line and /etc/lilo.conf option.
- This option can be used to either disable I/O port scanning or to limit
- scanning to 1 - 4 I/O ports. Regardless of the option setting EISA and
- PCI boards will still be searched for and detected. This option only
- affects searching for ISA and VL boards.
-
- Examples:
- 1. Eliminate I/O port scanning:
- boot: linux advansys=
- or
- boot: linux advansys=0x0
- 2. Limit I/O port scanning to one I/O port:
- boot: linux advansys=0x110
- 3. Limit I/O port scanning to four I/O ports:
- boot: linux advansys=0x110,0x210,0x230,0x330
-
- For a loadable module the same effect can be achieved by setting
- the 'asc_iopflag' variable and 'asc_ioport' array when loading
- the driver, e.g.
-
- insmod advansys.o asc_iopflag=1 asc_ioport=0x110,0x330
-
- If ADVANSYS_DEBUG is defined a 5th (ASC_NUM_BOARD_SUPPORTED + 1)
- I/O Port may be added to specify the driver debug level. Refer to
- the 'Driver Compile Time Options and Debugging' section above for
- more information.
-
- G. Release History
-
- 12/23/95 BETA-1.0:
- First Release
-
- 12/28/95 BETA-1.1:
- 1. Prevent advansys_detect() from being called twice.
- 2. Add LILO 0xdeb[0-f] option to set 'asc_dbglvl'.
-
- 1/12/96 1.2:
- 1. Prevent re-entrancy in the interrupt handler which
- resulted in the driver hanging Linux.
- 2. Fix problem that prevented ABP-940 cards from being
- recognized on some PCI motherboards.
- 3. Add support for the ABP-5140 PnP ISA card.
- 4. Fix check condition return status.
- 5. Add conditionally compiled code for Linux 1.3.X.
-
- H. Known Problems or Issues
-
- 1. The setting for 'cmd_per_lun' needs to be changed. It is currently
- less then what the AdvanSys boards can queue. Because the target and
- mid-level Linux drivers base memory allocation on 'cmd_per_lun' (as
- well as 'sg_tablesize') memory use gets out of hand with a large
- 'cmd_per_lun'. 'cmd_per_lun' should be per device instead of per
- adapter. When the driver is compiled as a loadable module both
- 'cmd_per_lun' and 'sg_tablesize' are tuned down to try to prevent
- memory allocation errors.
-
- 2. For the first scsi command sent to a device the driver increases
- the timeout value. This gives the driver more time to perform
- its own initialization for the board and each device. The timeout
- value is only changed on the first scsi command for each device
- and never thereafter.
-
- I. Credits
-
- Nathan Hartwell (mage@cdc3.cdc.net) provided the directions and
- and basis for the Linux 1.3.X changes which were included in the
- 1.2 release.
-
- J. AdvanSys Contact Information
-
- Mail: Advanced System Products, Inc.
- 1150 Ringwood Court
- San Jose, CA 95131 USA
- Operator: 1-408-383-9400
- FAX: 1-408-383-9612
- Tech Support: 1-800-525-7440
- BBS: 1-408-383-9540 (9600,N,8,1)
- Interactive FAX: 1-408-383-9753
- Customer Direct Sales: 1-800-883-1099
- Tech Support E-Mail: support@advansys.com
- Linux Support E-Mail: bobf@advansys.com
- FTP Site: ftp.advansys.com (login: anonymous)
- Web Site: http://www.advansys.com
-
-*/
-
-
-/*
- * --- Linux Version
- */
-
-/*
- * The driver can be used in Linux 1.2.X or 1.3.X.
- */
-#if !defined(LINUX_1_2) && !defined(LINUX_1_3)
-#ifndef LINUX_VERSION_CODE
-#include <linux/version.h>
-#endif /* LINUX_VERSION_CODE */
-#if LINUX_VERSION_CODE > 65536 + 3 * 256
-#define LINUX_1_3
-#else /* LINUX_VERSION_CODE */
-#define LINUX_1_2
-#endif /* LINUX_VERSION_CODE */
-#endif /* !defined(LINUX_1_2) && !defined(LINUX_1_3) */
-
-
-/*
- * --- Linux Include Files
- */
-
-#ifdef MODULE
-#ifdef LINUX_1_3
-#include <linux/autoconf.h>
-#endif /* LINUX_1_3 */
-#include <linux/module.h>
-#endif /* MODULE */
-#include <linux/string.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/head.h>
-#include <linux/types.h>
-#include <linux/ioport.h>
-#include <linux/delay.h>
-#include <linux/malloc.h>
-#include <linux/config.h>
-#ifdef LINUX_1_3
-#include <linux/proc_fs.h>
-#endif /* LINUX_1_3 */
-#include <asm/io.h>
-#include <asm/system.h>
-#include <asm/dma.h>
-#ifdef LINUX_1_2
-#include "../block/blk.h"
-#else /* LINUX_1_3 */
-#include <linux/blk.h>
-#include <linux/stat.h>
-#endif /* LINUX_1_3 */
-#include "scsi.h"
-#include "hosts.h"
-#include "sd.h"
-#include "advansys.h"
-
-
-/*
- * --- Driver Options
- */
-#define ADVANSYS_DEBUG /* Enable for debugging and assertions. */
-#define ADVANSYS_STATS /* Enable for statistics and tracing. */
-#ifdef LINUX_1_2
-#undef ADVANSYS_STATS_1_2_PRINT /* Enable to print statistics to console. */
-#endif /* LINUX_1_2 */
-
-
-/*
- * --- Asc Library Constants and Macros
- */
-
-#define ASC_LIB_VERSION_MAJOR 1
-#define ASC_LIB_VERSION_MINOR 16
-#define ASC_LIB_SERIAL_NUMBER 53
-
-typedef unsigned char uchar;
-typedef unsigned char BYTE;
-typedef unsigned short WORD;
-typedef unsigned long DWORD;
-
-typedef int BOOL;
-
-#ifndef NULL
-#define NULL (0)
-#endif
-
-#ifndef TRUE
-#define TRUE (1)
-#endif
-
-#ifndef FALSE
-#define FALSE (0)
-#endif
-
-#define REG register
-
-#define rchar REG char
-#define rshort REG short
-#define rint REG int
-#define rlong REG long
-
-#define ruchar REG uchar
-#define rushort REG ushort
-#define ruint REG uint
-#define rulong REG ulong
-
-#define NULLPTR ( void *)0
-#define FNULLPTR ( void dosfar *)0UL
-#define EOF (-1)
-#define EOS '\0'
-#define ERR (-1)
-#define UB_ERR (uchar)(0xFF)
-#define UW_ERR (uint)(0xFFFF)
-#define UL_ERR (ulong)(0xFFFFFFFFUL)
-
-#define iseven_word( val ) ( ( ( ( uint )val) & ( uint )0x0001 ) == 0 )
-#define isodd_word( val ) ( ( ( ( uint )val) & ( uint )0x0001 ) != 0 )
-#define toeven_word( val ) ( ( ( uint )val ) & ( uint )0xFFFE )
-
-#define biton( val, bits ) ((( uint )( val >> bits ) & (uint)0x0001 ) != 0 )
-#define bitoff( val, bits ) ((( uint )( val >> bits ) & (uint)0x0001 ) == 0 )
-#define lbiton( val, bits ) ((( ulong )( val >> bits ) & (ulong)0x00000001UL ) != 0 )
-#define lbitoff( val, bits ) ((( ulong )( val >> bits ) & (ulong)0x00000001UL ) == 0 )
-
-#define absh( val ) ( ( val ) < 0 ? -( val ) : ( val ) )
-
-#define swapbyte( ch ) ( ( ( (ch) << 4 ) | ( (ch) >> 4 ) ) )
-
-#ifndef GBYTE
-#define GBYTE (0x40000000UL)
-#endif
-
-#ifndef MBYTE
-#define MBYTE (0x100000UL)
-#endif
-
-#ifndef KBYTE
-#define KBYTE (0x400)
-#endif
-
-#define HI_BYTE(x) ( *( ( BYTE *)(&x)+1 ) )
-#define LO_BYTE(x) ( *( ( BYTE *)&x ) )
-
-#define HI_WORD(x) ( *( ( WORD *)(&x)+1 ) )
-#define LO_WORD(x) ( *( ( WORD *)&x ) )
-
-#ifndef MAKEWORD
-#define MAKEWORD(lo, hi) ((WORD) (((WORD) lo) | ((WORD) hi << 8)))
-#endif
-
-#ifndef MAKELONG
-#define MAKELONG(lo, hi) ((DWORD) (((DWORD) lo) | ((DWORD) hi << 16)))
-#endif
-
-#define SwapWords(dWord) ((DWORD) ((dWord >> 16) | (dWord << 16)))
-#define SwapBytes(word) ((WORD) ((word >> 8) | (word << 8)))
-
-#define BigToLittle(dWord) \
- ((DWORD) (SwapWords(MAKELONG(SwapBytes(LO_WORD(dWord)), SwapBytes(HI_WORD(dWord))))))
-#define LittleToBig(dWord) BigToLittle(dWord)
-
-#define Lptr
-#define dosfar
-#define far
-#define PortAddr unsigned short
-#define Ptr2Func ulong
-
-#define inp(port) inb(port)
-#define inpw(port) inw(port)
-#define outp(port, byte) outb((byte), (port))
-#define outpw(port, word) outw((word), (port))
-
-#define ASC_MAX_SG_QUEUE 5
-#define ASC_MAX_SG_LIST (1 + ((ASC_SG_LIST_PER_Q) * (ASC_MAX_SG_QUEUE)))
-
-#define CC_INIT_INQ_DISPLAY FALSE
-
-#define CC_CLEAR_LRAM_SRB_PTR FALSE
-#define CC_VERIFY_LRAM_COPY FALSE
-
-#define CC_DEBUG_SG_LIST FALSE
-#define CC_FAST_STRING_IO FALSE
-
-#define CC_WRITE_IO_COUNT FALSE
-#define CC_CLEAR_DMA_REMAIN FALSE
-
-#define CC_DISABLE_PCI_PARITY_INT TRUE
-
-#define CC_LINK_BUSY_Q FALSE
-
-#define CC_TARGET_MODE FALSE
-
-#define CC_SCAM FALSE
-
-#define CC_LITTLE_ENDIAN_HOST TRUE
-
-#ifndef CC_TEST_LRAM_ENDIAN
-
-#if CC_LITTLE_ENDIAN_HOST
-#define CC_TEST_LRAM_ENDIAN FALSE
-#else
-#define CC_TEST_LRAM_ENDIAN TRUE
-#endif
-
-#endif
-
-#define CC_STRUCT_ALIGNED TRUE
-
-#define CC_MEMORY_MAPPED_IO FALSE
-
-#ifndef CC_TARGET_MODE
-#define CC_TARGET_MODE FALSE
-#endif
-
-#ifndef CC_STRUCT_ALIGNED
-#define CC_STRUCT_ALIGNED FALSE
-#endif
-
-#ifndef CC_LITTLE_ENDIAN_HOST
-#define CC_LITTLE_ENDIAN_HOST TRUE
-#endif
-
-#if !CC_LITTLE_ENDIAN_HOST
-
-#ifndef CC_TEST_LRAM_ENDIAN
-#define CC_TEST_LRAM_ENDIAN TRUE
-#endif
-
-#endif
-
-#ifndef CC_MEMORY_MAPPED_IO
-#define CC_MEMORY_MAPPED_IO FALSE
-#endif
-
-#ifndef CC_WRITE_IO_COUNT
-#define CC_WRITE_IO_COUNT FALSE
-#endif
-
-#ifndef CC_CLEAR_DMA_REMAIN
-#define CC_CLEAR_DMA_REMAIN FALSE
-#endif
-
-#define ASC_CS_TYPE unsigned short
-
-#ifndef asc_ptr_type
-#define asc_ptr_type
-#endif
-
-#ifndef CC_SCAM
-#define CC_SCAM FALSE
-#endif
-
-#ifndef ASC_GET_PTR2FUNC
-#define ASC_GET_PTR2FUNC( fun ) ( Ptr2Func )( fun )
-#endif
-
-#define FLIP_BYTE_NIBBLE( x ) ( ((x<<4)& 0xFF) | (x>>4) )
-
-#define ASC_IS_ISA (0x0001)
-#define ASC_IS_ISAPNP (0x0081)
-#define ASC_IS_EISA (0x0002)
-#define ASC_IS_PCI (0x0004)
-#define ASC_IS_PCMCIA (0x0008)
-#define ASC_IS_PNP (0x0010)
-#define ASC_IS_MCA (0x0020)
-#define ASC_IS_VL (0x0040)
-
-#define ASC_ISA_PNP_PORT_ADDR (0x279)
-#define ASC_ISA_PNP_PORT_WRITE (ASC_ISA_PNP_PORT_ADDR+0x800)
-
-#define ASC_IS_WIDESCSI_16 (0x0100)
-#define ASC_IS_WIDESCSI_32 (0x0200)
-
-#define ASC_IS_BIG_ENDIAN (0x8000)
-
-#define ASC_CHIP_MIN_VER_VL (0x01)
-#define ASC_CHIP_MAX_VER_VL (0x07)
-
-#define ASC_CHIP_MIN_VER_PCI (0x09)
-#define ASC_CHIP_MAX_VER_PCI (0x0F)
-#define ASC_CHIP_VER_PCI_BIT (0x08)
-
-#define ASC_CHIP_MIN_VER_ISA (0x11)
-#define ASC_CHIP_MIN_VER_ISA_PNP (0x21)
-#define ASC_CHIP_MAX_VER_ISA (0x27)
-#define ASC_CHIP_VER_ISA_BIT (0x30)
-#define ASC_CHIP_VER_ISAPNP_BIT (0x20)
-
-#define ASC_CHIP_VER_ASYN_BUG (0x21)
-
-#define ASC_CHIP_MIN_VER_EISA (0x41)
-#define ASC_CHIP_MAX_VER_EISA (0x47)
-#define ASC_CHIP_VER_EISA_BIT (0x40)
-
-#define ASC_MAX_VL_DMA_ADDR (0x07FFFFFFL)
-#define ASC_MAX_VL_DMA_COUNT (0x07FFFFFFL)
-
-#define ASC_MAX_PCI_DMA_ADDR (0xFFFFFFFFL)
-#define ASC_MAX_PCI_DMA_COUNT (0xFFFFFFFFL)
-
-#define ASC_MAX_ISA_DMA_ADDR (0x00FFFFFFL)
-#define ASC_MAX_ISA_DMA_COUNT (0x00FFFFFFL)
-
-#define ASC_MAX_EISA_DMA_ADDR (0x07FFFFFFL)
-#define ASC_MAX_EISA_DMA_COUNT (0x07FFFFFFL)
-
-#if !CC_STRUCT_ALIGNED
-
-#define DvcGetQinfo( iop_base, s_addr, outbuf, words) \
- AscMemWordCopyFromLram( iop_base, s_addr, outbuf, words)
-
-#define DvcPutScsiQ( iop_base, s_addr, outbuf, words) \
- AscMemWordCopyToLram( iop_base, s_addr, outbuf, words)
-
-#endif
-
-#define ASC_SCSI_ID_BITS 3
-#define ASC_SCSI_TIX_TYPE uchar
-#define ASC_ALL_DEVICE_BIT_SET 0xFF
-
-#ifdef ASC_WIDESCSI_16
-
-#undef ASC_SCSI_ID_BITS
-#define ASC_SCSI_ID_BITS 4
-#define ASC_ALL_DEVICE_BIT_SET 0xFFFF
-
-#endif
-
-#ifdef ASC_WIDESCSI_32
-
-#undef ASC_SCSI_ID_BITS
-#define ASC_SCSI_ID_BITS 5
-#define ASC_ALL_DEVICE_BIT_SET 0xFFFFFFFFL
-
-#endif
-
-#if ASC_SCSI_ID_BITS == 3
-
-#define ASC_SCSI_BIT_ID_TYPE uchar
-#define ASC_MAX_TID 7
-#define ASC_MAX_LUN 7
-#define ASC_SCSI_WIDTH_BIT_SET 0xFF
-
-#elif ASC_SCSI_ID_BITS == 4
-
-#define ASC_SCSI_BIT_ID_TYPE ushort
-#define ASC_MAX_TID 15
-#define ASC_MAX_LUN 7
-#define ASC_SCSI_WIDTH_BIT_SET 0xFFFF
-
-#elif ASC_SCSI_ID_BITS == 5
-
-#define ASC_SCSI_BIT_ID_TYPE ulong
-#define ASC_MAX_TID 31
-#define ASC_MAX_LUN 7
-#define ASC_SCSI_WIDTH_BIT_SET 0xFFFFFFFF
-
-#else
-
-#error ASC_SCSI_ID_BITS definition is wrong
-
-#endif
-
-#define ASC_MAX_SENSE_LEN 32
-#define ASC_MIN_SENSE_LEN 14
-
-#define ASC_MAX_CDB_LEN 12
-
-#define SCSICMD_TestUnitReady 0x00
-#define SCSICMD_Rewind 0x01
-#define SCSICMD_Rezero 0x01
-#define SCSICMD_RequestSense 0x03
-#define SCSICMD_Format 0x04
-#define SCSICMD_FormatUnit 0x04
-#define SCSICMD_Read6 0x08
-#define SCSICMD_Write6 0x0A
-#define SCSICMD_Seek6 0x0B
-#define SCSICMD_Inquiry 0x12
-#define SCSICMD_Verify6 0x13
-#define SCSICMD_ModeSelect6 0x15
-#define SCSICMD_ModeSense6 0x1A
-
-#define SCSICMD_StartStopUnit 0x1B
-#define SCSICMD_LoadUnloadTape 0x1B
-#define SCSICMD_ReadCapacity 0x25
-#define SCSICMD_Read10 0x28
-#define SCSICMD_Write10 0x2A
-#define SCSICMD_Seek10 0x2B
-#define SCSICMD_Erase10 0x2C
-#define SCSICMD_WriteAndVerify10 0x2E
-#define SCSICMD_Verify10 0x2F
-
-#define SCSICMD_ModeSelect10 0x55
-#define SCSICMD_ModeSense10 0x5A
-
-#define SCSI_TYPE_DASD 0x00
-#define SCSI_TYPE_SASD 0x01
-#define SCSI_TYPE_PRN 0x02
-#define SCSI_TYPE_PROC 0x03
-
-#define SCSI_TYPE_WORM 0x04
-#define SCSI_TYPE_CDROM 0x05
-#define SCSI_TYPE_SCANNER 0x06
-#define SCSI_TYPE_OPTMEM 0x07
-#define SCSI_TYPE_MED_CHG 0x08
-#define SCSI_TYPE_COMM 0x09
-#define SCSI_TYPE_UNKNOWN 0x1F
-#define SCSI_TYPE_NO_DVC 0xFF
-
-#define ASC_SCSIDIR_NOCHK 0x00
-
-#define ASC_SCSIDIR_T2H 0x08
-
-#define ASC_SCSIDIR_H2T 0x10
-
-#define ASC_SCSIDIR_NODATA 0x18
-
-#define SCSI_SENKEY_NO_SENSE 0x00
-#define SCSI_SENKEY_UNDEFINED 0x01
-#define SCSI_SENKEY_NOT_READY 0x02
-#define SCSI_SENKEY_MEDIUM_ERR 0x03
-#define SCSI_SENKEY_HW_ERR 0x04
-#define SCSI_SENKEY_ILLEGAL 0x05
-#define SCSI_SENKEY_ATTENSION 0x06
-#define SCSI_SENKEY_PROTECTED 0x07
-#define SCSI_SENKEY_BLANK 0x08
-#define SCSI_SENKEY_V_UNIQUE 0x09
-#define SCSI_SENKEY_CPY_ABORT 0x0A
-#define SCSI_SENKEY_ABORT 0x0B
-#define SCSI_SENKEY_EQUAL 0x0C
-#define SCSI_SENKEY_VOL_OVERFLOW 0x0D
-#define SCSI_SENKEY_MISCOMP 0x0E
-#define SCSI_SENKEY_RESERVED 0x0F
-
-#define ASC_SRB_HOST( x ) ( ( uchar )( ( uchar )( x ) >> 4 ) )
-#define ASC_SRB_TID( x ) ( ( uchar )( ( uchar )( x ) & ( uchar )0x0F ) )
-
-#define ASC_SRB_LUN( x ) ( ( uchar )( ( uint )( x ) >> 13 ) )
-
-#define PUT_CDB1( x ) ( ( uchar )( ( uint )( x ) >> 8 ) )
-
-#define SS_GOOD 0x00
-#define SS_CHK_CONDITION 0x02
-#define SS_CONDITION_MET 0x04
-#define SS_TARGET_BUSY 0x08
-#define SS_INTERMID 0x10
-#define SS_INTERMID_COND_MET 0x14
-
-#define SS_RSERV_CONFLICT 0x18
-#define SS_CMD_TERMINATED 0x22
-
-#define SS_QUEUE_FULL 0x28
-
-#define MS_CMD_DONE 0x00
-#define MS_EXTEND 0x01
-#define MS_SDTR_LEN 0x03
-#define MS_SDTR_CODE 0x01
-
-#define M1_SAVE_DATA_PTR 0x02
-#define M1_RESTORE_PTRS 0x03
-#define M1_DISCONNECT 0x04
-#define M1_INIT_DETECTED_ERR 0x05
-#define M1_ABORT 0x06
-#define M1_MSG_REJECT 0x07
-#define M1_NO_OP 0x08
-#define M1_MSG_PARITY_ERR 0x09
-#define M1_LINK_CMD_DONE 0x0A
-#define M1_LINK_CMD_DONE_WFLAG 0x0B
-#define M1_BUS_DVC_RESET 0x0C
-#define M1_ABORT_TAG 0x0D
-#define M1_CLR_QUEUE 0x0E
-#define M1_INIT_RECOVERY 0x0F
-#define M1_RELEASE_RECOVERY 0x10
-#define M1_KILL_IO_PROC 0x11
-
-#define M2_QTAG_MSG_SIMPLE 0x20
-#define M2_QTAG_MSG_HEAD 0x21
-#define M2_QTAG_MSG_ORDERED 0x22
-#define M2_IGNORE_WIDE_RESIDUE 0x23
-
-typedef struct {
- uchar peri_dvc_type:5;
- uchar peri_qualifier:3;
-} ASC_SCSI_INQ0;
-
-typedef struct {
- uchar dvc_type_modifier:7;
- uchar rmb:1;
-} ASC_SCSI_INQ1;
-
-typedef struct {
- uchar ansi_apr_ver:3;
- uchar ecma_ver:3;
- uchar iso_ver:2;
-} ASC_SCSI_INQ2;
-
-typedef struct {
- uchar rsp_data_fmt:4;
-
- uchar res:2;
- uchar TemIOP:1;
- uchar aenc:1;
-} ASC_SCSI_INQ3;
-
-typedef struct {
- uchar StfRe:1;
- uchar CmdQue:1;
- uchar Reserved:1;
- uchar Linked:1;
- uchar Sync:1;
- uchar WBus16:1;
- uchar WBus32:1;
- uchar RelAdr:1;
-} ASC_SCSI_INQ7;
-
-typedef struct {
- ASC_SCSI_INQ0 byte0;
- ASC_SCSI_INQ1 byte1;
- ASC_SCSI_INQ2 byte2;
- ASC_SCSI_INQ3 byte3;
- uchar add_len;
- uchar res1;
- uchar res2;
- ASC_SCSI_INQ7 byte7;
- uchar vendor_id[8];
- uchar product_id[16];
- uchar product_rev_level[4];
-} ASC_SCSI_INQUIRY;
-
-typedef struct asc_req_sense {
- uchar err_code:7;
- uchar info_valid:1;
- uchar segment_no;
- uchar sense_key:4;
- uchar reserved_bit:1;
- uchar sense_ILI:1;
- uchar sense_EOM:1;
- uchar file_mark:1;
- uchar info1[4];
- uchar add_sense_len;
- uchar cmd_sp_info[4];
- uchar asc;
- uchar ascq;
-
- uchar fruc;
- uchar sks_byte0:7;
- uchar sks_valid:1;
- uchar sks_bytes[2];
- uchar notused[2];
- uchar ex_sense_code;
- uchar info2[4];
-} ASC_REQ_SENSE;
-
-#define ASC_SG_LIST_PER_Q 7
-
-#define QS_FREE 0x00
-#define QS_READY 0x01
-#define QS_DISC1 0x02
-#define QS_DISC2 0x04
-#define QS_BUSY 0x08
-
-#define QS_ABORTED 0x40
-#define QS_DONE 0x80
-
-#define QC_NO_CALLBACK 0x01
-
-#define QC_SG_SWAP_QUEUE 0x02
-#define QC_SG_HEAD 0x04
-#define QC_DATA_IN 0x08
-#define QC_DATA_OUT 0x10
-
-#define QC_URGENT 0x20
-#define QC_MSG_OUT 0x40
-#define QC_REQ_SENSE 0x80
-
-#define QCSG_SG_XFER_LIST 0x02
-#define QCSG_SG_XFER_MORE 0x04
-#define QCSG_SG_XFER_END 0x08
-
-#define QD_IN_PROGRESS 0x00
-#define QD_NO_ERROR 0x01
-#define QD_ABORTED_BY_HOST 0x02
-#define QD_WITH_ERROR 0x04
-#define QD_INVALID_REQUEST 0x80
-#define QD_INVALID_HOST_NUM 0x81
-#define QD_INVALID_DEVICE 0x82
-#define QD_ERR_INTERNAL 0xFF
-
-#define QHSTA_NO_ERROR 0x00
-#define QHSTA_M_SEL_TIMEOUT 0x11
-#define QHSTA_M_DATA_OVER_RUN 0x12
-#define QHSTA_M_DATA_UNDER_RUN 0x12
-#define QHSTA_M_UNEXPECTED_BUS_FREE 0x13
-#define QHSTA_M_BAD_BUS_PHASE_SEQ 0x14
-
-#define QHSTA_D_QDONE_SG_LIST_CORRUPTED 0x21
-#define QHSTA_D_ASC_DVC_ERROR_CODE_SET 0x22
-#define QHSTA_D_HOST_ABORT_FAILED 0x23
-#define QHSTA_D_EXE_SCSI_Q_FAILED 0x24
-#define QHSTA_D_EXE_SCSI_Q_BUSY_TIMEOUT 0x25
-
-#define QHSTA_D_ASPI_NO_BUF_POOL 0x26
-
-#define QHSTA_M_WTM_TIMEOUT 0x41
-#define QHSTA_M_BAD_CMPL_STATUS_IN 0x42
-#define QHSTA_M_NO_AUTO_REQ_SENSE 0x43
-#define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44
-#define QHSTA_M_TARGET_STATUS_BUSY 0x45
-#define QHSTA_M_BAD_TAG_CODE 0x46
-
-#define QHSTA_M_BAD_QUEUE_FULL_OR_BUSY 0x47
-
-#define QHSTA_D_LRAM_CMP_ERROR 0x81
-#define QHSTA_M_MICRO_CODE_ERROR_HALT 0xA1
-
-#define ASC_FLAG_SCSIQ_REQ 0x01
-#define ASC_FLAG_BIOS_SCSIQ_REQ 0x02
-#define ASC_FLAG_BIOS_ASYNC_IO 0x04
-#define ASC_FLAG_SRB_LINEAR_ADDR 0x08
-
-#define ASC_FLAG_WIN16 0x10
-#define ASC_FLAG_WIN32 0x20
-
-#define ASC_FLAG_DOS_VM_CALLBACK 0x80
-
-#define ASC_TAG_FLAG_ADD_ONE_BYTE 0x10
-#define ASC_TAG_FLAG_ISAPNP_ADD_BYTES 0x40
-
-#define ASC_SCSIQ_CPY_BEG 4
-#define ASC_SCSIQ_SGHD_CPY_BEG 2
-
-#define ASC_SCSIQ_B_FWD 0
-#define ASC_SCSIQ_B_BWD 1
-
-#define ASC_SCSIQ_B_STATUS 2
-#define ASC_SCSIQ_B_QNO 3
-
-#define ASC_SCSIQ_B_CNTL 4
-#define ASC_SCSIQ_B_SG_QUEUE_CNT 5
-
-#define ASC_SCSIQ_D_DATA_ADDR 8
-#define ASC_SCSIQ_D_DATA_CNT 12
-#define ASC_SCSIQ_B_SENSE_LEN 20
-#define ASC_SCSIQ_DONE_INFO_BEG 22
-#define ASC_SCSIQ_D_SRBPTR 22
-#define ASC_SCSIQ_B_TARGET_IX 26
-#define ASC_SCSIQ_B_CDB_LEN 28
-#define ASC_SCSIQ_B_TAG_CODE 29
-#define ASC_SCSIQ_W_VM_ID 30
-#define ASC_SCSIQ_DONE_STATUS 32
-#define ASC_SCSIQ_HOST_STATUS 33
-#define ASC_SCSIQ_SCSI_STATUS 34
-#define ASC_SCSIQ_CDB_BEG 36
-#define ASC_SCSIQ_DW_REMAIN_XFER_ADDR 56
-#define ASC_SCSIQ_DW_REMAIN_XFER_CNT 60
-#define ASC_SCSIQ_B_SG_WK_QP 49
-#define ASC_SCSIQ_B_SG_WK_IX 50
-#define ASC_SCSIQ_W_REQ_COUNT 52
-#define ASC_SCSIQ_B_LIST_CNT 6
-#define ASC_SCSIQ_B_CUR_LIST_CNT 7
-
-#define ASC_SGQ_B_SG_CNTL 4
-#define ASC_SGQ_B_SG_HEAD_QP 5
-#define ASC_SGQ_B_SG_LIST_CNT 6
-#define ASC_SGQ_B_SG_CUR_LIST_CNT 7
-#define ASC_SGQ_LIST_BEG 8
-
-#define ASC_DEF_SCSI1_QNG 2
-#define ASC_MAX_SCSI1_QNG 2
-#define ASC_DEF_SCSI2_QNG 16
-#define ASC_MAX_SCSI2_QNG 32
-
-#define ASC_TAG_CODE_MASK 0x23
-
-#define ASC_STOP_REQ_RISC_STOP 0x01
-
-#define ASC_STOP_ACK_RISC_STOP 0x03
-
-#define ASC_STOP_CLEAN_UP_BUSY_Q 0x10
-#define ASC_STOP_CLEAN_UP_DISC_Q 0x20
-#define ASC_STOP_HOST_REQ_RISC_HALT 0x40
-#define ASC_STOP_SEND_INT_TO_HOST 0x80
-
-#define ASC_TIDLUN_TO_IX( tid, lun ) ( ASC_SCSI_TIX_TYPE )( (tid) + ((lun)<<ASC_SCSI_ID_BITS) )
-
-#define ASC_TID_TO_TARGET_ID( tid ) ( ASC_SCSI_BIT_ID_TYPE )( 0x01 << (tid) )
-#define ASC_TIX_TO_TARGET_ID( tix ) ( 0x01 << ( (tix) & ASC_MAX_TID ) )
-#define ASC_TIX_TO_TID( tix ) ( (tix) & ASC_MAX_TID )
-#define ASC_TID_TO_TIX( tid ) ( (tid) & ASC_MAX_TID )
-#define ASC_TIX_TO_LUN( tix ) ( ( (tix) >> ASC_SCSI_ID_BITS ) & ASC_MAX_LUN )
-
-#define ASC_QNO_TO_QADDR( q_no ) ( (ASC_QADR_BEG)+( ( int )(q_no) << 6 ) )
-
-typedef struct asc_scisq_1 {
- uchar status;
- uchar q_no;
- uchar cntl;
- uchar sg_queue_cnt;
-
- uchar target_id;
- uchar target_lun;
-
- ulong data_addr;
- ulong data_cnt;
- ulong sense_addr;
- uchar sense_len;
- uchar user_def;
-} ASC_SCSIQ_1;
-
-typedef struct asc_scisq_2 {
- ulong srb_ptr;
- uchar target_ix;
-
- uchar flag;
- uchar cdb_len;
- uchar tag_code;
-
- ushort vm_id;
-} ASC_SCSIQ_2;
-
-typedef struct asc_scsiq_3 {
- uchar done_stat;
- uchar host_stat;
- uchar scsi_stat;
- uchar scsi_msg;
-} ASC_SCSIQ_3;
-
-typedef struct asc_scsiq_4 {
- uchar cdb[ASC_MAX_CDB_LEN];
- uchar y_first_sg_list_qp;
- uchar y_working_sg_qp;
- uchar y_working_sg_ix;
- uchar y_cntl;
- ushort x_req_count;
- ushort x_reconnect_rtn;
- ulong x_saved_data_addr;
- ulong x_saved_data_cnt;
-} ASC_SCSIQ_4;
-
-typedef struct asc_q_done_info {
- ASC_SCSIQ_2 d2;
- ASC_SCSIQ_3 d3;
- uchar q_status;
- uchar q_no;
- uchar cntl;
- uchar sense_len;
- uchar user_def;
- uchar res;
- ulong remain_bytes;
-} ASC_QDONE_INFO;
-
-typedef struct asc_sg_list {
- ulong addr;
- ulong bytes;
-} ASC_SG_LIST;
-
-typedef struct asc_sg_head {
- uchar entry_cnt;
-
- uchar queue_cnt;
-
- uchar entry_to_copy;
- uchar res;
- ASC_SG_LIST sg_list[ASC_MAX_SG_LIST];
-} ASC_SG_HEAD;
-
-#define ASC_MIN_SG_LIST 2
-
-typedef struct asc_min_sg_head {
- uchar entry_cnt;
-
- uchar queue_cnt;
-
- uchar entry_to_copy;
- uchar res;
- ASC_SG_LIST sg_list[ASC_MIN_SG_LIST];
-} ASC_MIN_SG_HEAD;
-
-#define QCX_SORT (0x0001)
-#define QCX_COALEASE (0x0002)
-
-#if CC_LINK_BUSY_Q
-typedef struct asc_ext_scsi_q {
- ulong lba;
- ushort lba_len;
- struct asc_scsi_q dosfar *next;
- struct asc_scsi_q dosfar *join;
- ushort cntl;
- ushort buffer_id;
- uchar q_required;
- uchar res;
-} ASC_EXT_SCSI_Q;
-
-#endif
-
-typedef struct asc_scsi_q {
- ASC_SCSIQ_1 q1;
- ASC_SCSIQ_2 q2;
- uchar dosfar *cdbptr;
-
- ASC_SG_HEAD dosfar *sg_head;
-
-#if CC_LINK_BUSY_Q
- ASC_EXT_SCSI_Q ext;
-#endif
-
-} ASC_SCSI_Q;
-
-typedef struct asc_scsi_req_q {
- ASC_SCSIQ_1 r1;
- ASC_SCSIQ_2 r2;
- uchar dosfar *cdbptr;
- ASC_SG_HEAD dosfar *sg_head;
-
-#if CC_LINK_BUSY_Q
- ASC_EXT_SCSI_Q ext;
-#endif
-
- uchar dosfar *sense_ptr;
-
- ASC_SCSIQ_3 r3;
- uchar cdb[ASC_MAX_CDB_LEN];
- uchar sense[ASC_MIN_SENSE_LEN];
-} ASC_SCSI_REQ_Q;
-
-typedef struct asc_risc_q {
- uchar fwd;
- uchar bwd;
- ASC_SCSIQ_1 i1;
- ASC_SCSIQ_2 i2;
- ASC_SCSIQ_3 i3;
- ASC_SCSIQ_4 i4;
-} ASC_RISC_Q;
-
-typedef struct asc_sg_list_q {
-
- uchar seq_no;
- uchar q_no;
- uchar cntl;
- uchar sg_head_qp;
- uchar sg_list_cnt;
- uchar sg_cur_list_cnt;
-
-} ASC_SG_LIST_Q;
-
-typedef struct asc_risc_sg_list_q {
- uchar fwd;
- uchar bwd;
- ASC_SG_LIST_Q sg;
- ASC_SG_LIST sg_list[7];
-} ASC_RISC_SG_LIST_Q;
-
-#define ASC_EXE_SCSI_IO_MAX_IDLE_LOOP 0x1000000UL
-#define ASC_EXE_SCSI_IO_MAX_WAIT_LOOP 1024
-
-#define ASCQ_ERR_NO_ERROR 0
-#define ASCQ_ERR_IO_NOT_FOUND 1
-#define ASCQ_ERR_LOCAL_MEM 2
-#define ASCQ_ERR_CHKSUM 3
-#define ASCQ_ERR_START_CHIP 4
-#define ASCQ_ERR_INT_TARGET_ID 5
-#define ASCQ_ERR_INT_LOCAL_MEM 6
-#define ASCQ_ERR_HALT_RISC 7
-#define ASCQ_ERR_GET_ASPI_ENTRY 8
-#define ASCQ_ERR_CLOSE_ASPI 9
-#define ASCQ_ERR_HOST_INQUIRY 0x0A
-#define ASCQ_ERR_SAVED_SRB_BAD 0x0B
-#define ASCQ_ERR_QCNTL_SG_LIST 0x0C
-#define ASCQ_ERR_Q_STATUS 0x0D
-#define ASCQ_ERR_WR_SCSIQ 0x0E
-#define ASCQ_ERR_PC_ADDR 0x0F
-#define ASCQ_ERR_SYN_OFFSET 0x10
-#define ASCQ_ERR_SYN_XFER_TIME 0x11
-#define ASCQ_ERR_LOCK_DMA 0x12
-#define ASCQ_ERR_UNLOCK_DMA 0x13
-#define ASCQ_ERR_VDS_CHK_INSTALL 0x14
-#define ASCQ_ERR_MICRO_CODE_HALT 0x15
-#define ASCQ_ERR_SET_LRAM_ADDR 0x16
-#define ASCQ_ERR_CUR_QNG 0x17
-#define ASCQ_ERR_SG_Q_LINKS 0x18
-#define ASCQ_ERR_SCSIQ_PTR 0x19
-#define ASCQ_ERR_ISR_RE_ENTRY 0x1A
-#define ASCQ_ERR_CRITICAL_RE_ENTRY 0x1B
-#define ASCQ_ERR_ISR_ON_CRITICAL 0x1C
-#define ASCQ_ERR_SG_LIST_ODD_ADDRESS 0x1D
-#define ASCQ_ERR_XFER_ADDRESS_TOO_BIG 0x1E
-#define ASCQ_ERR_SCSIQ_NULL_PTR 0x1F
-#define ASCQ_ERR_SCSIQ_BAD_NEXT_PTR 0x20
-#define ASCQ_ERR_GET_NUM_OF_FREE_Q 0x21
-#define ASCQ_ERR_SEND_SCSI_Q 0x22
-#define ASCQ_ERR_HOST_REQ_RISC_HALT 0x23
-#define ASCQ_ERR_RESET_SDTR 0x24
-
-#define ASC_WARN_NO_ERROR 0x0000
-#define ASC_WARN_IO_PORT_ROTATE 0x0001
-#define ASC_WARN_EEPROM_CHKSUM 0x0002
-#define ASC_WARN_IRQ_MODIFIED 0x0004
-#define ASC_WARN_AUTO_CONFIG 0x0008
-#define ASC_WARN_CMD_QNG_CONFLICT 0x0010
-
-#define ASC_WARN_EEPROM_RECOVER 0x0020
-#define ASC_WARN_CFG_MSW_RECOVER 0x0040
-
-#define ASC_IERR_WRITE_EEPROM 0x0001
-#define ASC_IERR_MCODE_CHKSUM 0x0002
-#define ASC_IERR_SET_PC_ADDR 0x0004
-#define ASC_IERR_START_STOP_CHIP 0x0008
-
-#define ASC_IERR_IRQ_NO 0x0010
-
-#define ASC_IERR_SET_IRQ_NO 0x0020
-#define ASC_IERR_CHIP_VERSION 0x0040
-#define ASC_IERR_SET_SCSI_ID 0x0080
-#define ASC_IERR_GET_PHY_ADDR 0x0100
-#define ASC_IERR_BAD_SIGNATURE 0x0200
-#define ASC_IERR_NO_BUS_TYPE 0x0400
-#define ASC_IERR_SCAM 0x0800
-#define ASC_IERR_SET_SDTR 0x1000
-#define ASC_IERR_RW_LRAM 0x8000
-
-#define ASC_DEF_IRQ_NO 10
-#define ASC_MAX_IRQ_NO 15
-#define ASC_MIN_IRQ_NO 10
-
-#define ASC_MIN_REMAIN_Q (0x02)
-#define ASC_DEF_MAX_TOTAL_QNG (0x40)
-
-#define ASC_MIN_TAG_Q_PER_DVC (0x04)
-#define ASC_DEF_TAG_Q_PER_DVC (0x04)
-
-#define ASC_MIN_FREE_Q ASC_MIN_REMAIN_Q
-
-#define ASC_MIN_TOTAL_QNG (( ASC_MAX_SG_QUEUE )+( ASC_MIN_FREE_Q ))
-
-#define ASC_MAX_TOTAL_QNG 240
-#define ASC_MAX_PCI_INRAM_TOTAL_QNG 20
-
-#define ASC_MAX_INRAM_TAG_QNG 16
-
-typedef struct asc_dvc_cfg {
- ASC_SCSI_BIT_ID_TYPE can_tagged_qng;
-
- ASC_SCSI_BIT_ID_TYPE cmd_qng_enabled;
- ASC_SCSI_BIT_ID_TYPE disc_enable;
- uchar res;
- uchar chip_scsi_id:4;
-
- uchar isa_dma_speed:4;
-
- uchar isa_dma_channel;
- uchar chip_version;
- ushort pci_device_id;
- ushort lib_serial_no;
- ushort lib_version;
- ushort mcode_date;
- ushort mcode_version;
- uchar sdtr_data[ASC_MAX_TID + 1];
- uchar max_tag_qng[ASC_MAX_TID + 1];
- uchar dosfar *overrun_buf;
-
-} ASC_DVC_CFG;
-
-#define ASC_DEF_DVC_CNTL 0xFFFF
-#define ASC_DEF_CHIP_SCSI_ID 7
-#define ASC_DEF_ISA_DMA_SPEED 4
-
-#define ASC_INIT_STATE_NULL 0x0000
-#define ASC_INIT_STATE_BEG_GET_CFG 0x0001
-#define ASC_INIT_STATE_END_GET_CFG 0x0002
-#define ASC_INIT_STATE_BEG_SET_CFG 0x0004
-#define ASC_INIT_STATE_END_SET_CFG 0x0008
-#define ASC_INIT_STATE_BEG_LOAD_MC 0x0010
-#define ASC_INIT_STATE_END_LOAD_MC 0x0020
-#define ASC_INIT_STATE_BEG_INQUIRY 0x0040
-#define ASC_INIT_STATE_END_INQUIRY 0x0080
-#define ASC_INIT_RESET_SCSI_DONE 0x0100
-
-#define ASC_PCI_DEVICE_ID_REV_A 0x1100
-#define ASC_PCI_DEVICE_ID_REV_B 0x1200
-
-#define ASC_BUG_FIX_ADD_ONE_BYTE 0x0001
-
-#define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41
-
-#define ASC_MIN_TAGGED_CMD 7
-
-typedef struct asc_dvc_var {
- PortAddr iop_base;
- ushort err_code;
- ushort dvc_cntl;
- ushort bug_fix_cntl;
- ushort bus_type;
- Ptr2Func isr_callback;
- Ptr2Func exe_callback;
-
- ASC_SCSI_BIT_ID_TYPE init_sdtr;
-
- ASC_SCSI_BIT_ID_TYPE sdtr_done;
-
- ASC_SCSI_BIT_ID_TYPE use_tagged_qng;
-
- ASC_SCSI_BIT_ID_TYPE unit_not_ready;
-
- ASC_SCSI_BIT_ID_TYPE queue_full_or_busy;
-
- ASC_SCSI_BIT_ID_TYPE start_motor;
- uchar scsi_reset_wait;
- uchar chip_no;
-
- char is_in_int;
- uchar max_total_qng;
-
- uchar cur_total_qng;
-
- uchar in_critical_cnt;
-
- uchar irq_no;
- uchar last_q_shortage;
-
- ushort init_state;
- uchar cur_dvc_qng[ASC_MAX_TID + 1];
- uchar max_dvc_qng[ASC_MAX_TID + 1];
-
- ASC_SCSI_Q dosfar *scsiq_busy_head[ASC_MAX_TID + 1];
- ASC_SCSI_Q dosfar *scsiq_busy_tail[ASC_MAX_TID + 1];
-
- ulong int_count;
- ulong req_count;
- ulong busy_count;
-
- ASC_DVC_CFG dosfar *cfg;
- Ptr2Func saved_ptr2func;
- ulong reserved2;
- ulong reserved3;
- ulong max_dma_count;
- ASC_SCSI_BIT_ID_TYPE no_scam;
- ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer;
-} ASC_DVC_VAR;
-
-typedef int (dosfar * ASC_ISR_CALLBACK) (ASC_DVC_VAR asc_ptr_type *, ASC_QDONE_INFO dosfar *);
-typedef int (dosfar * ASC_EXE_CALLBACK) (ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_Q dosfar *);
-
-typedef struct asc_dvc_inq_info {
- uchar type[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
-} ASC_DVC_INQ_INFO;
-
-typedef struct asc_cap_info {
- ulong lba;
- ulong blk_size;
-} ASC_CAP_INFO;
-
-typedef struct asc_cap_info_array {
- ASC_CAP_INFO cap_info[ASC_MAX_TID + 1][ASC_MAX_LUN + 1];
-} ASC_CAP_INFO_ARRAY;
-
-#define ASC_IOADR_TABLE_MAX_IX 11
-#define ASC_IOADR_GAP 0x10
-#define ASC_SEARCH_IOP_GAP 0x10
-#define ASC_MIN_IOP_ADDR ( PortAddr )0x0100
-#define ASC_MAX_IOP_ADDR ( PortAddr )0x3F0
-
-#define ASC_IOADR_1 ( PortAddr )0x0110
-#define ASC_IOADR_2 ( PortAddr )0x0130
-#define ASC_IOADR_3 ( PortAddr )0x0150
-#define ASC_IOADR_4 ( PortAddr )0x0190
-#define ASC_IOADR_5 ( PortAddr )0x0210
-#define ASC_IOADR_6 ( PortAddr )0x0230
-#define ASC_IOADR_7 ( PortAddr )0x0250
-#define ASC_IOADR_8 ( PortAddr )0x0330
-#define ASC_IOADR_DEF ASC_IOADR_8
-
-#define ASC_SYN_XFER_NO 8
-#define ASC_MAX_SDTR_PERIOD_INDEX 7
-#define ASC_SYN_MAX_OFFSET 0x0F
-#define ASC_DEF_SDTR_OFFSET 0x0F
-#define ASC_DEF_SDTR_INDEX 0x00
-
-#define SYN_XFER_NS_0 25
-#define SYN_XFER_NS_1 30
-#define SYN_XFER_NS_2 35
-#define SYN_XFER_NS_3 40
-#define SYN_XFER_NS_4 50
-#define SYN_XFER_NS_5 60
-#define SYN_XFER_NS_6 70
-#define SYN_XFER_NS_7 85
-
-#define ASC_SDTR_PERIOD_IX_MIN 7
-
-#define SYN_XMSG_WLEN 3
-
-typedef struct sdtr_xmsg {
- uchar msg_type;
- uchar msg_len;
- uchar msg_req;
- uchar xfer_period;
- uchar req_ack_offset;
- uchar res;
-} SDTR_XMSG;
-
-#define ASC_MCNTL_NO_SEL_TIMEOUT ( ushort )0x0001
-#define ASC_MCNTL_NULL_TARGET ( ushort )0x0002
-
-#define ASC_CNTL_INITIATOR ( ushort )0x0001
-#define ASC_CNTL_BIOS_GT_1GB ( ushort )0x0002
-#define ASC_CNTL_BIOS_GT_2_DISK ( ushort )0x0004
-#define ASC_CNTL_BIOS_REMOVABLE ( ushort )0x0008
-#define ASC_CNTL_NO_SCAM ( ushort )0x0010
-#define ASC_CNTL_NO_PCI_FIX_ASYN_XFER ( ushort )0x0020
-
-#define ASC_CNTL_INT_MULTI_Q ( ushort )0x0080
-
-#define ASC_CNTL_NO_LUN_SUPPORT ( ushort )0x0040
-
-#define ASC_CNTL_NO_VERIFY_COPY ( ushort )0x0100
-#define ASC_CNTL_RESET_SCSI ( ushort )0x0200
-#define ASC_CNTL_INIT_INQUIRY ( ushort )0x0400
-#define ASC_CNTL_INIT_VERBOSE ( ushort )0x0800
-
-#define ASC_CNTL_SCSI_PARITY ( ushort )0x1000
-#define ASC_CNTL_BURST_MODE ( ushort )0x2000
-
-#define ASC_CNTL_USE_8_IOP_BASE ( ushort )0x4000
-
-#define ASC_EEP_DVC_CFG_BEG_VL 2
-#define ASC_EEP_MAX_DVC_ADDR_VL 15
-
-#define ASC_EEP_DVC_CFG_BEG 32
-#define ASC_EEP_MAX_DVC_ADDR 45
-
-#define ASC_EEP_DEFINED_WORDS 10
-#define ASC_EEP_MAX_ADDR 63
-#define ASC_EEP_RES_WORDS 0
-#define ASC_EEP_MAX_RETRY 20
-#define ASC_MAX_INIT_BUSY_RETRY 8
-
-#define ASC_EEP_ISA_PNP_WSIZE 16
-
-typedef struct asceep_config {
- ushort cfg_lsw;
- ushort cfg_msw;
-
- uchar init_sdtr;
- uchar disc_enable;
-
- uchar use_cmd_qng;
-
- uchar start_motor;
- uchar max_total_qng;
- uchar max_tag_qng;
- uchar bios_scan;
-
- uchar power_up_wait;
-
- uchar no_scam;
- uchar chip_scsi_id:4;
-
- uchar isa_dma_speed:4;
-
- uchar sdtr_data[ASC_MAX_TID + 1];
-
- uchar adapter_info[6];
-
- ushort cntl;
-
- ushort chksum;
-} ASCEEP_CONFIG;
-
-#define ASC_EEP_CMD_READ 0x80
-#define ASC_EEP_CMD_WRITE 0x40
-#define ASC_EEP_CMD_WRITE_ABLE 0x30
-#define ASC_EEP_CMD_WRITE_DISABLE 0x00
-
-#define ASC_OVERRUN_BSIZE 0x00000048UL
-
-#define ASCV_MSGOUT_BEG 0x0000
-#define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3)
-#define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4)
-
-#define ASCV_MSGIN_BEG (ASCV_MSGOUT_BEG+8)
-#define ASCV_MSGIN_SDTR_PERIOD (ASCV_MSGIN_BEG+3)
-#define ASCV_MSGIN_SDTR_OFFSET (ASCV_MSGIN_BEG+4)
-
-#define ASCV_SDTR_DATA_BEG (ASCV_MSGIN_BEG+8)
-#define ASCV_SDTR_DONE_BEG (ASCV_SDTR_DATA_BEG+8)
-#define ASCV_MAX_DVC_QNG_BEG ( ushort )0x0020
-
-#define ASCV_ASCDVC_ERR_CODE_W ( ushort )0x0030
-#define ASCV_MCODE_CHKSUM_W ( ushort )0x0032
-#define ASCV_MCODE_SIZE_W ( ushort )0x0034
-#define ASCV_STOP_CODE_B ( ushort )0x0036
-#define ASCV_DVC_ERR_CODE_B ( ushort )0x0037
-
-#define ASCV_OVERRUN_PADDR_D ( ushort )0x0038
-#define ASCV_OVERRUN_BSIZE_D ( ushort )0x003C
-
-#define ASCV_HALTCODE_W ( ushort )0x0040
-#define ASCV_CHKSUM_W ( ushort )0x0042
-#define ASCV_MC_DATE_W ( ushort )0x0044
-#define ASCV_MC_VER_W ( ushort )0x0046
-#define ASCV_NEXTRDY_B ( ushort )0x0048
-#define ASCV_DONENEXT_B ( ushort )0x0049
-#define ASCV_USE_TAGGED_QNG_B ( ushort )0x004A
-#define ASCV_SCSIBUSY_B ( ushort )0x004B
-#define ASCV_CDBCNT_B ( ushort )0x004C
-#define ASCV_CURCDB_B ( ushort )0x004D
-#define ASCV_RCLUN_B ( ushort )0x004E
-#define ASCV_BUSY_QHEAD_B ( ushort )0x004F
-#define ASCV_DISC1_QHEAD_B ( ushort )0x0050
-
-#define ASCV_DISC_ENABLE_B ( ushort )0x0052
-#define ASCV_CAN_TAGGED_QNG_B ( ushort )0x0053
-#define ASCV_HOSTSCSI_ID_B ( ushort )0x0055
-#define ASCV_MCODE_CNTL_B ( ushort )0x0056
-#define ASCV_NULL_TARGET_B ( ushort )0x0057
-
-#define ASCV_FREE_Q_HEAD_W ( ushort )0x0058
-#define ASCV_DONE_Q_TAIL_W ( ushort )0x005A
-#define ASCV_FREE_Q_HEAD_B ( ushort )(ASCV_FREE_Q_HEAD_W+1)
-#define ASCV_DONE_Q_TAIL_B ( ushort )(ASCV_DONE_Q_TAIL_W+1)
-
-#define ASCV_HOST_FLAG_B ( ushort )0x005D
-
-#define ASCV_TOTAL_READY_Q_B ( ushort )0x0064
-#define ASCV_VER_SERIAL_B ( ushort )0x0065
-#define ASCV_HALTCODE_SAVED_W ( ushort )0x0066
-#define ASCV_WTM_FLAG_B ( ushort )0x0068
-#define ASCV_RISC_FLAG_B ( ushort )0x006A
-#define ASCV_REQ_SG_LIST_QP ( ushort )0x006B
-
-#define ASC_HOST_FLAG_IN_ISR 0x01
-#define ASC_HOST_FLAG_ACK_INT 0x02
-
-#define ASC_RISC_FLAG_GEN_INT 0x01
-#define ASC_RISC_FLAG_REQ_SG_LIST 0x02
-
-#define IOP_CTRL (0x0F)
-#define IOP_STATUS (0x0E)
-#define IOP_INT_ACK IOP_STATUS
-
-#define IOP_REG_IFC (0x0D)
-
-#define IOP_SYN_OFFSET (0x0B)
-#define IOP_REG_PC (0x0C)
-#define IOP_RAM_ADDR (0x0A)
-#define IOP_RAM_DATA (0x08)
-#define IOP_EEP_DATA (0x06)
-#define IOP_EEP_CMD (0x07)
-
-#define IOP_VERSION (0x03)
-#define IOP_CONFIG_HIGH (0x04)
-#define IOP_CONFIG_LOW (0x02)
-#define IOP_ASPI_ID_LOW (0x01)
-#define IOP_ASPI_ID_HIGH (0x00)
-
-#define IOP_REG_DC1 (0x0E)
-#define IOP_REG_DC0 (0x0C)
-#define IOP_REG_SB (0x0B)
-#define IOP_REG_DA1 (0x0A)
-#define IOP_REG_DA0 (0x08)
-#define IOP_REG_SC (0x09)
-#define IOP_DMA_SPEED (0x07)
-#define IOP_REG_FLAG (0x07)
-#define IOP_FIFO_H (0x06)
-#define IOP_FIFO_L (0x04)
-#define IOP_REG_ID (0x05)
-#define IOP_REG_QP (0x03)
-#define IOP_REG_IH (0x02)
-#define IOP_REG_IX (0x01)
-#define IOP_REG_AX (0x00)
-
-#define IFC_REG_LOCK (0x00)
-#define IFC_REG_UNLOCK (0x09)
-
-#define IFC_WR_EN_FILTER (0x10)
-#define IFC_RD_NO_EEPROM (0x10)
-#define IFC_SLEW_RATE (0x20)
-#define IFC_ACT_NEG (0x40)
-#define IFC_INP_FILTER (0x80)
-
-#define IFC_INIT_DEFAULT ( IFC_ACT_NEG | IFC_REG_UNLOCK )
-
-#define SC_SEL (0x80)
-#define SC_BSY (0x40)
-#define SC_ACK (0x20)
-#define SC_REQ (0x10)
-#define SC_ATN (0x08)
-#define SC_IO (0x04)
-#define SC_CD (0x02)
-#define SC_MSG (0x01)
-
-#define AscGetVarFreeQHead( port ) AscReadLramWord( port, ASCV_FREE_Q_HEAD_W )
-#define AscGetVarDoneQTail( port ) AscReadLramWord( port, ASCV_DONE_Q_TAIL_W )
-#define AscPutVarFreeQHead( port, val ) AscWriteLramWord( port, ASCV_FREE_Q_HEAD_W, val )
-#define AscPutVarDoneQTail( port, val ) AscWriteLramWord( port, ASCV_DONE_Q_TAIL_W, val )
-
-#define AscGetRiscVarFreeQHead( port ) AscReadLramByte( port, ASCV_NEXTRDY_B )
-#define AscGetRiscVarDoneQTail( port ) AscReadLramByte( port, ASCV_DONENEXT_B )
-#define AscPutRiscVarFreeQHead( port, val ) AscWriteLramByte( port, ASCV_NEXTRDY_B, val )
-#define AscPutRiscVarDoneQTail( port, val ) AscWriteLramByte( port, ASCV_DONENEXT_B, val )
-
-#define AscGetChipIFC( port ) inp( (port)+IOP_REG_IFC )
-#define AscPutChipIFC( port, data ) outp( (port)+IOP_REG_IFC, data )
-
-#define AscGetChipLramAddr( port ) ( ushort )inpw( ( PortAddr )((port)+IOP_RAM_ADDR) )
-#define AscSetChipLramAddr( port, addr ) outpw( ( PortAddr )( (port)+IOP_RAM_ADDR ), addr )
-#define AscPutChipLramData( port, data ) outpw( (port)+IOP_RAM_DATA, data )
-#define AscGetChipLramData( port ) inpw( (port)+IOP_RAM_DATA )
-
-#define AscWriteChipSyn( port, data ) outp( (port)+IOP_SYN_OFFSET, data )
-#define AscReadChipSyn( port ) inp( (port)+IOP_SYN_OFFSET )
-
-#define AscWriteChipIH( port, data ) outpw( (port)+IOP_REG_IH, data )
-#define AscReadChipIH( port ) inpw( (port)+IOP_REG_IH )
-
-#define AscWriteChipScsiID( port, data ) outp( (port)+IOP_REG_ID, data )
-#define AscReadChipScsiID( port ) inp( (port)+IOP_REG_ID )
-
-#define AscGetChipDmaSpeed( port ) ( uchar )inp( (port)+IOP_DMA_SPEED )
-#define AscSetChipDmaSpeed( port, data ) outp( (port)+IOP_DMA_SPEED, data )
-#define AscGetChipQP( port ) ( uchar )inp( (port)+IOP_REG_QP )
-#define AscSetPCAddr( port, data ) outpw( (port)+IOP_REG_PC, data )
-#define AscGetPCAddr( port ) inpw( (port)+IOP_REG_PC )
-#define AscGetChipVerNo( port ) ( uchar )inp( (port)+IOP_VERSION )
-
-#define AscGetChipEEPCmd( port ) ( uchar )inp( (port)+IOP_EEP_CMD )
-#define AscSetChipEEPCmd( port, data ) outp( (port)+IOP_EEP_CMD, data )
-#define AscGetChipEEPData( port ) inpw( (port)+IOP_EEP_DATA )
-#define AscSetChipEEPData( port, data ) outpw( (port)+IOP_EEP_DATA, data )
-
-#define AscGetChipControl( port ) ( uchar )inp( (port)+IOP_CTRL )
-#define AscSetChipControl( port, cc_val ) outp( (port)+IOP_CTRL, cc_val )
-
-#define AscGetChipStatus( port ) ( ASC_CS_TYPE )inpw( (port)+IOP_STATUS )
-#define AscSetChipStatus( port, cs_val ) outpw( (port)+IOP_STATUS, cs_val )
-
-#define AscGetChipCfgLsw( port ) ( ushort )inpw( (port)+IOP_CONFIG_LOW )
-#define AscGetChipCfgMsw( port ) ( ushort )inpw( (port)+IOP_CONFIG_HIGH )
-#define AscSetChipCfgLsw( port, data ) outpw( (port)+IOP_CONFIG_LOW, data )
-#define AscSetChipCfgMsw( port, data ) outpw( (port)+IOP_CONFIG_HIGH, data )
-
-#define AscIsIntPending( port ) ( AscGetChipStatus( port ) & CSW_INT_PENDING )
-#define AscGetChipScsiID( port ) ( ( AscGetChipCfgLsw( port ) >> 8 ) & ASC_MAX_TID )
-
-#define ASC_HALT_EXTMSG_IN ( ushort )0x8000
-#define ASC_HALT_CHK_CONDITION ( ushort )0x8100
-#define ASC_HALT_SS_QUEUE_FULL ( ushort )0x8200
-#define ASC_HALT_SDTR_REJECTED ( ushort )0x4000
-
-#define ASC_MAX_QNO 0xF8
-#define ASC_DATA_SEC_BEG ( ushort )0x0080
-#define ASC_DATA_SEC_END ( ushort )0x0080
-#define ASC_CODE_SEC_BEG ( ushort )0x0080
-#define ASC_CODE_SEC_END ( ushort )0x0080
-#define ASC_QADR_BEG (0x4000)
-#define ASC_QADR_USED ( ushort )( ASC_MAX_QNO * 64 )
-#define ASC_QADR_END ( ushort )0x7FFF
-#define ASC_QLAST_ADR ( ushort )0x7FC0
-#define ASC_QBLK_SIZE 0x40
-#define ASC_BIOS_DATA_QBEG 0xF8
-
-#define ASC_MIN_ACTIVE_QNO 0x01
-
-#define ASC_QLINK_END 0xFF
-#define ASC_EEPROM_WORDS 0x10
-#define ASC_MAX_MGS_LEN 0x10
-
-#define ASC_BIOS_ADDR_DEF 0xDC00
-#define ASC_BIOS_SIZE 0x3800
-#define ASC_BIOS_RAM_OFF 0x3800
-#define ASC_BIOS_RAM_SIZE 0x800
-#define ASC_BIOS_MIN_ADDR 0xC000
-#define ASC_BIOS_MAX_ADDR 0xEC00
-#define ASC_BIOS_BANK_SIZE 0x0400
-
-#define ASC_MCODE_START_ADDR 0x0080
-
-#define ASC_CFG0_HOST_INT_ON 0x0020
-#define ASC_CFG0_BIOS_ON 0x0040
-#define ASC_CFG0_VERA_BURST_ON 0x0080
-#define ASC_CFG0_SCSI_PARITY_ON 0x0800
-
-#define ASC_CFG1_SCSI_TARGET_ON 0x0080
-#define ASC_CFG1_LRAM_8BITS_ON 0x0800
-
-#define ASC_CFG_MSW_CLR_MASK 0xF0C0
-
-#define CSW_TEST1 ( ASC_CS_TYPE )0x8000
-#define CSW_AUTO_CONFIG ( ASC_CS_TYPE )0x4000
-#define CSW_RESERVED1 ( ASC_CS_TYPE )0x2000
-#define CSW_IRQ_WRITTEN ( ASC_CS_TYPE )0x1000
-#define CSW_33MHZ_SELECTED ( ASC_CS_TYPE )0x0800
-#define CSW_TEST2 ( ASC_CS_TYPE )0x0400
-#define CSW_TEST3 ( ASC_CS_TYPE )0x0200
-#define CSW_RESERVED2 ( ASC_CS_TYPE )0x0100
-#define CSW_DMA_DONE ( ASC_CS_TYPE )0x0080
-#define CSW_FIFO_RDY ( ASC_CS_TYPE )0x0040
-
-#define CSW_EEP_READ_DONE ( ASC_CS_TYPE )0x0020
-
-#define CSW_HALTED ( ASC_CS_TYPE )0x0010
-#define CSW_SCSI_RESET_ACTIVE ( ASC_CS_TYPE )0x0008
-
-#define CSW_PARITY_ERR ( ASC_CS_TYPE )0x0004
-#define CSW_SCSI_RESET_LATCH ( ASC_CS_TYPE )0x0002
-
-#define CSW_INT_PENDING ( ASC_CS_TYPE )0x0001
-
-#define CIW_INT_ACK ( ASC_CS_TYPE )0x0100
-#define CIW_TEST1 ( ASC_CS_TYPE )0x0200
-#define CIW_TEST2 ( ASC_CS_TYPE )0x0400
-#define CIW_SEL_33MHZ ( ASC_CS_TYPE )0x0800
-
-#define CIW_IRQ_ACT ( ASC_CS_TYPE )0x1000
-
-#define CC_CHIP_RESET ( uchar )0x80
-#define CC_SCSI_RESET ( uchar )0x40
-#define CC_HALT ( uchar )0x20
-#define CC_SINGLE_STEP ( uchar )0x10
-#define CC_DMA_ABLE ( uchar )0x08
-#define CC_TEST ( uchar )0x04
-#define CC_BANK_ONE ( uchar )0x02
-#define CC_DIAG ( uchar )0x01
-
-#define ASC_1000_ID0W 0x04C1
-#define ASC_1000_ID0W_FIX 0x00C1
-#define ASC_1000_ID1B 0x25
-
-#define ASC_EISA_BIG_IOP_GAP (0x1C30-0x0C50)
-#define ASC_EISA_SMALL_IOP_GAP (0x0020)
-#define ASC_EISA_MIN_IOP_ADDR (0x0C30)
-#define ASC_EISA_MAX_IOP_ADDR (0xFC50)
-#define ASC_EISA_REV_IOP_MASK (0x0C83)
-#define ASC_EISA_PID_IOP_MASK (0x0C80)
-#define ASC_EISA_CFG_IOP_MASK (0x0C86)
-
-#define ASC_GET_EISA_SLOT( iop ) ( PortAddr )( (iop) & 0xF000 )
-
-#define ASC_EISA_ID_740 0x01745004UL
-#define ASC_EISA_ID_750 0x01755004UL
-
-#define INS_HALTINT ( ushort )0x6281
-#define INS_HALT ( ushort )0x6280
-#define INS_SINT ( ushort )0x6200
-#define INS_RFLAG_WTM ( ushort )0x7380
-
-#define ASC_MC_SAVE_CODE_WSIZE 0x500
-#define ASC_MC_SAVE_DATA_WSIZE 0x40
-
-typedef struct asc_mc_saved {
- ushort data[ASC_MC_SAVE_DATA_WSIZE];
- ushort code[ASC_MC_SAVE_CODE_WSIZE];
-} ASC_MC_SAVED;
-
-int AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg);
-int AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg);
-void AscWaitEEPRead(void);
-void AscWaitEEPWrite(void);
-ushort AscReadEEPWord(PortAddr, uchar);
-ushort AscWriteEEPWord(PortAddr, uchar, ushort);
-ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG dosfar *, ushort);
-int AscSetEEPConfigOnce(PortAddr, ASCEEP_CONFIG dosfar *, ushort);
-int AscSetEEPConfig(PortAddr, ASCEEP_CONFIG dosfar *, ushort);
-ushort AscEEPSum(PortAddr, uchar, uchar);
-
-int AscStartChip(PortAddr);
-int AscStopChip(PortAddr);
-void AscSetChipIH(PortAddr, ushort);
-int AscSetRunChipSynRegAtID(PortAddr, uchar, uchar);
-
-int AscIsChipHalted(PortAddr);
-
-void AscSetChipCfgDword(PortAddr, ulong);
-ulong AscGetChipCfgDword(PortAddr);
-
-void AscAckInterrupt(PortAddr);
-void AscDisableInterrupt(PortAddr);
-void AscEnableInterrupt(PortAddr);
-void AscSetBank(PortAddr, uchar);
-uchar AscGetBank(PortAddr);
-int AscResetChipAndScsiBus(PortAddr);
-ushort AscGetIsaDmaChannel(PortAddr);
-ushort AscSetIsaDmaChannel(PortAddr, ushort);
-uchar AscSetIsaDmaSpeed(PortAddr, uchar);
-uchar AscGetIsaDmaSpeed(PortAddr);
-
-uchar AscReadLramByte(PortAddr, ushort);
-ushort AscReadLramWord(PortAddr, ushort);
-ulong AscReadLramDWord(PortAddr, ushort);
-void AscWriteLramWord(PortAddr, ushort, ushort);
-void AscWriteLramDWord(PortAddr, ushort, ulong);
-void AscWriteLramByte(PortAddr, ushort, uchar);
-int AscVerWriteLramDWord(PortAddr, ushort, ulong);
-int AscVerWriteLramWord(PortAddr, ushort, ushort);
-int AscVerWriteLramByte(PortAddr, ushort, uchar);
-
-ulong AscMemSumLramWord(PortAddr, ushort, int);
-void AscMemWordSetLram(PortAddr, ushort, ushort, int);
-void AscMemWordCopyToLram(PortAddr, ushort, ushort dosfar *, int);
-void AscMemDWordCopyToLram(PortAddr, ushort, ulong dosfar *, int);
-void AscMemWordCopyFromLram(PortAddr, ushort, ushort dosfar *, int);
-int AscMemWordCmpToLram(PortAddr, ushort, ushort dosfar *, int);
-
-ushort AscInitAscDvcVar(ASC_DVC_VAR asc_ptr_type *);
-ulong AscLoadMicroCode(PortAddr, ushort,
- ushort dosfar *, ushort);
-ushort AscInitFromEEP(ASC_DVC_VAR asc_ptr_type *);
-ushort AscInitFromAscDvcVar(ASC_DVC_VAR asc_ptr_type *);
-ushort AscInitMicroCodeVar(ASC_DVC_VAR asc_ptr_type * asc_dvc);
-
-void dosfar AscInitPollIsrCallBack(ASC_DVC_VAR asc_ptr_type *,
- ASC_QDONE_INFO dosfar *);
-int AscTestExternalLram(ASC_DVC_VAR asc_ptr_type *);
-ushort AscTestLramEndian(PortAddr);
-
-uchar AscMsgOutSDTR(PortAddr, uchar, uchar);
-
-uchar AscCalSDTRData(uchar, uchar);
-void AscSetChipSDTR(PortAddr, uchar, uchar);
-int AscInitChipAllSynReg(ASC_DVC_VAR asc_ptr_type *, uchar);
-uchar AscGetSynPeriodIndex(uchar);
-uchar AscSynIndexToPeriod(uchar);
-uchar AscAllocFreeQueue(PortAddr, uchar);
-uchar AscAllocMultipleFreeQueue(PortAddr, uchar, uchar);
-int AscRiscHaltedAbortSRB(ASC_DVC_VAR asc_ptr_type *, ulong);
-int AscRiscHaltedAbortTIX(ASC_DVC_VAR asc_ptr_type *, uchar);
-int AscRiscHaltedAbortALL(ASC_DVC_VAR asc_ptr_type *);
-int AscHostReqRiscHalt(PortAddr);
-int AscStopQueueExe(PortAddr);
-int AscStartQueueExe(PortAddr);
-int AscCleanUpDiscQueue(PortAddr);
-int AscCleanUpBusyQueue(PortAddr);
-int _AscAbortTidBusyQueue(ASC_DVC_VAR asc_ptr_type *,
- ASC_QDONE_INFO dosfar *, uchar);
-int _AscAbortSrbBusyQueue(ASC_DVC_VAR asc_ptr_type *,
- ASC_QDONE_INFO dosfar *, ulong);
-int AscWaitTixISRDone(ASC_DVC_VAR asc_ptr_type *, uchar);
-int AscWaitISRDone(ASC_DVC_VAR asc_ptr_type *);
-ulong AscGetOnePhyAddr(ASC_DVC_VAR asc_ptr_type *, uchar dosfar *, ulong);
-
-int AscSendScsiQueue(ASC_DVC_VAR asc_ptr_type * asc_dvc,
- ASC_SCSI_Q dosfar * scsiq,
- uchar n_q_required);
-int AscPutReadyQueue(ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_Q dosfar *, uchar);
-int AscPutReadySgListQueue(ASC_DVC_VAR asc_ptr_type *,
- ASC_SCSI_Q dosfar *, uchar);
-int AscAbortScsiIO(ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_Q dosfar *);
-void AscExeScsiIO(ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_Q dosfar *);
-int AscSetChipSynRegAtID(PortAddr, uchar, uchar);
-int AscSetRunChipSynRegAtID(PortAddr, uchar, uchar);
-ushort AscInitLram(ASC_DVC_VAR asc_ptr_type *);
-int AscReInitLram(ASC_DVC_VAR asc_ptr_type *);
-ushort AscInitQLinkVar(ASC_DVC_VAR asc_ptr_type *);
-int AscSetLibErrorCode(ASC_DVC_VAR asc_ptr_type *, ushort);
-int _AscWaitQDone(PortAddr, ASC_SCSI_Q dosfar *);
-
-int AscEnterCritical(void);
-void AscLeaveCritical(int);
-
-int AscIsrChipHalted(ASC_DVC_VAR asc_ptr_type *);
-uchar _AscCopyLramScsiDoneQ(PortAddr, ushort,
- ASC_QDONE_INFO dosfar *, ulong);
-int AscIsrQDone(ASC_DVC_VAR asc_ptr_type *);
-ushort AscIsrExeBusyQueue(ASC_DVC_VAR asc_ptr_type *, uchar);
-int AscScsiSetupCmdQ(ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_REQ_Q dosfar *,
- uchar dosfar *, ulong);
-
-int AscScsiInquiry(ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_REQ_Q dosfar *,
- uchar dosfar *, int);
-int AscScsiTestUnitReady(ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_REQ_Q dosfar *);
-int AscScsiStartStopUnit(ASC_DVC_VAR asc_ptr_type *,
- ASC_SCSI_REQ_Q dosfar *, uchar);
-int AscScsiReadCapacity(ASC_DVC_VAR asc_ptr_type *,
- ASC_SCSI_REQ_Q dosfar *,
- uchar dosfar *);
-
-ulong dosfar *swapfarbuf4(uchar dosfar *);
-int PollQueueDone(ASC_DVC_VAR asc_ptr_type *,
- ASC_SCSI_REQ_Q dosfar *,
- int);
-int PollScsiReadCapacity(ASC_DVC_VAR asc_ptr_type *,
- ASC_SCSI_REQ_Q dosfar *,
- ASC_CAP_INFO dosfar *);
-int PollScsiInquiry(ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_REQ_Q dosfar *,
- uchar dosfar *, int);
-int PollScsiTestUnitReady(ASC_DVC_VAR asc_ptr_type *,
- ASC_SCSI_REQ_Q dosfar *);
-int PollScsiStartUnit(ASC_DVC_VAR asc_ptr_type *,
- ASC_SCSI_REQ_Q dosfar *);
-int InitTestUnitReady(ASC_DVC_VAR asc_ptr_type *,
- ASC_SCSI_REQ_Q dosfar *);
-void AscDispInquiry(uchar, uchar, ASC_SCSI_INQUIRY dosfar *);
-int AscPollQDone(ASC_DVC_VAR asc_ptr_type *,
- ASC_SCSI_REQ_Q dosfar *, int);
-
-int AscSetBIOSBank(PortAddr, int, ushort);
-int AscSetVlBIOSBank(PortAddr, int);
-int AscSetEisaBIOSBank(PortAddr, int);
-int AscSetIsaBIOSBank(PortAddr, int);
-
-int AscIsBiosEnabled(PortAddr, ushort);
-void AscResetScsiBus(PortAddr);
-void AscClrResetScsiBus(PortAddr);
-
-void AscSingleStepChip(PortAddr);
-uchar AscSetChipScsiID(PortAddr, uchar);
-ushort AscGetChipBiosAddress(PortAddr, ushort);
-ushort AscSetChipBiosAddress(PortAddr, ushort, ushort);
-uchar AscGetChipVersion(PortAddr, ushort);
-ushort AscGetChipBusType(PortAddr);
-
-PortAddr AscSearchIOPortAddr11(PortAddr);
-PortAddr AscSearchIOPortAddr100(PortAddr);
-int AscFindSignature(PortAddr);
-void AscToggleIRQAct(PortAddr);
-int AscResetChip(PortAddr);
-void AscClrResetChip(PortAddr);
-
-short itos(ushort, uchar dosfar *, short, short);
-int insnchar(uchar dosfar *, short, short, ruchar, short);
-void itoh(ushort, ruchar dosfar *);
-void btoh(uchar, ruchar dosfar *);
-void ltoh(ulong, ruchar dosfar *);
-uchar dosfar *todstr(ushort, uchar dosfar *);
-uchar dosfar *tohstr(ushort, uchar dosfar *);
-uchar dosfar *tobhstr(uchar, uchar dosfar *);
-uchar dosfar *tolhstr(ulong, uchar dosfar *);
-
-void AscSetISAPNPWaitForKey(void);
-uchar AscGetChipIRQ(PortAddr, ushort);
-uchar AscSetChipIRQ(PortAddr, uchar, ushort);
-uchar AscGetChipScsiCtrl(PortAddr);
-
-ushort AscGetEisaChipCfg(PortAddr);
-ushort AscGetEisaChipGpReg(PortAddr);
-ushort AscSetEisaChipCfg(PortAddr, ushort);
-ushort AscSetEisaChipGpReg(PortAddr, ushort);
-
-ulong AscGetEisaProductID(PortAddr);
-PortAddr AscSearchIOPortAddrEISA(PortAddr);
-
-int AscPollQTailSync(PortAddr);
-int AscPollQHeadSync(PortAddr);
-int AscWaitQTailSync(PortAddr);
-
-int _AscRestoreMicroCode(PortAddr, ASC_MC_SAVED dosfar *);
-
-int AscSCAM(ASC_DVC_VAR asc_ptr_type *);
-
-ushort SwapByteOfWord(ushort word_val);
-ulong SwapWordOfDWord(ulong dword_val);
-ulong AdjEndianDword(ulong dword_val);
-
-int AscAdjEndianScsiQ(ASC_SCSI_Q dosfar *);
-int AscAdjEndianQDoneInfo(ASC_QDONE_INFO dosfar *);
-
-extern int DvcEnterCritical(void);
-extern void DvcLeaveCritical(int);
-
-extern void DvcInPortWords(PortAddr, ushort dosfar *, int);
-extern void DvcOutPortWords(PortAddr, ushort dosfar *, int);
-extern void DvcOutPortDWords(PortAddr, ulong dosfar *, int);
-
-extern void DvcSleepMilliSecond(ulong);
-extern void DvcDisplayString(uchar dosfar *);
-extern ulong DvcGetPhyAddr(uchar dosfar * buf_addr, ulong buf_len);
-extern ulong DvcGetSGList(ASC_DVC_VAR asc_ptr_type *, uchar dosfar *, ulong,
- ASC_SG_HEAD dosfar *);
-
-extern void DvcSCAMDelayMS(ulong);
-extern int DvcDisableCPUInterrupt(void);
-extern void DvcRestoreCPUInterrupt(int);
-
-void DvcPutScsiQ(PortAddr, ushort, ushort dosfar *, int);
-void DvcGetQinfo(PortAddr, ushort, ushort dosfar *, int);
-
-PortAddr AscSearchIOPortAddr(PortAddr, ushort);
-ushort AscInitGetConfig(ASC_DVC_VAR asc_ptr_type *);
-ushort AscInitSetConfig(ASC_DVC_VAR asc_ptr_type *);
-ushort AscInitAsc1000Driver(ASC_DVC_VAR asc_ptr_type *);
-int AscInitScsiTarget(ASC_DVC_VAR asc_ptr_type *,
- ASC_DVC_INQ_INFO dosfar *,
- uchar dosfar *,
- ASC_CAP_INFO_ARRAY dosfar *,
- ushort);
-int AscInitPollBegin(ASC_DVC_VAR asc_ptr_type *);
-int AscInitPollEnd(ASC_DVC_VAR asc_ptr_type *);
-int AscInitPollTarget(ASC_DVC_VAR asc_ptr_type *,
- ASC_SCSI_REQ_Q dosfar *,
- ASC_SCSI_INQUIRY dosfar *,
- ASC_CAP_INFO dosfar *);
-int AscExeScsiQueue(ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_Q dosfar *);
-
-int AscISR(ASC_DVC_VAR asc_ptr_type *);
-void AscISR_AckInterrupt(ASC_DVC_VAR asc_ptr_type *);
-int AscISR_CheckQDone(ASC_DVC_VAR asc_ptr_type *,
- ASC_QDONE_INFO dosfar *,
- uchar dosfar *);
-
-int AscStartUnit(ASC_DVC_VAR asc_ptr_type *, ASC_SCSI_TIX_TYPE);
-int AscStopUnit(
- ASC_DVC_VAR asc_ptr_type * asc_dvc,
- ASC_SCSI_TIX_TYPE target_ix
-);
-
-uint AscGetNumOfFreeQueue(ASC_DVC_VAR asc_ptr_type *, uchar, uchar);
-int AscSgListToQueue(int);
-int AscQueueToSgList(int);
-int AscSetDvcErrorCode(ASC_DVC_VAR asc_ptr_type *, uchar);
-
-int AscAbortSRB(ASC_DVC_VAR asc_ptr_type *, ulong);
-int AscResetDevice(ASC_DVC_VAR asc_ptr_type *, uchar);
-int AscResetSB(ASC_DVC_VAR asc_ptr_type *);
-
-void AscEnableIsaDma(uchar);
-void AscDisableIsaDma(uchar);
-
-ulong AscGetMaxDmaAddress(ushort);
-ulong AscGetMaxDmaCount(ushort);
-
-int AscSaveMicroCode(ASC_DVC_VAR asc_ptr_type *, ASC_MC_SAVED dosfar *);
-int AscRestoreOldMicroCode(ASC_DVC_VAR asc_ptr_type *, ASC_MC_SAVED dosfar *);
-int AscRestoreNewMicroCode(ASC_DVC_VAR asc_ptr_type *, ASC_MC_SAVED dosfar *);
-
-/*
- * --- Debugging Header
- */
-
-#ifdef ADVANSYS_DEBUG
-#define STATIC
-#else /* ADVANSYS_DEBUG */
-#define STATIC static
-#endif /* ADVANSYS_DEBUG */
-
-
-/*
- * --- Driver Constants and Macros
- */
-
-#define ASC_NUM_BOARD_SUPPORTED 4
-#define ASC_NUM_BUS 4
-
-/* Reference Scsi_Host hostdata */
-#define ASC_BOARD(host) ((struct asc_board *) &(host)->hostdata)
-
-#define NO_ISA_DMA 0xff /* No ISA DMA Channel Used */
-
-#ifndef min
-#define min(a, b) (((a) < (b)) ? (a) : (b))
-#endif /* min */
-
-/* Asc Library return codes */
-#define ASC_TRUE 1
-#define ASC_FALSE 0
-#define ASC_NOERROR 1
-#define ASC_BUSY 0
-#define ASC_ERROR (-1)
-
-/* Scsi_Cmnd function return codes */
-#define STATUS_BYTE(byte) (byte)
-#define MSG_BYTE(byte) ((byte) << 8)
-#define HOST_BYTE(byte) ((byte) << 16)
-#define DRIVER_BYTE(byte) ((byte) << 24)
-
-/* asc_enqueue() flags */
-#define ASC_FRONT 1
-#define ASC_BACK 2
-
-/* PCI configuration declarations */
-
-#define ASC_PCI_REV_A_INIT 0x01
-#define ASC_PCI_REV_A_DONE 0x02
-#define ASC_PCI_REV_B_INIT 0x04
-#define ASC_PCI_REV_B_DONE 0x08
-
-#define PCI_BASE_CLASS_PREDEFINED 0x00
-#define PCI_BASE_CLASS_MASS_STORAGE 0x01
-#define PCI_BASE_CLASS_NETWORK 0x02
-#define PCI_BASE_CLASS_DISPLAY 0x03
-#define PCI_BASE_CLASS_MULTIMEDIA 0x04
-#define PCI_BASE_CLASS_MEMORY_CONTROLLER 0x05
-#define PCI_BASE_CLASS_BRIDGE_DEVICE 0x06
-
-/* MASS STORAGE */
-#define PCI_SUB_CLASS_SCSI_CONTROLLER 0x00
-#define PCI_SUB_CLASS_IDE_CONTROLLER 0x01
-#define PCI_SUB_CLASS_FLOPPY_DISK_CONTROLLER 0x02
-#define PCI_SUB_CLASS_IPI_BUS_CONTROLLER 0x03
-#define PCI_SUB_CLASS_OTHER_MASS_CONTROLLER 0x80
-
-/* NETWORK CONTROLLER */
-#define PCI_SUB_CLASS_ETHERNET_CONTROLLER 0x00
-#define PCI_SUB_CLASS_TOKEN_RING_CONTROLLER 0x01
-#define PCI_SUB_CLASS_FDDI_CONTROLLER 0x02
-#define PCI_SUB_CLASS_OTHER_NETWORK_CONTROLLER 0x80
-
-/* DISPLAY CONTROLLER */
-#define PCI_SUB_CLASS_VGA_CONTROLLER 0x00
-#define PCI_SUB_CLASS_XGA_CONTROLLER 0x01
-#define PCI_SUB_CLASS_OTHER_DISPLAY_CONTROLLER 0x80
-
-/* MULTIMEDIA CONTROLLER */
-#define PCI_SUB_CLASS_VIDEO_DEVICE 0x00
-#define PCI_SUB_CLASS_AUDIO_DEVICE 0x01
-#define PCI_SUB_CLASS_OTHER_MULTIMEDIA_DEVICE 0x80
-
-/* MEMORY CONTROLLER */
-#define PCI_SUB_CLASS_RAM_CONTROLLER 0x00
-#define PCI_SUB_CLASS_FLASH_CONTROLLER 0x01
-#define PCI_SUB_CLASS_OTHER_MEMORY_CONTROLLER 0x80
-
-/* BRIDGE CONTROLLER */
-#define PCI_SUB_CLASS_HOST_BRIDGE_CONTROLLER 0x00
-#define PCI_SUB_CLASS_ISA_BRIDGE_CONTROLLER 0x01
-#define PCI_SUB_CLASS_EISA_BRIDGE_CONTROLLER 0x02
-#define PCI_SUB_CLASS_MC_BRIDGE_CONTROLLER 0x03
-#define PCI_SUB_CLASS_PCI_TO_PCI_BRIDGE_CONTROLLER 0x04
-#define PCI_SUB_CLASS_PCMCIA_BRIDGE_CONTROLLER 0x05
-#define PCI_SUB_CLASS_OTHER_BRIDGE_CONTROLLER 0x80
-
-#define PCI_MAX_SLOT 0x1F
-#define PCI_MAX_BUS 0xFF
-#define ASC_PCI_VENDORID 0x10CD
-#define PCI_IOADDRESS_MASK 0xFFFE
-
-/* PCI IO Port Addresses to generate special cycle */
-
-#define PCI_CONFIG_ADDRESS_MECH1 0x0CF8
-#define PCI_CONFIG_DATA_MECH1 0x0CFC
-
-#define PCI_CONFIG_FORWARD_REGISTER 0x0CFA /* 0=type 0; 1=type 1; */
-
-#define PCI_CONFIG_BUS_NUMBER_MASK 0x00FF0000
-#define PCI_CONFIG_DEVICE_FUNCTION_MASK 0x0000FF00
-#define PCI_CONFIG_REGISTER_NUMBER_MASK 0x000000F8
-
-#define PCI_DEVICE_FOUND 0x0000
-#define PCI_DEVICE_NOT_FOUND 0xffff
-
-#define SUBCLASS_OFFSET 0x0A
-#define CLASSCODE_OFFSET 0x0B
-#define VENDORID_OFFSET 0x00
-#define DEVICEID_OFFSET 0x02
-
-/*
- * --- Driver Macros
- */
-
-#ifndef ADVANSYS_STATS
-#define ASC_STATS(counter)
-#define ASC_STATS_ADD(counter, count)
-#else /* ADVANSYS_STATS */
-#define ASC_STATS(counter) asc_stats.counter++
-#define ASC_STATS_ADD(counter, count) asc_stats.counter += (count)
-#endif /* ADVANSYS_STATS */
-
-#ifndef ADVANSYS_DEBUG
-
-#define ASC_DBG(lvl, s)
-#define ASC_DBG1(lvl, s, a1)
-#define ASC_DBG2(lvl, s, a1, a2)
-#define ASC_DBG3(lvl, s, a1, a2, a3)
-#define ASC_DBG4(lvl, s, a1, a2, a3, a4)
-#define ASC_DBG_PRT_SCSI_HOST(lvl, s)
-#define ASC_DBG_PRT_DVC_VAR(lvl, v)
-#define ASC_DBG_PRT_DVC_CFG(lvl, c)
-#define ASC_DBG_PRT_SCSI_Q(lvl, scsiqp)
-#define ASC_DBG_PRT_QDONE_INFO(lvl, qdone)
-#define ASC_DBG_PRT_HEX(lvl, name, start, length)
-#define ASC_DBG_PRT_CDB(lvl, cdb, len)
-#define ASC_DBG_PRT_SENSE(lvl, sense, len)
-#define ASC_DBG_PRT_INQUIRY(lvl, inq, len)
-#define ASC_ASSERT(a)
-
-#else /* ADVANSYS_DEBUG */
-
-/*
- * Debugging Message Levels:
- * 0: Errors Only
- * 1: High-Level Tracing
- * 2-N: Verbose Tracing
- */
-
-#define ASC_DBG(lvl, s) \
- { \
- if (asc_dbglvl >= (lvl)) { \
- printk(s); \
- } \
- }
-
-#define ASC_DBG1(lvl, s, a1) \
- { \
- if (asc_dbglvl >= (lvl)) { \
- printk((s), (a1)); \
- } \
- }
-
-#define ASC_DBG2(lvl, s, a1, a2) \
- { \
- if (asc_dbglvl >= (lvl)) { \
- printk((s), (a1), (a2)); \
- } \
- }
-
-#define ASC_DBG3(lvl, s, a1, a2, a3) \
- { \
- if (asc_dbglvl >= (lvl)) { \
- printk((s), (a1), (a2), (a3)); \
- } \
- }
-
-#define ASC_DBG4(lvl, s, a1, a2, a3, a4) \
- { \
- if (asc_dbglvl >= (lvl)) { \
- printk((s), (a1), (a2), (a3), (a4)); \
- } \
- }
-
-#define ASC_DBG_PRT_SCSI_HOST(lvl, s) \
- { \
- if (asc_dbglvl >= (lvl)) { \
- asc_prt_scsi_host(s); \
- } \
- }
-
-#define ASC_DBG_PRT_DVC_VAR(lvl, v) \
- { \
- if (asc_dbglvl >= (lvl)) { \
- asc_prt_dvc_var(v); \
- } \
- }
-
-#define ASC_DBG_PRT_DVC_CFG(lvl, c) \
- { \
- if (asc_dbglvl >= (lvl)) { \
- asc_prt_dvc_cfg(c); \
- } \
- }
-
-#define ASC_DBG_PRT_SCSI_Q(lvl, scsiqp) \
- { \
- if (asc_dbglvl >= (lvl)) { \
- asc_prt_scsi_q(scsiqp); \
- } \
- }
-
-#define ASC_DBG_PRT_QDONE_INFO(lvl, qdone) \
- { \
- if (asc_dbglvl >= (lvl)) { \
- asc_prt_qdone_info(qdone); \
- } \
- }
-
-#define ASC_DBG_PRT_HEX(lvl, name, start, length) \
- { \
- if (asc_dbglvl >= (lvl)) { \
- asc_prt_hex((name), (start), (length)); \
- } \
- }
-
-#define ASC_DBG_PRT_CDB(lvl, cdb, len) \
- ASC_DBG_PRT_HEX((lvl), "CDB", (uchar *) (cdb), (len));
-
-#define ASC_DBG_PRT_SENSE(lvl, sense, len) \
- ASC_DBG_PRT_HEX((lvl), "SENSE", (uchar *) (sense), (len));
-
-#define ASC_DBG_PRT_INQUIRY(lvl, inq, len) \
- ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len));
-
-#define ASC_ASSERT(a) \
- { \
- if (!(a)) { \
- printk("ASC_ASSERT() Failure: file %s, line %d\n", \
- __FILE__, __LINE__); \
- } \
- }
-#endif /* ADVANSYS_DEBUG */
-
-
-/*
- * --- Driver Structures
- */
-
-/*
- * Structure allocated for each board.
- *
- * This structure is allocated by scsi_register() at the end
- * of the 'Scsi_Host' structure starting at the 'hostdata'
- * field. It is guaranteed to be allocated from DMA-able memory.
- */
-struct asc_board {
- /* Asc Library */
- ASC_DVC_VAR board; /* Board configuration */
- ASC_DVC_CFG cfg; /* Device configuration */
- uchar overrun_buf[ASC_OVERRUN_BSIZE];
- /* Queued Commands */
- ASC_SCSI_BIT_ID_TYPE pending_tidmask; /* Pending command mask */
- Scsi_Cmnd *pending[ASC_MAX_TID];
- /* Target Initialization */
- ASC_SCSI_BIT_ID_TYPE init_tidmask; /* Target initialized mask */
- ASC_SCSI_REQ_Q scsireqq;
- ASC_CAP_INFO cap_info;
- ASC_SCSI_INQUIRY inquiry;
-};
-
-/*
- * PCI configuration structures
- */
-typedef struct _PCI_DATA_
-{
- uchar type;
- uchar bus;
- uchar slot;
- uchar func;
- uchar offset;
-} PCI_DATA;
-
-typedef struct _PCI_DEVICE_
-{
- ushort vendorID;
- ushort deviceID;
- ushort slotNumber;
- ushort slotFound;
- uchar busNumber;
- uchar maxBusNumber;
- uchar devFunc;
- ushort startSlot;
- ushort endSlot;
- uchar bridge;
- uchar type;
-} PCI_DEVICE;
-
-typedef struct _PCI_CONFIG_SPACE_
-{
- ushort vendorID;
- ushort deviceID;
- ushort command;
- ushort status;
- uchar revision;
- uchar classCode[3];
- uchar cacheSize;
- uchar latencyTimer;
- uchar headerType;
- uchar bist;
- ulong baseAddress[6];
- ushort reserved[4];
- ulong optionRomAddr;
- ushort reserved2[4];
- uchar irqLine;
- uchar irqPin;
- uchar minGnt;
- uchar maxLatency;
-} PCI_CONFIG_SPACE;
-
-#ifdef ADVANSYS_STATS
-struct asc_stats {
- ulong command; /* # calls to advansys_command() */
- ulong queuecommand; /* # calls to advansys_queuecommand() */
- ulong abort; /* # calls to advansys_abort() */
- ulong reset; /* # calls to advansys_reset() */
- ulong biosparam; /* # calls to advansys_biosparam() */
- ulong interrupt; /* # calls to advansys_interrupt() */
- ulong callback; /* # calls asc_isr_callback() */
- ulong cont_cnt; /* # non-scatter-gather I/O requests received */
- ulong cont_xfer; /* contiguous transfer total (512 byte units) */
- ulong sg_cnt; /* # scatter-gather I/O requests received */
- ulong sg_elem; /* scatter-gather element total */
- ulong sg_xfer; /* scatter-gather tranfer total (512 byte units) */
- ulong error; /* # AscExeScsiQueue() ASC_ERROR returns. */
- /*
- * Number of times interrupts disabled in advansys_queuecommand() and
- * asc_isr_callback(), respectively. For the former indicates how many
- * times commands were pending when a new command was received.
- */
- ulong cmd_disable;
- ulong intr_disable;
- /*
- * Number of times asc_enqueue() called. Indicates how many ASC_BUSY
- * returns have occurred.
- */
- ulong enqueue;
- ulong dequeue; /* # calls to asc_dequeue(). */
- /*
- * Number of times asc_rmqueue() called and the specified command
- * was found and removed.
- */
- ulong rmqueue;
-} asc_stats;
-#endif /* ADVANSYS_STATS */
-
-
-/*
- * --- Driver Data
- */
-
-#ifdef LINUX_1_3
-struct proc_dir_entry proc_scsi_advansys =
-{
- PROC_SCSI_ADVANSYS, /* unsigned short low_ino */
- 8, /* unsigned short namelen */
- "advansys", /* const char *name */
- S_IFDIR | S_IRUGO | S_IXUGO, /* mode_t mode */
- 2 /* nlink_t nlink */
-};
-#endif /* LINUX_1_3 */
-
-STATIC int asc_board_count; /* Number of boards detected in system. */
-STATIC struct Scsi_Host *asc_host[ASC_NUM_BOARD_SUPPORTED];
-STATIC Scsi_Cmnd *asc_scsi_done; /* Commands needing done function call. */
-
-STATIC ushort asc_bus[ASC_NUM_BUS] = {
- ASC_IS_ISA,
- ASC_IS_VL,
- ASC_IS_EISA,
- ASC_IS_PCI,
-};
-
-/*
- * Used with the LILO 'advansys' option to eliminate or
- * limit I/O port probing at boot time, cf. advansys_setup().
- */
-int asc_iopflag = ASC_FALSE;
-int asc_ioport[ASC_NUM_BOARD_SUPPORTED] = { 0, 0, 0, 0 };
-
-#ifdef ADVANSYS_DEBUG
-char *
-asc_bus_name[ASC_NUM_BUS] = {
- "ASC_IS_ISA",
- "ASC_IS_VL",
- "ASC_IS_EISA",
- "ASC_IS_PCI",
-};
-
-int asc_dbglvl = 0;
-#endif /* ADVANSYS_DEBUG */
-
-
-/*
- * --- Driver Function Prototypes
- *
- * advansys.h contains function prototypes for functions global to Linux.
- */
-
-#ifdef LINUX_1_3
-STATIC int asc_proc_copy(off_t, off_t, char *, int , char *, int);
-#endif /* LINUX_1_3 */
-STATIC void advansys_interrupt(int, struct pt_regs *);
-STATIC void advansys_command_done(Scsi_Cmnd *);
-STATIC int asc_execute_scsi_cmnd(Scsi_Cmnd *);
-STATIC void asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *);
-STATIC void asc_execute_pending(struct Scsi_Host *);
-STATIC int asc_init_dev(ASC_DVC_VAR *, Scsi_Cmnd *);
-STATIC int asc_srch_pci_dev(PCI_DEVICE *);
-STATIC uchar asc_scan_method(PCI_DEVICE *);
-STATIC int asc_pci_find_dev(PCI_DEVICE *);
-STATIC void asc_get_pci_cfg(PCI_DEVICE *, PCI_CONFIG_SPACE *);
-STATIC ushort asc_get_cfg_word(PCI_DATA *);
-STATIC uchar asc_get_cfg_byte(PCI_DATA *);
-STATIC void asc_enqueue(struct Scsi_Host *, Scsi_Cmnd *, int, int);
-STATIC Scsi_Cmnd *asc_dequeue(struct Scsi_Host *, int);
-STATIC int asc_rmqueue(struct Scsi_Host *, Scsi_Cmnd *, int);
-
-/* XXX - Asc Library Routines not supposed to be used directly */
-ushort AscGetChipBiosAddress(PortAddr, ushort);
-int AscFindSignature(PortAddr);
-
-#ifdef ADVANSYS_STATS
-STATIC int asc_prt_stats(char *, int);
-STATIC int asc_prt_stats_line(char *, int, char *fmt, ...);
-#endif /* ADVANSYS_STATS */
-#ifdef ADVANSYS_DEBUG
-STATIC void asc_prt_scsi_host(struct Scsi_Host *);
-STATIC void asc_prt_dvc_cfg(ASC_DVC_CFG *);
-STATIC void asc_prt_dvc_var(ASC_DVC_VAR *);
-STATIC void asc_prt_scsi_q(ASC_SCSI_Q *);
-STATIC void asc_prt_qdone_info(ASC_QDONE_INFO *);
-STATIC void asc_prt_hex(char *f, uchar *, int);
-STATIC int interrupts_enabled(void);
-#endif /* ADVANSYS_DEBUG */
-
-
-/*
- * --- Linux 'Scsi_Host_Template' and advansys_setup() Functions
- */
-
-#ifdef LINUX_1_3
-/*
- * advansys_proc_info() - /proc/scsi/advansys/[0-ASC_NUM_BOARD_SUPPORTED]
- *
- * *buffer: I/O buffer
- * **start: if inout == FALSE pointer into buffer where user read should start
- * offset: current offset into /proc/scsi/advansys file
- * length: length of buffer
- * hostno: Scsi_Host host_no
- * inout: TRUE - user is writing; FALSE - user is reading
- *
- * Return the number of bytes read from or written to
- * /proc/scsi/advansys file.
- */
-int
-advansys_proc_info(char *buffer, char **start, off_t offset, int length,
- int hostno, int inout)
-{
- struct Scsi_Host *shp;
- int i;
- char *cp;
- int cplen;
- int cnt;
- int totcnt;
- int leftlen;
- char *curbuf;
- off_t advoffset;
- Scsi_Device *scd;
- char prtbuf[480]; /* 6 lines */
-
- ASC_DBG(1, "advansys_proc_info: begin\n");
-
- /*
- * User write not supported.
- */
- if (inout == TRUE) {
- return(-ENOSYS);
- }
-
- /*
- * User read of /proc/scsi/advansys file.
- */
-
- /* Find the specified board. */
- for (i = 0; i < asc_board_count; i++) {
- if (asc_host[i]->host_no == hostno) {
- break;
- }
- }
- if (i == asc_board_count) {
- return(-ENOENT);
- }
- shp = asc_host[i];
-
- /* Always copy read data to the beginning of the buffer. */
- *start = buffer;
-
- curbuf = buffer;
- advoffset = 0;
- totcnt = 0;
- leftlen = length;
-
- /* Get board information. */
- cp = (char *) advansys_info(shp);
- strcat(cp, "\n");
- cplen = strlen(cp);
-
- /* Copy board information. */
- cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
- totcnt += cnt;
- leftlen -= cnt;
- if (leftlen == 0) {
- ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
- return totcnt;
- }
- advoffset += cplen;
- curbuf += cnt;
-
- /*
- * Get and copy information for each device attached to the board.
- */
- cp = &prtbuf[0];
- sprintf(cp, "\nDevices attached to SCSI Host %d:\n", shp->host_no);
- cplen = strlen(cp);
- cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
- totcnt += cnt;
- leftlen -= cnt;
- if (leftlen == 0) {
- ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
- return totcnt;
- }
- advoffset += cplen;
- curbuf += cnt;
-
- cp = &prtbuf[0];
- for (scd = scsi_devices; scd; scd = scd->next) {
- if (scd->host == shp) {
- proc_print_scsidevice(scd, cp, &cplen, 0);
- cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
- totcnt += cnt;
- leftlen -= cnt;
- if (leftlen == 0) {
- ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
- return totcnt;
- }
- advoffset += cplen;
- curbuf += cnt;
- }
- }
-
-#ifdef ADVANSYS_STATS
- /*
- * prtbuf[] has about 6 lines worth of space. If the statistics ever
- * get longer than 6 lines, prtbuf[] should be increased in size. If
- * prtbuf[] is too small it will not be overwritten. Instead the user
- * just won't get all of the available statistics.
- */
- cp = &prtbuf[0];
- cplen = asc_prt_stats(cp, sizeof(prtbuf));
- cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen);
- totcnt += cnt;
- leftlen -= cnt;
- if (leftlen == 0) {
- ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
- return totcnt;
- }
- advoffset += cplen;
- curbuf += cnt;
-#endif /* ADVANSYS_STATS */
-
- ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt);
-
- return totcnt;
-}
-#endif /* LINUX_1_3 */
-
-
-/*
- * advansys_detect()
- *
- * Detect function for AdvanSys adapters.
- *
- * Argument is a pointer to the host driver's scsi_hosts entry.
- *
- * Return number of adapters found.
- *
- * Note: Because this function is called during system initialization
- * it must not call SCSI mid-level functions including scsi_malloc()
- * and scsi_free().
- */
-int
-advansys_detect(Scsi_Host_Template *tpnt)
-{
- static int detect_called = ASC_FALSE;
- int iop;
- int bus;
- struct Scsi_Host *shp;
- ASC_DVC_VAR *boardp;
- int ioport = 0;
- PCI_DEVICE pciDevice;
- PCI_CONFIG_SPACE pciConfig;
- int ret;
- extern PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX];
-
-
- if (detect_called == ASC_FALSE) {
- detect_called = ASC_TRUE;
- } else {
- printk("AdvanSys SCSI: advansys_detect() mulitple calls ignored\n");
- return 0;
- }
-
- ASC_DBG(1, "advansys_detect: begin\n");
-
-#ifdef LINUX_1_3
- tpnt->proc_dir = &proc_scsi_advansys;
-#endif /* LINUX_1_3 */
-
-#ifdef ADVANSYS_STATS
- memset(&asc_stats, 0, sizeof(asc_stats));
-#endif /* ADVANSYS_STATS */
-
- asc_board_count = 0;
-
- /*
- * If I/O port probing has been modified, then verify and
- * clean-up the 'asc_ioport' list.
- */
- if (asc_iopflag == ASC_TRUE) {
- for (ioport = 0; ioport < ASC_NUM_BOARD_SUPPORTED; ioport++) {
- ASC_DBG2(1, "asdvansys_detect: asc_ioport[%d] %x\n",
- ioport, asc_ioport[ioport]);
- if (asc_ioport[ioport] != 0) {
- for (iop = 0; iop < ASC_IOADR_TABLE_MAX_IX; iop++) {
- if (_asc_def_iop_base[iop] == asc_ioport[ioport]) {
- break;
- }
- }
- if (iop == ASC_IOADR_TABLE_MAX_IX) {
- printk("AdvanSys SCSI: specified I/O Port 0x%X is invalid\n",
- asc_ioport[ioport]);
- asc_ioport[ioport] = 0;
- }
- }
- }
- ioport = 0;
- }
-
- memset(&pciDevice, 0, sizeof(PCI_DEVICE));
- memset(&pciConfig, 0, sizeof(PCI_CONFIG_SPACE));
- pciDevice.maxBusNumber = PCI_MAX_BUS;
- pciDevice.endSlot = PCI_MAX_SLOT;
-
- for (bus = 0; bus < ASC_NUM_BUS; bus++) {
-
- ASC_DBG2(1, "advansys_detect: bus search type %d (%s)\n",
- bus, asc_bus_name[bus]);
- iop = 0;
-
- while (asc_board_count < ASC_NUM_BOARD_SUPPORTED) {
-
- ASC_DBG1(2, "advansys_detect: asc_board_count %d\n",
- asc_board_count);
-
- switch (asc_bus[bus]) {
- case ASC_IS_ISA:
- case ASC_IS_VL:
- if (asc_iopflag == ASC_FALSE) {
- iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
- } else {
- /*
- * ISA and VL I/O port scanning has either been
- * eliminated or limited to selected ports on
- * the LILO command line, /etc/lilo.conf, or
- * by setting variables when the module was loaded.
- */
- ASC_DBG(1, "advansys_detect: I/O port scanning modified\n");
- ioport_try_again:
- iop = 0;
- for (; ioport < ASC_NUM_BOARD_SUPPORTED; ioport++) {
- if ((iop = asc_ioport[ioport]) != 0) {
- break;
- }
- }
- if (iop) {
- ASC_DBG1(1, "advansys_detect: probing I/O port %x...\n",
- iop);
- if (check_region(iop, ASC_IOADR_GAP) != 0) {
- printk("AdvanSys SCSI: specified I/O Port 0x%X is busy\n", iop);
- /* Don't try this I/O port twice. */
- asc_ioport[ioport] = 0;
- goto ioport_try_again;
- } else if (AscFindSignature(iop) == ASC_FALSE) {
- printk("AdvanSys SCSI: specified I/O Port 0x%X has no adapter\n", iop);
- /* Don't try this I/O port twice. */
- asc_ioport[ioport] = 0;
- goto ioport_try_again;
- } else {
- /*
- * If this isn't an ISA board, then it must be
- * a VL board. If currently looking an ISA
- * board is being looked for then try for
- * another ISA board in 'asc_ioport'.
- */
- if (asc_bus[bus] == ASC_IS_ISA &&
- (AscGetChipVersion(iop, ASC_IS_ISA) &
- ASC_CHIP_VER_ISA_BIT) == 0) {
- /*
- * Don't clear 'asc_ioport[ioport]'. Try
- * this board again for VL. Increment
- * 'ioport' past this board.
- */
- ioport++;
- goto ioport_try_again;
- }
- }
- /*
- * This board appears good, don't try the I/O port
- * again by clearing its value. Increment 'ioport'
- * for the next iteration.
- */
- asc_ioport[ioport++] = 0;
- }
- }
- break;
-
- case ASC_IS_EISA:
- iop = AscSearchIOPortAddr(iop, asc_bus[bus]);
- break;
-
- case ASC_IS_PCI:
- if (asc_srch_pci_dev(&pciDevice) != PCI_DEVICE_FOUND) {
- iop = 0;
- } else {
- ASC_DBG2(2,
- "advansys_detect: slotFound %d, busNumber %d\n",
- pciDevice.slotFound, pciDevice.busNumber);
- asc_get_pci_cfg(&pciDevice, &pciConfig);
- iop = pciConfig.baseAddress[0] & PCI_IOADDRESS_MASK;
- ASC_DBG2(2, "advansys_detect: iop %x, irqLine %d\n",
- iop, pciConfig.irqLine);
- }
- break;
-
- default:
- ASC_DBG(0, "advansys_detect: unknown bus type\n");
- break;
- }
- ASC_DBG1(1, "advansys_detect: iop %x\n", iop);
-
- /*
- * Adapter not found, try next bus type.
- */
- if (iop == 0) {
- break;
- }
-
- /*
- * Adapter found.
- *
- * Register the adapter, get its configuration, and
- * initialize it.
- */
- ASC_DBG(2, "advansys_detect: scsi_register()\n");
- shp = scsi_register(tpnt, sizeof(struct asc_board));
-
- /* Save a pointer to the Scsi_host of each found board. */
- asc_host[asc_board_count++] = shp;
-
- /* Initialize private per board data */
- memset(ASC_BOARD(shp), 0, sizeof(struct asc_board));
- boardp = &ASC_BOARD(shp)->board;
- boardp->cfg = &ASC_BOARD(shp)->cfg;
- boardp->cfg->overrun_buf = &ASC_BOARD(shp)->overrun_buf[0];
- boardp->iop_base = iop;
-
- /*
- * Set the board bus type and PCI IRQ for AscInitGetConfig().
- */
- boardp->bus_type = asc_bus[bus];
- switch (boardp->bus_type) {
- case ASC_IS_ISA:
- shp->unchecked_isa_dma = TRUE;
- break;
- case ASC_IS_EISA:
- shp->unchecked_isa_dma = FALSE;
- break;
- case ASC_IS_VL:
- shp->unchecked_isa_dma = FALSE;
- break;
- case ASC_IS_PCI:
- shp->irq = boardp->irq_no = pciConfig.irqLine;
- boardp->cfg->pci_device_id = pciConfig.deviceID;
- shp->unchecked_isa_dma = FALSE;
- break;
- default:
- ASC_DBG(0, "advansys_detect: unknown adapter type");
- shp->unchecked_isa_dma = TRUE;
- break;
- }
-
- /*
- * Get the board configuration. AscInitGetConfig() may change
- * the board's bus_type value. The asc_bus[bus] value should no
- * longer be used.
- */
- ASC_DBG(2, "advansys_detect: AscInitGetConfig()\n");
- switch(ret = AscInitGetConfig(boardp)) {
- case 0: /* No error */
- break;
- case ASC_WARN_IO_PORT_ROTATE:
- ASC_DBG(0, "AscInitGetConfig: I/O port address modified\n");
- break;
- case ASC_WARN_EEPROM_CHKSUM:
- ASC_DBG(0, "AscInitGetConfig: EEPROM checksum error\n");
- break;
- case ASC_WARN_IRQ_MODIFIED:
- ASC_DBG(0, "AscInitGetConfig: IRQ modified\n");
- break;
- case ASC_WARN_CMD_QNG_CONFLICT:
- ASC_DBG(0,
- "AscInitGetConfig: Tag queuing enabled w/o disconnects\n");
- break;
- default:
- ASC_DBG1(0, "AscInitGetConfig: Unknown warning: %x\n", ret);
- break;
- }
- if (boardp->err_code != 0) {
- ASC_DBG2(0,
- "AscInitGetConfig: error: init_state %x, err_code %x\n",
- boardp->init_state, boardp->err_code);
- scsi_unregister(shp);
- asc_board_count--;
- continue;
- }
-
- /*
- * Modify board configuration.
- */
- boardp->isr_callback = (Ptr2Func) asc_isr_callback;
- boardp->exe_callback = (Ptr2Func) NULL;
-
- ASC_DBG(2, "advansys_detect: AscInitSetConfig()\n");
- switch (ret = AscInitSetConfig(boardp)) {
- case 0: /* No error. */
- break;
- case ASC_WARN_IO_PORT_ROTATE:
- ASC_DBG(0, "AscInitSetConfig: I/O port address modified\n");
- break;
- case ASC_WARN_EEPROM_CHKSUM:
- ASC_DBG(0, "AscInitSetConfig: EEPROM checksum error\n");
- break;
- case ASC_WARN_IRQ_MODIFIED:
- ASC_DBG(0, "AscInitSetConfig: IRQ modified\n");
- break;
- case ASC_WARN_CMD_QNG_CONFLICT:
- ASC_DBG(0, "AscInitSetConfig: Tag queuing w/o disconnects\n");
- break;
- default:
- ASC_DBG1(0, "AscInitSetConfig: Unknown warning: %x\n", ret);
- break;
- }
- if (boardp->err_code != 0) {
- ASC_DBG2(0,
- "AscInitSetConfig: error: init_state %x, err_code %x\n",
- boardp->init_state, boardp->err_code);
- scsi_unregister(shp);
- asc_board_count--;
- continue;
- }
-
- /*
- * Finish initializing the 'Scsi_Host' structure.
- */
-
- /* AscInitSetConfig() will set the IRQ for non-PCI boards. */
- if (boardp->bus_type != ASC_IS_PCI) {
- shp->irq = boardp->irq_no;
- }
-
- shp->io_port = boardp->iop_base;
- shp->n_io_port = ASC_IOADR_GAP;
- shp->this_id = boardp->cfg->chip_scsi_id;
-
- /* Maximum number of queues this adapter can handle. */
- shp->can_queue = boardp->max_total_qng;
-
- /*
- * XXX - Command queuing limits are maintained per target
- * by AdvanSys adapters. Set 'cmd_per_lun' to the minimum
- * value of the all the target settings for the adapter.
- *
- * For now set 'cmd_per_lun' to 'max_total_qng'. This
- * value should be adjusted every time a new device is
- * found in asc_init_dev().
- *
- * XXX - memory allocation is done by the mid-level scsi
- * driver based on 'cmd_per_lun'. If 'sg_tablesize' is too large
- * allocation failures can occur in scsi_register_host().
- * A 'Scsi_Cmnd' structure is pre-allocated for each command
- * also DMA memory is reserved. Set it artificially low for now.
- *
- * shp->cmd_per_lun = boardp->max_total_qng;
- */
-#ifdef MODULE
- shp->cmd_per_lun = 1;
-#else /* MODULE */
- shp->cmd_per_lun = 4;
-#endif /* MODULE */
- ASC_DBG1(1, "advansys_detect: cmd_per_lun: %d\n", shp->cmd_per_lun);
-
- /* Maximum number of scatter-gather elements adapter can handle. */
- /*
- * XXX - memory allocation is done by the mid-level scsi
- * driver based on sg_tablesize. If 'sg_tablesize' is too large
- * allocation failures can occur in scsi_register_host().
- */
-#ifdef MODULE
- shp->sg_tablesize = 8;
-#else /* MODULE */
- shp->sg_tablesize = ASC_MAX_SG_LIST;
-#endif /* MODULE */
- ASC_DBG1(1, "advansys_detect: sg_tablesize: %d\n",
- shp->sg_tablesize);
-
- /* BIOS start address. */
- shp->base = (char *) ((ulong) AscGetChipBiosAddress(
- boardp->iop_base,
- boardp->bus_type));
-
- /*
- * Register Board Resources - I/O Port, DMA, IRQ
- */
-
- /* Register I/O port range */
- ASC_DBG(2, "advansys_detect: request_region()\n");
- request_region(shp->io_port, shp->n_io_port, "advansys");
-
- /* Register DMA channel for ISA bus. */
- if ((boardp->bus_type & ASC_IS_ISA) == 0) {
- shp->dma_channel = NO_ISA_DMA;
- } else {
- shp->dma_channel = boardp->cfg->isa_dma_channel;
- if ((ret = request_dma(shp->dma_channel, "advansys")) != 0) {
- ASC_DBG2(0, "advansys_detect: request_dma() %d failed %d\n",
- shp->dma_channel, ret);
- release_region(shp->io_port, shp->n_io_port);
- scsi_unregister(shp);
- asc_board_count--;
- continue;
- }
- AscEnableIsaDma(shp->dma_channel);
- }
-
- /* Register IRQ Number. */
- ASC_DBG1(2, "advansys_detect: request_irq() %d\n", shp->irq);
- if ((ret = request_irq(shp->irq, advansys_interrupt,
- SA_INTERRUPT, "advansys")) != 0) {
- ASC_DBG1(0, "advansys_detect: request_irq() failed %d\n", ret);
- release_region(shp->io_port, shp->n_io_port);
- if (shp->dma_channel != NO_ISA_DMA) {
- free_dma(shp->dma_channel);
- }
- scsi_unregister(shp);
- asc_board_count--;
- continue;
- }
-
- /*
- * Initialize board RISC chip and enable interrupts.
- */
- ASC_DBG(2, "advansys_detect: AscInitAsc1000Driver()\n");
- if (AscInitAsc1000Driver(boardp)) {
- ASC_DBG2(0,
- "AscInitAsc1000Driver: error: init_state %x, err_code %x\n",
- boardp->init_state, boardp->err_code);
- release_region(shp->io_port, shp->n_io_port);
- if (shp->dma_channel != NO_ISA_DMA) {
- free_dma(shp->dma_channel);
- }
- free_irq(shp->irq);
- scsi_unregister(shp);
- asc_board_count--;
- continue;
- }
- ASC_DBG_PRT_SCSI_HOST(2, shp);
- }
- }
-
- ASC_DBG1(1, "advansys_detect: done: asc_board_count %d\n", asc_board_count);
- return asc_board_count;
-}
-
-/*
- * advansys_release()
- *
- * Release resources allocated for a single AdvanSys adapter.
- */
-int
-advansys_release(struct Scsi_Host *shp)
-{
- ASC_DBG(1, "advansys_release: begin\n");
- free_irq(shp->irq);
- if (shp->dma_channel != NO_ISA_DMA) {
- ASC_DBG(1, "advansys_release: free_dma()\n");
- free_dma(shp->dma_channel);
- }
- release_region(shp->io_port, shp->n_io_port);
- scsi_unregister(shp);
- ASC_DBG(1, "advansys_release: end\n");
- return 0;
-}
-
-/*
- * advansys_info()
- *
- * Return suitable for printing on the console with the argument
- * adapter's configuration information.
- */
-const char *
-advansys_info(struct Scsi_Host *shp)
-{
- static char info[128];
- ASC_DVC_VAR *boardp;
- char *busname;
-
- boardp = &ASC_BOARD(shp)->board;
- ASC_DBG(1, "advansys_info: begin\n");
- if (boardp->bus_type & ASC_IS_ISA) {
- sprintf(info,
- "AdvanSys SCSI %s: ISA (%u CDB): BIOS %X, IO %X-%X, IRQ %u, DMA %u",
- ASC_VERSION, ASC_BOARD(shp)->board.max_total_qng,
- (unsigned) shp->base, shp->io_port,
- shp->io_port + (shp->n_io_port - 1), shp->irq, shp->dma_channel);
- } else {
- switch (boardp->bus_type) {
- case ASC_IS_EISA:
- busname = "EISA";
- break;
- case ASC_IS_VL:
- busname = "VL";
- break;
- case ASC_IS_PCI:
- busname = "PCI";
- break;
- default:
- busname = "?";
- ASC_DBG1(0, "advansys_info: unknown bus type %d\n",
- boardp->bus_type);
- break;
- }
- /* No DMA channel for non-ISA busses. */
- sprintf(info,
- "AdvanSys SCSI %s: %s (%u CDB): BIOS %X, IO %X-%X, IRQ %u",
- ASC_VERSION, busname, ASC_BOARD(shp)->board.max_total_qng,
- (unsigned) shp->base, shp->io_port,
- shp->io_port + (shp->n_io_port - 1), shp->irq);
- }
- ASC_DBG(1, "advansys_info: end\n");
- return info;
-}
-
-/*
- * advansys_command()
- *
- * Polled-I/O. Apparently host driver shouldn't return until
- * command is finished.
- *
- * XXX - Can host driver block here instead of spinning on command status?
- */
-int
-advansys_command(Scsi_Cmnd *scp)
-{
- ASC_DBG1(1, "advansys_command: scp %x\n", (unsigned) scp);
- ASC_STATS(command);
- scp->SCp.Status = 0; /* Set to a known state */
- advansys_queuecommand(scp, advansys_command_done);
- while (scp->SCp.Status == 0) {
- continue;
- }
- ASC_DBG1(1, "advansys_command: result %x\n", scp->result);
- return scp->result;
-}
-
-/*
- * advansys_queuecommand()
- *
- * This function always returns 0. Command return status is saved
- * in the 'scp' result field.
- */
-int
-advansys_queuecommand(Scsi_Cmnd *scp, void (*done)(Scsi_Cmnd *))
-{
- struct Scsi_Host *shp;
- int flags = 0;
- int interrupts_disabled;
-
- ASC_STATS(queuecommand);
- shp = scp->host;
-
-#ifdef LINUX_1_2
- /*
- * For LINUX_1_3, if statistics are enabled they can be accessed
- * by reading /proc/scsi/advansys/[0-9].
- */
-#ifdef ADVANSYS_STATS_1_2_PRINT
- /* Display statistics every 10000 commands. */
- if ((asc_stats.queuecommand % 10000) == 0) {
- printk("\n");
- (void) asc_prt_stats(NULL, 0);
- printk("\n");
- }
-#endif /* ADVANSYS_STATS_1_2_PRINT */
-#endif /* LINUX_1_2 */
-
- /*
- * If there are any pending commands for this board before trying
- * to execute them, disable interrupts to preserve request ordering.
- *
- * The typical case will be no pending commands and interrupts
- * not disabled.
- */
- if (ASC_BOARD(shp)->pending_tidmask == 0) {
- interrupts_disabled = ASC_FALSE;
- } else {
- ASC_STATS(cmd_disable);
- /* Disable interrupts */
- interrupts_disabled = ASC_TRUE;
- save_flags(flags);
- cli();
- ASC_DBG1(1, "advansys_queuecommand: asc_execute_pending() %x\n",
- ASC_BOARD(shp)->pending_tidmask);
- asc_execute_pending(shp);
- }
-
- /*
- * Save the function pointer to Linux mid-level 'done' function and
- * execute the command.
- */
- scp->scsi_done = done;
- if (asc_execute_scsi_cmnd(scp) == ASC_BUSY) {
- if (interrupts_disabled == ASC_FALSE) {
- save_flags(flags);
- cli();
- interrupts_disabled = ASC_TRUE;
- }
- asc_enqueue(shp, scp, scp->target, ASC_BACK);
- }
-
- if (interrupts_disabled == ASC_TRUE) {
- restore_flags(flags);
- }
-
- return 0;
-}
-
-/*
- * advansys_abort()
- *
- * Abort the specified command and reset the device
- * associated with the command 'scp'.
- */
-int
-advansys_abort(Scsi_Cmnd *scp)
-{
- ASC_DVC_VAR *boardp;
- int flags;
- int ret;
-
- ASC_DBG1(1, "advansys_abort: scp %x\n", (unsigned) scp);
- save_flags(flags);
- cli();
- ASC_STATS(abort);
- if (scp->host == NULL) {
- scp->result = HOST_BYTE(DID_ERROR);
- ret = SCSI_ABORT_ERROR;
- } else if (asc_rmqueue(scp->host, scp, scp->target) == ASC_TRUE) {
- scp->result = HOST_BYTE(DID_ABORT);
- ret = SCSI_ABORT_SUCCESS;
- (void) AscResetDevice(&ASC_BOARD(scp->host)->board, scp->target);
- } else {
- /* Must enable interrupts for AscAbortSRB() */
- sti();
- boardp = &ASC_BOARD(scp->host)->board;
- scp->result = HOST_BYTE(DID_ABORT);
- switch (AscAbortSRB(boardp, (ulong) scp)) {
- case ASC_TRUE:
- /* asc_isr_callback() will be called */
- ASC_DBG(1, "advansys_abort: AscAbortSRB() TRUE\n");
- ret = SCSI_ABORT_PENDING;
- break;
- case ASC_FALSE:
- /* Request has apparently already completed. */
- ASC_DBG(1, "advansys_abort: AscAbortSRB() FALSE\n");
- ret = SCSI_ABORT_NOT_RUNNING;
- break;
- case ASC_ERROR:
- default:
- ASC_DBG(1, "advansys_abort: AscAbortSRB() ERROR\n");
- ret = SCSI_ABORT_ERROR;
- break;
- }
- (void) AscResetDevice(boardp, scp->target);
- }
- restore_flags(flags);
- ASC_DBG1(1, "advansys_abort: ret %d\n", ret);
- return ret;
-}
-
-/*
- * advansys_reset()
- *
- * Reset all devices and the SCSI bus for the board
- * associated with 'scp'.
- */
-int
-advansys_reset(Scsi_Cmnd *scp)
-{
- ASC_DVC_VAR *boardp;
- int flags;
- Scsi_Cmnd *tscp;
- int i;
- int ret;
-
- ASC_DBG1(1, "advansys_reset: %x\n", (unsigned) scp);
- save_flags(flags);
- cli();
- ASC_STATS(reset);
- if (scp->host == NULL) {
- scp->result = HOST_BYTE(DID_ERROR);
- ret = SCSI_RESET_ERROR;
- } else {
- /* Remove any pending commands, set DID_RESET, and done them. */
- for (i = 0; i < ASC_MAX_TID; i++) {
- while ((tscp = asc_dequeue(scp->host, i)) != NULL) {
- tscp->result = HOST_BYTE(DID_RESET);
- tscp->scsi_done(tscp);
- }
- }
- /* Must enable interrupts for AscResetSB() */
- sti();
- boardp = &ASC_BOARD(scp->host)->board;
- scp->result = HOST_BYTE(DID_RESET);
- switch (AscResetSB(boardp)) {
- case ASC_TRUE:
- ASC_DBG(1, "advansys_abort: AscResetSB() TRUE\n");
- ret = SCSI_RESET_SUCCESS;
- break;
- case ASC_ERROR:
- default:
- ASC_DBG(1, "advansys_abort: AscResetSB() ERROR\n");
- ret = SCSI_RESET_ERROR;
- break;
- }
- }
- restore_flags(flags);
- ASC_DBG1(1, "advansys_reset: ret %d", ret);
- return ret;
-}
-
-/*
- * advansys_biosparam()
- *
- * Translate disk drive geometry if the "BIOS greater than 1 GB"
- * support is enabled for a drive.
- *
- * ip (information pointer) is an int array with the following definition:
- * ip[0]: heads
- * ip[1]: sectors
- * ip[2]: cylinders
- */
-int
-#ifdef LINUX_1_2
-advansys_biosparam(Disk *dp, int dep, int ip[])
-#else /* LINUX_1_3 */
-advansys_biosparam(Disk *dp, kdev_t dep, int ip[])
-#endif /* LINUX_1_3 */
-{
- ASC_DBG(1, "advansys_biosparam: begin\n");
- ASC_STATS(biosparam);
- if ((ASC_BOARD(dp->device->host)->board.dvc_cntl & ASC_CNTL_BIOS_GT_1GB) &&
- dp->capacity > 0x200000) {
- ip[0] = 255;
- ip[1] = 64;
- } else {
- ip[0] = 64;
- ip[1] = 32;
- }
- ip[2] = dp->capacity / (ip[0] * ip[1]);
- ASC_DBG(1, "advansys_biosparam: end\n");
- return 0;
-}
-
-/*
- * advansys_setup()
- *
- * This function is called from init/main.c at boot time.
- * It it passed LILO parameters that can be set from the
- * LILO command line or in /etc/lilo.conf.
- *
- * It is used by the AdvanSys driver to either disable I/O
- * port scanning or to limit scanning to 1 - 4 I/O ports.
- * Regardless of the option setting EISA and PCI boards
- * will still be searched for and detected. This option
- * only affects searching for ISA and VL boards.
- *
- * If ADVANSYS_DEBUG is defined the driver debug level may
- * be set using the 5th (ASC_NUM_BOARD_SUPPORTED + 1) I/O Port.
- *
- * Examples:
- * 1. Eliminate I/O port scanning:
- * boot: linux advansys=
- * or
- * boot: linux advansys=0x0
- * 2. Limit I/O port scanning to one I/O port:
- * boot: linux advansys=0x110
- * 3. Limit I/O port scanning to four I/O ports:
- * boot: linux advansys=0x110,0x210,0x230,0x330
- * 4. If ADVANSYS_DEBUG, limit I/O port scanning to four I/O ports and
- * set the driver debug level to 2.
- * boot: linux advansys=0x110,0x210,0x230,0x330,0xdeb2
- *
- * ints[0] - number of arguments
- * ints[1] - first argument
- * ints[2] - second argument
- * ...
- */
-void
-advansys_setup(char *str, int *ints)
-{
- int i;
-
- if (asc_iopflag == ASC_TRUE) {
- printk("AdvanSys SCSI: 'advansys' LILO option may appear only once\n");
- return;
- }
-
- asc_iopflag = ASC_TRUE;
-
- if (ints[0] > ASC_NUM_BOARD_SUPPORTED) {
-#ifdef ADVANSYS_DEBUG
- if ((ints[0] == ASC_NUM_BOARD_SUPPORTED + 1) &&
- (ints[ASC_NUM_BOARD_SUPPORTED + 1] >> 4 == 0xdeb)) {
- asc_dbglvl = ints[ASC_NUM_BOARD_SUPPORTED + 1] & 0xf;
- } else {
-#endif /* ADVANSYS_DEBUG */
- printk("AdvanSys SCSI: only %d I/O ports accepted\n",
- ASC_NUM_BOARD_SUPPORTED);
-#ifdef ADVANSYS_DEBUG
- }
-#endif /* ADVANSYS_DEBUG */
- }
-
-#ifdef ADVANSYS_DEBUG
- ASC_DBG1(1, "advansys_setup: ints[0] %d\n", ints[0]);
- for (i = 1; i < ints[0]; i++) {
- ASC_DBG2(1, " ints[%d] %x", i, ints[i]);
- }
- ASC_DBG(1, "\n");
-#endif /* ADVANSYS_DEBUG */
-
- for (i = 1; i <= ints[0] && i <= ASC_NUM_BOARD_SUPPORTED; i++) {
- asc_ioport[i-1] = ints[i];
- ASC_DBG2(1, "advansys_setup: asc_ioport[%d] %x\n",
- i - 1, asc_ioport[i-1]);
- }
-}
-
-
-/*
- * --- Loadable Driver Support
- */
-
-#ifdef MODULE
-Scsi_Host_Template driver_template = ADVANSYS;
-# include "scsi_module.c"
-#endif /* MODULE */
-
-
-/*
- * --- Miscellaneous Driver Functions
- */
-
-#ifdef LINUX_1_3
-/*
- * asc_proc_copy()
- *
- * Copy proc information to a read buffer considering the current read
- * offset in the file and the remaining space in the read buffer.
- */
-STATIC int
-asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen,
- char *cp, int cplen)
-{
- int cnt = 0;
-
- ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n",
- (unsigned) offset, (unsigned) advoffset, cplen);
- if (offset <= advoffset) {
- /* Read offset below current offset, copy everything. */
- cnt = min(cplen, leftlen);
- ASC_DBG3(2, "asc_proc_copy: curbuf %x, cp %x, cnt %d\n",
- (unsigned) curbuf, (unsigned) cp, cnt);
- memcpy(curbuf, cp, cnt);
- } else if (offset < advoffset + cplen) {
- /* Read offset within current range, partial copy. */
- cnt = (advoffset + cplen) - offset;
- cp = (cp + cplen) - cnt;
- cnt = min(cnt, leftlen);
- ASC_DBG3(2, "asc_proc_copy: curbuf %x, cp %x, cnt %d\n",
- (unsigned) curbuf, (unsigned) cp, cnt);
- memcpy(curbuf, cp, cnt);
- }
- return cnt;
-}
-#endif /* LINUX_1_3 */
-
-/*
- * First-level interrupt handler.
- */
-STATIC void
-advansys_interrupt(int irq, struct pt_regs *regs)
-{
- int i;
- int flags;
- Scsi_Cmnd *scp;
- Scsi_Cmnd *tscp;
-
- /* Disable interrupts, if the aren't already disabled. */
- save_flags(flags);
- cli();
-
- ASC_DBG(1, "advansys_interrupt: begin\n");
- ASC_STATS(interrupt);
- /*
- * Check for interrupts on all boards.
- * AscISR() will call asc_isr_callback().
- */
- for (i = 0; i < asc_board_count; i++) {
- while (AscIsIntPending(asc_host[i]->io_port)) {
- ASC_DBG(1, "advansys_interrupt: before AscISR()\n");
- AscISR(&ASC_BOARD(asc_host[i])->board);
- }
- }
- ASC_DBG(1, "advansys_interrupt: end\n");
-
- /*
- * While interrupts are still disabled save the list of requests that
- * need their done function called. After re-enabling interrupts call
- * the done function which may re-enable interrupts anyway.
- */
- if ((scp = asc_scsi_done) != NULL) {
- asc_scsi_done = NULL;
- }
-
- /* Re-enable interrupts, if they were enabled on entry. */
- restore_flags(flags);
-
- while (scp) {
- tscp = (Scsi_Cmnd *) scp->host_scribble;
- scp->scsi_done(scp);
- scp = tscp;
- }
-
- return;
-}
-
-/*
- * Function used only with polled I/O requests that are initiated by
- * advansys_command().
- */
-STATIC void
-advansys_command_done(Scsi_Cmnd *scp)
-{
- ASC_DBG1(1, "advansys_command_done: scp %x\n", (unsigned) scp);
- scp->SCp.Status = 1;
-}
-
-/*
- * Execute a single 'Scsi_Cmnd'.
- *
- * The function 'done' is called when the request has been completed.
- *
- * Scsi_Cmnd:
- *
- * host - board controlling device
- * device - device to send command
- * target - target of device
- * lun - lun of device
- * cmd_len - length of SCSI CDB
- * cmnd - buffer for SCSI 8, 10, or 12 byte CDB
- * use_sg - if non-zero indicates scatter-gather request with use_sg elements
- *
- * if (use_sg == 0)
- * request_buffer - buffer address for request
- * request_bufflen - length of request buffer
- * else
- * request_buffer - pointer to scatterlist structure
- *
- * sense_buffer - sense command buffer
- *
- * result (4 bytes of an int):
- * Byte Meaning
- * 0 SCSI Status Byte Code
- * 1 SCSI One Byte Message Code
- * 2 Host Error Code
- * 3 Mid-Level Error Code
- *
- * host driver fields:
- * SCp - Scsi_Pointer used for command processing status
- * scsi_done - used to save caller's done function
- * host_scribble - used for pointer to another Scsi_Cmnd
- *
- * If this function returns ASC_NOERROR or ASC_ERROR the done
- * function has been called. If ASC_BUSY is returned the request
- * must be enqueued by the caller and re-tried later.
- */
-STATIC int
-asc_execute_scsi_cmnd(Scsi_Cmnd *scp)
-{
- ASC_DVC_VAR *boardp;
- ASC_SCSI_Q scsiq;
- ASC_SG_HEAD sghead;
- int ret;
-
- ASC_DBG2(1, "asc_execute_scsi_cmnd: scp %x, done %x\n",
- (unsigned) scp, (unsigned) scp->scsi_done);
-
- boardp = &ASC_BOARD(scp->host)->board;
-
- /*
- * If this is the first command, then initialize the device. If
- * no device is found set 'DID_BAD_TARGET' and return.
- */
- if ((ASC_BOARD(scp->host)->init_tidmask &
- ASC_TIX_TO_TARGET_ID(scp->target)) == 0) {
- if (asc_init_dev(boardp, scp) == ASC_FALSE) {
- scp->result = HOST_BYTE(DID_BAD_TARGET);
- scp->scsi_done(scp);
- return ASC_ERROR;
- }
- ASC_BOARD(scp->host)->init_tidmask |= ASC_TIX_TO_TARGET_ID(scp->target);
- }
-
- memset(&scsiq, 0, sizeof(ASC_SCSI_Q));
-
- /*
- * Point the ASC_SCSI_Q to the 'Scsi_Cmnd'.
- */
- scsiq.q2.srb_ptr = (ulong) scp;
-
- /*
- * Build the ASC_SCSI_Q request.
- */
- scsiq.cdbptr = &scp->cmnd[0];
- scsiq.q2.cdb_len = scp->cmd_len;
- scsiq.q1.target_id = ASC_TID_TO_TARGET_ID(scp->target);
- scsiq.q1.target_lun = scp->lun;
- scsiq.q2.target_ix = ASC_TIDLUN_TO_IX(scp->target, scp->lun);
- scsiq.q1.sense_addr = (ulong) &scp->sense_buffer[0];
- scsiq.q1.sense_len = sizeof(scp->sense_buffer);
- scsiq.q2.tag_code = M2_QTAG_MSG_SIMPLE;
-
- /*
- * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather
- * buffer command.
- */
- if (scp->use_sg == 0) {
- /*
- * CDB request of single contiguous buffer.
- */
- ASC_STATS(cont_cnt);
- /* request_buffer is already a real address. */
- scsiq.q1.data_addr = (ulong) scp->request_buffer;
- scsiq.q1.data_cnt = scp->request_bufflen;
- ASC_STATS_ADD(cont_xfer, (scp->request_bufflen + 511) >> 9);
- scsiq.q1.sg_queue_cnt = 0;
- scsiq.sg_head = NULL;
- } else {
- /*
- * CDB scatter-gather request list.
- */
- int sgcnt;
- struct scatterlist *slp;
-
- if (scp->use_sg > ASC_MAX_SG_LIST) {
- ASC_DBG2(0, "asc_execute_scsi_cmnd: use_sg %d > %d\n",
- scp->use_sg, ASC_MAX_SG_LIST);
- scp->result = HOST_BYTE(DID_ERROR);
- scp->scsi_done(scp);
- return ASC_ERROR;
- }
-
- ASC_STATS(sg_cnt);
-
- /*
- * Allocate a ASC_SG_HEAD structure and set the ASC_SCSI_Q
- * to point to it.
- */
- memset(&sghead, 0, sizeof(ASC_SG_HEAD));
-
- scsiq.q1.cntl |= QC_SG_HEAD;
- scsiq.sg_head = &sghead;
- scsiq.q1.data_cnt = 0;
- scsiq.q1.data_addr = 0;
- sghead.entry_cnt = scsiq.q1.sg_queue_cnt = scp->use_sg;
- ASC_STATS_ADD(sg_elem, sghead.entry_cnt);
-
- /*
- * Convert scatter-gather list into ASC_SG_HEAD list.
- */
- slp = (struct scatterlist *) scp->request_buffer;
- for (sgcnt = 0; sgcnt < scp->use_sg; sgcnt++, slp++) {
- sghead.sg_list[sgcnt].addr = (ulong) slp->address;
- sghead.sg_list[sgcnt].bytes = slp->length;
- ASC_STATS_ADD(sg_xfer, (slp->length + 511) >> 9);
- }
- }
-
- ASC_DBG_PRT_SCSI_Q(2, &scsiq);
- ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len);
-
- switch (ret = AscExeScsiQueue(boardp, &scsiq)) {
- case ASC_NOERROR:
- ASC_DBG(1, "asc_execute_scsi_cmnd: AscExeScsiQueue() ASC_NOERROR\n");
- break;
- case ASC_BUSY:
- /* Caller must enqueue request and retry later. */
- break;
- case ASC_ERROR:
- ASC_DBG1(0,
- "asc_execute_scsi_cmnd: AscExeScsiQueue() ASC_ERROR err_code %x\n",
- boardp->err_code);
- ASC_STATS(error);
- scp->result = HOST_BYTE(DID_ERROR);
- scp->scsi_done(scp);
- break;
- }
-
- ASC_DBG(1, "asc_execute_scsi_cmnd: end\n");
- return ret;
-}
-
-/*
- * asc_isr_callback() - Second Level Interrupt Handler called by AscISR().
- */
-void
-asc_isr_callback(ASC_DVC_VAR *boardp, ASC_QDONE_INFO *qdonep)
-{
- Scsi_Cmnd *scp;
- struct Scsi_Host *shp;
- int flags;
- Scsi_Cmnd **scpp;
-
- ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
- ASC_DBG2(1, "asc_isr_callback: boardp %x, qdonep %x\n",
- (unsigned) boardp, (unsigned) qdonep);
- ASC_STATS(callback);
- ASC_DBG_PRT_QDONE_INFO(2, qdonep);
-
- /*
- * Get the Scsi_Cmnd structure and Scsi_Host structure for the
- * command that has been completed.
- */
- scp = (Scsi_Cmnd *) qdonep->d2.srb_ptr;
- ASC_DBG1(1, "asc_isr_callback: scp %x\n", (unsigned) scp);
- ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len);
-
- shp = scp->host;
- ASC_ASSERT(shp);
- ASC_DBG1(1, "asc_isr_callback: shp %x\n", (unsigned) shp);
-
- /*
- * 'qdonep' contains the command's ending status.
- */
- switch (qdonep->d3.done_stat) {
- case QD_NO_ERROR:
- ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n");
- switch (qdonep->d3.host_stat) {
- case QHSTA_NO_ERROR:
- scp->result = 0;
- break;
- default:
- /* QHSTA error occurred */
- scp->result = HOST_BYTE(DID_ERROR);
- break;
- }
- break;
-
- case QD_WITH_ERROR:
- ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n");
- switch (qdonep->d3.host_stat) {
- case QHSTA_NO_ERROR:
- if (qdonep->d3.scsi_stat == SS_CHK_CONDITION) {
- ASC_DBG(2, "asc_isr_callback: SS_CHK_CONDITION\n");
- ASC_DBG_PRT_SENSE(2, scp->sense_buffer,
- sizeof(scp->sense_buffer));
- /*
- * Note: The status_byte() macro used by target drivers
- * defined in scsi.h shifts the status byte returned by
- * host drivers right by 1 bit. This is why target drivers
- * also use left shifted status byte definitions. For instance
- * target drivers use CHECK_CONDITION, defined to 0x1, instead
- * of the SCSI defined check condition value of 0x2.
- */
- scp->result = DRIVER_BYTE(DRIVER_SENSE) |
- STATUS_BYTE(qdonep->d3.scsi_stat);
- } else {
- scp->result = STATUS_BYTE(qdonep->d3.scsi_stat);
- }
- break;
-
- default:
- /* QHSTA error occurred */
- ASC_DBG1(2, "asc_isr_callback: host_stat %x\n",
- qdonep->d3.host_stat);
- scp->result = HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.scsi_msg) |
- STATUS_BYTE(qdonep->d3.scsi_stat);
- break;
- }
- break;
-
- case QD_ABORTED_BY_HOST:
- ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n");
- scp->result = HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3.scsi_msg) |
- STATUS_BYTE(qdonep->d3.scsi_stat);
- break;
-
- default:
- ASC_DBG1(0, "asc_isr_callback: done_stat %x\n", qdonep->d3.done_stat );
- scp->result = HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3.scsi_msg) |
- STATUS_BYTE(qdonep->d3.scsi_stat);
- break;
- }
-
- /*
- * Before calling 'scsi_done' for the current 'Scsi_Cmnd' and possibly
- * triggering more commands to be issued, try to start any pending
- * commands.
- */
- if (ASC_BOARD(shp)->pending_tidmask != 0) {
- /*
- * If there are any pending commands for this board before trying
- * to execute them, disable interrupts to preserve request ordering.
- */
- ASC_STATS(intr_disable);
- save_flags(flags);
- cli();
- ASC_DBG1(1, "asc_isr_callback: asc_execute_pending() %x\n",
- ASC_BOARD(shp)->pending_tidmask);
- asc_execute_pending(shp);
- restore_flags(flags);
- }
-
- /*
- * Because interrupts may be enabled by the 'Scsi_Cmnd' done function,
- * add the command to the end of the global done list. The done function
- * for the command will be called in advansys_interrupt().
- */
- for (scpp = &asc_scsi_done; *scpp;
- scpp = (Scsi_Cmnd **) &(*scpp)->host_scribble) {
- ;
- }
- *scpp = scp;
- scp->host_scribble = NULL;
- return;
-}
-
-/*
- * Execute as many pending requests as possible for the
- * board specified by 'Scsi_Host'.
- */
-STATIC void
-asc_execute_pending(struct Scsi_Host *shp)
-{
- ASC_SCSI_BIT_ID_TYPE scan_tidmask;
- Scsi_Cmnd *scp;
- int i;
-
- ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
- /*
- * Execute pending commands for devices attached to
- * the current board in round-robin fashion.
- */
- scan_tidmask = ASC_BOARD(shp)->pending_tidmask;
- do {
- for (i = 0; i < ASC_MAX_TID; i++) {
- if (scan_tidmask & ASC_TIX_TO_TARGET_ID(i)) {
- if ((scp = asc_dequeue(shp, i)) == NULL) {
- scan_tidmask &= ~ASC_TIX_TO_TARGET_ID(i);
- } else if (asc_execute_scsi_cmnd(scp) == ASC_BUSY) {
- scan_tidmask &= ~ASC_TIX_TO_TARGET_ID(i);
- /* Put the request back at front of the list. */
- asc_enqueue(shp, scp, i, ASC_FRONT);
- }
- }
- }
- } while (scan_tidmask);
- return;
-}
-
-/*
- * asc_init_dev()
- *
- * Perform one-time initialization of a device.
- */
-STATIC int
-asc_init_dev(ASC_DVC_VAR *boardp, Scsi_Cmnd *scp)
-{
- ASC_SCSI_REQ_Q *scsireqq;
- ASC_CAP_INFO *cap_info;
- ASC_SCSI_INQUIRY *inquiry;
- int found;
- ASC_SCSI_BIT_ID_TYPE save_use_tagged_qng;
- ASC_SCSI_BIT_ID_TYPE save_can_tagged_qng;
- int ret;
-#ifdef ADVANSYS_DEBUG
- ASC_SCSI_BIT_ID_TYPE tidmask; /* target id bit mask: 1 - 128 */
-#endif /* ADVANSYS_DEBUG */
-
- ASC_DBG1(1, "asc_init_dev: target %d\n", (unsigned) scp->target);
-
- /* Return true for the board's target id. */
- if (boardp->cfg->chip_scsi_id == scp->target) {
- return ASC_TRUE;
- }
-
- /*
- * XXX - Host drivers should not modify the timeout field.
- * But on the first command only add some extra time to
- * allow the driver to complete its initialization for the
- * device.
- */
- scp->timeout += 2000; /* Add 5 seconds to the request timeout. */
-
- /* Set-up AscInitPollTarget() arguments. */
- scsireqq = &ASC_BOARD(scp->host)->scsireqq;
- memset(scsireqq, 0, sizeof(ASC_SCSI_REQ_Q));
- cap_info = &ASC_BOARD(scp->host)->cap_info;
- memset(cap_info, 0, sizeof(ASC_CAP_INFO));
- inquiry = &ASC_BOARD(scp->host)->inquiry;
- memset(inquiry, 0, sizeof(ASC_SCSI_INQUIRY));
-
- /*
- * XXX - AscInitPollBegin() re-initializes these fields to
- * zero. 'Or' in the new values and restore them before calling
- * AscInitPollEnd(). Normally all targets are initialized within
- * a call to AscInitPollBegin() and AscInitPollEnd().
- */
- save_use_tagged_qng = boardp->use_tagged_qng;
- save_can_tagged_qng = boardp->cfg->can_tagged_qng;
-
- ASC_DBG(2, "asc_init_dev: AscInitPollBegin()\n");
- if (AscInitPollBegin(boardp)) {
- ASC_DBG(0, "asc_init_dev: AscInitPollBegin() failed\n");
- return ASC_FALSE;
- }
-
- scsireqq->sense_ptr = &scsireqq->sense[0];
- scsireqq->r1.sense_len = ASC_MIN_SENSE_LEN;
- scsireqq->r1.target_id = ASC_TID_TO_TARGET_ID(scp->target);
- scsireqq->r1.target_lun = 0;
- scsireqq->r2.target_ix = ASC_TIDLUN_TO_IX(scp->target, 0);
-
- found = ASC_FALSE;
- ASC_DBG(2, "asc_init_dev: AscInitPollTarget()\n");
- switch (ret = AscInitPollTarget(boardp, scsireqq, inquiry, cap_info)) {
- case ASC_TRUE:
- found = ASC_TRUE;
-#ifdef ADVANSYS_DEBUG
- tidmask = ASC_TIX_TO_TARGET_ID(scp->target);
- ASC_DBG2(1, "asc_init_dev: lba %lu, blk_size %lu\n",
- cap_info->lba, cap_info->blk_size);
- ASC_DBG1(1, "asc_init_dev: peri_dvc_type %x\n",
- inquiry->byte0.peri_dvc_type);
- if (boardp->use_tagged_qng & tidmask) {
- ASC_DBG1(1, "asc_init_dev: command queuing enabled: %d\n",
- boardp->max_dvc_qng[scp->target]);
- } else {
- ASC_DBG(1, "asc_init_dev: command queuing disabled\n");
- }
- if (boardp->init_sdtr & tidmask) {
- ASC_DBG(1, "asc_init_dev: synchronous transfers enabled\n");
- } else {
- ASC_DBG(1, "asc_init_dev: synchronous transfers disabled\n");
- }
- /* Set bit means fix disabled. */
- if (boardp->pci_fix_asyn_xfer & tidmask) {
- ASC_DBG(1, "asc_init_dev: synchronous transfer fix disabled\n");
- } else {
- ASC_DBG(1, "asc_init_dev: synchronous transfer fix enabled\n");
- }
-#endif /* ADVANSYS_DEBUG */
- break;
- case ASC_FALSE:
- ASC_DBG(1, "asc_init_dev: no device found\n");
- break;
- case ASC_ERROR:
- ASC_DBG(0, "asc_init_dev: AscInitPollTarget() ASC_ERROR\n");
- break;
- default:
- ASC_DBG1(0, "asc_init_dev: AscInitPollTarget() unknown ret %d\n", ret);
- break;
- }
-
- /* XXX - 'Or' in original tag bits. */
- boardp->use_tagged_qng |= save_use_tagged_qng;
- boardp->cfg->can_tagged_qng |= save_can_tagged_qng;
-
- ASC_DBG(2, "asc_init_dev: AscInitPollEnd()\n");
- AscInitPollEnd(boardp);
-
-#ifdef ASC_SET_CMD_PER_LUN
- /*
- * XXX - Refer to the comment in advansys_detect()
- * regarding cmd_per_lun.
- */
- for (i = 0; i <= ASC_MAX_TID; i++) {
- if (boardp->max_dvc_qng[i] < scp->host->cmd_per_lun) {
- scp->host->cmd_per_lun = boardp->max_dvc_qng[i];
- }
- }
-#endif /* ASC_SET_CMD_PER_LUN */
-
- return found;
-}
-
-/*
- * Search for an AdvanSys PCI device in the PCI configuration space.
- */
-STATIC int
-asc_srch_pci_dev(PCI_DEVICE *pciDevice)
-{
- int ret;
- static int scan = 1;
-
- ASC_DBG(2, "asc_srch_pci_dev: begin\n");
-
- if (scan) {
- pciDevice->type = asc_scan_method(pciDevice);
- scan = 0;
- ASC_DBG1(2, "asc_srch_pci_dev: type %d\n", pciDevice->type);
- }
- ret = asc_pci_find_dev(pciDevice);
- ASC_DBG1(2, "asc_srch_pci_dev: asc_pci_find_dev() return %d\n", ret);
- if (ret == PCI_DEVICE_FOUND) {
- pciDevice->slotNumber = pciDevice->slotFound + 1;
- pciDevice->startSlot = pciDevice->slotFound + 1;
- } else {
- if (pciDevice->bridge > pciDevice->busNumber) {
- ASC_DBG2(2, "asc_srch_pci_dev: bridge %x, busNumber %x\n",
- pciDevice->bridge, pciDevice->busNumber);
- pciDevice->busNumber++;
- pciDevice->slotNumber = 0;
- pciDevice->startSlot = 0;
- pciDevice->endSlot = 0x0f;
- ret = asc_srch_pci_dev(pciDevice);
- ASC_DBG1(2, "asc_srch_pci_dev recursive call return %d\n", ret);
- }
- }
- ASC_DBG1(2, "asc_srch_pci_dev: return %d\n", ret);
- return ret;
-}
-
-/*
- * Determine the access method to be used for 'pciDevice'.
- */
-STATIC uchar
-asc_scan_method(PCI_DEVICE *pciDevice)
-{
- ushort data;
- PCI_DATA pciData;
- uchar type;
- uchar slot;
-
- ASC_DBG(2, "asc_scan_method: begin\n");
- memset(&pciData, 0, sizeof(pciData));
- for (type = 1; type < 3; type++) {
- pciData.type = type;
- for (slot = 0; slot < PCI_MAX_SLOT; slot++) {
- pciData.slot = slot;
- data = asc_get_cfg_word(&pciData);
- if ((data != 0xFFFF) && (data != 0x0000)) {
- ASC_DBG2(4, "asc_scan_method: data %x, type %d\n", data, type);
- return (type);
- }
- }
- }
- ASC_DBG1(4, "asc_scan_method: type %d\n", type);
- return (type);
-}
-
-/*
- * Check for an AdvanSys PCI device in 'pciDevice'.
- *
- * Return PCI_DEVICE_FOUND if found, otherwise return PCI_DEVICE_NOT_FOUND.
- */
-STATIC int
-asc_pci_find_dev(PCI_DEVICE *pciDevice)
-{
- PCI_DATA pciData;
- ushort vendorid, deviceid;
- uchar classcode, subclass;
- uchar lslot;
-
- ASC_DBG(3, "asc_pci_find_dev: begin\n");
- pciData.type = pciDevice->type;
- pciData.bus = pciDevice->busNumber;
- pciData.func = pciDevice->devFunc;
- lslot = pciDevice->startSlot;
- for (; lslot < pciDevice->endSlot; lslot++) {
- pciData.slot = lslot;
- pciData.offset = VENDORID_OFFSET;
- vendorid = asc_get_cfg_word(&pciData);
- ASC_DBG1(3, "asc_pci_find_dev: vendorid %x\n", vendorid);
- if (vendorid != 0xffff) {
- pciData.offset = DEVICEID_OFFSET;
- deviceid = asc_get_cfg_word(&pciData);
- ASC_DBG1(3, "asc_pci_find_dev: deviceid %x\n", deviceid);
- if ((vendorid == ASC_PCI_VENDORID) &&
- ((deviceid == ASC_PCI_DEVICE_ID_REV_A) ||
- (deviceid == ASC_PCI_DEVICE_ID_REV_B))) {
- pciDevice->slotFound = lslot;
- ASC_DBG(3, "asc_pci_find_dev: PCI_DEVICE_FOUND\n");
- return PCI_DEVICE_FOUND;
- } else {
- pciData.offset = SUBCLASS_OFFSET;
- subclass = asc_get_cfg_byte(&pciData);
- pciData.offset = CLASSCODE_OFFSET;
- classcode = asc_get_cfg_byte(&pciData);
- if ((classcode & PCI_BASE_CLASS_BRIDGE_DEVICE) &&
- (subclass & PCI_SUB_CLASS_PCI_TO_PCI_BRIDGE_CONTROLLER)) {
- pciDevice->bridge++;
- }
- ASC_DBG2(3, "asc_pci_find_dev: subclass %x, classcode %x\n",
- subclass, classcode);
- }
- }
- }
- return PCI_DEVICE_NOT_FOUND;
-}
-
-/*
- * Read PCI configuration data into 'pciConfig'.
- */
-STATIC void
-asc_get_pci_cfg(PCI_DEVICE *pciDevice, PCI_CONFIG_SPACE *pciConfig)
-{
- PCI_DATA pciData;
- uchar counter;
- uchar *localConfig;
-
- ASC_DBG1(4, "asc_get_pci_cfg: slot found - %d\n ",
- pciDevice->slotFound);
-
- pciData.type = pciDevice->type;
- pciData.bus = pciDevice->busNumber;
- pciData.slot = pciDevice->slotFound;
- pciData.func = pciDevice->devFunc;
- localConfig = (uchar *) pciConfig;
-
- for (counter = 0; counter < sizeof(PCI_CONFIG_SPACE); counter++) {
- pciData.offset = counter;
- *localConfig = asc_get_cfg_byte(&pciData);
- ASC_DBG1(4, "asc_get_pci_cfg: byte %x\n", *localConfig);
- localConfig++;
- }
- ASC_DBG1(4, "asc_get_pci_cfg: counter %d\n", counter);
-}
-
-/*
- * Read a word (16 bits) from the PCI configuration space.
- *
- * The configuration mechanism is checked for the correct access method.
- */
-STATIC ushort
-asc_get_cfg_word(PCI_DATA *pciData)
-{
- ushort tmp;
- ulong address;
- ulong lbus = pciData->bus;
- ulong lslot = pciData->slot;
- ulong lfunc = pciData->func;
- uchar t2CFA, t2CF8;
- ushort t1CF8, t1CFA, t1CFC, t1CFE;
-
- ASC_DBG4(4, "asc_get_cfg_word: type %d, bus %lu, slot %lu, func %lu\n",
- pciData->type, lbus, lslot, lfunc);
-
- /*
- * check type of configuration mechanism
- */
- if (pciData->type == 2) {
- /*
- * save these registers so we can restore them after we are done
- */
- t2CFA = inp(0xCFA); /* save PCI bus register */
- t2CF8 = inp(0xCF8); /* save config space enable register */
-
- /*
- * go out and write the bus and enable registers
- */
- /* set for type 1 cycle, if needed */
- outp(0xCFA, pciData->bus);
- /* set the function number */
- outp(0xCF8, 0x10 | (pciData->func << 1)) ;
-
- /*
- * read the configuration space type 2 locations
- */
- tmp = (ushort) inpw(0xC000 | ((pciData->slot << 8) + pciData->offset));
- } else {
- /*
- * type 1 configuration mechanism
- *
- * save the CONFIG_ADDRESS and CONFIG_DATA register values
- */
- t1CFC = inpw(0xCFC);
- t1CFE = inpw(0xCFE);
- t1CF8 = inpw(0xCF8);
- t1CFA = inpw(0xCFA);
-
- /*
- * enable <31>, bus = <23:16>, slot = <15:11>,
- * func = <10:8>, reg = <7:2>
- */
- address = (ulong) ((lbus << 16) | (lslot << 11) |
- (lfunc << 8) | (pciData->offset & 0xFC) | 0x80000000L);
-
- /*
- * write out the address to CONFIG_ADDRESS
- */
- outl(address, 0xCF8);
-
- /*
- * read in the word from CONFIG_DATA
- */
- tmp = (ushort) ((inl(0xCFC) >>
- ((pciData->offset & 2) * 8)) & 0xFFFF);
- }
- ASC_DBG1(4, "asc_get_cfg_word: config data: %x\n", tmp);
- return tmp;
-}
-
-/*
- * Reads a byte from the PCI configuration space.
- *
- * The configuration mechanism is checked for the correct access method.
- */
-STATIC uchar
-asc_get_cfg_byte(PCI_DATA *pciData)
-{
- uchar tmp;
- ulong address;
- ulong lbus = pciData->bus, lslot = pciData->slot, lfunc = pciData->func;
- uchar t2CFA, t2CF8;
- ushort t1CF8, t1CFA, t1CFC, t1CFE;
-
- ASC_DBG1(4, "asc_get_cfg_byte: type: %d\n", pciData->type);
-
- /*
- * check type of configuration mechanism
- */
- if (pciData->type == 2) {
- /*
- * save these registers so we can restore them after we are done
- */
- t2CFA = inp(0xCFA); /* save PCI bus register */
- t2CF8 = inp(0xCF8); /* save config space enable register */
-
- /*
- * go out and write the bus and enable registers
- */
- /* set for type 1 cycle, if needed */
- outp(0xCFA, pciData->bus);
- /* set the function number */
- outp(0xCF8, 0x10 | (pciData->func << 1));
-
- /*
- * read the configuration space type 2 locations
- */
- tmp = inp(0xC000 | ((pciData->slot << 8) + pciData->offset));
-
- /*
- * restore the registers used for our transaction
- */
- outp(0xCF8, t2CF8); /* restore the enable register */
- outp(0xCFA, t2CFA); /* restore PCI bus register */
- } else {
- /*
- * type 1 configuration mechanism
- *
- * save the CONFIG_ADDRESS and CONFIG_DATA register values
- */
- t1CFC = inpw(0xCFC);
- t1CFE = inpw(0xCFE);
- t1CF8 = inpw(0xCF8);
- t1CFA = inpw(0xCFA);
-
- /*
- * enable <31>, bus = <23:16>, slot = <15:11>, func = <10:8>,
- * reg = <7:2>
- */
- address = (ulong) ((lbus << 16) | (lslot << 11) |
- (lfunc << 8) | (pciData->offset & 0xFC) | 0x80000000L);
-
- /*
- * write out the address to CONFIG_ADDRESS
- */
- outl(address, 0xCF8);
-
- /*
- * read in the word from CONFIG_DATA
- */
- tmp = (uchar) ((inl(0xCFC) >> ((pciData->offset & 3) * 8)) & 0xFF);
- }
- ASC_DBG1(4, "asc_get_cfg_byte: config data: %x\n", tmp);
- return tmp;
-}
-
-/*
- * Add a 'Scsi_Cmnd' to the end of specified 'Scsi_Host'
- * target device pending command list. Set 'pending_tidmask'
- * to indicate a command is queued for the device.
- *
- * 'flag' may be either ASC_FRONT or ASC_BACK.
- *
- * The 'Scsi_Cmnd' host_scribble field is used as a next pointer.
- */
-STATIC void
-asc_enqueue(struct Scsi_Host *shp, Scsi_Cmnd *scp, int tid, int flag)
-{
- Scsi_Cmnd **scpp;
-
- ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
- ASC_ASSERT(flag == ASC_FRONT || flag == ASC_BACK);
- ASC_STATS(enqueue);
- if (flag == ASC_FRONT) {
- scp->host_scribble = (unsigned char *) ASC_BOARD(shp)->pending[tid];
- ASC_BOARD(shp)->pending[tid] = (Scsi_Cmnd *) scp;
- } else { /* ASC_BACK */
- for (scpp = &ASC_BOARD(shp)->pending[tid]; *scpp;
- scpp = (Scsi_Cmnd **) &(*scpp)->host_scribble) {
- ;
- }
- *scpp = scp;
- scp->host_scribble = NULL;
- }
- ASC_BOARD(shp)->pending_tidmask |= ASC_TIX_TO_TARGET_ID(tid);
-}
-
-/*
- * Return first pending 'Scsi_Cmnd' on the specified 'Scsi_Host'
- * for the specified target device. Clear the 'pending_tidmask'
- * bit for the device if no more commands are left queued for it.
- *
- * The 'Scsi_Cmnd' host_scribble field is used as a next pointer.
- */
-STATIC Scsi_Cmnd *
-asc_dequeue(struct Scsi_Host *shp, int tid)
-{
- Scsi_Cmnd *scp;
-
- ASC_STATS(dequeue);
- ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
- if ((scp = ASC_BOARD(shp)->pending[tid]) != NULL) {
- ASC_BOARD(shp)->pending[tid] = (Scsi_Cmnd *) scp->host_scribble;
- }
- if (ASC_BOARD(shp)->pending[tid] == NULL) {
- ASC_BOARD(shp)->pending_tidmask &= ~ASC_TIX_TO_TARGET_ID(tid);
- }
- return scp;
-}
-
-/*
- * Remove the specified 'Scsi_Cmnd' from the specified 'Scsi_Host'
- * for the specified target device. Clear the 'pending_tidmask'
- * bit for the device if no more commands are left queued for it.
- *
- * The 'Scsi_Cmnd' host_scribble field is used as a next pointer.
- *
- * Return ASC_TRUE if the command was found and removed, otherwise
- * return ASC_FALSE if the command was not found.
- */
-STATIC int
-asc_rmqueue(struct Scsi_Host *shp, Scsi_Cmnd *scp, int tid)
-{
- Scsi_Cmnd **scpp;
- int ret;
-
- ASC_ASSERT(interrupts_enabled() == ASC_FALSE);
- ret = ASC_FALSE;
- for (scpp = &ASC_BOARD(shp)->pending[tid];
- *scpp; scpp = (Scsi_Cmnd **) &(*scpp)->host_scribble) {
- if (*scpp == scp) {
- *scpp = (Scsi_Cmnd *) scp->host_scribble;
- scp->host_scribble = NULL;
- ASC_STATS(rmqueue);
- ret = ASC_TRUE;
- }
- }
- if (ASC_BOARD(shp)->pending[tid] == NULL) {
- ASC_BOARD(shp)->pending_tidmask &= ~ASC_TIX_TO_TARGET_ID(tid);
- }
- return ret;
-}
-
-
-/*
- * --- Functions Required by the Asc Library
- */
-
-/*
- * Delay for 'n' milliseconds. Don't use the 'jiffies'
- * global variable which is incremented once every 5 ms
- * from a timer interrupt, because this function may be
- * called when interrupts are disabled.
- */
-void
-DvcSleepMilliSecond(ulong n)
-{
- ulong i;
-
- ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", n);
- for (i = 0; i < n; i++) {
- udelay(1000);
- }
-}
-
-void
-DvcDisplayString(uchar *s)
-{
- printk(s);
-}
-
-int
-DvcEnterCritical(void)
-{
- int flags;
-
- save_flags(flags);
- cli();
- return flags;
-}
-
-void
-DvcLeaveCritical(int flags)
-{
- restore_flags(flags);
-}
-
-/*
- * Convert a virtual address to a virtual address.
- *
- * Apparently Linux is loaded V=R (virtual equals real). Just return
- * the virtual address.
- */
-ulong
-DvcGetPhyAddr(uchar *buf_addr, ulong buf_len)
-{
- ulong phys_addr;
-
- phys_addr = (ulong) buf_addr;
- return phys_addr;
-}
-
-ulong
-DvcGetSGList(ASC_DVC_VAR *asc_dvc_sg, uchar *buf_addr, ulong buf_len,
- ASC_SG_HEAD *asc_sg_head_ptr)
-{
- ulong buf_size;
-
- buf_size = buf_len;
- asc_sg_head_ptr->entry_cnt = 1;
- asc_sg_head_ptr->sg_list[0].addr = (ulong) buf_addr;
- asc_sg_head_ptr->sg_list[0].bytes = buf_size;
- return buf_size;
-}
-
-/*
- * void
- * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, ushort *outbuf, int words)
- *
- * Calling/Exit State:
- * none
- *
- * Description:
- * Output an ASC_SCSI_Q structure to the chip
- */
-void
-DvcPutScsiQ(PortAddr iop_base, ushort s_addr, ushort *outbuf, int words)
-{
- int i;
-
- ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", (uchar *) outbuf, 2 * words);
- AscSetChipLramAddr(iop_base, s_addr);
- for (i = 0; i < words; i++, outbuf++) {
- if (i == 2 || i == 10) {
- continue;
- }
- AscPutChipLramData(iop_base, *outbuf);
- }
-}
-
-/*
- * void
- * DvcGetQinfo(PortAddr iop_base, ushort s_addr, ushort *inbuf, int words)
- *
- * Calling/Exit State:
- * none
- *
- * Description:
- * Input an ASC_QDONE_INFO structure from the chip
- */
-void
-DvcGetQinfo(PortAddr iop_base, ushort s_addr, ushort *inbuf, int words)
-{
- int i;
-
- AscSetChipLramAddr(iop_base, s_addr);
- for (i = 0; i < words; i++, inbuf++) {
- if (i == 5) {
- continue;
- }
- *inbuf = AscGetChipLramData(iop_base);
- }
- ASC_DBG_PRT_HEX(2, "DvcGetQinfo", (uchar *) inbuf, 2 * words);
-}
-
-/*
- * void DvcOutPortWords(ushort iop_base, ushort &outbuf, int words)
- *
- * Calling/Exit State:
- * none
- *
- * Description:
- * output a buffer to an i/o port address
- */
-void
-DvcOutPortWords(ushort iop_base, ushort *outbuf, int words)
-{
- int i;
-
- for (i = 0; i < words; i++, outbuf++)
- outpw(iop_base, *outbuf);
-}
-
-/*
- * void DvcInPortWords(ushort iop_base, ushort &outbuf, int words)
- *
- * Calling/Exit State:
- * none
- *
- * Description:
- * input a buffer from an i/o port address
- */
-void
-DvcInPortWords(ushort iop_base, ushort *inbuf, int words)
-{
- int i;
-
- for (i = 0; i < words; i++, inbuf++)
- *inbuf = inpw(iop_base);
-}
-
-
-/*
- * void DvcOutPortDWords(PortAddr port, ulong *pdw, int dwords)
- *
- * Calling/Exit State:
- * none
- *
- * Description:
- * output a buffer of 32-bit integers to an i/o port address in
- * 16 bit integer units
- */
-void
-DvcOutPortDWords(PortAddr port, ulong *pdw, int dwords)
-{
- int i;
- int words;
- ushort *pw;
-
- pw = (ushort *) pdw;
- words = dwords << 1;
- for(i = 0; i < words; i++, pw++) {
- outpw(port, *pw);
- }
- return;
-}
-
-
-/*
- * --- Tracing and Debugging Functions
- */
-
-#ifdef ADVANSYS_STATS
-
-#define ASC_PRT_STATS_NEXT() \
- if (cp) { \
- totlen += len; \
- leftlen -= len; \
- if (leftlen == 0) { \
- return totlen; \
- } \
- cp += len; \
- }
-
-/*
- * asc_prt_stats()
- *
- * Note: no single line should be greater than 160 characters, cf.
- * asc_prt_stats_line().
- *
- * Return the number of characters copied into 'cp'. No more than
- * 'cplen' characters will be copied to 'cp'.
- */
-STATIC int
-asc_prt_stats(char *cp, int cplen)
-{
- struct asc_stats *s;
- int leftlen;
- int totlen;
- int len;
-
- s = &asc_stats;
- leftlen = cplen;
- totlen = len = 0;
-
- len = asc_prt_stats_line(cp, leftlen,
-"\nAdvanSys SCSI Host Driver Statistics:\n");
- ASC_PRT_STATS_NEXT();
-
- len = asc_prt_stats_line(cp, leftlen,
-" command %lu, queuecommand %lu, abort %lu, reset %lu, biosparam %lu,\n",
- s->command, s->queuecommand, s->abort, s->reset, s->biosparam);
- ASC_PRT_STATS_NEXT();
-
- len = asc_prt_stats_line(cp, leftlen,
-" interrupt %lu, callback %lu, cmd_disable %lu, intr_disable %lu,\n",
- s->interrupt, s->callback, s->cmd_disable, s->intr_disable);
- ASC_PRT_STATS_NEXT();
-
- len = asc_prt_stats_line(cp, leftlen,
-" error %lu, enqueue %lu, dequeue %lu, rmqueue %lu,\n",
- s->error, s->enqueue, s->dequeue, s->rmqueue);
- ASC_PRT_STATS_NEXT();
-
- if (s->cont_cnt > 0) {
- len = asc_prt_stats_line(cp, leftlen,
-" cont_cnt %lu, cont_xfer %lu: avg_xfer=%lu kb\n",
- s->cont_cnt, s->cont_xfer, (s->cont_xfer/2)/s->cont_cnt);
- ASC_PRT_STATS_NEXT();
- }
-
- if (s->sg_cnt > 0) {
- len = asc_prt_stats_line(cp, leftlen,
-" sg_cnt %lu, sg_elem %lu, sg_xfer %lu: avg_elem=%lu, avg_size=%lu kb\n",
- s->sg_cnt, s->sg_elem, s->sg_xfer,
- s->sg_elem/s->sg_cnt, (s->sg_xfer/2)/s->sg_cnt);
- ASC_PRT_STATS_NEXT();
- }
-
- return totlen;
-}
-
-/*
- * asc_prt_stats_line()
- *
- * If 'cp' is NULL print to the console, otherwise print to a buffer.
- *
- * Return 0 if printing to the console, otherwise return the number of
- * bytes written to the buffer.
- *
- * Note: If any single line is greater than 160 bytes the stack
- * will be corrupted. 's[]' is defined to be 160 bytes.
- */
-int
-asc_prt_stats_line(char *buf, int buflen, char *fmt, ...)
-{
- va_list args;
- int ret;
- char s[160]; /* 2 lines */
-
- va_start(args, fmt);
- ret = vsprintf(s, fmt, args);
- if (buf == NULL) {
- (void) printk(s);
- ret = 0;
- } else {
- ret = min(buflen, ret);
- memcpy(buf, s, ret);
- }
- va_end(args);
- return ret;
-}
-#endif /* ADVANSYS_STATS */
-
-#ifdef ADVANSYS_DEBUG
-/*
- * asc_prt_scsi_host()
- */
-STATIC void
-asc_prt_scsi_host(struct Scsi_Host *s)
-{
- printk("Scsi_Host at addr %x\n", (unsigned) s);
- printk(
-" next %x, extra_bytes %u, host_busy %u, host_no %d, last_reset %d,\n",
- (unsigned) s->next, s->extra_bytes, s->host_busy, s->host_no,
- s->last_reset);
-
- printk(
-" host_wait %x, host_queue %x, hostt %x, block %x,\n",
- (unsigned) s->host_wait, (unsigned) s->host_queue,
- (unsigned) s->hostt, (unsigned) s->block);
-
- printk(
-" wish_block %d, base %x, io_port %d, n_io_port %d, irq %d, dma_channel %d,\n",
- s->wish_block, (unsigned) s->base, s->io_port, s->n_io_port,
- s->irq, s->dma_channel);
-
- printk(
-" this_id %d, can_queue %d,\n", s->this_id, s->can_queue);
-
- printk(
-" cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d, loaded_as_module %d\n",
- s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma,
- s->loaded_as_module);
-
- printk("hostdata (struct asc_board)\n");
- asc_prt_dvc_var(&ASC_BOARD(s)->board);
- asc_prt_dvc_cfg(&ASC_BOARD(s)->cfg);
- printk(" overrun_buf %x\n", (unsigned) &ASC_BOARD(s)->overrun_buf[0]);
-}
-
-/*
- * asc_prt_dvc_var()
- */
-STATIC void
-asc_prt_dvc_var(ASC_DVC_VAR *h)
-{
- printk("ASC_DVC_VAR at addr %x\n", (unsigned) h);
-
- printk(
-" iop_base %x, err_code %x, dvc_cntl %x, bug_fix_cntl %d,\n",
- h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl);
-
- printk(
-" bus_type %d, isr_callback %x, exe_callback %x, init_sdtr %x,\n",
- h->bus_type, (unsigned) h->isr_callback, (unsigned) h->exe_callback,
- (unsigned) h->init_sdtr);
-
- printk(
-" sdtr_done %x, use_tagged_qng %x, unit_not_ready %x, chip_no %x,\n",
- (unsigned) h->sdtr_done, (unsigned) h->use_tagged_qng,
- (unsigned) h->unit_not_ready, (unsigned) h->chip_no);
-
- printk(
-" queue_full_or_busy %x, start_motor %x, scsi_reset_wait %x, irq_no %x,\n",
- (unsigned) h->queue_full_or_busy, (unsigned) h->start_motor,
- (unsigned) h->scsi_reset_wait, (unsigned) h->irq_no);
-
- printk(
-" is_in_int %x, max_total_qng %x, cur_total_qng %x, in_critical_cnt %x,\n",
- (unsigned) h->is_in_int, (unsigned) h->max_total_qng,
- (unsigned) h->cur_total_qng, (unsigned) h->in_critical_cnt);
-
- printk(
-" last_q_shortage %x, init_state %x, no_scam %x, pci_fix_asyn_xfer %x,\n",
- (unsigned) h->last_q_shortage, (unsigned) h->init_state,
- (unsigned) h->no_scam, (unsigned) h->pci_fix_asyn_xfer);
-
- printk(
-" int_count %ld, req_count %ld, busy_count %ld, cfg %x, saved_ptr2func %x\n",
- h->int_count, h->req_count, h->busy_count, (unsigned) h->cfg,
- (unsigned) h->saved_ptr2func);
-}
-
-/*
- * asc_prt_dvc_cfg()
- */
-STATIC void
-asc_prt_dvc_cfg(ASC_DVC_CFG *h)
-{
- printk("ASC_DVC_CFG at addr %x\n", (unsigned) h);
-
- printk(
-" can_tagged_qng %x, cmd_qng_enabled %x, disc_enable %x, res %x,\n",
- h->can_tagged_qng, h->cmd_qng_enabled, h->disc_enable, h->res);
-
- printk(
-" chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n",
- h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel,
- h->chip_version);
-
- printk(
-" pci_device_id %d, lib_serial_no %d, lib_version %d, mcode_date %d,\n",
- h->pci_device_id, h->lib_serial_no, h->lib_version, h->mcode_date);
-
- printk(
-" mcode_version %d, overrun_buf %x\n",
- h->mcode_version, (unsigned) h->overrun_buf);
-}
-
-/*
- * asc_prt_scsi_q()
- */
-STATIC void
-asc_prt_scsi_q(ASC_SCSI_Q *q)
-{
- ASC_SG_HEAD *sgp;
- int i;
-
- printk("ASC_SCSI_Q at addr %x\n", (unsigned) q);
-
- printk(
-" target_ix %u, target_lun %u, srb_ptr %x, tag_code %u,\n",
- q->q2.target_ix, q->q1.target_lun,
- (unsigned) q->q2.srb_ptr, q->q2.tag_code);
-
- printk(
-" data_addr %x, data_cnt %lu, sense_addr %x, sense_len %u,\n",
- (unsigned) q->q1.data_addr, q->q1.data_cnt,
- (unsigned) q->q1.sense_addr, q->q1.sense_len);
-
- printk(
-" cdbptr %x, cdb_len %u, sg_head %x, sg_queue_cnt %u\n",
- (unsigned) q->cdbptr, q->q2.cdb_len,
- (unsigned) q->sg_head, q->q1.sg_queue_cnt);
-
- if (q->sg_head) {
- sgp = q->sg_head;
- printk("ASC_SG_HEAD at addr %x\n", (unsigned) sgp);
- printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt, sgp->queue_cnt);
- for (i = 0; i < sgp->entry_cnt; i++) {
- printk(" [%u]: addr %x, bytes %lu\n",
- i, (unsigned) sgp->sg_list[i].addr, sgp->sg_list[i].bytes);
- }
-
- }
-}
-
-/*
- * asc_prt_qdone_info()
- */
-STATIC void
-asc_prt_qdone_info(ASC_QDONE_INFO *q)
-{
- printk("ASC_QDONE_INFO at addr %x\n", (unsigned) q);
- printk(
-" srb_ptr %x, target_ix %u, cdb_len %u, tag_code %u, done_stat %x\n",
- (unsigned) q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len,
- q->d2.tag_code, q->d3.done_stat);
- printk(
-" host_stat %x, scsi_stat %x, scsi_msg %x\n",
- q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg);
-}
-
-/*
- * asc_prt_hex()
- *
- * Print hexadecimal output in 4 byte groupings 32 bytes
- * or 8 double-words per line.
- */
-STATIC void
-asc_prt_hex(char *f, uchar *s, int l)
-{
- int i;
- int j;
- int k;
- int m;
-
- printk("%s: (%d bytes)\n", f, l);
-
- for (i = 0; i < l; i += 32) {
-
- /* Display a maximum of 8 double-words per line. */
- if ((k = (l - i) / 4) >= 8) {
- k = 8;
- m = 0;
- } else {
- m = (l - i) % 4 ;
- }
-
- for (j = 0; j < k; j++) {
- printk(" %2.2X%2.2X%2.2X%2.2X",
- (unsigned) s[i+(j*4)], (unsigned) s[i+(j*4)+1],
- (unsigned) s[i+(j*4)+2], (unsigned) s[i+(j*4)+3]);
- }
-
- switch (m) {
- case 0:
- default:
- break;
- case 1:
- printk(" %2.2X",
- (unsigned) s[i+(j*4)+4]);
- break;
- case 2:
- printk(" %2.2X%2.2X",
- (unsigned) s[i+(j*4)+4],
- (unsigned) s[i+(j*4)+5]);
- break;
- case 3:
- printk(" %2.2X%2.2X%2.2X",
- (unsigned) s[i+(j*4)+4],
- (unsigned) s[i+(j*4)+5],
- (unsigned) s[i+(j*4)+6]);
- break;
- }
-
- printk("\n");
- }
-}
-
-/*
- * interrupts_enabled()
- *
- * Return 1 if interrupts are enabled, otherwise return 0.
- */
-STATIC int
-interrupts_enabled(void)
-{
- int flags;
-
- save_flags(flags);
- if (flags & 0x0200) {
- return ASC_TRUE;
- } else {
- return ASC_FALSE;
- }
-}
-
-#endif /* ADVANSYS_DEBUG */
-
-
-/*
- * --- Asc Library Functions
- */
-
-ushort
-AscGetEisaChipCfg(
- PortAddr iop_base
-)
-{
- PortAddr eisa_cfg_iop;
-
- eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
- (PortAddr) (ASC_EISA_CFG_IOP_MASK);
- return (inpw(eisa_cfg_iop));
-}
-
-uchar
-AscSetChipScsiID(
- PortAddr iop_base,
- uchar new_host_id
-)
-{
- ushort cfg_lsw;
-
- if (AscGetChipScsiID(iop_base) == new_host_id) {
- return (new_host_id);
- }
- cfg_lsw = AscGetChipCfgLsw(iop_base);
- cfg_lsw &= 0xF8FF;
- cfg_lsw |= (ushort) ((new_host_id & ASC_MAX_TID) << 8);
- AscSetChipCfgLsw(iop_base, cfg_lsw);
- return (AscGetChipScsiID(iop_base));
-}
-
-ushort
-AscGetChipBiosAddress(
- PortAddr iop_base,
- ushort bus_type
-)
-{
- ushort cfg_lsw;
- ushort bios_addr;
-
- if ((bus_type & ASC_IS_EISA) != 0) {
- cfg_lsw = AscGetEisaChipCfg(iop_base);
- cfg_lsw &= 0x000F;
- bios_addr = (ushort) (ASC_BIOS_MIN_ADDR +
- (cfg_lsw * ASC_BIOS_BANK_SIZE));
- return (bios_addr);
- }
- cfg_lsw = AscGetChipCfgLsw(iop_base);
- bios_addr = (ushort) (((cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE) + ASC_BIOS_MIN_ADDR);
- return (bios_addr);
-}
-
-uchar
-AscGetChipVersion(
- PortAddr iop_base,
- ushort bus_type
-)
-{
- if ((bus_type & ASC_IS_EISA) != 0) {
-
- PortAddr eisa_iop;
- uchar revision;
-
- eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) |
- (PortAddr) ASC_EISA_REV_IOP_MASK;
- revision = inp(eisa_iop);
- return ((uchar) ((ASC_CHIP_MIN_VER_EISA - 1) + revision));
- }
- return (AscGetChipVerNo(iop_base));
-}
-
-ushort
-AscGetChipBusType(
- PortAddr iop_base
-)
-{
- ushort chip_ver;
-
- chip_ver = AscGetChipVerNo(iop_base);
- if ((chip_ver >= ASC_CHIP_MIN_VER_VL) &&
- (chip_ver <= ASC_CHIP_MAX_VER_VL)) {
- if (((iop_base & 0x0C30) == 0x0C30) ||
- ((iop_base & 0x0C50) == 0x0C50)) {
- return (ASC_IS_EISA);
- }
- return (ASC_IS_VL);
- } else if ((chip_ver >= ASC_CHIP_MIN_VER_ISA) &&
- (chip_ver <= ASC_CHIP_MAX_VER_ISA)) {
- if (chip_ver >= ASC_CHIP_MIN_VER_ISA_PNP) {
- return (ASC_IS_ISAPNP);
- }
- return (ASC_IS_ISA);
- } else if ((chip_ver >= ASC_CHIP_MIN_VER_PCI) &&
- (chip_ver <= ASC_CHIP_MAX_VER_PCI)) {
- return (ASC_IS_PCI);
- } else {
- return (0);
- }
-}
-
-void
-AscEnableIsaDma(
- uchar dma_channel
-)
-{
- if (dma_channel < 4) {
- outp(0x000B, (ushort) (0xC0 | dma_channel));
- outp(0x000A, dma_channel);
- } else if (dma_channel < 8) {
-
- outp(0x00D6, (ushort) (0xC0 | (dma_channel - 4)));
- outp(0x00D4, (ushort) (dma_channel - 4));
- }
- return;
-}
-
-ulong
-AscLoadMicroCode(
- PortAddr iop_base,
- ushort s_addr,
- ushort dosfar * mcode_buf,
- ushort mcode_size
-)
-{
- ulong chksum;
- ushort mcode_word_size;
- ushort mcode_chksum;
-
- mcode_word_size = (ushort) (mcode_size >> 1);
- AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size);
- AscMemWordCopyToLram(iop_base, s_addr, mcode_buf, mcode_word_size);
-
- chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size);
- mcode_chksum = (ushort) AscMemSumLramWord(iop_base,
- (ushort) ASC_CODE_SEC_BEG,
- (ushort) ((mcode_size - s_addr - (ushort) ASC_CODE_SEC_BEG) / 2));
- AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum);
- AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size);
- return (chksum);
-}
-
-uchar _hextbl_[16] =
-{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
- 'A', 'B', 'C', 'D', 'E', 'F'};
-
-uchar _isa_pnp_inited = 0;
-
-PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] =
-{
- 0x100, ASC_IOADR_1, 0x120, ASC_IOADR_2, 0x140, ASC_IOADR_3, ASC_IOADR_4,
- ASC_IOADR_5, ASC_IOADR_6, ASC_IOADR_7, ASC_IOADR_8
-};
-
-PortAddr
-AscSearchIOPortAddr(
- PortAddr iop_beg,
- ushort bus_type
-)
-{
- if (bus_type & ASC_IS_VL) {
- while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
- if (AscGetChipVersion(iop_beg, bus_type) <= ASC_CHIP_MAX_VER_VL) {
- return (iop_beg);
- }
- }
- return (0);
- }
- if (bus_type & ASC_IS_ISA) {
- if (_isa_pnp_inited == 0) {
- AscSetISAPNPWaitForKey();
- _isa_pnp_inited++;
- }
- while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) {
- if ((AscGetChipVersion(iop_beg, bus_type) & ASC_CHIP_VER_ISA_BIT) != 0) {
- return (iop_beg);
- }
- }
- return (0);
- }
- if (bus_type & ASC_IS_EISA) {
- if ((iop_beg = AscSearchIOPortAddrEISA(iop_beg)) != 0) {
- return (iop_beg);
- }
- return (0);
- }
- return (0);
-}
-
-PortAddr
-AscSearchIOPortAddr11(
- PortAddr s_addr
-)
-{
-
- int i;
- PortAddr iop_base;
-
- for (i = 0; i < ASC_IOADR_TABLE_MAX_IX; i++) {
- if (_asc_def_iop_base[i] > s_addr) {
- break;
- }
- }
- for (; i < ASC_IOADR_TABLE_MAX_IX; i++) {
- iop_base = _asc_def_iop_base[i];
- if (AscFindSignature(iop_base)) {
- return (iop_base);
- }
- }
- return (0);
-}
-
-int
-AscFindSignature(
- PortAddr iop_base
-)
-{
- ushort sig_word;
-
- if ((inp((PortAddr) (iop_base + 1)) & 0xFF) == (uchar) ASC_1000_ID1B) {
- sig_word = inpw(iop_base);
- if ((sig_word == (ushort) ASC_1000_ID0W) ||
- (sig_word == (ushort) ASC_1000_ID0W_FIX)) {
- return (1);
- }
- }
- return (0);
-}
-
-void
-AscToggleIRQAct(
- PortAddr iop_base
-)
-{
- AscSetChipStatus(iop_base, CIW_IRQ_ACT);
- AscSetChipStatus(iop_base, 0);
- return;
-}
-
-#if CC_INIT_INQ_DISPLAY
-
-#endif
-
-void
-AscSetISAPNPWaitForKey(
- void)
-{
-
- outp(ASC_ISA_PNP_PORT_ADDR, 0x02);
- outp(ASC_ISA_PNP_PORT_WRITE, 0x02);
- return;
-}
-
-uchar
-AscGetChipIRQ(
- PortAddr iop_base,
- ushort bus_type
-)
-{
- ushort cfg_lsw;
- uchar chip_irq;
-
- if ((bus_type & ASC_IS_EISA) != 0) {
-
- cfg_lsw = AscGetEisaChipCfg(iop_base);
- chip_irq = (uchar) (((cfg_lsw >> 8) & 0x07) + 10);
- if ((chip_irq == 13) || (chip_irq > 15)) {
-
- return (0);
- }
- return (chip_irq);
- } else {
-
- cfg_lsw = AscGetChipCfgLsw(iop_base);
-
- if ((bus_type & ASC_IS_VL) != 0) {
-
- chip_irq = (uchar) (((cfg_lsw >> 2) & 0x07));
- if ((chip_irq == 0) ||
- (chip_irq == 4) ||
- (chip_irq == 7)) {
- return (0);
- }
- return ((uchar) (chip_irq + (ASC_MIN_IRQ_NO - 1)));
- }
- chip_irq = (uchar) (((cfg_lsw >> 2) & 0x03));
- if (chip_irq == 3)
- chip_irq += (uchar) 2;
- return ((uchar) (chip_irq + ASC_MIN_IRQ_NO));
- }
-}
-
-uchar
-AscSetChipIRQ(
- PortAddr iop_base,
- uchar irq_no,
- ushort bus_type
-)
-{
- ushort cfg_lsw;
-
- if ((bus_type & ASC_IS_VL) != 0) {
-
- if (irq_no != 0) {
- if ((irq_no < ASC_MIN_IRQ_NO) || (irq_no > ASC_MAX_IRQ_NO)) {
- irq_no = 0;
- } else {
- irq_no -= (uchar) ((ASC_MIN_IRQ_NO - 1));
- }
- }
- cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFE3);
- cfg_lsw |= (ushort) 0x0010;
- AscSetChipCfgLsw(iop_base, cfg_lsw);
- AscToggleIRQAct(iop_base);
-
- cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFE0);
- cfg_lsw |= (ushort) ((irq_no & 0x07) << 2);
- AscSetChipCfgLsw(iop_base, cfg_lsw);
- AscToggleIRQAct(iop_base);
-
- return (AscGetChipIRQ(iop_base, bus_type));
-
- } else if ((bus_type & (ASC_IS_ISA)) != 0) {
-
- if (irq_no == 15)
- irq_no -= (uchar) 2;
- irq_no -= (uchar) ASC_MIN_IRQ_NO;
- cfg_lsw = (ushort) (AscGetChipCfgLsw(iop_base) & 0xFFF3);
- cfg_lsw |= (ushort) ((irq_no & 0x03) << 2);
- AscSetChipCfgLsw(iop_base, cfg_lsw);
- return (AscGetChipIRQ(iop_base, bus_type));
- } else {
-
- return (0);
- }
-}
-
-uchar
-AscGetChipScsiCtrl(
- PortAddr iop_base
-)
-{
- uchar sc;
-
- AscSetBank(iop_base, 1);
- sc = inp(iop_base + IOP_REG_SC);
- AscSetBank(iop_base, 0);
- return (sc);
-}
-
-extern uchar _sdtr_period_tbl_[];
-
-int
-AscIsrChipHalted(
- ASC_DVC_VAR asc_ptr_type * asc_dvc
-)
-{
- SDTR_XMSG sdtr_xmsg;
- SDTR_XMSG out_msg;
- ushort halt_q_addr;
- int sdtr_accept;
- ushort int_halt_code;
- ASC_SCSI_BIT_ID_TYPE scsi_busy;
- ASC_SCSI_BIT_ID_TYPE target_id;
- PortAddr iop_base;
- uchar tag_code;
- uchar q_status;
- uchar halt_qp;
- uchar sdtr_data;
- uchar target_ix;
- uchar q_cntl, tid_no;
- uchar cur_dvc_qng;
- uchar asyn_sdtr;
- uchar scsi_status;
-
- iop_base = asc_dvc->iop_base;
- int_halt_code = AscReadLramWord(iop_base, ASCV_HALTCODE_W);
-
- halt_qp = AscReadLramByte(iop_base, ASCV_CURCDB_B);
- halt_q_addr = ASC_QNO_TO_QADDR(halt_qp);
- target_ix = AscReadLramByte(iop_base,
- (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TARGET_IX));
- q_cntl = AscReadLramByte(iop_base,
- (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL));
- tid_no = ASC_TIX_TO_TID(target_ix);
- target_id = (uchar) ASC_TID_TO_TARGET_ID(tid_no);
- if (asc_dvc->pci_fix_asyn_xfer & target_id) {
-
- asyn_sdtr = ASYN_SDTR_DATA_FIX_PCI_REV_AB;
- } else {
- asyn_sdtr = 0;
- }
- if (int_halt_code == ASC_HALT_EXTMSG_IN) {
-
- AscMemWordCopyFromLram(iop_base,
- ASCV_MSGIN_BEG,
- (ushort dosfar *) & sdtr_xmsg,
- (ushort) (sizeof (SDTR_XMSG) >> 1));
- if ((sdtr_xmsg.msg_type == MS_EXTEND) &&
- (sdtr_xmsg.msg_len == MS_SDTR_LEN)) {
- sdtr_accept = TRUE;
- if (sdtr_xmsg.msg_req == MS_SDTR_CODE) {
- if (sdtr_xmsg.req_ack_offset > ASC_SYN_MAX_OFFSET) {
-
- sdtr_accept = FALSE;
- sdtr_xmsg.req_ack_offset = ASC_SYN_MAX_OFFSET;
- }
- sdtr_data = AscCalSDTRData(sdtr_xmsg.xfer_period,
- sdtr_xmsg.req_ack_offset);
- if (sdtr_xmsg.req_ack_offset == 0) {
-
- q_cntl &= ~QC_MSG_OUT;
- asc_dvc->init_sdtr &= ~target_id;
- asc_dvc->sdtr_done &= ~target_id;
- AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
- } else if ((sdtr_data == 0xFF)) {
-
- q_cntl |= QC_MSG_OUT;
- asc_dvc->init_sdtr &= ~target_id;
- asc_dvc->sdtr_done &= ~target_id;
- AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
- } else {
- if (sdtr_accept && (q_cntl & QC_MSG_OUT)) {
-
- q_cntl &= ~QC_MSG_OUT;
- asc_dvc->sdtr_done |= target_id;
- asc_dvc->init_sdtr |= target_id;
- asc_dvc->pci_fix_asyn_xfer &= ~target_id;
- AscSetChipSDTR(iop_base, sdtr_data, tid_no);
- } else {
-
- q_cntl |= QC_MSG_OUT;
-
- AscMsgOutSDTR(iop_base,
- sdtr_xmsg.xfer_period,
- sdtr_xmsg.req_ack_offset);
- asc_dvc->pci_fix_asyn_xfer &= ~target_id;
- AscSetChipSDTR(iop_base, sdtr_data, tid_no);
- asc_dvc->sdtr_done |= target_id;
- asc_dvc->init_sdtr |= target_id;
- }
- }
-
- AscWriteLramByte(iop_base,
- (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
- q_cntl);
- AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
- return (0);
- }
- }
- } else if (int_halt_code == ASC_HALT_CHK_CONDITION) {
-
- q_cntl |= QC_REQ_SENSE;
- if (((asc_dvc->init_sdtr & target_id) != 0) &&
- ((asc_dvc->sdtr_done & target_id) != 0)) {
-
- sdtr_data = AscReadLramByte(iop_base,
- (ushort) ((ushort) ASCV_SDTR_DATA_BEG + (ushort) tid_no));
- AscMsgOutSDTR(iop_base,
- _sdtr_period_tbl_[(sdtr_data >> 4) & (uchar) (ASC_SYN_XFER_NO - 1)],
- (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET));
- q_cntl |= QC_MSG_OUT;
- }
- AscWriteLramByte(iop_base,
- (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
- q_cntl);
-
- tag_code = AscReadLramByte(iop_base,
- (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE));
- tag_code &= 0xDC;
- AscWriteLramByte(iop_base,
- (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE),
- tag_code);
-
- q_status = AscReadLramByte(iop_base,
- (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS));
- q_status |= (QS_READY | QS_BUSY);
- AscWriteLramByte(iop_base,
- (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_STATUS),
- q_status);
-
- scsi_busy = AscReadLramByte(iop_base,
- (ushort) ASCV_SCSIBUSY_B);
- scsi_busy &= ~target_id;
- AscWriteLramByte(iop_base, (ushort) ASCV_SCSIBUSY_B, scsi_busy);
-
- AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
- return (0);
- } else if (int_halt_code == ASC_HALT_SDTR_REJECTED) {
-
- AscMemWordCopyFromLram(iop_base,
- ASCV_MSGOUT_BEG,
- (ushort dosfar *) & out_msg,
- (ushort) (sizeof (SDTR_XMSG) >> 1));
-
- if ((out_msg.msg_type == MS_EXTEND) &&
- (out_msg.msg_len == MS_SDTR_LEN) &&
- (out_msg.msg_req == MS_SDTR_CODE)) {
-
- asc_dvc->init_sdtr &= ~target_id;
- asc_dvc->sdtr_done &= ~target_id;
- AscSetChipSDTR(iop_base, asyn_sdtr, tid_no);
-
- } else {
-
- }
-
- q_cntl &= ~QC_MSG_OUT;
- AscWriteLramByte(iop_base,
- (ushort) (halt_q_addr + (ushort) ASC_SCSIQ_B_CNTL),
- q_cntl);
- AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
- return (0);
- } else if (int_halt_code == ASC_HALT_SS_QUEUE_FULL) {
-
- scsi_status = AscReadLramByte(iop_base,
- (ushort) ((ushort) halt_q_addr + (ushort) ASC_SCSIQ_SCSI_STATUS));
- cur_dvc_qng = AscReadLramByte(iop_base,
- (ushort) ((ushort) ASC_QADR_BEG + (ushort) target_ix));
- if ((cur_dvc_qng > 0) &&
- (asc_dvc->cur_dvc_qng[tid_no] > 0)) {
-
- scsi_busy = AscReadLramByte(iop_base,
- (ushort) ASCV_SCSIBUSY_B);
- scsi_busy |= target_id;
- AscWriteLramByte(iop_base,
- (ushort) ASCV_SCSIBUSY_B, scsi_busy);
- asc_dvc->queue_full_or_busy |= target_id;
-
- if (scsi_status == SS_QUEUE_FULL) {
- if (cur_dvc_qng > ASC_MIN_TAGGED_CMD) {
- cur_dvc_qng -= 1;
- asc_dvc->max_dvc_qng[tid_no] = cur_dvc_qng;
-
- AscWriteLramByte(iop_base,
- (ushort) ((ushort) ASCV_MAX_DVC_QNG_BEG + (ushort) tid_no),
- cur_dvc_qng);
- }
- }
- }
- AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
- return (0);
- }
- return (0);
-}
-
-uchar
-_AscCopyLramScsiDoneQ(
- PortAddr iop_base,
- ushort q_addr,
- ASC_QDONE_INFO dosfar * scsiq,
- ulong max_dma_count
-)
-{
- ushort _val;
- uchar sg_queue_cnt;
-
- DvcGetQinfo(iop_base,
- (ushort) (q_addr + (ushort) ASC_SCSIQ_DONE_INFO_BEG),
- (ushort dosfar *) scsiq,
- (ushort) ((sizeof (ASC_SCSIQ_2) + sizeof (ASC_SCSIQ_3)) / 2));
-
-#if !CC_LITTLE_ENDIAN_HOST
- AscAdjEndianQDoneInfo(scsiq);
-#endif
-
- _val = AscReadLramWord(iop_base,
- (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS));
- scsiq->q_status = (uchar) _val;
- scsiq->q_no = (uchar) (_val >> 8);
-
- _val = AscReadLramWord(iop_base,
- (ushort) (q_addr + (ushort) ASC_SCSIQ_B_CNTL));
- scsiq->cntl = (uchar) _val;
- sg_queue_cnt = (uchar) (_val >> 8);
-
- _val = AscReadLramWord(iop_base,
- (ushort) (q_addr + (ushort) ASC_SCSIQ_B_SENSE_LEN));
- scsiq->sense_len = (uchar) _val;
- scsiq->user_def = (uchar) (_val >> 8);
-
- scsiq->remain_bytes = AscReadLramDWord(iop_base,
- (ushort) (q_addr + (ushort) ASC_SCSIQ_DW_REMAIN_XFER_CNT));
- scsiq->remain_bytes &= max_dma_count;
-
- return (sg_queue_cnt);
-}
-
-int
-AscIsrQDone(
- ASC_DVC_VAR asc_ptr_type * asc_dvc
-)
-{
- uchar next_qp;
- uchar i;
- uchar n_q_used;
- uchar sg_list_qp;
- uchar sg_queue_cnt;
- uchar done_q_tail;
-
- uchar tid_no;
- ASC_SCSI_BIT_ID_TYPE scsi_busy;
- ASC_SCSI_BIT_ID_TYPE target_id;
- PortAddr iop_base;
- ushort q_addr;
- ushort sg_q_addr;
- uchar cur_target_qng;
- ASC_QDONE_INFO scsiq_buf;
- ASC_QDONE_INFO dosfar *scsiq;
- int false_overrun;
- ASC_ISR_CALLBACK asc_isr_callback;
-
- uchar tag_code;
-
-#if CC_LINK_BUSY_Q
- ushort n_busy_q_done;
-
-#endif
-
- iop_base = asc_dvc->iop_base;
- asc_isr_callback = (ASC_ISR_CALLBACK) asc_dvc->isr_callback;
-
- n_q_used = 1;
- scsiq = (ASC_QDONE_INFO dosfar *) & scsiq_buf;
- done_q_tail = (uchar) AscGetVarDoneQTail(iop_base);
- q_addr = ASC_QNO_TO_QADDR(done_q_tail);
- next_qp = AscReadLramByte(iop_base,
- (ushort) (q_addr + (ushort) ASC_SCSIQ_B_FWD));
- if (next_qp != ASC_QLINK_END) {
-
- AscPutVarDoneQTail(iop_base, next_qp);
- q_addr = ASC_QNO_TO_QADDR(next_qp);
-
- sg_queue_cnt = _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq, asc_dvc->max_dma_count);
-
- AscWriteLramByte(iop_base,
- (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
- (uchar) (scsiq->q_status & (uchar) ~ (QS_READY | QS_ABORTED)));
- tid_no = ASC_TIX_TO_TID(scsiq->d2.target_ix);
- target_id = ASC_TIX_TO_TARGET_ID(scsiq->d2.target_ix);
- if ((scsiq->cntl & QC_SG_HEAD) != 0) {
- sg_q_addr = q_addr;
- sg_list_qp = next_qp;
- for (i = 0; i < sg_queue_cnt; i++) {
- sg_list_qp = AscReadLramByte(iop_base,
- (ushort) (sg_q_addr + (ushort) ASC_SCSIQ_B_FWD));
- sg_q_addr = ASC_QNO_TO_QADDR(sg_list_qp);
- if (sg_list_qp == ASC_QLINK_END) {
- AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SG_Q_LINKS);
- scsiq->d3.done_stat = QD_WITH_ERROR;
- scsiq->d3.host_stat = QHSTA_D_QDONE_SG_LIST_CORRUPTED;
- goto FATAL_ERR_QDONE;
- }
- AscWriteLramByte(iop_base,
- (ushort) (sg_q_addr + (ushort) ASC_SCSIQ_B_STATUS),
- QS_FREE);
- }
-
- n_q_used = sg_queue_cnt + 1;
- AscPutVarDoneQTail(iop_base, sg_list_qp);
- }
- if (asc_dvc->queue_full_or_busy & target_id) {
-
- cur_target_qng = AscReadLramByte(iop_base,
- (ushort) ((ushort) ASC_QADR_BEG + (ushort) scsiq->d2.target_ix));
- if (cur_target_qng < asc_dvc->max_dvc_qng[tid_no]) {
- scsi_busy = AscReadLramByte(iop_base,
- (ushort) ASCV_SCSIBUSY_B);
- scsi_busy &= ~target_id;
- AscWriteLramByte(iop_base,
- (ushort) ASCV_SCSIBUSY_B, scsi_busy);
- asc_dvc->queue_full_or_busy &= ~target_id;
- }
- }
- if (asc_dvc->cur_total_qng >= n_q_used) {
- asc_dvc->cur_total_qng -= n_q_used;
- if (asc_dvc->cur_dvc_qng[tid_no] != 0) {
- asc_dvc->cur_dvc_qng[tid_no]--;
- }
- } else {
- AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CUR_QNG);
- scsiq->d3.done_stat = QD_WITH_ERROR;
- goto FATAL_ERR_QDONE;
- }
-
- if ((scsiq->d2.srb_ptr == 0UL) ||
- ((scsiq->q_status & QS_ABORTED) != 0)) {
-
- return (0x11);
- } else if (scsiq->q_status == QS_DONE) {
-
- false_overrun = FALSE;
-
- if (asc_dvc->bug_fix_cntl) {
- if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ADD_ONE_BYTE) {
- tag_code = AscReadLramByte(iop_base,
- (ushort) (q_addr + (ushort) ASC_SCSIQ_B_TAG_CODE));
- if (tag_code & ASC_TAG_FLAG_ADD_ONE_BYTE) {
- if (scsiq->remain_bytes != 0UL) {
- scsiq->remain_bytes--;
- if (scsiq->remain_bytes == 0UL) {
- false_overrun = TRUE;
- }
- }
- }
- }
- }
- if ((scsiq->d3.done_stat == QD_WITH_ERROR) &&
- (scsiq->d3.host_stat == QHSTA_M_DATA_OVER_RUN)) {
- if ((scsiq->cntl & (QC_DATA_IN | QC_DATA_OUT)) == 0) {
- scsiq->d3.done_stat = QD_NO_ERROR;
- scsiq->d3.host_stat = QHSTA_NO_ERROR;
- } else if (false_overrun) {
- scsiq->d3.done_stat = QD_NO_ERROR;
- scsiq->d3.host_stat = QHSTA_NO_ERROR;
- }
- }
-#if CC_CLEAR_LRAM_SRB_PTR
- AscWriteLramDWord(iop_base,
- (ushort) (q_addr + (ushort) ASC_SCSIQ_D_SRBPTR),
- asc_dvc->int_count);
-#endif
-
- if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
- (*asc_isr_callback) (asc_dvc, scsiq);
- } else {
- if ((AscReadLramByte(iop_base,
- (ushort) (q_addr + (ushort) ASC_SCSIQ_CDB_BEG)) ==
- SCSICMD_StartStopUnit)) {
-
- asc_dvc->unit_not_ready &= ~target_id;
- if (scsiq->d3.done_stat != QD_NO_ERROR) {
- asc_dvc->start_motor &= ~target_id;
- }
- }
- }
-
-#if CC_LINK_BUSY_Q
- n_busy_q_done = AscIsrExeBusyQueue(asc_dvc, tid_no);
- if (n_busy_q_done == 0) {
-
- i = tid_no + 1;
- while (TRUE) {
- if (i > ASC_MAX_TID)
- i = 0;
- if (i == tid_no)
- break;
- n_busy_q_done = AscIsrExeBusyQueue(asc_dvc, i);
- if (n_busy_q_done != 0)
- break;
- i++;
- }
- }
- if (n_busy_q_done == 0xFFFF)
- return (0x80);
-#endif
-
- return (1);
- } else {
-
- AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS);
-
- FATAL_ERR_QDONE:
- if ((scsiq->cntl & QC_NO_CALLBACK) == 0) {
- (*asc_isr_callback) (asc_dvc, scsiq);
- }
- return (0x80);
- }
- }
- return (0);
-}
-
-int
-AscISR(
- ASC_DVC_VAR asc_ptr_type * asc_dvc
-)
-{
- ASC_CS_TYPE chipstat;
- PortAddr iop_base;
- ushort saved_ram_addr;
- uchar ctrl_reg;
- uchar saved_ctrl_reg;
- int int_pending;
- int status;
- uchar host_flag;
-
- iop_base = asc_dvc->iop_base;
- int_pending = FALSE;
-
- asc_dvc->int_count++;
-
- if (((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0) ||
- (asc_dvc->isr_callback == 0)) {
-
- return (ERR);
- }
- if (asc_dvc->in_critical_cnt != 0) {
- AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL);
- return (ERR);
- }
- if (asc_dvc->is_in_int) {
- AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY);
- asc_dvc->busy_count++;
- return (ERR);
- }
- asc_dvc->is_in_int = TRUE;
- ctrl_reg = AscGetChipControl(iop_base);
- saved_ctrl_reg = ctrl_reg & (~(CC_SCSI_RESET | CC_CHIP_RESET |
- CC_SINGLE_STEP | CC_DIAG | CC_TEST));
-
- if ((chipstat = AscGetChipStatus(iop_base)) & CSW_INT_PENDING) {
- int_pending = TRUE;
- AscAckInterrupt(iop_base);
-
- host_flag = AscReadLramByte(iop_base, ASCV_HOST_FLAG_B);
- AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
- (uchar) (host_flag | (uchar) ASC_HOST_FLAG_IN_ISR));
- saved_ram_addr = AscGetChipLramAddr(iop_base);
-
- if ((chipstat & CSW_HALTED) &&
- (ctrl_reg & CC_SINGLE_STEP)) {
- if (AscIsrChipHalted(asc_dvc) == ERR) {
-
- goto ISR_REPORT_QDONE_FATAL_ERROR;
-
- } else {
- saved_ctrl_reg &= ~CC_HALT;
- }
- } else {
- ISR_REPORT_QDONE_FATAL_ERROR:
- if ((asc_dvc->dvc_cntl & ASC_CNTL_INT_MULTI_Q) != 0) {
- while (((status = AscIsrQDone(asc_dvc)) & 0x01) != 0) {
-
- }
- } else {
- do {
- if ((status = AscIsrQDone(asc_dvc)) == 1) {
-
- break;
- }
- } while (status == 0x11);
- }
- if ((status & 0x80) != 0)
- int_pending = ERR;
- }
- AscSetChipLramAddr(iop_base, saved_ram_addr);
- if (AscGetChipLramAddr(iop_base) != saved_ram_addr) {
- AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SET_LRAM_ADDR);
- }
- AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
- }
- AscSetChipControl(iop_base, saved_ctrl_reg);
- asc_dvc->is_in_int = FALSE;
- return (int_pending);
-}
-
-int
-AscScsiSetupCmdQ(
- ASC_DVC_VAR asc_ptr_type * asc_dvc,
- ASC_SCSI_REQ_Q dosfar * scsiq,
- uchar dosfar * buf_addr,
- ulong buf_len
-)
-{
- ulong phy_addr;
-
- scsiq->r1.cntl = 0;
- scsiq->r1.sg_queue_cnt = 0;
- scsiq->r1.q_no = 0;
- scsiq->r1.user_def = 0;
- scsiq->cdbptr = (uchar dosfar *) scsiq->cdb;
- scsiq->r3.scsi_stat = 0;
- scsiq->r3.scsi_msg = 0;
- scsiq->r3.host_stat = 0;
- scsiq->r3.done_stat = 0;
- scsiq->r2.vm_id = 0;
- scsiq->r1.data_cnt = buf_len;
-
- scsiq->r2.tag_code = (uchar) M2_QTAG_MSG_SIMPLE;
- scsiq->r2.flag = (uchar) ASC_FLAG_SCSIQ_REQ;
- scsiq->r2.srb_ptr = (ulong) scsiq;
- scsiq->r1.status = (uchar) QS_READY;
- scsiq->r1.data_addr = 0L;
-
- if (buf_len != 0L) {
- if ((phy_addr = AscGetOnePhyAddr(asc_dvc,
- (uchar dosfar *) buf_addr, scsiq->r1.data_cnt)) == 0L) {
- return (ERR);
- }
- scsiq->r1.data_addr = phy_addr;
- }
- return (0);
-}
-
-uchar _mcode_buf[] =
-{
- 0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xDD, 0x0A, 0x01, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x23, 0x00, 0x16, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
- 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA4, 0x88, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0x73, 0x48, 0x04, 0x36, 0x00, 0x00, 0xA2, 0xC8, 0x00, 0x80, 0x73, 0x03, 0x23, 0x36, 0x40,
- 0xB6, 0x00, 0x36, 0x00, 0x06, 0xD6, 0x0D, 0xD2, 0x15, 0xDE, 0x12, 0xDA, 0x00, 0xA2, 0xC8, 0x00,
- 0x92, 0x80, 0xE0, 0x97, 0x50, 0x00, 0xF5, 0x00, 0x0A, 0x98, 0xDF, 0x23, 0x36, 0x60, 0xB6, 0x00,
- 0x92, 0x80, 0x4F, 0x00, 0xF5, 0x00, 0x0A, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80,
- 0x80, 0x62, 0x92, 0x80, 0x00, 0x62, 0x92, 0x80, 0x00, 0x46, 0x17, 0xEE, 0x13, 0xEA, 0x02, 0x01,
- 0x09, 0xD8, 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xDC, 0x00, 0x68, 0x97, 0x7F, 0x23, 0x04, 0x61,
- 0x84, 0x01, 0xB2, 0x84, 0xCF, 0xC1, 0x80, 0x73, 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xE8, 0x01,
- 0x68, 0x97, 0xD4, 0x81, 0x00, 0x33, 0x02, 0x00, 0x82, 0x88, 0x80, 0x73, 0x80, 0x77, 0x00, 0x01,
- 0x01, 0xA1, 0x08, 0x01, 0x4F, 0x00, 0x46, 0x97, 0x07, 0xA6, 0x12, 0x01, 0x00, 0x33, 0x03, 0x00,
- 0x82, 0x88, 0x03, 0x03, 0x03, 0xDE, 0x00, 0x33, 0x05, 0x00, 0x82, 0x88, 0xCE, 0x00, 0x69, 0x60,
- 0xCE, 0x00, 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x86, 0x01, 0x80, 0x63, 0x07, 0xA6, 0x32, 0x01,
- 0x86, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6, 0x42, 0x01, 0x00, 0x33, 0x04, 0x00,
- 0x82, 0x88, 0x03, 0x07, 0x02, 0x01, 0x04, 0xCA, 0x0D, 0x23, 0x2A, 0x98, 0x4D, 0x04, 0xD0, 0x84,
- 0x05, 0xD8, 0x0D, 0x23, 0x2A, 0x98, 0xCD, 0x04, 0x15, 0x23, 0xB8, 0x88, 0xFB, 0x23, 0x02, 0x61,
- 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x70, 0x01, 0x00, 0x33, 0x0A, 0x00, 0x82, 0x88,
- 0x4E, 0x00, 0x07, 0xA3, 0x7C, 0x01, 0x00, 0x33, 0x0B, 0x00, 0x82, 0x88, 0xCD, 0x04, 0x36, 0x2D,
- 0x00, 0x33, 0x1A, 0x00, 0x82, 0x88, 0x50, 0x04, 0x96, 0x81, 0x06, 0xAB, 0x90, 0x01, 0x96, 0x81,
- 0x4E, 0x00, 0x07, 0xA3, 0xA0, 0x01, 0x50, 0x00, 0x00, 0xA3, 0x4A, 0x01, 0x00, 0x05, 0x8A, 0x81,
- 0x08, 0x97, 0x02, 0x01, 0x05, 0xC6, 0x04, 0x23, 0xA0, 0x01, 0x15, 0x23, 0xA1, 0x01, 0xCC, 0x81,
- 0xFD, 0x23, 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0, 0xC2, 0x01,
- 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00, 0x82, 0x88, 0x06, 0x23, 0x2A, 0x98,
- 0xCD, 0x04, 0xB2, 0x84, 0x06, 0x01, 0x00, 0xA2, 0xE2, 0x01, 0x57, 0x60, 0x00, 0xA0, 0xE8, 0x01,
- 0xB2, 0x84, 0x80, 0x23, 0xA0, 0x01, 0xB2, 0x84, 0x80, 0x73, 0x4B, 0x00, 0x06, 0x61, 0x00, 0xA2,
- 0x10, 0x02, 0x04, 0x01, 0x0D, 0xDE, 0x02, 0x01, 0x03, 0xCC, 0x4F, 0x00, 0x46, 0x97, 0x0A, 0x82,
- 0x08, 0x23, 0x02, 0x41, 0x82, 0x01, 0x4F, 0x00, 0x24, 0x97, 0x48, 0x04, 0xFF, 0x23, 0x84, 0x80,
- 0xB2, 0x97, 0x00, 0x46, 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00, 0x81, 0x73, 0x06, 0x29,
- 0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x66, 0xEB, 0x11, 0x23, 0xB8, 0x88, 0xC6, 0x97, 0xFA, 0x80,
- 0x80, 0x73, 0x80, 0x77, 0x06, 0xA6, 0x3E, 0x02, 0x00, 0x33, 0x31, 0x00, 0x82, 0x88, 0x04, 0x01,
- 0x03, 0xD8, 0x74, 0x98, 0x02, 0x96, 0x50, 0x82, 0xA2, 0x95, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63,
- 0xB6, 0x2D, 0x02, 0xA6, 0x7A, 0x02, 0x07, 0xA6, 0x68, 0x02, 0x06, 0xA6, 0x6C, 0x02, 0x03, 0xA6,
- 0x70, 0x02, 0x00, 0x33, 0x10, 0x00, 0x82, 0x88, 0x4A, 0x95, 0x52, 0x82, 0xF8, 0x95, 0x52, 0x82,
- 0x04, 0x23, 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x16, 0x84, 0x04, 0x01, 0x0C, 0xDC, 0xE0, 0x23,
- 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01, 0x6F, 0x00, 0xA5, 0x01, 0x03, 0x23,
- 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01, 0x24, 0x2B, 0x1C, 0x01, 0x02, 0xA6, 0xAC, 0x02, 0x07, 0xA6,
- 0x68, 0x02, 0x06, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x12, 0x00, 0x82, 0x88, 0x00, 0x0E, 0x80, 0x63,
- 0x00, 0x43, 0x00, 0xA0, 0x9A, 0x02, 0x4D, 0x04, 0x04, 0x01, 0x0B, 0xDC, 0xE7, 0x23, 0x04, 0x61,
- 0x84, 0x01, 0x10, 0x31, 0x12, 0x35, 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00,
- 0xEC, 0x82, 0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE4, 0x02, 0x04, 0x01, 0x8E, 0xC8, 0x00, 0x33,
- 0x1F, 0x00, 0x82, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39, 0x0E, 0x3D, 0x40, 0x98, 0xB6, 0x2D,
- 0x01, 0xA6, 0x0E, 0x03, 0x00, 0xA6, 0x1C, 0x03, 0x07, 0xA6, 0x2A, 0x03, 0x06, 0xA6, 0x2E, 0x03,
- 0x03, 0xA6, 0xFA, 0x03, 0x02, 0xA6, 0x7A, 0x02, 0x00, 0x33, 0x33, 0x00, 0x82, 0x88, 0x08, 0x23,
- 0xB3, 0x01, 0x04, 0x01, 0x0E, 0xD0, 0x00, 0x33, 0x14, 0x00, 0x82, 0x88, 0x10, 0x23, 0xB3, 0x01,
- 0x04, 0x01, 0x07, 0xCC, 0x00, 0x33, 0x15, 0x00, 0x82, 0x88, 0x4A, 0x95, 0xF0, 0x82, 0xF8, 0x95,
- 0xF0, 0x82, 0x44, 0x98, 0x80, 0x42, 0x40, 0x98, 0x48, 0xE4, 0x04, 0x01, 0x29, 0xC8, 0x31, 0x05,
- 0x07, 0x01, 0x00, 0xA2, 0x72, 0x03, 0x00, 0x43, 0x87, 0x01, 0x05, 0x05, 0x48, 0x98, 0x40, 0x98,
- 0x00, 0xA6, 0x34, 0x03, 0x07, 0xA6, 0x6A, 0x03, 0x03, 0xA6, 0x16, 0x04, 0x06, 0xA6, 0x6E, 0x03,
- 0x01, 0xA6, 0x34, 0x03, 0x00, 0x33, 0x25, 0x00, 0x82, 0x88, 0x4A, 0x95, 0x50, 0x83, 0xF8, 0x95,
- 0x50, 0x83, 0x04, 0x01, 0x0C, 0xCE, 0x03, 0xC8, 0x00, 0x33, 0x42, 0x00, 0x82, 0x88, 0x00, 0x01,
- 0x05, 0x05, 0xFF, 0xA2, 0x90, 0x03, 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x4C, 0x83, 0x05, 0x05,
- 0x01, 0xA6, 0x9A, 0x03, 0x00, 0xA6, 0xAA, 0x03, 0xF0, 0x83, 0x68, 0x98, 0x80, 0x42, 0x01, 0xA6,
- 0x9A, 0x03, 0xBA, 0x83, 0x00, 0x33, 0x2F, 0x00, 0x82, 0x88, 0x68, 0x98, 0x80, 0x42, 0x00, 0xA6,
- 0xAA, 0x03, 0xBA, 0x83, 0x00, 0x33, 0x26, 0x00, 0x82, 0x88, 0x38, 0x2B, 0x80, 0x32, 0x80, 0x36,
- 0x04, 0x23, 0xA0, 0x01, 0x12, 0x23, 0xA1, 0x01, 0xF0, 0x83, 0x04, 0xF0, 0x80, 0x6B, 0x00, 0x33,
- 0x20, 0x00, 0x82, 0x88, 0x03, 0xA6, 0xEE, 0x03, 0x07, 0xA6, 0xE6, 0x03, 0x06, 0xA6, 0xEA, 0x03,
- 0x00, 0x33, 0x17, 0x00, 0x82, 0x88, 0x4A, 0x95, 0xD4, 0x83, 0xF8, 0x95, 0xD4, 0x83, 0xFA, 0x83,
- 0x04, 0xF0, 0x80, 0x6B, 0x00, 0x33, 0x20, 0x00, 0x82, 0x88, 0xB6, 0x2D, 0x03, 0xA6, 0x16, 0x04,
- 0x07, 0xA6, 0x0E, 0x04, 0x06, 0xA6, 0x12, 0x04, 0x00, 0x33, 0x30, 0x00, 0x82, 0x88, 0x4A, 0x95,
- 0xFA, 0x83, 0xF8, 0x95, 0xFA, 0x83, 0xA2, 0x0D, 0x80, 0x63, 0x07, 0xA6, 0x24, 0x04, 0x00, 0x33,
- 0x18, 0x00, 0x82, 0x88, 0x03, 0x03, 0x80, 0x63, 0xA3, 0x01, 0x07, 0xA4, 0x2E, 0x04, 0x23, 0x01,
- 0x00, 0xA2, 0x50, 0x04, 0x0A, 0xA0, 0x40, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1D, 0x00, 0x82, 0x88,
- 0x0B, 0xA0, 0x4C, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1E, 0x00, 0x82, 0x88, 0x42, 0x23, 0xB8, 0x88,
- 0x00, 0x23, 0x22, 0xA3, 0xB2, 0x04, 0x08, 0x23, 0x22, 0xA3, 0x6C, 0x04, 0x28, 0x23, 0x22, 0xA3,
- 0x78, 0x04, 0x02, 0x23, 0x22, 0xA3, 0x8E, 0x04, 0x42, 0x23, 0xB8, 0x88, 0x4A, 0x00, 0x06, 0x61,
- 0x00, 0xA0, 0x78, 0x04, 0x45, 0x23, 0xB8, 0x88, 0xC6, 0x97, 0x00, 0xA2, 0x8A, 0x04, 0x74, 0x98,
- 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20, 0x81, 0x62, 0xF6, 0x81, 0x47, 0x23, 0xB8, 0x88, 0x04, 0x01,
- 0x0C, 0xDE, 0x14, 0x01, 0x00, 0xA2, 0xA6, 0x04, 0xC6, 0x97, 0x74, 0x98, 0x00, 0x33, 0x00, 0x81,
- 0xC0, 0x20, 0x81, 0x62, 0x10, 0x82, 0x43, 0x23, 0xB8, 0x88, 0x04, 0x23, 0xA0, 0x01, 0x44, 0x23,
- 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3, 0xC0, 0x04, 0x00, 0x33, 0x27, 0x00, 0x82, 0x88,
- 0x04, 0x01, 0x04, 0xDC, 0x02, 0x23, 0xA2, 0x01, 0x04, 0x23, 0xA0, 0x01, 0xC6, 0x97, 0xF4, 0x94,
- 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00, 0x00, 0xA3, 0xEE, 0x04, 0x00, 0x05, 0x76, 0x00,
- 0x06, 0x61, 0x00, 0xA2, 0xE8, 0x04, 0xD6, 0x84, 0x08, 0x97, 0xCD, 0x04, 0xF2, 0x84, 0x48, 0x04,
- 0xFF, 0x23, 0x84, 0x80, 0x02, 0x01, 0x03, 0xDA, 0x80, 0x23, 0x82, 0x01, 0x02, 0x85, 0x02, 0x23,
- 0xA0, 0x01, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x0E, 0x05, 0x1D, 0x01, 0x04, 0xD6, 0xFF, 0x23,
- 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01, 0x49, 0x00, 0x81, 0x01, 0x04, 0x01,
- 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01, 0xF7, 0x04, 0x03, 0x01, 0x49, 0x04, 0x80, 0x01, 0xC9, 0x00,
- 0x00, 0x05, 0x00, 0x01, 0xFF, 0xA0, 0x2E, 0x05, 0x77, 0x04, 0x01, 0x23, 0xEA, 0x00, 0x5D, 0x00,
- 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63, 0x07, 0xA4, 0xA0, 0x05, 0x03, 0x03,
- 0x02, 0xA0, 0x5C, 0x05, 0x9C, 0x85, 0x00, 0x33, 0x2D, 0x00, 0x82, 0x88, 0x04, 0xA0, 0x82, 0x05,
- 0x80, 0x63, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x6E, 0x05, 0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23,
- 0x02, 0x41, 0x82, 0x01, 0x50, 0x00, 0x24, 0x97, 0xD0, 0x84, 0x04, 0x23, 0x02, 0x41, 0x82, 0x01,
- 0xD0, 0x84, 0x08, 0xA0, 0x88, 0x05, 0x9C, 0x85, 0x03, 0xA0, 0x8E, 0x05, 0x9C, 0x85, 0x01, 0xA0,
- 0x9A, 0x05, 0x88, 0x00, 0x80, 0x63, 0x78, 0x96, 0x4A, 0x85, 0x88, 0x86, 0x80, 0x63, 0x4A, 0x85,
- 0x00, 0x63, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0xDE, 0x05, 0x1D, 0x01, 0x18, 0xD4, 0xC0, 0x23,
- 0x07, 0x41, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0xC0, 0x05, 0x00, 0x33, 0x37, 0x00, 0x82, 0x88,
- 0x1D, 0x01, 0x02, 0xD6, 0x46, 0x23, 0xB8, 0x88, 0x63, 0x60, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6,
- 0xD8, 0x05, 0x00, 0x33, 0x38, 0x00, 0x82, 0x88, 0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00,
- 0x06, 0x41, 0xCB, 0x00, 0x52, 0x00, 0x06, 0x61, 0x00, 0xA2, 0xF2, 0x05, 0xC0, 0x23, 0x07, 0x41,
- 0x00, 0x63, 0x80, 0x23, 0x07, 0x41, 0x00, 0x63, 0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63,
- 0x00, 0x63, 0x06, 0xA6, 0x14, 0x06, 0x07, 0xA6, 0x64, 0x06, 0x02, 0xA6, 0xBC, 0x06, 0x00, 0x33,
- 0x39, 0x00, 0x82, 0x88, 0x00, 0x00, 0x01, 0xA0, 0xD6, 0x06, 0xA2, 0x95, 0x83, 0x03, 0x80, 0x63,
- 0x06, 0xA6, 0x28, 0x06, 0x07, 0xA6, 0x64, 0x06, 0x00, 0x00, 0x00, 0x2B, 0x40, 0x0E, 0x80, 0x63,
- 0x01, 0x00, 0x06, 0xA6, 0x40, 0x06, 0x07, 0xA6, 0x64, 0x06, 0x00, 0x33, 0x3A, 0x00, 0x82, 0x88,
- 0x40, 0x0E, 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0x32, 0x06, 0x06, 0xA6, 0x58, 0x06, 0x07, 0xA6,
- 0x64, 0x06, 0x00, 0x33, 0x3B, 0x00, 0x82, 0x88, 0x80, 0x67, 0x40, 0x0E, 0x80, 0x63, 0x07, 0xA6,
- 0x64, 0x06, 0x00, 0x63, 0x03, 0x03, 0x80, 0x63, 0x88, 0x00, 0x01, 0xA2, 0x78, 0x06, 0x07, 0xA2,
- 0xBC, 0x06, 0x00, 0x33, 0x35, 0x00, 0x82, 0x88, 0x07, 0xA6, 0x82, 0x06, 0x00, 0x33, 0x2A, 0x00,
- 0x82, 0x88, 0x03, 0x03, 0x03, 0xA2, 0x8E, 0x06, 0x07, 0x23, 0x80, 0x00, 0xC8, 0x86, 0x80, 0x63,
- 0x89, 0x00, 0x0A, 0x2B, 0x07, 0xA6, 0x9E, 0x06, 0x00, 0x33, 0x29, 0x00, 0x82, 0x88, 0x00, 0x43,
- 0x00, 0xA2, 0xAA, 0x06, 0xC0, 0x0E, 0x80, 0x63, 0x94, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80,
- 0xC0, 0x20, 0x81, 0x62, 0x04, 0x01, 0x08, 0xDA, 0x80, 0x63, 0x00, 0x63, 0x80, 0x67, 0x00, 0x33,
- 0x00, 0x40, 0xC0, 0x20, 0x81, 0x62, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x20, 0x06,
- 0x00, 0x33, 0x2C, 0x00, 0x82, 0x88, 0x0C, 0xA2, 0xF0, 0x06, 0xA2, 0x95, 0x83, 0x03, 0x80, 0x63,
- 0x06, 0xA6, 0xEE, 0x06, 0x07, 0xA6, 0x64, 0x06, 0x00, 0x33, 0x3D, 0x00, 0x82, 0x88, 0x00, 0x00,
- 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x06, 0x07, 0x07, 0xA6, 0x64, 0x06, 0xBF, 0x23,
- 0x04, 0x61, 0x84, 0x01, 0xB2, 0x84, 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x00, 0x01,
- 0xF2, 0x00, 0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04, 0x80, 0x05,
- 0x81, 0x05, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x70, 0x00,
- 0x81, 0x01, 0x70, 0x04, 0x71, 0x00, 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04, 0x70, 0x00,
- 0x80, 0x01, 0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01, 0xF1, 0x00,
- 0x70, 0x00, 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01, 0x72, 0x00, 0x81, 0x01, 0x71, 0x04,
- 0x70, 0x00, 0x81, 0x01, 0x70, 0x04, 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05, 0xA3, 0x01,
- 0xA2, 0x01, 0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1, 0x86, 0x07,
- 0x00, 0x33, 0x07, 0x00, 0x82, 0x88, 0x80, 0x05, 0x81, 0x05, 0x04, 0x01, 0x11, 0xC8, 0x48, 0x00,
- 0xB0, 0x01, 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43, 0x00, 0xA2,
- 0xA6, 0x07, 0x00, 0x05, 0x9C, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01, 0x05, 0x05,
- 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x80, 0x43, 0x76, 0x08,
- 0x80, 0x02, 0x77, 0x04, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02,
- 0x00, 0xA0, 0xD6, 0x07, 0xD8, 0x87, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04, 0x00, 0x63,
- 0xF3, 0x04, 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43, 0xF4, 0x00, 0xCF, 0x40, 0x00, 0xA2,
- 0x06, 0x08, 0x74, 0x04, 0x02, 0x01, 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1, 0xE6, 0x07,
- 0xC6, 0x97, 0xF4, 0x94, 0xE6, 0x87, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04, 0x1C, 0x88,
- 0x02, 0x01, 0x04, 0xD8, 0x08, 0x97, 0xC6, 0x97, 0xF4, 0x94, 0x0C, 0x88, 0x75, 0x00, 0x00, 0xA3,
- 0x26, 0x08, 0x00, 0x05, 0x10, 0x88, 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6,
- 0x38, 0x08, 0x00, 0x33, 0x3E, 0x00, 0x82, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63,
- 0x38, 0x2B, 0x5E, 0x88, 0x38, 0x2B, 0x54, 0x88, 0x32, 0x09, 0x31, 0x05, 0x54, 0x98, 0x05, 0x05,
- 0xB2, 0x09, 0x00, 0x63, 0x00, 0x32, 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63, 0x80, 0x32,
- 0x80, 0x36, 0x80, 0x3A, 0x80, 0x3E, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32, 0x40, 0x36, 0x40, 0x3A,
- 0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40, 0x00, 0xA0, 0x74, 0x08, 0x5D, 0x00, 0xFE, 0xC3,
- 0x00, 0x63, 0x80, 0x73, 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73, 0xFF, 0xFD, 0x80, 0x73,
- 0x13, 0x23, 0xB8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01, 0xA1, 0x23, 0xA1, 0x01,
- 0x81, 0x62, 0xA2, 0x88, 0x80, 0x73, 0x80, 0x77, 0x68, 0x00, 0x00, 0xA2, 0x80, 0x00, 0x03, 0xC2,
- 0xF1, 0xC7, 0x41, 0x23, 0xB8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23, 0xA0, 0x01, 0xB2, 0x84,
-
-};
-
-ushort _mcode_size = sizeof (_mcode_buf);
-ulong _mcode_chksum = 0x012258FBUL;
-
-extern uchar _sdtr_period_tbl_[];
-
-int
-AscExeScsiQueue(
- ASC_DVC_VAR asc_ptr_type * asc_dvc,
- ASC_SCSI_Q dosfar * scsiq
-)
-{
- PortAddr iop_base;
- int last_int_level;
- int sta;
- ulong addr;
- uchar sg_entry_cnt;
- uchar target_ix;
- int n_q_required;
- uchar sg_entry_cnt_minus_one;
- uchar tid_no;
- uchar sdtr_data;
- ASC_EXE_CALLBACK asc_exe_callback;
-
-#if CC_DEBUG_SG_LIST
- int i;
-
-#endif
-#if CC_LINK_BUSY_Q
- ASC_SCSI_Q dosfar *scsiq_tail;
- ASC_SCSI_Q dosfar *scsiq_next;
- ASC_SCSI_Q dosfar *scsiq_prev;
-
-#endif
-
- iop_base = asc_dvc->iop_base;
- asc_exe_callback = (ASC_EXE_CALLBACK) asc_dvc->exe_callback;
- if (asc_dvc->err_code != 0)
- return (ERR);
- if (scsiq == (ASC_SCSI_Q dosfar *) 0L) {
- AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SCSIQ_NULL_PTR);
- return (ERR);
- }
- scsiq->q1.q_no = 0;
- sta = 0;
- target_ix = scsiq->q2.target_ix;
- tid_no = ASC_TIX_TO_TID(target_ix);
-
- n_q_required = 1;
-
- if (scsiq->cdbptr[0] == SCSICMD_RequestSense) {
-
- if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
- ((asc_dvc->sdtr_done & scsiq->q1.target_id) != 0)) {
- sdtr_data = AscReadLramByte(iop_base,
- (ushort) ((ushort) ASCV_SDTR_DATA_BEG + (ushort) tid_no));
- AscMsgOutSDTR(iop_base,
- _sdtr_period_tbl_[(sdtr_data >> 4) & (uchar) (ASC_SYN_XFER_NO - 1)],
- (uchar) (sdtr_data & (uchar) ASC_SYN_MAX_OFFSET));
- scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT);
- }
- }
- last_int_level = DvcEnterCritical();
- if (asc_dvc->in_critical_cnt != 0) {
- DvcLeaveCritical(last_int_level);
- AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY);
- return (ERR);
- }
- asc_dvc->in_critical_cnt++;
-
- if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) {
-
- if ((sg_entry_cnt = scsiq->sg_head->entry_cnt) == 0) {
- asc_dvc->in_critical_cnt--;
- DvcLeaveCritical(last_int_level);
- return (ERR);
- }
- if (sg_entry_cnt == 1) {
- scsiq->q1.data_addr = scsiq->sg_head->sg_list[0].addr;
- scsiq->q1.data_cnt = scsiq->sg_head->sg_list[0].bytes;
- scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE);
- goto NON_SG_LIST_REQ;
- }
- if (sg_entry_cnt > ASC_MAX_SG_LIST) {
-
- return (ERR);
- }
- sg_entry_cnt_minus_one = sg_entry_cnt - 1;
-
-#if CC_DEBUG_SG_LIST
- if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) {
- for (i = 0; i < sg_entry_cnt_minus_one; i++) {
-
- addr = scsiq->sg_head->sg_list[i].addr +
- scsiq->sg_head->sg_list[i].bytes;
-
- if (((ushort) addr & 0x0003) != 0) {
- asc_dvc->in_critical_cnt--;
- DvcLeaveCritical(last_int_level);
- AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SG_LIST_ODD_ADDRESS);
- return (ERR);
- }
- }
- }
-#endif
-
- if (asc_dvc->bug_fix_cntl) {
- if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ADD_ONE_BYTE) {
-
- addr = scsiq->sg_head->sg_list[sg_entry_cnt_minus_one].addr +
- scsiq->sg_head->sg_list[sg_entry_cnt_minus_one].bytes;
- if (((ushort) addr & 0x0003) != 0) {
- if ((scsiq->cdbptr[0] == SCSICMD_Read6) ||
- (scsiq->cdbptr[0] == SCSICMD_Read10)) {
- if ((scsiq->q2.tag_code & ASC_TAG_FLAG_ADD_ONE_BYTE) == 0) {
-
- scsiq->sg_head->sg_list[sg_entry_cnt_minus_one].bytes++;
- scsiq->q2.tag_code |= ASC_TAG_FLAG_ADD_ONE_BYTE;
- }
- }
- }
- }
- }
- scsiq->sg_head->entry_to_copy = scsiq->sg_head->entry_cnt;
- n_q_required = AscSgListToQueue(sg_entry_cnt);
-
-#if CC_LINK_BUSY_Q
- scsiq_next = (ASC_SCSI_Q dosfar *) asc_dvc->scsiq_busy_head[tid_no];
- if (scsiq_next != (ASC_SCSI_Q dosfar *) 0L) {
- goto link_scisq_to_busy_list;
- }
-#endif
-
- if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required)
- >= (uint) n_q_required) ||
- ((scsiq->q1.cntl & QC_URGENT) != 0)) {
- if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
- n_q_required)) == 1) {
-
- asc_dvc->in_critical_cnt--;
- if (asc_exe_callback != 0) {
- (*asc_exe_callback) (asc_dvc, scsiq);
- }
- DvcLeaveCritical(last_int_level);
- return (sta);
- }
- }
- } else {
-
- NON_SG_LIST_REQ:
-
- if (asc_dvc->bug_fix_cntl) {
- if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ADD_ONE_BYTE) {
-
- addr = scsiq->q1.data_addr + scsiq->q1.data_cnt;
- if ((scsiq->cdbptr[0] == SCSICMD_Read6) ||
- (scsiq->cdbptr[0] == SCSICMD_Read10)) {
- if (((ushort) addr & 0x0003) != 0) {
- if (((ushort) scsiq->q1.data_cnt & 0x01FF) == 0) {
-
- if ((scsiq->q2.tag_code & ASC_TAG_FLAG_ADD_ONE_BYTE) == 0) {
-
- scsiq->q2.tag_code |= ASC_TAG_FLAG_ADD_ONE_BYTE;
- scsiq->q1.data_cnt++;
- }
- }
- }
- }
- }
- }
- n_q_required = 1;
-
-#if CC_LINK_BUSY_Q
- scsiq_next = (ASC_SCSI_Q dosfar *) asc_dvc->scsiq_busy_head[tid_no];
- if (scsiq_next != (ASC_SCSI_Q dosfar *) 0L) {
- goto link_scisq_to_busy_list;
- }
-#endif
- if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) ||
- ((scsiq->q1.cntl & QC_URGENT) != 0)) {
- if ((sta = AscSendScsiQueue(asc_dvc, scsiq,
- n_q_required)) == 1) {
-
- asc_dvc->in_critical_cnt--;
- if (asc_exe_callback != 0) {
- (*asc_exe_callback) (asc_dvc, scsiq);
- }
- DvcLeaveCritical(last_int_level);
- return (sta);
- }
- }
- }
-
-#if CC_LINK_BUSY_Q
- if (sta == 0) {
-
- link_scisq_to_busy_list:
- scsiq->ext.q_required = n_q_required;
- if (scsiq_next == (ASC_SCSI_Q dosfar *) 0L) {
- asc_dvc->scsiq_busy_head[tid_no] = (ASC_SCSI_Q dosfar *) scsiq;
- asc_dvc->scsiq_busy_tail[tid_no] = (ASC_SCSI_Q dosfar *) scsiq;
- scsiq->ext.next = (ASC_SCSI_Q dosfar *) 0L;
- scsiq->ext.join = (ASC_SCSI_Q dosfar *) 0L;
- scsiq->q1.status = QS_BUSY;
- sta = 1;
- } else {
- scsiq_tail = (ASC_SCSI_Q dosfar *) asc_dvc->scsiq_busy_tail[tid_no];
- if (scsiq_tail->ext.next == (ASC_SCSI_Q dosfar *) 0L) {
- if ((scsiq->q1.cntl & QC_URGENT) != 0) {
-
- asc_dvc->scsiq_busy_head[tid_no] = (ASC_SCSI_Q dosfar *) scsiq;
- scsiq->ext.next = scsiq_next;
- scsiq->ext.join = (ASC_SCSI_Q dosfar *) 0L;
- } else {
- if (scsiq->ext.cntl & QCX_SORT) {
- do {
- scsiq_prev = scsiq_next;
- scsiq_next = scsiq_next->ext.next;
- if (scsiq->ext.lba < scsiq_prev->ext.lba)
- break;
- } while (scsiq_next != (ASC_SCSI_Q dosfar *) 0L);
-
- scsiq_prev->ext.next = scsiq;
- scsiq->ext.next = scsiq_next;
- if (scsiq_next == (ASC_SCSI_Q dosfar *) 0L) {
- asc_dvc->scsiq_busy_tail[tid_no] = (ASC_SCSI_Q dosfar *) scsiq;
- }
- scsiq->ext.join = (ASC_SCSI_Q dosfar *) 0L;
- } else {
-
- scsiq_tail->ext.next = (ASC_SCSI_Q dosfar *) scsiq;
- asc_dvc->scsiq_busy_tail[tid_no] = (ASC_SCSI_Q dosfar *) scsiq;
- scsiq->ext.next = (ASC_SCSI_Q dosfar *) 0L;
- scsiq->ext.join = (ASC_SCSI_Q dosfar *) 0L;
- }
- }
- scsiq->q1.status = QS_BUSY;
- sta = 1;
- } else {
-
- AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SCSIQ_BAD_NEXT_PTR);
- sta = ERR;
- }
- }
- }
-#endif
- asc_dvc->in_critical_cnt--;
- DvcLeaveCritical(last_int_level);
- return (sta);
-}
-
-int
-AscSendScsiQueue(
- ASC_DVC_VAR asc_ptr_type * asc_dvc,
- ASC_SCSI_Q dosfar * scsiq,
- uchar n_q_required
-)
-{
- PortAddr iop_base;
- uchar free_q_head;
- uchar next_qp;
- uchar tid_no;
- uchar target_ix;
- int sta;
-
- iop_base = asc_dvc->iop_base;
- target_ix = scsiq->q2.target_ix;
- tid_no = ASC_TIX_TO_TID(target_ix);
- sta = 0;
- free_q_head = (uchar) AscGetVarFreeQHead(iop_base);
- if (n_q_required > 1) {
- if ((next_qp = AscAllocMultipleFreeQueue(iop_base,
- free_q_head, (uchar) (n_q_required)))
- != (uchar) ASC_QLINK_END) {
- asc_dvc->last_q_shortage = 0;
- scsiq->sg_head->queue_cnt = n_q_required - 1;
- scsiq->q1.q_no = free_q_head;
-
- if ((sta = AscPutReadySgListQueue(asc_dvc, scsiq,
- free_q_head)) == 1) {
-
-#if CC_WRITE_IO_COUNT
- asc_dvc->req_count++;
-#endif
-
- AscPutVarFreeQHead(iop_base, next_qp);
- asc_dvc->cur_total_qng += (uchar) (n_q_required);
- asc_dvc->cur_dvc_qng[tid_no]++;
- }
- return (sta);
- }
- } else if (n_q_required == 1) {
-
- if ((next_qp = AscAllocFreeQueue(iop_base,
- free_q_head)) != ASC_QLINK_END) {
-
- scsiq->q1.q_no = free_q_head;
- if ((sta = AscPutReadyQueue(asc_dvc, scsiq,
- free_q_head)) == 1) {
-
-#if CC_WRITE_IO_COUNT
- asc_dvc->req_count++;
-#endif
-
- AscPutVarFreeQHead(iop_base, next_qp);
- asc_dvc->cur_total_qng++;
- asc_dvc->cur_dvc_qng[tid_no]++;
- }
- return (sta);
- }
- }
- return (sta);
-}
-
-int
-AscSgListToQueue(
- int sg_list
-)
-{
- int n_sg_list_qs;
-
- n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q);
- if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0)
- n_sg_list_qs++;
- return (n_sg_list_qs + 1);
-}
-
-uint
-AscGetNumOfFreeQueue(
- ASC_DVC_VAR asc_ptr_type * asc_dvc,
- uchar target_ix, uchar n_qs
-)
-{
- uint cur_used_qs;
- uint cur_free_qs;
- ASC_SCSI_BIT_ID_TYPE target_id;
- uchar tid_no;
-
- target_id = ASC_TIX_TO_TARGET_ID(target_ix);
- tid_no = ASC_TIX_TO_TID(target_ix);
- if ((asc_dvc->unit_not_ready & target_id) ||
- (asc_dvc->queue_full_or_busy & target_id)) {
- return (0);
- }
- if (n_qs == 1) {
- cur_used_qs = (uint) asc_dvc->cur_total_qng +
- (uint) asc_dvc->last_q_shortage +
- (uint) ASC_MIN_FREE_Q;
- } else {
- cur_used_qs = (uint) asc_dvc->cur_total_qng +
- (uint) ASC_MIN_FREE_Q;
- }
-
- if ((uint) (cur_used_qs + n_qs) <= (uint) asc_dvc->max_total_qng) {
- cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs;
- if (asc_dvc->cur_dvc_qng[tid_no] >=
- asc_dvc->max_dvc_qng[tid_no]) {
- return (0);
- }
- return (cur_free_qs);
- }
- if (n_qs > 1) {
- if (n_qs > asc_dvc->last_q_shortage) {
- asc_dvc->last_q_shortage = n_qs;
- }
- }
- return (0);
-}
-
-int
-AscPutReadyQueue(
- ASC_DVC_VAR asc_ptr_type * asc_dvc,
- ASC_SCSI_Q dosfar * scsiq,
- uchar q_no
-)
-{
- ushort q_addr;
- uchar tid_no;
- uchar sdtr_data;
- uchar syn_period_ix;
- uchar syn_offset;
- PortAddr iop_base;
-
- iop_base = asc_dvc->iop_base;
-
- if (((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) &&
- ((asc_dvc->sdtr_done & scsiq->q1.target_id) == 0)) {
-
- tid_no = ASC_TIX_TO_TID(scsiq->q2.target_ix);
-
- sdtr_data = AscReadLramByte(iop_base,
- (ushort) ((ushort) ASCV_SDTR_DATA_BEG + (ushort) tid_no));
- syn_period_ix = (sdtr_data >> 4) & (ASC_SYN_XFER_NO - 1);
- syn_offset = sdtr_data & ASC_SYN_MAX_OFFSET;
- AscMsgOutSDTR(iop_base,
- _sdtr_period_tbl_[syn_period_ix],
- syn_offset);
-
- scsiq->q1.cntl |= QC_MSG_OUT;
- }
- q_addr = ASC_QNO_TO_QADDR(q_no);
-
- if ((scsiq->q1.target_id & asc_dvc->use_tagged_qng) == 0) {
- scsiq->q2.tag_code &= ~M2_QTAG_MSG_SIMPLE;
- }
- scsiq->q1.status = QS_FREE;
-
- AscMemWordCopyToLram(iop_base,
- (ushort) (q_addr + (ushort) ASC_SCSIQ_CDB_BEG),
- (ushort dosfar *) scsiq->cdbptr,
- (ushort) ((ushort) scsiq->q2.cdb_len >> 1));
-
-#if !CC_LITTLE_ENDIAN_HOST
- AscAdjEndianScsiQ(scsiq);
-#endif
-
- DvcPutScsiQ(iop_base,
- (ushort) (q_addr + (ushort) ASC_SCSIQ_CPY_BEG),
- (ushort dosfar *) & scsiq->q1.cntl,
- (ushort) ((((sizeof (ASC_SCSIQ_1) + sizeof (ASC_SCSIQ_2)) / 2) - 1)));
-
-#if CC_WRITE_IO_COUNT
- AscWriteLramWord(iop_base,
- (ushort) (q_addr + (ushort) ASC_SCSIQ_W_REQ_COUNT),
- (ushort) asc_dvc->req_count);
-
-#endif
-
-#if CC_VERIFY_LRAM_COPY
- if ((asc_dvc->dvc_cntl & ASC_CNTL_NO_VERIFY_COPY) == 0) {
-
- if (AscMemWordCmpToLram(iop_base,
- (ushort) (q_addr + (ushort) ASC_SCSIQ_CDB_BEG),
- (ushort dosfar *) scsiq->cdbptr,
- (ushort) (scsiq->q2.cdb_len >> 1)) != 0) {
- AscSetLibErrorCode(asc_dvc, ASCQ_ERR_LOCAL_MEM);
- return (ERR);
- }
- if (AscMemWordCmpToLram(iop_base,
- (ushort) (q_addr + (ushort) ASC_SCSIQ_CPY_BEG),
- (ushort dosfar *) & scsiq->q1.cntl,
- (ushort) (((sizeof (ASC_SCSIQ_1) + sizeof (ASC_SCSIQ_2)) / 2) - 1))
- != 0) {
- AscSetLibErrorCode(asc_dvc, ASCQ_ERR_LOCAL_MEM);
- return (ERR);
- }
- }
-#endif
-
-#if CC_CLEAR_DMA_REMAIN
-
- AscWriteLramDWord(iop_base,
- (ushort) (q_addr + (ushort) ASC_SCSIQ_DW_REMAIN_XFER_ADDR), 0UL);
- AscWriteLramDWord(iop_base,
- (ushort) (q_addr + (ushort) ASC_SCSIQ_DW_REMAIN_XFER_CNT), 0UL);
-
-#endif
-
- AscWriteLramWord(iop_base,
- (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
- (ushort) (((ushort) scsiq->q1.q_no << 8) | (ushort) QS_READY));
- return (1);
-}
-
-int
-AscPutReadySgListQueue(
- ASC_DVC_VAR asc_ptr_type * asc_dvc,
- ASC_SCSI_Q dosfar * scsiq,
- uchar q_no
-)
-{
- uchar sg_list_dwords;
- uchar sg_index, i;
- uchar sg_entry_cnt;
- uchar next_qp;
- ushort q_addr;
- int sta;
- ASC_SG_HEAD dosfar *sg_head;
- ASC_SG_LIST_Q scsi_sg_q;
- ulong saved_data_addr;
- ulong saved_data_cnt;
- PortAddr iop_base;
-
- iop_base = asc_dvc->iop_base;
-
- sg_head = scsiq->sg_head;
-
- saved_data_addr = scsiq->q1.data_addr;
- saved_data_cnt = scsiq->q1.data_cnt;
- scsiq->q1.data_addr = sg_head->sg_list[0].addr;
- scsiq->q1.data_cnt = sg_head->sg_list[0].bytes;
- sg_entry_cnt = sg_head->entry_cnt - 1;
- if (sg_entry_cnt != 0) {
- scsiq->q1.cntl |= QC_SG_HEAD;
- q_addr = ASC_QNO_TO_QADDR(q_no);
- sg_index = 1;
- scsiq->q1.sg_queue_cnt = sg_head->queue_cnt;
- scsi_sg_q.sg_head_qp = q_no;
- scsi_sg_q.cntl = QCSG_SG_XFER_LIST;
- for (i = 0; i < sg_head->queue_cnt; i++) {
- scsi_sg_q.seq_no = i + 1;
- if (sg_entry_cnt > ASC_SG_LIST_PER_Q) {
- sg_list_dwords = (uchar) (ASC_SG_LIST_PER_Q * 2);
- sg_entry_cnt -= ASC_SG_LIST_PER_Q;
- if (i == 0) {
- scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q;
- scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q;
- } else {
- scsi_sg_q.sg_list_cnt = ASC_SG_LIST_PER_Q - 1;
- scsi_sg_q.sg_cur_list_cnt = ASC_SG_LIST_PER_Q - 1;
- }
- } else {
-
- scsi_sg_q.cntl |= QCSG_SG_XFER_END;
- sg_list_dwords = sg_entry_cnt << 1;
- if (i == 0) {
- scsi_sg_q.sg_list_cnt = sg_entry_cnt;
- scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt;
- } else {
- scsi_sg_q.sg_list_cnt = sg_entry_cnt - 1;
- scsi_sg_q.sg_cur_list_cnt = sg_entry_cnt - 1;
- }
- sg_entry_cnt = 0;
- }
- next_qp = AscReadLramByte(iop_base,
- (ushort) (q_addr + ASC_SCSIQ_B_FWD));
- scsi_sg_q.q_no = next_qp;
- q_addr = ASC_QNO_TO_QADDR(next_qp);
-
- AscMemWordCopyToLram(iop_base,
- (ushort) (q_addr + ASC_SCSIQ_SGHD_CPY_BEG),
- (ushort dosfar *) & scsi_sg_q,
- (ushort) (sizeof (ASC_SG_LIST_Q) >> 1));
-
- AscMemDWordCopyToLram(iop_base,
- (ushort) (q_addr + ASC_SGQ_LIST_BEG),
- (ulong dosfar *) & sg_head->sg_list[sg_index],
- (ushort) sg_list_dwords);
-
- sg_index += ASC_SG_LIST_PER_Q;
- }
- } else {
-
- scsiq->q1.cntl &= ~QC_SG_HEAD;
- }
- sta = AscPutReadyQueue(asc_dvc, scsiq, q_no);
-
- scsiq->q1.data_addr = saved_data_addr;
- scsiq->q1.data_cnt = saved_data_cnt;
- return (sta);
-}
-
-int
-AscAbortSRB(
- ASC_DVC_VAR asc_ptr_type * asc_dvc,
- ulong srb_ptr
-)
-{
- int sta;
- ASC_SCSI_BIT_ID_TYPE saved_unit_not_ready;
- PortAddr iop_base;
-
- iop_base = asc_dvc->iop_base;
- sta = ERR;
- saved_unit_not_ready = asc_dvc->unit_not_ready;
- asc_dvc->unit_not_ready = 0xFF;
- AscWaitISRDone(asc_dvc);
- if (AscStopQueueExe(iop_base) == 1) {
- if (AscRiscHaltedAbortSRB(asc_dvc, srb_ptr) == 1) {
- sta = 1;
- AscCleanUpBusyQueue(iop_base);
- AscStartQueueExe(iop_base);
-
- } else {
- sta = 0;
- AscStartQueueExe(iop_base);
- }
- }
- asc_dvc->unit_not_ready = saved_unit_not_ready;
- return (sta);
-}
-
-int
-AscResetDevice(
- ASC_DVC_VAR asc_ptr_type * asc_dvc,
- uchar target_ix
-)
-{
- PortAddr iop_base;
- int sta;
- uchar tid_no;
- ASC_SCSI_BIT_ID_TYPE target_id;
- int i;
- ASC_SCSI_REQ_Q scsiq_buf;
- ASC_SCSI_REQ_Q dosfar *scsiq;
- uchar dosfar *buf;
- ASC_SCSI_BIT_ID_TYPE saved_unit_not_ready;
-
- iop_base = asc_dvc->iop_base;
- tid_no = ASC_TIX_TO_TID(target_ix);
- target_id = ASC_TID_TO_TARGET_ID(tid_no);
- saved_unit_not_ready = asc_dvc->unit_not_ready;
- asc_dvc->unit_not_ready = target_id;
- sta = ERR;
- AscWaitTixISRDone(asc_dvc, target_ix);
- if (AscStopQueueExe(iop_base) == 1) {
- if (AscRiscHaltedAbortTIX(asc_dvc, target_ix) == 1) {
-
- AscCleanUpBusyQueue(iop_base);
- AscStartQueueExe(iop_base);
-
- AscWaitTixISRDone(asc_dvc, target_ix);
-
- sta = TRUE;
- scsiq = (ASC_SCSI_REQ_Q dosfar *) & scsiq_buf;
- buf = (uchar dosfar *) & scsiq_buf;
- for (i = 0; i < sizeof (ASC_SCSI_REQ_Q); i++) {
- *buf++ = 0x00;
- }
-
- scsiq->r1.status = (uchar) QS_READY;
- scsiq->r2.cdb_len = 6;
- scsiq->r2.tag_code = M2_QTAG_MSG_SIMPLE;
- scsiq->r1.target_id = target_id;
-
- scsiq->r2.target_ix = ASC_TIDLUN_TO_IX(tid_no, 0);
- scsiq->cdbptr = (uchar dosfar *) scsiq->cdb;
-
- scsiq->r1.cntl = QC_NO_CALLBACK | QC_MSG_OUT | QC_URGENT;
- AscWriteLramByte(asc_dvc->iop_base, ASCV_MSGOUT_BEG,
- M1_BUS_DVC_RESET);
-
- asc_dvc->unit_not_ready &= ~target_id;
-
- asc_dvc->sdtr_done |= target_id;
-
- if (AscExeScsiQueue(asc_dvc, (ASC_SCSI_Q dosfar *) scsiq)
- == 1) {
- asc_dvc->unit_not_ready = target_id;
- DvcSleepMilliSecond(1000);
- _AscWaitQDone(iop_base, (ASC_SCSI_Q dosfar *) scsiq);
- if (AscStopQueueExe(iop_base) == 1) {
-
- AscCleanUpDiscQueue(iop_base);
- AscStartQueueExe(iop_base);
- if (asc_dvc->pci_fix_asyn_xfer & target_id) {
-
- AscSetRunChipSynRegAtID(iop_base, tid_no,
- ASYN_SDTR_DATA_FIX_PCI_REV_AB);
- }
- AscWaitTixISRDone(asc_dvc, target_ix);
- }
- } else {
-
- sta = 0;
- }
-
- asc_dvc->sdtr_done &= ~target_id;
- } else {
- sta = ERR;
- AscStartQueueExe(iop_base);
- }
- }
- asc_dvc->unit_not_ready = saved_unit_not_ready;
- return (sta);
-}
-
-int
-AscResetSB(
- ASC_DVC_VAR asc_ptr_type * asc_dvc
-)
-{
- int sta;
- int i;
- PortAddr iop_base;
-
- iop_base = asc_dvc->iop_base;
- asc_dvc->unit_not_ready = 0xFF;
- sta = TRUE;
- AscWaitISRDone(asc_dvc);
- AscStopQueueExe(iop_base);
-
- asc_dvc->sdtr_done = 0;
- AscResetChipAndScsiBus(iop_base);
-
- DvcSleepMilliSecond((ulong) ((ushort) asc_dvc->scsi_reset_wait * 1000));
-
-#if CC_SCAM
- if (!(asc_dvc->dvc_cntl & ASC_CNTL_NO_SCAM)) {
- AscSCAM(asc_dvc);
- }
-#endif
- AscReInitLram(asc_dvc);
-
- for (i = 0; i <= ASC_MAX_TID; i++) {
- asc_dvc->cur_dvc_qng[i] = 0;
- if (asc_dvc->pci_fix_asyn_xfer & (0x01 << i)) {
-
- AscSetChipSynRegAtID(iop_base, i, ASYN_SDTR_DATA_FIX_PCI_REV_AB);
- }
- }
-
- asc_dvc->err_code = 0;
-
- AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
- if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
- sta = ERR;
- }
- if (AscStartChip(iop_base) == 0) {
- sta = ERR;
- }
- AscStartQueueExe(iop_base);
- asc_dvc->unit_not_ready = 0;
- asc_dvc->queue_full_or_busy = 0;
- return (sta);
-}
-
-int
-AscSetRunChipSynRegAtID(
- PortAddr iop_base,
- uchar tid_no,
- uchar sdtr_data
-)
-{
- int sta = FALSE;
-
- if (AscHostReqRiscHalt(iop_base)) {
- sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data);
-
- AscStartChip(iop_base);
- return (sta);
- }
- return (sta);
-}
-
-int
-AscSetChipSynRegAtID(
- PortAddr iop_base,
- uchar id,
- uchar sdtr_data
-)
-{
- AscSetBank(iop_base, 1);
- AscWriteChipScsiID(iop_base, id);
- if (AscReadChipScsiID(iop_base) != (0x01 << id)) {
- return (FALSE);
- }
- AscSetBank(iop_base, 0);
- AscWriteChipSyn(iop_base, sdtr_data);
- if (AscReadChipSyn(iop_base) != sdtr_data) {
- return (FALSE);
- }
- return (TRUE);
-}
-
-int
-AscReInitLram(
- ASC_DVC_VAR asc_ptr_type * asc_dvc
-)
-{
- AscInitLram(asc_dvc);
- AscInitQLinkVar(asc_dvc);
- return (0);
-}
-
-ushort
-AscInitLram(
- ASC_DVC_VAR asc_ptr_type * asc_dvc)
-{
- uchar i;
- ushort s_addr;
- PortAddr iop_base;
- ushort warn_code;
-
- iop_base = asc_dvc->iop_base;
- warn_code = 0;
-
- AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0,
- (ushort) (((int) (asc_dvc->max_total_qng + 2 + 1) * 64) >> 1)
- );
-
- i = ASC_MIN_ACTIVE_QNO;
- s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE;
-
- AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
- (uchar) (i + 1));
- AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
- (uchar) (asc_dvc->max_total_qng));
- AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
- (uchar) i);
- i++;
- s_addr += ASC_QBLK_SIZE;
- for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) {
- AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
- (uchar) (i + 1));
- AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
- (uchar) (i - 1));
- AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
- (uchar) i);
- }
-
- AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_FWD),
- (uchar) ASC_QLINK_END);
- AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_BWD),
- (uchar) (asc_dvc->max_total_qng - 1));
- AscWriteLramByte(iop_base, (ushort) (s_addr + ASC_SCSIQ_B_QNO),
- (uchar) asc_dvc->max_total_qng);
- i++;
- s_addr += ASC_QBLK_SIZE;
-
- for (; i <= (uchar) (asc_dvc->max_total_qng + 3);
- i++, s_addr += ASC_QBLK_SIZE) {
-
- AscWriteLramByte(iop_base,
- (ushort) (s_addr + (ushort) ASC_SCSIQ_B_FWD), i);
- AscWriteLramByte(iop_base,
- (ushort) (s_addr + (ushort) ASC_SCSIQ_B_BWD), i);
- AscWriteLramByte(iop_base,
- (ushort) (s_addr + (ushort) ASC_SCSIQ_B_QNO), i);
- }
-
- return (warn_code);
-}
-
-ushort
-AscInitQLinkVar(
- ASC_DVC_VAR asc_ptr_type * asc_dvc
-)
-{
- PortAddr iop_base;
- int i;
- ushort lram_addr;
-
- iop_base = asc_dvc->iop_base;
- AscPutRiscVarFreeQHead(iop_base, 1);
- AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng);
-
- AscPutVarFreeQHead(iop_base, 1);
- AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng);
-
- AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B,
- (uchar) ((int) asc_dvc->max_total_qng + 1));
- AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B,
- (uchar) ((int) asc_dvc->max_total_qng + 2));
-
- AscWriteLramByte(iop_base, (ushort) ASCV_TOTAL_READY_Q_B,
- asc_dvc->max_total_qng);
-
- AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0);
- AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0);
- AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
- AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0);
- AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0);
-
- AscWriteLramByte(iop_base, (ushort) ASCV_CDBCNT_B, 0);
-
- lram_addr = ASC_QADR_BEG;
- for (i = 0; i < 32; i++, lram_addr += 2) {
- AscWriteLramWord(iop_base, lram_addr, 0);
- }
-
- return (0);
-}
-
-int
-AscSetLibErrorCode(
- ASC_DVC_VAR asc_ptr_type * asc_dvc,
- ushort err_code
-)
-{
- if (asc_dvc->err_code == 0) {
-
- asc_dvc->err_code = err_code;
- AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W,
- err_code);
- }
- return (err_code);
-}
-
-int
-_AscWaitQDone(
- PortAddr iop_base,
- ASC_SCSI_Q dosfar * scsiq
-)
-{
- ushort q_addr;
- uchar q_status;
- int count = 0;
-
- while (scsiq->q1.q_no == 0) ;
- q_addr = ASC_QNO_TO_QADDR(scsiq->q1.q_no);
-
- do {
- q_status = AscReadLramByte(iop_base, q_addr + ASC_SCSIQ_B_STATUS);
- DvcSleepMilliSecond(100L);
- if (count++ > 30) {
- return (0);
- }
- } while ((q_status & QS_READY) != 0);
- return (1);
-}
-
-uchar _sdtr_period_tbl_[ASC_SYN_XFER_NO] =
-{
- SYN_XFER_NS_0,
- SYN_XFER_NS_1,
- SYN_XFER_NS_2,
- SYN_XFER_NS_3,
- SYN_XFER_NS_4,
- SYN_XFER_NS_5,
- SYN_XFER_NS_6,
- SYN_XFER_NS_7};
-
-uchar
-AscMsgOutSDTR(
- PortAddr iop_base,
- uchar sdtr_period,
- uchar sdtr_offset
-)
-{
- SDTR_XMSG sdtr_buf;
- uchar sdtr_period_index;
-
- sdtr_buf.msg_type = MS_EXTEND;
- sdtr_buf.msg_len = MS_SDTR_LEN;
- sdtr_buf.msg_req = MS_SDTR_CODE;
- sdtr_buf.xfer_period = sdtr_period;
- sdtr_offset &= ASC_SYN_MAX_OFFSET;
- sdtr_buf.req_ack_offset = sdtr_offset;
- AscMemWordCopyToLram(iop_base, ASCV_MSGOUT_BEG,
- (ushort dosfar *) & sdtr_buf, SYN_XMSG_WLEN);
- if ((sdtr_period_index = AscGetSynPeriodIndex(sdtr_period)) <=
- ASC_MAX_SDTR_PERIOD_INDEX) {
- return ((sdtr_period_index << 4) | sdtr_offset);
- } else {
-
- return (0);
- }
-}
-
-uchar
-AscCalSDTRData(
- uchar sdtr_period,
- uchar syn_offset
-)
-{
- uchar byte;
- uchar sdtr_period_ix;
-
- sdtr_period_ix = AscGetSynPeriodIndex(sdtr_period);
- if ((sdtr_period_ix > ASC_MAX_SDTR_PERIOD_INDEX) ||
- (sdtr_period_ix > ASC_SDTR_PERIOD_IX_MIN)) {
- return (0xFF);
- }
- byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET);
- return (byte);
-}
-
-void
-AscSetChipSDTR(
- PortAddr iop_base,
- uchar sdtr_data,
- uchar tid_no
-)
-{
-
- AscWriteChipSyn(iop_base, sdtr_data);
- AscWriteLramByte(iop_base,
- (ushort) ((ushort) ASCV_SDTR_DONE_BEG + (ushort) tid_no),
- sdtr_data);
- return;
-}
-
-uchar
-AscGetSynPeriodIndex(
- uchar syn_time
-)
-{
- if ((syn_time >= SYN_XFER_NS_0) && (syn_time <= SYN_XFER_NS_7)) {
- if (syn_time <= SYN_XFER_NS_6) {
- if (syn_time <= SYN_XFER_NS_5) {
- if (syn_time <= SYN_XFER_NS_4) {
- if (syn_time <= SYN_XFER_NS_3) {
- if (syn_time <= SYN_XFER_NS_2) {
- if (syn_time <= SYN_XFER_NS_1) {
- if (syn_time <= SYN_XFER_NS_0) {
- return (0);
- } else
- return (1);
- } else {
- return (2);
- }
- } else {
- return (3);
- }
- } else {
- return (4);
- }
- } else {
- return (5);
- }
- } else {
- return (6);
- }
- } else {
- return (7);
- }
- } else {
-
- return (8);
- }
-}
-
-uchar
-AscAllocFreeQueue(
- PortAddr iop_base,
- uchar free_q_head
-)
-{
- ushort q_addr;
- uchar next_qp;
- uchar q_status;
-
- q_addr = ASC_QNO_TO_QADDR(free_q_head);
- q_status = (uchar) AscReadLramByte(iop_base,
- (ushort) (q_addr + ASC_SCSIQ_B_STATUS));
- next_qp = AscReadLramByte(iop_base,
- (ushort) (q_addr + ASC_SCSIQ_B_FWD));
- if (((q_status & QS_READY) == 0) &&
- (next_qp != ASC_QLINK_END)) {
- return (next_qp);
- }
- return (ASC_QLINK_END);
-}
-
-uchar
-AscAllocMultipleFreeQueue(
- PortAddr iop_base,
- uchar free_q_head,
- uchar n_free_q
-)
-{
- uchar i;
-
- for (i = 0; i < n_free_q; i++) {
- if ((free_q_head = AscAllocFreeQueue(iop_base, free_q_head))
- == ASC_QLINK_END) {
- return (ASC_QLINK_END);
- }
- }
- return (free_q_head);
-}
-
-int
-AscRiscHaltedAbortSRB(
- ASC_DVC_VAR asc_ptr_type * asc_dvc,
- ulong srb_ptr
-)
-{
- PortAddr iop_base;
- ushort q_addr;
- uchar q_no;
- ASC_QDONE_INFO scsiq_buf;
- ASC_QDONE_INFO dosfar *scsiq;
- ASC_ISR_CALLBACK asc_isr_callback;
- int last_int_level;
-
- iop_base = asc_dvc->iop_base;
- asc_isr_callback = (ASC_ISR_CALLBACK) asc_dvc->isr_callback;
- last_int_level = DvcEnterCritical();
- scsiq = (ASC_QDONE_INFO dosfar *) & scsiq_buf;
-
-#if CC_LINK_BUSY_Q
- _AscAbortSrbBusyQueue(asc_dvc, scsiq, srb_ptr);
-#endif
-
- for (q_no = ASC_MIN_ACTIVE_QNO; q_no <= asc_dvc->max_total_qng;
- q_no++) {
- q_addr = ASC_QNO_TO_QADDR(q_no);
- scsiq->d2.srb_ptr = AscReadLramDWord(iop_base,
- (ushort) (q_addr + (ushort) ASC_SCSIQ_D_SRBPTR));
- if (scsiq->d2.srb_ptr == srb_ptr) {
- _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq, asc_dvc->max_dma_count);
- if (((scsiq->q_status & QS_READY) != 0) &&
- ((scsiq->q_status & QS_ABORTED) == 0) &&
- ((scsiq->cntl & QCSG_SG_XFER_LIST) == 0)) {
-
- scsiq->q_status |= QS_ABORTED;
- scsiq->d3.done_stat = QD_ABORTED_BY_HOST;
- AscWriteLramDWord(iop_base,
- (ushort) (q_addr + (ushort) ASC_SCSIQ_D_SRBPTR),
- 0L);
- AscWriteLramByte(iop_base,
- (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
- scsiq->q_status);
- (*asc_isr_callback) (asc_dvc, scsiq);
- return (1);
- }
- }
- }
- DvcLeaveCritical(last_int_level);
- return (0);
-}
-
-int
-AscRiscHaltedAbortTIX(
- ASC_DVC_VAR asc_ptr_type * asc_dvc,
- uchar target_ix
-)
-{
- PortAddr iop_base;
- ushort q_addr;
- uchar q_no;
- ASC_QDONE_INFO scsiq_buf;
- ASC_QDONE_INFO dosfar *scsiq;
- ASC_ISR_CALLBACK asc_isr_callback;
- int last_int_level;
-
-#if CC_LINK_BUSY_Q
- uchar tid_no;
-
-#endif
-
- iop_base = asc_dvc->iop_base;
- asc_isr_callback = (ASC_ISR_CALLBACK) asc_dvc->isr_callback;
- last_int_level = DvcEnterCritical();
- scsiq = (ASC_QDONE_INFO dosfar *) & scsiq_buf;
-
-#if CC_LINK_BUSY_Q
-
- tid_no = ASC_TIX_TO_TID(target_ix);
- _AscAbortTidBusyQueue(asc_dvc, scsiq, tid_no);
-
-#endif
-
- for (q_no = ASC_MIN_ACTIVE_QNO; q_no <= asc_dvc->max_total_qng;
- q_no++) {
- q_addr = ASC_QNO_TO_QADDR(q_no);
- _AscCopyLramScsiDoneQ(iop_base, q_addr, scsiq, asc_dvc->max_dma_count);
- if (((scsiq->q_status & QS_READY) != 0) &&
- ((scsiq->q_status & QS_ABORTED) == 0) &&
- ((scsiq->cntl & QCSG_SG_XFER_LIST) == 0)) {
- if (scsiq->d2.target_ix == target_ix) {
- scsiq->q_status |= QS_ABORTED;
- scsiq->d3.done_stat = QD_ABORTED_BY_HOST;
-
- AscWriteLramDWord(iop_base,
- (ushort) (q_addr + (ushort) ASC_SCSIQ_D_SRBPTR),
- 0L);
-
- AscWriteLramByte(iop_base,
- (ushort) (q_addr + (ushort) ASC_SCSIQ_B_STATUS),
- scsiq->q_status);
- (*asc_isr_callback) (asc_dvc, scsiq);
- }
- }
- }
- DvcLeaveCritical(last_int_level);
- return (1);
-}
-
-#if CC_LINK_BUSY_Q
-
-#endif
-
-int
-AscHostReqRiscHalt(
- PortAddr iop_base
-)
-{
- int count = 0;
- int sta = 0;
- uchar saved_stop_code;
-
- if (AscIsChipHalted(iop_base))
- return (1);
- saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
-
- AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
- ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP
- );
- do {
- if (AscIsChipHalted(iop_base)) {
- sta = 1;
- break;
- }
- DvcSleepMilliSecond(100);
- } while (count++ < 20);
-
- AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code);
- return (sta);
-}
-
-int
-AscStopQueueExe(
- PortAddr iop_base
-)
-{
- int count;
-
- count = 0;
- if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) {
- AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
- ASC_STOP_REQ_RISC_STOP);
- do {
- if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) &
- ASC_STOP_ACK_RISC_STOP) {
- return (1);
- }
- DvcSleepMilliSecond(100);
- } while (count++ < 20);
- }
- return (0);
-}
-
-int
-AscStartQueueExe(
- PortAddr iop_base
-)
-{
- if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) != 0) {
- AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0);
- }
- return (1);
-}
-
-int
-AscCleanUpBusyQueue(
- PortAddr iop_base
-)
-{
- int count;
- uchar stop_code;
-
- count = 0;
- if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) != 0) {
- AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
- ASC_STOP_CLEAN_UP_BUSY_Q);
- do {
- stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
- if ((stop_code & ASC_STOP_CLEAN_UP_BUSY_Q) == 0)
- break;
- DvcSleepMilliSecond(100);
- } while (count++ < 20);
- }
- return (1);
-}
-
-int
-AscCleanUpDiscQueue(
- PortAddr iop_base
-)
-{
- int count;
- uchar stop_code;
-
- count = 0;
- if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) != 0) {
- AscWriteLramByte(iop_base, ASCV_STOP_CODE_B,
- ASC_STOP_CLEAN_UP_DISC_Q);
- do {
- stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B);
- if ((stop_code & ASC_STOP_CLEAN_UP_DISC_Q) == 0)
- break;
- DvcSleepMilliSecond(100);
- } while (count++ < 20);
- }
- return (1);
-}
-
-int
-AscWaitTixISRDone(
- ASC_DVC_VAR asc_ptr_type * asc_dvc,
- uchar target_ix
-)
-{
- uchar cur_req;
- uchar tid_no;
-
- tid_no = ASC_TIX_TO_TID(target_ix);
- while (TRUE) {
- if ((cur_req = asc_dvc->cur_dvc_qng[tid_no]) == 0) {
- break;
- }
- DvcSleepMilliSecond(1000L);
- if (asc_dvc->cur_dvc_qng[tid_no] == cur_req) {
- break;
- }
- }
- return (1);
-}
-
-int
-AscWaitISRDone(
- ASC_DVC_VAR asc_ptr_type * asc_dvc
-)
-{
- int tid;
-
- for (tid = 0; tid <= ASC_MAX_TID; tid++) {
- AscWaitTixISRDone(asc_dvc, ASC_TID_TO_TIX(tid));
- }
- return (1);
-}
-
-ulong
-AscGetOnePhyAddr(
- ASC_DVC_VAR asc_ptr_type * asc_dvc,
- uchar dosfar * buf_addr,
- ulong buf_size
-)
-{
- ASC_MIN_SG_HEAD sg_head;
-
- sg_head.entry_cnt = ASC_MIN_SG_LIST;
- if (DvcGetSGList(asc_dvc, (uchar dosfar *) buf_addr,
- buf_size, (ASC_SG_HEAD dosfar *) & sg_head) != buf_size) {
- return (0L);
- }
- if (sg_head.entry_cnt > 1) {
- return (0L);
- }
- return (sg_head.sg_list[0].addr);
-}
-
-ulong
-AscGetEisaProductID(
- PortAddr iop_base
-)
-{
- PortAddr eisa_iop;
- ushort product_id_high, product_id_low;
- ulong product_id;
-
- eisa_iop = ASC_GET_EISA_SLOT(iop_base) | ASC_EISA_PID_IOP_MASK;
- product_id_low = inpw(eisa_iop);
- product_id_high = inpw(eisa_iop + 2);
- product_id = ((ulong) product_id_high << 16) | (ulong) product_id_low;
- return (product_id);
-}
-
-PortAddr
-AscSearchIOPortAddrEISA(
- PortAddr iop_base
-)
-{
- ulong eisa_product_id;
-
- if (iop_base == 0) {
- iop_base = ASC_EISA_MIN_IOP_ADDR;
- } else {
- if (iop_base == ASC_EISA_MAX_IOP_ADDR)
- return (0);
- if ((iop_base & 0x0050) == 0x0050) {
- iop_base += ASC_EISA_BIG_IOP_GAP;
- } else {
- iop_base += ASC_EISA_SMALL_IOP_GAP;
- }
- }
- while (iop_base <= ASC_EISA_MAX_IOP_ADDR) {
-
- eisa_product_id = AscGetEisaProductID(iop_base);
- if ((eisa_product_id == ASC_EISA_ID_740) ||
- (eisa_product_id == ASC_EISA_ID_750)) {
- if (AscFindSignature(iop_base)) {
-
- inpw(iop_base + 4);
- return (iop_base);
- }
- }
- if (iop_base == ASC_EISA_MAX_IOP_ADDR)
- return (0);
- if ((iop_base & 0x0050) == 0x0050) {
- iop_base += ASC_EISA_BIG_IOP_GAP;
- } else {
- iop_base += ASC_EISA_SMALL_IOP_GAP;
- }
- }
- return (0);
-}
-
-int
-AscStartChip(
- PortAddr iop_base
-)
-{
- AscSetChipControl(iop_base, 0);
- if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
- return (0);
- }
- return (1);
-}
-
-int
-AscStopChip(
- PortAddr iop_base
-)
-{
- uchar cc_val;
-
- cc_val = AscGetChipControl(iop_base) & (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG));
- AscSetChipControl(iop_base, (uchar) (cc_val | CC_HALT));
- AscSetChipIH(iop_base, INS_HALT);
- AscSetChipIH(iop_base, INS_RFLAG_WTM);
- if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) {
- return (0);
- }
- return (1);
-}
-
-int
-AscIsChipHalted(
- PortAddr iop_base
-)
-{
-
- if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) {
- if ((AscGetChipControl(iop_base) & CC_HALT) != 0) {
- return (1);
- }
- }
- return (0);
-}
-
-void
-AscSetChipIH(
- PortAddr iop_base,
- ushort ins_code
-)
-{
- AscSetBank(iop_base, 1);
- AscWriteChipIH(iop_base, ins_code);
- AscSetBank(iop_base, 0);
- return;
-}
-
-void
-AscAckInterrupt(
- PortAddr iop_base
-)
-{
-
- uchar host_flag;
- uchar risc_flag;
- ushort loop;
-
- loop = 0;
- do {
- risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B);
- if (loop++ > 0x7FFF) {
- break;
- }
- } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0);
-
- host_flag = AscReadLramByte(iop_base, ASCV_HOST_FLAG_B);
- AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B,
- (uchar) (host_flag | ASC_HOST_FLAG_ACK_INT));
-
- AscSetChipStatus(iop_base, CIW_INT_ACK);
- loop = 0;
- while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) {
-
- AscSetChipStatus(iop_base, CIW_INT_ACK);
- if (loop++ > 3) {
- break;
- }
- }
-
- AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag);
- return;
-}
-
-void
-AscDisableInterrupt(
- PortAddr iop_base
-)
-{
- ushort cfg;
-
- cfg = AscGetChipCfgLsw(iop_base);
- AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON));
- return;
-}
-
-void
-AscEnableInterrupt(
- PortAddr iop_base
-)
-{
- ushort cfg;
-
- cfg = AscGetChipCfgLsw(iop_base);
- AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON);
- return;
-}
-
-void
-AscSetBank(
- PortAddr iop_base,
- uchar bank
-)
-{
- uchar val;
-
- val = AscGetChipControl(iop_base) &
- (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET | CC_CHIP_RESET));
- if (bank == 1) {
- val |= CC_BANK_ONE;
- } else if (bank == 2) {
- val |= CC_DIAG | CC_BANK_ONE;
- } else {
- val &= ~CC_BANK_ONE;
- }
- AscSetChipControl(iop_base, val);
- return;
-}
-
-int
-AscResetChipAndScsiBus(
- PortAddr iop_base
-)
-{
- AscStopChip(iop_base);
- AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT);
- DvcSleepMilliSecond(200);
-
- AscSetChipIH(iop_base, INS_RFLAG_WTM);
- AscSetChipIH(iop_base, INS_HALT);
-
- AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT);
- AscSetChipControl(iop_base, CC_HALT);
- DvcSleepMilliSecond(200);
- return (AscIsChipHalted(iop_base));
-}
-
-ushort
-AscGetIsaDmaChannel(
- PortAddr iop_base
-)
-{
- ushort channel;
-
- channel = AscGetChipCfgLsw(iop_base) & 0x0003;
- if (channel == 0x03)
- return (0);
- else if (channel == 0x00)
- return (7);
- return (channel + 4);
-}
-
-ushort
-AscSetIsaDmaChannel(
- PortAddr iop_base,
- ushort dma_channel
-)
-{
- ushort cfg_lsw;
- uchar value;
-
- if ((dma_channel >= 5) && (dma_channel <= 7)) {
-
- if (dma_channel == 7)
- value = 0x00;
- else
- value = dma_channel - 4;
- cfg_lsw = AscGetChipCfgLsw(iop_base) & 0xFFFC;
- cfg_lsw |= value;
- AscSetChipCfgLsw(iop_base, cfg_lsw);
- return (AscGetIsaDmaChannel(iop_base));
- }
- return (0);
-}
-
-uchar
-AscSetIsaDmaSpeed(
- PortAddr iop_base,
- uchar speed_value
-)
-{
- speed_value &= 0x07;
- AscSetBank(iop_base, 1);
- AscSetChipDmaSpeed(iop_base, speed_value);
- AscSetBank(iop_base, 0);
- return (AscGetIsaDmaSpeed(iop_base));
-}
-
-uchar
-AscGetIsaDmaSpeed(
- PortAddr iop_base
-)
-{
- uchar speed_value;
-
- AscSetBank(iop_base, 1);
- speed_value = AscGetChipDmaSpeed(iop_base);
- speed_value &= 0x07;
- AscSetBank(iop_base, 0);
- return (speed_value);
-}
-
-ulong
-AscGetMaxDmaCount(
- ushort bus_type
-)
-{
- if (bus_type & ASC_IS_ISA)
- return (ASC_MAX_ISA_DMA_COUNT);
- else if (bus_type & (ASC_IS_EISA | ASC_IS_VL))
- return (ASC_MAX_VL_DMA_COUNT);
- return (ASC_MAX_PCI_DMA_COUNT);
-}
-
-ushort
-AscInitGetConfig(
- ASC_DVC_VAR asc_ptr_type * asc_dvc
-)
-{
- ushort warn_code;
-
- warn_code = 0;
- asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG;
- if (asc_dvc->err_code != 0)
- return (UW_ERR);
- if (AscFindSignature(asc_dvc->iop_base)) {
- warn_code |= AscInitAscDvcVar(asc_dvc);
- warn_code |= AscInitFromEEP(asc_dvc);
- asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG;
-
- if (asc_dvc->scsi_reset_wait > 10)
- asc_dvc->scsi_reset_wait = 10;
-
- } else {
- asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
- }
- return (warn_code);
-}
-
-ushort
-AscInitSetConfig(
- ASC_DVC_VAR asc_ptr_type * asc_dvc
-)
-{
- ushort warn_code;
-
- warn_code = 0;
- asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG;
- if (asc_dvc->err_code != 0)
- return (UW_ERR);
- if (AscFindSignature(asc_dvc->iop_base)) {
- warn_code |= AscInitFromAscDvcVar(asc_dvc);
- asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG;
- } else {
- asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
- }
- return (warn_code);
-}
-
-ushort
-AscInitAsc1000Driver(
- ASC_DVC_VAR asc_ptr_type * asc_dvc
-)
-{
- ushort warn_code;
- PortAddr iop_base;
-
- extern ushort _mcode_size;
- extern ulong _mcode_chksum;
- extern uchar _mcode_buf[];
-
- ASC_DBG(3, "AscInitAsc1000Driver: begin\n");
- iop_base = asc_dvc->iop_base;
- warn_code = 0;
-
- if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) &&
- !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) {
-
- ASC_DBG(3, "AscInitAsc1000Driver: AscResetChipAndScsiBus()\n");
- AscResetChipAndScsiBus(iop_base);
- DvcSleepMilliSecond((ulong) ((ushort) asc_dvc->scsi_reset_wait * 1000));
- }
- asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC;
- if (asc_dvc->err_code != 0)
- return (UW_ERR);
- ASC_DBG(3, "AscInitAsc1000Driver: AscFindSignature()\n");
- if (!AscFindSignature(asc_dvc->iop_base)) {
- asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE;
- return (warn_code);
- }
- ASC_DBG(3, "AscInitAsc1000Driver: AscDisableInterrupt()\n");
- AscDisableInterrupt(iop_base);
-
- ASC_DBG(3, "AscInitAsc1000Driver: AscInitLram()\n");
- warn_code |= AscInitLram(asc_dvc);
- if (asc_dvc->err_code != 0)
- return (UW_ERR);
- ASC_DBG(3, "AscInitAsc1000Driver: AscLoadMicroCode()\n");
- if (AscLoadMicroCode(iop_base, 0, (ushort dosfar *) _mcode_buf,
- _mcode_size) != _mcode_chksum) {
- asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
- return (warn_code);
- }
- ASC_DBG(3, "AscInitAsc1000Driver: AscInitMicroCodeVar()\n");
- warn_code |= AscInitMicroCodeVar(asc_dvc);
- asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
- ASC_DBG(3, "AscInitAsc1000Driver: AscEnableInterrupt()\n");
- AscEnableInterrupt(iop_base);
- return (warn_code);
-}
-
-ushort
-AscInitAscDvcVar(
- ASC_DVC_VAR asc_ptr_type * asc_dvc
-)
-{
- int i;
- PortAddr iop_base;
- ushort warn_code;
-
- iop_base = asc_dvc->iop_base;
- warn_code = 0;
- asc_dvc->err_code = 0;
-
- if ((asc_dvc->bus_type &
- (ASC_IS_ISA | ASC_IS_PCI | ASC_IS_EISA | ASC_IS_VL)) == 0) {
- asc_dvc->err_code |= ASC_IERR_NO_BUS_TYPE;
- }
-#if CC_LINK_BUSY_Q
- for (i = 0; i <= ASC_MAX_TID; i++) {
- asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q dosfar *) 0L;
- asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q dosfar *) 0L;
- }
-#endif
-
- asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL;
- asc_dvc->bug_fix_cntl = 0;
- asc_dvc->pci_fix_asyn_xfer = 0;
- asc_dvc->init_sdtr = 0;
- asc_dvc->sdtr_done = 0;
- asc_dvc->max_total_qng = ASC_DEF_MAX_TOTAL_QNG;
- asc_dvc->cur_total_qng = 0;
- asc_dvc->is_in_int = 0;
- asc_dvc->scsi_reset_wait = 3;
- asc_dvc->in_critical_cnt = 0;
-
- asc_dvc->last_q_shortage = 0;
- asc_dvc->use_tagged_qng = 0;
- asc_dvc->cfg->can_tagged_qng = 0;
- asc_dvc->no_scam = 0;
- asc_dvc->irq_no = 10;
- asc_dvc->start_motor = ASC_SCSI_WIDTH_BIT_SET;
- asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET;
- asc_dvc->cfg->cmd_qng_enabled = ASC_SCSI_WIDTH_BIT_SET;
- asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID;
- asc_dvc->cfg->chip_version = AscGetChipVersion(iop_base,
- asc_dvc->bus_type);
- if (AscGetChipBusType(iop_base) == ASC_IS_ISAPNP) {
-
- AscPutChipIFC(iop_base, IFC_INIT_DEFAULT);
- asc_dvc->bus_type = ASC_IS_ISAPNP;
- }
- asc_dvc->unit_not_ready = 0;
- asc_dvc->queue_full_or_busy = 0;
-
- if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
- asc_dvc->cfg->isa_dma_channel = (uchar) AscGetIsaDmaChannel(iop_base);
- asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED;
- }
- asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER;
- asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) |
- ASC_LIB_VERSION_MINOR;
- asc_dvc->int_count = 0L;
- asc_dvc->req_count = 0L;
- asc_dvc->busy_count = 0L;
- asc_dvc->max_dma_count = AscGetMaxDmaCount(asc_dvc->bus_type);
-
- for (i = 0; i <= ASC_MAX_TID; i++) {
- asc_dvc->cfg->sdtr_data[i] =
- (uchar) (ASC_DEF_SDTR_OFFSET | (ASC_DEF_SDTR_INDEX << 4));
- asc_dvc->cur_dvc_qng[i] = 0;
- asc_dvc->max_dvc_qng[i] = ASC_MAX_SCSI1_QNG;
- asc_dvc->scsiq_busy_head[i] = (ASC_SCSI_Q dosfar *) 0L;
- asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q dosfar *) 0L;
- }
- return (warn_code);
-}
-
-ushort
-AscInitFromAscDvcVar(
- ASC_DVC_VAR asc_ptr_type * asc_dvc
-)
-{
- PortAddr iop_base;
- ushort cfg_msw;
- ushort warn_code;
-
- iop_base = asc_dvc->iop_base;
- warn_code = 0;
-
- cfg_msw = AscGetChipCfgMsw(iop_base);
-
- if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
- cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
- warn_code |= ASC_WARN_CFG_MSW_RECOVER;
- AscSetChipCfgMsw(iop_base, cfg_msw);
- }
- if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
- warn_code |= ASC_WARN_AUTO_CONFIG;
-
- }
- if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) !=
- asc_dvc->cfg->cmd_qng_enabled) {
- asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled;
- warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
- }
- if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) {
-
- if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type)
- != asc_dvc->irq_no) {
- asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO;
- }
- }
- if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) !=
- asc_dvc->cfg->chip_scsi_id) {
- asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID;
- }
- if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) {
- AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel);
- AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed);
- }
- return (warn_code);
-}
-
-ushort
-AscInitFromEEP(
- ASC_DVC_VAR asc_ptr_type * asc_dvc
-)
-{
- ASCEEP_CONFIG eep_config_buf;
- ASCEEP_CONFIG dosfar *eep_config;
- PortAddr iop_base;
- ushort chksum;
- ushort warn_code;
- ushort cfg_msw, cfg_lsw;
- uchar i;
-
- iop_base = asc_dvc->iop_base;
- warn_code = 0;
-
- AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE);
-
- AscStopQueueExe(iop_base);
- if ((AscStopChip(iop_base) == FALSE) ||
- (AscGetChipScsiCtrl(iop_base) != 0)) {
- asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE;
- AscResetChipAndScsiBus(iop_base);
- DvcSleepMilliSecond((ulong) ((ushort) asc_dvc->scsi_reset_wait * 1000));
- }
- if (AscIsChipHalted(iop_base) == FALSE) {
- asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
- return (warn_code);
- }
- AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
- if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
- asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
- return (warn_code);
- }
- eep_config = (ASCEEP_CONFIG dosfar *) & eep_config_buf;
-
- cfg_msw = AscGetChipCfgMsw(iop_base);
- cfg_lsw = AscGetChipCfgLsw(iop_base);
-
- if (asc_dvc->bus_type & ASC_IS_PCI) {
-#if CC_DISABLE_PCI_PARITY_INT
- cfg_msw &= 0xFFC0;
- AscSetChipCfgMsw(iop_base, cfg_msw);
-#endif
- if (asc_dvc->cfg->pci_device_id == ASC_PCI_DEVICE_ID_REV_A) {
- asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ADD_ONE_BYTE;
- }
- }
- if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) {
- cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
- warn_code |= ASC_WARN_CFG_MSW_RECOVER;
- AscSetChipCfgMsw(iop_base, cfg_msw);
- }
- chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type);
-
- eep_config->cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK));
-
- if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) {
- warn_code |= ASC_WARN_AUTO_CONFIG;
-
- if (asc_dvc->cfg->chip_version == 3) {
-
- if (eep_config->cfg_lsw != cfg_lsw) {
- warn_code |= ASC_WARN_EEPROM_RECOVER;
- eep_config->cfg_lsw = AscGetChipCfgLsw(iop_base);
- }
- if (eep_config->cfg_msw != cfg_msw) {
- warn_code |= ASC_WARN_EEPROM_RECOVER;
- eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
- }
- }
- }
- eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON;
- if (chksum != eep_config->chksum) {
- warn_code |= ASC_WARN_EEPROM_CHKSUM;
- }
- asc_dvc->init_sdtr = eep_config->init_sdtr;
- asc_dvc->cfg->disc_enable = eep_config->disc_enable;
-
- asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng;
- asc_dvc->cfg->isa_dma_speed = eep_config->isa_dma_speed;
- asc_dvc->start_motor = eep_config->start_motor;
- asc_dvc->dvc_cntl = eep_config->cntl;
- asc_dvc->no_scam = eep_config->no_scam;
-
- if ((asc_dvc->bus_type & ASC_IS_PCI) &&
- !(asc_dvc->dvc_cntl & ASC_CNTL_NO_PCI_FIX_ASYN_XFER)) {
- if ((asc_dvc->cfg->pci_device_id == ASC_PCI_DEVICE_ID_REV_A) ||
- (asc_dvc->cfg->pci_device_id == ASC_PCI_DEVICE_ID_REV_B)) {
- asc_dvc->pci_fix_asyn_xfer = ASC_ALL_DEVICE_BIT_SET;
- }
- } else if (asc_dvc->bus_type & ASC_IS_ISAPNP) {
-
- if (AscGetChipVersion(iop_base, asc_dvc->bus_type)
- == ASC_CHIP_VER_ASYN_BUG) {
- asc_dvc->pci_fix_asyn_xfer = ASC_ALL_DEVICE_BIT_SET;
- }
- }
- if (!AscTestExternalLram(asc_dvc)) {
- if (asc_dvc->bus_type & ASC_IS_PCI) {
- eep_config->cfg_msw |= 0x0800;
- cfg_msw |= 0x0800;
- AscSetChipCfgMsw(iop_base, cfg_msw);
- eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG;
- eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG;
- }
- } else {
-#if CC_TEST_RW_LRAM
- asc_dvc->err_code |= AscTestLramEndian(iop_base);
-#endif
- }
- if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) {
- eep_config->max_total_qng = ASC_MIN_TOTAL_QNG;
- }
- if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) {
- eep_config->max_total_qng = ASC_MAX_TOTAL_QNG;
- }
- if (eep_config->max_tag_qng > eep_config->max_total_qng) {
- eep_config->max_tag_qng = eep_config->max_total_qng;
- }
- if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) {
- eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC;
- }
- asc_dvc->max_total_qng = eep_config->max_total_qng;
-
- if ((eep_config->use_cmd_qng & eep_config->disc_enable) !=
- eep_config->use_cmd_qng) {
- eep_config->disc_enable = eep_config->use_cmd_qng;
- warn_code |= ASC_WARN_CMD_QNG_CONFLICT;
- }
- asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type);
- eep_config->chip_scsi_id &= ASC_MAX_TID;
- asc_dvc->cfg->chip_scsi_id = eep_config->chip_scsi_id;
-
- for (i = 0; i <= ASC_MAX_TID; i++) {
- asc_dvc->cfg->sdtr_data[i] = eep_config->sdtr_data[i];
- asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng;
- }
-
- eep_config->cfg_msw = AscGetChipCfgMsw(iop_base);
- if (AscSetEEPConfig(iop_base, eep_config, asc_dvc->bus_type) != 0) {
- asc_dvc->err_code |= ASC_IERR_WRITE_EEPROM;
- }
- return (warn_code);
-}
-
-ushort
-AscInitMicroCodeVar(
- ASC_DVC_VAR asc_ptr_type * asc_dvc
-)
-{
- int i;
- ushort warn_code;
- PortAddr iop_base;
- ulong phy_addr;
-
- iop_base = asc_dvc->iop_base;
- warn_code = 0;
- for (i = 0; i <= ASC_MAX_TID; i++) {
- AscWriteLramByte(iop_base, (ushort) (ASCV_SDTR_DATA_BEG + i),
- asc_dvc->cfg->sdtr_data[i]);
- }
-
- AscInitQLinkVar(asc_dvc);
-
- AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
- asc_dvc->cfg->disc_enable);
- AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B,
- ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id));
- if ((phy_addr = AscGetOnePhyAddr(asc_dvc,
- (uchar dosfar *) asc_dvc->cfg->overrun_buf,
- ASC_OVERRUN_BSIZE)) == 0L) {
- asc_dvc->err_code |= ASC_IERR_GET_PHY_ADDR;
- } else {
-
- phy_addr = (phy_addr & 0xFFFFFFF8UL) + 8;
- AscWriteLramDWord(iop_base, ASCV_OVERRUN_PADDR_D, phy_addr);
- AscWriteLramDWord(iop_base, ASCV_OVERRUN_BSIZE_D,
- ASC_OVERRUN_BSIZE - 8);
- }
-
- asc_dvc->cfg->mcode_date = AscReadLramWord(iop_base,
- (ushort) ASCV_MC_DATE_W);
- asc_dvc->cfg->mcode_version = AscReadLramWord(iop_base,
- (ushort) ASCV_MC_VER_W);
- AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR);
- if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) {
- asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR;
- return (warn_code);
- }
- if (AscStartChip(iop_base) != 1) {
- asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP;
- return (warn_code);
- }
- return (warn_code);
-}
-
-void dosfar
-AscInitPollIsrCallBack(
- ASC_DVC_VAR asc_ptr_type * asc_dvc,
- ASC_QDONE_INFO dosfar * scsi_done_q
-)
-{
- ASC_SCSI_REQ_Q dosfar *scsiq_req;
- ASC_ISR_CALLBACK asc_isr_callback;
- uchar cp_sen_len;
- uchar i;
-
- if ((scsi_done_q->d2.flag & ASC_FLAG_SCSIQ_REQ) != 0) {
- scsiq_req = (ASC_SCSI_REQ_Q dosfar *) scsi_done_q->d2.srb_ptr;
- ASC_DBG2(3, "AscInitPollIsrCallBack: done_stat %x, host_stat %x\n",
- scsiq_req->r3.done_stat, scsiq_req->r3.host_stat);
- scsiq_req->r3.done_stat = scsi_done_q->d3.done_stat;
- scsiq_req->r3.host_stat = scsi_done_q->d3.host_stat;
- scsiq_req->r3.scsi_stat = scsi_done_q->d3.scsi_stat;
- scsiq_req->r3.scsi_msg = scsi_done_q->d3.scsi_msg;
- if ((scsi_done_q->d3.scsi_stat == SS_CHK_CONDITION) &&
- (scsi_done_q->d3.host_stat == 0)) {
- cp_sen_len = (uchar) ASC_MIN_SENSE_LEN;
- if (scsiq_req->r1.sense_len < ASC_MIN_SENSE_LEN) {
- cp_sen_len = (uchar) scsiq_req->r1.sense_len;
- }
- for (i = 0; i < cp_sen_len; i++) {
- scsiq_req->sense[i] = scsiq_req->sense_ptr[i];
- }
- }
- } else {
- ASC_DBG1(3, "AscInitPollIsrCallBack: isr_callback %x\n",
- (unsigned) asc_dvc->isr_callback);
- if (asc_dvc->isr_callback != 0) {
- asc_isr_callback = (ASC_ISR_CALLBACK) asc_dvc->isr_callback;
- (*asc_isr_callback) (asc_dvc, scsi_done_q);
- }
- }
- return;
-}
-
-int
-AscTestExternalLram(
- ASC_DVC_VAR asc_ptr_type * asc_dvc
-)
-{
- PortAddr iop_base;
- ushort q_addr;
- ushort saved_word;
- int sta;
-
- iop_base = asc_dvc->iop_base;
- sta = 0;
-
- q_addr = ASC_QNO_TO_QADDR(241);
- saved_word = AscReadLramWord(iop_base, q_addr);
- if (AscVerWriteLramWord(iop_base, q_addr, 0x55AA) == 0) {
- sta = 1;
- AscWriteLramWord(iop_base, q_addr, saved_word);
- }
- return (sta);
-}
-
-#if CC_TEST_LRAM_ENDIAN
-
-#endif
-
-int
-AscWriteEEPCmdReg(
- PortAddr iop_base,
- uchar cmd_reg
-)
-{
- uchar read_back;
- int retry;
-
- retry = 0;
- while (TRUE) {
- AscSetChipEEPCmd(iop_base, cmd_reg);
- DvcSleepMilliSecond(1);
- read_back = AscGetChipEEPCmd(iop_base);
- if (read_back == cmd_reg) {
- return (1);
- }
- if (retry++ > ASC_EEP_MAX_RETRY) {
- return (0);
- }
- }
-}
-
-int
-AscWriteEEPDataReg(
- PortAddr iop_base,
- ushort data_reg
-)
-{
- ushort read_back;
- int retry;
-
- retry = 0;
- while (TRUE) {
- AscSetChipEEPData(iop_base, data_reg);
- DvcSleepMilliSecond(1);
- read_back = AscGetChipEEPData(iop_base);
- if (read_back == data_reg) {
- return (1);
- }
- if (retry++ > ASC_EEP_MAX_RETRY) {
- return (0);
- }
- }
-}
-
-void
-AscWaitEEPRead(
- void
-)
-{
- DvcSleepMilliSecond(1);
- return;
-}
-
-void
-AscWaitEEPWrite(
- void
-)
-{
- DvcSleepMilliSecond(20);
- return;
-}
-
-ushort
-AscReadEEPWord(
- PortAddr iop_base,
- uchar addr
-)
-{
- ushort read_wval;
- uchar cmd_reg;
-
- AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
- AscWaitEEPRead();
- cmd_reg = addr | ASC_EEP_CMD_READ;
- AscWriteEEPCmdReg(iop_base, cmd_reg);
- AscWaitEEPRead();
- read_wval = AscGetChipEEPData(iop_base);
- AscWaitEEPRead();
- return (read_wval);
-}
-
-ushort
-AscWriteEEPWord(
- PortAddr iop_base,
- uchar addr,
- ushort word_val
-)
-{
- ushort read_wval;
-
- read_wval = AscReadEEPWord(iop_base, addr);
- if (read_wval != word_val) {
- AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_ABLE);
- AscWaitEEPRead();
-
- AscWriteEEPDataReg(iop_base, word_val);
- AscWaitEEPRead();
-
- AscWriteEEPCmdReg(iop_base,
- (uchar) ((uchar) ASC_EEP_CMD_WRITE | addr));
- AscWaitEEPWrite();
-
- AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE);
- AscWaitEEPRead();
- return (AscReadEEPWord(iop_base, addr));
- }
- return (read_wval);
-}
-
-ushort
-AscGetEEPConfig(
- PortAddr iop_base,
- ASCEEP_CONFIG dosfar * cfg_buf, ushort bus_type
-)
-{
- ushort wval;
- ushort sum;
- ushort dosfar *wbuf;
- int cfg_beg;
- int cfg_end;
- int s_addr;
- int isa_pnp_wsize;
-
- wbuf = (ushort dosfar *) cfg_buf;
- sum = 0;
-
- isa_pnp_wsize = 0;
- for (s_addr = 0; s_addr < (2 + isa_pnp_wsize); s_addr++, wbuf++) {
- wval = AscReadEEPWord(iop_base, (uchar) s_addr);
- sum += wval;
- *wbuf = wval;
- }
-
- if (bus_type & ASC_IS_VL) {
- cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
- cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
- } else {
- cfg_beg = ASC_EEP_DVC_CFG_BEG;
- cfg_end = ASC_EEP_MAX_DVC_ADDR;
- }
-
- for (s_addr = cfg_beg; s_addr <= (cfg_end - 1);
- s_addr++, wbuf++) {
- wval = AscReadEEPWord(iop_base, (uchar) s_addr);
- sum += wval;
- *wbuf = wval;
- }
- *wbuf = AscReadEEPWord(iop_base, (uchar) s_addr);
- return (sum);
-}
-
-int
-AscSetEEPConfigOnce(
- PortAddr iop_base,
- ASCEEP_CONFIG dosfar * cfg_buf, ushort bus_type
-)
-{
- int n_error;
- ushort dosfar *wbuf;
- ushort sum;
- int s_addr;
- int cfg_beg;
- int cfg_end;
-
- wbuf = (ushort dosfar *) cfg_buf;
- n_error = 0;
- sum = 0;
- for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
- sum += *wbuf;
- if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) {
- n_error++;
- }
- }
- if (bus_type & ASC_IS_VL) {
- cfg_beg = ASC_EEP_DVC_CFG_BEG_VL;
- cfg_end = ASC_EEP_MAX_DVC_ADDR_VL;
- } else {
- cfg_beg = ASC_EEP_DVC_CFG_BEG;
- cfg_end = ASC_EEP_MAX_DVC_ADDR;
- }
- for (s_addr = cfg_beg; s_addr <= (cfg_end - 1);
- s_addr++, wbuf++) {
- sum += *wbuf;
- if (*wbuf != AscWriteEEPWord(iop_base, (uchar) s_addr, *wbuf)) {
- n_error++;
- }
- }
- *wbuf = sum;
- if (sum != AscWriteEEPWord(iop_base, (uchar) s_addr, sum)) {
- n_error++;
- }
- wbuf = (ushort dosfar *) cfg_buf;
- for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) {
- if (*wbuf != AscReadEEPWord(iop_base, (uchar) s_addr)) {
- n_error++;
- }
- }
- for (s_addr = cfg_beg; s_addr <= cfg_end;
- s_addr++, wbuf++) {
- if (*wbuf != AscReadEEPWord(iop_base, (uchar) s_addr)) {
- n_error++;
- }
- }
- return (n_error);
-}
-
-int
-AscSetEEPConfig(
- PortAddr iop_base,
- ASCEEP_CONFIG dosfar * cfg_buf, ushort bus_type
-)
-{
- int retry;
- int n_error;
-
- retry = 0;
- while (TRUE) {
- if ((n_error = AscSetEEPConfigOnce(iop_base, cfg_buf,
- bus_type)) == 0) {
- break;
- }
- if (++retry > ASC_EEP_MAX_RETRY) {
- break;
- }
- }
- return (n_error);
-}
-
-int
-AscInitPollBegin(
- ASC_DVC_VAR asc_ptr_type * asc_dvc
-)
-{
- PortAddr iop_base;
-
- iop_base = asc_dvc->iop_base;
-
-#if CC_INIT_INQ_DISPLAY
- DvcDisplayString((uchar dosfar *) "\r\n");
-#endif
-
- AscDisableInterrupt(iop_base);
-
- asc_dvc->init_state |= ASC_INIT_STATE_BEG_INQUIRY;
-
- AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B, 0x00);
- asc_dvc->use_tagged_qng = 0;
- asc_dvc->cfg->can_tagged_qng = 0;
- asc_dvc->saved_ptr2func = (ulong) asc_dvc->isr_callback;
- asc_dvc->isr_callback = ASC_GET_PTR2FUNC(AscInitPollIsrCallBack);
- return (0);
-}
-
-int
-AscInitPollEnd(
- ASC_DVC_VAR asc_ptr_type * asc_dvc
-)
-{
- PortAddr iop_base;
- int i;
-
- iop_base = asc_dvc->iop_base;
- asc_dvc->isr_callback = (Ptr2Func) asc_dvc->saved_ptr2func;
- AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B,
- asc_dvc->cfg->disc_enable);
- AscWriteLramByte(iop_base, ASCV_USE_TAGGED_QNG_B,
- asc_dvc->use_tagged_qng);
- AscWriteLramByte(iop_base, ASCV_CAN_TAGGED_QNG_B,
- asc_dvc->cfg->can_tagged_qng);
-
- for (i = 0; i <= ASC_MAX_TID; i++) {
- AscWriteLramByte(iop_base,
- (ushort) ((ushort) ASCV_MAX_DVC_QNG_BEG + (ushort) i),
- asc_dvc->max_dvc_qng[i]);
- }
-
- AscEnableInterrupt(iop_base);
-
-#if CC_INIT_INQ_DISPLAY
- DvcDisplayString((uchar dosfar *) "\r\n");
-#endif
- asc_dvc->init_state |= ASC_INIT_STATE_END_INQUIRY;
-
- return (0);
-}
-
-int _asc_wait_slow_device_ = FALSE;
-
-int
-AscInitPollTarget(
- ASC_DVC_VAR asc_ptr_type * asc_dvc,
- ASC_SCSI_REQ_Q dosfar * scsiq,
- ASC_SCSI_INQUIRY dosfar * inq,
- ASC_CAP_INFO dosfar * cap_info
-)
-{
- uchar tid_no, lun;
- uchar dvc_type;
- ASC_SCSI_BIT_ID_TYPE tid_bits;
- int dvc_found;
- int support_read_cap;
- int tmp_disable_init_sdtr;
- ulong phy_addr;
-
- dvc_found = 0;
- tmp_disable_init_sdtr = FALSE;
- tid_bits = scsiq->r1.target_id;
- lun = scsiq->r1.target_lun;
- tid_no = ASC_TIX_TO_TID(scsiq->r2.target_ix);
- if ((phy_addr = AscGetOnePhyAddr(asc_dvc,
- (uchar dosfar *) scsiq->sense_ptr,
- (ulong) scsiq->r1.sense_len)) == 0L) {
- return (ERR);
- }
- scsiq->r1.sense_addr = phy_addr;
- if (((asc_dvc->init_sdtr & tid_bits) != 0) &&
- ((asc_dvc->sdtr_done & tid_bits) == 0)) {
-
- asc_dvc->init_sdtr &= ~tid_bits;
- tmp_disable_init_sdtr = TRUE;
- }
- ASC_DBG(3, "AscInitPollTarget: PollScsiInquiry()\n");
- if (PollScsiInquiry(asc_dvc, scsiq, (uchar dosfar *) inq,
- sizeof (ASC_SCSI_INQUIRY)) == 1) {
- dvc_found = 1;
- support_read_cap = TRUE;
- dvc_type = inq->byte0.peri_dvc_type;
- if (dvc_type != SCSI_TYPE_UNKNOWN) {
- if ((dvc_type != SCSI_TYPE_DASD) &&
- (dvc_type != SCSI_TYPE_WORM) &&
- (dvc_type != SCSI_TYPE_CDROM) &&
- (dvc_type != SCSI_TYPE_OPTMEM)) {
- asc_dvc->start_motor &= ~tid_bits;
- support_read_cap = FALSE;
- }
- if ((dvc_type != SCSI_TYPE_DASD) ||
- inq->byte1.rmb) {
-
- if (!_asc_wait_slow_device_) {
- DvcSleepMilliSecond(3000 - ((int) tid_no * 250));
- _asc_wait_slow_device_ = TRUE;
- }
- }
-#if CC_INIT_INQ_DISPLAY
- AscDispInquiry(tid_no, lun, inq);
-#endif
-
- if (lun == 0) {
-
- if ((inq->byte3.rsp_data_fmt >= 2) ||
- (inq->byte2.ansi_apr_ver >= 2)) {
-
- if (inq->byte7.CmdQue) {
- asc_dvc->cfg->can_tagged_qng |= tid_bits;
- if (asc_dvc->cfg->cmd_qng_enabled & tid_bits) {
- asc_dvc->use_tagged_qng |= tid_bits;
- asc_dvc->max_dvc_qng[tid_no] =
- asc_dvc->cfg->max_tag_qng[tid_no];
- }
- }
- if (!inq->byte7.Sync) {
-
- asc_dvc->init_sdtr &= ~tid_bits;
- asc_dvc->sdtr_done &= ~tid_bits;
- } else if (tmp_disable_init_sdtr) {
-
- asc_dvc->init_sdtr |= tid_bits;
- }
- } else {
-
- asc_dvc->init_sdtr &= ~tid_bits;
- asc_dvc->sdtr_done &= ~tid_bits;
- asc_dvc->use_tagged_qng &= ~tid_bits;
- }
- }
- if (asc_dvc->pci_fix_asyn_xfer & tid_bits) {
- if (!(asc_dvc->init_sdtr & tid_bits)) {
-
- AscSetRunChipSynRegAtID(asc_dvc->iop_base, tid_no,
- ASYN_SDTR_DATA_FIX_PCI_REV_AB);
- }
- }
- ASC_DBG(3, "AscInitPollTarget: InitTestUnitReady()\n");
- if (InitTestUnitReady(asc_dvc, scsiq) != 1) {
-
- } else {
- if ((cap_info != 0L) && support_read_cap) {
- ASC_DBG(3, "AscInitPollTarget: PollScsiReadCapacity()\n");
- if (PollScsiReadCapacity(asc_dvc, scsiq,
- cap_info) != 1) {
- cap_info->lba = 0L;
- cap_info->blk_size = 0x0000;
- } else {
-
- }
- }
- }
- } else {
- asc_dvc->start_motor &= ~tid_bits;
- }
- } else {
-
- }
- return (dvc_found);
-}
-
-int
-PollQueueDone(
- ASC_DVC_VAR asc_ptr_type * asc_dvc,
- ASC_SCSI_REQ_Q dosfar * scsiq,
- int timeout_sec
-)
-{
- int status;
- int retry;
-
- retry = 0;
- do {
- ASC_DBG(3, "PollQueueDone: AscExeScsiQueue()\n");
- if ((status = AscExeScsiQueue(asc_dvc,
- (ASC_SCSI_Q dosfar *) scsiq)) == 1) {
- ASC_DBG(3, "PollQueueDone: AscPollQDone()\n");
- if ((status = AscPollQDone(asc_dvc, scsiq,
- timeout_sec)) != 1) {
- ASC_DBG1(3, "PollQueueDone: AscPollQDone() status %x\n", status);
- if (status == 0x80) {
- if (retry++ > ASC_MAX_INIT_BUSY_RETRY) {
- break;
- }
- scsiq->r3.done_stat = 0;
- scsiq->r3.host_stat = 0;
- scsiq->r3.scsi_stat = 0;
- scsiq->r3.scsi_msg = 0;
- DvcSleepMilliSecond(100);
- continue;
- }
- scsiq->r3.done_stat = 0;
- scsiq->r3.host_stat = 0;
- scsiq->r3.scsi_stat = 0;
- scsiq->r3.scsi_msg = 0;
- ASC_DBG1(3, "PollQueueDone: AscAbortSRB() scsiq %x\n",
- (unsigned) scsiq);
-
- AscAbortSRB(asc_dvc, (ulong) scsiq);
- }
- ASC_DBG1(3, "PollQueueDone: done_stat %x\n", scsiq->r3.done_stat);
- return (scsiq->r3.done_stat);
- }
- } while ((status == 0) || (status == 0x80));
- ASC_DBG(3, "PollQueueDone: done_stat QD_WITH_ERROR\n");
- return (scsiq->r3.done_stat = QD_WITH_ERROR);
-}
-
-int
-PollScsiInquiry(
- ASC_DVC_VAR asc_ptr_type * asc_dvc,
- ASC_SCSI_REQ_Q dosfar * scsiq,
- uchar dosfar * buf,
- int buf_len
-)
-{
- if (AscScsiInquiry(asc_dvc, scsiq, buf, buf_len) == ERR) {
- return (scsiq->r3.done_stat = QD_WITH_ERROR);
- }
- return (PollQueueDone(asc_dvc, (ASC_SCSI_REQ_Q dosfar *) scsiq, 4));
-}
-
-int
-PollScsiReadCapacity(
- ASC_DVC_VAR asc_ptr_type * asc_dvc,
- ASC_SCSI_REQ_Q dosfar * scsiq,
- ASC_CAP_INFO dosfar * cap_info
-)
-{
- ASC_CAP_INFO scsi_cap_info;
- int status;
-
- if (AscScsiReadCapacity(asc_dvc, scsiq,
- (uchar dosfar *) & scsi_cap_info) == ERR) {
- return (scsiq->r3.done_stat = QD_WITH_ERROR);
- }
- status = PollQueueDone(asc_dvc, (ASC_SCSI_REQ_Q dosfar *) scsiq, 8);
- if (status == 1) {
-#if CC_LITTLE_ENDIAN_HOST
- cap_info->lba = (ulong) * swapfarbuf4((uchar dosfar *) & scsi_cap_info.lba);
- cap_info->blk_size = (ulong) * swapfarbuf4((uchar dosfar *) & scsi_cap_info.blk_size);
-#else
- cap_info->lba = scsi_cap_info.lba;
- cap_info->blk_size = scsi_cap_info.blk_size;
-#endif
- return (scsiq->r3.done_stat);
- }
- return (scsiq->r3.done_stat = QD_WITH_ERROR);
-}
-
-ulong dosfar *
-swapfarbuf4(
- uchar dosfar * buf
-)
-{
- uchar tmp;
-
- tmp = buf[3];
- buf[3] = buf[0];
- buf[0] = tmp;
-
- tmp = buf[1];
- buf[1] = buf[2];
- buf[2] = tmp;
-
- return ((ulong dosfar *) buf);
-}
-
-int
-PollScsiTestUnitReady(
- ASC_DVC_VAR asc_ptr_type * asc_dvc,
- ASC_SCSI_REQ_Q dosfar * scsiq
-)
-{
- if (AscScsiTestUnitReady(asc_dvc, scsiq) == ERR) {
- return (scsiq->r3.done_stat = QD_WITH_ERROR);
- }
- return (PollQueueDone(asc_dvc, (ASC_SCSI_REQ_Q dosfar *) scsiq, 12));
-}
-
-int
-PollScsiStartUnit(
- ASC_DVC_VAR asc_ptr_type * asc_dvc,
- ASC_SCSI_REQ_Q dosfar * scsiq
-)
-{
- if (AscScsiStartStopUnit(asc_dvc, scsiq, 1) == ERR) {
- return (scsiq->r3.done_stat = QD_WITH_ERROR);
- }
- return (PollQueueDone(asc_dvc, (ASC_SCSI_REQ_Q dosfar *) scsiq, 40));
-}
-
-int
-InitTestUnitReady(
- ASC_DVC_VAR asc_ptr_type * asc_dvc,
- ASC_SCSI_REQ_Q dosfar * scsiq
-)
-{
- ASC_SCSI_BIT_ID_TYPE tid_bits;
- int retry;
- ASC_REQ_SENSE dosfar *sen;
-
- retry = 0;
- tid_bits = scsiq->r1.target_id;
- while (retry++ < 2) {
- ASC_DBG(3, "InitTestUnitReady: PollScsiTestUnitReady()\n");
- PollScsiTestUnitReady(asc_dvc, scsiq);
- ASC_DBG1(3, "InitTestUnitReady: done_stat %x\n", scsiq->r3.done_stat);
- if (scsiq->r3.done_stat == 0x01) {
- return (1);
- } else if (scsiq->r3.done_stat == QD_WITH_ERROR) {
- DvcSleepMilliSecond(100);
-
- sen = (ASC_REQ_SENSE dosfar *) scsiq->sense_ptr;
-
- if ((scsiq->r3.scsi_stat == SS_CHK_CONDITION) &&
- ((sen->err_code & 0x70) != 0)) {
-
- if (sen->sense_key == SCSI_SENKEY_NOT_READY) {
-
- if (asc_dvc->start_motor & tid_bits) {
- if (PollScsiStartUnit(asc_dvc, scsiq) == 1) {
- retry = 0;
- continue;
- } else {
- asc_dvc->start_motor &= ~tid_bits;
- break;
- }
- } else {
- DvcSleepMilliSecond(100);
- }
- } else if (sen->sense_key == SCSI_SENKEY_ATTENSION) {
- DvcSleepMilliSecond(100);
- } else {
- break;
- }
- } else {
- break;
- }
- } else if (scsiq->r3.done_stat == QD_ABORTED_BY_HOST) {
- break;
- } else {
- break;
- }
- }
- return (0);
-}
-
-#if CC_INIT_INQ_DISPLAY
-
-#endif
-
-int
-AscPollQDone(
- ASC_DVC_VAR asc_ptr_type * asc_dvc,
- ASC_SCSI_REQ_Q dosfar * scsiq,
- int timeout_sec
-)
-{
- int loop, loop_end;
- int sta;
- PortAddr iop_base;
-
- iop_base = asc_dvc->iop_base;
- loop = 0;
- loop_end = timeout_sec * 100;
- sta = 1;
-
- while (TRUE) {
- ASC_DBG4(3,
- "AscPollQDone: loop %d, err_code %x, done_stat %x, scsi_stat %x\n",
- loop, asc_dvc->err_code, scsiq->r3.done_stat, scsiq->r3.scsi_stat);
- if (asc_dvc->err_code != 0) {
- scsiq->r3.done_stat = QD_WITH_ERROR;
- sta = ERR;
- break;
- }
- if (scsiq->r3.done_stat != QD_IN_PROGRESS) {
- if ((scsiq->r3.done_stat == QD_WITH_ERROR) &&
- (scsiq->r3.scsi_stat == SS_TARGET_BUSY)) {
- sta = 0x80;
- break;
- }
- break;
- }
- DvcSleepMilliSecond(10);
- if (loop++ > loop_end) {
- sta = 0;
- break;
- }
- if (AscIsChipHalted(iop_base)) {
- AscISR(asc_dvc);
- loop = 0;
- } else {
- ASC_DBG(3, "AscPollQDone: AscIsIntPending()\n");
- if (AscIsIntPending(iop_base)) {
- ASC_DBG(3, "AscPollQDone: AscISR()\n");
- AscISR(asc_dvc);
- }
- }
- }
- ASC_DBG1(3, "AscPollQDone: sta %x\n", sta);
- return (sta);
-}
-
-uchar
-AscReadLramByte(
- PortAddr iop_base,
- ushort addr
-)
-{
- uchar byte_data;
- ushort word_data;
-
- if (isodd_word(addr)) {
- AscSetChipLramAddr(iop_base, addr - 1);
- word_data = AscGetChipLramData(iop_base);
-
-#if CC_LITTLE_ENDIAN_HOST
- byte_data = (uchar) ((word_data >> 8) & 0xFF);
-#else
- byte_data = (uchar) (word_data & 0xFF);
-#endif
-
- } else {
- AscSetChipLramAddr(iop_base, addr);
- word_data = AscGetChipLramData(iop_base);
-
-#if CC_LITTLE_ENDIAN_HOST
- byte_data = (uchar) (word_data & 0xFF);
-#else
- byte_data = (uchar) ((word_data >> 8) & 0xFF);
-#endif
-
- }
- return (byte_data);
-}
-
-ushort
-AscReadLramWord(
- PortAddr iop_base,
- ushort addr
-)
-{
- ushort word_data;
-
- AscSetChipLramAddr(iop_base, addr);
- word_data = AscGetChipLramData(iop_base);
- return (word_data);
-}
-
-ulong
-AscReadLramDWord(
- PortAddr iop_base,
- ushort addr
-)
-{
- ushort val_low, val_high;
- ulong dword_data;
-
- AscSetChipLramAddr(iop_base, addr);
-
-#if CC_LITTLE_ENDIAN_HOST
- val_low = AscGetChipLramData(iop_base);
-
- val_high = AscGetChipLramData(iop_base);
-#else
- val_high = AscGetChipLramData(iop_base);
- val_low = AscGetChipLramData(iop_base);
-#endif
-
- dword_data = ((ulong) val_high << 16) | (ulong) val_low;
- return (dword_data);
-}
-
-void
-AscWriteLramWord(
- PortAddr iop_base,
- ushort addr,
- ushort word_val
-)
-{
- AscSetChipLramAddr(iop_base, addr);
- AscPutChipLramData(iop_base, word_val);
- return;
-}
-
-void
-AscWriteLramDWord(
- PortAddr iop_base,
- ushort addr,
- ulong dword_val
-)
-{
- ushort word_val;
-
- AscSetChipLramAddr(iop_base, addr);
-
-#if CC_LITTLE_ENDIAN_HOST
- word_val = (ushort) dword_val;
- AscPutChipLramData(iop_base, word_val);
- word_val = (ushort) (dword_val >> 16);
- AscPutChipLramData(iop_base, word_val);
-#else
- word_val = (ushort) (dword_val >> 16);
- AscPutChipLramData(iop_base, word_val);
- word_val = (ushort) dword_val;
- AscPutChipLramData(iop_base, word_val);
-#endif
- return;
-}
-
-void
-AscWriteLramByte(
- PortAddr iop_base,
- ushort addr,
- uchar byte_val
-)
-{
- ushort word_data;
-
- if (isodd_word(addr)) {
- addr--;
- word_data = AscReadLramWord(iop_base, addr);
- word_data &= 0x00FF;
- word_data |= (((ushort) byte_val << 8) & 0xFF00);
- } else {
- word_data = AscReadLramWord(iop_base, addr);
- word_data &= 0xFF00;
- word_data |= ((ushort) byte_val & 0x00FF);
- }
- AscWriteLramWord(iop_base, addr, word_data);
- return;
-}
-
-int
-AscVerWriteLramWord(
- PortAddr iop_base,
- ushort addr,
- ushort word_val
-)
-{
- int sta;
-
- sta = 0;
- AscSetChipLramAddr(iop_base, addr);
- AscPutChipLramData(iop_base, word_val);
- AscSetChipLramAddr(iop_base, addr);
- if (word_val != AscGetChipLramData(iop_base)) {
- sta = ERR;
- }
- return (sta);
-}
-
-void
-AscMemWordCopyToLram(
- PortAddr iop_base,
- ushort s_addr,
- ushort dosfar * s_buffer,
- int words
-)
-{
- AscSetChipLramAddr(iop_base, s_addr);
- DvcOutPortWords(iop_base + IOP_RAM_DATA, s_buffer, words);
- return;
-}
-
-void
-AscMemDWordCopyToLram(
- PortAddr iop_base,
- ushort s_addr,
- ulong dosfar * s_buffer,
- int dwords
-)
-{
- AscSetChipLramAddr(iop_base, s_addr);
- DvcOutPortDWords(iop_base + IOP_RAM_DATA, s_buffer, dwords);
- return;
-}
-
-void
-AscMemWordCopyFromLram(
- PortAddr iop_base,
- ushort s_addr,
- ushort dosfar * d_buffer,
- int words
-)
-{
- AscSetChipLramAddr(iop_base, s_addr);
- DvcInPortWords(iop_base + IOP_RAM_DATA, d_buffer, words);
- return;
-}
-
-ulong
-AscMemSumLramWord(
- PortAddr iop_base,
- ushort s_addr,
- rint words
-)
-{
- ulong sum;
- int i;
-
- sum = 0L;
- for (i = 0; i < words; i++, s_addr += 2) {
- sum += AscReadLramWord(iop_base, s_addr);
- }
- return (sum);
-}
-
-void
-AscMemWordSetLram(
- PortAddr iop_base,
- ushort s_addr,
- ushort set_wval,
- rint words
-)
-{
- rint i;
-
- AscSetChipLramAddr(iop_base, s_addr);
- for (i = 0; i < words; i++) {
- AscPutChipLramData(iop_base, set_wval);
- }
- return;
-}
-
-int
-AscScsiInquiry(
- ASC_DVC_VAR asc_ptr_type * asc_dvc,
- ASC_SCSI_REQ_Q dosfar * scsiq,
- uchar dosfar * buf, int buf_len
-)
-{
- if (AscScsiSetupCmdQ(asc_dvc, scsiq, buf,
- (ulong) buf_len) == ERR) {
- return (scsiq->r3.done_stat = QD_WITH_ERROR);
- }
- scsiq->cdb[0] = (uchar) SCSICMD_Inquiry;
- scsiq->cdb[1] = scsiq->r1.target_lun << 5;
- scsiq->cdb[2] = 0;
- scsiq->cdb[3] = 0;
- scsiq->cdb[4] = buf_len;
- scsiq->cdb[5] = 0;
- scsiq->r2.cdb_len = 6;
- return (0);
-}
-
-int
-AscScsiReadCapacity(
- ASC_DVC_VAR asc_ptr_type * asc_dvc,
- ASC_SCSI_REQ_Q dosfar * scsiq,
- uchar dosfar * info
-)
-{
- if (AscScsiSetupCmdQ(asc_dvc, scsiq, info, 8L) == ERR) {
- return (scsiq->r3.done_stat = QD_WITH_ERROR);
- }
- scsiq->cdb[0] = (uchar) SCSICMD_ReadCapacity;
- scsiq->cdb[1] = scsiq->r1.target_lun << 5;
- scsiq->cdb[2] = 0;
- scsiq->cdb[3] = 0;
- scsiq->cdb[4] = 0;
- scsiq->cdb[5] = 0;
- scsiq->cdb[6] = 0;
- scsiq->cdb[7] = 0;
- scsiq->cdb[8] = 0;
- scsiq->cdb[9] = 0;
- scsiq->r2.cdb_len = 10;
- return (0);
-}
-
-int
-AscScsiTestUnitReady(
- ASC_DVC_VAR asc_ptr_type * asc_dvc,
- ASC_SCSI_REQ_Q dosfar * scsiq
-)
-{
- if (AscScsiSetupCmdQ(asc_dvc, scsiq, FNULLPTR,
- (ulong) 0L) == ERR) {
- return (scsiq->r3.done_stat = QD_WITH_ERROR);
- }
- scsiq->r1.cntl = (uchar) ASC_SCSIDIR_NODATA;
- scsiq->cdb[0] = (uchar) SCSICMD_TestUnitReady;
- scsiq->cdb[1] = scsiq->r1.target_lun << 5;
- scsiq->cdb[2] = 0;
- scsiq->cdb[3] = 0;
- scsiq->cdb[4] = 0;
- scsiq->cdb[5] = 0;
- scsiq->r2.cdb_len = 6;
- return (0);
-}
-
-int
-AscScsiStartStopUnit(
- ASC_DVC_VAR asc_ptr_type * asc_dvc,
- ASC_SCSI_REQ_Q dosfar * scsiq,
- uchar op_mode
-)
-{
- if (AscScsiSetupCmdQ(asc_dvc, scsiq, FNULLPTR, (ulong) 0L) == ERR) {
- return (scsiq->r3.done_stat = QD_WITH_ERROR);
- }
- scsiq->r1.cntl = (uchar) ASC_SCSIDIR_NODATA;
- scsiq->cdb[0] = (uchar) SCSICMD_StartStopUnit;
- scsiq->cdb[1] = scsiq->r1.target_lun << 5;
- scsiq->cdb[2] = 0;
- scsiq->cdb[3] = 0;
- scsiq->cdb[4] = op_mode;
-
- scsiq->cdb[5] = 0;
- scsiq->r2.cdb_len = 6;
- return (0);
-}
diff --git a/i386/i386at/gpl/linux/scsi/advansys.h b/i386/i386at/gpl/linux/scsi/advansys.h
deleted file mode 100644
index 255279ca..00000000
--- a/i386/i386at/gpl/linux/scsi/advansys.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/* $Id: advansys.h,v 1.1.1.1 1997/02/25 21:27:46 thomas Exp $ */
-/*
- * advansys.h - Linux Host Driver for AdvanSys SCSI Adapters
- *
- * Copyright (c) 1995-1996 Advanced System Products, Inc.
- *
- * This driver may be modified and freely distributed provided that
- * the above copyright message and this comment are included in the
- * distribution. The latest version of this driver is available at
- * the AdvanSys FTP and BBS sites listed below.
- *
- * Please send questions, comments, and bug reports to:
- * bobf@advansys.com (Bob Frey)
- */
-
-#ifndef _ADVANSYS_H
-#define _ADVANSYS_H
-
-/* The driver can be used in Linux 1.2.X or 1.3.X. */
-#if !defined(LINUX_1_2) && !defined(LINUX_1_3)
-#ifndef LINUX_VERSION_CODE
-#include <linux/version.h>
-#endif /* LINUX_VERSION_CODE */
-#if LINUX_VERSION_CODE > 65536 + 3 * 256
-#define LINUX_1_3
-#else /* LINUX_VERSION_CODE */
-#define LINUX_1_2
-#endif /* LINUX_VERSION_CODE */
-#endif /* !defined(LINUX_1_2) && !defined(LINUX_1_3) */
-
-/*
- * Scsi_Host_Template function prototypes.
- */
-int advansys_detect(Scsi_Host_Template *);
-int advansys_release(struct Scsi_Host *);
-const char *advansys_info(struct Scsi_Host *);
-int advansys_command(Scsi_Cmnd *);
-int advansys_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
-int advansys_abort(Scsi_Cmnd *);
-int advansys_reset(Scsi_Cmnd *);
-#ifdef LINUX_1_2
-int advansys_biosparam(Disk *, int, int[]);
-#else /* LINUX_1_3 */
-int advansys_biosparam(Disk *, kdev_t, int[]);
-extern struct proc_dir_entry proc_scsi_advansys;
-int advansys_proc_info(char *, char **, off_t, int, int, int);
-#endif /* LINUX_1_3 */
-
-/* init/main.c setup function */
-void advansys_setup(char *, int *);
-
-/*
- * AdvanSys Host Driver Scsi_Host_Template (struct SHT) from hosts.h.
- */
-#ifdef LINUX_1_2
-#define ADVANSYS { \
- NULL, /* struct SHT *next */ \
- NULL, /* int *usage_count */ \
- "advansys", /* char *name */ \
- advansys_detect, /* int (*detect)(struct SHT *) */ \
- advansys_release, /* int (*release)(struct Scsi_Host *) */ \
- advansys_info, /* const char *(*info)(struct Scsi_Host *) */ \
- advansys_command, /* int (*command)(Scsi_Cmnd *) */ \
- advansys_queuecommand, \
- /* int (*queuecommand)(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)) */ \
- advansys_abort, /* int (*abort)(Scsi_Cmnd *) */ \
- advansys_reset, /* int (*reset)(Scsi_Cmnd *) */ \
- NULL, /* int (*slave_attach)(int, int) */ \
- advansys_biosparam, /* int (* bios_param)(Disk *, int, int []) */ \
- /* \
- * The following fields are set per adapter in advansys_detect(). \
- */ \
- 0, /* int can_queue */ \
- 0, /* int this_id */ \
- 0, /* short unsigned int sg_tablesize */ \
- 0, /* short cmd_per_lun */ \
- 0, /* unsigned char present */ \
- /* \
- * Because the driver may control an ISA adapter 'unchecked_isa_dma' \
- * must be set. The flag will be cleared in advansys_detect for non-ISA \
- * adapters. Refer to the comment in scsi_module.c for more information. \
- */ \
- 1, /* unsigned unchecked_isa_dma:1 */ \
- /* \
- * All adapters controlled by this driver are capable of large \
- * scatter-gather lists. This apparently obviates any performance
- * gain provided by setting 'use_clustering'. \
- */ \
- DISABLE_CLUSTERING, /* unsigned use_clustering:1 */ \
-}
-#else /* LINUX_1_3 */
-#define ADVANSYS { \
- NULL, /* struct SHT *next */ \
- NULL, /* long *usage_count */ \
- &proc_scsi_advansys, /* struct proc_dir_entry *proc_dir */ \
- advansys_proc_info, \
- /* int (*proc_info)(char *, char **, off_t, int, int, int) */ \
- "advansys", /* const char *name */ \
- advansys_detect, /* int (*detect)(struct SHT *) */ \
- advansys_release, /* int (*release)(struct Scsi_Host *) */ \
- advansys_info, /* const char *(*info)(struct Scsi_Host *) */ \
- advansys_command, /* int (*command)(Scsi_Cmnd *) */ \
- advansys_queuecommand, \
- /* int (*queuecommand)(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)) */ \
- advansys_abort, /* int (*abort)(Scsi_Cmnd *) */ \
- advansys_reset, /* int (*reset)(Scsi_Cmnd *) */ \
- NULL, /* int (*slave_attach)(int, int) */ \
- advansys_biosparam, /* int (* bios_param)(Disk *, kdev_t, int []) */ \
- /* \
- * The following fields are set per adapter in advansys_detect(). \
- */ \
- 0, /* int can_queue */ \
- 0, /* int this_id */ \
- 0, /* short unsigned int sg_tablesize */ \
- 0, /* short cmd_per_lun */ \
- 0, /* unsigned char present */ \
- /* \
- * Because the driver may control an ISA adapter 'unchecked_isa_dma' \
- * must be set. The flag will be cleared in advansys_detect for non-ISA \
- * adapters. Refer to the comment in scsi_module.c for more information. \
- */ \
- 1, /* unsigned unchecked_isa_dma:1 */ \
- /* \
- * All adapters controlled by this driver are capable of large \
- * scatter-gather lists. This apparently obviates any performance
- * gain provided by setting 'use_clustering'. \
- */ \
- DISABLE_CLUSTERING, /* unsigned use_clustering:1 */ \
-}
-#endif /* LINUX_1_3 */
-#endif /* _ADVANSYS_H */
diff --git a/i386/i386at/gpl/linux/scsi/aha152x.c b/i386/i386at/gpl/linux/scsi/aha152x.c
deleted file mode 100644
index 67dcd102..00000000
--- a/i386/i386at/gpl/linux/scsi/aha152x.c
+++ /dev/null
@@ -1,2985 +0,0 @@
-/* aha152x.c -- Adaptec AHA-152x driver
- * Author: Juergen E. Fischer, fischer@et-inf.fho-emden.de
- * Copyright 1993, 1994, 1995 Juergen E. Fischer
- *
- *
- * This driver is based on
- * fdomain.c -- Future Domain TMC-16x0 driver
- * which is
- * Copyright 1992, 1993 Rickard E. Faith (faith@cs.unc.edu)
- *
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- *
- * $Id: aha152x.c,v 1.1.1.1 1997/02/25 21:27:46 thomas Exp $
- *
- * $Log: aha152x.c,v $
- * Revision 1.1.1.1 1996/10/30 01:40:01 thomas
- * Imported from UK22
- *
- * Revision 1.1 1996/03/25 20:25:17 goel
- * Linux driver merge.
- *
- * Revision 1.14 1996/01/17 15:11:20 fischer
- * - fixed lockup in MESSAGE IN phase after reconnection
- *
- * Revision 1.13 1996/01/09 02:15:53 fischer
- * - some cleanups
- * - moved request_irq behind controller initialization
- * (to avoid spurious interrupts)
- *
- * Revision 1.12 1995/12/16 12:26:07 fischer
- * - barrier()'s added
- * - configurable RESET delay added
- *
- * Revision 1.11 1995/12/06 21:18:35 fischer
- * - some minor updates
- *
- * Revision 1.10 1995/07/22 19:18:45 fischer
- * - support for 2 controllers
- * - started synchronous data transfers (not working yet)
- *
- * Revision 1.9 1995/03/18 09:20:24 root
- * - patches for PCMCIA and modules
- *
- * Revision 1.8 1995/01/21 22:07:19 root
- * - snarf_region => request_region
- * - aha152x_intr interface change
- *
- * Revision 1.7 1995/01/02 23:19:36 root
- * - updated COMMAND_SIZE to cmd_len
- * - changed sti() to restore_flags()
- * - fixed some #ifdef which generated warnings
- *
- * Revision 1.6 1994/11/24 20:35:27 root
- * - problem with odd number of bytes in fifo fixed
- *
- * Revision 1.5 1994/10/30 14:39:56 root
- * - abort code fixed
- * - debugging improved
- *
- * Revision 1.4 1994/09/12 11:33:01 root
- * - irqaction to request_irq
- * - abortion updated
- *
- * Revision 1.3 1994/08/04 13:53:05 root
- * - updates for mid-level-driver changes
- * - accept unexpected BUSFREE phase as error condition
- * - parity check now configurable
- *
- * Revision 1.2 1994/07/03 12:56:36 root
- * - cleaned up debugging code
- * - more tweaking on reset delays
- * - updated abort/reset code (pretty untested...)
- *
- * Revision 1.1 1994/05/28 21:18:49 root
- * - update for mid-level interface change (abort-reset)
- * - delays after resets adjusted for some slow devices
- *
- * Revision 1.0 1994/03/25 12:52:00 root
- * - Fixed "more data than expected" problem
- * - added new BIOS signatures
- *
- * Revision 0.102 1994/01/31 20:44:12 root
- * - minor changes in insw/outsw handling
- *
- * Revision 0.101 1993/12/13 01:16:27 root
- * - fixed STATUS phase (non-GOOD stati were dropped sometimes;
- * fixes problems with CD-ROM sector size detection & media change)
- *
- * Revision 0.100 1993/12/10 16:58:47 root
- * - fix for unsuccessful selections in case of non-continuous id assignments
- * on the scsi bus.
- *
- * Revision 0.99 1993/10/24 16:19:59 root
- * - fixed DATA IN (rare read errors gone)
- *
- * Revision 0.98 1993/10/17 12:54:44 root
- * - fixed some recent fixes (shame on me)
- * - moved initialization of scratch area to aha152x_queue
- *
- * Revision 0.97 1993/10/09 18:53:53 root
- * - DATA IN fixed. Rarely left data in the fifo.
- *
- * Revision 0.96 1993/10/03 00:53:59 root
- * - minor changes on DATA IN
- *
- * Revision 0.95 1993/09/24 10:36:01 root
- * - change handling of MSGI after reselection
- * - fixed sti/cli
- * - minor changes
- *
- * Revision 0.94 1993/09/18 14:08:22 root
- * - fixed bug in multiple outstanding command code
- * - changed detection
- * - support for kernel command line configuration
- * - reset corrected
- * - changed message handling
- *
- * Revision 0.93 1993/09/15 20:41:19 root
- * - fixed bugs with multiple outstanding commands
- *
- * Revision 0.92 1993/09/13 02:46:33 root
- * - multiple outstanding commands work (no problems with IBM drive)
- *
- * Revision 0.91 1993/09/12 20:51:46 root
- * added multiple outstanding commands
- * (some problem with this $%&? IBM device remain)
- *
- * Revision 0.9 1993/09/12 11:11:22 root
- * - corrected auto-configuration
- * - changed the auto-configuration (added some '#define's)
- * - added support for dis-/reconnection
- *
- * Revision 0.8 1993/09/06 23:09:39 root
- * - added support for the drive activity light
- * - minor changes
- *
- * Revision 0.7 1993/09/05 14:30:15 root
- * - improved phase detection
- * - now using the new snarf_region code of 0.99pl13
- *
- * Revision 0.6 1993/09/02 11:01:38 root
- * first public release; added some signatures and biosparam()
- *
- * Revision 0.5 1993/08/30 10:23:30 root
- * fixed timing problems with my IBM drive
- *
- * Revision 0.4 1993/08/29 14:06:52 root
- * fixed some problems with timeouts due incomplete commands
- *
- * Revision 0.3 1993/08/28 15:55:03 root
- * writing data works too. mounted and worked on a dos partition
- *
- * Revision 0.2 1993/08/27 22:42:07 root
- * reading data works. Mounted a msdos partition.
- *
- * Revision 0.1 1993/08/25 13:38:30 root
- * first "damn thing doesn't work" version
- *
- * Revision 0.0 1993/08/14 19:54:25 root
- * empty function bodies; detect() works.
- *
- *
- **************************************************************************
-
-
-
- DESCRIPTION:
-
- This is the Linux low-level SCSI driver for Adaptec AHA-1520/1522
- SCSI host adapters.
-
-
- PER-DEFINE CONFIGURABLE OPTIONS:
-
- AUTOCONF:
- use configuration the controller reports (only 152x)
-
- SKIP_BIOSTEST:
- Don't test for BIOS signature (AHA-1510 or disabled BIOS)
-
- SETUP0 { IOPORT, IRQ, SCSI_ID, RECONNECT, PARITY, SYNCHRONOUS, DELAY }:
- override for the first controller
-
- SETUP1 { IOPORT, IRQ, SCSI_ID, RECONNECT, PARITY, SYNCHRONOUS, DELAY }:
- override for the second controller
-
-
- LILO COMMAND LINE OPTIONS:
-
- aha152x=<IOPORT>[,<IRQ>[,<SCSI-ID>[,<RECONNECT>[,<PARITY>[,<SYNCHRONOUS>[,<DELAY>]]]]]]
-
- The normal configuration can be overridden by specifying a command line.
- When you do this, the BIOS test is skipped. Entered values have to be
- valid (known). Don't use values that aren't supported under normal operation.
- If you think that you need other values: contact me. For two controllers
- use the aha152x statement twice.
-
-
- REFERENCES USED:
-
- "AIC-6260 SCSI Chip Specification", Adaptec Corporation.
-
- "SCSI COMPUTER SYSTEM INTERFACE - 2 (SCSI-2)", X3T9.2/86-109 rev. 10h
-
- "Writing a SCSI device driver for Linux", Rik Faith (faith@cs.unc.edu)
-
- "Kernel Hacker's Guide", Michael K. Johnson (johnsonm@sunsite.unc.edu)
-
- "Adaptec 1520/1522 User's Guide", Adaptec Corporation.
-
- Michael K. Johnson (johnsonm@sunsite.unc.edu)
-
- Drew Eckhardt (drew@cs.colorado.edu)
-
- Eric Youngdale (ericy@cais.com)
-
- special thanks to Eric Youngdale for the free(!) supplying the
- documentation on the chip.
-
- **************************************************************************/
-
-#ifdef PCMCIA
-#define MODULE
-#endif
-
-#include <linux/module.h>
-
-#ifdef PCMCIA
-#undef MODULE
-#endif
-
-#include <linux/sched.h>
-#include <asm/io.h>
-#include <linux/blk.h>
-#include "scsi.h"
-#include "sd.h"
-#include "hosts.h"
-#include "constants.h"
-#include <asm/system.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/wait.h>
-#include <linux/ioport.h>
-#include <linux/proc_fs.h>
-
-#include "aha152x.h"
-#include <linux/stat.h>
-
-struct proc_dir_entry proc_scsi_aha152x = {
- PROC_SCSI_AHA152X, 7, "aha152x",
- S_IFDIR | S_IRUGO | S_IXUGO, 2
-};
-
-/* DEFINES */
-
-#ifdef MACH
-#define AUTOCONF
-#endif
-
-/* For PCMCIA cards, always use AUTOCONF */
-#if defined(PCMCIA) || defined(MODULE)
-#if !defined(AUTOCONF)
-#define AUTOCONF
-#endif
-#endif
-
-#if !defined(AUTOCONF) && !defined(SETUP0)
-#error define AUTOCONF or SETUP0
-#endif
-
-#if defined(DEBUG_AHA152X)
-
-#undef SKIP_PORTS /* don't display ports */
-
-#undef DEBUG_QUEUE /* debug queue() */
-#undef DEBUG_RESET /* debug reset() */
-#undef DEBUG_INTR /* debug intr() */
-#undef DEBUG_SELECTION /* debug selection part in intr() */
-#undef DEBUG_MSGO /* debug message out phase in intr() */
-#undef DEBUG_MSGI /* debug message in phase in intr() */
-#undef DEBUG_STATUS /* debug status phase in intr() */
-#undef DEBUG_CMD /* debug command phase in intr() */
-#undef DEBUG_DATAI /* debug data in phase in intr() */
-#undef DEBUG_DATAO /* debug data out phase in intr() */
-#undef DEBUG_ABORT /* debug abort() */
-#undef DEBUG_DONE /* debug done() */
-#undef DEBUG_BIOSPARAM /* debug biosparam() */
-
-#undef DEBUG_RACE /* debug race conditions */
-#undef DEBUG_PHASES /* debug phases (useful to trace) */
-#undef DEBUG_QUEUES /* debug reselection */
-
-/* recently used for debugging */
-#if 0
-#endif
-
-#define DEBUG_SELECTION
-#define DEBUG_PHASES
-#define DEBUG_RESET
-#define DEBUG_ABORT
-
-#define DEBUG_DEFAULT (debug_reset|debug_abort)
-
-#endif
-
-/* END OF DEFINES */
-
-extern long loops_per_sec;
-
-#define DELAY_DEFAULT 100
-
-/* some additional "phases" for getphase() */
-#define P_BUSFREE 1
-#define P_PARITY 2
-
-/* possible irq range */
-#define IRQ_MIN 9
-#define IRQ_MAX 12
-#define IRQS IRQ_MAX-IRQ_MIN+1
-
-enum {
- not_issued = 0x0001,
- in_selection = 0x0002,
- disconnected = 0x0004,
- aborted = 0x0008,
- sent_ident = 0x0010,
- in_other = 0x0020,
- in_sync = 0x0040,
- sync_ok = 0x0080,
-};
-
-/* set by aha152x_setup according to the command line */
-static int setup_count=0;
-static struct aha152x_setup {
- int io_port;
- int irq;
- int scsiid;
- int reconnect;
- int parity;
- int synchronous;
- int delay;
-#ifdef DEBUG_AHA152X
- int debug;
-#endif
- char *conf;
-} setup[2];
-
-static struct Scsi_Host *aha152x_host[IRQS];
-
-#define HOSTDATA(shpnt) ((struct aha152x_hostdata *) &shpnt->hostdata)
-#define CURRENT_SC (HOSTDATA(shpnt)->current_SC)
-#define ISSUE_SC (HOSTDATA(shpnt)->issue_SC)
-#define DISCONNECTED_SC (HOSTDATA(shpnt)->disconnected_SC)
-#define DELAY (HOSTDATA(shpnt)->delay)
-#define SYNCRATE (HOSTDATA(shpnt)->syncrate[CURRENT_SC->target])
-#define MSG(i) (HOSTDATA(shpnt)->message[i])
-#define MSGLEN (HOSTDATA(shpnt)->message_len)
-#define ADDMSG(x) (MSG(MSGLEN++)=x)
-
-struct aha152x_hostdata {
- Scsi_Cmnd *issue_SC;
- Scsi_Cmnd *current_SC;
- Scsi_Cmnd *disconnected_SC;
- int aborting;
- int abortion_complete;
- int abort_result;
- int commands;
-
- int reconnect;
- int parity;
- int synchronous;
- int delay;
-
- unsigned char syncrate[8];
-
- unsigned char message[256];
- int message_len;
-
-#ifdef DEBUG_AHA152X
- int debug;
-#endif
-};
-
-void aha152x_intr(int irq, struct pt_regs *);
-void aha152x_done(struct Scsi_Host *shpnt, int error);
-void aha152x_setup(char *str, int *ints);
-int aha152x_checksetup(struct aha152x_setup *setup);
-
-static void aha152x_reset_ports(struct Scsi_Host *shpnt);
-static void aha152x_panic(struct Scsi_Host *shpnt, char *msg);
-
-static void disp_ports(struct Scsi_Host *shpnt);
-static void show_command(Scsi_Cmnd *ptr);
-static void show_queues(struct Scsi_Host *shpnt);
-static void disp_enintr(struct Scsi_Host *shpnt);
-
-#if defined(DEBUG_RACE)
-static void enter_driver(const char *);
-static void leave_driver(const char *);
-#endif
-
-/* possible i/o addresses for the AIC-6260 */
-static unsigned short ports[] =
-{
- 0x340, /* default first */
- 0x140
-};
-#define PORT_COUNT (sizeof(ports) / sizeof(unsigned short))
-
-#if !defined(SKIP_BIOSTEST)
-/* possible locations for the Adaptec BIOS */
-static void *addresses[] =
-{
- (void *) 0xdc000, /* default first */
- (void *) 0xc8000,
- (void *) 0xcc000,
- (void *) 0xd0000,
- (void *) 0xd4000,
- (void *) 0xd8000,
- (void *) 0xe0000,
- (void *) 0xeb800, /* VTech Platinum SMP */
- (void *) 0xf0000,
-};
-#define ADDRESS_COUNT (sizeof(addresses) / sizeof(void *))
-
-/* signatures for various AIC-6[23]60 based controllers.
- The point in detecting signatures is to avoid useless
- and maybe harmful probes on ports. I'm not sure that
- all listed boards pass auto-configuration. For those
- which fail the BIOS signature is obsolete, because
- user intervention to supply the configuration is
- needed anyway. */
-static struct signature {
- char *signature;
- int sig_offset;
- int sig_length;
-} signatures[] =
-{
- { "Adaptec AHA-1520 BIOS", 0x102e, 21 }, /* Adaptec 152x */
- { "Adaptec ASW-B626 BIOS", 0x1029, 21 }, /* on-board controller */
- { "Adaptec BIOS: ASW-B626", 0x0f, 22 }, /* on-board controller */
- { "Adaptec ASW-B626 S2", 0x2e6c, 19 }, /* on-board controller */
- { "Adaptec BIOS:AIC-6360", 0xc, 21 }, /* on-board controller */
- { "ScsiPro SP-360 BIOS", 0x2873, 19 }, /* ScsiPro-Controller */
- { "GA-400 LOCAL BUS SCSI BIOS", 0x102e, 26 }, /* Gigabyte Local-Bus-SCSI */
- { "Adaptec BIOS:AVA-282X", 0xc, 21 }, /* Adaptec 282x */
- { "Adaptec IBM Dock II SCSI", 0x2edd, 24 }, /* IBM Thinkpad Dock II */
- { "Adaptec BIOS:AHA-1532P", 0x1c, 22 }, /* IBM Thinkpad Dock II SCSI */
-};
-#define SIGNATURE_COUNT (sizeof(signatures) / sizeof(struct signature))
-#endif
-
-
-static void do_pause(unsigned amount) /* Pause for amount*10 milliseconds */
-{
- unsigned long the_time = jiffies + amount; /* 0.01 seconds per jiffy */
-
- while (jiffies < the_time)
- barrier();
-}
-
-/*
- * queue services:
- */
-static inline void append_SC(Scsi_Cmnd **SC, Scsi_Cmnd *new_SC)
-{
- Scsi_Cmnd *end;
-
- new_SC->host_scribble = (unsigned char *) NULL;
- if(!*SC)
- *SC=new_SC;
- else
- {
- for(end=*SC; end->host_scribble; end = (Scsi_Cmnd *) end->host_scribble)
- ;
- end->host_scribble = (unsigned char *) new_SC;
- }
-}
-
-static inline Scsi_Cmnd *remove_first_SC(Scsi_Cmnd **SC)
-{
- Scsi_Cmnd *ptr;
-
- ptr=*SC;
- if(ptr)
- *SC= (Scsi_Cmnd *) (*SC)->host_scribble;
- return ptr;
-}
-
-static inline Scsi_Cmnd *remove_SC(Scsi_Cmnd **SC, int target, int lun)
-{
- Scsi_Cmnd *ptr, *prev;
-
- for(ptr=*SC, prev=NULL;
- ptr && ((ptr->target!=target) || (ptr->lun!=lun));
- prev = ptr, ptr = (Scsi_Cmnd *) ptr->host_scribble)
- ;
-
- if(ptr)
- if(prev)
- prev->host_scribble = ptr->host_scribble;
- else
- *SC= (Scsi_Cmnd *) ptr->host_scribble;
- return ptr;
-}
-
-/*
- * read inbound byte and wait for ACK to get low
- */
-static void make_acklow(struct Scsi_Host *shpnt)
-{
- SETPORT(SXFRCTL0, CH1|SPIOEN);
- GETPORT(SCSIDAT);
- SETPORT(SXFRCTL0, CH1);
-
- while(TESTHI(SCSISIG, ACKI))
- barrier();
-}
-
-/*
- * detect current phase more reliable:
- * phase is valid, when the target asserts REQ after we've deasserted ACK.
- *
- * return value is a valid phase or an error code.
- *
- * errorcodes:
- * P_BUSFREE BUS FREE phase detected
- * P_PARITY parity error in DATA phase
- */
-static int getphase(struct Scsi_Host *shpnt)
-{
- int phase, sstat1;
-
- while(1)
- {
- do
- {
- while(!((sstat1 = GETPORT(SSTAT1)) & (BUSFREE|SCSIRSTI|REQINIT)))
- barrier();
- if(sstat1 & BUSFREE)
- return P_BUSFREE;
- if(sstat1 & SCSIRSTI)
- {
- printk("aha152x: RESET IN\n");
- SETPORT(SSTAT1, SCSIRSTI);
- }
- }
- while(TESTHI(SCSISIG, ACKI) || TESTLO(SSTAT1, REQINIT));
-
- SETPORT(SSTAT1, CLRSCSIPERR);
-
- phase = GETPORT(SCSISIG) & P_MASK ;
-
- if(TESTHI(SSTAT1, SCSIPERR))
- {
- if((phase & (CDO|MSGO))==0) /* DATA phase */
- return P_PARITY;
-
- make_acklow(shpnt);
- }
- else
- return phase;
- }
-}
-
-/* called from init/main.c */
-void aha152x_setup(char *str, int *ints)
-{
- if(setup_count>2)
- panic("aha152x: you can only configure up to two controllers\n");
-
- setup[setup_count].conf = str;
- setup[setup_count].io_port = ints[0] >= 1 ? ints[1] : 0x340;
- setup[setup_count].irq = ints[0] >= 2 ? ints[2] : 11;
- setup[setup_count].scsiid = ints[0] >= 3 ? ints[3] : 7;
- setup[setup_count].reconnect = ints[0] >= 4 ? ints[4] : 1;
- setup[setup_count].parity = ints[0] >= 5 ? ints[5] : 1;
- setup[setup_count].synchronous = ints[0] >= 6 ? ints[6] : 0 /* FIXME: 1 */;
- setup[setup_count].delay = ints[0] >= 7 ? ints[7] : DELAY_DEFAULT;
-#ifdef DEBUG_AHA152X
- setup[setup_count].debug = ints[0] >= 8 ? ints[8] : DEBUG_DEFAULT;
- if(ints[0]>8)
- {
- printk("aha152x: usage: aha152x=<IOBASE>[,<IRQ>[,<SCSI ID>"
- "[,<RECONNECT>[,<PARITY>[,<SYNCHRONOUS>[,<DELAY>[,<DEBUG>]]]]]]]\n");
-#else
- if(ints[0]>7)
- {
- printk("aha152x: usage: aha152x=<IOBASE>[,<IRQ>[,<SCSI ID>"
- "[,<RECONNECT>[,<PARITY>[,<SYNCHRONOUS>[,<DELAY>]]]]]]\n");
-#endif
- }
- else
- setup_count++;
-}
-
-/*
- Test, if port_base is valid.
- */
-static int aha152x_porttest(int io_port)
-{
- int i;
-
- if(check_region(io_port, IO_RANGE))
- return 0;
-
- SETPORT(io_port+O_DMACNTRL1, 0); /* reset stack pointer */
- for(i=0; i<16; i++)
- SETPORT(io_port+O_STACK, i);
-
- SETPORT(io_port+O_DMACNTRL1, 0); /* reset stack pointer */
- for(i=0; i<16 && GETPORT(io_port+O_STACK)==i; i++)
- ;
-
- return(i==16);
-}
-
-int aha152x_checksetup(struct aha152x_setup *setup)
-{
- int i;
-
-#ifndef PCMCIA
- for(i=0; i<PORT_COUNT && (setup->io_port != ports[i]); i++)
- ;
-
- if(i==PORT_COUNT)
- return 0;
-#endif
-
- if(!aha152x_porttest(setup->io_port))
- return 0;
-
- if((setup->irq < IRQ_MIN) && (setup->irq > IRQ_MAX))
- return 0;
-
- if((setup->scsiid < 0) || (setup->scsiid > 7))
- return 0;
-
- if((setup->reconnect < 0) || (setup->reconnect > 1))
- return 0;
-
- if((setup->parity < 0) || (setup->parity > 1))
- return 0;
-
- if((setup->synchronous < 0) || (setup->synchronous > 1))
- return 0;
-
- return 1;
-}
-
-
-int aha152x_detect(Scsi_Host_Template * tpnt)
-{
- int i, j, ok;
-#if defined(AUTOCONF)
- aha152x_config conf;
-#endif
-
- tpnt->proc_dir = &proc_scsi_aha152x;
-
- for(i=0; i<IRQS; i++)
- aha152x_host[i] = (struct Scsi_Host *) NULL;
-
- if(setup_count)
- {
- printk("aha152x: processing commandline: ");
-
- for(i=0; i<setup_count; i++)
- if(!aha152x_checksetup(&setup[i]))
- {
- printk("\naha152x: %s\n", setup[i].conf);
- printk("aha152x: invalid line (controller=%d)\n", i+1);
- }
-
- printk("ok\n");
- }
-
-#ifdef SETUP0
- if(setup_count<2)
- {
- struct aha152x_setup override = SETUP0;
-
- if(setup_count==0 || (override.io_port != setup[0].io_port))
- if(!aha152x_checksetup(&override))
- {
- printk("\naha152x: SETUP0 (0x%x, %d, %d, %d, %d, %d, %d) invalid\n",
- override.io_port,
- override.irq,
- override.scsiid,
- override.reconnect,
- override.parity,
- override.synchronous,
- override.delay);
- }
- else
- setup[setup_count++] = override;
- }
-#endif
-
-#ifdef SETUP1
- if(setup_count<2)
- {
- struct aha152x_setup override = SETUP1;
-
- if(setup_count==0 || (override.io_port != setup[0].io_port))
- if(!aha152x_checksetup(&override))
- {
- printk("\naha152x: SETUP1 (0x%x, %d, %d, %d, %d, %d, %d) invalid\n",
- override.io_port,
- override.irq,
- override.scsiid,
- override.reconnect,
- override.parity,
- override.synchronous,
- override.delay);
- }
- else
- setup[setup_count++] = override;
- }
-#endif
-
-#if defined(AUTOCONF)
- if(setup_count<2)
- {
-#if !defined(SKIP_BIOSTEST)
- ok=0;
- for(i=0; i < ADDRESS_COUNT && !ok; i++)
- for(j=0; (j < SIGNATURE_COUNT) && !ok; j++)
- ok=!memcmp((void *) addresses[i]+signatures[j].sig_offset,
- (void *) signatures[j].signature,
- (int) signatures[j].sig_length);
-
- if(!ok && setup_count==0)
- return 0;
-
- printk("aha152x: BIOS test: passed, ");
-#else
- printk("aha152x: ");
-#endif /* !SKIP_BIOSTEST */
-
- for(i=0; i<PORT_COUNT && setup_count<2; i++)
- {
- if((setup_count==1) && (setup[0].io_port == ports[i]))
- continue;
-
- if(aha152x_porttest(ports[i]))
- {
- setup[setup_count].io_port = ports[i];
-
- conf.cf_port =
- (GETPORT(ports[i]+O_PORTA)<<8) + GETPORT(ports[i]+O_PORTB);
-
- setup[setup_count].irq = IRQ_MIN + conf.cf_irq;
- setup[setup_count].scsiid = conf.cf_id;
- setup[setup_count].reconnect = conf.cf_tardisc;
- setup[setup_count].parity = !conf.cf_parity;
- setup[setup_count].synchronous = 0 /* FIXME: conf.cf_syncneg */;
- setup[setup_count].delay = DELAY_DEFAULT;
-#ifdef DEBUG_AHA152X
- setup[setup_count].debug = DEBUG_DEFAULT;
-#endif
- setup_count++;
- }
- }
-
- printk("auto configuration: ok, ");
- }
-#endif
-
- printk("detection complete\n");
-
- for(i=0; i<setup_count; i++)
- {
- struct Scsi_Host *shpnt;
-
- shpnt = aha152x_host[setup[i].irq-IRQ_MIN] =
- scsi_register(tpnt, sizeof(struct aha152x_hostdata));
-
- shpnt->io_port = setup[i].io_port;
- shpnt->n_io_port = IO_RANGE;
- shpnt->irq = setup[i].irq;
-
- ISSUE_SC = (Scsi_Cmnd *) NULL;
- CURRENT_SC = (Scsi_Cmnd *) NULL;
- DISCONNECTED_SC = (Scsi_Cmnd *) NULL;
-
- HOSTDATA(shpnt)->reconnect = setup[i].reconnect;
- HOSTDATA(shpnt)->parity = setup[i].parity;
- HOSTDATA(shpnt)->synchronous = setup[i].synchronous;
- HOSTDATA(shpnt)->delay = setup[i].delay;
-#ifdef DEBUG_AHA152X
- HOSTDATA(shpnt)->debug = setup[i].debug;
-#endif
-
- HOSTDATA(shpnt)->aborting = 0;
- HOSTDATA(shpnt)->abortion_complete = 0;
- HOSTDATA(shpnt)->abort_result = 0;
- HOSTDATA(shpnt)->commands = 0;
-
- HOSTDATA(shpnt)->message_len = 0;
-
- for(j=0; j<8; j++)
- HOSTDATA(shpnt)->syncrate[j] = 0;
-
- SETPORT(SCSIID, setup[i].scsiid << 4);
- shpnt->this_id=setup[i].scsiid;
-
- if(setup[i].reconnect)
- shpnt->hostt->can_queue=AHA152X_MAXQUEUE;
-
- /* RESET OUT */
- SETBITS(SCSISEQ, SCSIRSTO);
- do_pause(30);
- CLRBITS(SCSISEQ, SCSIRSTO);
- do_pause(setup[i].delay);
-
- aha152x_reset_ports(shpnt);
-
- printk("aha152x%d: vital data: PORTBASE=0x%03x, IRQ=%d, SCSI ID=%d,"
- " reconnect=%s, parity=%s, synchronous=%s, delay=%d\n",
- i,
- shpnt->io_port,
- shpnt->irq,
- shpnt->this_id,
- HOSTDATA(shpnt)->reconnect ? "enabled" : "disabled",
- HOSTDATA(shpnt)->parity ? "enabled" : "disabled",
- HOSTDATA(shpnt)->synchronous ? "enabled" : "disabled",
- HOSTDATA(shpnt)->delay);
-
- request_region(shpnt->io_port, IO_RANGE, "aha152x"); /* Register */
-
- /* not expecting any interrupts */
- SETPORT(SIMODE0, 0);
- SETPORT(SIMODE1, 0);
-
- SETBITS(DMACNTRL0, INTEN);
-
- ok = request_irq(setup[i].irq, aha152x_intr, SA_INTERRUPT, "aha152x");
-
- if(ok<0)
- {
- if(ok == -EINVAL)
- {
- printk("aha152x%d: bad IRQ %d.\n", i, setup[i].irq);
- printk(" Contact author.\n");
- }
- else
- if(ok == -EBUSY)
- printk("aha152x%d: IRQ %d already in use. Configure another.\n",
- i, setup[i].irq);
- else
- {
- printk("\naha152x%d: Unexpected error code on"
- " requesting IRQ %d.\n", i, setup[i].irq);
- printk(" Contact author.\n");
- }
- printk("aha152x: driver needs an IRQ.\n");
- continue;
- }
- }
-
- return (setup_count>0);
-}
-
-/*
- * Queue a command and setup interrupts for a free bus.
- */
-int aha152x_queue(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
-{
- struct Scsi_Host *shpnt = SCpnt->host;
- unsigned long flags;
-
-#if defined(DEBUG_RACE)
- enter_driver("queue");
-#else
-#if defined(DEBUG_QUEUE)
- if(HOSTDATA(shpnt)->debug & debug_queue)
- printk("aha152x: queue(), ");
-#endif
-#endif
-
-#if defined(DEBUG_QUEUE)
- if(HOSTDATA(shpnt)->debug & debug_queue)
- {
- printk("SCpnt (target = %d lun = %d cmnd = ",
- SCpnt->target, SCpnt->lun);
- print_command(SCpnt->cmnd);
- printk(", cmd_len=%d, pieces = %d size = %u), ",
- SCpnt->cmd_len, SCpnt->use_sg, SCpnt->request_bufflen);
- disp_ports(shpnt);
- }
-#endif
-
- SCpnt->scsi_done = done;
-
- /* setup scratch area
- SCp.ptr : buffer pointer
- SCp.this_residual : buffer length
- SCp.buffer : next buffer
- SCp.buffers_residual : left buffers in list
- SCp.phase : current state of the command */
- SCpnt->SCp.phase = not_issued;
- if (SCpnt->use_sg)
- {
- SCpnt->SCp.buffer =
- (struct scatterlist *) SCpnt->request_buffer;
- SCpnt->SCp.ptr = SCpnt->SCp.buffer->address;
- SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
- SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;
- }
- else
- {
- SCpnt->SCp.ptr = (char *)SCpnt->request_buffer;
- SCpnt->SCp.this_residual = SCpnt->request_bufflen;
- SCpnt->SCp.buffer = NULL;
- SCpnt->SCp.buffers_residual = 0;
- }
-
- SCpnt->SCp.Status = CHECK_CONDITION;
- SCpnt->SCp.Message = 0;
- SCpnt->SCp.have_data_in = 0;
- SCpnt->SCp.sent_command = 0;
-
- /* Turn led on, when this is the first command. */
- save_flags(flags);
- cli();
- HOSTDATA(shpnt)->commands++;
- if(HOSTDATA(shpnt)->commands==1)
- SETPORT(PORTA, 1);
-
-#if defined(DEBUG_QUEUES)
- if(HOSTDATA(shpnt)->debug & debug_queues)
- printk("i+ (%d), ", HOSTDATA(shpnt)->commands);
-#endif
- append_SC(&ISSUE_SC, SCpnt);
-
- /* Enable bus free interrupt, when we aren't currently on the bus */
- if(!CURRENT_SC)
- {
- SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0);
- SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0);
- }
- restore_flags(flags);
-
-#if defined(DEBUG_RACE)
- leave_driver("queue");
-#endif
-
- return 0;
-}
-
-/*
- * We only support commands in interrupt-driven fashion
- */
-int aha152x_command(Scsi_Cmnd *SCpnt)
-{
- printk("aha152x: interrupt driven driver; use aha152x_queue()\n");
- return -1;
-}
-
-/*
- * Abort a queued command
- * (commands that are on the bus can't be aborted easily)
- */
-int aha152x_abort(Scsi_Cmnd *SCpnt)
-{
- struct Scsi_Host *shpnt = SCpnt->host;
- unsigned long flags;
- Scsi_Cmnd *ptr, *prev;
-
- save_flags(flags);
- cli();
-
-#if defined(DEBUG_ABORT)
- if(HOSTDATA(shpnt)->debug & debug_abort)
- {
- printk("aha152x: abort(), SCpnt=0x%08x, ", (unsigned int) SCpnt);
- show_queues(shpnt);
- }
-#endif
-
- /* look for command in issue queue */
- for(ptr=ISSUE_SC, prev=NULL;
- ptr && ptr!=SCpnt;
- prev=ptr, ptr=(Scsi_Cmnd *) ptr->host_scribble)
- ;
-
- if(ptr)
- {
- /* dequeue */
- if(prev)
- prev->host_scribble = ptr->host_scribble;
- else
- ISSUE_SC = (Scsi_Cmnd *) ptr->host_scribble;
- restore_flags(flags);
-
- ptr->host_scribble = NULL;
- ptr->result = DID_ABORT << 16;
- ptr->scsi_done(ptr);
- return SCSI_ABORT_SUCCESS;
- }
-
- /* if the bus is busy or a command is currently processed,
- we can't do anything more */
- if (TESTLO(SSTAT1, BUSFREE) || (CURRENT_SC && CURRENT_SC!=SCpnt))
- {
- /* fail abortion, if bus is busy */
-
- if(!CURRENT_SC)
- printk("bus busy w/o current command, ");
-
- restore_flags(flags);
- return SCSI_ABORT_BUSY;
- }
-
- /* bus is free */
-
- if(CURRENT_SC)
- {
- /* target entered bus free before COMMAND COMPLETE, nothing to abort */
- restore_flags(flags);
- CURRENT_SC->result = DID_ERROR << 16;
- CURRENT_SC->scsi_done(CURRENT_SC);
- CURRENT_SC = (Scsi_Cmnd *) NULL;
- return SCSI_ABORT_SUCCESS;
- }
-
- /* look for command in disconnected queue */
- for(ptr=DISCONNECTED_SC, prev=NULL;
- ptr && ptr!=SCpnt;
- prev=ptr, ptr=(Scsi_Cmnd *) ptr->host_scribble)
- ;
-
- if(ptr)
- if(!HOSTDATA(shpnt)->aborting)
- {
- /* dequeue */
- if(prev)
- prev->host_scribble = ptr->host_scribble;
- else
- DISCONNECTED_SC = (Scsi_Cmnd *) ptr->host_scribble;
-
- /* set command current and initiate selection,
- let the interrupt routine take care of the abortion */
- CURRENT_SC = ptr;
- ptr->SCp.phase = in_selection|aborted;
- SETPORT(SCSIID, (shpnt->this_id << OID_) | CURRENT_SC->target);
-
- ADDMSG(ABORT);
-
- /* enable interrupts for SELECTION OUT DONE and SELECTION TIME OUT */
- SETPORT(SIMODE0, ENSELDO | (DISCONNECTED_SC ? ENSELDI : 0));
- SETPORT(SIMODE1, ENSELTIMO);
-
- /* Enable SELECTION OUT sequence */
- SETBITS(SCSISEQ, ENSELO | ENAUTOATNO);
-
- SETBITS(DMACNTRL0, INTEN);
- HOSTDATA(shpnt)->abort_result=SCSI_ABORT_SUCCESS;
- HOSTDATA(shpnt)->aborting++;
- HOSTDATA(shpnt)->abortion_complete=0;
-
- sti(); /* Hi Eric, guess what ;-) */
-
- /* sleep until the abortion is complete */
- while(!HOSTDATA(shpnt)->abortion_complete)
- barrier();
- HOSTDATA(shpnt)->aborting=0;
- return HOSTDATA(shpnt)->abort_result;
- }
- else
- {
- /* we're already aborting a command */
- restore_flags(flags);
- return SCSI_ABORT_BUSY;
- }
-
- /* command wasn't found */
- printk("command not found\n");
- restore_flags(flags);
- return SCSI_ABORT_NOT_RUNNING;
-}
-
-/*
- * Restore default values to the AIC-6260 registers and reset the fifos
- */
-static void aha152x_reset_ports(struct Scsi_Host *shpnt)
-{
- /* disable interrupts */
- SETPORT(DMACNTRL0, RSTFIFO);
-
- SETPORT(SCSISEQ, 0);
-
- SETPORT(SXFRCTL1, 0);
- SETPORT(SCSISIG, 0);
- SETPORT(SCSIRATE, 0);
-
- /* clear all interrupt conditions */
- SETPORT(SSTAT0, 0x7f);
- SETPORT(SSTAT1, 0xef);
-
- SETPORT(SSTAT4, SYNCERR|FWERR|FRERR);
-
- SETPORT(DMACNTRL0, 0);
- SETPORT(DMACNTRL1, 0);
-
- SETPORT(BRSTCNTRL, 0xf1);
-
- /* clear SCSI fifo and transfer count */
- SETPORT(SXFRCTL0, CH1|CLRCH1|CLRSTCNT);
- SETPORT(SXFRCTL0, CH1);
-
- /* enable interrupts */
- SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0);
- SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0);
-}
-
-/*
- * Reset registers, reset a hanging bus and
- * kill active and disconnected commands for target w/o soft reset
- */
-int aha152x_reset(Scsi_Cmnd *SCpnt)
-{
- struct Scsi_Host *shpnt = SCpnt->host;
- unsigned long flags;
- Scsi_Cmnd *ptr, *prev, *next;
-
- aha152x_reset_ports(shpnt);
-
- /* Reset, if bus hangs */
- if(TESTLO(SSTAT1, BUSFREE))
- {
- CLRBITS(DMACNTRL0, INTEN);
-
-#if defined(DEBUG_RESET)
- if(HOSTDATA(shpnt)->debug & debug_reset)
- {
- printk("aha152x: reset(), bus not free: SCSI RESET OUT\n");
- show_queues(shpnt);
- }
-#endif
-
- ptr=CURRENT_SC;
- if(ptr && !ptr->device->soft_reset)
- {
- ptr->host_scribble = NULL;
- ptr->result = DID_RESET << 16;
- ptr->scsi_done(CURRENT_SC);
- CURRENT_SC=NULL;
- }
-
- save_flags(flags);
- cli();
- prev=NULL; ptr=DISCONNECTED_SC;
- while(ptr)
- {
- if(!ptr->device->soft_reset)
- {
- if(prev)
- prev->host_scribble = ptr->host_scribble;
- else
- DISCONNECTED_SC = (Scsi_Cmnd *) ptr->host_scribble;
-
- next = (Scsi_Cmnd *) ptr->host_scribble;
-
- ptr->host_scribble = NULL;
- ptr->result = DID_RESET << 16;
- ptr->scsi_done(ptr);
-
- ptr = next;
- }
- else
- {
- prev=ptr;
- ptr = (Scsi_Cmnd *) ptr->host_scribble;
- }
- }
- restore_flags(flags);
-
-#if defined(DEBUG_RESET)
- if(HOSTDATA(shpnt)->debug & debug_reset)
- {
- printk("commands on targets w/ soft-resets:\n");
- show_queues(shpnt);
- }
-#endif
-
- /* RESET OUT */
- SETPORT(SCSISEQ, SCSIRSTO);
- do_pause(30);
- SETPORT(SCSISEQ, 0);
- do_pause(DELAY);
-
- SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0);
- SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0);
-
- SETPORT(DMACNTRL0, INTEN);
- }
-
- return SCSI_RESET_SUCCESS;
-}
-
-/*
- * Return the "logical geometry"
- */
-int aha152x_biosparam(Scsi_Disk * disk, kdev_t dev, int *info_array)
-{
- int size = disk->capacity;
-
-#if defined(DEBUG_BIOSPARAM)
- if(HOSTDATA(shpnt)->debug & debug_biosparam)
- printk("aha152x_biosparam: dev=%s, size=%d, ", kdevname(dev), size);
-#endif
-
-/* I took this from other SCSI drivers, since it provides
- the correct data for my devices. */
- info_array[0]=64;
- info_array[1]=32;
- info_array[2]=size>>11;
-
-#if defined(DEBUG_BIOSPARAM)
- if(HOSTDATA(shpnt)->debug & debug_biosparam)
- {
- printk("bios geometry: head=%d, sec=%d, cyl=%d\n",
- info_array[0], info_array[1], info_array[2]);
- printk("WARNING: check, if the bios geometry is correct.\n");
- }
-#endif
-
- return 0;
-}
-
-/*
- * Internal done function
- */
-void aha152x_done(struct Scsi_Host *shpnt, int error)
-{
- unsigned long flags;
- Scsi_Cmnd *done_SC;
-
-#if defined(DEBUG_DONE)
- if(HOSTDATA(shpnt)->debug & debug_done)
- {
- printk("\naha152x: done(), ");
- disp_ports(shpnt);
- }
-#endif
-
- if (CURRENT_SC)
- {
-#if defined(DEBUG_DONE)
- if(HOSTDATA(shpnt)->debug & debug_done)
- printk("done(%x), ", error);
-#endif
-
- save_flags(flags);
- cli();
-
- done_SC = CURRENT_SC;
- CURRENT_SC = NULL;
-
- /* turn led off, when no commands are in the driver */
- HOSTDATA(shpnt)->commands--;
- if(!HOSTDATA(shpnt)->commands)
- SETPORT(PORTA, 0); /* turn led off */
-
-#if defined(DEBUG_QUEUES)
- if(HOSTDATA(shpnt)->debug & debug_queues)
- printk("ok (%d), ", HOSTDATA(shpnt)->commands);
-#endif
- restore_flags(flags);
-
- SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0);
- SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0);
-
-#if defined(DEBUG_PHASES)
- if(HOSTDATA(shpnt)->debug & debug_phases)
- printk("BUS FREE loop, ");
-#endif
- while(TESTLO(SSTAT1, BUSFREE))
- barrier();
-#if defined(DEBUG_PHASES)
- if(HOSTDATA(shpnt)->debug & debug_phases)
- printk("BUS FREE\n");
-#endif
-
- done_SC->result = error;
- if(done_SC->scsi_done)
- {
-#if defined(DEBUG_DONE)
- if(HOSTDATA(shpnt)->debug & debug_done)
- printk("calling scsi_done, ");
-#endif
- done_SC->scsi_done(done_SC);
-#if defined(DEBUG_DONE)
- if(HOSTDATA(shpnt)->debug & debug_done)
- printk("done returned, ");
-#endif
- }
- else
- panic("aha152x: current_SC->scsi_done() == NULL");
- }
- else
- aha152x_panic(shpnt, "done() called outside of command");
-}
-
-/*
- * Interrupts handler (main routine of the driver)
- */
-void aha152x_intr(int irqno, struct pt_regs * regs)
-{
- struct Scsi_Host *shpnt = aha152x_host[irqno-IRQ_MIN];
- unsigned int flags;
- int done=0, phase;
-
-#if defined(DEBUG_RACE)
- enter_driver("intr");
-#else
-#if defined(DEBUG_INTR)
- if(HOSTDATA(shpnt)->debug & debug_intr)
- printk("\naha152x: intr(), ");
-#endif
-#endif
-
- /* no more interrupts from the controller, while we busy.
- INTEN has to be restored, when we're ready to leave
- intr(). To avoid race conditions we have to return
- immediately afterwards. */
- CLRBITS(DMACNTRL0, INTEN);
- sti(); /* Yes, sti() really needs to be here */
-
- /* disconnected target is trying to reconnect.
- Only possible, if we have disconnected nexuses and
- nothing is occupying the bus.
- */
- if(TESTHI(SSTAT0, SELDI) &&
- DISCONNECTED_SC &&
- (!CURRENT_SC || (CURRENT_SC->SCp.phase & in_selection)) )
- {
- int identify_msg, target, i;
-
- /* Avoid conflicts when a target reconnects
- while we are trying to connect to another. */
- if(CURRENT_SC)
- {
-#if defined(DEBUG_QUEUES)
- if(HOSTDATA(shpnt)->debug & debug_queues)
- printk("i+, ");
-#endif
- save_flags(flags);
- cli();
- append_SC(&ISSUE_SC, CURRENT_SC);
- CURRENT_SC=NULL;
- restore_flags(flags);
- }
-
- /* disable sequences */
- SETPORT(SCSISEQ, 0);
- SETPORT(SSTAT0, CLRSELDI);
- SETPORT(SSTAT1, CLRBUSFREE);
-
-#if defined(DEBUG_QUEUES) || defined(DEBUG_PHASES)
- if(HOSTDATA(shpnt)->debug & (debug_queues|debug_phases))
- printk("reselected, ");
-#endif
-
- i = GETPORT(SELID) & ~(1 << shpnt->this_id);
- target=0;
- if(i)
- for(; (i & 1)==0; target++, i>>=1)
- ;
- else
- aha152x_panic(shpnt, "reconnecting target unknown");
-
-#if defined(DEBUG_QUEUES)
- if(HOSTDATA(shpnt)->debug & debug_queues)
- printk("SELID=%02x, target=%d, ", GETPORT(SELID), target);
-#endif
- SETPORT(SCSIID, (shpnt->this_id << OID_) | target);
- SETPORT(SCSISEQ, ENRESELI);
-
- if(TESTLO(SSTAT0, SELDI))
- aha152x_panic(shpnt, "RESELI failed");
-
- SETPORT(SCSIRATE, HOSTDATA(shpnt)->syncrate[target]&0x7f);
-
- SETPORT(SCSISIG, P_MSGI);
-
- /* Get identify message */
- if((i=getphase(shpnt))!=P_MSGI)
- {
- printk("target doesn't enter MSGI to identify (phase=%02x)\n", i);
- aha152x_panic(shpnt, "unknown lun");
- }
- SETPORT(SCSISEQ, 0);
-
- SETPORT(SXFRCTL0, CH1);
-
- identify_msg = GETPORT(SCSIBUS);
-
- if(!(identify_msg & IDENTIFY_BASE))
- {
- printk("target=%d, inbound message (%02x) != IDENTIFY\n",
- target, identify_msg);
- aha152x_panic(shpnt, "unknown lun");
- }
-
-
-#if defined(DEBUG_QUEUES)
- if(HOSTDATA(shpnt)->debug & debug_queues)
- printk("identify=%02x, lun=%d, ", identify_msg, identify_msg & 0x3f);
-#endif
-
- save_flags(flags);
- cli();
-
-#if defined(DEBUG_QUEUES)
- if(HOSTDATA(shpnt)->debug & debug_queues)
- printk("d-, ");
-#endif
- CURRENT_SC = remove_SC(&DISCONNECTED_SC,
- target,
- identify_msg & 0x3f);
-
- if(!CURRENT_SC)
- {
- printk("lun=%d, ", identify_msg & 0x3f);
- aha152x_panic(shpnt, "no disconnected command for that lun");
- }
-
- CURRENT_SC->SCp.phase &= ~disconnected;
- restore_flags(flags);
-
- make_acklow(shpnt);
- if(getphase(shpnt)!=P_MSGI) {
- SETPORT(SIMODE0, 0);
- SETPORT(SIMODE1, ENPHASEMIS|ENBUSFREE);
-#if defined(DEBUG_RACE)
- leave_driver("(reselected) intr");
-#endif
- SETBITS(DMACNTRL0, INTEN);
- return;
- }
- }
-
- /* Check, if we aren't busy with a command */
- if(!CURRENT_SC)
- {
- /* bus is free to issue a queued command */
- if(TESTHI(SSTAT1, BUSFREE) && ISSUE_SC)
- {
- save_flags(flags);
- cli();
-#if defined(DEBUG_QUEUES)
- if(HOSTDATA(shpnt)->debug & debug_queues)
- printk("i-, ");
-#endif
- CURRENT_SC = remove_first_SC(&ISSUE_SC);
- restore_flags(flags);
-
-#if defined(DEBUG_INTR) || defined(DEBUG_SELECTION) || defined(DEBUG_PHASES)
- if(HOSTDATA(shpnt)->debug & (debug_intr|debug_selection|debug_phases))
- printk("issuing command, ");
-#endif
- CURRENT_SC->SCp.phase = in_selection;
-
-#if defined(DEBUG_INTR) || defined(DEBUG_SELECTION) || defined(DEBUG_PHASES)
- if(HOSTDATA(shpnt)->debug & (debug_intr|debug_selection|debug_phases))
- printk("selecting %d, ", CURRENT_SC->target);
-#endif
- SETPORT(SCSIID, (shpnt->this_id << OID_) | CURRENT_SC->target);
-
- /* Enable interrupts for SELECTION OUT DONE and SELECTION OUT INITIATED */
- SETPORT(SXFRCTL1, HOSTDATA(shpnt)->parity ? (ENSPCHK|ENSTIMER) : ENSTIMER);
-
- /* enable interrupts for SELECTION OUT DONE and SELECTION TIME OUT */
- SETPORT(SIMODE0, ENSELDO | (DISCONNECTED_SC ? ENSELDI : 0));
- SETPORT(SIMODE1, ENSELTIMO);
-
- /* Enable SELECTION OUT sequence */
- SETBITS(SCSISEQ, ENSELO | ENAUTOATNO);
-
- }
- else
- {
- /* No command we are busy with and no new to issue */
- printk("aha152x: ignoring spurious interrupt, nothing to do\n");
- if(TESTHI(DMACNTRL0, SWINT)) {
- printk("aha152x: SWINT is set! Why?\n");
- CLRBITS(DMACNTRL0, SWINT);
- }
- show_queues(shpnt);
- }
-
-#if defined(DEBUG_RACE)
- leave_driver("(selecting) intr");
-#endif
- SETBITS(DMACNTRL0, INTEN);
- return;
- }
-
- /* the bus is busy with something */
-
-#if defined(DEBUG_INTR)
- if(HOSTDATA(shpnt)->debug & debug_intr)
- disp_ports(shpnt);
-#endif
-
- /* we are waiting for the result of a selection attempt */
- if(CURRENT_SC->SCp.phase & in_selection)
- {
- if(TESTLO(SSTAT1, SELTO))
- /* no timeout */
- if(TESTHI(SSTAT0, SELDO))
- {
- /* clear BUS FREE interrupt */
- SETPORT(SSTAT1, CLRBUSFREE);
-
- /* Disable SELECTION OUT sequence */
- CLRBITS(SCSISEQ, ENSELO|ENAUTOATNO);
-
- /* Disable SELECTION OUT DONE interrupt */
- CLRBITS(SIMODE0, ENSELDO);
- CLRBITS(SIMODE1, ENSELTIMO);
-
- if(TESTLO(SSTAT0, SELDO))
- {
- printk("aha152x: passing bus free condition\n");
-
-#if defined(DEBUG_RACE)
- leave_driver("(passing bus free) intr");
-#endif
- SETBITS(DMACNTRL0, INTEN);
-
- if(CURRENT_SC->SCp.phase & aborted)
- {
- HOSTDATA(shpnt)->abort_result=SCSI_ABORT_ERROR;
- HOSTDATA(shpnt)->abortion_complete++;
- }
-
- aha152x_done(shpnt, DID_NO_CONNECT << 16);
- return;
- }
-#if defined(DEBUG_SELECTION) || defined(DEBUG_PHASES)
- if(HOSTDATA(shpnt)->debug & (debug_selection|debug_phases))
- printk("SELDO (SELID=%x), ", GETPORT(SELID));
-#endif
-
- /* selection was done */
- SETPORT(SSTAT0, CLRSELDO);
-
-#if defined(DEBUG_ABORT)
- if((HOSTDATA(shpnt)->debug & debug_abort) && (CURRENT_SC->SCp.phase & aborted))
- printk("(ABORT) target selected, ");
-#endif
-
- CURRENT_SC->SCp.phase &= ~in_selection;
- CURRENT_SC->SCp.phase |= in_other;
-
- ADDMSG(IDENTIFY(HOSTDATA(shpnt)->reconnect,CURRENT_SC->lun));
-
- if(!(SYNCRATE&0x80) && HOSTDATA(shpnt)->synchronous)
- {
- ADDMSG(EXTENDED_MESSAGE);
- ADDMSG(3);
- ADDMSG(EXTENDED_SDTR);
- ADDMSG(50);
- ADDMSG(8);
-
- printk("outbound SDTR: ");
- print_msg(&MSG(MSGLEN-5));
-
- SYNCRATE=0x80;
- CURRENT_SC->SCp.phase |= in_sync;
- }
-
-#if defined(DEBUG_RACE)
- leave_driver("(SELDO) intr");
-#endif
- SETPORT(SCSIRATE, SYNCRATE&0x7f);
-
- SETPORT(SCSISIG, P_MSGO);
-
- SETPORT(SIMODE0, 0);
- SETPORT(SIMODE1, ENREQINIT|ENBUSFREE);
- SETBITS(DMACNTRL0, INTEN);
- return;
- }
- else
- aha152x_panic(shpnt, "neither timeout nor selection\007");
- else
- {
-#if defined(DEBUG_SELECTION) || defined(DEBUG_PHASES)
- if(HOSTDATA(shpnt)->debug & (debug_selection|debug_phases))
- printk("SELTO, ");
-#endif
- /* end selection attempt */
- CLRBITS(SCSISEQ, ENSELO|ENAUTOATNO);
-
- /* timeout */
- SETPORT(SSTAT1, CLRSELTIMO);
-
- SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0);
- SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0);
- SETBITS(DMACNTRL0, INTEN);
-#if defined(DEBUG_RACE)
- leave_driver("(SELTO) intr");
-#endif
-
- if(CURRENT_SC->SCp.phase & aborted)
- {
-#if defined(DEBUG_ABORT)
- if(HOSTDATA(shpnt)->debug & debug_abort)
- printk("(ABORT) selection timeout, ");
-#endif
- HOSTDATA(shpnt)->abort_result=SCSI_ABORT_ERROR;
- HOSTDATA(shpnt)->abortion_complete++;
- }
-
- if(TESTLO(SSTAT0, SELINGO))
- /* ARBITRATION not won */
- aha152x_done(shpnt, DID_BUS_BUSY << 16);
- else
- /* ARBITRATION won, but SELECTION failed */
- aha152x_done(shpnt, DID_NO_CONNECT << 16);
-
- return;
- }
- }
-
- /* enable interrupt, when target leaves current phase */
- phase = getphase(shpnt);
- if(!(phase & ~P_MASK)) /* "real" phase */
- SETPORT(SCSISIG, phase);
- SETPORT(SSTAT1, CLRPHASECHG);
- CURRENT_SC->SCp.phase =
- (CURRENT_SC->SCp.phase & ~((P_MASK|1)<<16)) | (phase << 16);
-
- /* information transfer phase */
- switch(phase)
- {
- case P_MSGO: /* MESSAGE OUT */
- {
- int i, identify=0, abort=0;
-
-#if defined(DEBUG_INTR) || defined(DEBUG_MSGO) || defined(DEBUG_PHASES)
- if(HOSTDATA(shpnt)->debug & (debug_intr|debug_msgo|debug_phases))
- printk("MESSAGE OUT, ");
-#endif
- if(MSGLEN==0)
- {
- ADDMSG(MESSAGE_REJECT);
-#if defined(DEBUG_MSGO)
- if(HOSTDATA(shpnt)->debug & debug_msgo)
- printk("unexpected MSGO; rejecting, ");
-#endif
- }
-
-
- CLRBITS(SXFRCTL0, ENDMA);
-
- SETPORT(SIMODE0, 0);
- SETPORT(SIMODE1, ENPHASEMIS|ENREQINIT|ENBUSFREE);
-
- /* wait for data latch to become ready or a phase change */
- while(TESTLO(DMASTAT, INTSTAT))
- barrier();
-
-#if defined(DEBUG_MSGO)
- if(HOSTDATA(shpnt)->debug & debug_msgo)
- {
- int i;
-
- printk("messages (");
- for(i=0; i<MSGLEN; i+=print_msg(&MSG(i)), printk(" "))
- ;
- printk("), ");
- }
-#endif
-
- for(i=0; i<MSGLEN && TESTLO(SSTAT1, PHASEMIS); i++)
- {
-#if defined(DEBUG_MSGO)
- if(HOSTDATA(shpnt)->debug & debug_msgo)
- printk("%x ", MSG(i));
-#endif
- if(i==MSGLEN-1)
- {
- /* Leave MESSAGE OUT after transfer */
- SETPORT(SSTAT1, CLRATNO);
- }
-
- SETPORT(SCSIDAT, MSG(i));
-
- make_acklow(shpnt);
- getphase(shpnt);
-
- if(MSG(i)==IDENTIFY(HOSTDATA(shpnt)->reconnect,CURRENT_SC->lun))
- identify++;
-
- if(MSG(i)==ABORT)
- abort++;
-
- }
-
- MSGLEN=0;
-
- if(identify)
- CURRENT_SC->SCp.phase |= sent_ident;
-
- if(abort)
- {
- /* revive abort(); abort() enables interrupts */
- HOSTDATA(shpnt)->abort_result=SCSI_ABORT_SUCCESS;
- HOSTDATA(shpnt)->abortion_complete++;
-
- CURRENT_SC->SCp.phase &= ~(P_MASK<<16);
-
- /* exit */
- SETBITS(DMACNTRL0, INTEN);
-#if defined(DEBUG_RACE)
- leave_driver("(ABORT) intr");
-#endif
- aha152x_done(shpnt, DID_ABORT<<16);
- return;
- }
- }
- break;
-
- case P_CMD: /* COMMAND phase */
-#if defined(DEBUG_INTR) || defined(DEBUG_CMD) || defined(DEBUG_PHASES)
- if(HOSTDATA(shpnt)->debug & (debug_intr|debug_cmd|debug_phases))
- printk("COMMAND, ");
-#endif
- if(!(CURRENT_SC->SCp.sent_command))
- {
- int i;
-
- CLRBITS(SXFRCTL0, ENDMA);
-
- SETPORT(SIMODE0, 0);
- SETPORT(SIMODE1, ENPHASEMIS|ENREQINIT|ENBUSFREE);
-
- /* wait for data latch to become ready or a phase change */
- while(TESTLO(DMASTAT, INTSTAT))
- barrier();
-
- for(i=0; i<CURRENT_SC->cmd_len && TESTLO(SSTAT1, PHASEMIS); i++)
- {
- SETPORT(SCSIDAT, CURRENT_SC->cmnd[i]);
-
- make_acklow(shpnt);
- getphase(shpnt);
- }
-
- if(i<CURRENT_SC->cmd_len && TESTHI(SSTAT1, PHASEMIS))
- aha152x_panic(shpnt, "target left COMMAND");
-
- CURRENT_SC->SCp.sent_command++;
- }
- else
- aha152x_panic(shpnt, "Nothing to send while in COMMAND");
- break;
-
- case P_MSGI: /* MESSAGE IN phase */
- {
- int start_sync=0;
-
-#if defined(DEBUG_INTR) || defined(DEBUG_MSGI) || defined(DEBUG_PHASES)
- if(HOSTDATA(shpnt)->debug & (debug_intr|debug_msgi|debug_phases))
- printk("MESSAGE IN, ");
-#endif
- SETPORT(SXFRCTL0, CH1);
-
- SETPORT(SIMODE0, 0);
- SETPORT(SIMODE1, ENBUSFREE);
-
- while(phase == P_MSGI)
- {
- CURRENT_SC->SCp.Message = GETPORT(SCSIDAT);
- switch(CURRENT_SC->SCp.Message)
- {
- case DISCONNECT:
-#if defined(DEBUG_MSGI) || defined(DEBUG_PHASES)
- if(HOSTDATA(shpnt)->debug & (debug_msgi|debug_phases))
- printk("target disconnected, ");
-#endif
- CURRENT_SC->SCp.Message = 0;
- CURRENT_SC->SCp.phase |= disconnected;
- if(!HOSTDATA(shpnt)->reconnect)
- aha152x_panic(shpnt, "target was not allowed to disconnect");
- break;
-
- case COMMAND_COMPLETE:
-#if defined(DEBUG_MSGI) || defined(DEBUG_PHASES)
- if(HOSTDATA(shpnt)->debug & (debug_msgi|debug_phases))
- printk("inbound message (COMMAND COMPLETE), ");
-#endif
- done++;
- break;
-
- case MESSAGE_REJECT:
- if(CURRENT_SC->SCp.phase & in_sync)
- {
- CURRENT_SC->SCp.phase &= ~in_sync;
- SYNCRATE=0x80;
- printk("synchronous rejected, ");
- }
- else
- printk("inbound message (MESSAGE REJECT), ");
-#if defined(DEBUG_MSGI)
- if(HOSTDATA(shpnt)->debug & debug_msgi)
- printk("inbound message (MESSAGE REJECT), ");
-#endif
- break;
-
- case SAVE_POINTERS:
-#if defined(DEBUG_MSGI)
- if(HOSTDATA(shpnt)->debug & debug_msgi)
- printk("inbound message (SAVE DATA POINTERS), ");
-#endif
- break;
-
- case EXTENDED_MESSAGE:
- {
- char buffer[16];
- int i;
-
-#if defined(DEBUG_MSGI)
- if(HOSTDATA(shpnt)->debug & debug_msgi)
- printk("inbound message (EXTENDED MESSAGE), ");
-#endif
- make_acklow(shpnt);
- if(getphase(shpnt)!=P_MSGI)
- break;
-
- buffer[0]=EXTENDED_MESSAGE;
- buffer[1]=GETPORT(SCSIDAT);
-
- for(i=0; i<buffer[1] &&
- (make_acklow(shpnt), getphase(shpnt)==P_MSGI); i++)
- buffer[2+i]=GETPORT(SCSIDAT);
-
-#if defined(DEBUG_MSGI)
- if(HOSTDATA(shpnt)->debug & debug_msgi)
- print_msg(buffer);
-#endif
-
- switch(buffer [2])
- {
- case EXTENDED_SDTR:
- {
- long ticks;
-
- if(buffer[1]!=3)
- aha152x_panic(shpnt, "SDTR message length != 3");
-
- if(!HOSTDATA(shpnt)->synchronous)
- break;
-
- printk("inbound SDTR: "); print_msg(buffer);
-
- ticks=(buffer[3]*4+49)/50;
-
- if(CURRENT_SC->SCp.phase & in_sync)
- {
- /* we initiated SDTR */
- if(ticks>9 || buffer[4]<1 || buffer[4]>8)
- aha152x_panic(shpnt, "received SDTR invalid");
-
- SYNCRATE |= ((ticks-2)<<4) + buffer[4];
- }
- else if(ticks<=9 && buffer[4]>=1)
- {
- if(buffer[4]>8)
- buffer[4]=8;
-
- ADDMSG(EXTENDED_MESSAGE);
- ADDMSG(3);
- ADDMSG(EXTENDED_SDTR);
- if(ticks<4)
- {
- ticks=4;
- ADDMSG(50);
- }
- else
- ADDMSG(buffer[3]);
-
- ADDMSG(buffer[4]);
-
- printk("outbound SDTR: ");
- print_msg(&MSG(MSGLEN-5));
-
- CURRENT_SC->SCp.phase |= in_sync;
-
- SYNCRATE |= ((ticks-2)<<4) + buffer[4];
-
- start_sync++;
- }
- else
- {
- /* requested SDTR is too slow, do it asynchronously */
- ADDMSG(MESSAGE_REJECT);
- SYNCRATE = 0;
- }
-
- SETPORT(SCSIRATE, SYNCRATE&0x7f);
- }
- break;
-
- case EXTENDED_MODIFY_DATA_POINTER:
- case EXTENDED_EXTENDED_IDENTIFY:
- case EXTENDED_WDTR:
- default:
- ADDMSG(MESSAGE_REJECT);
- break;
- }
- }
- break;
-
- default:
- printk("unsupported inbound message %x, ",
- CURRENT_SC->SCp.Message);
- break;
-
- }
-
- make_acklow(shpnt);
- phase=getphase(shpnt);
- }
-
- if(start_sync)
- CURRENT_SC->SCp.phase |= in_sync;
- else
- CURRENT_SC->SCp.phase &= ~in_sync;
-
- if(MSGLEN>0)
- SETPORT(SCSISIG, P_MSGI|ATNO);
-
- /* clear SCSI fifo on BUSFREE */
- if(phase==P_BUSFREE)
- SETPORT(SXFRCTL0, CH1|CLRCH1);
-
- if(CURRENT_SC->SCp.phase & disconnected)
- {
- save_flags(flags);
- cli();
-#if defined(DEBUG_QUEUES)
- if(HOSTDATA(shpnt)->debug & debug_queues)
- printk("d+, ");
-#endif
- append_SC(&DISCONNECTED_SC, CURRENT_SC);
- CURRENT_SC->SCp.phase |= 1<<16;
- CURRENT_SC = NULL;
- restore_flags(flags);
-
- SETBITS(SCSISEQ, ENRESELI);
-
- SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0);
- SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0);
-
- SETBITS(DMACNTRL0, INTEN);
- return;
- }
- }
- break;
-
- case P_STATUS: /* STATUS IN phase */
-#if defined(DEBUG_STATUS) || defined(DEBUG_INTR) || defined(DEBUG_PHASES)
- if(HOSTDATA(shpnt)->debug & (debug_status|debug_intr|debug_phases))
- printk("STATUS, ");
-#endif
- SETPORT(SXFRCTL0, CH1);
-
- SETPORT(SIMODE0, 0);
- SETPORT(SIMODE1, ENREQINIT|ENBUSFREE);
-
- if(TESTHI(SSTAT1, PHASEMIS))
- printk("aha152x: passing STATUS phase");
-
- CURRENT_SC->SCp.Status = GETPORT(SCSIBUS);
- make_acklow(shpnt);
- getphase(shpnt);
-
-#if defined(DEBUG_STATUS)
- if(HOSTDATA(shpnt)->debug & debug_status)
- {
- printk("inbound status ");
- print_status(CURRENT_SC->SCp.Status);
- printk(", ");
- }
-#endif
- break;
-
- case P_DATAI: /* DATA IN phase */
- {
- int fifodata, data_count, done;
-
-#if defined(DEBUG_DATAI) || defined(DEBUG_INTR) || defined(DEBUG_PHASES)
- if(HOSTDATA(shpnt)->debug & (debug_datai|debug_intr|debug_phases))
- printk("DATA IN, ");
-#endif
-
-#if 0
- if(GETPORT(FIFOSTAT) || GETPORT(SSTAT2) & (SFULL|SFCNT))
- printk("aha152x: P_DATAI: %d(%d) bytes left in FIFO, resetting\n",
- GETPORT(FIFOSTAT), GETPORT(SSTAT2) & (SFULL|SFCNT));
-#endif
-
- /* reset host fifo */
- SETPORT(DMACNTRL0, RSTFIFO);
- SETPORT(DMACNTRL0, RSTFIFO|ENDMA);
-
- SETPORT(SXFRCTL0, CH1|SCSIEN|DMAEN);
-
- SETPORT(SIMODE0, 0);
- SETPORT(SIMODE1, ENPHASEMIS|ENBUSFREE);
-
- /* done is set when the FIFO is empty after the target left DATA IN */
- done=0;
-
- /* while the target stays in DATA to transfer data */
- while (!done)
- {
-#if defined(DEBUG_DATAI)
- if(HOSTDATA(shpnt)->debug & debug_datai)
- printk("expecting data, ");
-#endif
- /* wait for PHASEMIS or full FIFO */
- while(TESTLO (DMASTAT, DFIFOFULL|INTSTAT))
- barrier();
-
-#if defined(DEBUG_DATAI)
- if(HOSTDATA(shpnt)->debug & debug_datai)
- printk("ok, ");
-#endif
-
- if(TESTHI(DMASTAT, DFIFOFULL))
- fifodata=GETPORT(FIFOSTAT);
- else
- {
- /* wait for SCSI fifo to get empty */
- while(TESTLO(SSTAT2, SEMPTY))
- barrier();
-
- /* rest of data in FIFO */
- fifodata=GETPORT(FIFOSTAT);
-#if defined(DEBUG_DATAI)
- if(HOSTDATA(shpnt)->debug & debug_datai)
- printk("last transfer, ");
-#endif
- done=1;
- }
-
-#if defined(DEBUG_DATAI)
- if(HOSTDATA(shpnt)->debug & debug_datai)
- printk("fifodata=%d, ", fifodata);
-#endif
-
- while(fifodata && CURRENT_SC->SCp.this_residual)
- {
- data_count=fifodata;
-
- /* limit data transfer to size of first sg buffer */
- if (data_count > CURRENT_SC->SCp.this_residual)
- data_count = CURRENT_SC->SCp.this_residual;
-
- fifodata -= data_count;
-
-#if defined(DEBUG_DATAI)
- if(HOSTDATA(shpnt)->debug & debug_datai)
- printk("data_count=%d, ", data_count);
-#endif
-
- if(data_count&1)
- {
- /* get a single byte in byte mode */
- SETBITS(DMACNTRL0, _8BIT);
- *CURRENT_SC->SCp.ptr++ = GETPORT(DATAPORT);
- CURRENT_SC->SCp.this_residual--;
- }
- if(data_count>1)
- {
- CLRBITS(DMACNTRL0, _8BIT);
- data_count >>= 1; /* Number of words */
- insw(DATAPORT, CURRENT_SC->SCp.ptr, data_count);
-#if defined(DEBUG_DATAI)
- if(HOSTDATA(shpnt)->debug & debug_datai)
- /* show what comes with the last transfer */
- if(done)
- {
-#ifdef 0
- int i;
- unsigned char *data;
-#endif
-
- printk("data on last transfer (%d bytes) ",
- 2*data_count);
-#ifdef 0
- printk("data on last transfer (%d bytes: ",
- 2*data_count);
- data = (unsigned char *) CURRENT_SC->SCp.ptr;
- for(i=0; i<2*data_count; i++)
- printk("%2x ", *data++);
- printk("), ");
-#endif
- }
-#endif
- CURRENT_SC->SCp.ptr += 2 * data_count;
- CURRENT_SC->SCp.this_residual -= 2 * data_count;
- }
-
- /* if this buffer is full and there are more buffers left */
- if (!CURRENT_SC->SCp.this_residual &&
- CURRENT_SC->SCp.buffers_residual)
- {
- /* advance to next buffer */
- CURRENT_SC->SCp.buffers_residual--;
- CURRENT_SC->SCp.buffer++;
- CURRENT_SC->SCp.ptr =
- CURRENT_SC->SCp.buffer->address;
- CURRENT_SC->SCp.this_residual =
- CURRENT_SC->SCp.buffer->length;
- }
- }
-
- /*
- * Fifo should be empty
- */
- if(fifodata>0)
- {
- printk("aha152x: more data than expected (%d bytes)\n",
- GETPORT(FIFOSTAT));
- SETBITS(DMACNTRL0, _8BIT);
- printk("aha152x: data (");
- while(fifodata--)
- printk("%2x ", GETPORT(DATAPORT));
- printk(")\n");
- }
-
-#if defined(DEBUG_DATAI)
- if(HOSTDATA(shpnt)->debug & debug_datai)
- if(!fifodata)
- printk("fifo empty, ");
- else
- printk("something left in fifo, ");
-#endif
- }
-
-#if defined(DEBUG_DATAI)
- if((HOSTDATA(shpnt)->debug & debug_datai) &&
- (CURRENT_SC->SCp.buffers_residual ||
- CURRENT_SC->SCp.this_residual))
- printk("left buffers (buffers=%d, bytes=%d), ",
- CURRENT_SC->SCp.buffers_residual,
- CURRENT_SC->SCp.this_residual);
-#endif
- /* transfer can be considered ended, when SCSIEN reads back zero */
- CLRBITS(SXFRCTL0, SCSIEN|DMAEN);
- while(TESTHI(SXFRCTL0, SCSIEN))
- barrier();
- CLRBITS(DMACNTRL0, ENDMA);
-
-#if defined(DEBUG_DATAI) || defined(DEBUG_INTR)
- if(HOSTDATA(shpnt)->debug & (debug_datai|debug_intr))
- printk("got %d bytes, ", GETSTCNT());
-#endif
-
- CURRENT_SC->SCp.have_data_in++;
- }
- break;
-
- case P_DATAO: /* DATA OUT phase */
- {
- int data_count;
-
-#if defined(DEBUG_DATAO) || defined(DEBUG_INTR) || defined(DEBUG_PHASES)
- if(HOSTDATA(shpnt)->debug & (debug_datao|debug_intr|debug_phases))
- printk("DATA OUT, ");
-#endif
-#if defined(DEBUG_DATAO)
- if(HOSTDATA(shpnt)->debug & debug_datao)
- printk("got data to send (bytes=%d, buffers=%d), ",
- CURRENT_SC->SCp.this_residual,
- CURRENT_SC->SCp.buffers_residual);
-#endif
-
- if(GETPORT(FIFOSTAT) || GETPORT(SSTAT2) & (SFULL|SFCNT))
- {
- printk("%d(%d) left in FIFO, ",
- GETPORT(FIFOSTAT), GETPORT(SSTAT2) & (SFULL|SFCNT));
- aha152x_panic(shpnt, "FIFO should be empty");
- }
-
- SETPORT(SXFRCTL0, CH1|CLRSTCNT|CLRCH1);
- SETPORT(SXFRCTL0, SCSIEN|DMAEN|CH1);
-
- SETPORT(DMACNTRL0, WRITE_READ|RSTFIFO);
- SETPORT(DMACNTRL0, ENDMA|WRITE_READ);
-
- SETPORT(SIMODE0, 0);
- SETPORT(SIMODE1, ENPHASEMIS|ENBUSFREE);
-
- /* while current buffer is not empty or
- there are more buffers to transfer */
- while(TESTLO(SSTAT1, PHASEMIS) &&
- (CURRENT_SC->SCp.this_residual ||
- CURRENT_SC->SCp.buffers_residual))
- {
-#if defined(DEBUG_DATAO)
- if(HOSTDATA(shpnt)->debug & debug_datao)
- printk("sending data (left: bytes=%d, buffers=%d), waiting, ",
- CURRENT_SC->SCp.this_residual,
- CURRENT_SC->SCp.buffers_residual);
-#endif
- /* transfer rest of buffer, but max. 128 byte */
- data_count =
- CURRENT_SC->SCp.this_residual > 128 ?
- 128 : CURRENT_SC->SCp.this_residual ;
-
-#if defined(DEBUG_DATAO)
- if(HOSTDATA(shpnt)->debug & debug_datao)
- printk("data_count=%d, ", data_count);
-#endif
-
- if(data_count&1)
- {
- /* put a single byte in byte mode */
- SETBITS(DMACNTRL0, _8BIT);
- SETPORT(DATAPORT, *CURRENT_SC->SCp.ptr++);
- CURRENT_SC->SCp.this_residual--;
- }
- if(data_count>1)
- {
- CLRBITS(DMACNTRL0, _8BIT);
- data_count >>= 1; /* number of words */
- outsw(DATAPORT, CURRENT_SC->SCp.ptr, data_count);
- CURRENT_SC->SCp.ptr += 2 * data_count;
- CURRENT_SC->SCp.this_residual -= 2 * data_count;
- }
-
- /* wait for FIFO to get empty */
- while(TESTLO(DMASTAT, DFIFOEMP|INTSTAT))
- barrier();
-
-#if defined(DEBUG_DATAO)
- if(HOSTDATA(shpnt)->debug & debug_datao)
- printk("fifo (%d bytes), transfered (%d bytes), ",
- GETPORT(FIFOSTAT), GETSTCNT());
-#endif
-
- /* if this buffer is empty and there are more buffers left */
- if (TESTLO(SSTAT1, PHASEMIS) &&
- !CURRENT_SC->SCp.this_residual &&
- CURRENT_SC->SCp.buffers_residual)
- {
- /* advance to next buffer */
- CURRENT_SC->SCp.buffers_residual--;
- CURRENT_SC->SCp.buffer++;
- CURRENT_SC->SCp.ptr =
- CURRENT_SC->SCp.buffer->address;
- CURRENT_SC->SCp.this_residual =
- CURRENT_SC->SCp.buffer->length;
- }
- }
-
- if (CURRENT_SC->SCp.this_residual || CURRENT_SC->SCp.buffers_residual)
- {
- /* target leaves DATA OUT for an other phase
- (perhaps disconnect) */
-
- /* data in fifos has to be resend */
- data_count = GETPORT(SSTAT2) & (SFULL|SFCNT);
-
- data_count += GETPORT(FIFOSTAT) ;
- CURRENT_SC->SCp.ptr -= data_count;
- CURRENT_SC->SCp.this_residual += data_count;
-#if defined(DEBUG_DATAO)
- if(HOSTDATA(shpnt)->debug & debug_datao)
- printk("left data (bytes=%d, buffers=%d), fifos (bytes=%d), "
- "transfer incomplete, resetting fifo, ",
- CURRENT_SC->SCp.this_residual,
- CURRENT_SC->SCp.buffers_residual,
- data_count);
-#endif
- SETPORT(DMACNTRL0, WRITE_READ|RSTFIFO);
- CLRBITS(SXFRCTL0, SCSIEN|DMAEN);
- CLRBITS(DMACNTRL0, ENDMA);
- }
- else
- {
-#if defined(DEBUG_DATAO)
- if(HOSTDATA(shpnt)->debug & debug_datao)
- printk("waiting for SCSI fifo to get empty, ");
-#endif
- /* wait for SCSI fifo to get empty */
- while(TESTLO(SSTAT2, SEMPTY))
- barrier();
-#if defined(DEBUG_DATAO)
- if(HOSTDATA(shpnt)->debug & debug_datao)
- printk("ok, left data (bytes=%d, buffers=%d) ",
- CURRENT_SC->SCp.this_residual,
- CURRENT_SC->SCp.buffers_residual);
-#endif
- CLRBITS(SXFRCTL0, SCSIEN|DMAEN);
-
- /* transfer can be considered ended, when SCSIEN reads back zero */
- while(TESTHI(SXFRCTL0, SCSIEN))
- barrier();
-
- CLRBITS(DMACNTRL0, ENDMA);
- }
-
-#if defined(DEBUG_DATAO) || defined(DEBUG_INTR)
- if(HOSTDATA(shpnt)->debug & (debug_datao|debug_intr))
- printk("sent %d data bytes, ", GETSTCNT());
-#endif
- }
- break;
-
- case P_BUSFREE: /* BUSFREE */
-#if defined(DEBUG_RACE)
- leave_driver("(BUSFREE) intr");
-#endif
-#if defined(DEBUG_PHASES)
- if(HOSTDATA(shpnt)->debug & debug_phases)
- printk("unexpected BUS FREE, ");
-#endif
- CURRENT_SC->SCp.phase &= ~(P_MASK<<16);
-
- aha152x_done(shpnt, DID_ERROR << 16); /* Don't know any better */
- return;
- break;
-
- case P_PARITY: /* parity error in DATA phase */
-#if defined(DEBUG_RACE)
- leave_driver("(DID_PARITY) intr");
-#endif
- printk("PARITY error in DATA phase, ");
-
- CURRENT_SC->SCp.phase &= ~(P_MASK<<16);
-
- SETBITS(DMACNTRL0, INTEN);
- aha152x_done(shpnt, DID_PARITY << 16);
- return;
- break;
-
- default:
- printk("aha152x: unexpected phase\n");
- break;
- }
-
- if(done)
- {
-#if defined(DEBUG_INTR)
- if(HOSTDATA(shpnt)->debug & debug_intr)
- printk("command done.\n");
-#endif
-#if defined(DEBUG_RACE)
- leave_driver("(done) intr");
-#endif
-
- SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0);
- SETPORT(SIMODE1, ISSUE_SC ? ENBUSFREE : 0);
- SETPORT(SCSISEQ, DISCONNECTED_SC ? ENRESELI : 0);
-
- SETBITS(DMACNTRL0, INTEN);
-
- aha152x_done(shpnt,
- (CURRENT_SC->SCp.Status & 0xff)
- | ((CURRENT_SC->SCp.Message & 0xff) << 8)
- | (DID_OK << 16));
-
-#if defined(DEBUG_RACE)
- printk("done returned (DID_OK: Status=%x; Message=%x).\n",
- CURRENT_SC->SCp.Status, CURRENT_SC->SCp.Message);
-#endif
- return;
- }
-
- if(CURRENT_SC)
- CURRENT_SC->SCp.phase |= 1<<16 ;
-
- SETPORT(SIMODE0, 0);
- SETPORT(SIMODE1, ENPHASEMIS|ENBUSFREE);
-#if defined(DEBUG_INTR)
- if(HOSTDATA(shpnt)->debug & debug_intr)
- disp_enintr(shpnt);
-#endif
-#if defined(DEBUG_RACE)
- leave_driver("(PHASEEND) intr");
-#endif
-
- SETBITS(DMACNTRL0, INTEN);
- return;
-}
-
-/*
- * Dump the current driver status and panic...
- */
-static void aha152x_panic(struct Scsi_Host *shpnt, char *msg)
-{
- printk("\naha152x: %s\n", msg);
- show_queues(shpnt);
- panic("aha152x panic");
-}
-
-/*
- * Display registers of AIC-6260
- */
-static void disp_ports(struct Scsi_Host *shpnt)
-{
-#ifdef DEBUG_AHA152X
- int s;
-
-#ifdef SKIP_PORTS
- if(HOSTDATA(shpnt)->debug & debug_skipports)
- return;
-#endif
-
- printk("\n%s: ", CURRENT_SC ? "on bus" : "waiting");
-
- s=GETPORT(SCSISEQ);
- printk("SCSISEQ (");
- if(s & TEMODEO) printk("TARGET MODE ");
- if(s & ENSELO) printk("SELO ");
- if(s & ENSELI) printk("SELI ");
- if(s & ENRESELI) printk("RESELI ");
- if(s & ENAUTOATNO) printk("AUTOATNO ");
- if(s & ENAUTOATNI) printk("AUTOATNI ");
- if(s & ENAUTOATNP) printk("AUTOATNP ");
- if(s & SCSIRSTO) printk("SCSIRSTO ");
- printk(");");
-
- printk(" SCSISIG (");
- s=GETPORT(SCSISIG);
- switch(s & P_MASK)
- {
- case P_DATAO:
- printk("DATA OUT");
- break;
- case P_DATAI:
- printk("DATA IN");
- break;
- case P_CMD:
- printk("COMMAND");
- break;
- case P_STATUS:
- printk("STATUS");
- break;
- case P_MSGO:
- printk("MESSAGE OUT");
- break;
- case P_MSGI:
- printk("MESSAGE IN");
- break;
- default:
- printk("*illegal*");
- break;
- }
-
- printk("); ");
-
- printk("INTSTAT (%s); ", TESTHI(DMASTAT, INTSTAT) ? "hi" : "lo");
-
- printk("SSTAT (");
- s=GETPORT(SSTAT0);
- if(s & TARGET) printk("TARGET ");
- if(s & SELDO) printk("SELDO ");
- if(s & SELDI) printk("SELDI ");
- if(s & SELINGO) printk("SELINGO ");
- if(s & SWRAP) printk("SWRAP ");
- if(s & SDONE) printk("SDONE ");
- if(s & SPIORDY) printk("SPIORDY ");
- if(s & DMADONE) printk("DMADONE ");
-
- s=GETPORT(SSTAT1);
- if(s & SELTO) printk("SELTO ");
- if(s & ATNTARG) printk("ATNTARG ");
- if(s & SCSIRSTI) printk("SCSIRSTI ");
- if(s & PHASEMIS) printk("PHASEMIS ");
- if(s & BUSFREE) printk("BUSFREE ");
- if(s & SCSIPERR) printk("SCSIPERR ");
- if(s & PHASECHG) printk("PHASECHG ");
- if(s & REQINIT) printk("REQINIT ");
- printk("); ");
-
-
- printk("SSTAT (");
-
- s=GETPORT(SSTAT0) & GETPORT(SIMODE0);
-
- if(s & TARGET) printk("TARGET ");
- if(s & SELDO) printk("SELDO ");
- if(s & SELDI) printk("SELDI ");
- if(s & SELINGO) printk("SELINGO ");
- if(s & SWRAP) printk("SWRAP ");
- if(s & SDONE) printk("SDONE ");
- if(s & SPIORDY) printk("SPIORDY ");
- if(s & DMADONE) printk("DMADONE ");
-
- s=GETPORT(SSTAT1) & GETPORT(SIMODE1);
-
- if(s & SELTO) printk("SELTO ");
- if(s & ATNTARG) printk("ATNTARG ");
- if(s & SCSIRSTI) printk("SCSIRSTI ");
- if(s & PHASEMIS) printk("PHASEMIS ");
- if(s & BUSFREE) printk("BUSFREE ");
- if(s & SCSIPERR) printk("SCSIPERR ");
- if(s & PHASECHG) printk("PHASECHG ");
- if(s & REQINIT) printk("REQINIT ");
- printk("); ");
-
- printk("SXFRCTL0 (");
-
- s=GETPORT(SXFRCTL0);
- if(s & SCSIEN) printk("SCSIEN ");
- if(s & DMAEN) printk("DMAEN ");
- if(s & CH1) printk("CH1 ");
- if(s & CLRSTCNT) printk("CLRSTCNT ");
- if(s & SPIOEN) printk("SPIOEN ");
- if(s & CLRCH1) printk("CLRCH1 ");
- printk("); ");
-
- printk("SIGNAL (");
-
- s=GETPORT(SCSISIG);
- if(s & ATNI) printk("ATNI ");
- if(s & SELI) printk("SELI ");
- if(s & BSYI) printk("BSYI ");
- if(s & REQI) printk("REQI ");
- if(s & ACKI) printk("ACKI ");
- printk("); ");
-
- printk("SELID (%02x), ", GETPORT(SELID));
-
- printk("SSTAT2 (");
-
- s=GETPORT(SSTAT2);
- if(s & SOFFSET) printk("SOFFSET ");
- if(s & SEMPTY) printk("SEMPTY ");
- if(s & SFULL) printk("SFULL ");
- printk("); SFCNT (%d); ", s & (SFULL|SFCNT));
-
- s=GETPORT(SSTAT3);
- printk("SCSICNT (%d), OFFCNT(%d), ", (s&0xf0)>>4, s&0x0f);
-
- printk("SSTAT4 (");
- s=GETPORT(SSTAT4);
- if(s & SYNCERR) printk("SYNCERR ");
- if(s & FWERR) printk("FWERR ");
- if(s & FRERR) printk("FRERR ");
- printk("); ");
-
- printk("DMACNTRL0 (");
- s=GETPORT(DMACNTRL0);
- printk("%s ", s & _8BIT ? "8BIT" : "16BIT");
- printk("%s ", s & DMA ? "DMA" : "PIO" );
- printk("%s ", s & WRITE_READ ? "WRITE" : "READ" );
- if(s & ENDMA) printk("ENDMA ");
- if(s & INTEN) printk("INTEN ");
- if(s & RSTFIFO) printk("RSTFIFO ");
- if(s & SWINT) printk("SWINT ");
- printk("); ");
-
-
-#if 0
- printk("DMACNTRL1 (");
-
- s=GETPORT(DMACNTRL1);
- if(s & PWRDWN) printk("PWRDN ");
- printk("); ");
-
-
- printk("STK (%d); ", s & 0xf);
-
-#endif
-
- printk("DMASTAT (");
- s=GETPORT(DMASTAT);
- if(s & ATDONE) printk("ATDONE ");
- if(s & WORDRDY) printk("WORDRDY ");
- if(s & DFIFOFULL) printk("DFIFOFULL ");
- if(s & DFIFOEMP) printk("DFIFOEMP ");
- printk(")");
-
- printk("\n");
-#endif
-}
-
-/*
- * display enabled interrupts
- */
-static void disp_enintr(struct Scsi_Host *shpnt)
-{
- int s;
-
- printk("enabled interrupts (");
-
- s=GETPORT(SIMODE0);
- if(s & ENSELDO) printk("ENSELDO ");
- if(s & ENSELDI) printk("ENSELDI ");
- if(s & ENSELINGO) printk("ENSELINGO ");
- if(s & ENSWRAP) printk("ENSWRAP ");
- if(s & ENSDONE) printk("ENSDONE ");
- if(s & ENSPIORDY) printk("ENSPIORDY ");
- if(s & ENDMADONE) printk("ENDMADONE ");
-
- s=GETPORT(SIMODE1);
- if(s & ENSELTIMO) printk("ENSELTIMO ");
- if(s & ENATNTARG) printk("ENATNTARG ");
- if(s & ENPHASEMIS) printk("ENPHASEMIS ");
- if(s & ENBUSFREE) printk("ENBUSFREE ");
- if(s & ENSCSIPERR) printk("ENSCSIPERR ");
- if(s & ENPHASECHG) printk("ENPHASECHG ");
- if(s & ENREQINIT) printk("ENREQINIT ");
- printk(")\n");
-}
-
-#if defined(DEBUG_RACE)
-
-static const char *should_leave;
-static int in_driver=0;
-
-/*
- * Only one routine can be in the driver at once.
- */
-static void enter_driver(const char *func)
-{
- unsigned long flags;
-
- save_flags(flags);
- cli();
- printk("aha152x: entering %s() (%x)\n", func, jiffies);
- if(in_driver)
- {
- printk("%s should leave first.\n", should_leave);
- panic("aha152x: already in driver\n");
- }
-
- in_driver++;
- should_leave=func;
- restore_flags(flags);
-}
-
-static void leave_driver(const char *func)
-{
- unsigned long flags;
-
- save_flags(flags);
- cli();
- printk("\naha152x: leaving %s() (%x)\n", func, jiffies);
- if(!in_driver)
- {
- printk("aha152x: %s already left.\n", should_leave);
- panic("aha152x: %s already left driver.\n");
- }
-
- in_driver--;
- should_leave=func;
- restore_flags(flags);
-}
-#endif
-
-/*
- * Show the command data of a command
- */
-static void show_command(Scsi_Cmnd *ptr)
-{
- printk("0x%08x: target=%d; lun=%d; cmnd=(",
- (unsigned int) ptr, ptr->target, ptr->lun);
-
- print_command(ptr->cmnd);
-
- printk("); residual=%d; buffers=%d; phase |",
- ptr->SCp.this_residual, ptr->SCp.buffers_residual);
-
- if(ptr->SCp.phase & not_issued ) printk("not issued|");
- if(ptr->SCp.phase & in_selection) printk("in selection|");
- if(ptr->SCp.phase & disconnected) printk("disconnected|");
- if(ptr->SCp.phase & aborted ) printk("aborted|");
- if(ptr->SCp.phase & sent_ident ) printk("send_ident|");
- if(ptr->SCp.phase & in_other)
- {
- printk("; in other(");
- switch((ptr->SCp.phase >> 16) & P_MASK)
- {
- case P_DATAO:
- printk("DATA OUT");
- break;
- case P_DATAI:
- printk("DATA IN");
- break;
- case P_CMD:
- printk("COMMAND");
- break;
- case P_STATUS:
- printk("STATUS");
- break;
- case P_MSGO:
- printk("MESSAGE OUT");
- break;
- case P_MSGI:
- printk("MESSAGE IN");
- break;
- default:
- printk("*illegal*");
- break;
- }
- printk(")");
- if(ptr->SCp.phase & (1<<16))
- printk("; phaseend");
- }
- printk("; next=0x%08x\n", (unsigned int) ptr->host_scribble);
-}
-
-/*
- * Dump the queued data
- */
-static void show_queues(struct Scsi_Host *shpnt)
-{
- unsigned long flags;
- Scsi_Cmnd *ptr;
-
- save_flags(flags);
- cli();
- printk("QUEUE STATUS:\nissue_SC:\n");
- for(ptr=ISSUE_SC; ptr; ptr = (Scsi_Cmnd *) ptr->host_scribble)
- show_command(ptr);
-
- printk("current_SC:\n");
- if(CURRENT_SC)
- show_command(CURRENT_SC);
- else
- printk("none\n");
-
- printk("disconnected_SC:\n");
- for(ptr=DISCONNECTED_SC; ptr; ptr = (Scsi_Cmnd *) ptr->host_scribble)
- show_command(ptr);
-
- disp_ports(shpnt);
- disp_enintr(shpnt);
- restore_flags(flags);
-}
-
-int aha152x_set_info(char *buffer, int length, struct Scsi_Host *shpnt)
-{
- return(-ENOSYS); /* Currently this is a no-op */
-}
-
-#undef SPRINTF
-#define SPRINTF(args...) pos += sprintf(pos, ## args)
-
-static int get_command(char *pos, Scsi_Cmnd *ptr)
-{
- char *start = pos;
- int i;
-
- SPRINTF("0x%08x: target=%d; lun=%d; cmnd=(",
- (unsigned int) ptr, ptr->target, ptr->lun);
-
- for(i=0; i<COMMAND_SIZE(ptr->cmnd[0]); i++)
- SPRINTF("0x%02x", ptr->cmnd[i]);
-
- SPRINTF("); residual=%d; buffers=%d; phase |",
- ptr->SCp.this_residual, ptr->SCp.buffers_residual);
-
- if(ptr->SCp.phase & not_issued ) SPRINTF("not issued|");
- if(ptr->SCp.phase & in_selection) SPRINTF("in selection|");
- if(ptr->SCp.phase & disconnected) SPRINTF("disconnected|");
- if(ptr->SCp.phase & aborted ) SPRINTF("aborted|");
- if(ptr->SCp.phase & sent_ident ) SPRINTF("send_ident|");
- if(ptr->SCp.phase & in_other)
- {
- SPRINTF("; in other(");
- switch((ptr->SCp.phase >> 16) & P_MASK)
- {
- case P_DATAO:
- SPRINTF("DATA OUT");
- break;
- case P_DATAI:
- SPRINTF("DATA IN");
- break;
- case P_CMD:
- SPRINTF("COMMAND");
- break;
- case P_STATUS:
- SPRINTF("STATUS");
- break;
- case P_MSGO:
- SPRINTF("MESSAGE OUT");
- break;
- case P_MSGI:
- SPRINTF("MESSAGE IN");
- break;
- default:
- SPRINTF("*illegal*");
- break;
- }
- SPRINTF(")");
- if(ptr->SCp.phase & (1<<16))
- SPRINTF("; phaseend");
- }
- SPRINTF("; next=0x%08x\n", (unsigned int) ptr->host_scribble);
-
- return(pos-start);
-}
-
-#undef SPRINTF
-#define SPRINTF(args...) do { if(pos < buffer + length) pos += sprintf(pos, ## args); } while(0)
-
-int aha152x_proc_info(
- char *buffer,
- char **start,
- off_t offset,
- int length,
- int hostno,
- int inout
- )
-{
- int i;
- char *pos = buffer;
- Scsi_Device *scd;
- struct Scsi_Host *shpnt;
- unsigned long flags;
- Scsi_Cmnd *ptr;
-
- for(i=0, shpnt= (struct Scsi_Host *) NULL; i<IRQS; i++)
- if(aha152x_host[i] && aha152x_host[i]->host_no == hostno)
- shpnt=aha152x_host[i];
-
- if(!shpnt)
- return(-ESRCH);
-
- if(inout) /* Has data been written to the file ? */
- return(aha152x_set_info(buffer, length, shpnt));
-
- SPRINTF(AHA152X_REVID "\n");
-
- save_flags(flags);
- cli();
-
- SPRINTF("vital data:\nioports 0x%04x to 0x%04x\n",
- shpnt->io_port, shpnt->io_port+shpnt->n_io_port-1);
- SPRINTF("interrupt 0x%02x\n", shpnt->irq);
- SPRINTF("disconnection/reconnection %s\n",
- HOSTDATA(shpnt)->reconnect ? "enabled" : "disabled");
- SPRINTF("parity checking %s\n",
- HOSTDATA(shpnt)->parity ? "enabled" : "disabled");
- SPRINTF("synchronous transfers %s\n",
- HOSTDATA(shpnt)->synchronous ? "enabled" : "disabled");
- SPRINTF("current queued %d commands\n",
- HOSTDATA(shpnt)->commands);
-
-#if 0
- SPRINTF("synchronously operating targets (tick=%ld ns):\n",
- 250000000/loops_per_sec);
- for(i=0; i<8; i++)
- if(HOSTDATA(shpnt)->syncrate[i]&0x7f)
- SPRINTF("target %d: period %dT/%ldns; req/ack offset %d\n",
- i,
- (((HOSTDATA(shpnt)->syncrate[i]&0x70)>>4)+2),
- (((HOSTDATA(shpnt)->syncrate[i]&0x70)>>4)+2)*
- 250000000/loops_per_sec,
- HOSTDATA(shpnt)->syncrate[i]&0x0f);
-#else
- SPRINTF("synchronously operating targets (tick=50 ns):\n");
- for(i=0; i<8; i++)
- if(HOSTDATA(shpnt)->syncrate[i]&0x7f)
- SPRINTF("target %d: period %dT/%dns; req/ack offset %d\n",
- i,
- (((HOSTDATA(shpnt)->syncrate[i]&0x70)>>4)+2),
- (((HOSTDATA(shpnt)->syncrate[i]&0x70)>>4)+2)*50,
- HOSTDATA(shpnt)->syncrate[i]&0x0f);
-#endif
-
-#ifdef DEBUG_AHA152X
-#define PDEBUG(flags,txt) if(HOSTDATA(shpnt)->debug & flags) SPRINTF("(%s) ", txt);
-
- SPRINTF("enabled debugging options:\n");
-
- PDEBUG(debug_skipports, "skip ports");
- PDEBUG(debug_queue, "queue");
- PDEBUG(debug_intr, "interrupt");
- PDEBUG(debug_selection, "selection");
- PDEBUG(debug_msgo, "message out");
- PDEBUG(debug_msgi, "message in");
- PDEBUG(debug_status, "status");
- PDEBUG(debug_cmd, "command");
- PDEBUG(debug_datai, "data in");
- PDEBUG(debug_datao, "data out");
- PDEBUG(debug_abort, "abort");
- PDEBUG(debug_done, "done");
- PDEBUG(debug_biosparam, "bios parameters");
- PDEBUG(debug_phases, "phases");
- PDEBUG(debug_queues, "queues");
- PDEBUG(debug_reset, "reset");
-
- SPRINTF("\n");
-#endif
-
- SPRINTF("queue status:\nnot yet issued commands:\n");
- for(ptr=ISSUE_SC; ptr; ptr = (Scsi_Cmnd *) ptr->host_scribble)
- pos += get_command(pos, ptr);
-
- if(CURRENT_SC)
- {
- SPRINTF("current command:\n");
- pos += get_command(pos, CURRENT_SC);
- }
-
- SPRINTF("disconnected commands:\n");
- for(ptr=DISCONNECTED_SC; ptr; ptr = (Scsi_Cmnd *) ptr->host_scribble)
- pos += get_command(pos, ptr);
-
- restore_flags(flags);
-
- scd = scsi_devices;
-
- SPRINTF("Attached devices: %s\n", (scd)?"":"none");
-
- while (scd) {
- if (scd->host == shpnt) {
-
- SPRINTF("Channel: %02d Id: %02d Lun: %02d\n Vendor: ",
- scd->channel, scd->id, scd->lun);
- for (i=0; i<8; i++) {
- if (scd->vendor[i] >= 0x20)
- SPRINTF("%c", scd->vendor[i]);
- else
- SPRINTF(" ");
- }
- SPRINTF(" Model: ");
- for (i = 0; i < 16; i++) {
- if (scd->model[i] >= 0x20)
- SPRINTF("%c", scd->model[i]);
- else
- SPRINTF(" ");
- }
- SPRINTF(" Rev: ");
- for (i = 0; i < 4; i++) {
- if (scd->rev[i] >= 0x20)
- SPRINTF("%c", scd->rev[i]);
- else
- SPRINTF(" ");
- }
- SPRINTF("\n");
-
- SPRINTF(" Type: %d ", scd->type);
- SPRINTF(" ANSI SCSI revision: %02x",
- (scd->scsi_level < 3)?1:2);
-
- if (scd->scsi_level == 2)
- SPRINTF(" CCS\n");
- else
- SPRINTF("\n");
- }
- scd = scd->next;
- }
-
- *start=buffer+offset;
- if (pos - buffer < offset)
- return 0;
- else if (pos - buffer - offset < length)
- return pos - buffer - offset;
- else
- return length;
-}
-
-#ifdef MODULE
-/* Eventually this will go into an include file, but this will be later */
-Scsi_Host_Template driver_template = AHA152X;
-
-#include "scsi_module.c"
-#endif
diff --git a/i386/i386at/gpl/linux/scsi/aha152x.h b/i386/i386at/gpl/linux/scsi/aha152x.h
deleted file mode 100644
index d62e5cfe..00000000
--- a/i386/i386at/gpl/linux/scsi/aha152x.h
+++ /dev/null
@@ -1,373 +0,0 @@
-#ifndef _AHA152X_H
-#define _AHA152X_H
-
-/*
- * $Id: aha152x.h,v 1.1.1.1 1997/02/25 21:27:46 thomas Exp $
- */
-
-#if defined(__KERNEL__)
-
-#include <linux/blk.h>
-#include "scsi.h"
-#include <asm/io.h>
-
-int aha152x_detect(Scsi_Host_Template *);
-int aha152x_command(Scsi_Cmnd *);
-int aha152x_queue(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-int aha152x_abort(Scsi_Cmnd *);
-int aha152x_reset(Scsi_Cmnd *);
-int aha152x_biosparam(Disk *, kdev_t, int*);
-int aha152x_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int inout);
-
-/* number of queueable commands
- (unless we support more than 1 cmd_per_lun this should do) */
-#define AHA152X_MAXQUEUE 7
-
-#define AHA152X_REVID "Adaptec 152x SCSI driver; $Revision: 1.1.1.1 $"
-
-extern struct proc_dir_entry proc_scsi_aha152x;
-
-/* Initial value of Scsi_Host entry */
-#define AHA152X { /* next */ NULL, \
- /* usage_count */ NULL, \
- /* proc_dir */ &proc_scsi_aha152x, \
- /* proc_info */ aha152x_proc_info, \
- /* name */ AHA152X_REVID, \
- /* detect */ aha152x_detect, \
- /* release */ NULL, \
- /* info */ NULL, \
- /* command */ aha152x_command, \
- /* queuecommand */ aha152x_queue, \
- /* abort */ aha152x_abort, \
- /* reset */ aha152x_reset, \
- /* slave_attach */ /* NULL */ 0, \
- /* bios_param */ aha152x_biosparam, \
- /* can_queue */ 1, \
- /* this_id */ 7, \
- /* sg_tablesize */ SG_ALL, \
- /* cmd_per_lun */ 1, \
- /* present */ 0, \
- /* unchecked_isa_dma */ 0, \
- /* use_clustering */ DISABLE_CLUSTERING }
-#endif
-
-
-/* port addresses */
-#define SCSISEQ (shpnt->io_port+0x00) /* SCSI sequence control */
-#define SXFRCTL0 (shpnt->io_port+0x01) /* SCSI transfer control 0 */
-#define SXFRCTL1 (shpnt->io_port+0x02) /* SCSI transfer control 1 */
-#define SCSISIG (shpnt->io_port+0x03) /* SCSI signal in/out */
-#define SCSIRATE (shpnt->io_port+0x04) /* SCSI rate control */
-#define SELID (shpnt->io_port+0x05) /* selection/reselection ID */
-#define SCSIID SELID /* SCSI ID */
-#define SCSIDAT (shpnt->io_port+0x06) /* SCSI latched data */
-#define SCSIBUS (shpnt->io_port+0x07) /* SCSI data bus */
-#define STCNT0 (shpnt->io_port+0x08) /* SCSI transfer count 0 */
-#define STCNT1 (shpnt->io_port+0x09) /* SCSI transfer count 1 */
-#define STCNT2 (shpnt->io_port+0x0a) /* SCSI transfer count 2 */
-#define SSTAT0 (shpnt->io_port+0x0b) /* SCSI interrupt status 0 */
-#define SSTAT1 (shpnt->io_port+0x0c) /* SCSI interrupt status 1 */
-#define SSTAT2 (shpnt->io_port+0x0d) /* SCSI interrupt status 2 */
-#define SCSITEST (shpnt->io_port+0x0e) /* SCSI test control */
-#define SSTAT3 SCSITEST /* SCSI interrupt status 3 */
-#define SSTAT4 (shpnt->io_port+0x0f) /* SCSI status 4 */
-#define SIMODE0 (shpnt->io_port+0x10) /* SCSI interrupt mode 0 */
-#define SIMODE1 (shpnt->io_port+0x11) /* SCSI interrupt mode 1 */
-#define DMACNTRL0 (shpnt->io_port+0x12) /* DMA control 0 */
-#define DMACNTRL1 (shpnt->io_port+0x13) /* DMA control 1 */
-#define DMASTAT (shpnt->io_port+0x14) /* DMA status */
-#define FIFOSTAT (shpnt->io_port+0x15) /* FIFO status */
-#define DATAPORT (shpnt->io_port+0x16) /* DATA port */
-#define BRSTCNTRL (shpnt->io_port+0x18) /* burst control */
-#define PORTA (shpnt->io_port+0x1a) /* PORT A */
-#define PORTB (shpnt->io_port+0x1b) /* PORT B */
-#define REV (shpnt->io_port+0x1c) /* revision */
-#define STACK (shpnt->io_port+0x1d) /* stack */
-#define TEST (shpnt->io_port+0x1e) /* test register */
-
-/* used in aha152x_porttest */
-#define O_PORTA (0x1a) /* PORT A */
-#define O_PORTB (0x1b) /* PORT B */
-#define O_DMACNTRL1 (0x13) /* DMA control 1 */
-#define O_STACK (0x1d) /* stack */
-#define IO_RANGE 0x20
-
-/* bits and bitmasks to ports */
-
-/* SCSI sequence control */
-#define TEMODEO 0x80
-#define ENSELO 0x40
-#define ENSELI 0x20
-#define ENRESELI 0x10
-#define ENAUTOATNO 0x08
-#define ENAUTOATNI 0x04
-#define ENAUTOATNP 0x02
-#define SCSIRSTO 0x01
-
-/* SCSI transfer control 0 */
-#define SCSIEN 0x80
-#define DMAEN 0x40
-#define CH1 0x20
-#define CLRSTCNT 0x10
-#define SPIOEN 0x08
-#define CLRCH1 0x02
-
-/* SCSI transfer control 1 */
-#define BITBUCKET 0x80
-#define SWRAPEN 0x40
-#define ENSPCHK 0x20
-#define STIMESEL 0x18 /* mask */
-#define STIMESEL_ 3
-#define ENSTIMER 0x04
-#define BYTEALIGN 0x02
-
-/* SCSI signal IN */
-#define CDI 0x80
-#define IOI 0x40
-#define MSGI 0x20
-#define ATNI 0x10
-#define SELI 0x08
-#define BSYI 0x04
-#define REQI 0x02
-#define ACKI 0x01
-
-/* SCSI Phases */
-#define P_MASK (MSGI|CDI|IOI)
-#define P_DATAO (0)
-#define P_DATAI (IOI)
-#define P_CMD (CDI)
-#define P_STATUS (CDI|IOI)
-#define P_MSGO (MSGI|CDI)
-#define P_MSGI (MSGI|CDI|IOI)
-
-/* SCSI signal OUT */
-#define CDO 0x80
-#define IOO 0x40
-#define MSGO 0x20
-#define ATNO 0x10
-#define SELO 0x08
-#define BSYO 0x04
-#define REQO 0x02
-#define ACKO 0x01
-
-/* SCSI rate control */
-#define SXFR 0x70 /* mask */
-#define SXFR_ 4
-#define SOFS 0x0f /* mask */
-
-/* SCSI ID */
-#define OID 0x70
-#define OID_ 4
-#define TID 0x07
-
-/* SCSI transfer count */
-#define GETSTCNT() ( (GETPORT(STCNT2)<<16) \
- + (GETPORT(STCNT1)<< 8) \
- + GETPORT(STCNT0) )
-
-#define SETSTCNT(X) { SETPORT(STCNT2, ((X) & 0xFF0000) >> 16); \
- SETPORT(STCNT1, ((X) & 0x00FF00) >> 8); \
- SETPORT(STCNT0, ((X) & 0x0000FF) ); }
-
-/* SCSI interrupt status */
-#define TARGET 0x80
-#define SELDO 0x40
-#define SELDI 0x20
-#define SELINGO 0x10
-#define SWRAP 0x08
-#define SDONE 0x04
-#define SPIORDY 0x02
-#define DMADONE 0x01
-
-#define SETSDONE 0x80
-#define CLRSELDO 0x40
-#define CLRSELDI 0x20
-#define CLRSELINGO 0x10
-#define CLRSWRAP 0x08
-#define CLRSDONE 0x04
-#define CLRSPIORDY 0x02
-#define CLRDMADONE 0x01
-
-/* SCSI status 1 */
-#define SELTO 0x80
-#define ATNTARG 0x40
-#define SCSIRSTI 0x20
-#define PHASEMIS 0x10
-#define BUSFREE 0x08
-#define SCSIPERR 0x04
-#define PHASECHG 0x02
-#define REQINIT 0x01
-
-#define CLRSELTIMO 0x80
-#define CLRATNO 0x40
-#define CLRSCSIRSTI 0x20
-#define CLRBUSFREE 0x08
-#define CLRSCSIPERR 0x04
-#define CLRPHASECHG 0x02
-#define CLRREQINIT 0x01
-
-/* SCSI status 2 */
-#define SOFFSET 0x20
-#define SEMPTY 0x10
-#define SFULL 0x08
-#define SFCNT 0x07 /* mask */
-
-/* SCSI status 3 */
-#define SCSICNT 0xf0 /* mask */
-#define SCSICNT_ 4
-#define OFFCNT 0x0f /* mask */
-
-/* SCSI TEST control */
-#define SCTESTU 0x08
-#define SCTESTD 0x04
-#define STCTEST 0x01
-
-/* SCSI status 4 */
-#define SYNCERR 0x04
-#define FWERR 0x02
-#define FRERR 0x01
-
-#define CLRSYNCERR 0x04
-#define CLRFWERR 0x02
-#define CLRFRERR 0x01
-
-/* SCSI interrupt mode 0 */
-#define ENSELDO 0x40
-#define ENSELDI 0x20
-#define ENSELINGO 0x10
-#define ENSWRAP 0x08
-#define ENSDONE 0x04
-#define ENSPIORDY 0x02
-#define ENDMADONE 0x01
-
-/* SCSI interrupt mode 1 */
-#define ENSELTIMO 0x80
-#define ENATNTARG 0x40
-#define ENSCSIRST 0x20
-#define ENPHASEMIS 0x10
-#define ENBUSFREE 0x08
-#define ENSCSIPERR 0x04
-#define ENPHASECHG 0x02
-#define ENREQINIT 0x01
-
-/* DMA control 0 */
-#define ENDMA 0x80
-#define _8BIT 0x40
-#define DMA 0x20
-#define WRITE_READ 0x08
-#define INTEN 0x04
-#define RSTFIFO 0x02
-#define SWINT 0x01
-
-/* DMA control 1 */
-#define PWRDWN 0x80
-#define STK 0x07 /* mask */
-
-/* DMA status */
-#define ATDONE 0x80
-#define WORDRDY 0x40
-#define INTSTAT 0x20
-#define DFIFOFULL 0x10
-#define DFIFOEMP 0x08
-
-/* BURST control */
-#define BON 0xf0
-#define BOFF 0x0f
-
-/* TEST REGISTER */
-#define BOFFTMR 0x40
-#define BONTMR 0x20
-#define STCNTH 0x10
-#define STCNTM 0x08
-#define STCNTL 0x04
-#define SCSIBLK 0x02
-#define DMABLK 0x01
-
-/* On the AHA-152x board PORTA and PORTB contain
- some information about the board's configuration. */
-typedef union {
- struct {
- unsigned reserved:2; /* reserved */
- unsigned tardisc:1; /* Target disconnect: 0=disabled, 1=enabled */
- unsigned syncneg:1; /* Initial sync neg: 0=disabled, 1=enabled */
- unsigned msgclasses:2; /* Message classes
- 0=#4
- 1=#0, #1, #2, #3, #4
- 2=#0, #3, #4
- 3=#0, #4
- */
- unsigned boot:1; /* boot: 0=disabled, 1=enabled */
- unsigned dma:1; /* Transfer mode: 0=PIO; 1=DMA */
- unsigned id:3; /* SCSI-id */
- unsigned irq:2; /* IRQ-Channel: 0,3=12, 1=10, 2=11 */
- unsigned dmachan:2; /* DMA-Channel: 0=0, 1=5, 2=6, 3=7 */
- unsigned parity:1; /* SCSI-parity: 1=enabled 0=disabled */
- } fields;
- unsigned short port;
-} aha152x_config ;
-
-#define cf_parity fields.parity
-#define cf_dmachan fields.dmachan
-#define cf_irq fields.irq
-#define cf_id fields.id
-#define cf_dma fields.dma
-#define cf_boot fields.boot
-#define cf_msgclasses fields.msgclasses
-#define cf_syncneg fields.syncneg
-#define cf_tardisc fields.tardisc
-#define cf_port port
-
-/* Some macros to manipulate ports and their bits */
-
-#define SETPORT(PORT, VAL) \
- outb( (VAL), (PORT) )
-
-#define SETPORTP(PORT, VAL) \
- outb_p( (VAL), (PORT) )
-
-#define SETPORTW(PORT, VAL) \
- outw( (VAL), (PORT) )
-
-#define GETPORT(PORT) \
- inb( PORT )
-
-#define GETPORTW(PORT) \
- inw( PORT )
-
-#define SETBITS(PORT, BITS) \
- outb( (inb(PORT) | (BITS)), (PORT) )
-
-#define CLRBITS(PORT, BITS) \
- outb( (inb(PORT) & ~(BITS)), (PORT) )
-
-#define CLRSETBITS(PORT, CLR, SET) \
- outb( (inb(PORT) & ~(CLR)) | (SET) , (PORT) )
-
-#define TESTHI(PORT, BITS) \
- ((inb(PORT) & (BITS)) == BITS)
-
-#define TESTLO(PORT, BITS) \
- ((inb(PORT) & (BITS)) == 0)
-
-#ifdef DEBUG_AHA152X
-enum {
- debug_skipports =0x0001,
- debug_queue =0x0002,
- debug_intr =0x0004,
- debug_selection =0x0008,
- debug_msgo =0x0010,
- debug_msgi =0x0020,
- debug_status =0x0040,
- debug_cmd =0x0080,
- debug_datai =0x0100,
- debug_datao =0x0200,
- debug_abort =0x0400,
- debug_done =0x0800,
- debug_biosparam =0x1000,
- debug_phases =0x2000,
- debug_queues =0x4000,
- debug_reset =0x8000,
-};
-#endif
-
-#endif /* _AHA152X_H */
diff --git a/i386/i386at/gpl/linux/scsi/aha1542.c b/i386/i386at/gpl/linux/scsi/aha1542.c
deleted file mode 100644
index 026292eb..00000000
--- a/i386/i386at/gpl/linux/scsi/aha1542.c
+++ /dev/null
@@ -1,1323 +0,0 @@
-/* $Id: aha1542.c,v 1.1.1.1 1997/02/25 21:27:46 thomas Exp $
- * linux/kernel/aha1542.c
- *
- * Copyright (C) 1992 Tommy Thorn
- * Copyright (C) 1993, 1994, 1995 Eric Youngdale
- *
- * Modified by Eric Youngdale
- * Use request_irq and request_dma to help prevent unexpected conflicts
- * Set up on-board DMA controller, such that we do not have to
- * have the bios enabled to use the aha1542.
- * Modified by David Gentzel
- * Don't call request_dma if dma mask is 0 (for BusLogic BT-445S VL-Bus
- * controller).
- * Modified by Matti Aarnio
- * Accept parameters from LILO cmd-line. -- 1-Oct-94
- */
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/head.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/proc_fs.h>
-#include <asm/dma.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <linux/blk.h>
-#include "scsi.h"
-#include "hosts.h"
-
-
-#include "aha1542.h"
-
-#include<linux/stat.h>
-
-struct proc_dir_entry proc_scsi_aha1542 = {
- PROC_SCSI_AHA1542, 7, "aha1542",
- S_IFDIR | S_IRUGO | S_IXUGO, 2
-};
-
-#ifdef DEBUG
-#define DEB(x) x
-#else
-#define DEB(x)
-#endif
-/*
-static const char RCSid[] = "$Header: cvs/gnumach/i386/i386at/gpl/linux/scsi/Attic/aha1542.c,v 1.1.1.1 1997/02/25 21:27:46 thomas Exp $";
-*/
-
-/* The adaptec can be configured for quite a number of addresses, but
-I generally do not want the card poking around at random. We allow
-two addresses - this allows people to use the Adaptec with a Midi
-card, which also used 0x330 -- can be overridden with LILO! */
-
-#define MAXBOARDS 2 /* Increase this and the sizes of the
- arrays below, if you need more.. */
-
-static unsigned int bases[MAXBOARDS]={0x330, 0x334};
-
-/* set by aha1542_setup according to the command line */
-static int setup_called[MAXBOARDS] = {0,0};
-static int setup_buson[MAXBOARDS] = {0,0};
-static int setup_busoff[MAXBOARDS] = {0,0};
-static int setup_dmaspeed[MAXBOARDS] = {-1,-1};
-
-static char *setup_str[MAXBOARDS] = {(char *)NULL,(char *)NULL};
-
-/*
- * LILO params: aha1542=<PORTBASE>[,<BUSON>,<BUSOFF>[,<DMASPEED>]]
- *
- * Where: <PORTBASE> is any of the valid AHA addresses:
- * 0x130, 0x134, 0x230, 0x234, 0x330, 0x334
- * <BUSON> is the time (in microsecs) that AHA spends on the AT-bus
- * when transferring data. 1542A power-on default is 11us,
- * valid values are in range: 2..15 (decimal)
- * <BUSOFF> is the time that AHA spends OFF THE BUS after while
- * it is transferring data (not to monopolize the bus).
- * Power-on default is 4us, valid range: 1..64 microseconds.
- * <DMASPEED> Default is jumper selected (1542A: on the J1),
- * but experimenter can alter it with this.
- * Valid values: 5, 6, 7, 8, 10 (MB/s)
- * Factory default is 5 MB/s.
- */
-
-
-/* The DMA-Controller. We need to fool with this because we want to
- be able to use the aha1542 without having to have the bios enabled */
-#define DMA_MODE_REG 0xd6
-#define DMA_MASK_REG 0xd4
-#define CASCADE 0xc0
-
-#define BIOS_TRANSLATION_1632 0 /* Used by some old 1542A boards */
-#define BIOS_TRANSLATION_6432 1 /* Default case these days */
-#define BIOS_TRANSLATION_25563 2 /* Big disk case */
-
-struct aha1542_hostdata{
- /* This will effectively start both of them at the first mailbox */
- int bios_translation; /* Mapping bios uses - for compatibility */
- int aha1542_last_mbi_used;
- int aha1542_last_mbo_used;
- Scsi_Cmnd * SCint[AHA1542_MAILBOXES];
- struct mailbox mb[2*AHA1542_MAILBOXES];
- struct ccb ccb[AHA1542_MAILBOXES];
-};
-
-#define HOSTDATA(host) ((struct aha1542_hostdata *) &host->hostdata)
-
-static struct Scsi_Host * aha_host[7] = {NULL,}; /* One for each IRQ level (9-15) */
-
-
-
-
-#define WAITnexttimeout 3000000
-
-static void setup_mailboxes(int base_io, struct Scsi_Host * shpnt);
-static int aha1542_restart(struct Scsi_Host * shost);
-
-#define aha1542_intr_reset(base) outb(IRST, CONTROL(base))
-
-#define WAIT(port, mask, allof, noneof) \
- { register WAITbits; \
- register WAITtimeout = WAITnexttimeout; \
- while (1) { \
- WAITbits = inb(port) & (mask); \
- if ((WAITbits & (allof)) == (allof) && ((WAITbits & (noneof)) == 0)) \
- break; \
- if (--WAITtimeout == 0) goto fail; \
- } \
- }
-
-/* Similar to WAIT, except we use the udelay call to regulate the
- amount of time we wait. */
-#define WAITd(port, mask, allof, noneof, timeout) \
- { register WAITbits; \
- register WAITtimeout = timeout; \
- while (1) { \
- WAITbits = inb(port) & (mask); \
- if ((WAITbits & (allof)) == (allof) && ((WAITbits & (noneof)) == 0)) \
- break; \
- udelay(1000); \
- if (--WAITtimeout == 0) goto fail; \
- } \
- }
-
-static void aha1542_stat(void)
-{
-/* int s = inb(STATUS), i = inb(INTRFLAGS);
- printk("status=%x intrflags=%x\n", s, i, WAITnexttimeout-WAITtimeout); */
-}
-
-/* This is a bit complicated, but we need to make sure that an interrupt
- routine does not send something out while we are in the middle of this.
- Fortunately, it is only at boot time that multi-byte messages
- are ever sent. */
-static int aha1542_out(unsigned int base, unchar *cmdp, int len)
-{
- unsigned long flags = 0;
-
- save_flags(flags);
- if(len == 1) {
- while(1==1){
- WAIT(STATUS(base), CDF, 0, CDF);
- cli();
- if(inb(STATUS(base)) & CDF) {restore_flags(flags); continue;}
- outb(*cmdp, DATA(base));
- restore_flags(flags);
- return 0;
- }
- } else {
- cli();
- while (len--)
- {
- WAIT(STATUS(base), CDF, 0, CDF);
- outb(*cmdp++, DATA(base));
- }
- restore_flags(flags);
- }
- return 0;
- fail:
- restore_flags(flags);
- printk("aha1542_out failed(%d): ", len+1); aha1542_stat();
- return 1;
-}
-
-/* Only used at boot time, so we do not need to worry about latency as much
- here */
-static int aha1542_in(unsigned int base, unchar *cmdp, int len)
-{
- unsigned long flags;
-
- save_flags(flags);
- cli();
- while (len--)
- {
- WAIT(STATUS(base), DF, DF, 0);
- *cmdp++ = inb(DATA(base));
- }
- restore_flags(flags);
- return 0;
- fail:
- restore_flags(flags);
- printk("aha1542_in failed(%d): ", len+1); aha1542_stat();
- return 1;
-}
-
-/* Similar to aha1542_in, except that we wait a very short period of time.
- We use this if we know the board is alive and awake, but we are not sure
- if the board will respond the the command we are about to send or not */
-static int aha1542_in1(unsigned int base, unchar *cmdp, int len)
-{
- unsigned long flags;
-
- save_flags(flags);
- cli();
- while (len--)
- {
- WAITd(STATUS(base), DF, DF, 0, 100);
- *cmdp++ = inb(DATA(base));
- }
- restore_flags(flags);
- return 0;
- fail:
- restore_flags(flags);
- return 1;
-}
-
-static int makecode(unsigned hosterr, unsigned scsierr)
-{
- switch (hosterr) {
- case 0x0:
- case 0xa: /* Linked command complete without error and linked normally */
- case 0xb: /* Linked command complete without error, interrupt generated */
- hosterr = 0;
- break;
-
- case 0x11: /* Selection time out-The initiator selection or target
- reselection was not complete within the SCSI Time out period */
- hosterr = DID_TIME_OUT;
- break;
-
- case 0x12: /* Data overrun/underrun-The target attempted to transfer more data
- than was allocated by the Data Length field or the sum of the
- Scatter / Gather Data Length fields. */
-
- case 0x13: /* Unexpected bus free-The target dropped the SCSI BSY at an unexpected time. */
-
- case 0x15: /* MBO command was not 00, 01 or 02-The first byte of the CB was
- invalid. This usually indicates a software failure. */
-
- case 0x16: /* Invalid CCB Operation Code-The first byte of the CCB was invalid.
- This usually indicates a software failure. */
-
- case 0x17: /* Linked CCB does not have the same LUN-A subsequent CCB of a set
- of linked CCB's does not specify the same logical unit number as
- the first. */
- case 0x18: /* Invalid Target Direction received from Host-The direction of a
- Target Mode CCB was invalid. */
-
- case 0x19: /* Duplicate CCB Received in Target Mode-More than once CCB was
- received to service data transfer between the same target LUN
- and initiator SCSI ID in the same direction. */
-
- case 0x1a: /* Invalid CCB or Segment List Parameter-A segment list with a zero
- length segment or invalid segment list boundaries was received.
- A CCB parameter was invalid. */
- DEB(printk("Aha1542: %x %x\n", hosterr, scsierr));
- hosterr = DID_ERROR; /* Couldn't find any better */
- break;
-
- case 0x14: /* Target bus phase sequence failure-An invalid bus phase or bus
- phase sequence was requested by the target. The host adapter
- will generate a SCSI Reset Condition, notifying the host with
- a SCRD interrupt */
- hosterr = DID_RESET;
- break;
- default:
- printk("makecode: unknown hoststatus %x\n", hosterr);
- break;
- }
- return scsierr|(hosterr << 16);
-}
-
-static int aha1542_test_port(int bse, struct Scsi_Host * shpnt)
-{
- int i;
- unchar inquiry_cmd[] = {CMD_INQUIRY };
- unchar inquiry_result[4];
- unchar *cmdp;
- int len;
- volatile int debug = 0;
-
- /* Quick and dirty test for presence of the card. */
- if(inb(STATUS(bse)) == 0xff) return 0;
-
- /* Reset the adapter. I ought to make a hard reset, but it's not really necessary */
-
- /* DEB(printk("aha1542_test_port called \n")); */
-
- /* In case some other card was probing here, reset interrupts */
- aha1542_intr_reset(bse); /* reset interrupts, so they don't block */
-
- outb(SRST|IRST/*|SCRST*/, CONTROL(bse));
-
- i = jiffies + 2;
- while (i>jiffies); /* Wait a little bit for things to settle down. */
-
- debug = 1;
- /* Expect INIT and IDLE, any of the others are bad */
- WAIT(STATUS(bse), STATMASK, INIT|IDLE, STST|DIAGF|INVDCMD|DF|CDF);
-
- debug = 2;
- /* Shouldn't have generated any interrupts during reset */
- if (inb(INTRFLAGS(bse))&INTRMASK) goto fail;
-
-
- /* Perform a host adapter inquiry instead so we do not need to set
- up the mailboxes ahead of time */
-
- aha1542_out(bse, inquiry_cmd, 1);
-
- debug = 3;
- len = 4;
- cmdp = &inquiry_result[0];
-
- while (len--)
- {
- WAIT(STATUS(bse), DF, DF, 0);
- *cmdp++ = inb(DATA(bse));
- }
-
- debug = 8;
- /* Reading port should reset DF */
- if (inb(STATUS(bse)) & DF) goto fail;
-
- debug = 9;
- /* When HACC, command is completed, and we're though testing */
- WAIT(INTRFLAGS(bse), HACC, HACC, 0);
- /* now initialize adapter */
-
- debug = 10;
- /* Clear interrupts */
- outb(IRST, CONTROL(bse));
-
- debug = 11;
-
- return debug; /* 1 = ok */
- fail:
- return 0; /* 0 = not ok */
-}
-
-/* A "high" level interrupt handler */
-static void aha1542_intr_handle(int irq, struct pt_regs *regs)
-{
- void (*my_done)(Scsi_Cmnd *) = NULL;
- int errstatus, mbi, mbo, mbistatus;
- int number_serviced;
- unsigned int flags;
- struct Scsi_Host * shost;
- Scsi_Cmnd * SCtmp;
- int flag;
- int needs_restart;
- struct mailbox * mb;
- struct ccb *ccb;
-
- shost = aha_host[irq - 9];
- if(!shost) panic("Splunge!");
-
- mb = HOSTDATA(shost)->mb;
- ccb = HOSTDATA(shost)->ccb;
-
-#ifdef DEBUG
- {
- flag = inb(INTRFLAGS(shost->io_port));
- printk("aha1542_intr_handle: ");
- if (!(flag&ANYINTR)) printk("no interrupt?");
- if (flag&MBIF) printk("MBIF ");
- if (flag&MBOA) printk("MBOF ");
- if (flag&HACC) printk("HACC ");
- if (flag&SCRD) printk("SCRD ");
- printk("status %02x\n", inb(STATUS(shost->io_port)));
- };
-#endif
- number_serviced = 0;
- needs_restart = 0;
-
- while(1==1){
- flag = inb(INTRFLAGS(shost->io_port));
-
- /* Check for unusual interrupts. If any of these happen, we should
- probably do something special, but for now just printing a message
- is sufficient. A SCSI reset detected is something that we really
- need to deal with in some way. */
- if (flag & ~MBIF) {
- if (flag&MBOA) printk("MBOF ");
- if (flag&HACC) printk("HACC ");
- if (flag&SCRD) {
- needs_restart = 1;
- printk("SCRD ");
- }
- }
-
- aha1542_intr_reset(shost->io_port);
-
- save_flags(flags);
- cli();
- mbi = HOSTDATA(shost)->aha1542_last_mbi_used + 1;
- if (mbi >= 2*AHA1542_MAILBOXES) mbi = AHA1542_MAILBOXES;
-
- do{
- if(mb[mbi].status != 0) break;
- mbi++;
- if (mbi >= 2*AHA1542_MAILBOXES) mbi = AHA1542_MAILBOXES;
- } while (mbi != HOSTDATA(shost)->aha1542_last_mbi_used);
-
- if(mb[mbi].status == 0){
- restore_flags(flags);
- /* Hmm, no mail. Must have read it the last time around */
- if (!number_serviced && !needs_restart)
- printk("aha1542.c: interrupt received, but no mail.\n");
- /* We detected a reset. Restart all pending commands for
- devices that use the hard reset option */
- if(needs_restart) aha1542_restart(shost);
- return;
- };
-
- mbo = (scsi2int(mb[mbi].ccbptr) - ((unsigned int) &ccb[0])) / sizeof(struct ccb);
- mbistatus = mb[mbi].status;
- mb[mbi].status = 0;
- HOSTDATA(shost)->aha1542_last_mbi_used = mbi;
- restore_flags(flags);
-
-#ifdef DEBUG
- {
- if (ccb[mbo].tarstat|ccb[mbo].hastat)
- printk("aha1542_command: returning %x (status %d)\n",
- ccb[mbo].tarstat + ((int) ccb[mbo].hastat << 16), mb[mbi].status);
- };
-#endif
-
- if(mbistatus == 3) continue; /* Aborted command not found */
-
-#ifdef DEBUG
- printk("...done %d %d\n",mbo, mbi);
-#endif
-
- SCtmp = HOSTDATA(shost)->SCint[mbo];
-
- if (!SCtmp || !SCtmp->scsi_done) {
- printk("aha1542_intr_handle: Unexpected interrupt\n");
- printk("tarstat=%x, hastat=%x idlun=%x ccb#=%d \n", ccb[mbo].tarstat,
- ccb[mbo].hastat, ccb[mbo].idlun, mbo);
- return;
- }
-
- my_done = SCtmp->scsi_done;
- if (SCtmp->host_scribble) scsi_free(SCtmp->host_scribble, 512);
-
- /* Fetch the sense data, and tuck it away, in the required slot. The
- Adaptec automatically fetches it, and there is no guarantee that
- we will still have it in the cdb when we come back */
- if (ccb[mbo].tarstat == 2)
- memcpy(SCtmp->sense_buffer, &ccb[mbo].cdb[ccb[mbo].cdblen],
- sizeof(SCtmp->sense_buffer));
-
-
- /* is there mail :-) */
-
- /* more error checking left out here */
- if (mbistatus != 1)
- /* This is surely wrong, but I don't know what's right */
- errstatus = makecode(ccb[mbo].hastat, ccb[mbo].tarstat);
- else
- errstatus = 0;
-
-#ifdef DEBUG
- if(errstatus) printk("(aha1542 error:%x %x %x) ",errstatus,
- ccb[mbo].hastat, ccb[mbo].tarstat);
-#endif
-
- if (ccb[mbo].tarstat == 2) {
-#ifdef DEBUG
- int i;
-#endif
- DEB(printk("aha1542_intr_handle: sense:"));
-#ifdef DEBUG
- for (i = 0; i < 12; i++)
- printk("%02x ", ccb[mbo].cdb[ccb[mbo].cdblen+i]);
- printk("\n");
-#endif
- /*
- DEB(printk("aha1542_intr_handle: buf:"));
- for (i = 0; i < bufflen; i++)
- printk("%02x ", ((unchar *)buff)[i]);
- printk("\n");
- */
- }
- DEB(if (errstatus) printk("aha1542_intr_handle: returning %6x\n", errstatus));
- SCtmp->result = errstatus;
- HOSTDATA(shost)->SCint[mbo] = NULL; /* This effectively frees up the mailbox slot, as
- far as queuecommand is concerned */
- my_done(SCtmp);
- number_serviced++;
- };
-}
-
-int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
-{
- unchar ahacmd = CMD_START_SCSI;
- unchar direction;
- unchar *cmd = (unchar *) SCpnt->cmnd;
- unchar target = SCpnt->target;
- unchar lun = SCpnt->lun;
- unsigned long flags;
- void *buff = SCpnt->request_buffer;
- int bufflen = SCpnt->request_bufflen;
- int mbo;
- struct mailbox * mb;
- struct ccb *ccb;
-
- DEB(int i);
-
- mb = HOSTDATA(SCpnt->host)->mb;
- ccb = HOSTDATA(SCpnt->host)->ccb;
-
- DEB(if (target > 1) {
- SCpnt->result = DID_TIME_OUT << 16;
- done(SCpnt); return 0;});
-
- if(*cmd == REQUEST_SENSE){
-#ifndef DEBUG
- if (bufflen != sizeof(SCpnt->sense_buffer)) {
- printk("Wrong buffer length supplied for request sense (%d)\n",bufflen);
- };
-#endif
- SCpnt->result = 0;
- done(SCpnt);
- return 0;
- };
-
-#ifdef DEBUG
- if (*cmd == READ_10 || *cmd == WRITE_10)
- i = xscsi2int(cmd+2);
- else if (*cmd == READ_6 || *cmd == WRITE_6)
- i = scsi2int(cmd+2);
- else
- i = -1;
- if (done)
- printk("aha1542_queuecommand: dev %d cmd %02x pos %d len %d ", target, *cmd, i, bufflen);
- else
- printk("aha1542_command: dev %d cmd %02x pos %d len %d ", target, *cmd, i, bufflen);
- aha1542_stat();
- printk("aha1542_queuecommand: dumping scsi cmd:");
- for (i = 0; i < SCpnt->cmd_len; i++) printk("%02x ", cmd[i]);
- printk("\n");
- if (*cmd == WRITE_10 || *cmd == WRITE_6)
- return 0; /* we are still testing, so *don't* write */
-#endif
-/* Use the outgoing mailboxes in a round-robin fashion, because this
- is how the host adapter will scan for them */
-
- save_flags(flags);
- cli();
- mbo = HOSTDATA(SCpnt->host)->aha1542_last_mbo_used + 1;
- if (mbo >= AHA1542_MAILBOXES) mbo = 0;
-
- do{
- if(mb[mbo].status == 0 && HOSTDATA(SCpnt->host)->SCint[mbo] == NULL)
- break;
- mbo++;
- if (mbo >= AHA1542_MAILBOXES) mbo = 0;
- } while (mbo != HOSTDATA(SCpnt->host)->aha1542_last_mbo_used);
-
- if(mb[mbo].status || HOSTDATA(SCpnt->host)->SCint[mbo])
- panic("Unable to find empty mailbox for aha1542.\n");
-
- HOSTDATA(SCpnt->host)->SCint[mbo] = SCpnt; /* This will effectively prevent someone else from
- screwing with this cdb. */
-
- HOSTDATA(SCpnt->host)->aha1542_last_mbo_used = mbo;
- restore_flags(flags);
-
-#ifdef DEBUG
- printk("Sending command (%d %x)...",mbo, done);
-#endif
-
- any2scsi(mb[mbo].ccbptr, &ccb[mbo]); /* This gets trashed for some reason*/
-
- memset(&ccb[mbo], 0, sizeof(struct ccb));
-
- ccb[mbo].cdblen = SCpnt->cmd_len;
-
- direction = 0;
- if (*cmd == READ_10 || *cmd == READ_6)
- direction = 8;
- else if (*cmd == WRITE_10 || *cmd == WRITE_6)
- direction = 16;
-
- memcpy(ccb[mbo].cdb, cmd, ccb[mbo].cdblen);
-
- if (SCpnt->use_sg) {
- struct scatterlist * sgpnt;
- struct chain * cptr;
-#ifdef DEBUG
- unsigned char * ptr;
-#endif
- int i;
- ccb[mbo].op = 2; /* SCSI Initiator Command w/scatter-gather*/
- SCpnt->host_scribble = (unsigned char *) scsi_malloc(512);
- sgpnt = (struct scatterlist *) SCpnt->request_buffer;
- cptr = (struct chain *) SCpnt->host_scribble;
- if (cptr == NULL) panic("aha1542.c: unable to allocate DMA memory\n");
- for(i=0; i<SCpnt->use_sg; i++) {
- if(sgpnt[i].length == 0 || SCpnt->use_sg > 16 ||
- (((int)sgpnt[i].address) & 1) || (sgpnt[i].length & 1)){
- unsigned char * ptr;
- printk("Bad segment list supplied to aha1542.c (%d, %d)\n",SCpnt->use_sg,i);
- for(i=0;i<SCpnt->use_sg;i++){
- printk("%d: %x %x %d\n",i,(unsigned int) sgpnt[i].address, (unsigned int) sgpnt[i].alt_address,
- sgpnt[i].length);
- };
- printk("cptr %x: ",(unsigned int) cptr);
- ptr = (unsigned char *) &cptr[i];
- for(i=0;i<18;i++) printk("%02x ", ptr[i]);
- panic("Foooooooood fight!");
- };
- any2scsi(cptr[i].dataptr, sgpnt[i].address);
- if(((unsigned int) sgpnt[i].address) & 0xff000000) goto baddma;
- any2scsi(cptr[i].datalen, sgpnt[i].length);
- };
- any2scsi(ccb[mbo].datalen, SCpnt->use_sg * sizeof(struct chain));
- any2scsi(ccb[mbo].dataptr, cptr);
-#ifdef DEBUG
- printk("cptr %x: ",cptr);
- ptr = (unsigned char *) cptr;
- for(i=0;i<18;i++) printk("%02x ", ptr[i]);
-#endif
- } else {
- ccb[mbo].op = 0; /* SCSI Initiator Command */
- SCpnt->host_scribble = NULL;
- any2scsi(ccb[mbo].datalen, bufflen);
- if(((unsigned int) buff & 0xff000000)) goto baddma;
- any2scsi(ccb[mbo].dataptr, buff);
- };
- ccb[mbo].idlun = (target&7)<<5 | direction | (lun & 7); /*SCSI Target Id*/
- ccb[mbo].rsalen = 12;
- ccb[mbo].linkptr[0] = ccb[mbo].linkptr[1] = ccb[mbo].linkptr[2] = 0;
- ccb[mbo].commlinkid = 0;
-
-#ifdef DEBUG
- { int i;
- printk("aha1542_command: sending.. ");
- for (i = 0; i < sizeof(ccb[mbo])-10; i++)
- printk("%02x ", ((unchar *)&ccb[mbo])[i]);
- };
-#endif
-
- if (done) {
- DEB(printk("aha1542_queuecommand: now waiting for interrupt "); aha1542_stat());
- SCpnt->scsi_done = done;
- mb[mbo].status = 1;
- aha1542_out(SCpnt->host->io_port, &ahacmd, 1); /* start scsi command */
- DEB(aha1542_stat());
- }
- else
- printk("aha1542_queuecommand: done can't be NULL\n");
-
- return 0;
- baddma:
- panic("Buffer at address > 16Mb used for 1542B");
-}
-
-static void internal_done(Scsi_Cmnd * SCpnt)
-{
- SCpnt->SCp.Status++;
-}
-
-int aha1542_command(Scsi_Cmnd * SCpnt)
-{
- DEB(printk("aha1542_command: ..calling aha1542_queuecommand\n"));
-
- aha1542_queuecommand(SCpnt, internal_done);
-
- SCpnt->SCp.Status = 0;
- while (!SCpnt->SCp.Status)
- barrier();
- return SCpnt->result;
-}
-
-/* Initialize mailboxes */
-static void setup_mailboxes(int bse, struct Scsi_Host * shpnt)
-{
- int i;
- struct mailbox * mb;
- struct ccb *ccb;
-
- unchar cmd[5] = {CMD_MBINIT, AHA1542_MAILBOXES, 0, 0, 0};
-
- mb = HOSTDATA(shpnt)->mb;
- ccb = HOSTDATA(shpnt)->ccb;
-
- for(i=0; i<AHA1542_MAILBOXES; i++){
- mb[i].status = mb[AHA1542_MAILBOXES+i].status = 0;
- any2scsi(mb[i].ccbptr, &ccb[i]);
- };
- aha1542_intr_reset(bse); /* reset interrupts, so they don't block */
- any2scsi((cmd+2), mb);
- aha1542_out(bse, cmd, 5);
- WAIT(INTRFLAGS(bse), INTRMASK, HACC, 0);
- while (0) {
- fail:
- printk("aha1542_detect: failed setting up mailboxes\n");
- }
- aha1542_intr_reset(bse);
-}
-
-static int aha1542_getconfig(int base_io, unsigned char * irq_level, unsigned char * dma_chan, unsigned char * scsi_id)
-{
- unchar inquiry_cmd[] = {CMD_RETCONF };
- unchar inquiry_result[3];
- int i;
- i = inb(STATUS(base_io));
- if (i & DF) {
- i = inb(DATA(base_io));
- };
- aha1542_out(base_io, inquiry_cmd, 1);
- aha1542_in(base_io, inquiry_result, 3);
- WAIT(INTRFLAGS(base_io), INTRMASK, HACC, 0);
- while (0) {
- fail:
- printk("aha1542_detect: query board settings\n");
- }
- aha1542_intr_reset(base_io);
- switch(inquiry_result[0]){
- case 0x80:
- *dma_chan = 7;
- break;
- case 0x40:
- *dma_chan = 6;
- break;
- case 0x20:
- *dma_chan = 5;
- break;
- case 0x01:
- printk("DMA priority 0 not available for Adaptec driver\n");
- return -1;
- case 0:
- /* This means that the adapter, although Adaptec 1542 compatible, doesn't use a DMA channel.
- Currently only aware of the BusLogic BT-445S VL-Bus adapter which needs this. */
- *dma_chan = 0xFF;
- break;
- default:
- printk("Unable to determine Adaptec DMA priority. Disabling board\n");
- return -1;
- };
- switch(inquiry_result[1]){
- case 0x40:
- *irq_level = 15;
- break;
- case 0x20:
- *irq_level = 14;
- break;
- case 0x8:
- *irq_level = 12;
- break;
- case 0x4:
- *irq_level = 11;
- break;
- case 0x2:
- *irq_level = 10;
- break;
- case 0x1:
- *irq_level = 9;
- break;
- default:
- printk("Unable to determine Adaptec IRQ level. Disabling board\n");
- return -1;
- };
- *scsi_id=inquiry_result[2] & 7;
- return 0;
-}
-
-/* This function should only be called for 1542C boards - we can detect
- the special firmware settings and unlock the board */
-
-static int aha1542_mbenable(int base)
-{
- static unchar mbenable_cmd[3];
- static unchar mbenable_result[2];
- int retval;
-
- retval = BIOS_TRANSLATION_6432;
-
- mbenable_cmd[0]=CMD_EXTBIOS;
- aha1542_out(base,mbenable_cmd,1);
- if(aha1542_in1(base,mbenable_result,2))
- return retval;
- WAITd(INTRFLAGS(base),INTRMASK,HACC,0,100);
- aha1542_intr_reset(base);
-
- if ((mbenable_result[0] & 0x08) || mbenable_result[1]) {
- mbenable_cmd[0]=CMD_MBENABLE;
- mbenable_cmd[1]=0;
- mbenable_cmd[2]=mbenable_result[1];
- if(mbenable_result[1] & 1) retval = BIOS_TRANSLATION_25563;
- aha1542_out(base,mbenable_cmd,3);
- WAIT(INTRFLAGS(base),INTRMASK,HACC,0);
- };
- while(0) {
-fail:
- printk("aha1542_mbenable: Mailbox init failed\n");
- }
-aha1542_intr_reset(base);
-return retval;
-}
-
-/* Query the board to find out if it is a 1542 or a 1740, or whatever. */
-static int aha1542_query(int base_io, int * transl)
-{
- unchar inquiry_cmd[] = {CMD_INQUIRY };
- unchar inquiry_result[4];
- int i;
- i = inb(STATUS(base_io));
- if (i & DF) {
- i = inb(DATA(base_io));
- };
- aha1542_out(base_io, inquiry_cmd, 1);
- aha1542_in(base_io, inquiry_result, 4);
- WAIT(INTRFLAGS(base_io), INTRMASK, HACC, 0);
- while (0) {
- fail:
- printk("aha1542_detect: query card type\n");
- }
- aha1542_intr_reset(base_io);
-
- *transl = BIOS_TRANSLATION_6432; /* Default case */
-
-/* For an AHA1740 series board, we ignore the board since there is a
- hardware bug which can lead to wrong blocks being returned if the board
- is operating in the 1542 emulation mode. Since there is an extended mode
- driver, we simply ignore the board and let the 1740 driver pick it up.
-*/
-
- if (inquiry_result[0] == 0x43) {
- printk("aha1542.c: Emulation mode not supported for AHA 174N hardware.\n");
- return 1;
- };
-
- /* Always call this - boards that do not support extended bios translation
- will ignore the command, and we will set the proper default */
-
- *transl = aha1542_mbenable(base_io);
-
- return 0;
-}
-
-/* called from init/main.c */
-void aha1542_setup( char *str, int *ints)
-{
- const char *ahausage = "aha1542: usage: aha1542=<PORTBASE>[,<BUSON>,<BUSOFF>[,<DMASPEED>]]\n";
- static int setup_idx = 0;
- int setup_portbase;
-
- if(setup_idx >= MAXBOARDS)
- {
- printk("aha1542: aha1542_setup called too many times! Bad LILO params ?\n");
- printk(" Entryline 1: %s\n",setup_str[0]);
- printk(" Entryline 2: %s\n",setup_str[1]);
- printk(" This line: %s\n",str);
- return;
- }
- if (ints[0] < 1 || ints[0] > 4)
- {
- printk("aha1542: %s\n", str );
- printk(ahausage);
- printk("aha1542: Wrong parameters may cause system malfunction.. We try anyway..\n");
- }
-
- setup_called[setup_idx]=ints[0];
- setup_str[setup_idx]=str;
-
- setup_portbase = ints[0] >= 1 ? ints[1] : 0; /* Preserve the default value.. */
- setup_buson [setup_idx] = ints[0] >= 2 ? ints[2] : 7;
- setup_busoff [setup_idx] = ints[0] >= 3 ? ints[3] : 5;
- if (ints[0] >= 4) {
- int atbt = -1;
- switch (ints[4]) {
- case 5:
- atbt = 0x00;
- break;
- case 6:
- atbt = 0x04;
- break;
- case 7:
- atbt = 0x01;
- break;
- case 8:
- atbt = 0x02;
- break;
- case 10:
- atbt = 0x03;
- break;
- default:
- printk("aha1542: %s\n", str );
- printk(ahausage);
- printk("aha1542: Valid values for DMASPEED are 5-8, 10 MB/s. Using jumper defaults.\n");
- break;
- }
- setup_dmaspeed[setup_idx] = atbt;
- }
-
- if (setup_portbase != 0)
- bases[setup_idx] = setup_portbase;
-
- ++setup_idx;
-}
-
-/* return non-zero on detection */
-int aha1542_detect(Scsi_Host_Template * tpnt)
-{
- unsigned char dma_chan;
- unsigned char irq_level;
- unsigned char scsi_id;
- unsigned long flags;
- unsigned int base_io;
- int trans;
- struct Scsi_Host * shpnt = NULL;
- int count = 0;
- int indx;
-
- DEB(printk("aha1542_detect: \n"));
-
- tpnt->proc_dir = &proc_scsi_aha1542;
-
- for(indx = 0; indx < sizeof(bases)/sizeof(bases[0]); indx++)
- if(bases[indx] != 0 && !check_region(bases[indx], 4)) {
- shpnt = scsi_register(tpnt,
- sizeof(struct aha1542_hostdata));
-
- /* For now we do this - until kmalloc is more intelligent
- we are resigned to stupid hacks like this */
- if ((unsigned int) shpnt > 0xffffff) {
- printk("Invalid address for shpnt with 1542.\n");
- goto unregister;
- }
-
- if(!aha1542_test_port(bases[indx], shpnt)) goto unregister;
-
-
- base_io = bases[indx];
-
- /* Set the Bus on/off-times as not to ruin floppy performance */
- {
- unchar oncmd[] = {CMD_BUSON_TIME, 7};
- unchar offcmd[] = {CMD_BUSOFF_TIME, 5};
-
- if(setup_called[indx])
- {
- oncmd[1] = setup_buson[indx];
- offcmd[1] = setup_busoff[indx];
- }
-
- aha1542_intr_reset(base_io);
- aha1542_out(base_io, oncmd, 2);
- WAIT(INTRFLAGS(base_io), INTRMASK, HACC, 0);
- aha1542_intr_reset(base_io);
- aha1542_out(base_io, offcmd, 2);
- WAIT(INTRFLAGS(base_io), INTRMASK, HACC, 0);
- if (setup_dmaspeed[indx] >= 0)
- {
- unchar dmacmd[] = {CMD_DMASPEED, 0};
- dmacmd[1] = setup_dmaspeed[indx];
- aha1542_intr_reset(base_io);
- aha1542_out(base_io, dmacmd, 2);
- WAIT(INTRFLAGS(base_io), INTRMASK, HACC, 0);
- }
- while (0) {
- fail:
- printk("aha1542_detect: setting bus on/off-time failed\n");
- }
- aha1542_intr_reset(base_io);
- }
- if(aha1542_query(base_io, &trans)) goto unregister;
-
- if (aha1542_getconfig(base_io, &irq_level, &dma_chan, &scsi_id) == -1) goto unregister;
-
- printk("Configuring Adaptec (SCSI-ID %d) at IO:%x, IRQ %d", scsi_id, base_io, irq_level);
- if (dma_chan != 0xFF)
- printk(", DMA priority %d", dma_chan);
- printk("\n");
-
- DEB(aha1542_stat());
- setup_mailboxes(base_io, shpnt);
-
- DEB(aha1542_stat());
-
- DEB(printk("aha1542_detect: enable interrupt channel %d\n", irq_level));
- save_flags(flags);
- cli();
- if (request_irq(irq_level,aha1542_intr_handle, 0, "aha1542")) {
- printk("Unable to allocate IRQ for adaptec controller.\n");
- goto unregister;
- }
-
- if (dma_chan != 0xFF) {
- if (request_dma(dma_chan,"aha1542")) {
- printk("Unable to allocate DMA channel for Adaptec.\n");
- free_irq(irq_level);
- goto unregister;
- }
-
- if (dma_chan >= 5) {
- outb((dma_chan - 4) | CASCADE, DMA_MODE_REG);
- outb(dma_chan - 4, DMA_MASK_REG);
- }
- }
- aha_host[irq_level - 9] = shpnt;
- shpnt->this_id = scsi_id;
- shpnt->unique_id = base_io;
- shpnt->io_port = base_io;
- shpnt->n_io_port = 4; /* Number of bytes of I/O space used */
- shpnt->dma_channel = dma_chan;
- shpnt->irq = irq_level;
- HOSTDATA(shpnt)->bios_translation = trans;
- if(trans == 2)
- printk("aha1542.c: Using extended bios translation\n");
- HOSTDATA(shpnt)->aha1542_last_mbi_used = (2*AHA1542_MAILBOXES - 1);
- HOSTDATA(shpnt)->aha1542_last_mbo_used = (AHA1542_MAILBOXES - 1);
- memset(HOSTDATA(shpnt)->SCint, 0, sizeof(HOSTDATA(shpnt)->SCint));
- restore_flags(flags);
-#if 0
- DEB(printk(" *** READ CAPACITY ***\n"));
-
- {
- unchar buf[8];
- static unchar cmd[] = { READ_CAPACITY, 0, 0, 0, 0, 0, 0, 0, 0, 0};
- int i;
-
- for (i = 0; i < sizeof(buf); ++i) buf[i] = 0x87;
- for (i = 0; i < 2; ++i)
- if (!aha1542_command(i, cmd, buf, sizeof(buf))) {
- printk("aha_detect: LU %d sector_size %d device_size %d\n",
- i, xscsi2int(buf+4), xscsi2int(buf));
- }
- }
-
- DEB(printk(" *** NOW RUNNING MY OWN TEST *** \n"));
-
- for (i = 0; i < 4; ++i)
- {
- unsigned char cmd[10];
- static buffer[512];
-
- cmd[0] = READ_10;
- cmd[1] = 0;
- xany2scsi(cmd+2, i);
- cmd[6] = 0;
- cmd[7] = 0;
- cmd[8] = 1;
- cmd[9] = 0;
- aha1542_command(0, cmd, buffer, 512);
- }
-#endif
- request_region(bases[indx], 4,"aha1542"); /* Register the IO ports that we use */
- count++;
- continue;
- unregister:
- scsi_unregister(shpnt);
- continue;
-
- };
-
- return count;
-}
-
-static int aha1542_restart(struct Scsi_Host * shost)
-{
- int i;
- int count = 0;
-#if 0
- unchar ahacmd = CMD_START_SCSI;
-#endif
-
- for(i=0; i< AHA1542_MAILBOXES; i++)
- if(HOSTDATA(shost)->SCint[i] &&
- !(HOSTDATA(shost)->SCint[i]->device->soft_reset))
- {
-#if 0
- HOSTDATA(shost)->mb[i].status = 1; /* Indicate ready to restart... */
-#endif
- count++;
- }
-
- printk("Potential to restart %d stalled commands...\n", count);
-#if 0
- /* start scsi command */
- if (count) aha1542_out(shost->io_port, &ahacmd, 1);
-#endif
- return 0;
-}
-
-/* The abort command does not leave the device in a clean state where
- it is available to be used again. Until this gets worked out, we will
- leave it commented out. */
-
-int aha1542_abort(Scsi_Cmnd * SCpnt)
-{
-#if 0
- unchar ahacmd = CMD_START_SCSI;
- unsigned long flags;
- struct mailbox * mb;
- int mbi, mbo, i;
-
- printk("In aha1542_abort: %x %x\n",
- inb(STATUS(SCpnt->host->io_port)),
- inb(INTRFLAGS(SCpnt->host->io_port)));
-
- save_flags(flags);
- cli();
- mb = HOSTDATA(SCpnt->host)->mb;
- mbi = HOSTDATA(SCpnt->host)->aha1542_last_mbi_used + 1;
- if (mbi >= 2*AHA1542_MAILBOXES) mbi = AHA1542_MAILBOXES;
-
- do{
- if(mb[mbi].status != 0) break;
- mbi++;
- if (mbi >= 2*AHA1542_MAILBOXES) mbi = AHA1542_MAILBOXES;
- } while (mbi != HOSTDATA(SCpnt->host)->aha1542_last_mbi_used);
- restore_flags(flags);
-
- if(mb[mbi].status) {
- printk("Lost interrupt discovered on irq %d - attempting to recover\n",
- SCpnt->host->irq);
- aha1542_intr_handle(SCpnt->host->irq, NULL);
- return 0;
- }
-
- /* OK, no lost interrupt. Try looking to see how many pending commands
- we think we have. */
-
- for(i=0; i< AHA1542_MAILBOXES; i++)
- if(HOSTDATA(SCpnt->host)->SCint[i])
- {
- if(HOSTDATA(SCpnt->host)->SCint[i] == SCpnt) {
- printk("Timed out command pending for %s\n",
- kdevname(SCpnt->request.rq_dev));
- if (HOSTDATA(SCpnt->host)->mb[i].status) {
- printk("OGMB still full - restarting\n");
- aha1542_out(SCpnt->host->io_port, &ahacmd, 1);
- };
- } else
- printk("Other pending command %s\n",
- kdevname(SCpnt->request.rq_dev));
- }
-
-#endif
-
- DEB(printk("aha1542_abort\n"));
-#if 0
- save_flags(flags);
- cli();
- for(mbo = 0; mbo < AHA1542_MAILBOXES; mbo++)
- if (SCpnt == HOSTDATA(SCpnt->host)->SCint[mbo]){
- mb[mbo].status = 2; /* Abort command */
- aha1542_out(SCpnt->host->io_port, &ahacmd, 1); /* start scsi command */
- restore_flags(flags);
- break;
- };
-#endif
- return SCSI_ABORT_SNOOZE;
-}
-
-/* We do not implement a reset function here, but the upper level code
- assumes that it will get some kind of response for the command in
- SCpnt. We must oblige, or the command will hang the scsi system.
- For a first go, we assume that the 1542 notifies us with all of the
- pending commands (it does implement soft reset, after all). */
-
-int aha1542_reset(Scsi_Cmnd * SCpnt)
-{
- unchar ahacmd = CMD_START_SCSI;
- int i;
-
- /*
- * See if a bus reset was suggested.
- */
- if( SCpnt->host->suggest_bus_reset )
- {
- /*
- * This does a scsi reset for all devices on the bus.
- * In principle, we could also reset the 1542 - should
- * we do this? Try this first, and we can add that later
- * if it turns out to be useful.
- */
- outb(HRST | SCRST, CONTROL(SCpnt->host->io_port));
-
- /*
- * Wait for the thing to settle down a bit. Unfortunately
- * this is going to basically lock up the machine while we
- * wait for this to complete. To be 100% correct, we need to
- * check for timeout, and if we are doing something like this
- * we are pretty desperate anyways.
- */
- WAIT(STATUS(SCpnt->host->io_port),
- STATMASK, INIT|IDLE, STST|DIAGF|INVDCMD|DF|CDF);
-
- /*
- * We need to do this too before the 1542 can interact with
- * us again.
- */
- setup_mailboxes(SCpnt->host->io_port, SCpnt->host);
-
- /*
- * Now try and pick up the pieces. Restart all commands
- * that are currently active on the bus, and reset all of
- * the datastructures. We have some time to kill while
- * things settle down, so print a nice message.
- */
- printk("Sent BUS RESET to scsi host %d\n", SCpnt->host->host_no);
-
- for(i=0; i< AHA1542_MAILBOXES; i++)
- if(HOSTDATA(SCpnt->host)->SCint[i] != NULL)
- {
- Scsi_Cmnd * SCtmp;
- SCtmp = HOSTDATA(SCpnt->host)->SCint[i];
- SCtmp->result = DID_RESET << 16;
- if (SCtmp->host_scribble) scsi_free(SCtmp->host_scribble, 512);
- printk("Sending DID_RESET for target %d\n", SCpnt->target);
- SCtmp->scsi_done(SCpnt);
-
- HOSTDATA(SCpnt->host)->SCint[i] = NULL;
- HOSTDATA(SCpnt->host)->mb[i].status = 0;
- }
- /*
- * Now tell the mid-level code what we did here. Since
- * we have restarted all of the outstanding commands,
- * then report SUCCESS.
- */
- return (SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET);
-fail:
- printk("aha1542.c: Unable to perform hard reset.\n");
- printk("Power cycle machine to reset\n");
- return (SCSI_RESET_ERROR | SCSI_RESET_BUS_RESET);
-
-
- }
- else
- {
- /* This does a selective reset of just the one device */
- /* First locate the ccb for this command */
- for(i=0; i< AHA1542_MAILBOXES; i++)
- if(HOSTDATA(SCpnt->host)->SCint[i] == SCpnt)
- {
- HOSTDATA(SCpnt->host)->ccb[i].op = 0x81; /* BUS DEVICE RESET */
- /* Now tell the 1542 to flush all pending commands for this target */
- aha1542_out(SCpnt->host->io_port, &ahacmd, 1);
-
- /* Here is the tricky part. What to do next. Do we get an interrupt
- for the commands that we aborted with the specified target, or
- do we generate this on our own? Try it without first and see
- what happens */
- printk("Sent BUS DEVICE RESET to target %d\n", SCpnt->target);
-
- /* If the first does not work, then try the second. I think the
- first option is more likely to be correct. Free the command
- block for all commands running on this target... */
- for(i=0; i< AHA1542_MAILBOXES; i++)
- if(HOSTDATA(SCpnt->host)->SCint[i] &&
- HOSTDATA(SCpnt->host)->SCint[i]->target == SCpnt->target)
- {
- Scsi_Cmnd * SCtmp;
- SCtmp = HOSTDATA(SCpnt->host)->SCint[i];
- SCtmp->result = DID_RESET << 16;
- if (SCtmp->host_scribble) scsi_free(SCtmp->host_scribble, 512);
- printk("Sending DID_RESET for target %d\n", SCpnt->target);
- SCtmp->scsi_done(SCpnt);
-
- HOSTDATA(SCpnt->host)->SCint[i] = NULL;
- HOSTDATA(SCpnt->host)->mb[i].status = 0;
- }
- return SCSI_RESET_SUCCESS;
- }
- }
- /* No active command at this time, so this means that each time we got
- some kind of response the last time through. Tell the mid-level code
- to request sense information in order to decide what to do next. */
- return SCSI_RESET_PUNT;
-}
-
-#include "sd.h"
-
-int aha1542_biosparam(Scsi_Disk * disk, kdev_t dev, int * ip)
-{
- int translation_algorithm;
- int size = disk->capacity;
-
- translation_algorithm = HOSTDATA(disk->device->host)->bios_translation;
- /* Should this be > 1024, or >= 1024? Enquiring minds want to know. */
- if((size>>11) > 1024 && translation_algorithm == 2) {
- /* Please verify that this is the same as what DOS returns */
- ip[0] = 255;
- ip[1] = 63;
- ip[2] = size /255/63;
- } else {
- ip[0] = 64;
- ip[1] = 32;
- ip[2] = size >> 11;
- };
-/* if (ip[2] >= 1024) ip[2] = 1024; */
- return 0;
-}
-
-
-#ifdef MODULE
-/* Eventually this will go into an include file, but this will be later */
-Scsi_Host_Template driver_template = AHA1542;
-
-#include "scsi_module.c"
-#endif
-
diff --git a/i386/i386at/gpl/linux/scsi/aha1542.h b/i386/i386at/gpl/linux/scsi/aha1542.h
deleted file mode 100644
index 4e0c6503..00000000
--- a/i386/i386at/gpl/linux/scsi/aha1542.h
+++ /dev/null
@@ -1,177 +0,0 @@
-#ifndef _AHA1542_H
-
-/* $Id: aha1542.h,v 1.1.1.1 1997/02/25 21:27:46 thomas Exp $
- *
- * Header file for the adaptec 1542 driver for Linux
- *
- * $Log: aha1542.h,v $
- * Revision 1.1.1.1 1996/10/30 01:40:02 thomas
- * Imported from UK22
- *
- * Revision 1.1 1996/03/25 20:25:20 goel
- * Linux driver merge.
- *
- * Revision 1.1 1992/07/24 06:27:38 root
- * Initial revision
- *
- * Revision 1.2 1992/07/04 18:41:49 root
- * Replaced distribution with current drivers
- *
- * Revision 1.3 1992/06/23 23:58:20 root
- * Fixes.
- *
- * Revision 1.2 1992/05/26 22:13:23 root
- * Changed bug that prevented DMA above first 2 mbytes.
- *
- * Revision 1.1 1992/05/22 21:00:29 root
- * Initial revision
- *
- * Revision 1.1 1992/04/24 18:01:50 root
- * Initial revision
- *
- * Revision 1.1 1992/04/02 03:23:13 drew
- * Initial revision
- *
- * Revision 1.3 1992/01/27 14:46:29 tthorn
- * *** empty log message ***
- *
- */
-
-#include <linux/types.h>
-#include <linux/kdev_t.h>
-
-/* I/O Port interface 4.2 */
-/* READ */
-#define STATUS(base) base
-#define STST 0x80 /* Self Test in Progress */
-#define DIAGF 0x40 /* Internal Diagnostic Failure */
-#define INIT 0x20 /* Mailbox Initialization Required */
-#define IDLE 0x10 /* SCSI Host Adapter Idle */
-#define CDF 0x08 /* Command/Data Out Port Full */
-#define DF 0x04 /* Data In Port Full */
-#define INVDCMD 0x01 /* Invalid H A Command */
-#define STATMASK 0xfd /* 0x02 is reserved */
-
-#define INTRFLAGS(base) (STATUS(base)+2)
-#define ANYINTR 0x80 /* Any Interrupt */
-#define SCRD 0x08 /* SCSI Reset Detected */
-#define HACC 0x04 /* HA Command Complete */
-#define MBOA 0x02 /* MBO Empty */
-#define MBIF 0x01 /* MBI Full */
-#define INTRMASK 0x8f
-
-/* WRITE */
-#define CONTROL(base) STATUS(base)
-#define HRST 0x80 /* Hard Reset */
-#define SRST 0x40 /* Soft Reset */
-#define IRST 0x20 /* Interrupt Reset */
-#define SCRST 0x10 /* SCSI Bus Reset */
-
-/* READ/WRITE */
-#define DATA(base) (STATUS(base)+1)
-#define CMD_NOP 0x00 /* No Operation */
-#define CMD_MBINIT 0x01 /* Mailbox Initialization */
-#define CMD_START_SCSI 0x02 /* Start SCSI Command */
-#define CMD_INQUIRY 0x04 /* Adapter Inquiry */
-#define CMD_EMBOI 0x05 /* Enable MailBox Out Interrupt */
-#define CMD_BUSON_TIME 0x07 /* Set Bus-On Time */
-#define CMD_BUSOFF_TIME 0x08 /* Set Bus-Off Time */
-#define CMD_DMASPEED 0x09 /* Set AT Bus Transfer Speed */
-#define CMD_RETDEVS 0x0a /* Return Installed Devices */
-#define CMD_RETCONF 0x0b /* Return Configuration Data */
-#define CMD_RETSETUP 0x0d /* Return Setup Data */
-#define CMD_ECHO 0x1f /* ECHO Command Data */
-
-#define CMD_EXTBIOS 0x28 /* Return extend bios information only 1542C */
-#define CMD_MBENABLE 0x29 /* Set Mailbox Interface enable only 1542C */
-
-/* Mailbox Definition 5.2.1 and 5.2.2 */
-struct mailbox {
- unchar status; /* Command/Status */
- unchar ccbptr[3]; /* msb, .., lsb */
-};
-
-/* This is used with scatter-gather */
-struct chain {
- unchar datalen[3]; /* Size of this part of chain */
- unchar dataptr[3]; /* Location of data */
-};
-
-/* These belong in scsi.h also */
-#define any2scsi(up, p) \
-(up)[0] = (((unsigned long)(p)) >> 16) ; \
-(up)[1] = (((unsigned long)(p)) >> 8); \
-(up)[2] = ((unsigned long)(p));
-
-#define scsi2int(up) ( (((long)*(up)) << 16) + (((long)(up)[1]) << 8) + ((long)(up)[2]) )
-
-#define xany2scsi(up, p) \
-(up)[0] = ((long)(p)) >> 24; \
-(up)[1] = ((long)(p)) >> 16; \
-(up)[2] = ((long)(p)) >> 8; \
-(up)[3] = ((long)(p));
-
-#define xscsi2int(up) ( (((long)(up)[0]) << 24) + (((long)(up)[1]) << 16) \
- + (((long)(up)[2]) << 8) + ((long)(up)[3]) )
-
-#define MAX_CDB 12
-#define MAX_SENSE 14
-
-struct ccb { /* Command Control Block 5.3 */
- unchar op; /* Command Control Block Operation Code */
- unchar idlun; /* op=0,2:Target Id, op=1:Initiator Id */
- /* Outbound data transfer, length is checked*/
- /* Inbound data transfer, length is checked */
- /* Logical Unit Number */
- unchar cdblen; /* SCSI Command Length */
- unchar rsalen; /* Request Sense Allocation Length/Disable */
- unchar datalen[3]; /* Data Length (msb, .., lsb) */
- unchar dataptr[3]; /* Data Pointer */
- unchar linkptr[3]; /* Link Pointer */
- unchar commlinkid; /* Command Linking Identifier */
- unchar hastat; /* Host Adapter Status (HASTAT) */
- unchar tarstat; /* Target Device Status */
- unchar reserved[2];
- unchar cdb[MAX_CDB+MAX_SENSE];/* SCSI Command Descriptor Block */
- /* REQUEST SENSE */
-};
-
-int aha1542_detect(Scsi_Host_Template *);
-int aha1542_command(Scsi_Cmnd *);
-int aha1542_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-int aha1542_abort(Scsi_Cmnd *);
-int aha1542_reset(Scsi_Cmnd *);
-int aha1542_biosparam(Disk *, kdev_t, int*);
-
-#define AHA1542_MAILBOXES 8
-#define AHA1542_SCATTER 16
-#define AHA1542_CMDLUN 1
-
-#ifndef NULL
- #define NULL 0
-#endif
-
-extern struct proc_dir_entry proc_scsi_aha1542;
-
-#define AHA1542 { NULL, NULL, \
- &proc_scsi_aha1542,/* proc_dir_entry */ \
- NULL, \
- "Adaptec 1542", \
- aha1542_detect, \
- NULL, \
- NULL, \
- aha1542_command, \
- aha1542_queuecommand, \
- aha1542_abort, \
- aha1542_reset, \
- NULL, \
- aha1542_biosparam, \
- AHA1542_MAILBOXES, \
- 7, \
- AHA1542_SCATTER, \
- AHA1542_CMDLUN, \
- 0, \
- 1, \
- ENABLE_CLUSTERING}
-
-#endif
diff --git a/i386/i386at/gpl/linux/scsi/aha1740.c b/i386/i386at/gpl/linux/scsi/aha1740.c
deleted file mode 100644
index 250aa1b8..00000000
--- a/i386/i386at/gpl/linux/scsi/aha1740.c
+++ /dev/null
@@ -1,531 +0,0 @@
-/* $Id: aha1740.c,v 1.2 1997/03/24 21:51:17 thomas Exp $
- * 1993/03/31
- * linux/kernel/aha1740.c
- *
- * Based loosely on aha1542.c which is
- * Copyright (C) 1992 Tommy Thorn and
- * Modified by Eric Youngdale
- *
- * This file is aha1740.c, written and
- * Copyright (C) 1992,1993 Brad McLean
- *
- * Modifications to makecode and queuecommand
- * for proper handling of multiple devices courteously
- * provided by Michael Weller, March, 1993
- *
- * aha1740_makecode may still need even more work
- * if it doesn't work for your devices, take a look.
- */
-
-#ifdef MODULE
-#include <linux/module.h>
-#endif
-
-#include <linux/kernel.h>
-#include <linux/head.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/proc_fs.h>
-#include <linux/sched.h>
-#include <asm/dma.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <linux/blk.h>
-#include "scsi.h"
-#include "hosts.h"
-#include "sd.h"
-
-#include "aha1740.h"
-#include<linux/stat.h>
-
-struct proc_dir_entry proc_scsi_aha1740 = {
- PROC_SCSI_AHA1740, 7, "aha1740",
- S_IFDIR | S_IRUGO | S_IXUGO, 2
-};
-
-/* IF YOU ARE HAVING PROBLEMS WITH THIS DRIVER, AND WANT TO WATCH
- IT WORK, THEN:
-#define DEBUG
-*/
-#ifdef DEBUG
-#define DEB(x) x
-#else
-#define DEB(x)
-#endif
-
-/*
-static const char RCSid[] = "$Header: cvs/gnumach/i386/i386at/gpl/linux/scsi/Attic/aha1740.c,v 1.2 1997/03/24 21:51:17 thomas Exp $";
-*/
-
-static unsigned int slot, base;
-static unsigned char irq_level;
-
-static struct ecb ecb[AHA1740_ECBS]; /* One for each queued operation */
-
-static int aha1740_last_ecb_used = 0; /* optimization */
-
-int aha1740_makecode(unchar *sense, unchar *status)
-{
- struct statusword
- {
- ushort don:1, /* Command Done - No Error */
- du:1, /* Data underrun */
- :1, qf:1, /* Queue full */
- sc:1, /* Specification Check */
- dor:1, /* Data overrun */
- ch:1, /* Chaining Halted */
- intr:1, /* Interrupt issued */
- asa:1, /* Additional Status Available */
- sns:1, /* Sense information Stored */
- :1, ini:1, /* Initialization Required */
- me:1, /* Major error or exception */
- :1, eca:1, /* Extended Contingent alliance */
- :1;
- } status_word;
- int retval = DID_OK;
-
- status_word = * (struct statusword *) status;
-#ifdef DEBUG
-printk("makecode from %x,%x,%x,%x %x,%x,%x,%x",status[0],status[1],status[2],status[3],
-sense[0],sense[1],sense[2],sense[3]);
-#endif
- if (!status_word.don) /* Anything abnormal was detected */
- {
- if ( (status[1]&0x18) || status_word.sc ) /*Additional info available*/
- {
- /* Use the supplied info for further diagnostics */
- switch ( status[2] )
- {
- case 0x12:
- if ( status_word.dor )
- retval=DID_ERROR; /* It's an Overrun */
- /* If not overrun, assume underrun and ignore it! */
- case 0x00: /* No info, assume no error, should not occur */
- break;
- case 0x11:
- case 0x21:
- retval=DID_TIME_OUT;
- break;
- case 0x0a:
- retval=DID_BAD_TARGET;
- break;
- case 0x04:
- case 0x05:
- retval=DID_ABORT; /* Either by this driver or the AHA1740
- itself */
- break;
- default:
- retval=DID_ERROR; /* No further diagnostics possible */
- }
- }
- else
- { /* Michael suggests, and Brad concurs: */
- if ( status_word.qf )
- {
- retval = DID_TIME_OUT; /* forces a redo */
- /* I think this specific one should not happen -Brad */
- printk("aha1740.c: WARNING: AHA1740 queue overflow!\n");
- }
- else if ( status[0]&0x60 )
- {
- retval = DID_ERROR; /* Didn't find a better error */
- }
- /* In any other case return DID_OK so for example
- CONDITION_CHECKS make it through to the appropriate
- device driver */
- }
- }
- /* Under all circumstances supply the target status -Michael */
- return status[3] | retval << 16;
-}
-
-int aha1740_test_port(void)
-{
- char name[4],tmp;
-
- /* Okay, look for the EISA ID's */
- name[0]= 'A' -1 + ((tmp = inb(HID0)) >> 2); /* First character */
- name[1]= 'A' -1 + ((tmp & 3) << 3);
- name[1]+= ((tmp = inb(HID1)) >> 5)&0x7; /* Second Character */
- name[2]= 'A' -1 + (tmp & 0x1f); /* Third Character */
- name[3]=0;
- tmp = inb(HID2);
- if ( strcmp ( name, HID_MFG ) || inb(HID2) != HID_PRD )
- return 0; /* Not an Adaptec 174x */
-
-/* if ( inb(HID3) != HID_REV )
- printk("aha1740: Warning; board revision of %d; expected %d\n",
- inb(HID3),HID_REV); */
-
- if ( inb(EBCNTRL) != EBCNTRL_VALUE )
- {
- printk("aha1740: Board detected, but EBCNTRL = %x, so disabled it.\n",
- inb(EBCNTRL));
- return 0;
- }
-
- /* Try and turn on enhanced mode */
- tmp = inb (PORTADR);
- outb (PORTADR, tmp | PORTADDR_ENH);
- if ( inb(PORTADR) & PORTADDR_ENH )
- return 1; /* Okay, we're all set */
-
- printk("aha1740: Board detected, but not in enhanced mode, so disabled it.\n");
- return 0;
-}
-
-/* A "high" level interrupt handler */
-void aha1740_intr_handle(int irq, struct pt_regs * regs)
-{
- void (*my_done)(Scsi_Cmnd *);
- int errstatus, adapstat;
- int number_serviced;
- struct ecb *ecbptr;
- Scsi_Cmnd *SCtmp;
-
- number_serviced = 0;
-
- while(inb(G2STAT) & G2STAT_INTPEND)
- {
- DEB(printk("aha1740_intr top of loop.\n"));
- adapstat = inb(G2INTST);
- ecbptr = (struct ecb *) bus_to_virt(inl(MBOXIN0));
- outb(G2CNTRL_IRST,G2CNTRL); /* interrupt reset */
-
- switch ( adapstat & G2INTST_MASK )
- {
- case G2INTST_CCBRETRY:
- case G2INTST_CCBERROR:
- case G2INTST_CCBGOOD:
- outb(G2CNTRL_HRDY,G2CNTRL); /* Host Ready -> Mailbox in complete */
- if (!ecbptr)
- {
- printk("Aha1740 null ecbptr in interrupt (%x,%x,%x,%d)\n",
- inb(G2STAT),adapstat,inb(G2INTST),number_serviced++);
- continue;
- }
- SCtmp = ecbptr->SCpnt;
- if (!SCtmp)
- {
- printk("Aha1740 null SCtmp in interrupt (%x,%x,%x,%d)\n",
- inb(G2STAT),adapstat,inb(G2INTST),number_serviced++);
- continue;
- }
- if (SCtmp->host_scribble)
- scsi_free(SCtmp->host_scribble, 512);
- /* Fetch the sense data, and tuck it away, in the required slot. The
- Adaptec automatically fetches it, and there is no guarantee that
- we will still have it in the cdb when we come back */
- if ( (adapstat & G2INTST_MASK) == G2INTST_CCBERROR )
- {
- memcpy(SCtmp->sense_buffer, ecbptr->sense,
- sizeof(SCtmp->sense_buffer));
- errstatus = aha1740_makecode(ecbptr->sense,ecbptr->status);
- }
- else
- errstatus = 0;
- DEB(if (errstatus) printk("aha1740_intr_handle: returning %6x\n", errstatus));
- SCtmp->result = errstatus;
- my_done = ecbptr->done;
- memset(ecbptr,0,sizeof(struct ecb));
- if ( my_done )
- my_done(SCtmp);
- break;
- case G2INTST_HARDFAIL:
- printk("aha1740 hardware failure!\n");
- panic("aha1740.c"); /* Goodbye */
- case G2INTST_ASNEVENT:
- printk("aha1740 asynchronous event: %02x %02x %02x %02x %02x\n",adapstat,
- inb(MBOXIN0),inb(MBOXIN1),inb(MBOXIN2),inb(MBOXIN3)); /* Say What? */
- outb(G2CNTRL_HRDY,G2CNTRL); /* Host Ready -> Mailbox in complete */
- break;
- case G2INTST_CMDGOOD:
- /* set immediate command success flag here: */
- break;
- case G2INTST_CMDERROR:
- /* Set immediate command failure flag here: */
- break;
- }
- number_serviced++;
- }
-}
-
-int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
-{
- unchar direction;
- unchar *cmd = (unchar *) SCpnt->cmnd;
- unchar target = SCpnt->target;
- unsigned long flags;
- void *buff = SCpnt->request_buffer;
- int bufflen = SCpnt->request_bufflen;
- int ecbno;
- DEB(int i);
-
-
- if(*cmd == REQUEST_SENSE)
- {
- if (bufflen != sizeof(SCpnt->sense_buffer))
- {
- printk("Wrong buffer length supplied for request sense (%d)\n",bufflen);
- }
- SCpnt->result = 0;
- done(SCpnt);
- return 0;
- }
-
-#ifdef DEBUG
- if (*cmd == READ_10 || *cmd == WRITE_10)
- i = xscsi2int(cmd+2);
- else if (*cmd == READ_6 || *cmd == WRITE_6)
- i = scsi2int(cmd+2);
- else
- i = -1;
- printk("aha1740_queuecommand: dev %d cmd %02x pos %d len %d ", target, *cmd, i, bufflen);
- printk("scsi cmd:");
- for (i = 0; i < SCpnt->cmd_len; i++) printk("%02x ", cmd[i]);
- printk("\n");
-#endif
-
- /* locate an available ecb */
-
- save_flags(flags);
- cli();
- ecbno = aha1740_last_ecb_used + 1; /* An optimization */
- if (ecbno >= AHA1740_ECBS) ecbno = 0;
-
- do{
- if( ! ecb[ecbno].cmdw )
- break;
- ecbno++;
- if (ecbno >= AHA1740_ECBS ) ecbno = 0;
- } while (ecbno != aha1740_last_ecb_used);
-
- if( ecb[ecbno].cmdw )
- panic("Unable to find empty ecb for aha1740.\n");
-
- ecb[ecbno].cmdw = AHA1740CMD_INIT; /* SCSI Initiator Command doubles as reserved flag */
-
- aha1740_last_ecb_used = ecbno;
- restore_flags(flags);
-
-#ifdef DEBUG
- printk("Sending command (%d %x)...",ecbno, done);
-#endif
-
- ecb[ecbno].cdblen = SCpnt->cmd_len; /* SCSI Command Descriptor Block Length */
-
- direction = 0;
- if (*cmd == READ_10 || *cmd == READ_6)
- direction = 1;
- else if (*cmd == WRITE_10 || *cmd == WRITE_6)
- direction = 0;
-
- memcpy(ecb[ecbno].cdb, cmd, ecb[ecbno].cdblen);
-
- if (SCpnt->use_sg)
- {
- struct scatterlist * sgpnt;
- struct aha1740_chain * cptr;
- int i;
-#ifdef DEBUG
- unsigned char * ptr;
-#endif
- ecb[ecbno].sg = 1; /* SCSI Initiator Command w/scatter-gather*/
- SCpnt->host_scribble = (unsigned char *) scsi_malloc(512);
- sgpnt = (struct scatterlist *) SCpnt->request_buffer;
- cptr = (struct aha1740_chain *) SCpnt->host_scribble;
- if (cptr == NULL) panic("aha1740.c: unable to allocate DMA memory\n");
- for(i=0; i<SCpnt->use_sg; i++)
- {
- cptr[i].dataptr = (long) sgpnt[i].address;
- cptr[i].datalen = sgpnt[i].length;
- }
- ecb[ecbno].datalen = SCpnt->use_sg * sizeof(struct aha1740_chain);
- ecb[ecbno].dataptr = (long) cptr;
-#ifdef DEBUG
- printk("cptr %x: ",cptr);
- ptr = (unsigned char *) cptr;
- for(i=0;i<24;i++) printk("%02x ", ptr[i]);
-#endif
- }
- else
- {
- SCpnt->host_scribble = NULL;
- ecb[ecbno].datalen = bufflen;
- ecb[ecbno].dataptr = (long) buff;
- }
- ecb[ecbno].lun = SCpnt->lun;
- ecb[ecbno].ses = 1; /* Suppress underrun errors */
- ecb[ecbno].dir= direction;
- ecb[ecbno].ars=1; /* Yes, get the sense on an error */
- ecb[ecbno].senselen = 12;
- ecb[ecbno].senseptr = (long) ecb[ecbno].sense;
- ecb[ecbno].statusptr = (long) ecb[ecbno].status;
- ecb[ecbno].done = done;
- ecb[ecbno].SCpnt = SCpnt;
-#ifdef DEBUG
- {
- int i;
- printk("aha1740_command: sending.. ");
- for (i = 0; i < sizeof(ecb[ecbno])-10; i++)
- printk("%02x ", ((unchar *)&ecb[ecbno])[i]);
- }
- printk("\n");
-#endif
- if (done)
- { /* You may question the code below, which contains potentially
- non-terminating while loops with interrupts disabled. So did
- I when I wrote it, but the Adaptec Spec says the card is so fast,
- that this problem virtually never occurs so I've kept it. We
- do printk a warning first, so that you'll know if it happens.
- In practice the only time we've seen this message is when some-
- thing else is in the driver was broken, like _makecode(), or
- when a scsi device hung the scsi bus. Even under these conditions,
- The loop actually only cycled < 3 times (we instrumented it). */
-
- DEB(printk("aha1740[%d] critical section\n",ecbno));
- save_flags(flags);
- cli();
- if ( ! (inb(G2STAT) & G2STAT_MBXOUT) )
- {
- printk("aha1740[%d]_mbxout wait!\n",ecbno);
- cli(); /* printk may have done a sti()! */
- }
- mb();
- while ( ! (inb(G2STAT) & G2STAT_MBXOUT) ); /* Oh Well. */
- outl(virt_to_bus(ecb+ecbno), MBOXOUT0);
- if ( inb(G2STAT) & G2STAT_BUSY )
- {
- printk("aha1740[%d]_attn wait!\n",ecbno);
- cli();
- }
- while ( inb(G2STAT) & G2STAT_BUSY ); /* And Again! */
- outb(ATTN_START | (target & 7), ATTN); /* Start it up */
- restore_flags(flags);
- DEB(printk("aha1740[%d] request queued.\n",ecbno));
- }
- else
- printk("aha1740_queuecommand: done can't be NULL\n");
-
- return 0;
-}
-
-static volatile int internal_done_flag = 0;
-static volatile int internal_done_errcode = 0;
-
-static void internal_done(Scsi_Cmnd * SCpnt)
-{
- internal_done_errcode = SCpnt->result;
- ++internal_done_flag;
-}
-
-int aha1740_command(Scsi_Cmnd * SCpnt)
-{
- aha1740_queuecommand(SCpnt, internal_done);
-
- while (!internal_done_flag);
- internal_done_flag = 0;
- return internal_done_errcode;
-}
-
-/* Query the board for its irq_level. Nothing else matters
- in enhanced mode on an EISA bus. */
-
-void aha1740_getconfig(void)
-{
- static int intab[] = { 9,10,11,12,0,14,15,0 };
-
- irq_level = intab [ inb(INTDEF)&0x7 ];
- outb(inb(INTDEF) | 0x10, INTDEF);
-}
-
-int aha1740_detect(Scsi_Host_Template * tpnt)
-{
- tpnt->proc_dir = &proc_scsi_aha1740;
-
- memset(&ecb, 0, sizeof(struct ecb));
- DEB(printk("aha1740_detect: \n"));
-
- for ( slot=MINEISA; slot <= MAXEISA; slot++ )
- {
- base = SLOTBASE(slot);
- /*
- * The ioports for eisa boards are generally beyond that used in the
- * check/allocate region code, but this may change at some point,
- * so we go through the motions.
- */
- if(check_region(base, 0x5c)) continue; /* See if in use */
- if ( aha1740_test_port()) break;
- }
- if ( slot > MAXEISA )
- return 0;
-
- aha1740_getconfig();
-
- if ( (inb(G2STAT) & (G2STAT_MBXOUT | G2STAT_BUSY) ) != G2STAT_MBXOUT )
- { /* If the card isn't ready, hard reset it */
- outb(G2CNTRL_HRST,G2CNTRL);
- outb(0,G2CNTRL);
- }
-
- printk("Configuring Adaptec at IO:%x, IRQ %d\n",base,
- irq_level);
-
- DEB(printk("aha1740_detect: enable interrupt channel %d\n", irq_level));
-
- if (request_irq(irq_level,aha1740_intr_handle, 0, "aha1740"))
- {
- printk("Unable to allocate IRQ for adaptec controller.\n");
- return 0;
- }
- request_region(base, 0x5c,"aha1740"); /* Reserve the space that we need to use */
- return 1;
-}
-
-/* Note: They following two functions do not apply very well to the Adaptec,
-which basically manages its own affairs quite well without our interference,
-so I haven't put anything into them. I can faintly imagine someone with a
-*very* badly behaved SCSI target (perhaps an old tape?) wanting the abort(),
-but it hasn't happened yet, and doing aborts brings the Adaptec to its
-knees. I cannot (at this moment in time) think of any reason to reset the
-card once it's running. So there. */
-
-int aha1740_abort(Scsi_Cmnd * SCpnt)
-{
- DEB(printk("aha1740_abort called\n"));
- return SCSI_ABORT_SNOOZE;
-}
-
-/* We do not implement a reset function here, but the upper level code assumes
- that it will get some kind of response for the command in SCpnt. We must
- oblige, or the command will hang the scsi system */
-
-int aha1740_reset(Scsi_Cmnd * SCpnt)
-{
- DEB(printk("aha1740_reset called\n"));
- return SCSI_RESET_PUNT;
-}
-
-int aha1740_biosparam(Disk * disk, kdev_t dev, int* ip)
-{
- int size = disk->capacity;
-DEB(printk("aha1740_biosparam\n"));
- ip[0] = 64;
- ip[1] = 32;
- ip[2] = size >> 11;
-/* if (ip[2] >= 1024) ip[2] = 1024; */
- return 0;
-}
-
-#ifdef MODULE
-/* Eventually this will go into an include file, but this will be later */
-Scsi_Host_Template driver_template = AHA1740;
-
-#include "scsi_module.c"
-#endif
-
-/* Okay, you made it all the way through. As of this writing, 3/31/93, I'm
-brad@saturn.gaylord.com or brad@bradpc.gaylord.com. I'll try to help as time
-permits if you have any trouble with this driver. Happy Linuxing! */
diff --git a/i386/i386at/gpl/linux/scsi/aha1740.h b/i386/i386at/gpl/linux/scsi/aha1740.h
deleted file mode 100644
index 79d94697..00000000
--- a/i386/i386at/gpl/linux/scsi/aha1740.h
+++ /dev/null
@@ -1,193 +0,0 @@
-#ifndef _AHA1740_H
-
-/* $Id: aha1740.h,v 1.1.1.1 1997/02/25 21:27:46 thomas Exp $
- *
- * Header file for the adaptec 1740 driver for Linux
- *
- * With minor revisions 3/31/93
- * Written and (C) 1992,1993 Brad McLean. See aha1740.c
- * for more info
- *
- */
-
-#include <linux/types.h>
-#include <linux/kdev_t.h>
-
-/* Eisa Enhanced mode operation - slot locating and addressing */
-#define MINEISA 1 /* I don't have an EISA Spec to know these ranges, so I */
-#define MAXEISA 8 /* Just took my machine's specifications. Adjust to fit.*/
- /* I just saw an ad, and bumped this from 6 to 8 */
-#define SLOTBASE(x) ((x << 12)+ 0xc80 )
-#define BASE (base)
-
-/* EISA configuration registers & values */
-#define HID0 (base + 0x0)
-#define HID1 (base + 0x1)
-#define HID2 (base + 0x2)
-#define HID3 (base + 0x3)
-#define EBCNTRL (base + 0x4)
-#define PORTADR (base + 0x40)
-#define BIOSADR (base + 0x41)
-#define INTDEF (base + 0x42)
-#define SCSIDEF (base + 0x43)
-#define BUSDEF (base + 0x44)
-#define RESV0 (base + 0x45)
-#define RESV1 (base + 0x46)
-#define RESV2 (base + 0x47)
-
-#define HID_MFG "ADP"
-#define HID_PRD 0
-#define HID_REV 2
-#define EBCNTRL_VALUE 1
-#define PORTADDR_ENH 0x80
-/* READ */
-#define G2INTST (BASE + 0x56)
-#define G2STAT (BASE + 0x57)
-#define MBOXIN0 (BASE + 0x58)
-#define MBOXIN1 (BASE + 0x59)
-#define MBOXIN2 (BASE + 0x5a)
-#define MBOXIN3 (BASE + 0x5b)
-#define G2STAT2 (BASE + 0x5c)
-
-#define G2INTST_MASK 0xf0 /* isolate the status */
-#define G2INTST_CCBGOOD 0x10 /* CCB Completed */
-#define G2INTST_CCBRETRY 0x50 /* CCB Completed with a retry */
-#define G2INTST_HARDFAIL 0x70 /* Adapter Hardware Failure */
-#define G2INTST_CMDGOOD 0xa0 /* Immediate command success */
-#define G2INTST_CCBERROR 0xc0 /* CCB Completed with error */
-#define G2INTST_ASNEVENT 0xd0 /* Asynchronous Event Notification */
-#define G2INTST_CMDERROR 0xe0 /* Immediate command error */
-
-#define G2STAT_MBXOUT 4 /* Mailbox Out Empty Bit */
-#define G2STAT_INTPEND 2 /* Interrupt Pending Bit */
-#define G2STAT_BUSY 1 /* Busy Bit (attention pending) */
-
-#define G2STAT2_READY 0 /* Host Ready Bit */
-
-/* WRITE (and ReadBack) */
-#define MBOXOUT0 (BASE + 0x50)
-#define MBOXOUT1 (BASE + 0x51)
-#define MBOXOUT2 (BASE + 0x52)
-#define MBOXOUT3 (BASE + 0x53)
-#define ATTN (BASE + 0x54)
-#define G2CNTRL (BASE + 0x55)
-
-#define ATTN_IMMED 0x10 /* Immediate Command */
-#define ATTN_START 0x40 /* Start CCB */
-#define ATTN_ABORT 0x50 /* Abort CCB */
-
-#define G2CNTRL_HRST 0x80 /* Hard Reset */
-#define G2CNTRL_IRST 0x40 /* Clear EISA Interrupt */
-#define G2CNTRL_HRDY 0x20 /* Sets HOST ready */
-
-/* This is used with scatter-gather */
-struct aha1740_chain {
- u32 dataptr; /* Location of data */
- u32 datalen; /* Size of this part of chain */
-};
-
-/* These belong in scsi.h */
-#define any2scsi(up, p) \
-(up)[0] = (((unsigned long)(p)) >> 16) ; \
-(up)[1] = (((unsigned long)(p)) >> 8); \
-(up)[2] = ((unsigned long)(p));
-
-#define scsi2int(up) ( (((long)*(up)) << 16) + (((long)(up)[1]) << 8) + ((long)(up)[2]) )
-
-#define xany2scsi(up, p) \
-(up)[0] = ((long)(p)) >> 24; \
-(up)[1] = ((long)(p)) >> 16; \
-(up)[2] = ((long)(p)) >> 8; \
-(up)[3] = ((long)(p));
-
-#define xscsi2int(up) ( (((long)(up)[0]) << 24) + (((long)(up)[1]) << 16) \
- + (((long)(up)[2]) << 8) + ((long)(up)[3]) )
-
-#define MAX_CDB 12
-#define MAX_SENSE 14
-#define MAX_STATUS 32
-
-struct ecb { /* Enhanced Control Block 6.1 */
- u16 cmdw; /* Command Word */
- /* Flag Word 1 */
- u16 cne:1, /* Control Block Chaining */
- :6, di:1, /* Disable Interrupt */
- :2, ses:1, /* Suppress Underrun error */
- :1, sg:1, /* Scatter/Gather */
- :1, dsb:1, /* Disable Status Block */
- ars:1; /* Automatic Request Sense */
- /* Flag Word 2 */
- u16 lun:3, /* Logical Unit */
- tag:1, /* Tagged Queuing */
- tt:2, /* Tag Type */
- nd:1, /* No Disconnect */
- :1, dat:1, /* Data transfer - check direction */
- dir:1, /* Direction of transfer 1 = datain */
- st:1, /* Suppress Transfer */
- chk:1, /* Calculate Checksum */
- :2, rec:1, :1; /* Error Recovery */
- u16 nil0; /* nothing */
- u32 dataptr; /* Data or Scatter List ptr */
- u32 datalen; /* Data or Scatter List len */
- u32 statusptr; /* Status Block ptr */
- u32 linkptr; /* Chain Address */
- u32 nil1; /* nothing */
- u32 senseptr; /* Sense Info Pointer */
- u8 senselen; /* Sense Length */
- u8 cdblen; /* CDB Length */
- u16 datacheck; /* Data checksum */
- u8 cdb[MAX_CDB]; /* CDB area */
-/* Hardware defined portion ends here, rest is driver defined */
- u8 sense[MAX_SENSE]; /* Sense area */
- u8 status[MAX_STATUS]; /* Status area */
- Scsi_Cmnd *SCpnt; /* Link to the SCSI Command Block */
- void (*done)(Scsi_Cmnd *); /* Completion Function */
-};
-
-#define AHA1740CMD_NOP 0x00 /* No OP */
-#define AHA1740CMD_INIT 0x01 /* Initiator SCSI Command */
-#define AHA1740CMD_DIAG 0x05 /* Run Diagnostic Command */
-#define AHA1740CMD_SCSI 0x06 /* Initialize SCSI */
-#define AHA1740CMD_SENSE 0x08 /* Read Sense Information */
-#define AHA1740CMD_DOWN 0x09 /* Download Firmware (yeah, I bet!) */
-#define AHA1740CMD_RINQ 0x0a /* Read Host Adapter Inquiry Data */
-#define AHA1740CMD_TARG 0x10 /* Target SCSI Command */
-
-int aha1740_detect(Scsi_Host_Template *);
-int aha1740_command(Scsi_Cmnd *);
-int aha1740_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-int aha1740_abort(Scsi_Cmnd *);
-int aha1740_reset(Scsi_Cmnd *);
-int aha1740_biosparam(Disk *, kdev_t, int*);
-
-#define AHA1740_ECBS 32
-#define AHA1740_SCATTER 16
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-
-#define AHA1740 {NULL, NULL, \
- NULL, \
- NULL, \
- "Adaptec 174x (EISA)", \
- aha1740_detect, \
- NULL, \
- NULL, \
- aha1740_command, \
- aha1740_queuecommand, \
- aha1740_abort, \
- aha1740_reset, \
- NULL, \
- aha1740_biosparam, \
- AHA1740_ECBS, \
- 7, \
- AHA1740_SCATTER, \
- 1, \
- 0, \
- 0, \
- ENABLE_CLUSTERING}
-
-#endif
-
diff --git a/i386/i386at/gpl/linux/scsi/aic7xxx.c b/i386/i386at/gpl/linux/scsi/aic7xxx.c
deleted file mode 100644
index 3b238983..00000000
--- a/i386/i386at/gpl/linux/scsi/aic7xxx.c
+++ /dev/null
@@ -1,4645 +0,0 @@
-/*+M*************************************************************************
- * Adaptec AIC7xxx device driver for Linux.
- *
- * Copyright (c) 1994 John Aycock
- * The University of Calgary Department of Computer Science.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Sources include the Adaptec 1740 driver (aha1740.c), the Ultrastor 24F
- * driver (ultrastor.c), various Linux kernel source, the Adaptec EISA
- * config file (!adp7771.cfg), the Adaptec AHA-2740A Series User's Guide,
- * the Linux Kernel Hacker's Guide, Writing a SCSI Device Driver for Linux,
- * the Adaptec 1542 driver (aha1542.c), the Adaptec EISA overlay file
- * (adp7770.ovl), the Adaptec AHA-2740 Series Technical Reference Manual,
- * the Adaptec AIC-7770 Data Book, the ANSI SCSI specification, the
- * ANSI SCSI-2 specification (draft 10c), ...
- *
- * ----------------------------------------------------------------
- * Modified to include support for wide and twin bus adapters,
- * DMAing of SCBs, tagged queueing, IRQ sharing, bug fixes,
- * and other rework of the code.
- *
- * Parts of this driver are based on the FreeBSD driver by Justin
- * T. Gibbs.
- *
- * A Boot time option was also added for not resetting the scsi bus.
- *
- * Form: aic7xxx=extended,no_reset
- *
- * -- Daniel M. Eischen, deischen@iworks.InterWorks.org, 04/03/95
- *
- * $Id: aic7xxx.c,v 1.1.1.1 1997/02/25 21:27:46 thomas Exp $
- *-M*************************************************************************/
-
-#ifdef MODULE
-#include <linux/module.h>
-#endif
-
-#include <stdarg.h>
-#include <asm/io.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/ioport.h>
-#include <linux/bios32.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/pci.h>
-#include <linux/proc_fs.h>
-#include <linux/blk.h>
-#include "sd.h"
-#include "scsi.h"
-#include "hosts.h"
-#include "aic7xxx.h"
-#include "aic7xxx_reg.h"
-#include <linux/stat.h>
-
-#include <linux/config.h> /* for CONFIG_PCI */
-
-struct proc_dir_entry proc_scsi_aic7xxx = {
- PROC_SCSI_AIC7XXX, 7, "aic7xxx",
- S_IFDIR | S_IRUGO | S_IXUGO, 2
-};
-
-#define AIC7XXX_C_VERSION "$Revision: 1.1.1.1 $"
-
-#define NUMBER(arr) (sizeof(arr) / sizeof(arr[0]))
-#define MIN(a,b) ((a < b) ? a : b)
-#define ALL_TARGETS -1
-#ifndef TRUE
-# define TRUE 1
-#endif
-#ifndef FALSE
-# define FALSE 0
-#endif
-
-/*
- * Defines for PCI bus support, testing twin bus support, DMAing of
- * SCBs, tagged queueing, commands (SCBs) per lun, and SCSI bus reset
- * delay time.
- *
- * o PCI bus support - this has been implemented and working since
- * the December 1, 1994 release of this driver. If you don't have
- * a PCI bus, then you can configure your kernel without PCI
- * support because all PCI dependent code is bracketed with
- * "#ifdef CONFIG_PCI ... #endif CONFIG_PCI".
- *
- * o Twin bus support - this has been tested and does work.
- *
- * o DMAing of SCBs - thanks to Kai Makisara, this now works.
- * This define is now taken out and DMAing of SCBs is always
- * performed (8/12/95 - DE).
- *
- * o Tagged queueing - this driver is capable of tagged queueing
- * but I am unsure as to how well the higher level driver implements
- * tagged queueing. Therefore, the maximum commands per lun is
- * set to 2. If you want to implement tagged queueing, ensure
- * this define is not commented out.
- *
- * o Sharing IRQs - allowed for sharing of IRQs. This will allow
- * for multiple aic7xxx host adapters sharing the same IRQ, but
- * not for sharing IRQs with other devices. The higher level
- * PCI code and interrupt handling needs to be modified to
- * support this.
- *
- * o Commands per lun - If tagged queueing is enabled, then you
- * may want to try increasing AIC7XXX_CMDS_PER_LUN to more
- * than 2. By default, we limit the SCBs per lun to 2 with
- * or without tagged queueing enabled. If tagged queueing is
- * disabled, the sequencer will keep the 2nd SCB in the input
- * queue until the first one completes - so it is OK to to have
- * more than 1 SCB queued. If tagged queueing is enabled, then
- * the sequencer will attempt to send the 2nd SCB to the device
- * while the first SCB is executing and the device is disconnected.
- * For adapters limited to 4 SCBs, you may want to actually
- * decrease the commands per lun to 1, if you often have more
- * than 2 devices active at the same time. This will allocate
- * 1 SCB for each device and ensure that there will always be
- * a free SCB for up to 4 devices active at the same time.
- *
- * o 3985 support - The 3985 adapter is much like the 3940, but
- * has three 7870 controllers as opposed to two for the 3940.
- * It will get probed and recognized as three different adapters,
- * but all three controllers share the same bank of 255 SCBs
- * instead of each controller having their own bank (like the
- * controllers on the 3940). For this reason, it is important
- * that all devices be resident on just one channel of the 3985.
- * In the near future, we'll modify the driver to reserve 1/3
- * of the SCBs for each controller.
- *
- * Daniel M. Eischen, deischen@iworks.InterWorks.org, 01/11/96
- */
-
-/* Uncomment this for testing twin bus support. */
-#define AIC7XXX_TWIN_SUPPORT
-
-/* Uncomment this for tagged queueing. */
-/* #define AIC7XXX_TAGGED_QUEUEING */
-
-/* Uncomment this for allowing sharing of IRQs. */
-#define AIC7XXX_SHARE_IRQS
-
-/*
- * You can try raising me if tagged queueing is enabled, or lowering
- * me if you only have 4 SCBs.
- */
-#define AIC7XXX_CMDS_PER_LUN 2
-
-/* Set this to the delay in seconds after SCSI bus reset. */
-#define AIC7XXX_RESET_DELAY 15
-
-/*
- * Uncomment the following define for collection of SCSI transfer statistics
- * for the /proc filesystem.
- *
- * NOTE: This does affect performance since it has to maintain statistics.
- */
-/* #define AIC7XXX_PROC_STATS */
-
-/*
- * For debugging the abort/reset code.
- */
-/* #define AIC7XXX_DEBUG_ABORT */
-
-/*
- * For general debug messages
- */
-#define AIC7XXX_DEBUG
-
-/*
- * Controller type and options
- */
-typedef enum {
- AIC_NONE,
- AIC_7770, /* EISA aic7770 on motherboard */
- AIC_7771, /* EISA aic7771 on 274x */
- AIC_284x, /* VLB aic7770 on 284x */
- AIC_7850, /* PCI aic7850 */
- AIC_7870, /* PCI aic7870 on motherboard */
- AIC_7871, /* PCI aic7871 on 294x */
- AIC_7872, /* PCI aic7872 on 3940 */
- AIC_7873, /* PCI aic7873 on 3985 */
- AIC_7874, /* PCI aic7874 on 294x Differential */
- AIC_7880, /* PCI aic7880 on motherboard */
- AIC_7881, /* PCI aic7881 on 294x Ultra */
- AIC_7882, /* PCI aic7882 on 3940 Ultra */
- AIC_7883, /* PCI aic7883 on 3985 Ultra */
- AIC_7884 /* PCI aic7884 on 294x Ultra Differential */
-} aha_type;
-
-typedef enum {
- AIC_777x, /* AIC-7770 based */
- AIC_785x, /* AIC-7850 based */
- AIC_787x, /* AIC-7870 based */
- AIC_788x /* AIC-7880 based */
-} aha_chip_type;
-
-typedef enum {
- AIC_SINGLE, /* Single Channel */
- AIC_TWIN, /* Twin Channel */
- AIC_WIDE /* Wide Channel */
-} aha_bus_type;
-
-typedef enum {
- AIC_UNKNOWN,
- AIC_ENABLED,
- AIC_DISABLED
-} aha_status_type;
-
-typedef enum {
- LIST_HEAD,
- LIST_SECOND
-} insert_type;
-
-typedef enum {
- ABORT_RESET_INACTIVE,
- ABORT_RESET_PENDING,
- ABORT_RESET_SUCCESS
-} aha_abort_reset_type;
-
-/*
- * Define an array of board names that can be indexed by aha_type.
- * Don't forget to change this when changing the types!
- */
-static const char * board_names[] = {
- "<AIC-7xxx Unknown>", /* AIC_NONE */
- "AIC-7770", /* AIC_7770 */
- "AHA-2740", /* AIC_7771 */
- "AHA-2840", /* AIC_284x */
- "AIC-7850", /* AIC_7850 */
- "AIC-7870", /* AIC_7870 */
- "AHA-2940", /* AIC_7871 */
- "AHA-3940", /* AIC_7872 */
- "AHA-3985", /* AIC_7873 */
- "AHA-2940 Differential", /* AIC_7874 */
- "AIC-7880 Ultra", /* AIC_7880 */
- "AHA-2940 Ultra", /* AIC_7881 */
- "AHA-3940 Ultra", /* AIC_7882 */
- "AHA-3985 Ultra", /* AIC_7883 */
- "AHA-2940 Ultra Differential" /* AIC_7884 */
-};
-
-/*
- * There should be a specific return value for this in scsi.h, but
- * it seems that most drivers ignore it.
- */
-#define DID_UNDERFLOW DID_ERROR
-
-/*
- * What we want to do is have the higher level scsi driver requeue
- * the command to us. There is no specific driver status for this
- * condition, but the higher level scsi driver will requeue the
- * command on a DID_BUS_BUSY error.
- */
-#define DID_RETRY_COMMAND DID_BUS_BUSY
-
-/*
- * EISA/VL-bus stuff
- */
-#define MINSLOT 1
-#define MAXSLOT 15
-#define SLOTBASE(x) ((x) << 12)
-#define MAXIRQ 15
-
-/*
- * Standard EISA Host ID regs (Offset from slot base)
- */
-#define HID0 0x80 /* 0,1: msb of ID2, 2-7: ID1 */
-#define HID1 0x81 /* 0-4: ID3, 5-7: LSB ID2 */
-#define HID2 0x82 /* product */
-#define HID3 0x83 /* firmware revision */
-
-/*
- * AIC-7770 I/O range to reserve for a card
- */
-#define MINREG 0xC00
-#define MAXREG 0xCBF
-
-#define INTDEF 0x5C /* Interrupt Definition Register */
-
-/*
- * Some defines for the HCNTRL register.
- */
-#define REQ_PAUSE IRQMS | INTEN | PAUSE
-#define UNPAUSE_274X IRQMS | INTEN
-#define UNPAUSE_284X INTEN
-#define UNPAUSE_294X IRQMS | INTEN
-
-/*
- * AIC-78X0 PCI registers
- */
-#define CLASS_PROGIF_REVID 0x08
-#define DEVREVID 0x000000FFul
-#define PROGINFC 0x0000FF00ul
-#define SUBCLASS 0x00FF0000ul
-#define BASECLASS 0xFF000000ul
-
-#define CSIZE_LATTIME 0x0C
-#define CACHESIZE 0x0000003Ful /* only 5 bits */
-#define LATTIME 0x0000FF00ul
-
-#define DEVCONFIG 0x40
-#define MPORTMODE 0x00000400ul /* aic7870 only */
-#define RAMPSM 0x00000200ul /* aic7870 only */
-#define VOLSENSE 0x00000100ul
-#define SCBRAMSEL 0x00000080ul
-#define MRDCEN 0x00000040ul
-#define EXTSCBTIME 0x00000020ul /* aic7870 only */
-#define EXTSCBPEN 0x00000010ul /* aic7870 only */
-#define BERREN 0x00000008ul
-#define DACEN 0x00000004ul
-#define STPWLEVEL 0x00000002ul
-#define DIFACTNEGEN 0x00000001ul /* aic7870 only */
-
-/*
- *
- * Define the format of the SEEPROM registers (16 bits).
- *
- */
-struct seeprom_config {
-
-/*
- * SCSI ID Configuration Flags
- */
-#define CFXFER 0x0007 /* synchronous transfer rate */
-#define CFSYNCH 0x0008 /* enable synchronous transfer */
-#define CFDISC 0x0010 /* enable disconnection */
-#define CFWIDEB 0x0020 /* wide bus device (wide card) */
-/* UNUSED 0x00C0 */
-#define CFSTART 0x0100 /* send start unit SCSI command */
-#define CFINCBIOS 0x0200 /* include in BIOS scan */
-#define CFRNFOUND 0x0400 /* report even if not found */
-/* UNUSED 0xF800 */
- unsigned short device_flags[16]; /* words 0-15 */
-
-/*
- * BIOS Control Bits
- */
-#define CFSUPREM 0x0001 /* support all removeable drives */
-#define CFSUPREMB 0x0002 /* support removeable drives for boot only */
-#define CFBIOSEN 0x0004 /* BIOS enabled */
-/* UNUSED 0x0008 */
-#define CFSM2DRV 0x0010 /* support more than two drives */
-#define CF284XEXTEND 0x0020 /* extended translation (284x cards) */
-/* UNUSED 0x0040 */
-#define CFEXTEND 0x0080 /* extended translation enabled */
-/* UNUSED 0xFF00 */
- unsigned short bios_control; /* word 16 */
-
-/*
- * Host Adapter Control Bits
- */
-/* UNUSED 0x0001 */
-#define CFULTRAEN 0x0002 /* Ultra SCSI speed enable (Ultra cards) */
-#define CF284XSELTO 0x0003 /* Selection timeout (284x cards) */
-#define CF284XFIFO 0x000C /* FIFO Threshold (284x cards) */
-#define CFSTERM 0x0004 /* SCSI low byte termination (non-wide cards) */
-#define CFWSTERM 0x0008 /* SCSI high byte termination (wide card) */
-#define CFSPARITY 0x0010 /* SCSI parity */
-#define CF284XSTERM 0x0020 /* SCSI low byte termination (284x cards) */
-#define CFRESETB 0x0040 /* reset SCSI bus at IC initialization */
-/* UNUSED 0xFF80 */
- unsigned short adapter_control; /* word 17 */
-
-/*
- * Bus Release, Host Adapter ID
- */
-#define CFSCSIID 0x000F /* host adapter SCSI ID */
-/* UNUSED 0x00F0 */
-#define CFBRTIME 0xFF00 /* bus release time */
- unsigned short brtime_id; /* word 18 */
-
-/*
- * Maximum targets
- */
-#define CFMAXTARG 0x00FF /* maximum targets */
-/* UNUSED 0xFF00 */
- unsigned short max_targets; /* word 19 */
-
- unsigned short res_1[11]; /* words 20-30 */
- unsigned short checksum; /* word 31 */
-};
-
-/*
- * Pause the sequencer and wait for it to actually stop - this
- * is important since the sequencer can disable pausing for critical
- * sections.
- */
-#define PAUSE_SEQUENCER(p) \
- outb(p->pause, HCNTRL + p->base); \
- while ((inb(HCNTRL + p->base) & PAUSE) == 0) \
- ; \
-
-/*
- * Unpause the sequencer. Unremarkable, yet done often enough to
- * warrant an easy way to do it.
- */
-#define UNPAUSE_SEQUENCER(p) \
- outb(p->unpause, HCNTRL + p->base)
-
-/*
- * Restart the sequencer program from address zero
- */
-#define RESTART_SEQUENCER(p) \
- do { \
- outb(SEQRESET | FASTMODE, SEQCTL + p->base); \
- } while (inb(SEQADDR0 + p->base) != 0 && \
- inb(SEQADDR1 + p->base) != 0); \
- UNPAUSE_SEQUENCER(p);
-
-/*
- * If an error occurs during a data transfer phase, run the comand
- * to completion - it's easier that way - making a note of the error
- * condition in this location. This then will modify a DID_OK status
- * into an appropriate error for the higher-level SCSI code.
- */
-#define aic7xxx_error(cmd) ((cmd)->SCp.Status)
-
-/*
- * Keep track of the targets returned status.
- */
-#define aic7xxx_status(cmd) ((cmd)->SCp.sent_command)
-
-/*
- * The position of the SCSI commands scb within the scb array.
- */
-#define aic7xxx_position(cmd) ((cmd)->SCp.have_data_in)
-
-/*
- * Since the sequencer code DMAs the scatter-gather structures
- * directly from memory, we use this macro to assert that the
- * kernel structure hasn't changed.
- */
-#define SG_STRUCT_CHECK(sg) \
- ((char *) &(sg).address - (char *) &(sg) != 0 || \
- (char *) &(sg).length - (char *) &(sg) != 8 || \
- sizeof((sg).address) != 4 || \
- sizeof((sg).length) != 4 || \
- sizeof(sg) != 12)
-
-/*
- * "Static" structures. Note that these are NOT initialized
- * to zero inside the kernel - we have to initialize them all
- * explicitly.
- *
- * We support multiple adapter cards per interrupt, but keep a
- * linked list of Scsi_Host structures for each IRQ. On an interrupt,
- * use the IRQ as an index into aic7xxx_boards[] to locate the card
- * information.
- */
-static struct Scsi_Host *aic7xxx_boards[MAXIRQ + 1];
-
-/*
- * When we detect and register the card, it is possible to
- * have the card raise a spurious interrupt. Because we need
- * to support multiple cards, we cannot tell which card caused
- * the spurious interrupt. And, we might not even have added
- * the card info to the linked list at the time the spurious
- * interrupt gets raised. This variable is suppose to keep track
- * of when we are registering a card and how many spurious
- * interrupts we have encountered.
- *
- * 0 - do not allow spurious interrupts.
- * 1 - allow 1 spurious interrupt
- * 2 - have 1 spurious interrupt, do not allow any more.
- *
- * I've made it an integer instead of a boolean in case we
- * want to allow more than one spurious interrupt for debugging
- * purposes. Otherwise, it could just go from true to false to
- * true (or something like that).
- *
- * When the driver detects the cards, we'll set the count to 1
- * for each card detection and registration. After the registration
- * of a card completes, we'll set the count back to 0. So far, it
- * seems to be enough to allow a spurious interrupt only during
- * card registration; if a spurious interrupt is going to occur,
- * this is where it happens.
- *
- * We should be able to find a way to avoid getting the spurious
- * interrupt. But until we do, we have to keep this ugly code.
- */
-static int aic7xxx_spurious_count;
-
-/*
- * The driver keeps up to four scb structures per card in memory. Only the
- * first 25 bytes of the structure are valid for the hardware, the rest used
- * for driver level bookkeeping.
- */
-
-struct aic7xxx_scb {
-/* ------------ Begin hardware supported fields ---------------- */
-/* 0*/ unsigned char control;
-/* 1*/ unsigned char target_channel_lun; /* 4/1/3 bits */
-/* 2*/ unsigned char target_status;
-/* 3*/ unsigned char SG_segment_count;
-/* 4*/ unsigned char SG_list_pointer[4] __attribute__ ((packed));
-/* 8*/ unsigned char residual_SG_segment_count;
-/* 9*/ unsigned char residual_data_count[3];
-/*12*/ unsigned char data_pointer[4] __attribute__ ((packed));
-/*16*/ unsigned long data_count;
-/*20*/ unsigned char SCSI_cmd_pointer[4] __attribute__ ((packed));
-/*24*/ unsigned char SCSI_cmd_length;
-#define SCB_PIO_TRANSFER_SIZE 25 /*
- * amount we need to upload/download
- * via rep in/outsb to perform
- * a request sense. The second
- * RESERVED byte is initialized to
- * 0 in getscb().
- */
-/*25*/ u_char next_waiting; /* Used to thread SCBs awaiting selection. */
- /*-----------------end of hardware supported fields----------------*/
- struct aic7xxx_scb *next; /* next ptr when in free list */
- Scsi_Cmnd *cmd; /* Scsi_Cmnd for this scb */
-#define SCB_FREE 0x00
-#define SCB_ACTIVE 0x01
-#define SCB_ABORTED 0x02
-#define SCB_DEVICE_RESET 0x04
-#define SCB_IMMED 0x08
-#define SCB_SENSE 0x10
- int state; /* current state of scb */
- unsigned int position; /* Position in scb array */
- struct scatterlist sg;
- struct scatterlist sense_sg;
- unsigned char sense_cmd[6]; /* Allocate 6 characters for sense command */
-};
-
-static struct {
- unsigned char errno;
- const char *errmesg;
-} hard_error[] = {
- { ILLHADDR, "Illegal Host Access" },
- { ILLSADDR, "Illegal Sequencer Address referrenced" },
- { ILLOPCODE, "Illegal Opcode in sequencer program" },
- { PARERR, "Sequencer Ram Parity Error" }
-};
-
-static unsigned char
-generic_sense[] = { REQUEST_SENSE, 0, 0, 0, 255, 0 };
-
-/*
- * The maximum number of SCBs we could have for ANY type
- * of card. DON'T FORGET TO CHANGE THE SCB MASK IN THE
- * SEQUENCER CODE IF THIS IS MODIFIED!
- */
-#define AIC7XXX_MAXSCB 255
-
-/*
- * Define a structure used for each host adapter, only one per IRQ.
- */
-struct aic7xxx_host {
- int base; /* card base address */
- int maxscb; /* hardware SCBs */
- int numscb; /* current number of scbs */
- int extended; /* extended xlate? */
- aha_type type; /* card type */
- aha_chip_type chip_type; /* chip base type */
- int ultra_enabled; /* Ultra SCSI speed enabled */
- int chan_num; /* for 3940/3985, channel number */
- aha_bus_type bus_type; /* normal/twin/wide bus */
- unsigned char a_scanned; /* 0 not scanned, 1 scanned */
- unsigned char b_scanned; /* 0 not scanned, 1 scanned */
- unsigned int isr_count; /* Interrupt count */
- volatile unsigned char unpause; /* unpause value for HCNTRL */
- volatile unsigned char pause; /* pause value for HCNTRL */
- volatile unsigned short needsdtr_copy; /* default config */
- volatile unsigned short needsdtr;
- volatile unsigned short sdtr_pending;
- volatile unsigned short needwdtr_copy; /* default config */
- volatile unsigned short needwdtr;
- volatile unsigned short wdtr_pending;
- volatile unsigned short discenable; /* Targets allowed to disconnect */
- struct seeprom_config seeprom;
- int have_seeprom;
- struct Scsi_Host *next; /* allow for multiple IRQs */
- struct aic7xxx_scb scb_array[AIC7XXX_MAXSCB]; /* active commands */
- struct aic7xxx_scb *free_scb; /* list of free SCBs */
-#ifdef AIC7XXX_PROC_STATS
- /*
- * Statistics Kept:
- *
- * Total Xfers (count for each command that has a data xfer),
- * broken down further by reads && writes.
- *
- * Binned sizes, writes && reads:
- * < 512, 512, 1-2K, 2-4K, 4-8K, 8-16K, 16-32K, 32-64K, 64K-128K, > 128K
- *
- * Total amounts read/written above 512 bytes (amts under ignored)
- */
- struct aic7xxx_xferstats {
- long xfers; /* total xfer count */
- long w_total; /* total writes */
- long w_total512; /* 512 byte blocks written */
- long w_bins[10]; /* binned write */
- long r_total; /* total reads */
- long r_total512; /* 512 byte blocks read */
- long r_bins[10]; /* binned reads */
- } stats[2][16][8]; /* channel, target, lun */
-#endif /* AIC7XXX_PROC_STATS */
-};
-
-struct aic7xxx_host_config {
- int irq; /* IRQ number */
- int base; /* I/O base */
- int maxscb; /* hardware SCBs */
- int unpause; /* unpause value for HCNTRL */
- int pause; /* pause value for HCNTRL */
- int scsi_id; /* host SCSI ID */
- int scsi_id_b; /* host SCSI ID B channel for twin cards */
- int extended; /* extended xlate? */
- int busrtime; /* bus release time */
- int walk_scbs; /* external SCB RAM detected; walk the scb array */
- aha_type type; /* card type */
- aha_chip_type chip_type; /* chip base type */
- int ultra_enabled; /* Ultra SCSI speed enabled */
- int chan_num; /* for 3940/3985, channel number */
- aha_bus_type bus_type; /* normal/twin/wide bus */
- aha_status_type parity; /* bus parity enabled/disabled */
- aha_status_type low_term; /* bus termination low byte */
- aha_status_type high_term; /* bus termination high byte (wide cards only) */
-};
-
-/*
- * Valid SCSIRATE values. (p. 3-17)
- * Provides a mapping of tranfer periods in ns to the proper value to
- * stick in the scsiscfr reg to use that transfer rate.
- */
-static struct {
- short period;
- /* Rates in Ultra mode have bit 8 of sxfr set */
-#define ULTRA_SXFR 0x100
- short rate;
- const char *english;
-} aic7xxx_syncrates[] = {
- { 50, 0x100, "20.0" },
- { 62, 0x110, "16.0" },
- { 75, 0x120, "13.4" },
- { 100, 0x140, "10.0" },
- { 100, 0x000, "10.0" },
- { 125, 0x010, "8.0" },
- { 150, 0x020, "6.67" },
- { 175, 0x030, "5.7" },
- { 200, 0x040, "5.0" },
- { 225, 0x050, "4.4" },
- { 250, 0x060, "4.0" },
- { 275, 0x070, "3.6" }
-};
-
-static int num_aic7xxx_syncrates =
- sizeof(aic7xxx_syncrates) / sizeof(aic7xxx_syncrates[0]);
-
-#ifdef CONFIG_PCI
-static int number_of_39xxs = 0;
-#endif CONFIG_PCI
-
-#ifdef AIC7XXX_DEBUG
-static void
-debug(const char *fmt, ...)
-{
- va_list ap;
- char buf[256];
-
- va_start(ap, fmt);
- vsprintf(buf, fmt, ap);
- printk(buf);
- va_end(ap);
-}
-
-static void
-debug_config(struct aic7xxx_host_config *p)
-{
- int host_conf, scsi_conf;
- unsigned char brelease;
- unsigned char dfthresh;
-
- static int DFT[] = { 0, 50, 75, 100 };
- static int SST[] = { 256, 128, 64, 32 };
- static const char *BUSW[] = { "", "-TWIN", "-WIDE" };
-
- host_conf = inb(HOSTCONF + p->base);
- scsi_conf = inb(SCSICONF + p->base);
-
- /*
- * The 7870 gets the bus release time and data FIFO threshold
- * from the serial EEPROM (stored in the config structure) and
- * scsi_conf register respectively. The 7770 gets the bus
- * release time and data FIFO threshold from the scsi_conf and
- * host_conf registers respectively.
- */
- if (p->chip_type == AIC_777x)
- {
- dfthresh = (host_conf >> 6);
- }
- else
- {
- dfthresh = (scsi_conf >> 6);
- }
-
- brelease = p->busrtime;
- if (brelease == 0)
- {
- brelease = 2;
- }
-
- switch (p->type)
- {
- case AIC_7770:
- case AIC_7771:
- printk("%s%s AT EISA SLOT %d:\n", board_names[p->type], BUSW[p->bus_type],
- p->base >> 12);
- break;
-
- case AIC_284x:
- printk("%s%s AT VLB SLOT %d:\n", board_names[p->type], BUSW[p->bus_type],
- p->base >> 12);
- break;
-
- case AIC_7850:
- case AIC_7870:
- case AIC_7871:
- case AIC_7872:
- case AIC_7873:
- case AIC_7874:
- case AIC_7880:
- case AIC_7881:
- case AIC_7882:
- case AIC_7883:
- case AIC_7884:
- printk("%s%s (PCI-bus):\n", board_names[p->type], BUSW[p->bus_type]);
- break;
-
- default:
- panic("aic7xxx: (debug_config) internal error.\n");
- }
-
- printk(" irq %d\n"
- " bus release time %d bclks\n"
- " data fifo threshold %d%%\n",
- p->irq,
- brelease,
- DFT[dfthresh]);
-
- printk(" SCSI CHANNEL A:\n"
- " scsi id %d\n"
- " scsi selection timeout %d ms\n"
- " scsi bus reset at power-on %sabled\n",
- scsi_conf & 0x07,
- SST[(scsi_conf >> 3) & 0x03],
- (scsi_conf & 0x40) ? "en" : "dis");
-
- if ((p->chip_type == AIC_777x) && (p->parity == AIC_UNKNOWN))
- {
- /*
- * Set the parity for 7770 based cards.
- */
- p->parity = (scsi_conf & 0x20) ? AIC_ENABLED : AIC_DISABLED;
- }
- if (p->parity != AIC_UNKNOWN)
- {
- printk(" scsi bus parity %sabled\n",
- (p->parity == AIC_ENABLED) ? "en" : "dis");
- }
-
- if ((p->type == AIC_7770) || (p->type == AIC_7771))
- {
- p->low_term = (scsi_conf & 0x80) ? AIC_ENABLED : AIC_DISABLED;
- }
- if (p->low_term != AIC_UNKNOWN)
- {
- printk(" scsi bus termination (low byte) %sabled\n",
- (p->low_term == AIC_ENABLED) ? "en" : "dis");
- }
- if ((p->bus_type == AIC_WIDE) && (p->high_term != AIC_UNKNOWN))
- {
- printk(" scsi bus termination (high byte) %sabled\n",
- (p->high_term == AIC_ENABLED) ? "en" : "dis");
- }
-}
-
-#if 0
-static void
-debug_scb(struct aic7xxx_scb *scb)
-{
- printk("control 0x%x, tcl 0x%x, sg_count %d, sg_ptr 0x%x, cmdp 0x%x, cmdlen %d\n",
- scb->control, scb->target_channel_lun, scb->SG_segment_count,
- (scb->SG_list_pointer[3] << 24) | (scb->SG_list_pointer[2] << 16) |
- (scb->SG_list_pointer[1] << 8) | scb->SG_list_pointer[0],
- (scb->SCSI_cmd_pointer[3] << 24) | (scb->SCSI_cmd_pointer[2] << 16) |
- (scb->SCSI_cmd_pointer[1] << 8) | scb->SCSI_cmd_pointer[0],
- scb->SCSI_cmd_length);
- printk("reserved 0x%x, target status 0x%x, resid SG count %d, resid data count %d\n",
- (scb->RESERVED[1] << 8) | scb->RESERVED[0], scb->target_status,
- scb->residual_SG_segment_count, scb->residual_data_count);
- printk("data ptr 0x%x, data count %d, next waiting %d\n",
- (scb->data_pointer[3] << 24) | (scb->data_pointer[2] << 16) |
- (scb->data_pointer[1] << 8) | scb->data_pointer[0],
- scb->data_count, scb->next_waiting);
- printk("next ptr 0x%lx, Scsi Cmnd 0x%lx, state 0x%x, position %d\n",
- (unsigned long) scb->next, (unsigned long) scb->cmd, scb->state,
- scb->position);
-}
-#endif
-
-#else
-# define debug(fmt, args...)
-# define debug_config(x)
-# define debug_scb(x)
-#endif AIC7XXX_DEBUG
-
-/*
- * XXX - these options apply unilaterally to _all_ 274x/284x/294x
- * cards in the system. This should be fixed, but then,
- * does anyone really have more than one in a machine?
- */
-static unsigned int aic7xxx_extended = 0; /* extended translation on? */
-static unsigned int aic7xxx_no_reset = 0; /* no resetting of SCSI bus */
-
-/*+F*************************************************************************
- * Function:
- * aic7xxx_setup
- *
- * Description:
- * Handle Linux boot parameters. This routine allows for assigning a value
- * to a parameter with a ':' between the parameter and the value.
- * ie. aic7xxx=unpause:0x0A,extended
- *-F*************************************************************************/
-void
-aic7xxx_setup(char *s, int *dummy)
-{
- int i, n;
- char *p;
-
- static struct {
- const char *name;
- unsigned int *flag;
- } options[] = {
- { "extended", &aic7xxx_extended },
- { "no_reset", &aic7xxx_no_reset },
- { NULL, NULL }
- };
-
- for (p = strtok(s, ","); p; p = strtok(NULL, ","))
- {
- for (i = 0; options[i].name; i++)
- {
- n = strlen(options[i].name);
- if (!strncmp(options[i].name, p, n))
- {
- if (p[n] == ':')
- {
- *(options[i].flag) = simple_strtoul(p + n + 1, NULL, 0);
- }
- else
- {
- *(options[i].flag) = !0;
- }
- }
- }
- }
-}
-
-/*+F*************************************************************************
- * Function:
- * aic7xxx_loadseq
- *
- * Description:
- * Load the sequencer code into the controller memory.
- *-F*************************************************************************/
-static void
-aic7xxx_loadseq(int base)
-{
- static unsigned char seqprog[] = {
- /*
- * Each sequencer instruction is 29 bits
- * long (fill in the excess with zeroes)
- * and has to be loaded from least -> most
- * significant byte, so this table has the
- * byte ordering reversed.
- */
-# include "aic7xxx_seq.h"
- };
-
- /*
- * When the AIC-7770 is paused (as on chip reset), the
- * sequencer address can be altered and a sequencer
- * program can be loaded by writing it, byte by byte, to
- * the sequencer RAM port - the Adaptec documentation
- * recommends using REP OUTSB to do this, hence the inline
- * assembly. Since the address autoincrements as we load
- * the program, reset it back to zero afterward. Disable
- * sequencer RAM parity error detection while loading, and
- * make sure the LOADRAM bit is enabled for loading.
- */
- outb(PERRORDIS | SEQRESET | LOADRAM, SEQCTL + base);
-
- outsb(SEQRAM + base, seqprog, sizeof(seqprog));
-
- /*
- * WARNING! This is a magic sequence! After extensive
- * experimentation, it seems that you MUST turn off the
- * LOADRAM bit before you play with SEQADDR again, else
- * you will end up with parity errors being flagged on
- * your sequencer program. (You would also think that
- * turning off LOADRAM and setting SEQRESET to reset the
- * address to zero would work, but you need to do it twice
- * for it to take effect on the address. Timing problem?)
- */
- do {
- /*
- * Actually, reset it until
- * the address shows up as
- * zero just to be safe..
- */
- outb(SEQRESET | FASTMODE, SEQCTL + base);
- } while ((inb(SEQADDR0 + base) != 0) && (inb(SEQADDR1 + base) != 0));
-}
-
-/*+F*************************************************************************
- * Function:
- * aic7xxx_delay
- *
- * Description:
- * Delay for specified amount of time.
- *-F*************************************************************************/
-static void
-aic7xxx_delay(int seconds)
-{
- unsigned long i;
-
- i = jiffies + (seconds * HZ); /* compute time to stop */
-
- while (jiffies < i)
- {
- ; /* Do nothing! */
- }
-}
-
-/*+F*************************************************************************
- * Function:
- * rcs_version
- *
- * Description:
- * Return a string containing just the RCS version number from either
- * an Id or Revison RCS clause.
- *-F*************************************************************************/
-const char *
-rcs_version(const char *version_info)
-{
- static char buf[10];
- char *bp, *ep;
-
- bp = NULL;
- strcpy(buf, "????");
- if (!strncmp(version_info, "$Id: ", 5))
- {
- if ((bp = strchr(version_info, ' ')) != NULL)
- {
- bp++;
- if ((bp = strchr(bp, ' ')) != NULL)
- {
- bp++;
- }
- }
- }
- else
- {
- if (!strncmp(version_info, "$Revision: ", 11))
- {
- if ((bp = strchr(version_info, ' ')) != NULL)
- {
- bp++;
- }
- }
- }
-
- if (bp != NULL)
- {
- if ((ep = strchr(bp, ' ')) != NULL)
- {
- register int len = ep - bp;
-
- strncpy(buf, bp, len);
- buf[len] = '\0';
- }
- }
-
- return buf;
-}
-
-/*+F*************************************************************************
- * Function:
- * aic7xxx_info
- *
- * Description:
- * Return a string describing the driver.
- *-F*************************************************************************/
-const char *
-aic7xxx_info(struct Scsi_Host *notused)
-{
- static char buffer[128];
-
- strcpy(buffer, "Adaptec AHA274x/284x/294x (EISA/VLB/PCI-Fast SCSI) ");
- strcat(buffer, rcs_version(AIC7XXX_C_VERSION));
- strcat(buffer, "/");
- strcat(buffer, rcs_version(AIC7XXX_H_VERSION));
- strcat(buffer, "/");
- strcat(buffer, rcs_version(AIC7XXX_SEQ_VER));
-
- return buffer;
-}
-
-/*+F*************************************************************************
- * Function:
- * aic7xxx_length
- *
- * Description:
- * How much data should be transferred for this SCSI command? Stop
- * at segment sg_last if it's a scatter-gather command so we can
- * compute underflow easily.
- *-F*************************************************************************/
-static unsigned
-aic7xxx_length(Scsi_Cmnd *cmd, int sg_last)
-{
- int i, segments;
- unsigned length;
- struct scatterlist *sg;
-
- segments = cmd->use_sg - sg_last;
- sg = (struct scatterlist *) cmd->buffer;
-
- if (cmd->use_sg)
- {
- for (i = length = 0; (i < cmd->use_sg) && (i < segments); i++)
- {
- length += sg[i].length;
- }
- }
- else
- {
- length = cmd->request_bufflen;
- }
-
- return (length);
-}
-
-/*+F*************************************************************************
- * Function:
- * aic7xxx_scsirate
- *
- * Description:
- * Look up the valid period to SCSIRATE conversion in our table
- *-F*************************************************************************/
-static void
-aic7xxx_scsirate(struct aic7xxx_host *p, unsigned char *scsirate,
- short period, unsigned char offset,
- int target, char channel)
-{
- int i;
-
- for (i = 0; i < num_aic7xxx_syncrates; i++)
- {
- if ((aic7xxx_syncrates[i].period - period) >= 0)
- {
- /*
- * Watch out for Ultra speeds when ultra is not enabled and
- * vice-versa.
- */
- if (p->ultra_enabled)
- {
- if (!(aic7xxx_syncrates[i].rate & ULTRA_SXFR))
- {
- printk ("aic7xxx: Target %d, channel %c, requests %sMHz transfers, "
- "but adapter in Ultra mode can only sync at 10MHz or "
- "above.\n", target, channel, aic7xxx_syncrates[i].english);
- break; /* Use asynchronous transfers. */
- }
- }
- else
- {
- /*
- * Check for an Ultra device trying to negotiate an Ultra rate
- * on an adapter with Ultra mode disabled.
- */
- if (aic7xxx_syncrates[i].rate & ULTRA_SXFR)
- {
- /*
- * This should only happen if the driver is the first to negotiate
- * and chooses a high rate. We'll just move down the table until
- * we hit a non Ultra speed.
- */
- continue;
- }
- }
- *scsirate = (aic7xxx_syncrates[i].rate) | (offset & 0x0F);
- printk("aic7xxx: Target %d, channel %c, now synchronous at %sMHz, "
- "offset(0x%x).\n",
- target, channel, aic7xxx_syncrates[i].english, offset);
- return;
- }
- }
-
- /*
- * Default to asynchronous transfer
- */
- *scsirate = 0;
- printk("aic7xxx: Target %d, channel %c, using asynchronous transfers.\n",
- target, channel);
-}
-
-/*+F*************************************************************************
- * Function:
- * aic7xxx_putscb
- *
- * Description:
- * Transfer a SCB to the controller.
- *-F*************************************************************************/
-static inline void
-aic7xxx_putscb(struct aic7xxx_host *p, struct aic7xxx_scb *scb)
-{
- unsigned char curscb;
- int base = p->base;
-
- curscb = inb(SCBPTR + base);
- outb(scb->position, SCBPTR + base);
- outb(SCBAUTO, SCBCNT + base);
-
- /*
- * By turning on the SCB auto increment, any reference
- * to the SCB I/O space postincrements the SCB address
- * we're looking at. So turn this on and dump the relevant
- * portion of the SCB to the card.
- *
- * We can do 16bit transfers on all but 284x.
- */
- if (p->type == AIC_284x)
- {
- outsb(SCBARRAY + base, scb, SCB_PIO_TRANSFER_SIZE);
- }
- else
- {
- outsl(SCBARRAY + base, scb, (SCB_PIO_TRANSFER_SIZE + 3) / 4);
- }
-
- outb(0, SCBCNT + base);
- outb(curscb, SCBPTR + base);
-}
-
-/*+F*************************************************************************
- * Function:
- * aic7xxx_getscb
- *
- * Description:
- * Get a SCB from the controller.
- *-F*************************************************************************/
-static inline void
-aic7xxx_getscb(struct aic7xxx_host *p, struct aic7xxx_scb *scb)
-{
- int base = p->base;
-
- /*
- * This is almost identical to aic7xxx_putscb().
- */
- outb(SCBAUTO, SCBCNT + base);
- insb(SCBARRAY + base, scb, SCB_PIO_TRANSFER_SIZE);
- outb(0, SCBCNT + base);
-}
-
-/*+F*************************************************************************
- * Function:
- * aic7xxx_match_scb
- *
- * Description:
- * Checks to see if an scb matches the target/channel as specified.
- * If target is ALL_TARGETS (-1), then we're looking for any device
- * on the specified channel; this happens when a channel is going
- * to be reset and all devices on that channel must be aborted.
- *-F*************************************************************************/
-static int
-aic7xxx_match_scb(struct aic7xxx_scb *scb, int target, char channel)
-{
- int targ = (scb->target_channel_lun >> 4) & 0x0F;
- char chan = (scb->target_channel_lun & SELBUSB) ? 'B' : 'A';
-
-#ifdef AIC7XXX_DEBUG_ABORT
- printk ("aic7xxx: (match_scb) comparing target/channel %d/%c to scb %d/%c\n",
- target, channel, targ, chan);
-#endif
- if (target == ALL_TARGETS)
- {
- return (chan == channel);
- }
- else
- {
- return ((chan == channel) && (targ == target));
- }
-}
-
-/*+F*************************************************************************
- * Function:
- * aic7xxx_busy_target
- *
- * Description:
- * Set the specified target active.
- *-F*************************************************************************/
-static void
-aic7xxx_busy_target(unsigned char target, char channel, int base)
-{
- unsigned char active;
- unsigned long active_port = ACTIVE_A + base;
-
- if ((target > 0x07) || (channel == 'B'))
- {
- /*
- * targets on the Second channel or above id 7 store info in byte two
- * of ACTIVE
- */
- active_port++;
- }
- active = inb(active_port);
- active |= (0x01 << (target & 0x07));
- outb(active, active_port);
-}
-
-/*+F*************************************************************************
- * Function:
- * aic7xxx_unbusy_target
- *
- * Description:
- * Set the specified target inactive.
- *-F*************************************************************************/
-static void
-aic7xxx_unbusy_target(unsigned char target, char channel, int base)
-{
- unsigned char active;
- unsigned long active_port = ACTIVE_A + base;
-
-#ifdef 0
- printk ("aic7xxx: (unbusy_target) target/channel %d/%c\n",
- target, channel);
-#endif
- if ((target > 0x07) || (channel == 'B'))
- {
- /*
- * targets on the Second channel or above id 7 store info in byte two
- * of ACTIVE
- */
- active_port++;
- }
- active = inb(active_port);
- active &= ~(0x01 << (target & 0x07));
- outb(active, active_port);
-}
-
-/*+F*************************************************************************
- * Function:
- * aic7xxx_done
- *
- * Description:
- * Calls the higher level scsi done function and frees the scb.
- *-F*************************************************************************/
-static void
-aic7xxx_done(struct aic7xxx_host *p, struct aic7xxx_scb *scb)
-{
- long flags;
- Scsi_Cmnd *cmd = scb->cmd;
-
-#ifdef 0
- printk ("aic7xxx: (done) target/channel %d/%d\n",
- cmd->target, cmd->channel);
-#endif
- /*
- * This is a critical section, since we don't want the
- * queue routine mucking with the host data.
- */
- save_flags(flags);
- cli();
-
- /*
- * Process the command after marking the scb as free
- * and adding it to the free list.
- */
- scb->state = SCB_FREE;
- scb->next = p->free_scb;
- p->free_scb = scb;
- scb->cmd = NULL;
-
- restore_flags(flags);
-
- cmd->scsi_done(cmd);
-}
-
-/*+F*************************************************************************
- * Function:
- * aic7xxx_add_waiting_scb
- *
- * Description:
- * Add this SCB to the "waiting for selection" list.
- *-F*************************************************************************/
-static void
-aic7xxx_add_waiting_scb(u_long base,
- struct aic7xxx_scb *scb,
- insert_type where)
-{
- unsigned char head;
- unsigned char curscb;
-
- curscb = inb(SCBPTR + base);
- head = inb(WAITING_SCBH + base);
- if (head == SCB_LIST_NULL)
- {
- /*
- * List was empty
- */
- head = scb->position;
- }
- else
- {
- if (where == LIST_HEAD)
- {
- outb(scb->position, SCBPTR + base);
- outb(head, SCB_NEXT_WAITING + base);
- head = scb->position;
- }
- else
- {
- /* where == LIST_SECOND */
- unsigned char third_scb;
-
- outb(head, SCBPTR + base);
- third_scb = inb(SCB_NEXT_WAITING + base);
- outb(scb->position, SCB_NEXT_WAITING + base);
- outb(scb->position, SCBPTR + base);
- outb(third_scb, SCB_NEXT_WAITING + base);
- }
- }
- outb(head, WAITING_SCBH + base);
- outb(curscb, SCBPTR + base);
-}
-
-/*+F*************************************************************************
- * Function:
- * aic7xxx_abort_waiting_scb
- *
- * Description:
- * Manipulate the waiting for selection list and return the
- * scb that follows the one that we remove.
- *-F*************************************************************************/
-static unsigned char
-aic7xxx_abort_waiting_scb(struct aic7xxx_host *p, struct aic7xxx_scb *scb,
- unsigned char prev, unsigned char timedout_scb)
-{
- unsigned char curscb, next;
- int target = (scb->target_channel_lun >> 4) & 0x0F;
- char channel = (scb->target_channel_lun & SELBUSB) ? 'B' : 'A';
- int base = p->base;
-
- /*
- * Select the SCB we want to abort and
- * pull the next pointer out of it.
- */
- curscb = inb(SCBPTR + base);
- outb(scb->position, SCBPTR + base);
- next = inb(SCB_NEXT_WAITING + base);
-
- /*
- * Clear the necessary fields
- */
- outb(0, SCBARRAY + base);
- outb(SCB_LIST_NULL, SCB_NEXT_WAITING + base);
- aic7xxx_unbusy_target(target, channel, base);
-
- /*
- * Update the waiting list
- */
- if (prev == SCB_LIST_NULL)
- {
- /*
- * First in the list
- */
- outb(next, WAITING_SCBH + base);
- }
- else
- {
- /*
- * Select the scb that pointed to us and update its next pointer.
- */
- outb(prev, SCBPTR + base);
- outb(next, SCB_NEXT_WAITING + base);
- }
- /*
- * Update the tail pointer
- */
- if (inb(WAITING_SCBT + base) == scb->position)
- {
- outb(prev, WAITING_SCBT + base);
- }
-
- /*
- * Point us back at the original scb position
- * and inform the SCSI system that the command
- * has been aborted.
- */
- outb(curscb, SCBPTR + base);
- scb->state |= SCB_ABORTED;
- scb->cmd->result = (DID_RESET << 16);
- aic7xxx_done(p, scb);
-
-#ifdef AIC7XXX_DEBUG_ABORT
- printk ("aic7xxx: (abort_waiting_scb) target/channel %d/%c, prev %d, "
- "to_scb %d, next %d\n", target, channel, prev, timedout_scb, next);
-#endif
- return (next);
-}
-
-/*+F*************************************************************************
- * Function:
- * aic7xxx_reset_device
- *
- * Description:
- * The device at the given target/channel has been reset. Abort
- * all active and queued scbs for that target/channel.
- *-F*************************************************************************/
-static int
-aic7xxx_reset_device(struct aic7xxx_host *p, int target, char channel,
- unsigned char timedout_scb)
-{
- int base = p->base;
- struct aic7xxx_scb *scb;
- unsigned char active_scb;
- int i = 0;
- int found = 0;
-
- /*
- * Restore this when we're done
- */
- active_scb = inb(SCBPTR + base);
-
-#ifdef AIC7XXX_DEBUG_ABORT
- printk ("aic7xxx: (reset_device) target/channel %d/%c, to_scb %d, "
- "active_scb %d\n", target, channel, timedout_scb, active_scb);
-#endif
- /*
- * Search the QINFIFO.
- */
- {
- int saved_queue[AIC7XXX_MAXSCB];
- int queued = inb(QINCNT + base);
-
- for (i = 0; i < (queued - found); i++)
- {
- saved_queue[i] = inb(QINFIFO + base);
- scb = &(p->scb_array[saved_queue[i]]);
- if (aic7xxx_match_scb(scb, target, channel))
- {
- /*
- * We found an scb that needs to be aborted.
- */
- scb->state |= SCB_ABORTED;
- scb->cmd->result = (DID_RESET << 16);
- aic7xxx_done(p, scb);
- outb(scb->position, SCBPTR + base);
- outb(0, SCBARRAY + base);
- i--;
- found++;
- }
- }
- /*
- * Now put the saved scbs back.
- */
- for (queued = 0; queued < i; queued++)
- {
- outb(saved_queue[queued], QINFIFO + base);
- }
- }
-
- /*
- * Search waiting for selection list.
- */
- {
- unsigned char next, prev;
-
- next = inb(WAITING_SCBH + base); /* Start at head of list. */
- prev = SCB_LIST_NULL;
-
- while (next != SCB_LIST_NULL)
- {
- scb = &(p->scb_array[next]);
- /*
- * Select the SCB.
- */
- if (aic7xxx_match_scb(scb, target, channel))
- {
- next = aic7xxx_abort_waiting_scb(p, scb, prev, timedout_scb);
- found++;
- }
- else
- {
- outb(scb->position, SCBPTR + base);
- prev = next;
- next = inb(SCB_NEXT_WAITING + base);
- }
- }
- }
-
- /*
- * Go through the entire SCB array now and look for
- * commands for this target that are active. These
- * are other (most likely tagged) commands that
- * were disconnected when the reset occured.
- */
- for (i = 0; i < p->numscb; i++)
- {
- scb = &(p->scb_array[i]);
- if ((scb->state & SCB_ACTIVE) && aic7xxx_match_scb(scb, target, channel))
- {
- /*
- * Ensure the target is "free"
- */
- aic7xxx_unbusy_target(target, channel, base);
- outb(scb->position, SCBPTR + base);
- outb(0, SCBARRAY + base);
- scb->state |= SCB_ABORTED;
- scb->cmd->result = (DID_RESET << 16);
- aic7xxx_done(p, scb);
- found++;
- }
- }
-
- outb(active_scb, SCBPTR + base);
- return (found);
-}
-
-/*+F*************************************************************************
- * Function:
- * aic7xxx_reset_current_bus
- *
- * Description:
- * Reset the current SCSI bus.
- *-F*************************************************************************/
-static void
-aic7xxx_reset_current_bus(int base)
-{
-#ifdef AIC7XXX_DEBUG_ABORT
- printk ("aic7xxx: (reset_current_bus)\n");
-#endif
- outb(SCSIRSTO, SCSISEQ + base);
- udelay(1000);
- outb(0, SCSISEQ + base);
-}
-
-/*+F*************************************************************************
- * Function:
- * aic7xxx_reset_channel
- *
- * Description:
- * Reset the channel.
- *-F*************************************************************************/
-static int
-aic7xxx_reset_channel(struct aic7xxx_host *p, char channel,
- unsigned char timedout_scb)
-{
- int base = p->base;
- unsigned char sblkctl;
- char cur_channel;
- unsigned long offset, offset_max;
- int found;
-
-#ifdef AIC7XXX_DEBUG_ABORT
- printk ("aic7xxx: (reset_channel) channel %c, to_scb %d\n",
- channel, timedout_scb);
-#endif
- /*
- * Clean up all the state information for the
- * pending transactions on this bus.
- */
- found = aic7xxx_reset_device(p, ALL_TARGETS, channel, timedout_scb);
-
- if (channel == 'B')
- {
- p->needsdtr |= (p->needsdtr_copy & 0xFF00);
- p->sdtr_pending &= 0x00FF;
- outb(0, ACTIVE_B + base);
- offset = TARG_SCRATCH + base + 8;
- offset_max = TARG_SCRATCH + base + 16;
- }
- else
- {
- if (p->bus_type == AIC_WIDE)
- {
- p->needsdtr = p->needsdtr_copy;
- p->needwdtr = p->needwdtr_copy;
- p->sdtr_pending = 0x0;
- p->wdtr_pending = 0x0;
- outb(0, ACTIVE_A + base);
- outb(0, ACTIVE_B + base);
- offset = TARG_SCRATCH + base;
- offset_max = TARG_SCRATCH + base + 16;
- }
- else
- {
- p->needsdtr |= (p->needsdtr_copy & 0x00FF);
- p->sdtr_pending &= 0xFF00;
- outb(0, ACTIVE_A + base);
- offset = TARG_SCRATCH + base;
- offset_max = TARG_SCRATCH + base + 8;
- }
- }
- while (offset < offset_max)
- {
- /*
- * Revert to async/narrow transfers
- * until we renegotiate.
- */
- u_char targ_scratch;
- targ_scratch = inb(offset);
- targ_scratch &= SXFR;
- outb(targ_scratch, offset);
- offset++;
- }
-
- /*
- * Reset the bus and unpause/restart the controller
- */
-
- /*
- * Case 1: Command for another bus is active
- */
- sblkctl = inb(SBLKCTL + base);
- cur_channel = (sblkctl & SELBUSB) ? 'B' : 'A';
- if (cur_channel != channel)
- {
-#ifdef AIC7XXX_DEBUG_ABORT
- printk ("aic7xxx: (reset_channel) Stealthily resetting channel %c\n",
- channel);
-#endif
- /*
- * Stealthily reset the other bus without upsetting the current bus
- */
- outb(sblkctl ^ SELBUSB, SBLKCTL + base);
- aic7xxx_reset_current_bus(base);
- outb(sblkctl, SBLKCTL + base);
-
- UNPAUSE_SEQUENCER(p);
- }
- /*
- * Case 2: A command from this bus is active or we're idle
- */
- else
- {
-#ifdef AIC7XXX_DEBUG_ABORT
- printk ("aic7xxx: (reset_channel) Resetting current channel %c\n",
- channel);
-#endif
- aic7xxx_reset_current_bus(base);
- RESTART_SEQUENCER(p);
- }
-
- return found;
-}
-
-/*+F*************************************************************************
- * Function:
- * aic7xxx_isr
- *
- * Description:
- * SCSI controller interrupt handler.
- *
- * NOTE: Since we declared this using SA_INTERRUPT, interrupts should
- * be disabled all through this function unless we say otherwise.
- *-F*************************************************************************/
-static void
-aic7xxx_isr(int irq, struct pt_regs * regs)
-{
- int base, intstat;
- struct aic7xxx_host *p;
- struct aic7xxx_scb *scb;
- unsigned char ha_flags;
- short transfer;
- unsigned char scsi_id, bus_width;
- unsigned char offset, rate, scratch, scratch_offset;
- unsigned char max_offset, rej_byte;
- unsigned short target_mask;
- char channel;
- void *addr;
- int actual;
- int scb_index;
- Scsi_Cmnd *cmd;
-
- p = (struct aic7xxx_host *) aic7xxx_boards[irq]->hostdata;
-
- /*
- * Search for the host with a pending interrupt. If we can't find
- * one, then we've encountered a spurious interrupt.
- */
- while ((p != NULL) && !(inb(INTSTAT + p->base) & INT_PEND))
- {
- if (p->next == NULL)
- {
- p = NULL;
- }
- else
- {
- p = (struct aic7xxx_host *) p->next->hostdata;
- }
- }
-
- if (p == NULL)
- {
- if (aic7xxx_spurious_count == 1)
- {
- aic7xxx_spurious_count = 2;
- printk("aic7xxx: (aic7xxx_isr) Encountered spurious interrupt.\n");
- return;
- }
- else
- {
- /*
- * The best we can do is to set p back to head of list and process
- * the erroneous interrupt - most likely a BRKADRINT.
- */
- p = (struct aic7xxx_host *) aic7xxx_boards[irq]->hostdata;
- }
- }
-
- /*
- * Keep track of interrupts for /proc/scsi
- */
- p->isr_count++;
-
- if (!p->a_scanned && (p->isr_count == 1))
- {
- /*
- * We must only have one card at this IRQ and it must have been
- * added to the board data before the spurious interrupt occurred.
- * It is sufficient that we check isr_count and not the spurious
- * interrupt count.
- */
- printk("aic7xxx: (aic7xxx_isr) Encountered spurious interrupt.\n");
- return;
- }
-
- base = p->base;
- /*
- * Handle all the interrupt sources - especially for SCSI
- * interrupts, we won't get a second chance at them.
- */
- intstat = inb(INTSTAT + base);
-
- if (intstat & BRKADRINT)
- {
- int i;
- unsigned char errno = inb(ERROR + base);
-
- printk("aic7xxx: (aic7xxx_isr) BRKADRINT error(0x%x):\n", errno);
- for (i = 0; i < NUMBER(hard_error); i++)
- {
- if (errno & hard_error[i].errno)
- {
- printk(" %s\n", hard_error[i].errmesg);
- }
- }
-
- panic("aic7xxx: (aic7xxx_isr) BRKADRINT, error(0x%x) seqaddr(0x%x).\n",
- inb(ERROR + base), (inb(SEQADDR1 + base) << 8) | inb(SEQADDR0 + base));
- }
-
- if (intstat & SEQINT)
- {
- /*
- * Although the sequencer is paused immediately on
- * a SEQINT, an interrupt for a SCSIINT condition will
- * unpaused the sequencer before this point.
- */
- PAUSE_SEQUENCER(p);
-
- scsi_id = (inb(SCSIID + base) >> 4) & 0x0F;
- scratch_offset = scsi_id;
- channel = 'A';
- if (inb(SBLKCTL + base) & SELBUSB)
- {
- channel = 'B';
- scratch_offset += 8;
- }
- target_mask = (0x01 << scratch_offset);
-
- switch (intstat & SEQINT_MASK)
- {
- case BAD_PHASE:
- panic("aic7xxx: (aic7xxx_isr) Unknown scsi bus phase.\n");
- break;
-
- case SEND_REJECT:
- rej_byte = inb(REJBYTE + base);
- if ((rej_byte & 0xF0) == 0x20)
- {
- scb_index = inb(SCBPTR + base);
- scb = &(p->scb_array[scb_index]);
- printk("aic7xxx: Warning - Tagged message received without identify."
- "Disabling tagged commands for target %d channel %c.\n",
- scsi_id, channel);
- scb->cmd->device->tagged_supported = 0;
- scb->cmd->device->tagged_queue = 0;
- }
- else
- {
- debug("aic7xxx: Warning - Rejecting unknown message (0x%x) received "
- "from target %d channel %c.\n", rej_byte, scsi_id, channel);
- }
- break;
-
- case NO_IDENT:
- panic("aic7xxx: Target %d, channel %c, did not send an IDENTIFY "
- "message. SAVED_TCL(0x%x).\n",
- scsi_id, channel, inb(SAVED_TCL + base));
- break;
-
- case NO_MATCH:
- printk("aic7xxx: No active SCB for reconnecting target %d, "
- "channel %c - Issuing ABORT. SAVED_TCL(0x%x).\n",
- scsi_id, channel, inb(SAVED_TCL + base));
- aic7xxx_unbusy_target(scsi_id, channel, base);
- outb(0, SCBARRAY + base);
- outb(CLRSELTIMEO, CLRSINT1 + base);
- RESTART_SEQUENCER(p);
- break;
-
- case SDTR_MSG:
- /*
- * Help the sequencer to translate the negotiated
- * transfer rate. Transfer is 1/4 the period
- * in ns as is returned by the sync negotiation
- * message. So, we must multiply by four.
- */
- transfer = (inb(ARG_1 + base) << 2);
- offset = inb(ACCUM + base);
- scratch = inb(TARG_SCRATCH + base + scratch_offset);
- /*
- * The maximum offset for a wide device is 0x08; for a
- * 8-bit bus device the maximum offset is 0x0F.
- */
- if (scratch & WIDEXFER)
- {
- max_offset = 0x08;
- }
- else
- {
- max_offset = 0x0F;
- }
- aic7xxx_scsirate(p, &rate, transfer, MIN(offset, max_offset),
- scsi_id, channel);
- /*
- * Preserve the wide transfer flag.
- */
- scratch = rate | (scratch & WIDEXFER);
- outb(scratch, TARG_SCRATCH + base + scratch_offset);
- outb(scratch, SCSIRATE + base);
- if ((scratch & 0x0F) == 0)
- { /*
- * The requested rate was so low that asynchronous transfers
- * are faster (not to mention the controller won't support
- * them), so we issue a reject to ensure we go to asynchronous
- * transfers.
- */
- outb(SEND_REJ, RETURN_1 + base);
- }
- else
- {
- /*
- * See if we initiated Sync Negotiation
- */
- if (p->sdtr_pending & target_mask)
- {
- /*
- * Don't send an SDTR back to the target.
- */
- outb(0, RETURN_1 + base);
- }
- else
- {
- /*
- * Send our own SDTR in reply.
- */
- printk("aic7xxx: Sending SDTR!!\n");
- outb(SEND_SDTR, RETURN_1 + base);
- }
- }
- /*
- * Clear the flags.
- */
- p->needsdtr &= ~target_mask;
- p->sdtr_pending &= ~target_mask;
- break;
-
- case WDTR_MSG:
- {
- bus_width = inb(ARG_1 + base);
- printk("aic7xxx: Received MSG_WDTR, Target %d, channel %c "
- "needwdtr(0x%x).\n", scsi_id, channel, p->needwdtr);
- scratch = inb(TARG_SCRATCH + base + scratch_offset);
-
- if (p->wdtr_pending & target_mask)
- {
- /*
- * Don't send an WDTR back to the target, since we asked first.
- */
- outb(0, RETURN_1 + base);
- switch (bus_width)
- {
- case BUS_8_BIT:
- scratch &= 0x7F;
- break;
-
- case BUS_16_BIT:
- printk("aic7xxx: Target %d, channel %c, using 16 bit "
- "transfers.\n", scsi_id, channel);
- scratch |= 0x80;
- break;
-
- case BUS_32_BIT:
- outb(SEND_REJ, RETURN_1 + base);
- printk("aic7xxx: Target %d, channel %c, requesting 32 bit "
- "transfers, rejecting...\n", scsi_id, channel);
- break;
- }
- }
- else
- {
- /*
- * Send our own WDTR in reply.
- */
- printk("aic7xxx: Will send WDTR!!\n");
- switch (bus_width)
- {
- case BUS_8_BIT:
- scratch &= 0x7F;
- break;
-
- case BUS_32_BIT:
- /*
- * Negotiate 16 bits.
- */
- bus_width = BUS_16_BIT;
- /* Yes, we mean to fall thru here. */
-
- case BUS_16_BIT:
- printk("aic7xxx: Target %d, channel %c, using 16 bit "
- "transfers.\n", scsi_id, channel);
- scratch |= 0x80;
- break;
- }
- outb(bus_width | SEND_WDTR, RETURN_1 + base);
- }
- p->needwdtr &= ~target_mask;
- p->wdtr_pending &= ~target_mask;
- outb(scratch, TARG_SCRATCH + base + scratch_offset);
- outb(scratch, SCSIRATE + base);
- break;
- }
-
- case REJECT_MSG:
- {
- /*
- * What we care about here is if we had an
- * outstanding SDTR or WDTR message for this
- * target. If we did, this is a signal that
- * the target is refusing negotiation.
- */
-
- scratch = inb(TARG_SCRATCH + base + scratch_offset);
-
- if (p->wdtr_pending & target_mask)
- {
- /*
- * note 8bit xfers and clear flag
- */
- scratch &= 0x7F;
- p->needwdtr &= ~target_mask;
- p->wdtr_pending &= ~target_mask;
- printk("aic7xxx: Target %d, channel %c, refusing WIDE negotiation. "
- "Using 8 bit transfers.\n", scsi_id, channel);
- }
- else
- {
- if (p->sdtr_pending & target_mask)
- {
- /*
- * note asynch xfers and clear flag
- */
- scratch &= 0xF0;
- p->needsdtr &= ~target_mask;
- p->sdtr_pending &= ~target_mask;
- printk("aic7xxx: Target %d, channel %c, refusing synchronous "
- "negotiation. Using asynchronous transfers.\n",
- scsi_id, channel);
- }
- /*
- * Otherwise, we ignore it.
- */
- }
- outb(scratch, TARG_SCRATCH + base + scratch_offset);
- outb(scratch, SCSIRATE + base);
- break;
- }
-
- case BAD_STATUS:
- scb_index = inb(SCBPTR + base);
- scb = &(p->scb_array[scb_index]);
- outb(0, RETURN_1 + base); /* CHECK_CONDITION may change this */
- if (!(scb->state & SCB_ACTIVE) || (scb->cmd == NULL))
- {
- printk("aic7xxx: Referenced SCB not valid during SEQINT(0x%x) "
- "scb(%d) state(0x%x) cmd(0x%x).\n",
- intstat, scb_index, scb->state, (unsigned int) scb->cmd);
- }
- else
- {
- cmd = scb->cmd;
- aic7xxx_getscb(p, scb);
- aic7xxx_status(cmd) = scb->target_status;
-
- cmd->result |= scb->target_status;
-
- switch (status_byte(scb->target_status))
- {
- case GOOD:
- printk("aic7xxx: Interrupted for status of GOOD???\n");
- break;
-
- case CHECK_CONDITION:
- if ((aic7xxx_error(cmd) == 0) && !(cmd->flags & WAS_SENSE))
- {
- unsigned char tcl;
- unsigned char control;
- void *req_buf;
-
- tcl = scb->target_channel_lun;
-
- /*
- * Send a sense command to the requesting target.
- */
- cmd->flags |= WAS_SENSE;
- memcpy((void *) scb->sense_cmd, (void *) generic_sense,
- sizeof(generic_sense));
-
- scb->sense_cmd[1] = (cmd->lun << 5);
- scb->sense_cmd[4] = sizeof(cmd->sense_buffer);
-
- scb->sense_sg.address = (char *) &cmd->sense_buffer;
- scb->sense_sg.length = sizeof(cmd->sense_buffer);
- req_buf = &scb->sense_sg;
- cmd->cmd_len = COMMAND_SIZE(cmd->cmnd[0]);
- control = scb->control;
-
- memset(scb, 0, SCB_PIO_TRANSFER_SIZE);
- scb->control = control & DISCENB;
- scb->target_channel_lun = tcl;
- addr = scb->sense_cmd;
- scb->SCSI_cmd_length = COMMAND_SIZE(scb->sense_cmd[0]);
- memcpy(scb->SCSI_cmd_pointer, &addr,
- sizeof(scb->SCSI_cmd_pointer));
- scb->SG_segment_count = 1;
- memcpy(scb->SG_list_pointer, &req_buf,
- sizeof(scb->SG_list_pointer));
- scb->data_count = scb->sense_sg.length;
- memcpy(scb->data_pointer, &(scb->sense_sg.address), 4);
-
- aic7xxx_putscb(p, scb);
- outb(SCB_LIST_NULL, SCB_NEXT_WAITING + base);
- /*
- * Ensure that the target is "BUSY" so we don't get overlapping
- * commands if we happen to be doing tagged I/O.
- */
- aic7xxx_busy_target(scsi_id, channel, base);
-
- aic7xxx_add_waiting_scb(base, scb, LIST_HEAD);
- outb(SEND_SENSE, RETURN_1 + base);
- } /* first time sense, no errors */
-
- cmd->flags &= ~ASKED_FOR_SENSE;
- if (aic7xxx_error(cmd) == 0)
- {
- aic7xxx_error(cmd) = DID_RETRY_COMMAND;
- }
- break;
-
- case BUSY:
- printk("aic7xxx: Target busy.\n");
- if (!aic7xxx_error(cmd))
- {
- aic7xxx_error(cmd) = DID_BUS_BUSY;
- }
- break;
-
- case QUEUE_FULL:
- printk("aic7xxx: Queue full.\n");
- if (!aic7xxx_error(cmd))
- {
- aic7xxx_error(cmd) = DID_RETRY_COMMAND;
- }
- break;
-
- default:
- printk("aic7xxx: Unexpected target status(0x%x).\n",
- scb->target_status);
- if (!aic7xxx_error(cmd))
- {
- aic7xxx_error(cmd) = DID_RETRY_COMMAND;
- }
- break;
- } /* end switch */
- } /* end else of */
- break;
-
- case RESIDUAL:
- scb_index = inb(SCBPTR + base);
- scb = &(p->scb_array[scb_index]);
- if (!(scb->state & SCB_ACTIVE) || (scb->cmd == NULL))
- {
- printk("aic7xxx: Referenced SCB not valid during SEQINT(0x%x) "
- "scb(%d) state(0x%x) cmd(0x%x).\n",
- intstat, scb_index, scb->state, (unsigned int) scb->cmd);
- }
- else
- {
- cmd = scb->cmd;
- /*
- * Don't destroy valid residual information with
- * residual coming from a check sense operation.
- */
- if (!(cmd->flags & WAS_SENSE))
- {
- /*
- * We had an underflow. At this time, there's only
- * one other driver that bothers to check for this,
- * and cmd->underflow seems to be set rather half-
- * heartedly in the higher-level SCSI code.
- */
- actual = aic7xxx_length(cmd, scb->residual_SG_segment_count);
-
- actual -= (inb(SCB_RESID_DCNT2 + base) << 16) |
- (inb(SCB_RESID_DCNT1 + base) << 8) |
- inb(SCB_RESID_DCNT0 + base);
-
- if (actual < cmd->underflow)
- {
- printk("aic7xxx: Target %d underflow - "
- "Wanted (at least) (%u) got(%u) count(%d).\n",
- cmd->target, cmd->underflow, actual,
- inb(SCB_RESID_SGCNT + base));
- aic7xxx_error(cmd) = DID_RETRY_COMMAND;
- aic7xxx_status(cmd) = scb->target_status;
- }
- }
- }
- break;
-
- case ABORT_TAG:
- scb_index = inb(SCBPTR + base);
- scb = &(p->scb_array[scb_index]);
- if (!(scb->state & SCB_ACTIVE) || (scb->cmd == NULL))
- {
- printk("aic7xxx: Referenced SCB not valid during SEQINT(0x%x) "
- "scb(%d) state(0x%x) cmd(0x%x)\n",
- intstat, scb_index, scb->state, (unsigned int) scb->cmd);
- }
- else
- {
- cmd = scb->cmd;
- /*
- * We didn't receive a valid tag back from the target
- * on a reconnect.
- */
- printk("aic7xxx: Invalid tag received on target %d, channel %c, "
- "lun %d - Sending ABORT_TAG.\n",
- scsi_id, channel, cmd->lun & 0x07);
-
- cmd->result = (DID_RETRY_COMMAND << 16);
- aic7xxx_done(p, scb);
- }
- break;
-
- case AWAITING_MSG:
- scb_index = inb(SCBPTR + base);
- scb = &(p->scb_array[scb_index]);
- if (!(scb->state & SCB_ACTIVE) || (scb->cmd == NULL))
- {
- printk("aic7xxx: Referenced SCB not valid during SEQINT(0x%x) "
- "scb(%d) state(0x%x) cmd(0x%x).\n",
- intstat, scb_index, scb->state, (unsigned int) scb->cmd);
- }
- else
- {
- /*
- * This SCB had a zero length command, informing the sequencer
- * that we wanted to send a special message to this target.
- * We only do this for BUS_DEVICE_RESET messages currently.
- */
- if (scb->state & SCB_DEVICE_RESET)
- {
-#ifdef AIC7XXX_DEBUG_ABORT
- printk ("aic7xxx: (isr) sending bus device reset to target %d\n",
- scsi_id);
-#endif
- outb(MSG_BUS_DEVICE_RESET, MSG0 + base);
- outb(1, MSG_LEN + base);
- }
- else
- {
- panic("aic7xxx: AWAITING_SCB for an SCB that does "
- "not have a waiting message.\n");
- }
- }
- break;
-
- case IMMEDDONE:
- scb_index = inb(SCBPTR + base);
- scb = &(p->scb_array[scb_index]);
-#ifdef AIC7XXX_DEBUG_ABORT
- printk ("aic7xxx: (isr) received IMMEDDONE for target %d, scb %d, state %d\n",
- scsi_id, scb_index, scb->state);
-#endif
- if (scb->state & SCB_DEVICE_RESET)
- {
- int found;
-
- /*
- * Go back to async/narrow transfers and renogiate.
- */
- aic7xxx_unbusy_target(scsi_id, channel, base);
- p->needsdtr |= (p->needsdtr_copy & target_mask);
- p->needwdtr |= (p->needwdtr_copy & target_mask);
- p->sdtr_pending &= ~target_mask;
- p->wdtr_pending &= ~target_mask;
- scratch = inb(TARG_SCRATCH + base + scratch_offset);
- scratch &= SXFR;
- outb(scratch, TARG_SCRATCH + base + scratch_offset);
- found = aic7xxx_reset_device(p, (int) scsi_id, channel, SCB_LIST_NULL);
- }
- else
- {
- panic("aic7xxx: Immediate complete for unknown operation.\n");
- }
- break;
-
-#if AIC7XXX_NOT_YET
- /* XXX Fill these in later */
- case MESG_BUFFER_BUSY:
- break;
- case MSGIN_PHASEMIS:
- break;
-#endif
-
- case PARITY_ERROR:
- {
- scb_index = inb(SCBPTR + base);
- scb = &(p->scb_array[scb_index]);
- if (!(scb->state & SCB_ACTIVE) || (scb->cmd == NULL))
- {
- printk("aic7xxx: Referenced SCB not valid during SEQINT(0x%x) "
- "scb(%d) state(0x%x) cmd(0x%x).\n",
- intstat, scb_index, scb->state, (unsigned int) scb->cmd);
- }
- else
- {
- char *phase;
- unsigned char mesg_out = MSG_NOP;
- unsigned char lastphase = inb(LASTPHASE + base);
-
- cmd = scb->cmd;
- switch (lastphase)
- {
- case P_DATAOUT:
- phase = "Data-Out";
- break;
- case P_DATAIN:
- phase = "Data-In";
- mesg_out = MSG_INITIATOR_DET_ERROR;
- break;
- case P_COMMAND:
- phase = "Command";
- break;
- case P_MESGOUT:
- phase = "Message-Out";
- break;
- case P_STATUS:
- phase = "Status";
- mesg_out = MSG_INITIATOR_DET_ERROR;
- break;
- case P_MESGIN:
- phase = "Message-In";
- mesg_out = MSG_MSG_PARITY_ERROR;
- break;
- default:
- phase = "unknown";
- break;
- }
-
- /*
- * A parity error has occurred during a data
- * transfer phase. Flag it and continue.
- */
- printk("aic7xxx: Parity error during phase %s on target %d, "
- "channel %d, lun %d.\n", phase,
- cmd->target, cmd->channel & 0x01, cmd->lun & 0x07);
-
- /*
- * We've set the hardware to assert ATN if we get a parity
- * error on "in" phases, so all we need to do is stuff the
- * message buffer with the appropriate message. In phases
- * have set mesg_out to something other than MSG_NOP.
- */
- if (mesg_out != MSG_NOP)
- {
- outb(mesg_out, MSG0 + base);
- outb(1, MSG_LEN + base);
- aic7xxx_error(cmd) = DID_PARITY;
- }
- else
- {
- /*
- * Should we allow the target to make this decision for us?
- */
- aic7xxx_error(cmd) = DID_RETRY_COMMAND;
- }
- }
- break;
- }
- default: /* unknown */
- debug("aic7xxx: SEQINT, INTSTAT(0x%x) SCSISIGI(0x%x).\n",
- intstat, inb(SCSISIGI + base));
- break;
- }
-
- outb(CLRSEQINT, CLRINT + base);
- UNPAUSE_SEQUENCER(p);
- }
-
- if (intstat & SCSIINT)
- {
- int status = inb(SSTAT1 + base);
- scsi_id = (inb(SCSIID + base) >> 4) & 0x0F;
- channel = 'A';
- if (inb(SBLKCTL + base) & SELBUSB)
- {
- channel = 'B';
- }
-
- scb_index = inb(SCBPTR + base);
- scb = &(p->scb_array[scb_index]);
- if (!(scb->state & SCB_ACTIVE) || (scb->cmd == NULL))
- {
- printk("aic7xxx: No command for SCB (SCSIINT).\n");
- /*
- * Turn off the interrupt and set status
- * to zero, so that it falls through the
- * reset of the SCSIINT code.
- */
- outb(status, CLRSINT1 + base);
- UNPAUSE_SEQUENCER(p);
- outb(CLRSCSIINT, CLRINT + base);
- scb = NULL;
- }
- else
- {
- cmd = scb->cmd;
-
- /*
- * Only the SCSI Status 1 register has information
- * about exceptional conditions that we'd have a
- * SCSIINT about; anything in SSTAT0 will be handled
- * by the sequencer. Note that there can be multiple
- * bits set.
- */
- if (status & SELTO)
- {
- unsigned char waiting;
-
- /*
- * Hardware selection timer has expired. Turn
- * off SCSI selection sequence.
- */
- outb(ENRSELI, SCSISEQ + base);
- cmd->result = (DID_TIME_OUT << 16);
- /*
- * Clear an pending messages for the timed out
- * target and mark the target as free.
- */
- ha_flags = inb(FLAGS + base);
- outb(0, MSG_LEN + base);
- aic7xxx_unbusy_target(scsi_id, channel, base);
-
- outb(0, SCBARRAY + base);
-
- /*
- * Shut off the offending interrupt sources, reset
- * the sequencer address to zero and unpause it,
- * then call the high-level SCSI completion routine.
- *
- * WARNING! This is a magic sequence! After many
- * hours of guesswork, turning off the SCSI interrupts
- * in CLRSINT? does NOT clear the SCSIINT bit in
- * INTSTAT. By writing to the (undocumented, unused
- * according to the AIC-7770 manual) third bit of
- * CLRINT, you can clear INTSTAT. But, if you do it
- * while the sequencer is paused, you get a BRKADRINT
- * with an Illegal Host Address status, so the
- * sequencer has to be restarted first.
- */
- outb(CLRSELTIMEO, CLRSINT1 + base);
-
- outb(CLRSCSIINT, CLRINT + base);
-
- /*
- * Shift the waiting for selection queue forward
- */
- waiting = inb(WAITING_SCBH + base);
- outb(waiting, SCBPTR + base);
- waiting = inb(SCB_NEXT_WAITING + base);
- outb(waiting, WAITING_SCBH + base);
-
- RESTART_SEQUENCER(p);
- aic7xxx_done(p, scb);
-#if 0
- printk("aic7xxx: SELTO SCB(%d) state(0x%x) cmd(0x%x).\n",
- scb->position, scb->state, (unsigned int) scb->cmd);
-#endif
- }
- else
- {
- if (!(status & BUSFREE))
- {
- /*
- * We don't know what's going on. Turn off the
- * interrupt source and try to continue.
- */
- printk("aic7xxx: SSTAT1(0x%x).\n", status);
- outb(status, CLRSINT1 + base);
- UNPAUSE_SEQUENCER(p);
- outb(CLRSCSIINT, CLRINT + base);
- }
- }
- } /* else */
- }
-
- if (intstat & CMDCMPLT)
- {
- int complete;
-
- /*
- * The sequencer will continue running when it
- * issues this interrupt. There may be >1 commands
- * finished, so loop until we've processed them all.
- */
- do {
- complete = inb(QOUTFIFO + base);
-
- scb = &(p->scb_array[complete]);
- if (!(scb->state & SCB_ACTIVE) || (scb->cmd == NULL))
- {
- printk("aic7xxx: Warning - No command for SCB %d (CMDCMPLT).\n"
- " QOUTCNT(%d) SCB state(0x%x) cmd(0x%x) pos(%d).\n",
- complete, inb(QOUTFIFO + base),
- scb->state, (unsigned int) scb->cmd, scb->position);
- outb(CLRCMDINT, CLRINT + base);
- continue;
- }
- cmd = scb->cmd;
-
- if ((cmd->flags & WAS_SENSE) && !(cmd->flags & ASKED_FOR_SENSE))
- {
- /*
- * Got sense information.
- */
- cmd->flags &= ASKED_FOR_SENSE;
- }
-#if 0
- printk("aic7xxx: (complete) State(%d) cmd(0x%x) free(0x%x).\n",
- scb->state, (unsigned int) scb->cmd, (unsigned int) p->free_scb);
-#endif
-
- /*
- * Clear interrupt status before checking
- * the output queue again. This eliminates
- * a race condition whereby a command could
- * complete between the queue poll and the
- * interrupt clearing, so notification of the
- * command being complete never made it back
- * up to the kernel.
- */
- outb(CLRCMDINT, CLRINT + base);
- aic7xxx_done(p, scb);
-#if 0
- if (scb != &p->scb_array[scb->position])
- {
- printk("aic7xxx: (complete) Address mismatch, pos(%d).\n", scb->position);
- }
- printk("aic7xxx: (complete) State(%d) cmd(0x%x) free(0x%x).\n",
- scb->state, (unsigned int) scb->cmd, (unsigned int) p->free_scb);
-#endif
-
-#ifdef AIC7XXX_PROC_STATS
- /*
- * XXX: we should actually know how much actually transferred
- * XXX: for each command, but apparently that's too difficult.
- */
- actual = aic7xxx_length(cmd, 0);
- if (!(cmd->flags & WAS_SENSE) && (actual > 0))
- {
- struct aic7xxx_xferstats *sp;
- long *ptr;
- int x;
-
- sp = &p->stats[cmd->channel & 0x01][cmd->target & 0x0F][cmd->lun & 0x07];
- sp->xfers++;
-
- if (cmd->request.cmd == WRITE)
- {
- sp->w_total++;
- sp->w_total512 += (actual >> 9);
- ptr = sp->w_bins;
- }
- else
- {
- sp->r_total++;
- sp->r_total512 += (actual >> 9);
- ptr = sp->r_bins;
- }
- for (x = 9; x <= 17; x++)
- {
- if (actual < (1 << x))
- {
- ptr[x - 9]++;
- break;
- }
- }
- if (x > 17)
- {
- ptr[x - 9]++;
- }
- }
-#endif /* AIC7XXX_PROC_STATS */
-
- } while (inb(QOUTCNT + base));
- }
-}
-
-/*+F*************************************************************************
- * Function:
- * aic7xxx_probe
- *
- * Description:
- * Probing for EISA boards: it looks like the first two bytes
- * are a manufacturer code - three characters, five bits each:
- *
- * BYTE 0 BYTE 1 BYTE 2 BYTE 3
- * ?1111122 22233333 PPPPPPPP RRRRRRRR
- *
- * The characters are baselined off ASCII '@', so add that value
- * to each to get the real ASCII code for it. The next two bytes
- * appear to be a product and revision number, probably vendor-
- * specific. This is what is being searched for at each port,
- * and what should probably correspond to the ID= field in the
- * ECU's .cfg file for the card - if your card is not detected,
- * make sure your signature is listed in the array.
- *
- * The fourth byte's lowest bit seems to be an enabled/disabled
- * flag (rest of the bits are reserved?).
- *-F*************************************************************************/
-static aha_type
-aic7xxx_probe(int slot, int base)
-{
- int i;
- unsigned char buf[4];
-
- static struct {
- int n;
- unsigned char signature[sizeof(buf)];
- aha_type type;
- } AIC7xxx[] = {
- { 4, { 0x04, 0x90, 0x77, 0x71 }, AIC_7771 }, /* host adapter 274x */
- { 4, { 0x04, 0x90, 0x77, 0x70 }, AIC_7770 }, /* motherboard 7770 */
- { 4, { 0x04, 0x90, 0x77, 0x56 }, AIC_284x }, /* 284x, BIOS enabled */
- { 4, { 0x04, 0x90, 0x77, 0x57 }, AIC_284x } /* 284x, BIOS disabled */
- };
-
- /*
- * The VL-bus cards need to be primed by
- * writing before a signature check.
- */
- for (i = 0; i < sizeof(buf); i++)
- {
- outb(0x80 + i, base);
- buf[i] = inb(base + i);
- }
-
- for (i = 0; i < NUMBER(AIC7xxx); i++)
- {
- /*
- * Signature match on enabled card?
- */
- if (!memcmp(buf, AIC7xxx[i].signature, AIC7xxx[i].n))
- {
- if (inb(base + 4) & 1)
- {
- return (AIC7xxx[i].type);
- }
-
- printk("aic7xxx: Disabled at slot %d, ignored.\n", slot);
- }
- }
-
- return (AIC_NONE);
-}
-
-/*+F*************************************************************************
- * Function:
- * read_2840_seeprom
- *
- * Description:
- * Reads the 2840 serial EEPROM and returns 1 if successful and 0 if
- * not successful.
- *
- * See read_seeprom (for the 2940) for the instruction set of the 93C46
- * chip.
- *
- * The 2840 interface to the 93C46 serial EEPROM is through the
- * STATUS_2840 and SEECTL_2840 registers. The CS_2840, CK_2840, and
- * DO_2840 bits of the SEECTL_2840 register are connected to the chip
- * select, clock, and data out lines respectively of the serial EEPROM.
- * The DI_2840 bit of the STATUS_2840 is connected to the data in line
- * of the serial EEPROM. The EEPROM_TF bit of STATUS_2840 register is
- * useful in that it gives us an 800 nsec timer. After a read from the
- * SEECTL_2840 register the timing flag is cleard and goes high 800 nsec
- * later.
- *
- *-F*************************************************************************/
-static int
-read_2840_seeprom(int base, struct seeprom_config *sc)
-{
- int i = 0, k = 0;
- unsigned char temp;
- unsigned short checksum = 0;
- unsigned short *seeprom = (unsigned short *) sc;
- struct seeprom_cmd {
- unsigned char len;
- unsigned char bits[3];
- };
- struct seeprom_cmd seeprom_read = {3, {1, 1, 0}};
-
-#define CLOCK_PULSE(p) \
- while ((inb(STATUS_2840 + base) & EEPROM_TF) == 0) \
- { \
- ; /* Do nothing */ \
- } \
- (void) inb(SEECTL_2840 + base);
-
- /*
- * Read the first 32 registers of the seeprom. For the 2840,
- * the 93C46 SEEPROM is a 1024-bit device with 64 16-bit registers
- * but only the first 32 are used by Adaptec BIOS. The loop
- * will range from 0 to 31.
- */
- for (k = 0; k < (sizeof(*sc) / 2); k++)
- {
- /*
- * Send chip select for one clock cycle.
- */
- outb(CK_2840 | CS_2840, SEECTL_2840 + base);
- CLOCK_PULSE(base);
-
- /*
- * Now we're ready to send the read command followed by the
- * address of the 16-bit register we want to read.
- */
- for (i = 0; i < seeprom_read.len; i++)
- {
- temp = CS_2840 | seeprom_read.bits[i];
- outb(temp, SEECTL_2840 + base);
- CLOCK_PULSE(base);
- temp = temp ^ CK_2840;
- outb(temp, SEECTL_2840 + base);
- CLOCK_PULSE(base);
- }
- /*
- * Send the 6 bit address (MSB first, LSB last).
- */
- for (i = 5; i >= 0; i--)
- {
- temp = k;
- temp = (temp >> i) & 1; /* Mask out all but lower bit. */
- temp = CS_2840 | temp;
- outb(temp, SEECTL_2840 + base);
- CLOCK_PULSE(base);
- temp = temp ^ CK_2840;
- outb(temp, SEECTL_2840 + base);
- CLOCK_PULSE(base);
- }
-
- /*
- * Now read the 16 bit register. An initial 0 precedes the
- * register contents which begins with bit 15 (MSB) and ends
- * with bit 0 (LSB). The initial 0 will be shifted off the
- * top of our word as we let the loop run from 0 to 16.
- */
- for (i = 0; i <= 16; i++)
- {
- temp = CS_2840;
- outb(temp, SEECTL_2840 + base);
- CLOCK_PULSE(base);
- temp = temp ^ CK_2840;
- seeprom[k] = (seeprom[k] << 1) | (inb(STATUS_2840 + base) & DI_2840);
- outb(temp, SEECTL_2840 + base);
- CLOCK_PULSE(base);
- }
- /*
- * The serial EEPROM has a checksum in the last word. Keep a
- * running checksum for all words read except for the last
- * word. We'll verify the checksum after all words have been
- * read.
- */
- if (k < (sizeof(*sc) / 2) - 1)
- {
- checksum = checksum + seeprom[k];
- }
-
- /*
- * Reset the chip select for the next command cycle.
- */
- outb(0, SEECTL_2840 + base);
- CLOCK_PULSE(base);
- outb(CK_2840, SEECTL_2840 + base);
- CLOCK_PULSE(base);
- outb(0, SEECTL_2840 + base);
- CLOCK_PULSE(base);
- }
-
-#if 0
- printk("Computed checksum 0x%x, checksum read 0x%x\n", checksum, sc->checksum);
- printk("Serial EEPROM:");
- for (k = 0; k < (sizeof(*sc) / 2); k++)
- {
- if (((k % 8) == 0) && (k != 0))
- {
- printk("\n ");
- }
- printk(" 0x%x", seeprom[k]);
- }
- printk("\n");
-#endif
-
- if (checksum != sc->checksum)
- {
- printk("aic7xxx: SEEPROM checksum error, ignoring SEEPROM settings.\n");
- return (0);
- }
-
- return (1);
-#undef CLOCK_PULSE
-}
-
-/*+F*************************************************************************
- * Function:
- * read_seeprom
- *
- * Description:
- * Reads the serial EEPROM and returns 1 if successful and 0 if
- * not successful.
- *
- * The instruction set of the 93C46 chip is as follows:
- *
- * Start OP
- * Function Bit Code Address Data Description
- * -------------------------------------------------------------------
- * READ 1 10 A5 - A0 Reads data stored in memory,
- * starting at specified address
- * EWEN 1 00 11XXXX Write enable must preceed
- * all programming modes
- * ERASE 1 11 A5 - A0 Erase register A5A4A3A2A1A0
- * WRITE 1 01 A5 - A0 D15 - D0 Writes register
- * ERAL 1 00 10XXXX Erase all registers
- * WRAL 1 00 01XXXX D15 - D0 Writes to all registers
- * EWDS 1 00 00XXXX Disables all programming
- * instructions
- * *Note: A value of X for address is a don't care condition.
- *
- * The 93C46 has a four wire interface: clock, chip select, data in, and
- * data out. In order to perform one of the above functions, you need
- * to enable the chip select for a clock period (typically a minimum of
- * 1 usec, with the clock high and low a minimum of 750 and 250 nsec
- * respectively. While the chip select remains high, you can clock in
- * the instructions (above) starting with the start bit, followed by the
- * OP code, Address, and Data (if needed). For the READ instruction, the
- * requested 16-bit register contents is read from the data out line but
- * is preceded by an initial zero (leading 0, followed by 16-bits, MSB
- * first). The clock cycling from low to high initiates the next data
- * bit to be sent from the chip.
- *
- * The 7870 interface to the 93C46 serial EEPROM is through the SEECTL
- * register. After successful arbitration for the memory port, the
- * SEECS bit of the SEECTL register is connected to the chip select.
- * The SEECK, SEEDO, and SEEDI are connected to the clock, data out,
- * and data in lines respectively. The SEERDY bit of SEECTL is useful
- * in that it gives us an 800 nsec timer. After a write to the SEECTL
- * register, the SEERDY goes high 800 nsec later. The one exception
- * to this is when we first request access to the memory port. The
- * SEERDY goes high to signify that access has been granted and, for
- * this case, has no implied timing.
- *
- *-F*************************************************************************/
-static int
-read_seeprom(int base, int offset, struct seeprom_config *sc)
-{
- int i = 0, k;
- unsigned long timeout;
- unsigned char temp;
- unsigned short checksum = 0;
- unsigned short *seeprom = (unsigned short *) sc;
- struct seeprom_cmd {
- unsigned char len;
- unsigned char bits[3];
- };
- struct seeprom_cmd seeprom_read = {3, {1, 1, 0}};
-
-#define CLOCK_PULSE(p) \
- while ((inb(SEECTL + base) & SEERDY) == 0) \
- { \
- ; /* Do nothing */ \
- }
-
- /*
- * Request access of the memory port. When access is
- * granted, SEERDY will go high. We use a 1 second
- * timeout which should be near 1 second more than
- * is needed. Reason: after the 7870 chip reset, there
- * should be no contention.
- */
- outb(SEEMS, SEECTL + base);
- timeout = jiffies + 100; /* 1 second timeout */
- while ((jiffies < timeout) && ((inb(SEECTL + base) & SEERDY) == 0))
- {
- ; /* Do nothing! Wait for access to be granted. */
- }
- if ((inb(SEECTL + base) & SEERDY) == 0)
- {
- outb(0, SEECTL + base);
- return (0);
- }
-
- /*
- * Read the first 32 registers of the seeprom. For the 7870,
- * the 93C46 SEEPROM is a 1024-bit device with 64 16-bit registers
- * but only the first 32 are used by Adaptec BIOS. The loop
- * will range from 0 to 31.
- */
- for (k = 0; k < (sizeof(*sc) / 2); k++)
- {
- /*
- * Send chip select for one clock cycle.
- */
- outb(SEEMS | SEECK | SEECS, SEECTL + base);
- CLOCK_PULSE(base);
-
- /*
- * Now we're ready to send the read command followed by the
- * address of the 16-bit register we want to read.
- */
- for (i = 0; i < seeprom_read.len; i++)
- {
- temp = SEEMS | SEECS | (seeprom_read.bits[i] << 1);
- outb(temp, SEECTL + base);
- CLOCK_PULSE(base);
- temp = temp ^ SEECK;
- outb(temp, SEECTL + base);
- CLOCK_PULSE(base);
- }
- /*
- * Send the 6 bit address (MSB first, LSB last).
- */
- for (i = 5; i >= 0; i--)
- {
- temp = k + offset;
- temp = (temp >> i) & 1; /* Mask out all but lower bit. */
- temp = SEEMS | SEECS | (temp << 1);
- outb(temp, SEECTL + base);
- CLOCK_PULSE(base);
- temp = temp ^ SEECK;
- outb(temp, SEECTL + base);
- CLOCK_PULSE(base);
- }
-
- /*
- * Now read the 16 bit register. An initial 0 precedes the
- * register contents which begins with bit 15 (MSB) and ends
- * with bit 0 (LSB). The initial 0 will be shifted off the
- * top of our word as we let the loop run from 0 to 16.
- */
- for (i = 0; i <= 16; i++)
- {
- temp = SEEMS | SEECS;
- outb(temp, SEECTL + base);
- CLOCK_PULSE(base);
- temp = temp ^ SEECK;
- seeprom[k] = (seeprom[k] << 1) | (inb(SEECTL + base) & SEEDI);
- outb(temp, SEECTL + base);
- CLOCK_PULSE(base);
- }
-
- /*
- * The serial EEPROM has a checksum in the last word. Keep a
- * running checksum for all words read except for the last
- * word. We'll verify the checksum after all words have been
- * read.
- */
- if (k < (sizeof(*sc) / 2) - 1)
- {
- checksum = checksum + seeprom[k];
- }
-
- /*
- * Reset the chip select for the next command cycle.
- */
- outb(SEEMS, SEECTL + base);
- CLOCK_PULSE(base);
- outb(SEEMS | SEECK, SEECTL + base);
- CLOCK_PULSE(base);
- outb(SEEMS, SEECTL + base);
- CLOCK_PULSE(base);
- }
-
- /*
- * Release access to the memory port and the serial EEPROM.
- */
- outb(0, SEECTL + base);
-
-#if 0
- printk("Computed checksum 0x%x, checksum read 0x%x\n", checksum, sc->checksum);
- printk("Serial EEPROM:");
- for (k = 0; k < (sizeof(*sc) / 2); k++)
- {
- if (((k % 8) == 0) && (k != 0))
- {
- printk("\n ");
- }
- printk(" 0x%x", seeprom[k]);
- }
- printk("\n");
-#endif
-
- if (checksum != sc->checksum)
- {
- printk("aic7xxx: SEEPROM checksum error, ignoring SEEPROM settings.\n");
- return (0);
- }
-
- return (1);
-#undef CLOCK_PULSE
-}
-
-/*+F*************************************************************************
- * Function:
- * detect_maxscb
- *
- * Description:
- * Return the maximum number of SCB's allowed for a given controller.
- *-F*************************************************************************/
-static int
-detect_maxscb(aha_type type, int base, int walk_scbs)
-{
- unsigned char sblkctl_reg, scb_byte;
- int maxscb = 0, i;
-
- switch (type)
- {
- case AIC_7770:
- case AIC_7771:
- case AIC_284x:
- /*
- * Check for Rev C or E boards. Rev E boards can supposedly have
- * more than 4 SCBs, while the Rev C boards are limited to 4 SCBs.
- * Until we know how to access more than 4 SCBs for the Rev E chips,
- * we limit them, along with the Rev C chips, to 4 SCBs.
- *
- * The Rev E boards have a read/write autoflush bit in the
- * SBLKCTL register, while in the Rev C boards it is read only.
- */
- sblkctl_reg = inb(SBLKCTL + base) ^ AUTOFLUSHDIS;
- outb(sblkctl_reg, SBLKCTL + base);
- if (inb(SBLKCTL + base) == sblkctl_reg)
- {
- /*
- * We detected a Rev E board.
- */
- printk("aic7xxx: %s Rev E and subsequent.\n", board_names[type]);
- outb(sblkctl_reg ^ AUTOFLUSHDIS, SBLKCTL + base);
- maxscb = 4;
- }
- else
- {
- printk("aic7xxx: %s Rev C and previous.\n", board_names[type]);
- maxscb = 4;
- }
- break;
-
- case AIC_7850:
- maxscb = 3;
- break;
-
- case AIC_7870:
- case AIC_7871:
- case AIC_7874:
- case AIC_7880:
- case AIC_7881:
- case AIC_7884:
- maxscb = 16;
- break;
-
- case AIC_7872:
- case AIC_7873:
- case AIC_7882:
- case AIC_7883:
- /*
- * Is suppose to have 255 SCBs, but we'll walk the SCBs
- * looking for more if external RAM is detected.
- */
- maxscb = 16;
- break;
-
- case AIC_NONE:
- /*
- * This should never happen... But just in case.
- */
- break;
- }
-
- if (walk_scbs)
- {
- /*
- * This adapter has external SCB memory.
- * Walk the SCBs to determine how many there are.
- */
- i = 0;
- while (i < AIC7XXX_MAXSCB)
- {
- outb(i, SCBPTR + base);
- scb_byte = ~(inb(SCBARRAY + base)); /* complement the byte */
- outb(scb_byte, SCBARRAY + base); /* write it back out */
- if (inb(SCBARRAY + base) != scb_byte)
- {
- break;
- }
- i++;
- }
- maxscb = i;
-
- printk("aic7xxx: Using %d SCB's after checking for SCB memory.\n", maxscb);
- }
- else
- {
- printk("aic7xxx: Using %d SCB's; No SCB memory check.\n", maxscb);
- }
-
- return (maxscb);
-}
-
-/*+F*************************************************************************
- * Function:
- * aic7xxx_register
- *
- * Description:
- * Register a Adaptec aic7xxx chip SCSI controller with the kernel.
- *-F*************************************************************************/
-static int
-aic7xxx_register(Scsi_Host_Template *template,
- struct aic7xxx_host_config *config)
-{
- int i;
- unsigned char sblkctl;
- int max_targets;
- int found = 1, base;
- int bios_disabled = FALSE;
- unsigned char target_settings;
- unsigned char scsi_conf, host_conf;
- int have_seeprom = FALSE;
- struct Scsi_Host *host;
- struct aic7xxx_host *p;
- struct seeprom_config sc;
-
- base = config->base;
-
- /*
- * Lock out other contenders for our i/o space.
- */
- request_region(MINREG + base, MAXREG - MINREG, "aic7xxx");
-
- switch (config->type)
- {
- case AIC_7770:
- case AIC_7771:
- /*
- * For some 274x boards, we must clear the CHIPRST bit
- * and pause the sequencer. For some reason, this makes
- * the driver work. For 284x boards, we give it a
- * CHIPRST just like the 294x boards.
- *
- * Use the BIOS settings to determine the interrupt
- * trigger type (level or edge) and use this value
- * for pausing and unpausing the sequencer.
- */
- config->unpause = (inb(HCNTRL + base) & IRQMS) | INTEN;
- config->pause = config->unpause | PAUSE;
- config->extended = aic7xxx_extended;
-
- outb(config->pause | CHIPRST, HCNTRL + base);
- aic7xxx_delay(1);
- if (inb(HCNTRL + base) & CHIPRST)
- {
- printk("aic7xxx: Chip reset not cleared; clearing manually.\n");
- }
- outb(config->pause, HCNTRL + base);
-
- /*
- * Just to be on the safe side with the 274x, we will re-read the irq
- * since there was some issue about resetting the board.
- */
- config->irq = inb(INTDEF + base) & 0x0F;
- if ((inb(HA_274_BIOSCTRL + base) & BIOSMODE) == BIOSDISABLED)
- {
- bios_disabled = TRUE;
- }
- host_conf = inb(HOSTCONF + base);
- config->busrtime = host_conf & 0x3C;
- /* XXX Is this valid for motherboard based controllers? */
- /* Setup the FIFO threshold and the bus off time */
- outb(host_conf & DFTHRSH, BUSSPD + base);
- outb((host_conf << 2) & BOFF, BUSTIME + base);
-
- /*
- * A reminder until this can be detected automatically.
- */
- printk("aic7xxx: Extended translation %sabled.\n",
- config->extended ? "en" : "dis");
- break;
-
- case AIC_284x:
- outb(CHIPRST, HCNTRL + base);
- config->unpause = UNPAUSE_284X;
- config->pause = REQ_PAUSE; /* DWG would like to be like the rest */
- aic7xxx_delay(1);
- outb(config->pause, HCNTRL + base);
-
- config->extended = aic7xxx_extended;
- config->irq = inb(INTDEF + base) & 0x0F;
- if ((inb(HA_274_BIOSCTRL + base) & BIOSMODE) == BIOSDISABLED)
- {
- bios_disabled = TRUE;
- }
- host_conf = inb(HOSTCONF + base);
-
- printk("aic7xxx: Reading SEEPROM...");
- have_seeprom = read_2840_seeprom(base, &sc);
- if (!have_seeprom)
- {
- printk("aic7xxx: Unable to read SEEPROM.\n");
- config->busrtime = host_conf & 0x3C;
- }
- else
- {
- printk("done.\n");
- config->extended = ((sc.bios_control & CF284XEXTEND) >> 5);
- config->scsi_id = (sc.brtime_id & CFSCSIID);
- config->parity = (sc.adapter_control & CFSPARITY) ?
- AIC_ENABLED : AIC_DISABLED;
- config->low_term = (sc.adapter_control & CF284XSTERM) ?
- AIC_ENABLED : AIC_DISABLED;
- /*
- * XXX - Adaptec *does* make 284x wide controllers, but the
- * documents do not say where the high byte termination
- * enable bit is located. For now, we'll just assume
- * that it's in the same place as for the 2940 card.
- */
- config->high_term = (sc.adapter_control & CFWSTERM) ?
- AIC_ENABLED : AIC_DISABLED;
- config->busrtime = ((sc.brtime_id & CFBRTIME) >> 8);
- }
- /* XXX Is this valid for motherboard based controllers? */
- /* Setup the FIFO threshold and the bus off time */
- outb(host_conf & DFTHRSH, BUSSPD + base);
- outb((host_conf << 2) & BOFF, BUSTIME + base);
-
- printk("aic7xxx: Extended translation %sabled.\n",
- config->extended ? "en" : "dis");
- break;
-
- case AIC_7850:
- case AIC_7870:
- case AIC_7871:
- case AIC_7872:
- case AIC_7873:
- case AIC_7874:
- case AIC_7880:
- case AIC_7881:
- case AIC_7882:
- case AIC_7883:
- case AIC_7884:
- outb(CHIPRST, HCNTRL + base);
- config->unpause = UNPAUSE_294X;
- config->pause = config->unpause | PAUSE;
- aic7xxx_delay(1);
- outb(config->pause, HCNTRL + base);
-
- config->extended = aic7xxx_extended;
- config->scsi_id = 7;
-
- printk("aic7xxx: Reading SEEPROM...");
- have_seeprom = read_seeprom(base, config->chan_num * (sizeof(sc) / 2), &sc);
- if (!have_seeprom)
- {
- printk("aic7xxx: Unable to read SEEPROM.\n");
- }
- else
- {
- printk("done.\n");
- config->extended = ((sc.bios_control & CFEXTEND) >> 7);
- config->scsi_id = (sc.brtime_id & CFSCSIID);
- config->parity = (sc.adapter_control & CFSPARITY) ?
- AIC_ENABLED : AIC_DISABLED;
- config->low_term = (sc.adapter_control & CFSTERM) ?
- AIC_ENABLED : AIC_DISABLED;
- config->high_term = (sc.adapter_control & CFWSTERM) ?
- AIC_ENABLED : AIC_DISABLED;
- config->busrtime = ((sc.brtime_id & CFBRTIME) >> 8);
- if (((config->type == AIC_7880) || (config->type == AIC_7882) ||
- (config->type == AIC_7883) || (config->type == AIC_7884)) &&
- (sc.adapter_control & CFULTRAEN))
- {
- printk ("aic7xxx: Enabling support for Ultra SCSI speed.\n");
- config->ultra_enabled = TRUE;
- }
- }
-
- /*
- * XXX - force data fifo threshold to 100%. Why does this
- * need to be done?
- *
- * We don't know where this is set in the SEEPROM or by the BIOS,
- * so we default it to 100%.
- */
- outb(config->scsi_id | DFTHRSH_100, SCSICONF + base);
- outb(DFTHRSH_100, DSPCISTATUS + base);
-
- /*
- * In case we are a wide card, place scsi ID in second conf byte.
- */
- outb(config->scsi_id, (SCSICONF + base + 1));
-
- printk("aic7xxx: Extended translation %sabled.\n",
- config->extended ? "en" : "dis");
- break;
-
- default:
- panic("aic7xxx: (aic7xxx_register) Internal error.\n");
- }
-
- config->maxscb = detect_maxscb(config->type, base, config->walk_scbs);
-
- if (config->chip_type == AIC_777x)
- {
- if (config->pause & IRQMS)
- {
- printk("aic7xxx: Using level sensitive interrupts.\n");
- }
- else
- {
- printk("aic7xxx: Using edge triggered interrupts.\n");
- }
- }
-
- /*
- * Read the bus type from the SBLKCTL register. Set the FLAGS
- * register in the sequencer for twin and wide bus cards.
- */
- sblkctl = inb(SBLKCTL + base);
- switch (sblkctl & SELBUS_MASK)
- {
- case SELNARROW: /* narrow/normal bus */
- config->scsi_id = inb(SCSICONF + base) & 0x07;
- config->bus_type = AIC_SINGLE;
- outb(SINGLE_BUS, FLAGS + base);
- break;
-
- case SELWIDE: /* Wide bus */
- config->scsi_id = inb(SCSICONF + base + 1) & 0x0F;
- config->bus_type = AIC_WIDE;
- printk("aic7xxx: Enabling wide channel of %s-Wide.\n",
- board_names[config->type]);
- outb(WIDE_BUS, FLAGS + base);
- break;
-
- case SELBUSB: /* Twin bus */
- config->scsi_id = inb(SCSICONF + base) & 0x07;
-#ifdef AIC7XXX_TWIN_SUPPORT
- config->scsi_id_b = inb(SCSICONF + base + 1) & 0x07;
- config->bus_type = AIC_TWIN;
- printk("aic7xxx: Enabled channel B of %s-Twin.\n",
- board_names[config->type]);
- outb(TWIN_BUS, FLAGS + base);
-#else
- config->bus_type = AIC_SINGLE;
- printk("aic7xxx: Channel B of %s-Twin will be ignored.\n",
- board_names[config->type]);
- outb(0, FLAGS + base);
-#endif
- break;
-
- default:
- printk("aic7xxx: Unsupported type 0x%x, please "
- "mail deang@ims.com\n", inb(SBLKCTL + base));
- outb(0, FLAGS + base);
- return (0);
- }
-
- /*
- * For the 294x cards, clearing DIAGLEDEN and DIAGLEDON, will
- * take the card out of diagnostic mode and make the host adatper
- * LED follow bus activity (will not always be on).
- */
- outb(sblkctl & ~(DIAGLEDEN | DIAGLEDON), SBLKCTL + base);
-
- /*
- * The IRQ level in i/o port 4 maps directly onto the real
- * IRQ number. If it's ok, register it with the kernel.
- *
- * NB. the Adaptec documentation says the IRQ number is only
- * in the lower four bits; the ECU information shows the
- * high bit being used as well. Which is correct?
- *
- * The PCI cards get their interrupt from PCI BIOS.
- */
- if ((config->chip_type == AIC_777x) && ((config->irq < 9) || (config->irq > 15)))
- {
- printk("aic7xxx: Host adapter uses unsupported IRQ level, ignoring.\n");
- return (0);
- }
-
- /*
- * Check the IRQ to see if it is shared by another aic7xxx
- * controller. If it is and sharing of IRQs is not defined,
- * then return 0 hosts found. If sharing of IRQs is allowed
- * or the IRQ is not shared by another host adapter, then
- * proceed.
- */
-#ifndef AIC7XXX_SHARE_IRQS
- if (aic7xxx_boards[config->irq] != NULL)
- {
- printk("aic7xxx: Sharing of IRQ's is not configured.\n");
- return (0);
- }
-#endif
-
- /*
- * Print out debugging information before re-enabling
- * the card - a lot of registers on it can't be read
- * when the sequencer is active.
- */
- debug_config(config);
-
- /*
- * Before registry, make sure that the offsets of the
- * struct scatterlist are what the sequencer will expect,
- * otherwise disable scatter-gather altogether until someone
- * can fix it. This is important since the sequencer will
- * DMA elements of the SG array in while executing commands.
- */
- if (template->sg_tablesize != SG_NONE)
- {
- struct scatterlist sg;
-
- if (SG_STRUCT_CHECK(sg))
- {
- printk("aic7xxx: Warning - Kernel scatter-gather structures changed, "
- "disabling it.\n");
- template->sg_tablesize = SG_NONE;
- }
- }
-
- /*
- * Register each "host" and fill in the returned Scsi_Host
- * structure as best we can. Some of the parameters aren't
- * really relevant for bus types beyond ISA, and none of the
- * high-level SCSI code looks at it anyway. Why are the fields
- * there? Also save the pointer so that we can find the
- * information when an IRQ is triggered.
- */
- host = scsi_register(template, sizeof(struct aic7xxx_host));
- host->can_queue = config->maxscb;
- host->cmd_per_lun = AIC7XXX_CMDS_PER_LUN;
- host->this_id = config->scsi_id;
- host->irq = config->irq;
- if (config->bus_type == AIC_WIDE)
- {
- host->max_id = 16;
- }
- if (config->bus_type == AIC_TWIN)
- {
- host->max_channel = 1;
- }
-
- p = (struct aic7xxx_host *) host->hostdata;
-
- /*
- * Initialize the scb array by setting the state to free.
- */
- for (i = 0; i < AIC7XXX_MAXSCB; i++)
- {
- p->scb_array[i].state = SCB_FREE;
- p->scb_array[i].next = NULL;
- p->scb_array[i].cmd = NULL;
- }
-
- p->isr_count = 0;
- p->a_scanned = FALSE;
- p->b_scanned = FALSE;
- p->base = base;
- p->maxscb = config->maxscb;
- p->numscb = 0;
- p->extended = config->extended;
- p->type = config->type;
- p->chip_type = config->chip_type;
- p->ultra_enabled = config->ultra_enabled;
- p->chan_num = config->chan_num;
- p->bus_type = config->bus_type;
- p->have_seeprom = have_seeprom;
- p->seeprom = sc;
- p->free_scb = NULL;
- p->next = NULL;
-
- p->unpause = config->unpause;
- p->pause = config->pause;
-
- if (aic7xxx_boards[config->irq] == NULL)
- {
- /*
- * Warning! This must be done before requesting the irq. It is
- * possible for some boards to raise an interrupt as soon as
- * they are enabled. So when we request the irq from the Linux
- * kernel, an interrupt is triggered immediately. Therefore, we
- * must ensure the board data is correctly set before the request.
- */
- aic7xxx_boards[config->irq] = host;
-
- /*
- * Register IRQ with the kernel.
- */
- if (request_irq(config->irq, aic7xxx_isr, SA_INTERRUPT, "aic7xxx"))
- {
- printk("aic7xxx: Couldn't register IRQ %d, ignoring.\n", config->irq);
- aic7xxx_boards[config->irq] = NULL;
- return (0);
- }
- }
- else
- {
- /*
- * We have found a host adapter sharing an IRQ of a previously
- * registered host adapter. Add this host adapter's Scsi_Host
- * to the beginning of the linked list of hosts at the same IRQ.
- */
- p->next = aic7xxx_boards[config->irq];
- aic7xxx_boards[config->irq] = host;
- }
-
- /*
- * Load the sequencer program, then re-enable the board -
- * resetting the AIC-7770 disables it, leaving the lights
- * on with nobody home. On the PCI bus you *may* be home,
- * but then your mailing address is dynamically assigned
- * so no one can find you anyway :-)
- */
- printk("aic7xxx: Downloading sequencer code...");
- aic7xxx_loadseq(base);
-
- /*
- * Set Fast Mode and Enable the board
- */
- outb(FASTMODE, SEQCTL + base);
-
- if (p->chip_type == AIC_777x)
- {
- outb(ENABLE, BCTL + base);
- }
-
- printk("done.\n");
-
- /*
- * Set the SCSI Id, SXFRCTL0, SXFRCTL1, and SIMODE1, for both channels
- */
- if (p->bus_type == AIC_TWIN)
- {
- /*
- * Select Channel B.
- */
- outb((sblkctl & ~SELBUS_MASK) | SELBUSB, SBLKCTL + base);
-
- outb(config->scsi_id_b, SCSIID + base);
- scsi_conf = inb(SCSICONF + base + 1) & (ENSPCHK | STIMESEL);
- outb(scsi_conf | ENSTIMER | ACTNEGEN | STPWEN, SXFRCTL1 + base);
- outb(ENSELTIMO , SIMODE1 + base);
- if (p->ultra_enabled)
- {
- outb(DFON | SPIOEN | ULTRAEN, SXFRCTL0 + base);
- }
- else
- {
- outb(DFON | SPIOEN, SXFRCTL0 + base);
- }
-
- /*
- * Select Channel A
- */
- outb((sblkctl & ~SELBUS_MASK) | SELNARROW, SBLKCTL + base);
- }
- outb(config->scsi_id, SCSIID + base);
- scsi_conf = inb(SCSICONF + base) & (ENSPCHK | STIMESEL);
- outb(scsi_conf | ENSTIMER | ACTNEGEN | STPWEN, SXFRCTL1 + base);
- outb(ENSELTIMO , SIMODE1 + base);
- if (p->ultra_enabled)
- {
- outb(DFON | SPIOEN | ULTRAEN, SXFRCTL0 + base);
- }
- else
- {
- outb(DFON | SPIOEN, SXFRCTL0 + base);
- }
-
- /*
- * Look at the information that board initialization or the board
- * BIOS has left us. In the lower four bits of each target's
- * scratch space any value other than 0 indicates that we should
- * initiate synchronous transfers. If it's zero, the user or the
- * BIOS has decided to disable synchronous negotiation to that
- * target so we don't activate the needsdtr flag.
- */
- p->needsdtr_copy = 0x0;
- p->sdtr_pending = 0x0;
- p->needwdtr_copy = 0x0;
- p->wdtr_pending = 0x0;
- if (p->bus_type == AIC_SINGLE)
- {
- max_targets = 8;
- }
- else
- {
- max_targets = 16;
- }
-
- /*
- * Grab the disconnection disable table and invert it for our needs
- */
- if (have_seeprom)
- {
- p->discenable = 0x0;
- }
- else
- {
- if (bios_disabled)
- {
- printk("aic7xxx : Host adapter BIOS disabled. Using default SCSI "
- "device parameters.\n");
- p->discenable = 0xFFFF;
- }
- else
- {
- p->discenable = ~((inb(DISC_DSB + base + 1) << 8) |
- inb(DISC_DSB + base));
- }
- }
-
- for (i = 0; i < max_targets; i++)
- {
- if (have_seeprom)
- {
- target_settings = ((sc.device_flags[i] & CFXFER) << 4);
- if (sc.device_flags[i] & CFSYNCH)
- {
- p->needsdtr_copy |= (0x01 << i);
- }
- if (sc.device_flags[i] & CFWIDEB)
- {
- p->needwdtr_copy |= (0x01 << i);
- }
- if (sc.device_flags[i] & CFDISC)
- {
- p->discenable |= (0x01 << i);
- }
- }
- else
- {
- if (bios_disabled)
- {
- target_settings = 0; /* 10 MHz */
- p->needsdtr_copy |= (0x01 << i);
- p->needwdtr_copy |= (0x01 << i);
- }
- else
- {
- target_settings = inb(TARG_SCRATCH + base + i);
- if (target_settings & 0x0F)
- {
- p->needsdtr_copy |= (0x01 << i);
- /*
- * Default to asynchronous transfers (0 offset)
- */
- target_settings &= 0xF0;
- }
- if (target_settings & 0x80)
- {
- p->needwdtr_copy |= (0x01 << i);
- target_settings &= 0x7F;
- }
- }
- }
- outb(target_settings, (TARG_SCRATCH + base + i));
- }
-
- /*
- * If we are not wide, forget WDTR. This makes the driver
- * work on some cards that don't leave these fields cleared
- * when BIOS is not installed.
- */
- if (p->bus_type != AIC_WIDE)
- {
- p->needwdtr = 0;
- }
- p->needsdtr = p->needsdtr_copy;
- p->needwdtr = p->needwdtr_copy;
-#if 0
- printk("NeedSdtr = 0x%x, 0x%x\n", p->needsdtr_copy, p->needsdtr);
- printk("NeedWdtr = 0x%x, 0x%x\n", p->needwdtr_copy, p->needwdtr);
-#endif
-
- /*
- * Clear the control byte for every SCB so that the sequencer
- * doesn't get confused and think that one of them is valid
- */
- for (i = 0; i < config->maxscb; i++)
- {
- outb(i, SCBPTR + base);
- outb(0, SCBARRAY + base);
- }
-
- /*
- * For reconnecting targets, the sequencer code needs to
- * know how many SCBs it has to search through.
- */
- outb(config->maxscb, SCBCOUNT + base);
-
- /*
- * 2s compliment of SCBCOUNT
- */
- i = p->maxscb;
- outb(-i & 0xff, COMP_SCBCOUNT + base);
-
- /*
- * Clear the active flags - no targets are busy.
- */
- outb(0, ACTIVE_A + base);
- outb(0, ACTIVE_B + base);
-
- /*
- * We don't have any waiting selections
- */
- outb(SCB_LIST_NULL, WAITING_SCBH + base);
- outb(SCB_LIST_NULL, WAITING_SCBT + base);
-
- /*
- * Reset the SCSI bus. Is this necessary?
- * There may be problems for a warm boot without resetting
- * the SCSI bus. Either BIOS settings in scratch RAM
- * will not get reinitialized, or devices may stay at
- * previous negotiated settings (SDTR and WDTR) while
- * the driver will think that no negotiations have been
- * performed.
- *
- * Some devices need a long time to "settle" after a SCSI
- * bus reset.
- */
-
- if (!aic7xxx_no_reset)
- {
- printk("aic7xxx: Resetting the SCSI bus...");
- if (p->bus_type == AIC_TWIN)
- {
- /*
- * Select Channel B.
- */
- outb((sblkctl & ~SELBUS_MASK) | SELBUSB, SBLKCTL + base);
-
- outb(SCSIRSTO, SCSISEQ + base);
- udelay(1000);
- outb(0, SCSISEQ + base);
-
- /*
- * Select Channel A.
- */
- outb((sblkctl & ~SELBUS_MASK) | SELNARROW, SBLKCTL + base);
- }
-
- outb(SCSIRSTO, SCSISEQ + base);
- udelay(1000);
- outb(0, SCSISEQ + base);
-
- aic7xxx_delay(AIC7XXX_RESET_DELAY);
-
- printk("done.\n");
- }
-
- /*
- * Unpause the sequencer before returning and enable
- * interrupts - we shouldn't get any until the first
- * command is sent to us by the high-level SCSI code.
- */
- UNPAUSE_SEQUENCER(p);
- return (found);
-}
-
-/*+F*************************************************************************
- * Function:
- * aic7xxx_detect
- *
- * Description:
- * Try to detect and register an Adaptec 7770 or 7870 SCSI controller.
- *-F*************************************************************************/
-int
-aic7xxx_detect(Scsi_Host_Template *template)
-{
- int found = 0, slot, base;
- unsigned char irq = 0;
- int i;
- struct aic7xxx_host_config config;
-
- template->proc_dir = &proc_scsi_aic7xxx;
- config.chan_num = 0;
-
- /*
- * Since we may allow sharing of IRQs, it is imperative
- * that we "null-out" the aic7xxx_boards array. It is
- * not guaranteed to be initialized to 0 (NULL). We use
- * a NULL entry to indicate that no prior hosts have
- * been found/registered for that IRQ.
- */
- for (i = 0; i <= MAXIRQ; i++)
- {
- aic7xxx_boards[i] = NULL;
- }
-
- /*
- * Initialize the spurious count to 0.
- */
- aic7xxx_spurious_count = 0;
-
- /*
- * EISA/VL-bus card signature probe.
- */
- for (slot = MINSLOT; slot <= MAXSLOT; slot++)
- {
- base = SLOTBASE(slot) + MINREG;
-
- if (check_region(MINREG + base, MAXREG - MINREG))
- {
- /*
- * Some other driver has staked a
- * claim to this i/o region already.
- */
- continue;
- }
-
- config.type = aic7xxx_probe(slot, HID0 + base);
- if (config.type != AIC_NONE)
- {
- /*
- * We found a card, allow 1 spurious interrupt.
- */
- aic7xxx_spurious_count = 1;
-
- /*
- * We "find" a AIC-7770 if we locate the card
- * signature and we can set it up and register
- * it with the kernel without incident.
- */
- config.chip_type = AIC_777x;
- config.base = base;
- config.irq = irq;
- config.parity = AIC_UNKNOWN;
- config.low_term = AIC_UNKNOWN;
- config.high_term = AIC_UNKNOWN;
- config.busrtime = 0;
- config.walk_scbs = FALSE;
- config.ultra_enabled = FALSE;
- found += aic7xxx_register(template, &config);
-
- /*
- * Disallow spurious interrupts.
- */
- aic7xxx_spurious_count = 0;
- }
- }
-
-#ifdef CONFIG_PCI
- /*
- * PCI-bus probe.
- */
- if (pcibios_present())
- {
- struct
- {
- unsigned short vendor_id;
- unsigned short device_id;
- aha_type card_type;
- aha_chip_type chip_type;
- } const aic7xxx_pci_devices[] = {
- {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7850, AIC_7850, AIC_785x},
- {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7870, AIC_7870, AIC_787x},
- {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7871, AIC_7871, AIC_787x},
- {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7872, AIC_7872, AIC_787x},
- {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7873, AIC_7873, AIC_787x},
- {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7874, AIC_7874, AIC_787x},
- {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7880, AIC_7880, AIC_788x},
- {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7881, AIC_7881, AIC_788x},
- {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7882, AIC_7882, AIC_788x},
- {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7883, AIC_7883, AIC_788x},
- {PCI_VENDOR_ID_ADAPTEC, PCI_DEVICE_ID_ADAPTEC_7884, AIC_7884, AIC_788x}
- };
-
- int error;
- int done = 0;
- unsigned int io_port;
- unsigned short index = 0;
- unsigned char pci_bus, pci_device_fn;
- unsigned int csize_lattime;
- unsigned int class_revid;
- unsigned int devconfig;
- char rev_id[] = {'B', 'C', 'D'};
-
- for (i = 0; i < NUMBER(aic7xxx_pci_devices); i++)
- {
- done = FALSE;
- while (!done)
- {
- if (pcibios_find_device(aic7xxx_pci_devices[i].vendor_id,
- aic7xxx_pci_devices[i].device_id,
- index, &pci_bus, &pci_device_fn))
- {
- done = TRUE;
- }
- else /* Found an Adaptec PCI device. */
- {
- config.type = aic7xxx_pci_devices[i].card_type;
- config.chip_type = aic7xxx_pci_devices[i].chip_type;
- config.chan_num = 0;
- config.walk_scbs = FALSE;
- switch (config.type)
- {
- case AIC_7872: /* 3940 */
- case AIC_7882: /* 3940-Ultra */
- config.walk_scbs = TRUE;
- config.chan_num = number_of_39xxs & 0x1; /* Has 2 controllers */
- number_of_39xxs++;
- if (number_of_39xxs == 2)
- {
- number_of_39xxs = 0; /* To be consistent with 3985. */
- }
- break;
-
- case AIC_7873: /* 3985 */
- case AIC_7883: /* 3985-Ultra */
- config.chan_num = number_of_39xxs & 0x3; /* Has 3 controllers */
- number_of_39xxs++;
- if (number_of_39xxs == 3)
- {
- number_of_39xxs = 0;
- }
- break;
-
- default:
- break;
- }
-
- /*
- * Read esundry information from PCI BIOS.
- */
- error = pcibios_read_config_dword(pci_bus, pci_device_fn,
- PCI_BASE_ADDRESS_0, &io_port);
- error += pcibios_read_config_byte(pci_bus, pci_device_fn,
- PCI_INTERRUPT_LINE, &irq);
-
- /*
- * Ensure that we are using good values for the PCI burst size
- * and latency timer.
- */
- error += pcibios_read_config_dword(pci_bus, pci_device_fn,
- CSIZE_LATTIME, &csize_lattime);
- if ((csize_lattime & CACHESIZE) == 0)
- {
- /* Default to 8DWDs - what's the PCI define for this? */
- csize_lattime |= 8;
- }
- if((csize_lattime & LATTIME) == 0)
- {
- /* Default to 64 PCLKS (is this a good value?) */
- /* This may also be availble in the SEEPROM?? */
- csize_lattime |= (64 << 8);
- }
- pcibios_write_config_dword(pci_bus, pci_device_fn,
- CSIZE_LATTIME, csize_lattime);
- printk("aic7xxx: BurstLen = %d DWDs, Latency Timer = %d PCLKS\n",
- (int) (csize_lattime & CACHESIZE),
- (csize_lattime >> 8) & 0x000000ff);
-
- error += pcibios_read_config_dword(pci_bus, pci_device_fn,
- CLASS_PROGIF_REVID, &class_revid);
- if ((class_revid & DEVREVID) < 3)
- {
- printk("aic7xxx: %s Rev %c.\n", board_names[config.type],
- rev_id[class_revid & DEVREVID]);
- }
-
- error += pcibios_read_config_dword(pci_bus, pci_device_fn,
- DEVCONFIG, &devconfig);
- if (error)
- {
- panic("aic7xxx: (aic7xxx_detect) Error %d reading PCI registers.\n",
- error);
- }
-
- printk("aic7xxx: devconfig = 0x%x.\n", devconfig);
-
- /*
- * The first bit of PCI_BASE_ADDRESS_0 is always set, so
- * we mask it off.
- */
- base = io_port & 0xfffffffe;
-
- /*
- * I don't think we need to bother with allowing
- * spurious interrupts for the 787x/7850, but what
- * the hey.
- */
- aic7xxx_spurious_count = 1;
-
- config.base = base;
- config.irq = irq;
- config.parity = AIC_UNKNOWN;
- config.low_term = AIC_UNKNOWN;
- config.high_term = AIC_UNKNOWN;
- config.busrtime = 0;
- config.ultra_enabled = FALSE;
- if (devconfig & RAMPSM)
- {
- /*
- * External SRAM present. Have the probe walk the SCBs to see
- * how much SRAM we have and set the number of SCBs accordingly.
- * We have to turn off SCBRAMSEL to access the external SCB
- * SRAM.
- *
- * It seems that early versions of the aic7870 didn't use these
- * bits, hence the hack for the 3940 above. I would guess that
- * recent 3940s using later aic7870 or aic7880 chips do actually
- * set RAMPSM.
- *
- * The documentation isn't clear, but it sounds like the value
- * written to devconfig must not have RAMPSM set. The second
- * sixteen bits of the register are R/O anyway, so it shouldn't
- * affect RAMPSM either way.
- */
- printk ("aic7xxx: External RAM detected. Enabling RAM access.\n");
- devconfig &= ~(RAMPSM | SCBRAMSEL);
- pcibios_write_config_dword(pci_bus, pci_device_fn,
- DEVCONFIG, devconfig);
- config.walk_scbs = TRUE;
- }
- found += aic7xxx_register(template, &config);
-
- /*
- * Disable spurious interrupts.
- */
- aic7xxx_spurious_count = 0;
-
- index++;
- } /* Found an Adaptec PCI device. */
- }
- }
- }
-#endif CONFIG_PCI
-
- template->name = aic7xxx_info(NULL);
- return (found);
-}
-
-
-/*+F*************************************************************************
- * Function:
- * aic7xxx_buildscb
- *
- * Description:
- * Build a SCB.
- *-F*************************************************************************/
-static void
-aic7xxx_buildscb(struct aic7xxx_host *p,
- Scsi_Cmnd *cmd,
- struct aic7xxx_scb *scb)
-{
- void *addr;
- unsigned short mask;
- struct scatterlist *sg;
-
- /*
- * Setup the control byte if we need negotiation and have not
- * already requested it.
- */
-#ifdef AIC7XXX_TAGGED_QUEUEING
- if (cmd->device->tagged_supported)
- {
- if (cmd->device->tagged_queue == 0)
- {
- printk("aic7xxx: Enabling tagged queuing for target %d, "
- "channel %d.\n", cmd->target, cmd->channel);
- cmd->device->tagged_queue = 1;
- cmd->device->current_tag = 1; /* enable tagging */
- }
- cmd->tag = cmd->device->current_tag;
- cmd->device->current_tag++;
- scb->control |= TAG_ENB;
- }
-#endif
- mask = (0x01 << (cmd->target | (cmd->channel << 3)));
- if (p->discenable & mask)
- {
- scb->control |= DISCENB;
- }
- if ((p->needwdtr & mask) && !(p->wdtr_pending & mask))
- {
- p->wdtr_pending |= mask;
- scb->control |= NEEDWDTR;
-#if 0
- printk("aic7xxx: Sending WDTR request to target %d.\n", cmd->target);
-#endif
- }
- else
- {
- if ((p->needsdtr & mask) && !(p->sdtr_pending & mask))
- {
- p->sdtr_pending |= mask;
- scb->control |= NEEDSDTR;
-#if 0
- printk("aic7xxx: Sending SDTR request to target %d.\n", cmd->target);
-#endif
- }
- }
-
-#if 0
- printk("aic7xxx: (build_scb) Target %d, cmd(0x%x) size(%u) wdtr(0x%x) "
- "mask(0x%x).\n",
- cmd->target, cmd->cmnd[0], cmd->cmd_len, p->needwdtr, mask);
-#endif
- scb->target_channel_lun = ((cmd->target << 4) & 0xF0) |
- ((cmd->channel & 0x01) << 3) | (cmd->lun & 0x07);
-
- /*
- * The interpretation of request_buffer and request_bufflen
- * changes depending on whether or not use_sg is zero; a
- * non-zero use_sg indicates the number of elements in the
- * scatter-gather array.
- */
-
- /*
- * XXX - this relies on the host data being stored in a
- * little-endian format.
- */
- addr = cmd->cmnd;
- scb->SCSI_cmd_length = cmd->cmd_len;
- memcpy(scb->SCSI_cmd_pointer, &addr, sizeof(scb->SCSI_cmd_pointer));
-
- if (cmd->use_sg)
- {
- scb->SG_segment_count = cmd->use_sg;
- memcpy(scb->SG_list_pointer, &cmd->request_buffer,
- sizeof(scb->SG_list_pointer));
- memcpy(&sg, &cmd->request_buffer, sizeof(sg));
- memcpy(scb->data_pointer, &(sg[0].address), sizeof(scb->data_pointer));
- scb->data_count = sg[0].length;
-#if 0
- debug("aic7xxx: (build_scb) SG segs(%d), length(%u), sg[0].length(%d).\n",
- cmd->use_sg, aic7xxx_length(cmd, 0), scb->data_count);
-#endif
- }
- else
- {
-#if 0
- debug("aic7xxx: (build_scb) Creating scatterlist, addr(0x%lx) length(%d).\n",
- (unsigned long) cmd->request_buffer, cmd->request_bufflen);
-#endif
- if (cmd->request_bufflen == 0)
- {
- /*
- * In case the higher level SCSI code ever tries to send a zero
- * length command, ensure the SCB indicates no data. The driver
- * will interpret a zero length command as a Bus Device Reset.
- */
- scb->SG_segment_count = 0;
- memset(scb->SG_list_pointer, 0, sizeof(scb->SG_list_pointer));
- memset(scb->data_pointer, 0, sizeof(scb->data_pointer));
- scb->data_count = 0;
- }
- else
- {
- scb->SG_segment_count = 1;
- scb->sg.address = (char *) cmd->request_buffer;
- scb->sg.length = cmd->request_bufflen;
- addr = &scb->sg;
- memcpy(scb->SG_list_pointer, &addr, sizeof(scb->SG_list_pointer));
- scb->data_count = scb->sg.length;
- memcpy(scb->data_pointer, &cmd->request_buffer, sizeof(scb->data_pointer));
- }
- }
-}
-
-/*+F*************************************************************************
- * Function:
- * aic7xxx_queue
- *
- * Description:
- * Queue a SCB to the controller.
- *-F*************************************************************************/
-int
-aic7xxx_queue(Scsi_Cmnd *cmd, void (*fn)(Scsi_Cmnd *))
-{
- long flags;
- struct aic7xxx_host *p;
- struct aic7xxx_scb *scb;
-
- p = (struct aic7xxx_host *) cmd->host->hostdata;
-
- /*
- * Check to see if channel was scanned.
- */
- if (!p->a_scanned && (cmd->channel == 0))
- {
- printk("aic7xxx: Scanning channel A for devices.\n");
- p->a_scanned = TRUE;
- }
- else
- {
- if (!p->b_scanned && (cmd->channel == 1))
- {
- printk("aic7xxx: Scanning channel B for devices.\n");
- p->b_scanned = TRUE;
- }
- }
-
-#if 0
- debug("aic7xxx: (queue) cmd(0x%x) size(%u), target %d, channel %d, lun %d.\n",
- cmd->cmnd[0], cmd->cmd_len, cmd->target, cmd->channel,
- cmd->lun & 0x07);
-#endif
-
- /*
- * This is a critical section, since we don't want the
- * interrupt routine mucking with the host data or the
- * card. Since the kernel documentation is vague on
- * whether or not we are in a cli/sti pair already, save
- * the flags to be on the safe side.
- */
- save_flags(flags);
- cli();
-
- /*
- * Find a free slot in the SCB array to load this command
- * into. Since can_queue is set to the maximum number of
- * SCBs for the card, we should always find one.
- *
- * First try to find an scb in the free list. If there are
- * none in the free list, then check the current number of
- * of scbs and take an unused one from the scb array.
- */
- scb = p->free_scb;
- if (scb != NULL)
- { /* found one in the free list */
- p->free_scb = scb->next; /* remove and update head of list */
- /*
- * Warning! For some unknown reason, the scb at the head
- * of the free list is not the same address that it should
- * be. That's why we set the scb pointer taken by the
- * position in the array. The scb at the head of the list
- * should match this address, but it doesn't.
- */
- scb = &(p->scb_array[scb->position]);
- scb->control = 0;
- scb->state = SCB_ACTIVE;
- }
- else
- {
- if (p->numscb >= p->maxscb)
- {
- panic("aic7xxx: (aic7xxx_queue) Couldn't find a free SCB.\n");
- }
- else
- {
- /*
- * Initialize the scb within the scb array. The
- * position within the array is the position on
- * the board that it will be loaded.
- */
- scb = &(p->scb_array[p->numscb]);
- memset(scb, 0, sizeof(*scb));
-
- scb->position = p->numscb;
- p->numscb++;
- scb->state = SCB_ACTIVE;
- }
- }
-
- scb->cmd = cmd;
- aic7xxx_position(cmd) = scb->position;
-#if 0
- debug_scb(scb);
-#endif;
-
- /*
- * Construct the SCB beforehand, so the sequencer is
- * paused a minimal amount of time.
- */
- aic7xxx_buildscb(p, cmd, scb);
-
-#if 0
- if (scb != &p->scb_array[scb->position])
- {
- printk("aic7xxx: (queue) Address of SCB by position does not match SCB "
- "address.\n");
- }
- printk("aic7xxx: (queue) SCB pos(%d) cmdptr(0x%x) state(%d) freescb(0x%x)\n",
- scb->position, (unsigned int) scb->cmd,
- scb->state, (unsigned int) p->free_scb);
-#endif
- /*
- * Pause the sequencer so we can play with its registers -
- * wait for it to acknowledge the pause.
- *
- * XXX - should the interrupts be left on while doing this?
- */
- PAUSE_SEQUENCER(p);
-
- /*
- * Save the SCB pointer and put our own pointer in - this
- * selects one of the four banks of SCB registers. Load
- * the SCB, then write its pointer into the queue in FIFO
- * and restore the saved SCB pointer.
- */
- aic7xxx_putscb(p, scb);
- outb(scb->position, QINFIFO + p->base);
-
- /*
- * Make sure the Scsi_Cmnd pointer is saved, the struct it
- * points to is set up properly, and the parity error flag
- * is reset, then unpause the sequencer and watch the fun
- * begin.
- */
- cmd->scsi_done = fn;
- aic7xxx_error(cmd) = DID_OK;
- aic7xxx_status(cmd) = 0;
- cmd->result = 0;
- memset(&cmd->sense_buffer, 0, sizeof(cmd->sense_buffer));
-
- UNPAUSE_SEQUENCER(p);
-#if 0
- printk("aic7xxx: (queue) After - cmd(0x%lx) scb->cmd(0x%lx) pos(%d).\n",
- (long) cmd, (long) scb->cmd, scb->position);
-#endif;
- restore_flags(flags);
- return (0);
-}
-
-/*+F*************************************************************************
- * Function:
- * aic7xxx_abort_scb
- *
- * Description:
- * Abort an scb. If the scb has not previously been aborted, then
- * we attempt to send a BUS_DEVICE_RESET message to the target. If
- * the scb has previously been unsuccessfully aborted, then we will
- * reset the channel and have all devices renegotiate. Returns an
- * enumerated type that indicates the status of the operation.
- *-F*************************************************************************/
-static aha_abort_reset_type
-aic7xxx_abort_scb(struct aic7xxx_host *p, struct aic7xxx_scb *scb,
- unsigned char errcode)
-{
- int base = p->base;
- int found = FALSE;
- aha_abort_reset_type scb_status = ABORT_RESET_SUCCESS;
- char channel = scb->target_channel_lun & SELBUSB ? 'B': 'A';
-
- /*
- * Ensure that the card doesn't do anything
- * behind our back.
- */
- PAUSE_SEQUENCER(p);
-
-#ifdef AIC7XXX_DEBUG_ABORT
- printk ("aic7xxx: (abort_scb) scb %d, scb_aborted 0x%x\n",
- scb->position, (scb->state & SCB_ABORTED));
-#endif
- /*
- * First, determine if we want to do a bus reset or simply a bus device
- * reset. If this is the first time that a transaction has timed out,
- * just schedule a bus device reset. Otherwise, we reset the bus and
- * abort all pending I/Os on that bus.
- */
- if (scb->state & SCB_ABORTED)
- {
- /*
- * Been down this road before. Do a full bus reset.
- */
- found = aic7xxx_reset_channel(p, channel, scb->position);
- }
- else
- {
- unsigned char active_scb, control;
- struct aic7xxx_scb *active_scbp;
-
- /*
- * Send a Bus Device Reset Message:
- * The target we select to send the message to may be entirely
- * different than the target pointed to by the scb that timed
- * out. If the command is in the QINFIFO or the waiting for
- * selection list, its not tying up the bus and isn't responsible
- * for the delay so we pick off the active command which should
- * be the SCB selected by SCBPTR. If its disconnected or active,
- * we device reset the target scbp points to. Although it may
- * be that this target is not responsible for the delay, it may
- * may also be that we're timing out on a command that just takes
- * too much time, so we try the bus device reset there first.
- */
- active_scb = inb(SCBPTR + base);
- active_scbp = &(p->scb_array[active_scb]);
- control = inb(SCBARRAY + base);
-
- /*
- * Test to see if scbp is disconnected
- */
- outb(scb->position, SCBPTR + base);
- if (inb(SCBARRAY + base) & DISCONNECTED)
- {
-#ifdef AIC7XXX_DEBUG_ABORT
- printk ("aic7xxx: (abort_scb) scb %d is disconnected.\n", scb->position);
-#endif
- scb->state |= (SCB_DEVICE_RESET | SCB_ABORTED);
- scb->SG_segment_count = 0;
- memset(scb->SG_list_pointer, 0, sizeof(scb->SG_list_pointer));
- memset(scb->data_pointer, 0, sizeof(scb->data_pointer));
- scb->data_count = 0;
- aic7xxx_putscb(p, scb);
- aic7xxx_error(scb->cmd) = errcode;
- scb_status = ABORT_RESET_PENDING;
- aic7xxx_add_waiting_scb(base, scb, LIST_SECOND);
- UNPAUSE_SEQUENCER(p);
- }
- else
- {
- /*
- * Is the active SCB really active?
- */
- if (active_scbp->state & SCB_ACTIVE)
- {
- unsigned char msg_len = inb(MSG_LEN + base);
- if (msg_len != 0)
- {
-#ifdef AIC7XXX_DEBUG_ABORT
- printk ("aic7xxx: (abort_scb) scb is active, needs DMA, "
- "msg_len is non-zero.\n");
-#endif
- /*
- * If we're in a message phase, tacking on another message
- * may confuse the target totally. The bus is probably wedged,
- * so reset the channel.
- */
- channel = (active_scbp->target_channel_lun & SELBUSB) ? 'B': 'A';
- aic7xxx_reset_channel(p, channel, scb->position);
- }
- else
- {
-#ifdef AIC7XXX_DEBUG_ABORT
- printk ("aic7xxx: (abort_scb) scb is active, needs DMA, "
- "msg_len is zero.\n");
-#endif
- /*
- * Load the message buffer and assert attention.
- */
- active_scbp->state |= (SCB_DEVICE_RESET | SCB_ABORTED);
- outb(1, MSG_LEN + base);
- outb(MSG_BUS_DEVICE_RESET, MSG0 + base);
- if (active_scbp->target_channel_lun != scb->target_channel_lun)
- {
- /*
- * XXX - We would like to increment the timeout on scb, but
- * access to that routine is denied because it is hidden
- * in scsi.c. If we were able to do this, it would give
- * scb a new lease on life.
- */
- ;
- }
- aic7xxx_error(scb->cmd) = errcode;
- scb_status = ABORT_RESET_PENDING;
- UNPAUSE_SEQUENCER(p);
- }
- }
- else
- {
-#ifdef AIC7XXX_DEBUG_ABORT
- printk ("aic7xxx: (abort_scb) no active command.\n");
-#endif
- /*
- * No active command to single out, so reset
- * the bus for the timed out target.
- */
- aic7xxx_reset_channel(p, channel, scb->position);
- }
- }
- }
- return (scb_status);
-}
-
-/*+F*************************************************************************
- * Function:
- * aic7xxx_abort_reset
- *
- * Description:
- * Abort or reset the current SCSI command(s). Returns an enumerated
- * type that indicates the status of the operation.
- *-F*************************************************************************/
-static aha_abort_reset_type
-aic7xxx_abort_reset(Scsi_Cmnd *cmd, unsigned char errcode)
-{
- struct aic7xxx_scb *scb;
- struct aic7xxx_host *p;
- long flags;
- aha_abort_reset_type scb_status = ABORT_RESET_SUCCESS;
-
- p = (struct aic7xxx_host *) cmd->host->hostdata;
- scb = &(p->scb_array[aic7xxx_position(cmd)]);
-
- save_flags(flags);
- cli();
-
-#ifdef AIC7XXX_DEBUG_ABORT
- printk ("aic7xxx: (abort_reset) scb state 0x%x\n", scb->state);
-#endif
-
- if (scb->state & SCB_ACTIVE)
- {
- if (scb->state & SCB_IMMED)
- {
- /*
- * Don't know how set the number of retries to 0.
- */
- /* cmd->retries = 0; */
- aic7xxx_error(cmd) = errcode;
- aic7xxx_done(p, scb);
- }
- else
- {
- /*
- * Abort the operation.
- */
- scb_status = aic7xxx_abort_scb(p, scb, errcode);
- }
- }
- else
- {
- /*
- * The scb is not active and must have completed after the timeout
- * check in scsi.c and before we check the scb state above. For
- * this case we return SCSI_ABORT_NOT_RUNNING (if abort was called)
- * or SCSI_RESET_SUCCESS (if reset was called).
- */
-#ifdef AIC7XXX_DEBUG_ABORT
- printk ("aic7xxx: (abort_reset) called with no active scb, errcode 0x%x\n",
- errcode);
-#endif
- scb_status = ABORT_RESET_INACTIVE;
- /*
- * According to the comments in scsi.h and Michael Neuffer, if we do not
- * have an active command for abort or reset, we should not call the
- * command done function. Unfortunately, this hangs the system for me
- * unless we *do* call the done function.
- *
- * XXX - Revisit this sometime!
- */
- cmd->result = errcode << 16;
- cmd->scsi_done(cmd);
- }
- restore_flags(flags);
- return (scb_status);
-}
-
-
-/*+F*************************************************************************
- * Function:
- * aic7xxx_abort
- *
- * Description:
- * Abort the current SCSI command(s).
- *-F*************************************************************************/
-int
-aic7xxx_abort(Scsi_Cmnd *cmd)
-{
-#ifdef AIC7XXX_DEBUG_ABORT
- printk ("aic7xxx: (abort) target/channel %d/%d\n", cmd->target, cmd->channel);
-#endif
-
- switch (aic7xxx_abort_reset(cmd, DID_ABORT))
- {
- case ABORT_RESET_INACTIVE:
- return (SCSI_ABORT_NOT_RUNNING);
- break;
- case ABORT_RESET_PENDING:
- return (SCSI_ABORT_PENDING);
- break;
- case ABORT_RESET_SUCCESS:
- default:
- return (SCSI_ABORT_SUCCESS);
- break;
- }
-}
-
-/*+F*************************************************************************
- * Function:
- * aic7xxx_reset
- *
- * Description:
- * Resetting the bus always succeeds - is has to, otherwise the
- * kernel will panic! Try a surgical technique - sending a BUS
- * DEVICE RESET message - on the offending target before pulling
- * the SCSI bus reset line.
- *-F*************************************************************************/
-int
-aic7xxx_reset(Scsi_Cmnd *cmd)
-{
-#ifdef AIC7XXX_DEBUG_ABORT
- printk ("aic7xxx: (reset) target/channel %d/%d\n", cmd->target, cmd->channel);
-#endif
-
- switch (aic7xxx_abort_reset(cmd, DID_RESET))
- {
- case ABORT_RESET_PENDING:
- return (SCSI_RESET_PENDING);
- break;
- case ABORT_RESET_INACTIVE:
- case ABORT_RESET_SUCCESS:
- default:
- return (SCSI_RESET_SUCCESS);
- break;
- }
-}
-
-/*+F*************************************************************************
- * Function:
- * aic7xxx_biosparam
- *
- * Description:
- * Return the disk geometry for the given SCSI device.
- *-F*************************************************************************/
-int
-aic7xxx_biosparam(Disk *disk, kdev_t dev, int geom[])
-{
- int heads, sectors, cylinders;
- struct aic7xxx_host *p;
-
- p = (struct aic7xxx_host *) disk->device->host->hostdata;
-
- /*
- * XXX - if I could portably find the card's configuration
- * information, then this could be autodetected instead
- * of left to a boot-time switch.
- */
- heads = 64;
- sectors = 32;
- cylinders = disk->capacity / (heads * sectors);
-
- if (p->extended && cylinders > 1024)
- {
- heads = 255;
- sectors = 63;
- cylinders = disk->capacity / (255 * 63);
- }
-
- geom[0] = heads;
- geom[1] = sectors;
- geom[2] = cylinders;
-
- return (0);
-}
-
-#ifdef MACH
-#include "aic7xxx_proc.src"
-#else
-#include "aic7xxx_proc.c"
-#endif
-
-#ifdef MODULE
-/* Eventually this will go into an include file, but this will be later */
-Scsi_Host_Template driver_template = AIC7XXX;
-
-#include "scsi_module.c"
-#endif
-
-/*
- * Overrides for Emacs so that we almost follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 2
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -2
- * c-argdecl-indent: 2
- * c-label-offset: -2
- * c-continued-statement-offset: 2
- * c-continued-brace-offset: 0
- * indent-tabs-mode: nil
- * tab-width: 8
- * End:
- */
-
diff --git a/i386/i386at/gpl/linux/scsi/aic7xxx.h b/i386/i386at/gpl/linux/scsi/aic7xxx.h
deleted file mode 100644
index 76d4d962..00000000
--- a/i386/i386at/gpl/linux/scsi/aic7xxx.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*+M*************************************************************************
- * Adaptec 274x/284x/294x device driver for Linux.
- *
- * Copyright (c) 1994 John Aycock
- * The University of Calgary Department of Computer Science.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id: aic7xxx.h,v 1.1.1.1 1997/02/25 21:27:47 thomas Exp $
- *-M*************************************************************************/
-#ifndef _aic7xxx_h
-#define _aic7xxx_h
-
-#define AIC7XXX_H_VERSION "$Revision: 1.1.1.1 $"
-
-/*
- * Scsi_Host_Template (see hosts.h) for AIC-7770/AIC-7870 - some fields
- * to do with card config are filled in after the card is detected.
- */
-#define AIC7XXX { \
- NULL, \
- NULL, \
- NULL, \
- aic7xxx_proc_info, \
- NULL, \
- aic7xxx_detect, \
- NULL, \
- aic7xxx_info, \
- NULL, \
- aic7xxx_queue, \
- aic7xxx_abort, \
- aic7xxx_reset, \
- NULL, \
- aic7xxx_biosparam, \
- -1, /* max simultaneous cmds */\
- -1, /* scsi id of host adapter */\
- SG_ALL, /* max scatter-gather cmds */\
- 2, /* cmds per lun (linked cmds) */\
- 0, /* number of 7xxx's present */\
- 0, /* no memory DMA restrictions */\
- ENABLE_CLUSTERING \
-}
-
-extern int aic7xxx_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *));
-extern int aic7xxx_biosparam(Disk *, kdev_t, int[]);
-extern int aic7xxx_detect(Scsi_Host_Template *);
-extern int aic7xxx_command(Scsi_Cmnd *);
-extern int aic7xxx_abort(Scsi_Cmnd *);
-extern int aic7xxx_reset(Scsi_Cmnd *);
-
-extern const char *aic7xxx_info(struct Scsi_Host *);
-
-extern int aic7xxx_proc_info(char *, char **, off_t, int, int, int);
-
-#endif /* _aic7xxx_h */
diff --git a/i386/i386at/gpl/linux/scsi/aic7xxx_proc.src b/i386/i386at/gpl/linux/scsi/aic7xxx_proc.src
deleted file mode 100644
index 65996822..00000000
--- a/i386/i386at/gpl/linux/scsi/aic7xxx_proc.src
+++ /dev/null
@@ -1,271 +0,0 @@
-/*+M*************************************************************************
- * Adaptec 274x/284x/294x device driver proc support for Linux.
- *
- * Copyright (c) 1995 Dean W. Gehnert
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * ----------------------------------------------------------------
- * o Modified from the EATA /proc support.
- * o Additional support for device block statistics provided by
- * Matthew Jacob.
- *
- * Dean W. Gehnert, deang@ims.com, 08/30/95
- *
- * $Id: aic7xxx_proc.src,v 1.1.1.1 1997/02/25 21:27:47 thomas Exp $
- *-M*************************************************************************/
-
-#define BLS buffer + len + size
-#define HDRB \
-" < 512 512-1K 1-2K 2-4K 4-8K 8-16K 16-32K 32-64K 64-128K >128K"
-
-#ifdef PROC_DEBUG
-extern int vsprintf(char *, const char *, va_list);
-
-static void
-proc_debug(const char *fmt, ...)
-{
- va_list ap;
- char buf[256];
-
- va_start(ap, fmt);
- vsprintf(buf, fmt, ap);
- printk(buf);
- va_end(ap);
-}
-#else /* PROC_DEBUG */
-# define proc_debug(fmt, args...)
-#endif /* PROC_DEBUG */
-
-/*+F*************************************************************************
- * Function:
- * aic7xxx_set_info
- *
- * Description:
- * Set parameters for the driver from the /proc filesystem.
- *-F*************************************************************************/
-int
-aic7xxx_set_info(char *buffer, int length, struct Scsi_Host *HBAptr)
-{
- proc_debug("aic7xxx_set_info(): %s\n", buffer);
- return (-ENOSYS); /* Currently this is a no-op */
-}
-
-/*+F*************************************************************************
- * Function:
- * aic7xxx_proc_info
- *
- * Description:
- * Return information to handle /proc support for the driver.
- *-F*************************************************************************/
-int
-aic7xxx_proc_info(char *buffer, char **start, off_t offset, int length,
- int hostno, int inout)
-{
- struct Scsi_Host *HBAptr;
- struct aic7xxx_host *p;
- static u8 buff[512];
- int i;
- int size = 0;
- int len = 0;
- off_t begin = 0;
- off_t pos = 0;
- static char *bus_name[] = {"Single", "Twin", "Wide"};
-
- HBAptr = NULL;
- for (i = 0; i < NUMBER(aic7xxx_boards); i++)
- {
- if ((HBAptr = aic7xxx_boards[i]) != NULL)
- {
- if (HBAptr->host_no == hostno)
- {
- break;
- }
-
- while ((HBAptr->hostdata != NULL) &&
- ((HBAptr = ((struct aic7xxx_host *) HBAptr->hostdata)->next) != NULL))
- {
- if (HBAptr->host_no == hostno)
- {
- break; break;
- }
- }
-
- HBAptr = NULL;
- }
- }
-
- if (HBAptr == NULL)
- {
- size += sprintf(BLS, "Can't find adapter for host number %d\n", hostno);
- len += size; pos = begin + len; size = 0;
- goto stop_output;
- }
-
- if (inout == TRUE) /* Has data been written to the file? */
- {
- return (aic7xxx_set_info(buffer, length, HBAptr));
- }
-
- if (offset == 0)
- {
- memset(buff, 0, sizeof(buff));
- }
-
- p = (struct aic7xxx_host *) HBAptr->hostdata;
-
- size += sprintf(BLS, "Adaptec AIC7xxx driver version: ");
- size += sprintf(BLS, "%s/", rcs_version(AIC7XXX_C_VERSION));
- size += sprintf(BLS, "%s/", rcs_version(AIC7XXX_H_VERSION));
- size += sprintf(BLS, "%s\n", rcs_version(AIC7XXX_SEQ_VER));
- len += size; pos = begin + len; size = 0;
-
- size += sprintf(BLS, "\n");
- size += sprintf(BLS, "Compile Options:\n");
-#ifdef AIC7XXX_RESET_DELAY
- size += sprintf(BLS, " AIC7XXX_RESET_DELAY : %d\n", AIC7XXX_RESET_DELAY);
-#endif
-#ifdef AIC7XXX_TWIN_SUPPORT
- size += sprintf(BLS, " AIC7XXX_TWIN_SUPPORT : Enabled\n");
-#else
- size += sprintf(BLS, " AIC7XXX_TWIN_SUPPORT : Disabled\n");
-#endif
-#ifdef AIC7XXX_TAGGED_QUEUEING
- size += sprintf(BLS, " AIC7XXX_TAGGED_QUEUEING: Enabled\n");
-#else
- size += sprintf(BLS, " AIC7XXX_TAGGED_QUEUEING: Disabled\n");
-#endif
-#ifdef AIC7XXX_SHARE_IRQS
- size += sprintf(BLS, " AIC7XXX_SHARE_IRQS : Enabled\n");
-#else
- size += sprintf(BLS, " AIC7XXX_SHARE_IRQS : Disabled\n");
-#endif
-#ifdef AIC7XXX_PROC_STATS
- size += sprintf(BLS, " AIC7XXX_PROC_STATS : Enabled\n");
-#else
- size += sprintf(BLS, " AIC7XXX_PROC_STATS : Disabled\n");
-#endif
- len += size; pos = begin + len; size = 0;
-
- size += sprintf(BLS, "\n");
- size += sprintf(BLS, "Adapter Configuration:\n");
- size += sprintf(BLS, " SCSI Adapter: %s\n", board_names[p->type]);
- size += sprintf(BLS, " Host Bus: %s\n", bus_name[p->bus_type]);
- size += sprintf(BLS, " Base IO: %#.4x\n", p->base);
- size += sprintf(BLS, " IRQ: %d\n", HBAptr->irq);
- size += sprintf(BLS, " SCB: %d (%d)\n", p->numscb, p->maxscb);
- size += sprintf(BLS, " Interrupts: %d", p->isr_count);
- if (p->chip_type == AIC_777x)
- {
- size += sprintf(BLS, " %s\n",
- (p->pause & IRQMS) ? "(Level Sensitive)" : "(Edge Triggered)");
- }
- else
- {
- size += sprintf(BLS, "\n");
- }
- size += sprintf(BLS, " Serial EEPROM: %s\n",
- p->have_seeprom ? "True" : "False");
- size += sprintf(BLS, " Pause/Unpause: %#.2x/%#.2x\n", p->pause,
- p->unpause);
- size += sprintf(BLS, " Extended Translation: %sabled\n",
- p->extended ? "En" : "Dis");
- size += sprintf(BLS, " SCSI Bus Reset: %sabled\n",
- aic7xxx_no_reset ? "Dis" : "En");
- size += sprintf(BLS, " Ultra SCSI: %sabled\n",
- p->ultra_enabled ? "En" : "Dis");
- len += size; pos = begin + len; size = 0;
-
-#ifdef AIC7XXX_PROC_STATS
- {
- struct aic7xxx_xferstats *sp;
- int channel, target, lun;
-
- /*
- * XXX: Need to fix this to avoid overflow...
- */
- size += sprintf(BLS, "\n");
- size += sprintf(BLS, "Statistics:\n");
- for (channel = 0; channel < 2; channel++)
- {
- for (target = 0; target < 16; target++)
- {
- for (lun = 0; lun < 8; lun++)
- {
- sp = &p->stats[channel][target][lun];
- if (sp->xfers == 0)
- {
- continue;
- }
- size += sprintf(BLS, "CHAN#%c (TGT %d LUN %d):\n",
- 'A' + channel, target, lun);
- size += sprintf(BLS, "nxfers %ld (%ld read;%ld written)\n",
- sp->xfers, sp->r_total, sp->w_total);
- size += sprintf(BLS, "blks(512) rd=%ld; blks(512) wr=%ld\n",
- sp->r_total512, sp->w_total512);
- size += sprintf(BLS, "%s\n", HDRB);
- size += sprintf(BLS, " Reads:");
- size += sprintf(BLS, "%6ld %6ld %6ld %6ld ", sp->r_bins[0],
- sp->r_bins[1], sp->r_bins[2], sp->r_bins[3]);
- size += sprintf(BLS, "%6ld %6ld %6ld %6ld ", sp->r_bins[4],
- sp->r_bins[5], sp->r_bins[6], sp->r_bins[7]);
- size += sprintf(BLS, "%6ld %6ld\n", sp->r_bins[8],
- sp->r_bins[9]);
- size += sprintf(BLS, "Writes:");
- size += sprintf(BLS, "%6ld %6ld %6ld %6ld ", sp->w_bins[0],
- sp->w_bins[1], sp->w_bins[2], sp->w_bins[3]);
- size += sprintf(BLS, "%6ld %6ld %6ld %6ld ", sp->w_bins[4],
- sp->w_bins[5], sp->w_bins[6], sp->w_bins[7]);
- size += sprintf(BLS, "%6ld %6ld\n", sp->w_bins[8],
- sp->w_bins[9]);
- size += sprintf(BLS, "\n");
- }
- }
- }
- len += size; pos = begin + len; size = 0;
- }
-#endif /* AIC7XXX_PROC_STATS */
-
-stop_output:
- proc_debug("2pos: %ld offset: %ld len: %d\n", pos, offset, len);
- *start = buffer + (offset - begin); /* Start of wanted data */
- len -= (offset - begin); /* Start slop */
- if (len > length)
- {
- len = length; /* Ending slop */
- }
- proc_debug("3pos: %ld offset: %ld len: %d\n", pos, offset, len);
-
- return (len);
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 2
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -2
- * c-argdecl-indent: 2
- * c-label-offset: -2
- * c-continued-statement-offset: 2
- * c-continued-brace-offset: 0
- * indent-tabs-mode: nil
- * tab-width: 8
- * End:
- */
diff --git a/i386/i386at/gpl/linux/scsi/aic7xxx_reg.h b/i386/i386at/gpl/linux/scsi/aic7xxx_reg.h
deleted file mode 100644
index 4a7f612c..00000000
--- a/i386/i386at/gpl/linux/scsi/aic7xxx_reg.h
+++ /dev/null
@@ -1,746 +0,0 @@
-/*+M*************************************************************************
- * Adaptec AIC7xxx register and scratch ram definitions.
- *
- * Copyright (c) 1994, 1995, 1996 Justin T. Gibbs.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id: aic7xxx_reg.h,v 1.1.1.1 1997/02/25 21:27:47 thomas Exp $
- *-M*************************************************************************/
-
-/*
- * This header is shared by the sequencer code and the kernel level driver.
- *
- * All page numbers refer to the Adaptec AIC-7770 Data Book availible from
- * Adaptec's Technical Documents Department 1-800-934-2766
- */
-
-/*
- * SCSI Sequence Control (p. 3-11).
- * Each bit, when set starts a specific SCSI sequence on the bus
- */
-#define SCSISEQ 0x000
-#define TEMODEO 0x80
-#define ENSELO 0x40
-#define ENSELI 0x20
-#define ENRSELI 0x10
-#define ENAUTOATNO 0x08
-#define ENAUTOATNI 0x04
-#define ENAUTOATNP 0x02
-#define SCSIRSTO 0x01
-
-/*
- * SCSI Transfer Control 0 Register (pp. 3-13).
- * Controls the SCSI module data path.
- */
-#define SXFRCTL0 0x001
-#define DFON 0x80
-#define DFPEXP 0x40
-#define ULTRAEN 0x20
-#define CLRSTCNT 0x10
-#define SPIOEN 0x08
-#define SCAMEN 0x04
-#define CLRCHN 0x02
-/* UNUSED 0x01 */
-
-/*
- * SCSI Transfer Control 1 Register (pp. 3-14,15).
- * Controls the SCSI module data path.
- */
-#define SXFRCTL1 0x002
-#define BITBUCKET 0x80
-#define SWRAPEN 0x40
-#define ENSPCHK 0x20
-#define STIMESEL 0x18
-#define ENSTIMER 0x04
-#define ACTNEGEN 0x02
-#define STPWEN 0x01 /* Powered Termination */
-
-/*
- * SCSI Control Signal Read Register (p. 3-15).
- * Reads the actual state of the SCSI bus pins
- */
-#define SCSISIGI 0x003
-#define CDI 0x80
-#define IOI 0x40
-#define MSGI 0x20
-#define ATNI 0x10
-#define SELI 0x08
-#define BSYI 0x04
-#define REQI 0x02
-#define ACKI 0x01
-
-/*
- * Possible phases in SCSISIGI
- */
-#define PHASE_MASK 0xe0
-#define P_DATAOUT 0x00
-#define P_DATAIN 0x40
-#define P_COMMAND 0x80
-#define P_MESGOUT 0xa0
-#define P_STATUS 0xc0
-#define P_MESGIN 0xe0
-/*
- * SCSI Contol Signal Write Register (p. 3-16).
- * Writing to this register modifies the control signals on the bus. Only
- * those signals that are allowed in the current mode (Initiator/Target) are
- * asserted.
- */
-#define SCSISIGO 0x003
-#define CDO 0x80
-#define IOO 0x40
-#define MSGO 0x20
-#define ATNO 0x10
-#define SELO 0x08
-#define BSYO 0x04
-#define REQO 0x02
-#define ACKO 0x01
-
-/*
- * SCSI Rate Control (p. 3-17).
- * Contents of this register determine the Synchronous SCSI data transfer
- * rate and the maximum synchronous Req/Ack offset. An offset of 0 in the
- * SOFS (3:0) bits disables synchronous data transfers. Any offset value
- * greater than 0 enables synchronous transfers.
- */
-#define SCSIRATE 0x004
-#define WIDEXFER 0x80 /* Wide transfer control */
-#define SXFR 0x70 /* Sync transfer rate */
-#define SOFS 0x0f /* Sync offset */
-
-/*
- * SCSI ID (p. 3-18).
- * Contains the ID of the board and the current target on the
- * selected channel.
- */
-#define SCSIID 0x005
-#define TID 0xf0 /* Target ID mask */
-#define OID 0x0f /* Our ID mask */
-
-/*
- * SCSI Latched Data (p. 3-19).
- * Read/Write latchs used to transfer data on the SCSI bus during
- * Automatic or Manual PIO mode. SCSIDATH can be used for the
- * upper byte of a 16bit wide asyncronouse data phase transfer.
- */
-#define SCSIDATL 0x006
-#define SCSIDATH 0x007
-
-/*
- * SCSI Transfer Count (pp. 3-19,20)
- * These registers count down the number of bytes transfered
- * across the SCSI bus. The counter is decremented only once
- * the data has been safely transfered. SDONE in SSTAT0 is
- * set when STCNT goes to 0
- */
-#define STCNT 0x008
-#define STCNT0 0x008
-#define STCNT1 0x009
-#define STCNT2 0x00a
-
-/*
- * Clear SCSI Interrupt 0 (p. 3-20)
- * Writing a 1 to a bit clears the associated SCSI Interrupt in SSTAT0.
- */
-#define CLRSINT0 0x00b
-#define CLRSELDO 0x40
-#define CLRSELDI 0x20
-#define CLRSELINGO 0x10
-#define CLRSWRAP 0x08
-/* UNUSED 0x04 */
-#define CLRSPIORDY 0x02
-/* UNUSED 0x01 */
-
-/*
- * SCSI Status 0 (p. 3-21)
- * Contains one set of SCSI Interrupt codes
- * These are most likely of interest to the sequencer
- */
-#define SSTAT0 0x00b
-#define TARGET 0x80 /* Board acting as target */
-#define SELDO 0x40 /* Selection Done */
-#define SELDI 0x20 /* Board has been selected */
-#define SELINGO 0x10 /* Selection In Progress */
-#define SWRAP 0x08 /* 24bit counter wrap */
-#define SDONE 0x04 /* STCNT = 0x000000 */
-#define SPIORDY 0x02 /* SCSI PIO Ready */
-#define DMADONE 0x01 /* DMA transfer completed */
-
-/*
- * Clear SCSI Interrupt 1 (p. 3-23)
- * Writing a 1 to a bit clears the associated SCSI Interrupt in SSTAT1.
- */
-#define CLRSINT1 0x00c
-#define CLRSELTIMEO 0x80
-#define CLRATNO 0x40
-#define CLRSCSIRSTI 0x20
-/* UNUSED 0x10 */
-#define CLRBUSFREE 0x08
-#define CLRSCSIPERR 0x04
-#define CLRPHASECHG 0x02
-#define CLRREQINIT 0x01
-
-/*
- * SCSI Status 1 (p. 3-24)
- */
-#define SSTAT1 0x00c
-#define SELTO 0x80
-#define ATNTARG 0x40
-#define SCSIRSTI 0x20
-#define PHASEMIS 0x10
-#define BUSFREE 0x08
-#define SCSIPERR 0x04
-#define PHASECHG 0x02
-#define REQINIT 0x01
-
-/*
- * SCSI Interrupt Mode 1 (pp. 3-28,29)
- * Setting any bit will enable the corresponding function
- * in SIMODE1 to interrupt via the IRQ pin.
- */
-#define SIMODE1 0x011
-#define ENSELTIMO 0x80
-#define ENATNTARG 0x40
-#define ENSCSIRST 0x20
-#define ENPHASEMIS 0x10
-#define ENBUSFREE 0x08
-#define ENSCSIPERR 0x04
-#define ENPHASECHG 0x02
-#define ENREQINIT 0x01
-
-/*
- * SCSI Data Bus (High) (p. 3-29)
- * This register reads data on the SCSI Data bus directly.
- */
-#define SCSIBUSL 0x012
-#define SCSIBUSH 0x013
-
-/*
- * SCSI/Host Address (p. 3-30)
- * These registers hold the host address for the byte about to be
- * transfered on the SCSI bus. They are counted up in the same
- * manner as STCNT is counted down. SHADDR should always be used
- * to determine the address of the last byte transfered since HADDR
- * can be squewed by write ahead.
- */
-#define SHADDR 0x014
-#define SHADDR0 0x014
-#define SHADDR1 0x015
-#define SHADDR2 0x016
-#define SHADDR3 0x017
-
-/*
- * Selection/Reselection ID (p. 3-31)
- * Upper four bits are the device id. The ONEBIT is set when the re/selecting
- * device did not set its own ID.
- */
-#define SELID 0x019
-#define SELID_MASK 0xf0
-#define ONEBIT 0x08
-/* UNUSED 0x07 */
-
-/*
- * SCSI Block Control (p. 3-32)
- * Controls Bus type and channel selection. In a twin channel configuration
- * addresses 0x00-0x1e are gated to the appropriate channel based on this
- * register. SELWIDE allows for the coexistence of 8bit and 16bit devices
- * on a wide bus.
- */
-#define SBLKCTL 0x01f
-#define DIAGLEDEN 0x80 /* Aic78X0 only */
-#define DIAGLEDON 0x40 /* Aic78X0 only */
-#define AUTOFLUSHDIS 0x20
-/* UNUSED 0x10 */
-#define SELBUS_MASK 0x0a
-#define SELBUSB 0x08
-/* UNUSED 0x04 */
-#define SELWIDE 0x02
-/* UNUSED 0x01 */
-#define SELNARROW 0x00
-
-/*
- * Sequencer Control (p. 3-33)
- * Error detection mode and speed configuration
- */
-#define SEQCTL 0x060
-#define PERRORDIS 0x80
-#define PAUSEDIS 0x40
-#define FAILDIS 0x20
-#define FASTMODE 0x10
-#define BRKADRINTEN 0x08
-#define STEP 0x04
-#define SEQRESET 0x02
-#define LOADRAM 0x01
-
-/*
- * Sequencer RAM Data (p. 3-34)
- * Single byte window into the Scratch Ram area starting at the address
- * specified by SEQADDR0 and SEQADDR1. To write a full word, simply write
- * four bytes in sucessesion. The SEQADDRs will increment after the most
- * significant byte is written
- */
-#define SEQRAM 0x061
-
-/*
- * Sequencer Address Registers (p. 3-35)
- * Only the first bit of SEQADDR1 holds addressing information
- */
-#define SEQADDR0 0x062
-#define SEQADDR1 0x063
-#define SEQADDR1_MASK 0x01
-
-/*
- * Accumulator
- * We cheat by passing arguments in the Accumulator up to the kernel driver
- */
-#define ACCUM 0x064
-
-#define SINDEX 0x065
-#define DINDEX 0x066
-#define ALLZEROS 0x06a
-#define NONE 0x06a
-#define SINDIR 0x06c
-#define DINDIR 0x06d
-#define FUNCTION1 0x06e
-
-/*
- * Host Address (p. 3-48)
- * This register contains the address of the byte about
- * to be transfered across the host bus.
- */
-#define HADDR 0x088
-#define HADDR0 0x088
-#define HADDR1 0x089
-#define HADDR2 0x08a
-#define HADDR3 0x08b
-
-#define HCNT 0x08c
-#define HCNT0 0x08c
-#define HCNT1 0x08d
-#define HCNT2 0x08e
-
-/*
- * SCB Pointer (p. 3-49)
- * Gate one of the four SCBs into the SCBARRAY window.
- */
-#define SCBPTR 0x090
-
-/*
- * Board Control (p. 3-43)
- */
-#define BCTL 0x084
-/* RSVD 0xf0 */
-#define ACE 0x08 /* Support for external processors */
-/* RSVD 0x06 */
-#define ENABLE 0x01
-
-/*
- * On the aic78X0 chips, Board Control is replaced by the DSCommand
- * register (p. 4-64)
- */
-#define DSCOMMAND 0x084
-#define CACHETHEN 0x80 /* Cache Threshold enable */
-#define DPARCKEN 0x40 /* Data Parity Check Enable */
-#define MPARCKEN 0x20 /* Memory Parity Check Enable */
-#define EXTREQLCK 0x10 /* External Request Lock */
-
-/*
- * Bus On/Off Time (p. 3-44)
- */
-#define BUSTIME 0x085
-#define BOFF 0xf0
-#define BON 0x0f
-#define BOFF_60BCLKS 0xf0
-
-/*
- * Bus Speed (p. 3-45)
- */
-#define BUSSPD 0x086
-#define DFTHRSH 0xc0
-#define STBOFF 0x38
-#define STBON 0x07
-#define DFTHRSH_100 0xc0
-
-/*
- * Host Control (p. 3-47) R/W
- * Overal host control of the device.
- */
-#define HCNTRL 0x087
-/* UNUSED 0x80 */
-#define POWRDN 0x40
-/* UNUSED 0x20 */
-#define SWINT 0x10
-#define IRQMS 0x08
-#define PAUSE 0x04
-#define INTEN 0x02
-#define CHIPRST 0x01
-
-/*
- * Interrupt Status (p. 3-50)
- * Status for system interrupts
- */
-#define INTSTAT 0x091
-#define SEQINT_MASK 0xf1 /* SEQINT Status Codes */
-#define BAD_PHASE 0x01 /* unknown scsi bus phase */
-#define SEND_REJECT 0x11 /* sending a message reject */
-#define NO_IDENT 0x21 /* no IDENTIFY after reconnect*/
-#define NO_MATCH 0x31 /* no cmd match for reconnect */
-#define SDTR_MSG 0x41 /* SDTR message recieved */
-#define WDTR_MSG 0x51 /* WDTR message recieved */
-#define REJECT_MSG 0x61 /* Reject message recieved */
-#define BAD_STATUS 0x71 /* Bad status from target */
-#define RESIDUAL 0x81 /* Residual byte count != 0 */
-#define ABORT_TAG 0x91 /* Sent an ABORT_TAG message */
-#define AWAITING_MSG 0xa1 /*
- * Kernel requested to specify
- * a message to this target
- * (command was null), so tell
- * it that it can fill the
- * message buffer.
- */
-#define IMMEDDONE 0xb1 /*
- * An immediate command has
- * completed
- */
-#define MSG_BUFFER_BUSY 0xc1 /*
- * Sequencer wants to use the
- * message buffer, but it
- * already contains a message
- */
-#define MSGIN_PHASEMIS 0xd1 /*
- * Target changed phase on us
- * when we were expecting
- * another msgin byte.
- */
-#define PARITY_ERROR 0xe1 /*
- * Sequencer detected a parity
- * error.
- */
-#define BRKADRINT 0x08
-#define SCSIINT 0x04
-#define CMDCMPLT 0x02
-#define SEQINT 0x01
-#define INT_PEND (BRKADRINT | SEQINT | SCSIINT | CMDCMPLT)
-
-/*
- * Hard Error (p. 3-53)
- * Reporting of catastrophic errors. You usually cannot recover from
- * these without a full board reset.
- */
-#define ERROR 0x092
-/* UNUSED 0xf0 */
-#define PARERR 0x08
-#define ILLOPCODE 0x04
-#define ILLSADDR 0x02
-#define ILLHADDR 0x01
-
-/*
- * Clear Interrupt Status (p. 3-52)
- */
-#define CLRINT 0x092
-#define CLRBRKADRINT 0x08
-#define CLRSCSIINT 0x04
-#define CLRCMDINT 0x02
-#define CLRSEQINT 0x01
-
-#define DFCNTRL 0x093
-#define WIDEODD 0x40
-#define SCSIEN 0x20
-#define SDMAEN 0x10
-#define SDMAENACK 0x10
-#define HDMAEN 0x08
-#define HDMAENACK 0x08
-#define DIRECTION 0x04
-#define FIFOFLUSH 0x02
-#define FIFORESET 0x01
-
-#define DFSTATUS 0x094
-#define HDONE 0x08
-#define FIFOEMP 0x01
-
-#define DFDAT 0x099
-
-/*
- * SCB Auto Increment (p. 3-59)
- * Byte offset into the SCB Array and an optional bit to allow auto
- * incrementing of the address during download and upload operations
- */
-#define SCBCNT 0x09a
-#define SCBAUTO 0x80
-#define SCBCNT_MASK 0x1f
-
-/*
- * Queue In FIFO (p. 3-60)
- * Input queue for queued SCBs (commands that the seqencer has yet to start)
- */
-#define QINFIFO 0x09b
-
-/*
- * Queue In Count (p. 3-60)
- * Number of queued SCBs
- */
-#define QINCNT 0x09c
-
-/*
- * Queue Out FIFO (p. 3-61)
- * Queue of SCBs that have completed and await the host
- */
-#define QOUTFIFO 0x09d
-
-/*
- * Queue Out Count (p. 3-61)
- * Number of queued SCBs in the Out FIFO
- */
-#define QOUTCNT 0x09e
-
-/*
- * SCB Definition (p. 5-4)
- * The two reserved bytes at SCBARRAY+1[23] are expected to be set to
- * zero. Bit 3 in SCBARRAY+0 is used as an internal flag to indicate
- * whether or not to DMA an SCB from host ram. This flag prevents the
- * "re-fetching" of transactions that are requed because the target is
- * busy with another command. We also use bits 6 & 7 to indicate whether
- * or not to initiate SDTR or WDTR repectively when starting this command.
- */
-#define SCBARRAY 0x0a0
-#define SCB_CONTROL 0x0a0
-#define NEEDWDTR 0x80
-#define DISCENB 0x40
-#define TAG_ENB 0x20
-#define NEEDSDTR 0x10
-#define DISCONNECTED 0x04
-#define SCB_TAG_TYPE 0x03
-#define SCB_TCL 0x0a1
-#define SCB_TARGET_STATUS 0x0a2
-#define SCB_SGCOUNT 0x0a3
-#define SCB_SGPTR 0x0a4
-#define SCB_SGPTR0 0x0a4
-#define SCB_SGPTR1 0x0a5
-#define SCB_SGPTR2 0x0a6
-#define SCB_SGPTR3 0x0a7
-#define SCB_RESID_SGCNT 0x0a8
-#define SCB_RESID_DCNT 0x0a9
-#define SCB_RESID_DCNT0 0x0a9
-#define SCB_RESID_DCNT1 0x0aa
-#define SCB_RESID_DCNT2 0x0ab
-#define SCB_DATAPTR 0x0ac
-#define SCB_DATAPTR0 0x0ac
-#define SCB_DATAPTR1 0x0ad
-#define SCB_DATAPTR2 0x0ae
-#define SCB_DATAPTR3 0x0af
-#define SCB_DATACNT 0x0b0
-#define SCB_DATACNT0 0x0b0
-#define SCB_DATACNT1 0x0b1
-#define SCB_DATACNT2 0x0b2
-/* UNUSED - QUAD PADDING 0x0b3 */
-#define SCB_CMDPTR 0x0b4
-#define SCB_CMDPTR0 0x0b4
-#define SCB_CMDPTR1 0x0b5
-#define SCB_CMDPTR2 0x0b6
-#define SCB_CMDPTR3 0x0b7
-#define SCB_CMDLEN 0x0b8
-#define SCB_NEXT_WAITING 0x0b9
-
-#ifdef linux
-#define SG_SIZEOF 0x0c /* sizeof(struct scatterlist) */
-#else
-#define SG_SIZEOF 0x08 /* sizeof(struct ahc_dma) */
-#endif
-
-/* --------------------- AHA-2840-only definitions -------------------- */
-
-#define SEECTL_2840 0x0c0
-/* UNUSED 0xf8 */
-#define CS_2840 0x04
-#define CK_2840 0x02
-#define DO_2840 0x01
-
-#define STATUS_2840 0x0c1
-#define EEPROM_TF 0x80
-#define BIOS_SEL 0x60
-#define ADSEL 0x1e
-#define DI_2840 0x01
-
-/* --------------------- AIC-7870-only definitions -------------------- */
-
-#define DSPCISTATUS 0x086
-
-/*
- * Serial EEPROM Control (p. 4-92 in 7870 Databook)
- * Controls the reading and writing of an external serial 1-bit
- * EEPROM Device. In order to access the serial EEPROM, you must
- * first set the SEEMS bit that generates a request to the memory
- * port for access to the serial EEPROM device. When the memory
- * port is not busy servicing another request, it reconfigures
- * to allow access to the serial EEPROM. When this happens, SEERDY
- * gets set high to verify that the memory port access has been
- * granted.
- *
- * After successful arbitration for the memory port, the SEECS bit of
- * the SEECTL register is connected to the chip select. The SEECK,
- * SEEDO, and SEEDI are connected to the clock, data out, and data in
- * lines respectively. The SEERDY bit of SEECTL is useful in that it
- * gives us an 800 nsec timer. After a write to the SEECTL register,
- * the SEERDY goes high 800 nsec later. The one exception to this is
- * when we first request access to the memory port. The SEERDY goes
- * high to signify that access has been granted and, for this case, has
- * no implied timing.
- *
- * See 93cx6.c for detailed information on the protocol necessary to
- * read the serial EEPROM.
- */
-#define SEECTL 0x01e
-#define EXTARBACK 0x80
-#define EXTARBREQ 0x40
-#define SEEMS 0x20
-#define SEERDY 0x10
-#define SEECS 0x08
-#define SEECK 0x04
-#define SEEDO 0x02
-#define SEEDI 0x01
-
-/* ---------------------- Scratch RAM Offsets ------------------------- */
-/* These offsets are either to values that are initialized by the board's
- * BIOS or are specified by the sequencer code.
- *
- * The host adapter card (at least the BIOS) uses 20-2f for SCSI
- * device information, 32-33 and 5a-5f as well. As it turns out, the
- * BIOS trashes 20-2f, writing the synchronous negotiation results
- * on top of the BIOS values, so we re-use those for our per-target
- * scratchspace (actually a value that can be copied directly into
- * SCSIRATE). The kernel driver will enable synchronous negotiation
- * for all targets that have a value other than 0 in the lower four
- * bits of the target scratch space. This should work regardless of
- * whether the bios has been installed.
- */
-
-/*
- * 1 byte per target starting at this address for configuration values
- */
-#define TARG_SCRATCH 0x020
-
-/*
- * The sequencer will stick the frist byte of any rejected message here so
- * we can see what is getting thrown away.
- */
-#define REJBYTE 0x031
-
-/*
- * Bit vector of targets that have disconnection disabled.
- */
-#define DISC_DSB 0x032
-#define DISC_DSB_A 0x032
-#define DISC_DSB_B 0x033
-
-/*
- * Length of pending message
- */
-#define MSG_LEN 0x034
-
-#define MSG0 0x035
-#define COMP_MSG0 0xcb /* 2's complement of MSG0 */
-#define MSG1 0x036
-#define MSG2 0x037
-#define MSG3 0x038
-#define MSG4 0x039
-#define MSG5 0x03a
-
-/*
- * These are offsets into the card's scratch ram. Some of the values are
- * specified in the AHA2742 technical reference manual and are initialized
- * by the BIOS at boot time.
- */
-#define LASTPHASE 0x049
-#define ARG_1 0x04a
-#define RETURN_1 0x04a
-#define SEND_SENSE 0x80
-#define SEND_WDTR 0x80
-#define SEND_SDTR 0x80
-#define SEND_REJ 0x40
-
-#define SIGSTATE 0x04b
-
-#define DMAPARAMS 0x04c /* Parameters for DMA Logic */
-
-#define SG_COUNT 0x04d
-#define SG_NEXT 0x04e /* working value of SG pointer */
-#define SG_NEXT0 0x04e
-#define SG_NEXT1 0x04f
-#define SG_NEXT2 0x050
-#define SG_NEXT3 0x051
-
-#define SCBCOUNT 0x052 /*
- * Number of SCBs supported by
- * this card.
- */
-#define FLAGS 0x053
-#define SINGLE_BUS 0x00
-#define TWIN_BUS 0x01
-#define WIDE_BUS 0x02
-#define DPHASE 0x04
-#define MAXOFFSET 0x08
-#define IDENTIFY_SEEN 0x40
-#define RESELECTED 0x80
-
-#define ACTIVE_A 0x054
-#define ACTIVE_B 0x055
-#define SAVED_TCL 0x056 /*
- * Temporary storage for the
- * target/channel/lun of a
- * reconnecting target
- */
-#define WAITING_SCBH 0x057 /*
- * head of list of SCBs awaiting
- * selection
- */
-#define WAITING_SCBT 0x058 /*
- * tail of list of SCBs awaiting
- * selection
- */
-#define COMP_SCBCOUNT 0x059
-#define SCB_LIST_NULL 0xff
-
-#define SCSICONF 0x05a
-#define HOSTCONF 0x05d
-
-#define HA_274_BIOSCTRL 0x05f
-#define BIOSMODE 0x30
-#define BIOSDISABLED 0x30
-
-/* Message codes */
-#define MSG_EXTENDED 0x01
-#define MSG_SDTR 0x01
-#define MSG_WDTR 0x03
-#define MSG_SDPTRS 0x02
-#define MSG_RDPTRS 0x03
-#define MSG_DISCONNECT 0x04
-#define MSG_INITIATOR_DET_ERROR 0x05
-#define MSG_ABORT 0x06
-#define MSG_REJECT 0x07
-#define MSG_NOP 0x08
-#define MSG_MSG_PARITY_ERROR 0x09
-#define MSG_BUS_DEVICE_RESET 0x0c
-#define MSG_SIMPLE_TAG 0x20
-#define MSG_IDENTIFY 0x80
-
-/* WDTR Message values */
-#define BUS_8_BIT 0x00
-#define BUS_16_BIT 0x01
-#define BUS_32_BIT 0x02
-
-#define MAX_OFFSET_8BIT 0x0f
-#define MAX_OFFSET_16BIT 0x08
-
diff --git a/i386/i386at/gpl/linux/scsi/aic7xxx_seq.h b/i386/i386at/gpl/linux/scsi/aic7xxx_seq.h
deleted file mode 100644
index d08f7d81..00000000
--- a/i386/i386at/gpl/linux/scsi/aic7xxx_seq.h
+++ /dev/null
@@ -1,374 +0,0 @@
-#define AIC7XXX_SEQ_VER "$Id: aic7xxx_seq.h,v 1.1.1.1 1997/02/25 21:27:47 thomas Exp $"
- 0x10, 0x6a, 0x00, 0x00,
- 0x01, 0x53, 0x05, 0x1e,
- 0x08, 0x1f, 0x1f, 0x04,
- 0x20, 0x0b, 0x32, 0x1a,
- 0x08, 0x1f, 0x1f, 0x04,
- 0x20, 0x0b, 0x32, 0x1a,
- 0xff, 0x57, 0x12, 0x18,
- 0xff, 0x9c, 0x01, 0x1e,
- 0xff, 0x9b, 0x90, 0x02,
- 0xff, 0xa1, 0x6e, 0x02,
- 0xff, 0x6e, 0x64, 0x02,
- 0x88, 0xa1, 0x14, 0x1e,
- 0x00, 0x55, 0x10, 0x1a,
- 0x20, 0xa0, 0x17, 0x1a,
- 0x00, 0x55, 0x55, 0x00,
- 0x00, 0x65, 0x17, 0x10,
- 0xff, 0x90, 0x9b, 0x02,
- 0x00, 0x65, 0x01, 0x10,
- 0xff, 0x57, 0x90, 0x02,
- 0x00, 0x65, 0x19, 0x10,
- 0x00, 0x54, 0x10, 0x1a,
- 0x20, 0xa0, 0x17, 0x1a,
- 0x00, 0x54, 0x54, 0x00,
- 0xff, 0x57, 0xb9, 0x02,
- 0xff, 0x90, 0x57, 0x02,
- 0xf7, 0x1f, 0x65, 0x02,
- 0x08, 0xa1, 0x64, 0x02,
- 0x00, 0x65, 0x65, 0x00,
- 0xff, 0x65, 0x1f, 0x02,
- 0x00, 0xa1, 0x1f, 0x17,
- 0x58, 0x6a, 0x00, 0x00,
- 0xff, 0xb8, 0x22, 0x1a,
- 0xa1, 0x6a, 0x91, 0x00,
- 0x00, 0x65, 0x30, 0x10,
- 0x40, 0xa0, 0x64, 0x02,
- 0x07, 0xa1, 0x35, 0x02,
- 0x00, 0x35, 0x35, 0x00,
- 0x80, 0x35, 0x35, 0x00,
- 0x01, 0x6a, 0x34, 0x00,
- 0xb0, 0xa0, 0x30, 0x1e,
- 0x36, 0x6a, 0x66, 0x00,
- 0x20, 0xa0, 0x2e, 0x1e,
- 0x23, 0xa0, 0x64, 0x02,
- 0xff, 0x64, 0x6d, 0x02,
- 0xff, 0x90, 0x6d, 0x02,
- 0xcb, 0x66, 0x34, 0x06,
- 0x90, 0xa0, 0x30, 0x1e,
- 0x00, 0x66, 0x51, 0x17,
- 0x40, 0x0b, 0x37, 0x1a,
- 0x20, 0x0b, 0x30, 0x1e,
- 0xff, 0x6a, 0x34, 0x02,
- 0x00, 0x19, 0x1f, 0x17,
- 0x03, 0x53, 0x53, 0x02,
- 0x80, 0x53, 0x53, 0x00,
- 0x00, 0x65, 0x39, 0x10,
- 0x03, 0x53, 0x53, 0x02,
- 0xff, 0xb9, 0x57, 0x02,
- 0x02, 0x01, 0x01, 0x00,
- 0x00, 0x65, 0x4d, 0x17,
- 0xff, 0x6c, 0x04, 0x02,
- 0x02, 0x6a, 0x00, 0x00,
- 0x08, 0x6a, 0x0c, 0x00,
- 0x60, 0x6a, 0x0b, 0x00,
- 0x08, 0x0c, 0x04, 0x1b,
- 0x01, 0x0c, 0x3f, 0x1e,
- 0x04, 0x0c, 0x44, 0x1e,
- 0x04, 0x0c, 0x0c, 0x00,
- 0xe1, 0x6a, 0x91, 0x00,
- 0xe0, 0x03, 0x64, 0x02,
- 0xff, 0x64, 0x49, 0x02,
- 0xff, 0x64, 0x03, 0x02,
- 0x00, 0x6a, 0x4e, 0x1c,
- 0x40, 0x64, 0x54, 0x1c,
- 0x80, 0x64, 0x81, 0x1c,
- 0xa0, 0x64, 0x90, 0x1c,
- 0xc0, 0x64, 0x8e, 0x1c,
- 0xe0, 0x64, 0xa4, 0x1c,
- 0x01, 0x6a, 0x91, 0x00,
- 0x7d, 0x6a, 0x4c, 0x00,
- 0x00, 0x65, 0x55, 0x10,
- 0xff, 0xa9, 0x08, 0x02,
- 0xff, 0xaa, 0x09, 0x02,
- 0xff, 0xab, 0x0a, 0x02,
- 0x00, 0x65, 0x59, 0x10,
- 0x79, 0x6a, 0x4c, 0x00,
- 0x00, 0x65, 0x23, 0x17,
- 0x04, 0x53, 0x50, 0x1a,
- 0x00, 0x65, 0x31, 0x17,
- 0x04, 0x53, 0x53, 0x00,
- 0x01, 0x4d, 0x5b, 0x18,
- 0xbf, 0x4c, 0x4c, 0x02,
- 0x00, 0x4c, 0x17, 0x17,
- 0x04, 0x0b, 0x7c, 0x1e,
- 0xff, 0x4d, 0x4d, 0x06,
- 0xff, 0x4d, 0x7c, 0x1e,
- 0xff, 0x6a, 0x64, 0x02,
- 0x0c, 0x4e, 0x4e, 0x06,
- 0x00, 0x4f, 0x4f, 0x08,
- 0xff, 0x6a, 0x8e, 0x02,
- 0xff, 0x6a, 0x8d, 0x02,
- 0x0c, 0x6a, 0x8c, 0x00,
- 0xff, 0x4e, 0x88, 0x02,
- 0xff, 0x4f, 0x89, 0x02,
- 0xff, 0x50, 0x8a, 0x02,
- 0xff, 0x51, 0x8b, 0x02,
- 0x0d, 0x93, 0x93, 0x00,
- 0x08, 0x94, 0x6a, 0x1e,
- 0x40, 0x93, 0x93, 0x02,
- 0x08, 0x93, 0x6c, 0x1a,
- 0xff, 0x99, 0x88, 0x02,
- 0xff, 0x99, 0x89, 0x02,
- 0xff, 0x99, 0x8a, 0x02,
- 0xff, 0x99, 0x8b, 0x02,
- 0xff, 0x99, 0x6a, 0x02,
- 0xff, 0x99, 0x6a, 0x02,
- 0xff, 0x99, 0x6a, 0x02,
- 0xff, 0x99, 0x6a, 0x02,
- 0xff, 0x99, 0x8c, 0x02,
- 0xff, 0x99, 0x8d, 0x02,
- 0xff, 0x99, 0x8e, 0x02,
- 0xff, 0x8c, 0x08, 0x02,
- 0xff, 0x8d, 0x09, 0x02,
- 0xff, 0x8e, 0x0a, 0x02,
- 0x10, 0x0c, 0x59, 0x1e,
- 0xff, 0x08, 0xa9, 0x02,
- 0xff, 0x09, 0xaa, 0x02,
- 0xff, 0x0a, 0xab, 0x02,
- 0xff, 0x4d, 0xa8, 0x02,
- 0x00, 0x65, 0x3f, 0x10,
- 0x00, 0x65, 0x23, 0x17,
- 0xff, 0xb4, 0x88, 0x02,
- 0xff, 0xb5, 0x89, 0x02,
- 0xff, 0xb6, 0x8a, 0x02,
- 0xff, 0xb7, 0x8b, 0x02,
- 0xff, 0xb8, 0x8c, 0x02,
- 0xff, 0x6a, 0x8d, 0x02,
- 0xff, 0x6a, 0x8e, 0x02,
- 0xff, 0x8c, 0x08, 0x02,
- 0xff, 0x8d, 0x09, 0x02,
- 0xff, 0x8e, 0x0a, 0x02,
- 0x3d, 0x6a, 0x17, 0x17,
- 0x00, 0x65, 0x3f, 0x10,
- 0xa2, 0x6a, 0x12, 0x17,
- 0x00, 0x65, 0xb0, 0x10,
- 0xff, 0x34, 0x92, 0x1a,
- 0x08, 0x6a, 0x07, 0x17,
- 0x35, 0x6a, 0x65, 0x00,
- 0xff, 0x34, 0x66, 0x02,
- 0x10, 0x0c, 0xa1, 0x1a,
- 0x02, 0x0b, 0x94, 0x1e,
- 0x01, 0x66, 0x98, 0x18,
- 0x40, 0x6a, 0x0c, 0x00,
- 0xff, 0x66, 0x66, 0x06,
- 0x02, 0x0b, 0x0b, 0x00,
- 0xff, 0x6c, 0x06, 0x02,
- 0xff, 0x66, 0x94, 0x1a,
- 0x08, 0x0c, 0xa2, 0x1a,
- 0x01, 0x0c, 0x9c, 0x1e,
- 0x10, 0x0c, 0xa2, 0x1a,
- 0x10, 0x03, 0x03, 0x00,
- 0x00, 0x65, 0x3f, 0x10,
- 0x40, 0x6a, 0x0c, 0x00,
- 0xff, 0x6a, 0x34, 0x02,
- 0x00, 0x65, 0x3f, 0x10,
- 0x64, 0x6a, 0x12, 0x17,
- 0xff, 0x64, 0x31, 0x02,
- 0x80, 0x64, 0xe4, 0x1a,
- 0x04, 0x64, 0xde, 0x1c,
- 0x02, 0x64, 0xe0, 0x1c,
- 0x00, 0x6a, 0xb2, 0x1c,
- 0x03, 0x64, 0xe2, 0x1c,
- 0x01, 0x64, 0xc5, 0x1c,
- 0x07, 0x64, 0x02, 0x1d,
- 0x10, 0x03, 0x03, 0x00,
- 0x11, 0x6a, 0x91, 0x00,
- 0x07, 0x6a, 0x07, 0x17,
- 0x00, 0x65, 0x14, 0x17,
- 0x00, 0x65, 0x3f, 0x10,
- 0xff, 0xa8, 0xb4, 0x1e,
- 0x81, 0x6a, 0x91, 0x00,
- 0xff, 0xa2, 0xb8, 0x1e,
- 0x71, 0x6a, 0x91, 0x00,
- 0x80, 0x4a, 0xb8, 0x18,
- 0x00, 0x65, 0xb0, 0x10,
- 0x20, 0xa0, 0xbf, 0x1a,
- 0xff, 0xa1, 0x6e, 0x02,
- 0xff, 0x6e, 0x64, 0x02,
- 0x88, 0xa1, 0xbe, 0x1e,
- 0x00, 0x55, 0x55, 0x04,
- 0x00, 0x65, 0xbf, 0x10,
- 0x00, 0x54, 0x54, 0x04,
- 0xff, 0xb8, 0xc2, 0x1a,
- 0xb1, 0x6a, 0x91, 0x00,
- 0x00, 0x65, 0x00, 0x10,
- 0xff, 0x90, 0x9d, 0x02,
- 0x02, 0x6a, 0x91, 0x00,
- 0x00, 0x65, 0xb0, 0x10,
- 0x4a, 0x6a, 0x0e, 0x17,
- 0x64, 0x6a, 0x0e, 0x17,
- 0x01, 0x64, 0xd4, 0x1c,
- 0x03, 0x64, 0xca, 0x1c,
- 0x00, 0x65, 0xad, 0x10,
- 0x02, 0x4a, 0xad, 0x18,
- 0x4a, 0x6a, 0x0e, 0x17,
- 0x51, 0x6a, 0x91, 0x00,
- 0xff, 0x4a, 0xb0, 0x1e,
- 0x40, 0x4a, 0xad, 0x1c,
- 0x7f, 0x4a, 0x4a, 0x02,
- 0x35, 0x6a, 0x66, 0x00,
- 0x35, 0x6a, 0x62, 0x17,
- 0x10, 0x03, 0x03, 0x00,
- 0x00, 0x65, 0xb0, 0x10,
- 0x03, 0x4a, 0xad, 0x18,
- 0x4a, 0x6a, 0x0e, 0x17,
- 0x64, 0x6a, 0x0e, 0x17,
- 0x41, 0x6a, 0x91, 0x00,
- 0xff, 0x4a, 0xb0, 0x1e,
- 0x40, 0x4a, 0xad, 0x1c,
- 0x35, 0x6a, 0x66, 0x00,
- 0x35, 0x6a, 0x53, 0x17,
- 0x10, 0x03, 0x03, 0x00,
- 0x00, 0x65, 0xb0, 0x10,
- 0x04, 0xa0, 0xa0, 0x00,
- 0x00, 0x65, 0xb0, 0x10,
- 0x00, 0x65, 0x40, 0x17,
- 0x00, 0x65, 0xb0, 0x10,
- 0xfb, 0x53, 0x53, 0x02,
- 0x00, 0x65, 0xb0, 0x10,
- 0x78, 0x64, 0xad, 0x1a,
- 0x07, 0x64, 0x64, 0x02,
- 0x00, 0x19, 0x56, 0x00,
- 0xf7, 0x56, 0x56, 0x02,
- 0x08, 0x1f, 0x64, 0x02,
- 0x00, 0x56, 0x56, 0x00,
- 0x00, 0x65, 0x14, 0x17,
- 0x08, 0x0c, 0xf0, 0x1a,
- 0x01, 0x0c, 0xeb, 0x1e,
- 0x10, 0x0c, 0xf0, 0x1a,
- 0x64, 0x6a, 0x12, 0x17,
- 0x20, 0x64, 0xf4, 0x1c,
- 0x00, 0x6a, 0x26, 0x17,
- 0xfb, 0xa0, 0xa0, 0x02,
- 0x40, 0x53, 0x53, 0x00,
- 0x00, 0x65, 0x3f, 0x10,
- 0x4a, 0x6a, 0x0e, 0x17,
- 0xff, 0x59, 0x64, 0x02,
- 0x00, 0x4a, 0x65, 0x06,
- 0x00, 0x65, 0xfe, 0x12,
- 0xff, 0x4a, 0x90, 0x02,
- 0xff, 0x56, 0x64, 0x02,
- 0x00, 0xa1, 0xfe, 0x18,
- 0x20, 0xa0, 0xfe, 0x1e,
- 0x00, 0x65, 0x14, 0x17,
- 0x00, 0x65, 0xf1, 0x10,
- 0x10, 0x03, 0x03, 0x00,
- 0x91, 0x6a, 0x91, 0x00,
- 0x0d, 0x6a, 0x07, 0x17,
- 0x00, 0x65, 0xb0, 0x10,
- 0x61, 0x6a, 0x91, 0x00,
- 0x00, 0x65, 0xb0, 0x10,
- 0x40, 0x6a, 0x0c, 0x00,
- 0xff, 0xb8, 0xb8, 0x1e,
- 0x00, 0x65, 0x00, 0x10,
- 0x50, 0x6a, 0x60, 0x00,
- 0xff, 0x34, 0x0b, 0x1f,
- 0x10, 0x6a, 0x60, 0x00,
- 0xc1, 0x6a, 0x91, 0x00,
- 0x01, 0x6a, 0x34, 0x00,
- 0xff, 0x65, 0x35, 0x02,
- 0x10, 0x6a, 0x60, 0x01,
- 0x02, 0x0b, 0x0b, 0x00,
- 0xff, 0x06, 0x6a, 0x02,
- 0x10, 0x0c, 0x15, 0x1b,
- 0x02, 0x0b, 0x10, 0x1f,
- 0xff, 0x65, 0x66, 0x02,
- 0xff, 0x12, 0x6d, 0x03,
- 0xff, 0x06, 0x6a, 0x03,
- 0xd1, 0x6a, 0x91, 0x00,
- 0x00, 0x65, 0x3f, 0x10,
- 0xff, 0x65, 0x93, 0x02,
- 0x01, 0x0b, 0x1a, 0x1b,
- 0x10, 0x0c, 0x18, 0x1f,
- 0x04, 0x65, 0x1c, 0x1b,
- 0x01, 0x94, 0x1b, 0x1f,
- 0x40, 0x93, 0x93, 0x02,
- 0x38, 0x93, 0x1d, 0x1b,
- 0xff, 0x6a, 0x6a, 0x03,
- 0xf0, 0x65, 0x65, 0x02,
- 0x0f, 0x05, 0x64, 0x02,
- 0x00, 0x65, 0x65, 0x00,
- 0xff, 0x65, 0x05, 0x03,
- 0x80, 0x53, 0x74, 0x1f,
- 0x40, 0x53, 0x74, 0x1b,
- 0x21, 0x6a, 0x91, 0x01,
- 0xff, 0x56, 0x64, 0x02,
- 0xff, 0x65, 0x90, 0x02,
- 0x00, 0xa1, 0x2b, 0x19,
- 0x04, 0xa0, 0x2b, 0x1f,
- 0xff, 0x6a, 0x6a, 0x03,
- 0x01, 0x65, 0x65, 0x06,
- 0xff, 0x52, 0x64, 0x02,
- 0x00, 0x65, 0x26, 0x19,
- 0x31, 0x6a, 0x91, 0x00,
- 0x06, 0x6a, 0x07, 0x17,
- 0x10, 0x03, 0x03, 0x01,
- 0xff, 0xac, 0x88, 0x02,
- 0xff, 0xad, 0x89, 0x02,
- 0xff, 0xae, 0x8a, 0x02,
- 0xff, 0xaf, 0x8b, 0x02,
- 0xff, 0xb0, 0x8c, 0x02,
- 0xff, 0xb1, 0x8d, 0x02,
- 0xff, 0xb2, 0x8e, 0x02,
- 0xff, 0x8c, 0x08, 0x02,
- 0xff, 0x8d, 0x09, 0x02,
- 0xff, 0x8e, 0x0a, 0x02,
- 0xff, 0xa3, 0x4d, 0x02,
- 0xff, 0xa4, 0x4e, 0x02,
- 0xff, 0xa5, 0x4f, 0x02,
- 0xff, 0xa6, 0x50, 0x02,
- 0xff, 0xa7, 0x51, 0x03,
- 0x04, 0x53, 0x74, 0x1f,
- 0xff, 0x4d, 0xa3, 0x02,
- 0xff, 0x4e, 0xa4, 0x02,
- 0xff, 0x4f, 0xa5, 0x02,
- 0xff, 0x50, 0xa6, 0x02,
- 0xff, 0x51, 0xa7, 0x02,
- 0xff, 0x14, 0xac, 0x02,
- 0xff, 0x15, 0xad, 0x02,
- 0xff, 0x16, 0xae, 0x02,
- 0xff, 0x17, 0xaf, 0x02,
- 0xff, 0xa9, 0xb0, 0x02,
- 0xff, 0xaa, 0xb1, 0x02,
- 0xff, 0xab, 0xb2, 0x03,
- 0x4c, 0x05, 0x64, 0x0a,
- 0x08, 0x1f, 0x50, 0x1f,
- 0x08, 0x64, 0x64, 0x00,
- 0x20, 0x64, 0x65, 0x07,
- 0x80, 0xa0, 0x61, 0x1b,
- 0x08, 0x53, 0x53, 0x00,
- 0x01, 0x6a, 0x6d, 0x00,
- 0x03, 0x6a, 0x6d, 0x00,
- 0x01, 0x6a, 0x6d, 0x00,
- 0x00, 0x65, 0x67, 0x17,
- 0xff, 0x4a, 0x6d, 0x02,
- 0x08, 0x53, 0x5b, 0x1b,
- 0x0f, 0x6c, 0x6d, 0x02,
- 0xcb, 0x66, 0x34, 0x07,
- 0x08, 0x53, 0x53, 0x04,
- 0x80, 0x04, 0x5f, 0x1b,
- 0x0f, 0x6a, 0x6d, 0x00,
- 0x00, 0x65, 0x5a, 0x11,
- 0x08, 0x6a, 0x6d, 0x00,
- 0x00, 0x65, 0x5a, 0x11,
- 0x01, 0x6a, 0x4a, 0x00,
- 0x01, 0x6a, 0x6d, 0x00,
- 0x02, 0x6a, 0x6d, 0x00,
- 0x03, 0x6a, 0x6d, 0x00,
- 0xff, 0x4a, 0x6d, 0x02,
- 0xcb, 0x66, 0x34, 0x07,
- 0x00, 0x65, 0x4d, 0x17,
- 0x4c, 0x6c, 0x64, 0x0a,
- 0xff, 0x65, 0x65, 0x06,
- 0x07, 0x64, 0x64, 0x02,
- 0xff, 0x6a, 0x4a, 0x02,
- 0x0f, 0x64, 0x70, 0x1f,
- 0x19, 0x4a, 0x4a, 0x06,
- 0xff, 0x64, 0x64, 0x06,
- 0x00, 0x65, 0x6c, 0x11,
- 0x2e, 0x4a, 0x4a, 0x0a,
- 0x19, 0x4a, 0x4a, 0x06,
- 0x20, 0x01, 0x74, 0x1f,
- 0x1f, 0x4a, 0x4a, 0x0a,
- 0xff, 0x6a, 0x6a, 0x03,
diff --git a/i386/i386at/gpl/linux/scsi/constants.c b/i386/i386at/gpl/linux/scsi/constants.c
deleted file mode 100644
index 07f071b2..00000000
--- a/i386/i386at/gpl/linux/scsi/constants.c
+++ /dev/null
@@ -1,649 +0,0 @@
-/*
- * ASCII values for a number of symbolic constants, printing functions,
- * etc.
- */
-
-/*
- * Don't import our own symbols, as this would severely mess up our
- * symbol tables.
- */
-#define _SCSI_SYMS_VER_
-#define __NO_VERSION__
-#include <linux/module.h>
-
-#include <linux/config.h>
-#include <linux/blk.h>
-#include <linux/kernel.h>
-#include "scsi.h"
-#include "hosts.h"
-
-#define CONST_COMMAND 0x01
-#define CONST_STATUS 0x02
-#define CONST_SENSE 0x04
-#define CONST_XSENSE 0x08
-#define CONST_CMND 0x10
-#define CONST_MSG 0x20
-#define CONST_HOST 0x40
-#define CONST_DRIVER 0x80
-
-static const char unknown[] = "UNKNOWN";
-
-#ifdef CONFIG_SCSI_CONSTANTS
-#ifdef CONSTANTS
-#undef CONSTANTS
-#endif
-#define CONSTANTS (CONST_COMMAND | CONST_STATUS | CONST_SENSE | CONST_XSENSE \
- | CONST_CMND | CONST_MSG | CONST_HOST | CONST_DRIVER)
-#endif
-
-#if (CONSTANTS & CONST_COMMAND)
-static const char * group_0_commands[] = {
-/* 00-03 */ "Test Unit Ready", "Rezero Unit", unknown, "Request Sense",
-/* 04-07 */ "Format Unit", "Read Block Limits", unknown, "Reasssign Blocks",
-/* 08-0d */ "Read (6)", unknown, "Write (6)", "Seek (6)", unknown, unknown,
-/* 0e-12 */ unknown, "Read Reverse", "Write Filemarks", "Space", "Inquiry",
-/* 13-16 */ unknown, "Recover Buffered Data", "Mode Select", "Reserve",
-/* 17-1b */ "Release", "Copy", "Erase", "Mode Sense", "Start/Stop Unit",
-/* 1c-1d */ "Receive Diagnostic", "Send Diagnostic",
-/* 1e-1f */ "Prevent/Allow Medium Removal", unknown,
-};
-
-
-static const char *group_1_commands[] = {
-/* 20-22 */ unknown, unknown, unknown,
-/* 23-28 */ unknown, unknown, "Read Capacity", unknown, unknown, "Read (10)",
-/* 29-2d */ unknown, "Write (10)", "Seek (10)", unknown, unknown,
-/* 2e-31 */ "Write Verify","Verify", "Search High", "Search Equal",
-/* 32-34 */ "Search Low", "Set Limits", "Prefetch or Read Position",
-/* 35-37 */ "Synchronize Cache","Lock/Unlock Cache", "Read Defect Data",
-/* 38-3c */ "Medium Scan", "Compare","Copy Verify", "Write Buffer", "Read Buffer",
-/* 3d-3f */ "Update Block", "Read Long", "Write Long",
-};
-
-
-static const char *group_2_commands[] = {
-/* 40-41 */ "Change Definition", "Write Same",
-/* 42-48 */ unknown, unknown, unknown, unknown, unknown, unknown, unknown,
-/* 49-4f */ unknown, unknown, unknown, "Log Select", "Log Sense", unknown, unknown,
-/* 50-55 */ unknown, unknown, unknown, unknown, unknown, "Mode Select (10)",
-/* 56-5b */ unknown, unknown, unknown, unknown, "Mode Sense (10)", unknown,
-/* 5c-5f */ unknown, unknown, unknown,
-};
-
-
-
-#define group(opcode) (((opcode) >> 5) & 7)
-
-#define RESERVED_GROUP 0
-#define VENDOR_GROUP 1
-#define NOTEXT_GROUP 2
-
-static const char **commands[] = {
- group_0_commands, group_1_commands, group_2_commands,
- (const char **) RESERVED_GROUP, (const char **) RESERVED_GROUP,
- (const char **) NOTEXT_GROUP, (const char **) VENDOR_GROUP,
- (const char **) VENDOR_GROUP
-};
-
-static const char reserved[] = "RESERVED";
-static const char vendor[] = "VENDOR SPECIFIC";
-
-static void print_opcode(int opcode) {
- const char **table = commands[ group(opcode) ];
- switch ((unsigned long) table) {
- case RESERVED_GROUP:
- printk("%s(0x%02x) ", reserved, opcode);
- break;
- case NOTEXT_GROUP:
- printk("%s(0x%02x) ", unknown, opcode);
- break;
- case VENDOR_GROUP:
- printk("%s(0x%02x) ", vendor, opcode);
- break;
- default:
- printk("%s ",table[opcode & 0x1f]);
- }
-}
-#else /* CONST & CONST_COMMAND */
-static void print_opcode(int opcode) {
- printk("0x%02x ", opcode);
-}
-#endif
-
-void print_command (unsigned char *command) {
- int i,s;
- print_opcode(command[0]);
- for ( i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i)
- printk("%02x ", command[i]);
- printk("\n");
-}
-
-#if (CONSTANTS & CONST_STATUS)
-static const char * statuses[] = {
-/* 0-4 */ "Good", "Check Condition", "Condition Good", unknown, "Busy",
-/* 5-9 */ unknown, unknown, unknown, "Intermediate Good", unknown,
-/* a-d */ "Intermediate Good", unknown, "Reservation Conflict", unknown,
-/* e-f */ unknown, unknown,
-};
-#endif
-
-void print_status (int status) {
- status = (status >> 1) & 0xf;
-#if (CONSTANTS & CONST_STATUS)
- printk("%s ",statuses[status]);
-#else
- printk("0x%0x ", status);
-#endif
-}
-
-#if (CONSTANTS & CONST_XSENSE)
-#define D 0x001 /* DIRECT ACCESS DEVICE (disk) */
-#define T 0x002 /* SEQUENTIAL ACCESS DEVICE (tape) */
-#define L 0x004 /* PRINTER DEVICE */
-#define P 0x008 /* PROCESSOR DEVICE */
-#define W 0x010 /* WRITE ONCE READ MULTIPLE DEVICE */
-#define R 0x020 /* READ ONLY (CD-ROM) DEVICE */
-#define S 0x040 /* SCANNER DEVICE */
-#define O 0x080 /* OPTICAL MEMORY DEVICE */
-#define M 0x100 /* MEDIA CHANGER DEVICE */
-#define C 0x200 /* COMMUNICATION DEVICE */
-
-struct error_info{
- unsigned char code1, code2;
- unsigned short int devices;
- const char * text;
-};
-
-struct error_info2{
- unsigned char code1, code2_min, code2_max;
- unsigned short int devices;
- const char * text;
-};
-
-static struct error_info2 additional2[] =
-{
- {0x40,0x00,0x7f,D,"Ram failure (%x)"},
- {0x40,0x80,0xff,D|T|L|P|W|R|S|O|M|C,"Diagnostic failure on component (%x)"},
- {0x41,0x00,0xff,D,"Data path failure (%x)"},
- {0x42,0x00,0xff,D,"Power-on or self-test failure (%x)"},
- {0, 0, 0, 0, NULL}
-};
-
-static struct error_info additional[] =
-{
- {0x00,0x01,T,"Filemark detected"},
- {0x00,0x02,T|S,"End-of-partition/medium detected"},
- {0x00,0x03,T,"Setmark detected"},
- {0x00,0x04,T|S,"Beginning-of-partition/medium detected"},
- {0x00,0x05,T|S,"End-of-data detected"},
- {0x00,0x06,D|T|L|P|W|R|S|O|M|C,"I/O process terminated"},
- {0x00,0x11,R,"Audio play operation in progress"},
- {0x00,0x12,R,"Audio play operation paused"},
- {0x00,0x13,R,"Audio play operation successfully completed"},
- {0x00,0x14,R,"Audio play operation stopped due to error"},
- {0x00,0x15,R,"No current audio status to return"},
- {0x01,0x00,D|W|O,"No index/sector signal"},
- {0x02,0x00,D|W|R|O|M,"No seek complete"},
- {0x03,0x00,D|T|L|W|S|O,"Peripheral device write fault"},
- {0x03,0x01,T,"No write current"},
- {0x03,0x02,T,"Excessive write errors"},
- {0x04,0x00,D|T|L|P|W|R|S|O|M|C,
- "Logical unit not ready, cause not reportable"},
- {0x04,0x01,D|T|L|P|W|R|S|O|M|C,
- "Logical unit is in process of becoming ready"},
- {0x04,0x02,D|T|L|P|W|R|S|O|M|C,
- "Logical unit not ready, initializing command required"},
- {0x04,0x03,D|T|L|P|W|R|S|O|M|C,
- "Logical unit not ready, manual intervention required"},
- {0x04,0x04,D|T|L|O,"Logical unit not ready, format in progress"},
- {0x05,0x00,D|T|L|W|R|S|O|M|C,"Logical unit does not respond to selection"},
- {0x06,0x00,D|W|R|O|M,"No reference position found"},
- {0x07,0x00,D|T|L|W|R|S|O|M,"Multiple peripheral devices selected"},
- {0x08,0x00,D|T|L|W|R|S|O|M|C,"Logical unit communication failure"},
- {0x08,0x01,D|T|L|W|R|S|O|M|C,"Logical unit communication time-out"},
- {0x08,0x02,D|T|L|W|R|S|O|M|C,"Logical unit communication parity error"},
- {0x09,0x00,D|T|W|R|O,"Track following error"},
- {0x09,0x01,W|R|O,"Tracking servo failure"},
- {0x09,0x02,W|R|O,"Focus servo failure"},
- {0x09,0x03,W|R|O,"Spindle servo failure"},
- {0x0A,0x00,D|T|L|P|W|R|S|O|M|C,"Error log overflow"},
- {0x0C,0x00,T|S,"Write error"},
- {0x0C,0x01,D|W|O,"Write error recovered with auto reallocation"},
- {0x0C,0x02,D|W|O,"Write error - auto reallocation failed"},
- {0x10,0x00,D|W|O,"Id crc or ecc error"},
- {0x11,0x00,D|T|W|R|S|O,"Unrecovered read error"},
- {0x11,0x01,D|T|W|S|O,"Read retries exhausted"},
- {0x11,0x02,D|T|W|S|O,"Error too long to correct"},
- {0x11,0x03,D|T|W|S|O,"Multiple read errors"},
- {0x11,0x04,D|W|O,"Unrecovered read error - auto reallocate failed"},
- {0x11,0x05,W|R|O,"L-ec uncorrectable error"},
- {0x11,0x06,W|R|O,"Circ unrecovered error"},
- {0x11,0x07,W|O,"Data resynchronization error"},
- {0x11,0x08,T,"Incomplete block read"},
- {0x11,0x09,T,"No gap found"},
- {0x11,0x0A,D|T|O,"Miscorrected error"},
- {0x11,0x0B,D|W|O,"Unrecovered read error - recommend reassignment"},
- {0x11,0x0C,D|W|O,"Unrecovered read error - recommend rewrite the data"},
- {0x12,0x00,D|W|O,"Address mark not found for id field"},
- {0x13,0x00,D|W|O,"Address mark not found for data field"},
- {0x14,0x00,D|T|L|W|R|S|O,"Recorded entity not found"},
- {0x14,0x01,D|T|W|R|O,"Record not found"},
- {0x14,0x02,T,"Filemark or setmark not found"},
- {0x14,0x03,T,"End-of-data not found"},
- {0x14,0x04,T,"Block sequence error"},
- {0x15,0x00,D|T|L|W|R|S|O|M,"Random positioning error"},
- {0x15,0x01,D|T|L|W|R|S|O|M,"Mechanical positioning error"},
- {0x15,0x02,D|T|W|R|O,"Positioning error detected by read of medium"},
- {0x16,0x00,D|W|O,"Data synchronization mark error"},
- {0x17,0x00,D|T|W|R|S|O,"Recovered data with no error correction applied"},
- {0x17,0x01,D|T|W|R|S|O,"Recovered data with retries"},
- {0x17,0x02,D|T|W|R|O,"Recovered data with positive head offset"},
- {0x17,0x03,D|T|W|R|O,"Recovered data with negative head offset"},
- {0x17,0x04,W|R|O,"Recovered data with retries and/or circ applied"},
- {0x17,0x05,D|W|R|O,"Recovered data using previous sector id"},
- {0x17,0x06,D|W|O,"Recovered data without ecc - data auto-reallocated"},
- {0x17,0x07,D|W|O,"Recovered data without ecc - recommend reassignment"},
- {0x18,0x00,D|T|W|R|O,"Recovered data with error correction applied"},
- {0x18,0x01,D|W|R|O,"Recovered data with error correction and retries applied"},
- {0x18,0x02,D|W|R|O,"Recovered data - data auto-reallocated"},
- {0x18,0x03,R,"Recovered data with circ"},
- {0x18,0x04,R,"Recovered data with lec"},
- {0x18,0x05,D|W|R|O,"Recovered data - recommend reassignment"},
- {0x19,0x00,D|O,"Defect list error"},
- {0x19,0x01,D|O,"Defect list not available"},
- {0x19,0x02,D|O,"Defect list error in primary list"},
- {0x19,0x03,D|O,"Defect list error in grown list"},
- {0x1A,0x00,D|T|L|P|W|R|S|O|M|C,"Parameter list length error"},
- {0x1B,0x00,D|T|L|P|W|R|S|O|M|C,"Synchronous data transfer error"},
- {0x1C,0x00,D|O,"Defect list not found"},
- {0x1C,0x01,D|O,"Primary defect list not found"},
- {0x1C,0x02,D|O,"Grown defect list not found"},
- {0x1D,0x00,D|W|O,"Miscompare during verify operation"},
- {0x1E,0x00,D|W|O,"Recovered id with ecc correction"},
- {0x20,0x00,D|T|L|P|W|R|S|O|M|C,"Invalid command operation code"},
- {0x21,0x00,D|T|W|R|O|M,"Logical block address out of range"},
- {0x21,0x01,M,"Invalid element address"},
- {0x22,0x00,D,"Illegal function (should use 20 00, 24 00, or 26 00)"},
- {0x24,0x00,D|T|L|P|W|R|S|O|M|C,"Invalid field in cdb"},
- {0x25,0x00,D|T|L|P|W|R|S|O|M|C,"Logical unit not supported"},
- {0x26,0x00,D|T|L|P|W|R|S|O|M|C,"Invalid field in parameter list"},
- {0x26,0x01,D|T|L|P|W|R|S|O|M|C,"Parameter not supported"},
- {0x26,0x02,D|T|L|P|W|R|S|O|M|C,"Parameter value invalid"},
- {0x26,0x03,D|T|L|P|W|R|S|O|M|C,"Threshold parameters not supported"},
- {0x27,0x00,D|T|W|O,"Write protected"},
- {0x28,0x00,D|T|L|P|W|R|S|O|M|C,"Not ready to ready transition (medium may have changed)"},
- {0x28,0x01,M,"Import or export element accessed"},
- {0x29,0x00,D|T|L|P|W|R|S|O|M|C,"Power on, reset, or bus device reset occurred"},
- {0x2A,0x00,D|T|L|W|R|S|O|M|C,"Parameters changed"},
- {0x2A,0x01,D|T|L|W|R|S|O|M|C,"Mode parameters changed"},
- {0x2A,0x02,D|T|L|W|R|S|O|M|C,"Log parameters changed"},
- {0x2B,0x00,D|T|L|P|W|R|S|O|C,"Copy cannot execute since host cannot disconnect"},
- {0x2C,0x00,D|T|L|P|W|R|S|O|M|C,"Command sequence error"},
- {0x2C,0x01,S,"Too many windows specified"},
- {0x2C,0x02,S,"Invalid combination of windows specified"},
- {0x2D,0x00,T,"Overwrite error on update in place"},
- {0x2F,0x00,D|T|L|P|W|R|S|O|M|C,"Commands cleared by another initiator"},
- {0x30,0x00,D|T|W|R|O|M,"Incompatible medium installed"},
- {0x30,0x01,D|T|W|R|O,"Cannot read medium - unknown format"},
- {0x30,0x02,D|T|W|R|O,"Cannot read medium - incompatible format"},
- {0x30,0x03,D|T,"Cleaning cartridge installed"},
- {0x31,0x00,D|T|W|O,"Medium format corrupted"},
- {0x31,0x01,D|L|O,"Format command failed"},
- {0x32,0x00,D|W|O,"No defect spare location available"},
- {0x32,0x01,D|W|O,"Defect list update failure"},
- {0x33,0x00,T,"Tape length error"},
- {0x36,0x00,L,"Ribbon, ink, or toner failure"},
- {0x37,0x00,D|T|L|W|R|S|O|M|C,"Rounded parameter"},
- {0x39,0x00,D|T|L|W|R|S|O|M|C,"Saving parameters not supported"},
- {0x3A,0x00,D|T|L|W|R|S|O|M,"Medium not present"},
- {0x3B,0x00,T|L,"Sequential positioning error"},
- {0x3B,0x01,T,"Tape position error at beginning-of-medium"},
- {0x3B,0x02,T,"Tape position error at end-of-medium"},
- {0x3B,0x03,L,"Tape or electronic vertical forms unit not ready"},
- {0x3B,0x04,L,"Slew failure"},
- {0x3B,0x05,L,"Paper jam"},
- {0x3B,0x06,L,"Failed to sense top-of-form"},
- {0x3B,0x07,L,"Failed to sense bottom-of-form"},
- {0x3B,0x08,T,"Reposition error"},
- {0x3B,0x09,S,"Read past end of medium"},
- {0x3B,0x0A,S,"Read past beginning of medium"},
- {0x3B,0x0B,S,"Position past end of medium"},
- {0x3B,0x0C,S,"Position past beginning of medium"},
- {0x3B,0x0D,M,"Medium destination element full"},
- {0x3B,0x0E,M,"Medium source element empty"},
- {0x3D,0x00,D|T|L|P|W|R|S|O|M|C,"Invalid bits in identify message"},
- {0x3E,0x00,D|T|L|P|W|R|S|O|M|C,"Logical unit has not self-configured yet"},
- {0x3F,0x00,D|T|L|P|W|R|S|O|M|C,"Target operating conditions have changed"},
- {0x3F,0x01,D|T|L|P|W|R|S|O|M|C,"Microcode has been changed"},
- {0x3F,0x02,D|T|L|P|W|R|S|O|M|C,"Changed operating definition"},
- {0x3F,0x03,D|T|L|P|W|R|S|O|M|C,"Inquiry data has changed"},
- {0x43,0x00,D|T|L|P|W|R|S|O|M|C,"Message error"},
- {0x44,0x00,D|T|L|P|W|R|S|O|M|C,"Internal target failure"},
- {0x45,0x00,D|T|L|P|W|R|S|O|M|C,"Select or reselect failure"},
- {0x46,0x00,D|T|L|P|W|R|S|O|M|C,"Unsuccessful soft reset"},
- {0x47,0x00,D|T|L|P|W|R|S|O|M|C,"Scsi parity error"},
- {0x48,0x00,D|T|L|P|W|R|S|O|M|C,"Initiator detected error message received"},
- {0x49,0x00,D|T|L|P|W|R|S|O|M|C,"Invalid message error"},
- {0x4A,0x00,D|T|L|P|W|R|S|O|M|C,"Command phase error"},
- {0x4B,0x00,D|T|L|P|W|R|S|O|M|C,"Data phase error"},
- {0x4C,0x00,D|T|L|P|W|R|S|O|M|C,"Logical unit failed self-configuration"},
- {0x4E,0x00,D|T|L|P|W|R|S|O|M|C,"Overlapped commands attempted"},
- {0x50,0x00,T,"Write append error"},
- {0x50,0x01,T,"Write append position error"},
- {0x50,0x02,T,"Position error related to timing"},
- {0x51,0x00,T|O,"Erase failure"},
- {0x52,0x00,T,"Cartridge fault"},
- {0x53,0x00,D|T|L|W|R|S|O|M,"Media load or eject failed"},
- {0x53,0x01,T,"Unload tape failure"},
- {0x53,0x02,D|T|W|R|O|M,"Medium removal prevented"},
- {0x54,0x00,P,"Scsi to host system interface failure"},
- {0x55,0x00,P,"System resource failure"},
- {0x57,0x00,R,"Unable to recover table-of-contents"},
- {0x58,0x00,O,"Generation does not exist"},
- {0x59,0x00,O,"Updated block read"},
- {0x5A,0x00,D|T|L|P|W|R|S|O|M,"Operator request or state change input (unspecified)"},
- {0x5A,0x01,D|T|W|R|O|M,"Operator medium removal request"},
- {0x5A,0x02,D|T|W|O,"Operator selected write protect"},
- {0x5A,0x03,D|T|W|O,"Operator selected write permit"},
- {0x5B,0x00,D|T|L|P|W|R|S|O|M,"Log exception"},
- {0x5B,0x01,D|T|L|P|W|R|S|O|M,"Threshold condition met"},
- {0x5B,0x02,D|T|L|P|W|R|S|O|M,"Log counter at maximum"},
- {0x5B,0x03,D|T|L|P|W|R|S|O|M,"Log list codes exhausted"},
- {0x5C,0x00,D|O,"Rpl status change"},
- {0x5C,0x01,D|O,"Spindles synchronized"},
- {0x5C,0x02,D|O,"Spindles not synchronized"},
- {0x60,0x00,S,"Lamp failure"},
- {0x61,0x00,S,"Video acquisition error"},
- {0x61,0x01,S,"Unable to acquire video"},
- {0x61,0x02,S,"Out of focus"},
- {0x62,0x00,S,"Scan head positioning error"},
- {0x63,0x00,R,"End of user area encountered on this track"},
- {0x64,0x00,R,"Illegal mode for this track"},
- {0, 0, 0, NULL}
-};
-#endif
-
-#if (CONSTANTS & CONST_SENSE)
-static const char *snstext[] = {
- "None","Recovered Error","Not Ready","Medium Error","Hardware Error",
- "Illegal Request","Unit Attention","Data Protect","Blank Check",
- "Key=9","Copy Aborted","Aborted Command","End-Of-Medium",
- "Volume Overflow", "Miscompare", "Key=15"};
-#endif
-
-
-/* Print sense information */
-void print_sense(const char * devclass, Scsi_Cmnd * SCpnt)
-{
- int i, s;
- int sense_class, valid, code;
- unsigned char * sense_buffer = SCpnt->sense_buffer;
- const char * error = NULL;
-
- sense_class = (sense_buffer[0] >> 4) & 0x07;
- code = sense_buffer[0] & 0xf;
- valid = sense_buffer[0] & 0x80;
-
- if (sense_class == 7) {
- s = sense_buffer[7] + 8;
- if(s > sizeof(SCpnt->sense_buffer)) s = sizeof(SCpnt->sense_buffer);
-
- if (!valid)
- printk("extra data not valid ");
-
- if (sense_buffer[2] & 0x80) printk( "FMK ");
- if (sense_buffer[2] & 0x40) printk( "EOM ");
- if (sense_buffer[2] & 0x20) printk( "ILI ");
-
- switch (code) {
- case 0x0:
- error = "Current";
- break;
- case 0x1:
- error = "Deferred";
- break;
- default:
- error = "Invalid";
- }
-
- printk("%s error ", error);
-
-#if (CONSTANTS & CONST_SENSE)
- printk( "%s%s: sense key %s\n", devclass,
- kdevname(SCpnt->request.rq_dev), snstext[sense_buffer[2] & 0x0f]);
-#else
- printk("%s%s: sns = %2x %2x\n", devclass,
- kdevname(SCpnt->request.rq_dev), sense_buffer[0], sense_buffer[2]);
-#endif
-
- /* Check to see if additional sense information is available */
- if(sense_buffer[7] + 7 < 13 ||
- (sense_buffer[12] == 0 && sense_buffer[13] == 0)) goto done;
-
-#if (CONSTANTS & CONST_XSENSE)
- for(i=0; additional[i].text; i++)
- if(additional[i].code1 == sense_buffer[12] &&
- additional[i].code2 == sense_buffer[13])
- printk("Additional sense indicates %s\n", additional[i].text);
-
- for(i=0; additional2[i].text; i++)
- if(additional2[i].code1 == sense_buffer[12] &&
- additional2[i].code2_min >= sense_buffer[13] &&
- additional2[i].code2_max <= sense_buffer[13]) {
- printk("Additional sense indicates ");
- printk(additional2[i].text, sense_buffer[13]);
- printk("\n");
- };
-#else
- printk("ASC=%2x ASCQ=%2x\n", sense_buffer[12], sense_buffer[13]);
-#endif
- } else {
-
-#if (CONSTANTS & CONST_SENSE)
- if (sense_buffer[0] < 15)
- printk("%s%s: old sense key %s\n", devclass,
- kdevname(SCpnt->request.rq_dev), snstext[sense_buffer[0] & 0x0f]);
- else
-#endif
- printk("%s%s: sns = %2x %2x\n", devclass,
- kdevname(SCpnt->request.rq_dev), sense_buffer[0], sense_buffer[2]);
-
- printk("Non-extended sense class %d code 0x%0x ", sense_class, code);
- s = 4;
- }
-
- done:
-#if !(CONSTANTS & CONST_SENSE)
- printk("Raw sense data:");
- for (i = 0; i < s; ++i)
- printk("0x%02x ", sense_buffer[i]);
- printk("\n");
-#endif
- return;
-}
-
-#if (CONSTANTS & CONST_MSG)
-static const char *one_byte_msgs[] = {
-/* 0x00 */ "Command Complete", NULL, "Save Pointers",
-/* 0x03 */ "Restore Pointers", "Disconnect", "Initiator Error",
-/* 0x06 */ "Abort", "Message Reject", "Nop", "Message Parity Error",
-/* 0x0a */ "Linked Command Complete", "Linked Command Complete w/flag",
-/* 0x0c */ "Bus device reset", "Abort Tag", "Clear Queue",
-/* 0x0f */ "Initiate Recovery", "Release Recovery"
-};
-
-#define NO_ONE_BYTE_MSGS (sizeof(one_byte_msgs) / sizeof (const char *))
-
-static const char *two_byte_msgs[] = {
-/* 0x20 */ "Simple Queue Tag", "Head of Queue Tag", "Ordered Queue Tag"
-/* 0x23 */ "Ignore Wide Residue"
-};
-
-#define NO_TWO_BYTE_MSGS (sizeof(two_byte_msgs) / sizeof (const char *))
-
-static const char *extended_msgs[] = {
-/* 0x00 */ "Modify Data Pointer", "Synchronous Data Transfer Request",
-/* 0x02 */ "SCSI-I Extended Identify", "Wide Data Transfer Request"
-};
-
-#define NO_EXTENDED_MSGS (sizeof(two_byte_msgs) / sizeof (const char *))
-#endif /* (CONSTANTS & CONST_MSG) */
-
-int print_msg (const unsigned char *msg) {
- int len = 0, i;
- if (msg[0] == EXTENDED_MESSAGE) {
- len = 3 + msg[1];
-#if (CONSTANTS & CONST_MSG)
- if (msg[2] < NO_EXTENDED_MSGS)
- printk ("%s ", extended_msgs[msg[2]]);
- else
- printk ("Extended Message, reserved code (0x%02x) ", (int) msg[2]);
- switch (msg[2]) {
- case EXTENDED_MODIFY_DATA_POINTER:
- printk("pointer = %d", (int) (msg[3] << 24) | (msg[4] << 16) |
- (msg[5] << 8) | msg[6]);
- break;
- case EXTENDED_SDTR:
- printk("period = %d ns, offset = %d", (int) msg[3] * 4, (int)
- msg[4]);
- break;
- case EXTENDED_WDTR:
- printk("width = 2^%d bytes", msg[3]);
- break;
- default:
- for (i = 2; i < len; ++i)
- printk("%02x ", msg[i]);
- }
-#else
- for (i = 0; i < len; ++i)
- printk("%02x ", msg[i]);
-#endif
- /* Identify */
- } else if (msg[0] & 0x80) {
-#if (CONSTANTS & CONST_MSG)
- printk("Identify disconnect %sallowed %s %d ",
- (msg[0] & 0x40) ? "" : "not ",
- (msg[0] & 0x20) ? "target routine" : "lun",
- msg[0] & 0x7);
-#else
- printk("%02x ", msg[0]);
-#endif
- len = 1;
- /* Normal One byte */
- } else if (msg[0] < 0x1f) {
-#if (CONSTANTS & CONST_MSG)
- if (msg[0] < NO_ONE_BYTE_MSGS)
- printk(one_byte_msgs[msg[0]]);
- else
- printk("reserved (%02x) ", msg[0]);
-#else
- printk("%02x ", msg[0]);
-#endif
- len = 1;
- /* Two byte */
- } else if (msg[0] <= 0x2f) {
-#if (CONSTANTS & CONST_MSG)
- if ((msg[0] - 0x20) < NO_TWO_BYTE_MSGS)
- printk("%s %02x ", two_byte_msgs[msg[0] - 0x20],
- msg[1]);
- else
- printk("reserved two byte (%02x %02x) ",
- msg[0], msg[1]);
-#else
- printk("%02x %02x", msg[0], msg[1]);
-#endif
- len = 2;
- } else
-#if (CONSTANTS & CONST_MSG)
- printk(reserved);
-#else
- printk("%02x ", msg[0]);
-#endif
- return len;
-}
-
-void print_Scsi_Cmnd (Scsi_Cmnd *cmd) {
- printk("scsi%d : destination target %d, lun %d\n",
- cmd->host->host_no,
- cmd->target,
- cmd->lun);
- printk(" command = ");
- print_command (cmd->cmnd);
-}
-
-#if (CONSTANTS & CONST_HOST)
-static const char * hostbyte_table[]={
-"DID_OK", "DID_NO_CONNECT", "DID_BUS_BUSY", "DID_TIME_OUT", "DID_BAD_TARGET",
-"DID_ABORT", "DID_PARITY", "DID_ERROR", "DID_RESET", "DID_BAD_INTR",NULL};
-
-void print_hostbyte(int scsiresult)
-{ static int maxcode=0;
- int i;
-
- if(!maxcode) {
- for(i=0;hostbyte_table[i];i++) ;
- maxcode=i-1;
- }
- printk("Hostbyte=0x%02x",host_byte(scsiresult));
- if(host_byte(scsiresult)>maxcode) {
- printk("is invalid ");
- return;
- }
- printk("(%s) ",hostbyte_table[host_byte(scsiresult)]);
-}
-#else
-void print_hostbyte(int scsiresult)
-{ printk("Hostbyte=0x%02x ",host_byte(scsiresult));
-}
-#endif
-
-#if (CONSTANTS & CONST_DRIVER)
-static const char * driverbyte_table[]={
-"DRIVER_OK", "DRIVER_BUSY", "DRIVER_SOFT", "DRIVER_MEDIA", "DRIVER_ERROR",
-"DRIVER_INVALID", "DRIVER_TIMEOUT", "DRIVER_HARD",NULL };
-
-static const char * driversuggest_table[]={"SUGGEST_OK",
-"SUGGEST_RETRY", "SUGGEST_ABORT", "SUGGEST_REMAP", "SUGGEST_DIE",
-unknown,unknown,unknown, "SUGGEST_SENSE",NULL};
-
-
-void print_driverbyte(int scsiresult)
-{ static int driver_max=0,suggest_max=0;
- int i,dr=driver_byte(scsiresult)&DRIVER_MASK,
- su=(driver_byte(scsiresult)&SUGGEST_MASK)>>4;
-
- if(!driver_max) {
- for(i=0;driverbyte_table[i];i++) ;
- driver_max=i;
- for(i=0;driversuggest_table[i];i++) ;
- suggest_max=i;
- }
- printk("Driverbyte=0x%02x",driver_byte(scsiresult));
- printk("(%s,%s) ",
- dr<driver_max ? driverbyte_table[dr]:"invalid",
- su<suggest_max ? driversuggest_table[su]:"invalid");
-}
-#else
-void print_driverbyte(int scsiresult)
-{ printk("Driverbyte=0x%02x ",driver_byte(scsiresult));
-}
-#endif
-
-/*
- * Overrides for Emacs so that we almost follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 4
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * c-continued-statement-offset: 4
- * c-continued-brace-offset: 0
- * indent-tabs-mode: nil
- * tab-width: 8
- * End:
- */
diff --git a/i386/i386at/gpl/linux/scsi/constants.h b/i386/i386at/gpl/linux/scsi/constants.h
deleted file mode 100644
index e10527ea..00000000
--- a/i386/i386at/gpl/linux/scsi/constants.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _CONSTANTS_H
-#define _CONSTANTS_H
-extern int print_msg(unsigned char *);
-extern void print_status(int);
-extern void print_Scsi_Cmnd (Scsi_Cmnd *);
-#endif /* def _CONSTANTS_H */
diff --git a/i386/i386at/gpl/linux/scsi/eata.c b/i386/i386at/gpl/linux/scsi/eata.c
deleted file mode 100644
index 29000332..00000000
--- a/i386/i386at/gpl/linux/scsi/eata.c
+++ /dev/null
@@ -1,1099 +0,0 @@
-/*
- * eata.c - Low-level driver for EATA/DMA SCSI host adapters.
- *
- * 6 Jul 1995 rev. 2.01 for linux 1.3.7
- * Update required by the new /proc/scsi support.
- *
- * 11 Mar 1995 rev. 2.00 for linux 1.2.0
- * Fixed a bug which prevented media change detection for removable
- * disk drives.
- *
- * 23 Feb 1995 rev. 1.18 for linux 1.1.94
- * Added a check for scsi_register returning NULL.
- *
- * 11 Feb 1995 rev. 1.17 for linux 1.1.91
- * Now DEBUG_RESET is disabled by default.
- * Register a board even if it does not assert DMA protocol support
- * (DPT SK2011B does not report correctly the dmasup bit).
- *
- * 9 Feb 1995 rev. 1.16 for linux 1.1.90
- * Use host->wish_block instead of host->block.
- * New list of Data Out SCSI commands.
- *
- * 8 Feb 1995 rev. 1.15 for linux 1.1.89
- * Cleared target_time_out counter while performing a reset.
- * All external symbols renamed to avoid possible name conflicts.
- *
- * 28 Jan 1995 rev. 1.14 for linux 1.1.86
- * Added module support.
- * Log and do a retry when a disk drive returns a target status
- * different from zero on a recovered error.
- *
- * 24 Jan 1995 rev. 1.13 for linux 1.1.85
- * Use optimized board configuration, with a measured performance
- * increase in the range 10%-20% on i/o throughput.
- *
- * 16 Jan 1995 rev. 1.12 for linux 1.1.81
- * Fix mscp structure comments (no functional change).
- * Display a message if check_region detects a port address
- * already in use.
- *
- * 17 Dec 1994 rev. 1.11 for linux 1.1.74
- * Use the scsicam_bios_param routine. This allows an easy
- * migration path from disk partition tables created using
- * different SCSI drivers and non optimal disk geometry.
- *
- * 15 Dec 1994 rev. 1.10 for linux 1.1.74
- * Added support for ISA EATA boards (DPT PM2011, DPT PM2021).
- * The host->block flag is set for all the detected ISA boards.
- * The detect routine no longer enforces LEVEL triggering
- * for EISA boards, it just prints a warning message.
- *
- * 30 Nov 1994 rev. 1.09 for linux 1.1.68
- * Redo i/o on target status CHECK_CONDITION for TYPE_DISK only.
- * Added optional support for using a single board at a time.
- *
- * 18 Nov 1994 rev. 1.08 for linux 1.1.64
- * Forces sg_tablesize = 64 and can_queue = 64 if these
- * values are not correctly detected (DPT PM2012).
- *
- * 14 Nov 1994 rev. 1.07 for linux 1.1.63 Final BETA release.
- * 04 Aug 1994 rev. 1.00 for linux 1.1.39 First BETA release.
- *
- *
- * This driver is based on the CAM (Common Access Method Committee)
- * EATA (Enhanced AT Bus Attachment) rev. 2.0A, using DMA protocol.
- *
- * Copyright (C) 1994, 1995 Dario Ballabio (dario@milano.europe.dg.com)
- *
- */
-
-/*
- *
- * Here is a brief description of the DPT SCSI host adapters.
- * All these boards provide an EATA/DMA compatible programming interface
- * and are fully supported by this driver:
- *
- * PM2011B/9X - Entry Level ISA
- * PM2021A/9X - High Performance ISA
- * PM2012A Old EISA
- * PM2012B Old EISA
- * PM2022A/9X - Entry Level EISA
- * PM2122A/9X - High Performance EISA
- * PM2322A/9X - Extra High Performance EISA
- *
- * The DPT PM2001 provides only the EATA/PIO interface and hence is not
- * supported by this driver.
- *
- * This code has been tested with up to 3 Distributed Processing Technology
- * PM2122A/9X (DPT SCSI BIOS v002.D1, firmware v05E.0) eisa controllers,
- * no on board cache and no RAID option.
- * BIOS must be enabled on the first board and must be disabled for all other
- * boards.
- * Support is provided for any number of DPT PM2122 eisa boards.
- * All boards should be configured at the same IRQ level.
- * Multiple IRQ configurations are supported too.
- * Boards can be located in any eisa slot (1-15) and are named EATA0,
- * EATA1,... in increasing eisa slot number. ISA boards are detected
- * after the eisa slot probes.
- *
- * The IRQ for EISA boards should be _level_ triggered (not _edge_ triggered).
- * This is a requirement in order to support multiple boards on the same IRQ.
- *
- * Other eisa configuration parameters are:
- *
- * COMMAND QUEUING : ENABLED
- * COMMAND TIMEOUT : ENABLED
- * CACHE : DISABLED
- *
- * In order to support multiple ISA boards in a reliable way,
- * the driver sets host->wish_block = TRUE for all ISA boards.
- */
-
-#if defined(MODULE)
-#include <linux/module.h>
-#include <linux/version.h>
-#endif
-
-#include <linux/string.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/ioport.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include <linux/proc_fs.h>
-#include <linux/blk.h>
-#include "scsi.h"
-#include "hosts.h"
-#include "sd.h"
-#include <asm/dma.h>
-#include <asm/irq.h>
-#include "linux/in.h"
-#include "eata.h"
-#include<linux/stat.h>
-
-struct proc_dir_entry proc_scsi_eata2x = {
- PROC_SCSI_EATA2X, 6, "eata2x",
- S_IFDIR | S_IRUGO | S_IXUGO, 2
-};
-
-/* Subversion values */
-#define ISA 0
-#define ESA 1
-
-#undef FORCE_CONFIG
-
-#undef DEBUG_DETECT
-#undef DEBUG_INTERRUPT
-#undef DEBUG_STATISTICS
-#undef DEBUG_RESET
-
-#define MAX_TARGET 8
-#define MAX_IRQ 16
-#define MAX_BOARDS 18
-#define MAX_MAILBOXES 64
-#define MAX_SGLIST 64
-#define MAX_CMD_PER_LUN 2
-
-#define FALSE 0
-#define TRUE 1
-#define FREE 0
-#define IN_USE 1
-#define LOCKED 2
-#define IN_RESET 3
-#define IGNORE 4
-#define NO_IRQ 0xff
-#define NO_DMA 0xff
-#define MAXLOOP 200000
-
-#define REG_CMD 7
-#define REG_STATUS 7
-#define REG_AUX_STATUS 8
-#define REG_DATA 0
-#define REG_DATA2 1
-#define REG_SEE 6
-#define REG_LOW 2
-#define REG_LM 3
-#define REG_MID 4
-#define REG_MSB 5
-#define REGION_SIZE 9
-#define EISA_RANGE 0xf000
-#define BSY_ASSERTED 0x80
-#define DRQ_ASSERTED 0x08
-#define ABSY_ASSERTED 0x01
-#define IRQ_ASSERTED 0x02
-#define READ_CONFIG_PIO 0xf0
-#define SET_CONFIG_PIO 0xf1
-#define SEND_CP_PIO 0xf2
-#define RECEIVE_SP_PIO 0xf3
-#define TRUNCATE_XFR_PIO 0xf4
-#define RESET_PIO 0xf9
-#define READ_CONFIG_DMA 0xfd
-#define SET_CONFIG_DMA 0xfe
-#define SEND_CP_DMA 0xff
-#define ASOK 0x00
-#define ASST 0x01
-
-#define ARRAY_SIZE(arr) (sizeof (arr) / sizeof (arr)[0])
-
-/* "EATA", in Big Endian format */
-#define EATA_SIGNATURE 0x41544145
-
-/* Number of valid bytes in the board config structure for EATA 2.0x */
-#define EATA_2_0A_SIZE 28
-#define EATA_2_0B_SIZE 30
-
-/* Board info structure */
-struct eata_info {
- ulong data_len; /* Number of valid bytes after this field */
- ulong sign; /* ASCII "EATA" signature */
- unchar :4, /* unused low nibble */
- version:4; /* EATA version, should be 0x1 */
- unchar ocsena:1, /* Overlap Command Support Enabled */
- tarsup:1, /* Target Mode Supported */
- :2,
- dmasup:1, /* DMA Supported */
- drqvld:1, /* DRQ Index (DRQX) is valid */
- ata:1, /* This is an ATA device */
- haaval:1; /* Host Adapter Address Valid */
- ushort cp_pad_len; /* Number of pad bytes after cp_len */
- unchar host_addr[3]; /* Host Adapter SCSI ID for channels 2, 1, 0 */
- unchar reserved;
- ulong cp_len; /* Number of valid bytes in cp */
- ulong sp_len; /* Number of valid bytes in sp */
- ushort queue_size; /* Max number of cp that can be queued */
- ushort unused;
- ushort scatt_size; /* Max number of entries in scatter/gather table */
- unchar irq:4, /* Interrupt Request assigned to this controller */
- irq_tr:1, /* 0 for edge triggered, 1 for level triggered */
- second:1, /* 1 if this is a secondary (not primary) controller */
- drqx:2; /* DRQ Index (0=DMA0, 1=DMA7, 2=DMA6, 3=DMA5) */
- unchar sync; /* 1 if scsi target id 7...0 is running sync scsi */
-
- /* Structure extension defined in EATA 2.0B */
- unchar isaena:1, /* ISA i/o addressing is disabled/enabled */
- forcaddr:1, /* Port address has been forced */
- :6;
- unchar max_id:5, /* Max number of SCSI target IDs */
- max_chan:3; /* Max SCSI channel number on this board */
-
- ushort ipad[249];
- };
-
-/* Board config structure */
-struct eata_config {
- ushort len; /* Number of bytes following this field */
- unchar edis:1, /* Disable EATA interface after config command */
- ocena:1, /* Overlapped Commands Enabled */
- mdpena:1, /* Transfer all Modified Data Pointer Messages */
- tarena:1, /* Target Mode Enabled for this controller */
- :4;
- unchar cpad[511];
- };
-
-/* Returned status packet structure */
-struct mssp {
- unchar adapter_status:7, /* State related to current command */
- eoc:1; /* End Of Command (1 = command completed) */
- unchar target_status; /* SCSI status received after data transfer */
- unchar unused[2];
- ulong inv_res_len; /* Number of bytes not transferred */
- Scsi_Cmnd *SCpnt; /* Address set in cp */
- char mess[12];
- };
-
-/* MailBox SCSI Command Packet */
-struct mscp {
- unchar sreset:1, /* SCSI Bus Reset Signal should be asserted */
- init:1, /* Re-initialize controller and self test */
- reqsen:1, /* Transfer Request Sense Data to addr using DMA */
- sg:1, /* Use Scatter/Gather */
- :1,
- interp:1, /* The controller interprets cp, not the target */
- dout:1, /* Direction of Transfer is Out (Host to Target) */
- din:1; /* Direction of Transfer is In (Target to Host) */
- unchar sense_len; /* Request Sense Length */
- unchar unused[4];
- unchar phsunit:1, /* Send to Target Physical Unit (bypass RAID) */
- notused:7;
- unchar target; /* SCSI Target ID */
- unchar lun:3, /* LUN */
- :2,
- luntar:1, /* This cp is for Target (not LUN) */
- dispri:1, /* Disconnect Privilege granted */
- one:1; /* 1 */
- unchar mess[3]; /* Massage to/from Target */
- unchar cdb[12]; /* Command Descriptor Block */
- ulong data_len; /* If sg=0 Data Length, if sg=1 sglist length */
- Scsi_Cmnd *SCpnt; /* Address to be returned is sp */
- ulong data_address; /* If sg=0 Data Address, if sg=1 sglist address */
- ulong sp_addr; /* Address where sp is DMA'ed when cp completes */
- ulong sense_addr; /* Address where Sense Data is DMA'ed on error */
-
- struct sg_list {
- unsigned int address; /* Segment Address */
- unsigned int num_bytes; /* Segment Length */
- } sglist[MAX_SGLIST];
-
- unsigned int index; /* cp index */
- };
-
-struct hostdata {
- struct mscp cp[MAX_MAILBOXES]; /* Mailboxes for this board */
- unsigned int cp_stat[MAX_MAILBOXES]; /* FREE, IN_USE, LOCKED, IN_RESET */
- unsigned int last_cp_used; /* Index of last mailbox used */
- unsigned int iocount; /* Total i/o done for this board */
- unsigned int multicount; /* Total ... in second ihdlr loop */
- int board_number; /* Number of this board */
- char board_name[16]; /* Name of this board */
- char board_id[256]; /* data from INQUIRY on this board */
- int in_reset; /* True if board is doing a reset */
- int target_time_out[MAX_TARGET]; /* N. of timeout errors on target */
- int target_reset[MAX_TARGET]; /* If TRUE redo operation on target */
- unsigned char subversion; /* Bus type, either ISA or ESA */
- unsigned char protocol_rev; /* EATA 2.0 rev., 'A' or 'B' or 'C' */
- struct mssp sp[MAX_MAILBOXES]; /* Returned status for this board */
- };
-
-static struct Scsi_Host * sh[MAX_BOARDS + 1];
-static const char* driver_name = "EATA";
-static unsigned int irqlist[MAX_IRQ], calls[MAX_IRQ];
-
-#define HD(board) ((struct hostdata *) &sh[board]->hostdata)
-#define BN(board) (HD(board)->board_name)
-
-static void eata2x_interrupt_handler(int, struct pt_regs *);
-static int do_trace = FALSE;
-
-static inline unchar wait_on_busy(ushort iobase) {
- unsigned int loop = MAXLOOP;
-
- while (inb(iobase + REG_AUX_STATUS) & ABSY_ASSERTED)
- if (--loop == 0) return TRUE;
-
- return FALSE;
-}
-
-static inline unchar do_dma (ushort iobase, unsigned int addr, unchar cmd) {
-
- if (wait_on_busy(iobase)) return TRUE;
-
- if (addr) {
- outb((char) addr, iobase + REG_LOW);
- outb((char) (addr >> 8), iobase + REG_LM);
- outb((char) (addr >> 16), iobase + REG_MID);
- outb((char) (addr >> 24), iobase + REG_MSB);
- }
-
- outb(cmd, iobase + REG_CMD);
- return FALSE;
-}
-
-static inline unchar read_pio (ushort iobase, ushort *start, ushort *end) {
- unsigned int loop = MAXLOOP;
- ushort *p;
-
- for (p = start; p <= end; p++) {
-
- while (!(inb(iobase + REG_STATUS) & DRQ_ASSERTED))
- if (--loop == 0) return TRUE;
-
- loop = MAXLOOP;
- *p = inw(iobase);
- }
-
- return FALSE;
-}
-
-static inline int port_detect(ushort *port_base, unsigned int j,
- Scsi_Host_Template * tpnt) {
- unsigned char irq, dma_channel, subversion;
- unsigned char protocol_rev;
- struct eata_info info;
- const char *board_status;
-
- /* Allowed DMA channels for ISA (0 indicates reserved) */
- unsigned char dma_channel_table[4] = { 5, 6, 7, 0 };
-
- char name[16];
-
- sprintf(name, "%s%d", driver_name, j);
-
- if(check_region(*port_base, REGION_SIZE)) {
- printk("%s: address 0x%03x in use, skipping probe.\n",
- name, *port_base);
- return FALSE;
- }
-
- if (do_dma(*port_base, 0, READ_CONFIG_PIO)) return FALSE;
-
- /* Read the info structure */
- if (read_pio(*port_base, (ushort *)&info, (ushort *)&info.ipad[0]))
- return FALSE;
-
- /* Check the controller "EATA" signature */
- if (info.sign != EATA_SIGNATURE) return FALSE;
-
- if (ntohl(info.data_len) < EATA_2_0A_SIZE) {
- printk("%s: config structure size (%ld bytes) too short, detaching.\n",
- name, ntohl(info.data_len));
- return FALSE;
- }
- else if (ntohl(info.data_len) == EATA_2_0A_SIZE)
- protocol_rev = 'A';
- else if (ntohl(info.data_len) == EATA_2_0B_SIZE)
- protocol_rev = 'B';
- else
- protocol_rev = 'C';
-
- if (protocol_rev != 'A' && info.max_chan > 0)
- printk("%s: warning, only scsi channel 0 is supported.\n", name);
-
- irq = info.irq;
-
- if (*port_base & EISA_RANGE) {
-
- if (!info.haaval || info.ata || info.drqvld) {
- printk("%s: unusable EISA board found (%d%d%d), detaching.\n",
- name, info.haaval, info.ata, info.drqvld);
- return FALSE;
- }
-
- subversion = ESA;
- dma_channel = NO_DMA;
- }
- else {
-
- if (!info.haaval || info.ata || !info.drqvld) {
- printk("%s: unusable ISA board found (%d%d%d), detaching.\n",
- name, info.haaval, info.ata, info.drqvld);
- return FALSE;
- }
-
- subversion = ISA;
- dma_channel = dma_channel_table[3 - info.drqx];
- }
-
- if (!info.dmasup)
- printk("%s: warning, DMA protocol support not asserted.\n", name);
-
- if (subversion == ESA && !info.irq_tr)
- printk("%s: warning, LEVEL triggering is suggested for IRQ %u.\n",
- name, irq);
-
- if (info.second)
- board_status = "Sec.";
- else
- board_status = "Prim.";
-
- /* Board detected, allocate its IRQ if not already done */
- if ((irq >= MAX_IRQ) || ((irqlist[irq] == NO_IRQ) && request_irq
- (irq, eata2x_interrupt_handler, SA_INTERRUPT, driver_name))) {
- printk("%s: unable to allocate IRQ %u, detaching.\n", name, irq);
- return FALSE;
- }
-
- if (subversion == ISA && request_dma(dma_channel, driver_name)) {
- printk("%s: unable to allocate DMA channel %u, detaching.\n",
- name, dma_channel);
- free_irq(irq);
- return FALSE;
- }
-
-#if defined (FORCE_CONFIG)
- {
- struct eata_config config;
-
- /* Set board configuration */
- memset((char *)&config, 0, sizeof(struct eata_config));
- config.len = (ushort) htons((ushort)510);
- config.ocena = TRUE;
-
- if (do_dma(*port_base, (unsigned int)&config, SET_CONFIG_DMA)) {
- printk("%s: busy timeout sending configuration, detaching.\n", name);
- return FALSE;
- }
- }
-#endif
-
- sh[j] = scsi_register(tpnt, sizeof(struct hostdata));
-
- if (sh[j] == NULL) {
- printk("%s: unable to register host, detaching.\n", name);
-
- if (irqlist[irq] == NO_IRQ) free_irq(irq);
-
- if (subversion == ISA) free_dma(dma_channel);
-
- return FALSE;
- }
-
- sh[j]->io_port = *port_base;
- sh[j]->n_io_port = REGION_SIZE;
- sh[j]->dma_channel = dma_channel;
- sh[j]->irq = irq;
- sh[j]->sg_tablesize = (ushort) ntohs(info.scatt_size);
- sh[j]->this_id = (ushort) info.host_addr[3];
- sh[j]->can_queue = (ushort) ntohs(info.queue_size);
- sh[j]->cmd_per_lun = MAX_CMD_PER_LUN;
-
- /* Register the I/O space that we use */
- request_region(sh[j]->io_port, REGION_SIZE, driver_name);
-
- memset(HD(j), 0, sizeof(struct hostdata));
- HD(j)->subversion = subversion;
- HD(j)->protocol_rev = protocol_rev;
- HD(j)->board_number = j;
- irqlist[irq] = j;
-
- if (HD(j)->subversion == ESA)
- sh[j]->unchecked_isa_dma = FALSE;
- else {
- sh[j]->wish_block = TRUE;
- sh[j]->unchecked_isa_dma = TRUE;
- disable_dma(dma_channel);
- clear_dma_ff(dma_channel);
- set_dma_mode(dma_channel, DMA_MODE_CASCADE);
- enable_dma(dma_channel);
- }
-
- strcpy(BN(j), name);
-
- printk("%s: 2.0%c, %s, ID %d, PORT 0x%03x, IRQ %u, DMA %u, SG %d, "\
- "Mbox %d, CmdLun %d.\n", BN(j), HD(j)->protocol_rev, board_status,
- sh[j]->this_id, sh[j]->io_port, sh[j]->irq, sh[j]->dma_channel,
- sh[j]->sg_tablesize, sh[j]->can_queue, sh[j]->cmd_per_lun);
-
- /* DPT PM2012 does not allow to detect sg_tablesize correctly */
- if (sh[j]->sg_tablesize > MAX_SGLIST || sh[j]->sg_tablesize < 2) {
- printk("%s: detect, forcing to use %d SG lists.\n", BN(j), MAX_SGLIST);
- sh[j]->sg_tablesize = MAX_SGLIST;
- }
-
- /* DPT PM2012 does not allow to detect can_queue correctly */
- if (sh[j]->can_queue > MAX_MAILBOXES || sh[j]->can_queue < 2) {
- printk("%s: detect, forcing to use %d Mbox.\n", BN(j), MAX_MAILBOXES);
- sh[j]->can_queue = MAX_MAILBOXES;
- }
-
-#if defined (DEBUG_DETECT)
- if (protocol_rev != 'A')
- printk("%s: EATA 2.0%c, isaena %u, forcaddr %u, max_id %u,"\
- " max_chan %u.\n", name, protocol_rev, info.isaena,
- info.forcaddr, info.max_id, info.max_chan);
-
- printk("%s: Version 0x%x, SYNC 0x%x, infol %ld, cpl %ld spl %ld.\n",
- name, info.version, info.sync, ntohl(info.data_len),
- ntohl(info.cp_len), ntohl(info.sp_len));
-#endif
-
- return TRUE;
-}
-
-int eata2x_detect (Scsi_Host_Template * tpnt) {
- unsigned int j = 0, k, flags;
-
- ushort io_port[] = {
- 0x1c88, 0x2c88, 0x3c88, 0x4c88, 0x5c88, 0x6c88, 0x7c88, 0x8c88,
- 0x9c88, 0xac88, 0xbc88, 0xcc88, 0xdc88, 0xec88, 0xfc88,
- 0x1f0, 0x170, 0x330, 0x230, 0x0
- };
-
- ushort *port_base = io_port;
-
- tpnt->proc_dir = &proc_scsi_eata2x;
-
- save_flags(flags);
- cli();
-
- for (k = 0; k < MAX_IRQ; k++) {
- irqlist[k] = NO_IRQ;
- calls[k] = 0;
- }
-
- for (k = 0; k < MAX_BOARDS + 1; k++) sh[k] = NULL;
-
- while (*port_base) {
-
- if (j < MAX_BOARDS && port_detect(port_base, j, tpnt)) j++;
-
- port_base++;
- }
-
- if (j > 0)
- printk("EATA/DMA 2.0x: Copyright (C) 1994, 1995 Dario Ballabio.\n");
-
- restore_flags(flags);
- return j;
-}
-
-static inline void build_sg_list(struct mscp *cpp, Scsi_Cmnd *SCpnt) {
- unsigned int k;
- struct scatterlist * sgpnt;
-
- sgpnt = (struct scatterlist *) SCpnt->request_buffer;
-
- for (k = 0; k < SCpnt->use_sg; k++) {
- cpp->sglist[k].address = htonl((unsigned int) sgpnt[k].address);
- cpp->sglist[k].num_bytes = htonl((unsigned int) sgpnt[k].length);
- }
-
- cpp->data_address = htonl((unsigned int) cpp->sglist);
- cpp->data_len = htonl((SCpnt->use_sg * sizeof(struct sg_list)));
-}
-
-int eata2x_queuecommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
- unsigned int i, j, k, flags;
- struct mscp *cpp;
- struct mssp *spp;
-
- static const unsigned char data_out_cmds[] = {
- 0x0a, 0x2a, 0x15, 0x55, 0x04, 0x07, 0x0b, 0x10, 0x16, 0x18, 0x1d,
- 0x24, 0x2b, 0x2e, 0x30, 0x31, 0x32, 0x38, 0x39, 0x3a, 0x3b, 0x3d,
- 0x3f, 0x40, 0x41, 0x4c, 0xaa, 0xae, 0xb0, 0xb1, 0xb2, 0xb6, 0xea
- };
-
- save_flags(flags);
- cli();
- /* j is the board number */
- j = ((struct hostdata *) SCpnt->host->hostdata)->board_number;
-
- if (!done) panic("%s: qcomm, pid %ld, null done.\n", BN(j), SCpnt->pid);
-
- /* i is the mailbox number, look for the first free mailbox
- starting from last_cp_used */
- i = HD(j)->last_cp_used + 1;
-
- for (k = 0; k < sh[j]->can_queue; k++, i++) {
-
- if (i >= sh[j]->can_queue) i = 0;
-
- if (HD(j)->cp_stat[i] == FREE) {
- HD(j)->last_cp_used = i;
- break;
- }
- }
-
- if (k == sh[j]->can_queue) {
- printk("%s: qcomm, no free mailbox, resetting.\n", BN(j));
-
- if (HD(j)->in_reset)
- printk("%s: qcomm, already in reset.\n", BN(j));
- else if (eata2x_reset(SCpnt) == SCSI_RESET_SUCCESS)
- panic("%s: qcomm, SCSI_RESET_SUCCESS.\n", BN(j));
-
- SCpnt->result = DID_BUS_BUSY << 16;
- SCpnt->host_scribble = NULL;
- printk("%s: qcomm, pid %ld, DID_BUS_BUSY, done.\n", BN(j), SCpnt->pid);
- restore_flags(flags);
- done(SCpnt);
- return 0;
- }
-
- /* Set pointer to control packet structure */
- cpp = &HD(j)->cp[i];
-
- memset(cpp, 0, sizeof(struct mscp));
-
- /* Set pointer to status packet structure */
- spp = &HD(j)->sp[i];
-
- memset(spp, 0, sizeof(struct mssp));
-
- /* The EATA protocol uses Big Endian format, while Intel is Little Endian */
- cpp->sp_addr = htonl((unsigned int) spp);
-
- SCpnt->scsi_done = done;
- cpp->index = i;
- SCpnt->host_scribble = (unsigned char *) &cpp->index;
-
- if (do_trace) printk("%s: qcomm, mbox %d, target %d, pid %ld.\n",
- BN(j), i, SCpnt->target, SCpnt->pid);
-
- for (k = 0; k < ARRAY_SIZE(data_out_cmds); k++)
- if (SCpnt->cmnd[0] == data_out_cmds[k]) {
- cpp->dout = TRUE;
- break;
- }
-
- cpp->din = !cpp->dout;
- cpp->reqsen = TRUE;
- cpp->dispri = TRUE;
- cpp->one = TRUE;
- cpp->target = SCpnt->target;
- cpp->lun = SCpnt->lun;
- cpp->SCpnt = SCpnt;
- cpp->sense_addr = htonl((unsigned int) SCpnt->sense_buffer);
- cpp->sense_len = sizeof SCpnt->sense_buffer;
-
- if (SCpnt->use_sg) {
- cpp->sg = TRUE;
- build_sg_list(cpp, SCpnt);
- }
- else {
- cpp->data_address = htonl((unsigned int) SCpnt->request_buffer);
- cpp->data_len = htonl(SCpnt->request_bufflen);
- }
-
- memcpy(cpp->cdb, SCpnt->cmnd, SCpnt->cmd_len);
-
- /* Send control packet to the board */
- if (do_dma(sh[j]->io_port, (unsigned int) cpp, SEND_CP_DMA)) {
- SCpnt->result = DID_ERROR << 16;
- SCpnt->host_scribble = NULL;
- printk("%s: qcomm, target %d, pid %ld, adapter busy, DID_ERROR, done.\n",
- BN(j), SCpnt->target, SCpnt->pid);
- restore_flags(flags);
- done(SCpnt);
- return 0;
- }
-
- HD(j)->cp_stat[i] = IN_USE;
- restore_flags(flags);
- return 0;
-}
-
-int eata2x_abort (Scsi_Cmnd *SCarg) {
- unsigned int i, j, flags;
-
- save_flags(flags);
- cli();
- j = ((struct hostdata *) SCarg->host->hostdata)->board_number;
-
- if (SCarg->host_scribble == NULL) {
- printk("%s: abort, target %d, pid %ld inactive.\n",
- BN(j), SCarg->target, SCarg->pid);
- restore_flags(flags);
- return SCSI_ABORT_NOT_RUNNING;
- }
-
- i = *(unsigned int *)SCarg->host_scribble;
- printk("%s: abort, mbox %d, target %d, pid %ld.\n",
- BN(j), i, SCarg->target, SCarg->pid);
-
- if (i >= sh[j]->can_queue)
- panic("%s: abort, invalid SCarg->host_scribble.\n", BN(j));
-
- if (wait_on_busy(sh[j]->io_port)) {
- printk("%s: abort, timeout error.\n", BN(j));
- restore_flags(flags);
- return SCSI_ABORT_ERROR;
- }
-
- if (HD(j)->cp_stat[i] == FREE) {
- printk("%s: abort, mbox %d is free.\n", BN(j), i);
- restore_flags(flags);
- return SCSI_ABORT_NOT_RUNNING;
- }
-
- if (HD(j)->cp_stat[i] == IN_USE) {
- printk("%s: abort, mbox %d is in use.\n", BN(j), i);
-
- if (SCarg != HD(j)->cp[i].SCpnt)
- panic("%s: abort, mbox %d, SCarg %p, cp SCpnt %p.\n",
- BN(j), i, SCarg, HD(j)->cp[i].SCpnt);
-
- restore_flags(flags);
- return SCSI_ABORT_SNOOZE;
- }
-
- if (HD(j)->cp_stat[i] == IN_RESET) {
- printk("%s: abort, mbox %d is in reset.\n", BN(j), i);
- restore_flags(flags);
- return SCSI_ABORT_ERROR;
- }
-
- if (HD(j)->cp_stat[i] == LOCKED) {
- printk("%s: abort, mbox %d is locked.\n", BN(j), i);
- restore_flags(flags);
- return SCSI_ABORT_NOT_RUNNING;
- }
- restore_flags(flags);
- panic("%s: abort, mbox %d, invalid cp_stat.\n", BN(j), i);
-}
-
-int eata2x_reset (Scsi_Cmnd *SCarg) {
- unsigned int i, j, flags, time, k, limit = 0;
- int arg_done = FALSE;
- Scsi_Cmnd *SCpnt;
-
- save_flags(flags);
- cli();
- j = ((struct hostdata *) SCarg->host->hostdata)->board_number;
- printk("%s: reset, enter, target %d, pid %ld.\n",
- BN(j), SCarg->target, SCarg->pid);
-
- if (SCarg->host_scribble == NULL)
- printk("%s: reset, pid %ld inactive.\n", BN(j), SCarg->pid);
-
- if (HD(j)->in_reset) {
- printk("%s: reset, exit, already in reset.\n", BN(j));
- restore_flags(flags);
- return SCSI_RESET_ERROR;
- }
-
- if (wait_on_busy(sh[j]->io_port)) {
- printk("%s: reset, exit, timeout error.\n", BN(j));
- restore_flags(flags);
- return SCSI_RESET_ERROR;
- }
-
- for (k = 0; k < MAX_TARGET; k++) HD(j)->target_reset[k] = TRUE;
-
- for (k = 0; k < MAX_TARGET; k++) HD(j)->target_time_out[k] = 0;
-
- for (i = 0; i < sh[j]->can_queue; i++) {
-
- if (HD(j)->cp_stat[i] == FREE) continue;
-
- if (HD(j)->cp_stat[i] == LOCKED) {
- HD(j)->cp_stat[i] = FREE;
- printk("%s: reset, locked mbox %d forced free.\n", BN(j), i);
- continue;
- }
-
- SCpnt = HD(j)->cp[i].SCpnt;
- HD(j)->cp_stat[i] = IN_RESET;
- printk("%s: reset, mbox %d in reset, pid %ld.\n",
- BN(j), i, SCpnt->pid);
-
- if (SCpnt == NULL)
- panic("%s: reset, mbox %d, SCpnt == NULL.\n", BN(j), i);
-
- if (SCpnt->host_scribble == NULL)
- panic("%s: reset, mbox %d, garbled SCpnt.\n", BN(j), i);
-
- if (*(unsigned int *)SCpnt->host_scribble != i)
- panic("%s: reset, mbox %d, index mismatch.\n", BN(j), i);
-
- if (SCpnt->scsi_done == NULL)
- panic("%s: reset, mbox %d, SCpnt->scsi_done == NULL.\n", BN(j), i);
-
- if (SCpnt == SCarg) arg_done = TRUE;
- }
-
- if (do_dma(sh[j]->io_port, 0, RESET_PIO)) {
- printk("%s: reset, cannot reset, timeout error.\n", BN(j));
- restore_flags(flags);
- return SCSI_RESET_ERROR;
- }
-
- printk("%s: reset, board reset done, enabling interrupts.\n", BN(j));
-
-#if defined (DEBUG_RESET)
- do_trace = TRUE;
-#endif
-
- HD(j)->in_reset = TRUE;
- sti();
- time = jiffies;
- while (jiffies < (time + 100) && limit++ < 100000000);
- cli();
- printk("%s: reset, interrupts disabled, loops %d.\n", BN(j), limit);
-
- for (i = 0; i < sh[j]->can_queue; i++) {
-
- /* Skip mailboxes already set free by interrupt */
- if (HD(j)->cp_stat[i] != IN_RESET) continue;
-
- SCpnt = HD(j)->cp[i].SCpnt;
- SCpnt->result = DID_RESET << 16;
- SCpnt->host_scribble = NULL;
-
- /* This mailbox is still waiting for its interrupt */
- HD(j)->cp_stat[i] = LOCKED;
-
- printk("%s, reset, mbox %d locked, DID_RESET, pid %ld done.\n",
- BN(j), i, SCpnt->pid);
- restore_flags(flags);
- SCpnt->scsi_done(SCpnt);
- cli();
- }
-
- HD(j)->in_reset = FALSE;
- do_trace = FALSE;
- restore_flags(flags);
-
- if (arg_done) {
- printk("%s: reset, exit, success.\n", BN(j));
- return SCSI_RESET_SUCCESS;
- }
- else {
- printk("%s: reset, exit, wakeup.\n", BN(j));
- return SCSI_RESET_PUNT;
- }
-}
-
-static void eata2x_interrupt_handler(int irq, struct pt_regs * regs) {
- Scsi_Cmnd *SCpnt;
- unsigned int i, j, k, flags, status, tstatus, loops, total_loops = 0;
- struct mssp *spp;
- struct mscp *cpp;
-
- save_flags(flags);
- cli();
-
- if (irqlist[irq] == NO_IRQ) {
- printk("%s, ihdlr, irq %d, unexpected interrupt.\n", driver_name, irq);
- restore_flags(flags);
- return;
- }
-
- if (do_trace) printk("%s: ihdlr, enter, irq %d, calls %d.\n",
- driver_name, irq, calls[irq]);
-
- /* Service all the boards configured on this irq */
- for (j = 0; sh[j] != NULL; j++) {
-
- if (sh[j]->irq != irq) continue;
-
- loops = 0;
-
- /* Loop until all interrupts for a board are serviced */
- while (inb(sh[j]->io_port + REG_AUX_STATUS) & IRQ_ASSERTED) {
- total_loops++;
- loops++;
-
- if (do_trace) printk("%s: ihdlr, start service, count %d.\n",
- BN(j), HD(j)->iocount);
-
- /* Read the status register to clear the interrupt indication */
- inb(sh[j]->io_port + REG_STATUS);
-
- /* Service all mailboxes of this board */
- for (i = 0; i < sh[j]->can_queue; i++) {
- spp = &HD(j)->sp[i];
-
- /* Check if this mailbox has completed the operation */
- if (spp->eoc == FALSE) continue;
-
- spp->eoc = FALSE;
-
- if (HD(j)->cp_stat[i] == IGNORE) {
- HD(j)->cp_stat[i] = FREE;
- continue;
- }
- else if (HD(j)->cp_stat[i] == LOCKED) {
- HD(j)->cp_stat[i] = FREE;
- printk("%s: ihdlr, mbox %d unlocked, count %d.\n",
- BN(j), i, HD(j)->iocount);
- continue;
- }
- else if (HD(j)->cp_stat[i] == FREE) {
- printk("%s: ihdlr, mbox %d is free, count %d.\n",
- BN(j), i, HD(j)->iocount);
- continue;
- }
- else if (HD(j)->cp_stat[i] == IN_RESET)
- printk("%s: ihdlr, mbox %d is in reset.\n", BN(j), i);
- else if (HD(j)->cp_stat[i] != IN_USE)
- panic("%s: ihdlr, mbox %d, invalid cp_stat.\n", BN(j), i);
-
- HD(j)->cp_stat[i] = FREE;
- cpp = &HD(j)->cp[i];
- SCpnt = spp->SCpnt;
-
- if (SCpnt == NULL)
- panic("%s: ihdlr, mbox %d, SCpnt == NULL.\n", BN(j), i);
-
- if (SCpnt != cpp->SCpnt)
- panic("%s: ihdlr, mbox %d, sp SCpnt %p, cp SCpnt %p.\n",
- BN(j), i, SCpnt, cpp->SCpnt);
-
- if (SCpnt->host_scribble == NULL)
- panic("%s: ihdlr, mbox %d, pid %ld, SCpnt %p garbled.\n",
- BN(j), i, SCpnt->pid, SCpnt);
-
- if (*(unsigned int *)SCpnt->host_scribble != i)
- panic("%s: ihdlr, mbox %d, pid %ld, index mismatch %d,"\
- " irq %d.\n", BN(j), i, SCpnt->pid,
- *(unsigned int *)SCpnt->host_scribble, irq);
-
- tstatus = status_byte(spp->target_status);
-
- switch (spp->adapter_status) {
- case ASOK: /* status OK */
-
- /* Forces a reset if a disk drive keeps returning BUSY */
- if (tstatus == BUSY && SCpnt->device->type != TYPE_TAPE)
- status = DID_ERROR << 16;
-
- /* If there was a bus reset, redo operation on each target */
- else if (tstatus != GOOD
- && SCpnt->device->type == TYPE_DISK
- && HD(j)->target_reset[SCpnt->target])
- status = DID_BUS_BUSY << 16;
-
- /* Works around a flaw in scsi.c */
- else if (tstatus == CHECK_CONDITION
- && SCpnt->device->type == TYPE_DISK
- && (SCpnt->sense_buffer[2] & 0xf) == RECOVERED_ERROR)
- status = DID_BUS_BUSY << 16;
-
- else
- status = DID_OK << 16;
-
- if (tstatus == GOOD)
- HD(j)->target_reset[SCpnt->target] = FALSE;
-
- if (spp->target_status && SCpnt->device->type == TYPE_DISK)
- printk("%s: ihdlr, target %d:%d, pid %ld, target_status "\
- "0x%x, sense key 0x%x.\n", BN(j),
- SCpnt->target, SCpnt->lun, SCpnt->pid,
- spp->target_status, SCpnt->sense_buffer[2]);
-
- HD(j)->target_time_out[SCpnt->target] = 0;
-
- break;
- case ASST: /* Selection Time Out */
- case 0x02: /* Command Time Out */
-
- if (HD(j)->target_time_out[SCpnt->target] > 1)
- status = DID_ERROR << 16;
- else {
- status = DID_TIME_OUT << 16;
- HD(j)->target_time_out[SCpnt->target]++;
- }
-
- break;
- case 0x03: /* SCSI Bus Reset Received */
- case 0x04: /* Initial Controller Power-up */
-
- if (SCpnt->device->type != TYPE_TAPE)
- status = DID_BUS_BUSY << 16;
- else
- status = DID_ERROR << 16;
-
- for (k = 0; k < MAX_TARGET; k++)
- HD(j)->target_reset[k] = TRUE;
-
- break;
- case 0x07: /* Bus Parity Error */
- case 0x0c: /* Controller Ram Parity */
- case 0x05: /* Unexpected Bus Phase */
- case 0x06: /* Unexpected Bus Free */
- case 0x08: /* SCSI Hung */
- case 0x09: /* Unexpected Message Reject */
- case 0x0a: /* SCSI Bus Reset Stuck */
- case 0x0b: /* Auto Request-Sense Failed */
- default:
- status = DID_ERROR << 16;
- break;
- }
-
- SCpnt->result = status | spp->target_status;
- HD(j)->iocount++;
-
- if (loops > 1) HD(j)->multicount++;
-
-#if defined (DEBUG_INTERRUPT)
- if (SCpnt->result || do_trace)
-#else
- if ((spp->adapter_status != ASOK && HD(j)->iocount > 1000) ||
- (spp->adapter_status != ASOK &&
- spp->adapter_status != ASST && HD(j)->iocount <= 1000) ||
- do_trace)
-#endif
- printk("%s: ihdlr, mbox %d, err 0x%x:%x,"\
- " target %d:%d, pid %ld, count %d.\n",
- BN(j), i, spp->adapter_status, spp->target_status,
- SCpnt->target, SCpnt->lun, SCpnt->pid, HD(j)->iocount);
-
- /* Set the command state to inactive */
- SCpnt->host_scribble = NULL;
-
- restore_flags(flags);
- SCpnt->scsi_done(SCpnt);
- cli();
-
- } /* Mailbox loop */
-
- } /* Multiple command loop */
-
- } /* Boards loop */
-
- calls[irq]++;
-
- if (total_loops == 0)
- printk("%s: ihdlr, irq %d, no command completed, calls %d.\n",
- driver_name, irq, calls[irq]);
-
- if (do_trace) printk("%s: ihdlr, exit, irq %d, calls %d.\n",
- driver_name, irq, calls[irq]);
-
-#if defined (DEBUG_STATISTICS)
- if ((calls[irq] % 100000) == 10000)
- for (j = 0; sh[j] != NULL; j++)
- printk("%s: ihdlr, calls %d, count %d, multi %d.\n", BN(j),
- calls[(sh[j]->irq)], HD(j)->iocount, HD(j)->multicount);
-#endif
-
- restore_flags(flags);
- return;
-}
-
-#if defined(MODULE)
-Scsi_Host_Template driver_template = EATA;
-
-#include "scsi_module.c"
-#endif
diff --git a/i386/i386at/gpl/linux/scsi/eata.h b/i386/i386at/gpl/linux/scsi/eata.h
deleted file mode 100644
index aabcc806..00000000
--- a/i386/i386at/gpl/linux/scsi/eata.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * eata.h - used by the low-level driver for EATA/DMA SCSI host adapters.
- *
- */
-#ifndef _EATA_H
-#define _EATA_H
-
-#include <linux/scsicam.h>
-
-int eata2x_detect(Scsi_Host_Template *);
-int eata2x_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-int eata2x_abort(Scsi_Cmnd *);
-int eata2x_reset(Scsi_Cmnd *);
-
-#define EATA_VERSION "2.01.00"
-
-
-#define EATA { \
- NULL, /* Ptr for modules */ \
- NULL, /* usage count for modules */ \
- NULL, \
- NULL, \
- "EATA/DMA 2.0x rev. " EATA_VERSION " ", \
- eata2x_detect, \
- NULL, /* Release */ \
- NULL, \
- NULL, \
- eata2x_queuecommand, \
- eata2x_abort, \
- eata2x_reset, \
- NULL, \
- scsicam_bios_param, \
- 0, /* can_queue, reset by detect */ \
- 7, /* this_id, reset by detect */ \
- 0, /* sg_tablesize, reset by detect */ \
- 0, /* cmd_per_lun, reset by detect */ \
- 0, /* number of boards present */ \
- 1, /* unchecked isa dma, reset by detect */ \
- ENABLE_CLUSTERING \
- }
-#endif
diff --git a/i386/i386at/gpl/linux/scsi/eata_dma.c b/i386/i386at/gpl/linux/scsi/eata_dma.c
deleted file mode 100644
index da9e3daa..00000000
--- a/i386/i386at/gpl/linux/scsi/eata_dma.c
+++ /dev/null
@@ -1,1375 +0,0 @@
-/************************************************************
- * *
- * Linux EATA SCSI driver *
- * *
- * based on the CAM document CAM/89-004 rev. 2.0c, *
- * DPT's driver kit, some internal documents and source, *
- * and several other Linux scsi drivers and kernel docs. *
- * *
- * The driver currently: *
- * -supports all ISA based EATA-DMA boards *
- * -supports all EISA based EATA-DMA boards *
- * -supports all PCI based EATA-DMA boards *
- * -supports multiple HBAs with & without IRQ sharing *
- * -supports all SCSI channels on multi channel boards *
- * -needs identical IDs on all channels of a HBA *
- * -can be loaded as module *
- * -displays statistical and hardware information *
- * in /proc/scsi/eata_dma *
- * -provides rudimentary latency measurement *
- * possibilities via /proc/scsi/eata_dma/<hostnum> *
- * *
- * (c)1993,94,95 Michael Neuffer *
- * neuffer@goofy.zdv.uni-mainz.de *
- * *
- * This program is free software; you can redistribute it *
- * and/or modify it under the terms of the GNU General *
- * Public License as published by the Free Software *
- * Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be *
- * useful, but WITHOUT ANY WARRANTY; without even the *
- * implied warranty of MERCHANTABILITY or FITNESS FOR A *
- * PARTICULAR PURPOSE. See the GNU General Public License *
- * for more details. *
- * *
- * You should have received a copy of the GNU General *
- * Public License along with this kernel; if not, write to *
- * the Free Software Foundation, Inc., 675 Mass Ave, *
- * Cambridge, MA 02139, USA. *
- * *
- * I have to thank DPT for their excellent support. I took *
- * me almost a year and a stopover at their HQ, on my first *
- * trip to the USA, to get it, but since then they've been *
- * very helpful and tried to give me all the infos and *
- * support I need. *
- * *
- * Thanks also to Greg Hosler who did a lot of testing and *
- * found quite a number of bugs during the development. *
- ************************************************************
- * last change: 95/11/29 OS: Linux 1.3.45 *
- ************************************************************/
-
-/* Look in eata_dma.h for configuration and revision information */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/malloc.h>
-#include <linux/in.h>
-#include <linux/bios32.h>
-#include <linux/pci.h>
-#include <linux/proc_fs.h>
-#include <asm/byteorder.h>
-#include <asm/types.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <linux/blk.h>
-#include "scsi.h"
-#include "sd.h"
-#include "hosts.h"
-#include <linux/scsicam.h>
-#include "eata_dma.h"
-#include "eata_dma_proc.h"
-
-#include <linux/stat.h>
-#include <linux/config.h> /* for CONFIG_PCI */
-
-struct proc_dir_entry proc_scsi_eata_dma = {
- PROC_SCSI_EATA, 8, "eata_dma",
- S_IFDIR | S_IRUGO | S_IXUGO, 2
-};
-
-static u32 ISAbases[] =
-{0x1F0, 0x170, 0x330, 0x230};
-static unchar EISAbases[] =
-{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
-static uint registered_HBAs = 0;
-static struct Scsi_Host *last_HBA = NULL;
-static struct Scsi_Host *first_HBA = NULL;
-static unchar reg_IRQ[] =
-{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-static unchar reg_IRQL[] =
-{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-static struct eata_sp *status = 0; /* Statuspacket array */
-static void *dma_scratch = 0;
-
-static struct eata_register *fake_int_base;
-static int fake_int_result;
-static int fake_int_happened;
-
-static ulong int_counter = 0;
-static ulong queue_counter = 0;
-
-void eata_scsi_done (Scsi_Cmnd * scmd)
-{
- scmd->request.rq_status = RQ_SCSI_DONE;
-
- if (scmd->request.sem != NULL)
- up(scmd->request.sem);
-
- return;
-}
-
-void eata_fake_int_handler(s32 irq, struct pt_regs * regs)
-{
- fake_int_result = inb((ulong)fake_int_base + HA_RSTATUS);
- fake_int_happened = TRUE;
- DBG(DBG_INTR3, printk("eata_fake_int_handler called irq%d base %p"
- " res %#x\n", irq, fake_int_base, fake_int_result));
- return;
-}
-
-#ifdef MACH
-#include "eata_dma_proc.src"
-#else
-#include "eata_dma_proc.c"
-#endif
-
-#ifdef MODULE
-int eata_release(struct Scsi_Host *sh)
-{
- uint i;
- if (sh->irq && reg_IRQ[sh->irq] == 1) free_irq(sh->irq);
- else reg_IRQ[sh->irq]--;
-
- scsi_init_free((void *)status, 512);
- scsi_init_free((void *)dma_scratch, 512);
- for (i = 0; i < sh->can_queue; i++){ /* Free all SG arrays */
- if(SD(sh)->ccb[i].sg_list != NULL)
- scsi_init_free((void *) SD(sh)->ccb[i].sg_list,
- sh->sg_tablesize * sizeof(struct eata_sg_list));
- }
-
- if (SD(sh)->channel == 0) {
- if (sh->dma_channel != BUSMASTER) free_dma(sh->dma_channel);
- if (sh->io_port && sh->n_io_port)
- release_region(sh->io_port, sh->n_io_port);
- }
- return(TRUE);
-}
-#endif
-
-
-void eata_int_handler(int irq, struct pt_regs * regs)
-{
- uint i, result = 0;
- uint hba_stat, scsi_stat, eata_stat;
- Scsi_Cmnd *cmd;
- struct eata_ccb *cp;
- struct eata_sp *sp;
- uint base;
- ulong flags;
- uint x;
- struct Scsi_Host *sh;
-
- save_flags(flags);
- cli();
-
- for (x = 1, sh = first_HBA; x <= registered_HBAs; x++, sh = SD(sh)->next) {
- if (sh->irq != irq)
- continue;
-
- while(inb((uint)sh->base + HA_RAUXSTAT) & HA_AIRQ) {
-
- int_counter++;
-
- sp = &SD(sh)->sp;
- cp = sp->ccb;
-
- if(cp == NULL) {
- eata_stat = inb((uint)sh->base + HA_RSTATUS);
- printk("eata_dma: int_handler, Spurious IRQ %d "
- "received. CCB pointer not set.\n", irq);
- break;
- }
-
- cmd = cp->cmd;
- base = (uint) cmd->host->base;
- hba_stat = sp->hba_stat;
-
- scsi_stat = (sp->scsi_stat >> 1) & 0x1f;
-
- if (sp->EOC == FALSE) {
- eata_stat = inb(base + HA_RSTATUS);
- printk("eata_dma: int_handler, board: %x cmd %lx returned "
- "unfinished.\nEATA: %x HBA: %x SCSI: %x spadr %lx "
- "spadrirq %lx, irq%d\n", base, (long)cp, eata_stat,
- hba_stat, scsi_stat,(long)&status, (long)&status[irq],
- irq);
- DBG(DBG_DELAY, DEL2(800));
- break;
- }
-
- if (cp->status == LOCKED) {
- cp->status = FREE;
- eata_stat = inb(base + HA_RSTATUS);
- printk("eata_dma: int_handler, freeing locked queueslot\n");
- DBG(DBG_INTR && DBG_DELAY, DEL2(800));
- break;
- }
-
- eata_stat = inb(base + HA_RSTATUS);
- DBG(DBG_INTR, printk("IRQ %d received, base %#.4x, pid %ld, "
- "target: %x, lun: %x, ea_s: %#.2x, hba_s: "
- "%#.2x \n", irq, base, cmd->pid, cmd->target,
- cmd->lun, eata_stat, hba_stat));
-
- switch (hba_stat) {
- case HA_NO_ERROR: /* NO Error */
- if (scsi_stat == CONDITION_GOOD
- && cmd->device->type == TYPE_DISK
- && (HD(cmd)->t_state[cp->cp_channel][cp->cp_id] == RESET))
- result = DID_BUS_BUSY << 16;
- else if (scsi_stat == GOOD) {
- HD(cmd)->t_state[cp->cp_channel][cp->cp_id] = OK;
- if(HD(cmd)->do_latency == TRUE && cp->timestamp) {
- uint time;
- time = jiffies - cp->timestamp;
- if((cp->rw_latency) == TRUE) { /* was WRITE */
- if(HD(cmd)->writes_lat[cp->sizeindex][1] > time)
- HD(cmd)->writes_lat[cp->sizeindex][1] = time;
- if(HD(cmd)->writes_lat[cp->sizeindex][2] < time)
- HD(cmd)->writes_lat[cp->sizeindex][2] = time;
- HD(cmd)->writes_lat[cp->sizeindex][3] += time;
- HD(cmd)->writes_lat[cp->sizeindex][0]++;
- } else {
- if(HD(cmd)->reads_lat[cp->sizeindex][1] > time)
- HD(cmd)->reads_lat[cp->sizeindex][1] = time;
- if(HD(cmd)->reads_lat[cp->sizeindex][2] < time)
- HD(cmd)->reads_lat[cp->sizeindex][2] = time;
- HD(cmd)->reads_lat[cp->sizeindex][3] += time;
- HD(cmd)->reads_lat[cp->sizeindex][0]++;
- }
- }
- }
- else if (scsi_stat == CHECK_CONDITION
- && cmd->device->type == TYPE_DISK
- && (cmd->sense_buffer[2] & 0xf) == RECOVERED_ERROR)
- result = DID_BUS_BUSY << 16;
- else
- result = DID_OK << 16;
- HD(cmd)->t_timeout[cp->cp_channel][cp->cp_id] = OK;
- break;
- case HA_ERR_SEL_TO: /* Selection Timeout */
- result = DID_BAD_TARGET << 16;
- break;
- case HA_ERR_CMD_TO: /* Command Timeout */
- if (HD(cmd)->t_timeout[cp->cp_channel][cp->cp_id] > 1)
- result = DID_ERROR << 16;
- else {
- result = DID_TIME_OUT << 16;
- HD(cmd)->t_timeout[cp->cp_channel][cp->cp_id]++;
- }
- break;
- case HA_ERR_RESET: /* SCSI Bus Reset Received */
- case HA_INIT_POWERUP: /* Initial Controller Power-up */
- if (cmd->device->type != TYPE_TAPE)
- result = DID_BUS_BUSY << 16;
- else
- result = DID_ERROR << 16;
-
- for (i = 0; i < MAXTARGET; i++)
- HD(cmd)->t_state[cp->cp_channel][i] = RESET;
- break;
- case HA_UNX_BUSPHASE: /* Unexpected Bus Phase */
- case HA_UNX_BUS_FREE: /* Unexpected Bus Free */
- case HA_BUS_PARITY: /* Bus Parity Error */
- case HA_SCSI_HUNG: /* SCSI Hung */
- case HA_UNX_MSGRJCT: /* Unexpected Message Reject */
- case HA_RESET_STUCK: /* SCSI Bus Reset Stuck */
- case HA_RSENSE_FAIL: /* Auto Request-Sense Failed */
- case HA_PARITY_ERR: /* Controller Ram Parity */
- default:
- result = DID_ERROR << 16;
- break;
- }
- cmd->result = result | (scsi_stat << 1);
-
-#if DBG_INTR2
- if (scsi_stat || result || hba_stat || eata_stat != 0x50
- || cmd->scsi_done == NULL || cmd->device->id == 7)
- printk("HBA: %d, channel %d, id: %d, lun %d, pid %ld:\n"
- "eata_stat %#x, hba_stat %#.2x, scsi_stat %#.2x, "
- "sense_key: %#x, result: %#.8x\n", x,
- cmd->device->channel, cmd->device->id, cmd->device->lun,
- cmd->pid, eata_stat, hba_stat, scsi_stat,
- cmd->sense_buffer[2] & 0xf, cmd->result);
- DBG(DBG_INTR&&DBG_DELAY,DEL2(800));
-#endif
-
- cp->status = FREE; /* now we can release the slot */
- cmd->scsi_done(cmd);
- }
- }
- restore_flags(flags);
-
- return;
-}
-
-inline int eata_send_command(u32 addr, u32 base, u8 command)
-{
- long loop = R_LIMIT;
-
- while (inb(base + HA_RAUXSTAT) & HA_ABUSY)
- if (--loop == 0)
- return(FALSE);
-
- /* And now the address in nice little byte chunks */
- outb( addr & 0x000000ff, base + HA_WDMAADDR);
- outb((addr & 0x0000ff00) >> 8, base + HA_WDMAADDR + 1);
- outb((addr & 0x00ff0000) >> 16, base + HA_WDMAADDR + 2);
- outb((addr & 0xff000000) >> 24, base + HA_WDMAADDR + 3);
- outb(command, base + HA_WCOMMAND);
- return(TRUE);
-}
-
-#if 0
-inline int eata_send_immediate(u32 addr, u32 base, u8 cmnd, u8 cmnd2, u8 id,
- u8 lun)
-{
- if(addr){
- outb( addr & 0x000000ff, base + HA_WDMAADDR);
- outb((addr & 0x0000ff00) >> 8, base + HA_WDMAADDR + 1);
- outb((addr & 0x00ff0000) >> 16, base + HA_WDMAADDR + 2);
- outb((addr & 0xff000000) >> 24, base + HA_WDMAADDR + 3);
- } else {
- outb(id, base + HA_WSUBCODE);
- outb(lun, base + HA_WSUBLUN);
- }
-
- outb(cmnd2, base + HA_WCOMMAND2);
- outb(cmnd, base + HA_WCOMMAND);
- return(TRUE);
-}
-#endif
-
-int eata_queue(Scsi_Cmnd * cmd, void (* done) (Scsi_Cmnd *))
-{
- unsigned int i, x, y;
- u32 flags;
- hostdata *hd;
- struct Scsi_Host *sh;
- struct eata_ccb *cp;
- struct scatterlist *sl;
-
- save_flags(flags);
- cli();
-
- queue_counter++;
-
- hd = HD(cmd);
- sh = cmd->host;
-
- /* check for free slot */
- for (y = hd->last_ccb + 1, x = 0; x < sh->can_queue; x++, y++) {
- if (y >= sh->can_queue)
- y = 0;
- if (hd->ccb[y].status == FREE)
- break;
- }
-
- hd->last_ccb = y;
-
- if (x >= sh->can_queue) {
- uint z;
-
- printk(KERN_EMERG "eata_dma: run out of queue slots cmdno:%ld"
- " intrno: %ld, can_queue: %d, x: %d, y: %d\n",
- queue_counter, int_counter, sh->can_queue, x, y);
- printk(KERN_EMERG "Status of queueslots:");
- for(z = 0; z < sh->can_queue; z +=2) {
- switch(hd->ccb[z].status) {
- case FREE:
- printk(KERN_EMERG "Slot %2d is FREE \t", z);
- break;
- case USED:
- printk(KERN_EMERG "Slot %2d is USED \t", z);
- break;
- case LOCKED:
- printk(KERN_EMERG "Slot %2d is LOCKED\t", z);
- break;
- default:
- printk(KERN_EMERG "Slot %2d is UNKNOWN\t", z);
- }
- panic("\nSystem halted.\n");
- }
- }
- cp = &hd->ccb[y];
-
- memset(cp, 0, sizeof(struct eata_ccb) - sizeof(struct eata_sg_list *));
-
- cp->status = USED; /* claim free slot */
-
- DBG(DBG_QUEUE, printk("eata_queue pid %ld, target: %x, lun: %x, y %d\n",
- cmd->pid, cmd->target, cmd->lun, y));
- DBG(DBG_QUEUE && DBG_DELAY, DEL2(250));
-
- if(hd->do_latency == TRUE) {
- int x, z;
- short *sho;
- long *lon;
- x = 0; /* just to keep GCC quiet */
- if (cmd->cmnd[0] == WRITE_6 || cmd->cmnd[0] == WRITE_10 ||
- cmd->cmnd[0] == WRITE_12 || cmd->cmnd[0] == READ_6 ||
- cmd->cmnd[0] == READ_10 || cmd->cmnd[0] == READ_12) {
-
- cp->timestamp = jiffies; /* For latency measurements */
- switch(cmd->cmnd[0]) {
- case WRITE_6:
- case READ_6:
- x = cmd->cmnd[4]/2;
- break;
- case WRITE_10:
- case READ_10:
- sho = (short *) &cmd->cmnd[7];
- x = ntohs(*sho)/2;
- break;
- case WRITE_12:
- case READ_12:
- lon = (long *) &cmd->cmnd[6];
- x = ntohl(*lon)/2;
- break;
- }
-
- for(z = 0; (x > (1 << z)) && (z <= 11); z++)
- /* nothing */;
- cp->sizeindex = z;
- if (cmd->cmnd[0] == WRITE_6 || cmd->cmnd[0] == WRITE_10 ||
- cmd->cmnd[0] == WRITE_12){
- cp->rw_latency = TRUE;
- }
- }
- }
- cmd->scsi_done = (void *)done;
-
- switch (cmd->cmnd[0]) {
- case CHANGE_DEFINITION: case COMPARE: case COPY:
- case COPY_VERIFY: case LOG_SELECT: case MODE_SELECT:
- case MODE_SELECT_10: case SEND_DIAGNOSTIC: case WRITE_BUFFER:
- case FORMAT_UNIT: case REASSIGN_BLOCKS: case RESERVE:
- case SEARCH_EQUAL: case SEARCH_HIGH: case SEARCH_LOW:
- case WRITE_6: case WRITE_10: case WRITE_VERIFY:
- case UPDATE_BLOCK: case WRITE_LONG: case WRITE_SAME:
- case SEARCH_HIGH_12: case SEARCH_EQUAL_12: case SEARCH_LOW_12:
- case WRITE_12: case WRITE_VERIFY_12: case SET_WINDOW:
- case MEDIUM_SCAN: case SEND_VOLUME_TAG:
- case 0xea: /* alternate number for WRITE LONG */
- cp->DataOut = TRUE; /* Output mode */
- break;
- case TEST_UNIT_READY:
- default:
- cp->DataIn = TRUE; /* Input mode */
- }
-
- /* FIXME: This will will have to be changed once the midlevel driver
- * allows different HBA IDs on every channel.
- */
- if (cmd->target == sh->this_id)
- cp->Interpret = TRUE; /* Interpret command */
-
- if (cmd->use_sg) {
- cp->scatter = TRUE; /* SG mode */
- if (cp->sg_list == NULL) {
- cp->sg_list = kmalloc(sh->sg_tablesize * sizeof(struct eata_sg_list),
- GFP_ATOMIC | GFP_DMA);
- }
- if (cp->sg_list == NULL)
- panic("eata_dma: Run out of DMA memory for SG lists !\n");
- cp->cp_dataDMA = htonl(virt_to_bus(cp->sg_list));
-
- cp->cp_datalen = htonl(cmd->use_sg * sizeof(struct eata_sg_list));
- sl=(struct scatterlist *)cmd->request_buffer;
- for(i = 0; i < cmd->use_sg; i++, sl++){
- cp->sg_list[i].data = htonl(virt_to_bus(sl->address));
- cp->sg_list[i].len = htonl((u32) sl->length);
- }
- } else {
- cp->scatter = FALSE;
- cp->cp_datalen = htonl(cmd->request_bufflen);
- cp->cp_dataDMA = htonl(virt_to_bus(cmd->request_buffer));
- }
-
- cp->Auto_Req_Sen = TRUE;
- cp->cp_reqDMA = htonl(virt_to_bus(cmd->sense_buffer));
- cp->reqlen = sizeof(cmd->sense_buffer);
-
- cp->cp_id = cmd->target;
- cp->cp_channel = cmd->channel;
- cp->cp_lun = cmd->lun;
- cp->cp_dispri = TRUE;
- cp->cp_identify = TRUE;
- memcpy(cp->cp_cdb, cmd->cmnd, cmd->cmd_len);
-
- cp->cp_statDMA = htonl(virt_to_bus(&(hd->sp)));
-
- cp->cp_viraddr = cp; /* This will be passed thru, so we don't need to
- * convert it */
- cp->cmd = cmd;
- cmd->host_scribble = (char *)&hd->ccb[y];
-
- if(eata_send_command((u32) cp, (u32) sh->base, EATA_CMD_DMA_SEND_CP) == FALSE) {
- cmd->result = DID_BUS_BUSY << 16;
- DBG(DBG_QUEUE && DBG_ABNORM,
- printk("eata_queue target %d, pid %ld, HBA busy, "
- "returning DID_BUS_BUSY\n",cmd->target, cmd->pid));
- done(cmd);
- cp->status = FREE;
- restore_flags(flags);
- return(0);
- }
- DBG(DBG_QUEUE, printk("Queued base %#.4x pid: %ld target: %x lun: %x "
- "slot %d irq %d\n", (s32)sh->base, cmd->pid,
- cmd->target, cmd->lun, y, sh->irq));
- DBG(DBG_QUEUE && DBG_DELAY, DEL2(200));
- restore_flags(flags);
- return(0);
-}
-
-
-int eata_abort(Scsi_Cmnd * cmd)
-{
- ulong loop = R_LIMIT;
- ulong flags;
-
- save_flags(flags);
- cli();
-
- DBG(DBG_ABNORM, printk("eata_abort called pid: %ld target: %x lun: %x"
- " reason %x\n", cmd->pid, cmd->target, cmd->lun,
- cmd->abort_reason));
- DBG(DBG_ABNORM && DBG_DELAY, DEL2(500));
-
- while (inb((u32)(cmd->host->base) + HA_RAUXSTAT) & HA_ABUSY) {
- if (--loop == 0) {
- printk("eata_dma: abort, timeout error.\n");
- restore_flags(flags);
- DBG(DBG_ABNORM && DBG_DELAY, DEL2(500));
- return (SCSI_ABORT_ERROR);
- }
- }
- if (CD(cmd)->status == RESET) {
- restore_flags(flags);
- printk("eata_dma: abort, command reset error.\n");
- DBG(DBG_ABNORM && DBG_DELAY, DEL2(500));
- return (SCSI_ABORT_ERROR);
- }
- if (CD(cmd)->status == LOCKED) {
- restore_flags(flags);
- DBG(DBG_ABNORM, printk("eata_dma: abort, queue slot locked.\n"));
- DBG(DBG_ABNORM && DBG_DELAY, DEL2(500));
- return (SCSI_ABORT_NOT_RUNNING);
- }
- if (CD(cmd)->status == USED) {
- DBG(DBG_ABNORM, printk("Returning: SCSI_ABORT_BUSY\n"));
- restore_flags(flags);
- return (SCSI_ABORT_BUSY); /* SNOOZE */
- }
- if (CD(cmd)->status == FREE) {
- DBG(DBG_ABNORM, printk("Returning: SCSI_ABORT_NOT_RUNNING\n"));
- restore_flags(flags);
- return (SCSI_ABORT_NOT_RUNNING);
- }
- restore_flags(flags);
- panic("eata_dma: abort: invalid slot status\n");
-}
-
-int eata_reset(Scsi_Cmnd * cmd)
-{
- ushort x, z;
- ulong time, limit = 0;
- ulong loop = R_LIMIT;
- ulong flags;
- unchar success = FALSE;
- Scsi_Cmnd *sp;
-
- save_flags(flags);
- cli();
-
- DBG(DBG_ABNORM, printk("eata_reset called pid:%ld target: %x lun: %x"
- " reason %x\n", cmd->pid, cmd->target, cmd->lun,
- cmd->abort_reason));
-
- if (HD(cmd)->state == RESET) {
- printk("eata_reset: exit, already in reset.\n");
- restore_flags(flags);
- DBG(DBG_ABNORM && DBG_DELAY, DEL2(500));
- return (SCSI_RESET_ERROR);
- }
-
- while (inb((u32)(cmd->host->base) + HA_RAUXSTAT) & HA_ABUSY)
- if (--loop == 0) {
- printk("eata_reset: exit, timeout error.\n");
- restore_flags(flags);
- DBG(DBG_ABNORM && DBG_DELAY, DEL2(500));
- return (SCSI_RESET_ERROR);
- }
-
- for (x = 0; x < MAXCHANNEL; x++) {
- for (z = 0; z < MAXTARGET; z++) {
- HD(cmd)->t_state[x][z] = RESET;
- HD(cmd)->t_timeout[x][z] = NO_TIMEOUT;
- }
- }
-
- for (x = 0; x < cmd->host->can_queue; x++) {
- if (HD(cmd)->ccb[x].status == FREE)
- continue;
-
- if (HD(cmd)->ccb[x].status == LOCKED) {
- HD(cmd)->ccb[x].status = FREE;
- printk("eata_reset: locked slot %d forced free.\n", x);
- DBG(DBG_ABNORM && DBG_DELAY, DEL2(500));
- continue;
- }
- sp = HD(cmd)->ccb[x].cmd;
- HD(cmd)->ccb[x].status = RESET;
- printk("eata_reset: slot %d in reset, pid %ld.\n", x, sp->pid);
- DBG(DBG_ABNORM && DBG_DELAY, DEL2(500));
-
- if (sp == NULL)
- panic("eata_reset: slot %d, sp==NULL.\n", x);
- DBG(DBG_ABNORM && DBG_DELAY, DEL2(500));
-
- if (sp == cmd)
- success = TRUE;
- }
-
- /* hard reset the HBA */
- inb((u32) (cmd->host->base) + HA_RSTATUS); /* This might cause trouble */
- eata_send_command(0, (u32) cmd->host->base, EATA_CMD_RESET);
-
- DBG(DBG_ABNORM, printk("eata_reset: board reset done, enabling interrupts.\n"));
- HD(cmd)->state = RESET;
-
- restore_flags(flags);
-
- time = jiffies;
- while (jiffies < (time + (3 * HZ)) || limit++ < 10000000)
- /* As time goes by... */;
-
- save_flags(flags);
- cli();
-
- DBG(DBG_ABNORM, printk("eata_reset: interrupts disabled, loops %ld.\n",
- limit));
- DBG(DBG_ABNORM && DBG_DELAY, DEL2(500));
-
- for (x = 0; x < cmd->host->can_queue; x++) {
-
- /* Skip slots already set free by interrupt */
- if (HD(cmd)->ccb[x].status != RESET)
- continue;
-
- sp = HD(cmd)->ccb[x].cmd;
- sp->result = DID_RESET << 16;
-
- /* This mailbox is still waiting for its interrupt */
- HD(cmd)->ccb[x].status = LOCKED;
-
- printk("eata_reset: slot %d locked, DID_RESET, pid %ld done.\n",
- x, sp->pid);
- DBG(DBG_ABNORM && DBG_DELAY, DEL2(500));
- restore_flags(flags);
- sp->scsi_done(sp);
- cli();
- }
-
- HD(cmd)->state = FALSE;
- restore_flags(flags);
-
- if (success) {
- DBG(DBG_ABNORM, printk("eata_reset: exit, success.\n"));
- DBG(DBG_ABNORM && DBG_DELAY, DEL2(500));
- return (SCSI_RESET_SUCCESS);
- } else {
- DBG(DBG_ABNORM, printk("eata_reset: exit, wakeup.\n"));
- DBG(DBG_ABNORM && DBG_DELAY, DEL2(500));
- return (SCSI_RESET_PUNT);
- }
-}
-
-char * get_board_data(u32 base, u32 irq, u32 id)
-{
- struct eata_ccb *cp;
- struct eata_sp *sp;
- static char *buff;
- ulong i;
- ulong limit = 0;
-
- cp = (struct eata_ccb *) scsi_init_malloc(sizeof(struct eata_ccb),
- GFP_ATOMIC | GFP_DMA);
- sp = (struct eata_sp *) scsi_init_malloc(sizeof(struct eata_sp),
- GFP_ATOMIC | GFP_DMA);
-
- buff = dma_scratch;
-
- memset(cp, 0, sizeof(struct eata_ccb));
- memset(sp, 0, sizeof(struct eata_sp));
- memset(buff, 0, 256);
-
- cp->DataIn = TRUE;
- cp->Interpret = TRUE; /* Interpret command */
- cp->cp_dispri = TRUE;
- cp->cp_identify = TRUE;
-
- cp->cp_datalen = htonl(56);
- cp->cp_dataDMA = htonl(virt_to_bus(buff));
- cp->cp_statDMA = htonl(virt_to_bus(sp));
- cp->cp_viraddr = cp;
-
- cp->cp_id = id;
- cp->cp_lun = 0;
-
- cp->cp_cdb[0] = INQUIRY;
- cp->cp_cdb[1] = 0;
- cp->cp_cdb[2] = 0;
- cp->cp_cdb[3] = 0;
- cp->cp_cdb[4] = 56;
- cp->cp_cdb[5] = 0;
-
- fake_int_base = (struct eata_register *) base;
- fake_int_result = FALSE;
- fake_int_happened = FALSE;
-
- eata_send_command((u32) cp, (u32) base, EATA_CMD_DMA_SEND_CP);
-
- i = jiffies + (3 * HZ);
- while (fake_int_happened == FALSE && jiffies <= i)
- barrier();
-
- DBG(DBG_INTR3, printk("fake_int_result: %#x hbastat %#x scsistat %#x,"
- " buff %p sp %p\n",
- fake_int_result, (u32) (sp->hba_stat /*& 0x7f*/),
- (u32) sp->scsi_stat, buff, sp));
-
- scsi_init_free((void *)cp, sizeof(struct eata_ccb));
- scsi_init_free((void *)sp, sizeof(struct eata_sp));
-
- if ((fake_int_result & HA_SERROR) || jiffies > i){
- /* hard reset the HBA */
- inb((u32) (base) + HA_RSTATUS);
- eata_send_command(0, base, EATA_CMD_RESET);
- i = jiffies;
- while (jiffies < (i + (3 * HZ)) && limit++ < 10000000)
- barrier();
- return (NULL);
- } else
- return (buff);
-}
-
-int check_blink_state(long base)
-{
- ushort loops = 10;
- u32 blinkindicator;
- u32 state = 0x12345678;
- u32 oldstate = 0;
-
- blinkindicator = htonl(0x54504442);
- while ((loops--) && (state != oldstate)) {
- oldstate = state;
- state = inl((uint) base + 1);
- }
-
- DBG(DBG_BLINK, printk("Did Blink check. Status: %d\n",
- (state == oldstate) && (state == blinkindicator)));
-
- if ((state == oldstate) && (state == blinkindicator))
- return(TRUE);
- else
- return (FALSE);
-}
-
-int get_conf_PIO(u32 base, struct get_conf *buf)
-{
- ulong loop = R_LIMIT;
- u16 *p;
-
- if(check_region(base, 9))
- return (FALSE);
-
- memset(buf, 0, sizeof(struct get_conf));
-
- while (inb(base + HA_RSTATUS) & HA_SBUSY)
- if (--loop == 0)
- return (FALSE);
-
- DBG(DBG_PIO && DBG_PROBE,
- printk("Issuing PIO READ CONFIG to HBA at %#x\n", base));
- eata_send_command(0, base, EATA_CMD_PIO_READ_CONFIG);
-
- loop = R_LIMIT;
- for (p = (u16 *) buf;
- (long)p <= ((long)buf + (sizeof(struct get_conf) / 2)); p++) {
- while (!(inb(base + HA_RSTATUS) & HA_SDRQ))
- if (--loop == 0)
- return (FALSE);
-
- loop = R_LIMIT;
- *p = inw(base + HA_RDATA);
- }
-
- if (!(inb(base + HA_RSTATUS) & HA_SERROR)) { /* Error ? */
- if (htonl(EATA_SIGNATURE) == buf->signature) {
- DBG(DBG_PIO&&DBG_PROBE, printk("EATA Controller found at %x "
- "EATA Level: %x\n", (uint) base,
- (uint) (buf->version)));
-
- while (inb(base + HA_RSTATUS) & HA_SDRQ)
- inw(base + HA_RDATA);
- return (TRUE);
- }
- } else {
- DBG(DBG_PROBE, printk("eata_dma: get_conf_PIO, error during transfer "
- "for HBA at %lx\n", (long)base));
- }
- return (FALSE);
-}
-
-void print_config(struct get_conf *gc)
-{
- printk("LEN: %d ver:%d OCS:%d TAR:%d TRNXFR:%d MORES:%d DMAS:%d\n",
- (u32) ntohl(gc->len), gc->version,
- gc->OCS_enabled, gc->TAR_support, gc->TRNXFR, gc->MORE_support,
- gc->DMA_support);
- printk("DMAV:%d HAAV:%d SCSIID0:%d ID1:%d ID2:%d QUEUE:%d SG:%d SEC:%d\n",
- gc->DMA_valid, gc->HAA_valid, gc->scsi_id[3], gc->scsi_id[2],
- gc->scsi_id[1], ntohs(gc->queuesiz), ntohs(gc->SGsiz), gc->SECOND);
- printk("IRQ:%d IRQT:%d DMAC:%d FORCADR:%d SG_64K:%d SG_UAE:%d MID:%d "
- "MCH:%d MLUN:%d\n",
- gc->IRQ, gc->IRQ_TR, (8 - gc->DMA_channel) & 7, gc->FORCADR,
- gc->SG_64K, gc->SG_UAE, gc->MAX_ID, gc->MAX_CHAN, gc->MAX_LUN);
- printk("RIDQ:%d PCI:%d EISA:%d\n",
- gc->ID_qest, gc->is_PCI, gc->is_EISA);
- DBG(DPT_DEBUG, DELAY(14));
-}
-
-short register_HBA(u32 base, struct get_conf *gc, Scsi_Host_Template * tpnt,
- u8 bustype)
-{
- ulong size = 0;
- unchar dma_channel = 0;
- char *buff = 0;
- unchar bugs = 0;
- struct Scsi_Host *sh;
- hostdata *hd;
- int x;
-
-
- DBG(DBG_REGISTER, print_config(gc));
-
- if (gc->DMA_support == FALSE) {
- printk("The EATA HBA at %#.4x does not support DMA.\n"
- "Please use the EATA-PIO driver.\n", base);
- return (FALSE);
- }
- if(gc->HAA_valid == FALSE || ntohl(gc->len) < 0x22)
- gc->MAX_CHAN = 0;
-
- if (reg_IRQ[gc->IRQ] == FALSE) { /* Interrupt already registered ? */
- if (!request_irq(gc->IRQ, (void *) eata_fake_int_handler, SA_INTERRUPT,
- "eata_dma")){
- reg_IRQ[gc->IRQ]++;
- if (!gc->IRQ_TR)
- reg_IRQL[gc->IRQ] = TRUE; /* IRQ is edge triggered */
- } else {
- printk("Couldn't allocate IRQ %d, Sorry.", gc->IRQ);
- return (FALSE);
- }
- } else { /* More than one HBA on this IRQ */
- if (reg_IRQL[gc->IRQ] == TRUE) {
- printk("Can't support more than one HBA on this IRQ,\n"
- " if the IRQ is edge triggered. Sorry.\n");
- return (FALSE);
- } else
- reg_IRQ[gc->IRQ]++;
- }
-
- /* if gc->DMA_valid it must be an ISA HBA and we have to register it */
- dma_channel = BUSMASTER;
- if (gc->DMA_valid) {
- if (request_dma(dma_channel = (8 - gc->DMA_channel) & 7, "eata_dma")) {
- printk("Unable to allocate DMA channel %d for ISA HBA at %#.4x.\n",
- dma_channel, base);
- reg_IRQ[gc->IRQ]--;
- if (reg_IRQ[gc->IRQ] == 0)
- free_irq(gc->IRQ);
- if (gc->IRQ_TR == FALSE)
- reg_IRQL[gc->IRQ] = FALSE;
- return (FALSE);
- }
- }
-
-#if !(NEWSTUFF)
- if (bustype != IS_EISA && bustype != IS_ISA)
-#endif
- buff = get_board_data(base, gc->IRQ, gc->scsi_id[3]);
-
- if (buff == NULL) {
-#if !(NEWSTUFF)
- if (bustype == IS_EISA || bustype == IS_ISA) {
- bugs = bugs || BROKEN_INQUIRY;
- } else {
-#endif
- if (gc->DMA_support == FALSE)
- printk("HBA at %#.4x doesn't support DMA. Sorry\n", base);
- else
- printk("HBA at %#.4x does not react on INQUIRY. Sorry.\n",
- base);
- if (gc->DMA_valid)
- free_dma(dma_channel);
- reg_IRQ[gc->IRQ]--;
- if (reg_IRQ[gc->IRQ] == 0)
- free_irq(gc->IRQ);
- if (gc->IRQ_TR == FALSE)
- reg_IRQL[gc->IRQ] = FALSE;
- return (FALSE);
-#if !(NEWSTUFF)
- }
-#endif
- }
-
- if (gc->DMA_support == FALSE && buff != NULL)
- printk("HBA %.12sat %#.4x doesn't set the DMA_support flag correctly.\n",
- &buff[16], base);
-
- request_region(base, 9, "eata_dma"); /* We already checked the
- * availability, so this
- * should not fail.
- */
-
- if(ntohs(gc->queuesiz) == 0) {
- gc->queuesiz = ntohs(64);
- printk("Warning: Queue size has to be corrected. Assuming 64 queueslots\n"
- " This might be a PM2012B with a defective Firmware\n");
- }
-
- size = sizeof(hostdata) + ((sizeof(struct eata_ccb) + sizeof(long))
- * ntohs(gc->queuesiz));
-
- DBG(DBG_REGISTER, printk("scsi_register size: %ld\n", size));
-
- sh = scsi_register(tpnt, size);
-
- if(sh == NULL) {
- if (gc->DMA_valid)
- free_dma(dma_channel);
-
- reg_IRQ[gc->IRQ]--;
- if (reg_IRQ[gc->IRQ] == 0)
- free_irq(gc->IRQ);
- if (gc->IRQ_TR == FALSE)
- reg_IRQL[gc->IRQ] = FALSE;
- return (FALSE);
- }
-
- hd = SD(sh);
-
- memset(hd->ccb, 0, sizeof(struct eata_ccb) * ntohs(gc->queuesiz));
- memset(hd->reads, 0, sizeof(u32) * 26);
-
- hd->broken_INQUIRY = (bugs & BROKEN_INQUIRY);
-
- if(hd->broken_INQUIRY == TRUE) {
- strcpy(SD(sh)->vendor, "DPT");
- strcpy(SD(sh)->name, "??????????");
- strcpy(SD(sh)->revision, "???.?");
- } else {
- strncpy(SD(sh)->vendor, &buff[8], 8);
- SD(sh)->vendor[8] = 0;
- strncpy(SD(sh)->name, &buff[16], 17);
- SD(sh)->name[17] = 0;
- SD(sh)->revision[0] = buff[32];
- SD(sh)->revision[1] = buff[33];
- SD(sh)->revision[2] = buff[34];
- SD(sh)->revision[3] = '.';
- SD(sh)->revision[4] = buff[35];
- SD(sh)->revision[5] = 0;
- }
-
- switch (ntohl(gc->len)) {
- case 0x1c:
- SD(sh)->EATA_revision = 'a';
- break;
- case 0x1e:
- SD(sh)->EATA_revision = 'b';
- break;
- case 0x22:
- SD(sh)->EATA_revision = 'c';
- break;
- case 0x24:
- SD(sh)->EATA_revision = 'z';
- default:
- SD(sh)->EATA_revision = '?';
- }
-
- if(ntohl(gc->len) >= 0x22) {
- if (gc->is_PCI == TRUE)
- hd->bustype = IS_PCI;
- else if (gc->is_EISA == TRUE)
- hd->bustype = IS_EISA;
- else
- hd->bustype = IS_ISA;
- } else if(hd->broken_INQUIRY == FALSE) {
- if (buff[21] == '4')
- hd->bustype = IS_PCI;
- else if (buff[21] == '2')
- hd->bustype = IS_EISA;
- else
- hd->bustype = IS_ISA;
- } else
- hd->bustype = bustype;
-
- if(ntohl(gc->len) >= 0x22) {
- sh->max_id = gc->MAX_ID + 1;
- sh->max_lun = gc->MAX_LUN + 1;
- } else {
- sh->max_id = 8;
- sh->max_lun = 8;
- }
-
- hd->channel = gc->MAX_CHAN;
- sh->max_channel = gc->MAX_CHAN;
- sh->unique_id = base;
- sh->base = (char *) base;
- sh->io_port = base;
- sh->n_io_port = 9;
- sh->irq = gc->IRQ;
- sh->dma_channel = dma_channel;
-
- /* FIXME:
- * SCSI midlevel code should support different HBA ids on every channel
- */
- sh->this_id = gc->scsi_id[3];
- sh->can_queue = ntohs(gc->queuesiz);
-
- if (gc->OCS_enabled == TRUE) {
- if(hd->bustype != IS_ISA)
- sh->cmd_per_lun = sh->can_queue/C_P_L_DIV;
- else
- sh->cmd_per_lun = 8; /* We artificially limit this to conserve
- * memory, which would be needed for ISA
- * bounce buffers */
- } else
- sh->cmd_per_lun = 1;
-
- /* FIXME:
- * SG should be allocated more dynamically
- */
- /*
- * If we are using a ISA board, we can't use extended SG,
- * because we would need exessive amounts of memory for
- * bounce buffers.
- */
- if (gc->SG_64K == TRUE && ntohs(gc->SGsiz) == 64 && hd->bustype != IS_ISA){
- sh->sg_tablesize = SG_SIZE_BIG;
- sh->use_clustering = FALSE;
- } else {
- sh->sg_tablesize = ntohs(gc->SGsiz);
- sh->use_clustering = TRUE;
- if (sh->sg_tablesize > SG_SIZE || sh->sg_tablesize == 0) {
- sh->sg_tablesize = SG_SIZE;
- if (ntohs(gc->SGsiz) == 0)
- printk("Warning: SG size had to be corrected.\n"
- "This might be a PM2012 with a defective Firmware\n");
- }
- }
-
- if (gc->SECOND)
- hd->primary = FALSE;
- else
- hd->primary = TRUE;
-
- sh->wish_block = FALSE;
-
- if (hd->bustype != IS_ISA) {
- sh->unchecked_isa_dma = FALSE;
- } else {
- sh->unchecked_isa_dma = TRUE; /* We're doing ISA DMA */
- }
-
- for(x = 0; x <= 11; x++){ /* Initialize min. latency */
- hd->writes_lat[x][1] = 0xffffffff;
- hd->reads_lat[x][1] = 0xffffffff;
- }
-
- hd->next = NULL; /* build a linked list of all HBAs */
- hd->prev = last_HBA;
- if(hd->prev != NULL)
- SD(hd->prev)->next = sh;
- last_HBA = sh;
- if (first_HBA == NULL)
- first_HBA = sh;
- registered_HBAs++;
-
- return (TRUE);
-}
-
-
-void find_EISA(struct get_conf *buf, Scsi_Host_Template * tpnt)
-{
- u32 base;
- int i;
-
-#if CHECKPAL
- u8 pal1, pal2, pal3;
-#endif
-
- for (i = 0; i < MAXEISA; i++) {
- if (EISAbases[i] == TRUE) { /* Still a possibility ? */
-
- base = 0x1c88 + (i * 0x1000);
-#if CHECKPAL
- pal1 = inb((u16)base - 8);
- pal2 = inb((u16)base - 7);
- pal3 = inb((u16)base - 6);
-
- if (((pal1 == DPT_ID1) && (pal2 == DPT_ID2)) ||
- ((pal1 == NEC_ID1) && (pal2 == NEC_ID2) && (pal3 == NEC_ID3))||
- ((pal1 == ATT_ID1) && (pal2 == ATT_ID2) && (pal3 == ATT_ID3))){
- DBG(DBG_PROBE, printk("EISA EATA id tags found: %x %x %x \n",
- (int)pal1, (int)pal2, (int)pal3));
-#endif
- if (get_conf_PIO(base, buf) == TRUE) {
- if (buf->IRQ) {
- DBG(DBG_EISA, printk("Registering EISA HBA\n"));
- register_HBA(base, buf, tpnt, IS_EISA);
- } else
- printk("eata_dma: No valid IRQ. HBA removed from list\n");
- } else {
- if (check_blink_state(base))
- printk("HBA is in BLINK state. Consult your HBAs "
- "Manual to correct this.\n");
- }
- /* Nothing found here so we take it from the list */
- EISAbases[i] = 0;
-#if CHECKPAL
- }
-#endif
- }
- }
- return;
-}
-
-void find_ISA(struct get_conf *buf, Scsi_Host_Template * tpnt)
-{
- int i;
-
- for (i = 0; i < MAXISA; i++) {
- if (ISAbases[i]) {
- if (get_conf_PIO(ISAbases[i],buf) == TRUE){
- DBG(DBG_ISA, printk("Registering ISA HBA\n"));
- register_HBA(ISAbases[i], buf, tpnt, IS_ISA);
- } else {
- if (check_blink_state(ISAbases[i]))
- printk("HBA is in BLINK state. Consult your HBAs "
- "Manual to correct this.\n");
- }
- ISAbases[i] = 0;
- }
- }
- return;
-}
-
-void find_PCI(struct get_conf *buf, Scsi_Host_Template * tpnt)
-{
-
-#ifndef CONFIG_PCI
- printk("eata_dma: kernel PCI support not enabled. Skipping scan for PCI HBAs.\n");
-#else
-
- u8 pci_bus, pci_device_fn;
- static s16 pci_index = 0; /* Device index to PCI BIOS calls */
- u32 base = 0;
- u16 com_adr;
- u16 rev_device;
- u32 error, i, x;
- u8 pal1, pal2, pal3;
-
- if (pcibios_present()) {
- for (i = 0; i <= MAXPCI; ++i, ++pci_index) {
- if (pcibios_find_device(PCI_VENDOR_ID_DPT, PCI_DEVICE_ID_DPT,
- pci_index, &pci_bus, &pci_device_fn))
- break;
- DBG(DBG_PROBE && DBG_PCI,
- printk("eata_dma: find_PCI, HBA at bus %d, device %d,"
- " function %d, index %d\n", (s32)pci_bus,
- (s32)((pci_device_fn & 0xf8) >> 3),
- (s32)(pci_device_fn & 7), pci_index));
-
- if (!(error = pcibios_read_config_word(pci_bus, pci_device_fn,
- PCI_CLASS_DEVICE, &rev_device))) {
- if (rev_device == PCI_CLASS_STORAGE_SCSI) {
- if (!(error = pcibios_read_config_word(pci_bus,
- pci_device_fn, PCI_COMMAND,
- (u16 *) & com_adr))) {
- if (!((com_adr & PCI_COMMAND_IO) &&
- (com_adr & PCI_COMMAND_MASTER))) {
- printk("eata_dma: find_PCI, HBA has IO or BUSMASTER mode disabled\n");
- continue;
- }
- } else
- printk("eata_dma: find_PCI, error %x while reading "
- "PCI_COMMAND\n", error);
- } else
- printk("eata_dma: find_PCI, DEVICECLASSID %x didn't match\n",
- rev_device);
- } else {
- printk("eata_dma: find_PCI, error %x while reading PCI_CLASS_BASE\n",
- error);
- continue;
- }
-
- if (!(error = pcibios_read_config_dword(pci_bus, pci_device_fn,
- PCI_BASE_ADDRESS_0, (int *) &base))){
-
- /* Check if the address is valid */
- if (base & 0x01) {
- base &= 0xfffffffe;
- /* EISA tag there ? */
- pal1 = inb(base);
- pal2 = inb(base + 1);
- pal3 = inb(base + 2);
- if (((pal1 == DPT_ID1) && (pal2 == DPT_ID2)) ||
- ((pal1 == NEC_ID1) && (pal2 == NEC_ID2) &&
- (pal3 == NEC_ID3)) ||
- ((pal1 == ATT_ID1) && (pal2 == ATT_ID2) &&
- (pal3 == ATT_ID3)))
- base += 0x08;
- else
- base += 0x10; /* Now, THIS is the real address */
-
- if (base != 0x1f8) {
- /* We didn't find it in the primary search */
- if (get_conf_PIO(base, buf) == TRUE) {
-
- /* OK. We made it till here, so we can go now
- * and register it. We only have to check and
- * eventually remove it from the EISA and ISA list
- */
- DBG(DBG_PCI, printk("Registering PCI HBA\n"));
- register_HBA(base, buf, tpnt, IS_PCI);
-
- if (base < 0x1000) {
- for (x = 0; x < MAXISA; ++x) {
- if (ISAbases[x] == base) {
- ISAbases[x] = 0;
- break;
- }
- }
- } else if ((base & 0x0fff) == 0x0c88)
- EISAbases[(base >> 12) & 0x0f] = 0;
- continue; /* break; */
- } else if (check_blink_state(base) == TRUE) {
- printk("eata_dma: HBA is in BLINK state.\n"
- "Consult your HBAs Manual to correct this.\n");
- }
- }
- }
- } else {
- printk("eata_dma: error %x while reading "
- "PCI_BASE_ADDRESS_0\n", error);
- }
- }
- } else {
- printk("eata_dma: No BIOS32 extensions present. This driver release "
- "still depends on it.\n"
- " Skipping scan for PCI HBAs. \n");
- }
-#endif /* #ifndef CONFIG_PCI */
- return;
-}
-
-int eata_detect(Scsi_Host_Template * tpnt)
-{
- struct Scsi_Host *HBA_ptr;
- struct get_conf gc;
- int i;
-
- DBG((DBG_PROBE && DBG_DELAY) || DPT_DEBUG,
- printk("Using lots of delays to let you read the debugging output\n"));
-
- tpnt->proc_dir = &proc_scsi_eata_dma;
-
- status = scsi_init_malloc(512, GFP_ATOMIC | GFP_DMA);
- dma_scratch = scsi_init_malloc(512, GFP_ATOMIC | GFP_DMA);
-
- if(status == NULL || dma_scratch == NULL) {
- printk("eata_dma: can't allocate enough memory to probe for hosts !\n");
- return(0);
- }
-
- find_PCI(&gc, tpnt);
-
- find_EISA(&gc, tpnt);
-
- find_ISA(&gc, tpnt);
-
- for (i = 0; i <= MAXIRQ; i++) { /* Now that we know what we have, we */
- if (reg_IRQ[i]){ /* exchange the interrupt handler which */
- free_irq(i); /* we used for probing with the real one */
- request_irq(i, (void *)(eata_int_handler), SA_INTERRUPT, "eata_dma");
- }
- }
- HBA_ptr = first_HBA;
-
- if (registered_HBAs != 0) {
- printk("EATA (Extended Attachment) driver version: %d.%d%s\n"
- "developed in co-operation with DPT\n"
- "(c) 1993-95 Michael Neuffer, neuffer@goofy.zdv.uni-mainz.de\n",
- VER_MAJOR, VER_MINOR, VER_SUB);
- printk("Registered HBAs:");
- printk("\nHBA no. Boardtype: Revis: EATA: Bus: BaseIO: IRQ: DMA: Ch: "
- "ID: Pr: QS: SG: CPL:\n");
- for (i = 1; i <= registered_HBAs; i++) {
- printk("scsi%-2d: %.10s v%s 2.0%c %s %#.4x %2d",
- HBA_ptr->host_no, SD(HBA_ptr)->name, SD(HBA_ptr)->revision,
- SD(HBA_ptr)->EATA_revision, (SD(HBA_ptr)->bustype == 'P')?
- "PCI ":(SD(HBA_ptr)->bustype == 'E')?"EISA":"ISA ",
- (u32) HBA_ptr->base, HBA_ptr->irq);
- if(HBA_ptr->dma_channel != BUSMASTER)
- printk(" %2x ", HBA_ptr->dma_channel);
- else
- printk(" %s", "BMST");
- printk(" %d %d %c %2d %2d %2d\n", SD(HBA_ptr)->channel,
- HBA_ptr->this_id, (SD(HBA_ptr)->primary == TRUE)?'Y':'N',
- HBA_ptr->can_queue, HBA_ptr->sg_tablesize, HBA_ptr->cmd_per_lun);
- HBA_ptr = SD(HBA_ptr)->next;
- }
- } else {
- scsi_init_free((void *)status, 512);
- }
-
- scsi_init_free((void *)dma_scratch, 512);
-
- DBG(DPT_DEBUG, DELAY(12));
-
- return(registered_HBAs);
-}
-
-#ifdef MODULE
-/* Eventually this will go into an include file, but this will be later */
-Scsi_Host_Template driver_template = EATA_DMA;
-#include "scsi_module.c"
-#endif
-
-/*
- * Overrides for Emacs so that we almost follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 4
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * c-continued-statement-offset: 4
- * c-continued-brace-offset: 0
- * tab-width: 8
- * End:
- */
diff --git a/i386/i386at/gpl/linux/scsi/eata_dma.h b/i386/i386at/gpl/linux/scsi/eata_dma.h
deleted file mode 100644
index 41504673..00000000
--- a/i386/i386at/gpl/linux/scsi/eata_dma.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/********************************************************
-* Header file for eata_dma.c Linux EATA-DMA SCSI driver *
-* (c) 1993,94,95 Michael Neuffer *
-*********************************************************
-* last change: 95/07/18 *
-********************************************************/
-
-
-#ifndef _EATA_DMA_H
-#define _EATA_DMA_H
-
-#ifndef HOSTS_C
-
-#include "eata_generic.h"
-
-
-#define VER_MAJOR 2
-#define VER_MINOR 5
-#define VER_SUB "8a"
-
-
-/************************************************************************
- * Here you can switch parts of the code on and of *
- ************************************************************************/
-
-#define CHECKPAL 0 /* EISA pal checking on/off */
-#define NEWSTUFF 0 /* Some changes for ISA/EISA boards */
-
-/************************************************************************
- * Debug options. *
- * Enable DEBUG and whichever options you require. *
- ************************************************************************/
-#define DEBUG_EATA 1 /* Enable debug code. */
-#define DPT_DEBUG 0 /* Bobs special */
-#define DBG_DELAY 0 /* Build in delays so debug messages can be
- * be read before they vanish of the top of
- * the screen! */
-#define DBG_PROBE 0 /* Debug probe routines. */
-#define DBG_PCI 0 /* Trace PCI routines */
-#define DBG_EISA 0 /* Trace EISA routines */
-#define DBG_ISA 0 /* Trace ISA routines */
-#define DBG_BLINK 0 /* Trace Blink check */
-#define DBG_PIO 0 /* Trace get_config_PIO */
-#define DBG_COM 0 /* Trace command call */
-#define DBG_QUEUE 0 /* Trace command queueing. */
-#define DBG_QUEUE2 0 /* Trace command queueing SG. */
-#define DBG_INTR 0 /* Trace interrupt service routine. */
-#define DBG_INTR2 0 /* Trace interrupt service routine. */
-#define DBG_INTR3 0 /* Trace get_board_data interrupts. */
-#define DBG_PROC 0 /* Debug proc-fs related statistics */
-#define DBG_PROC_WRITE 0
-#define DBG_REGISTER 0 /* */
-#define DBG_ABNORM 1 /* Debug abnormal actions (reset, abort)*/
-
-#if DEBUG_EATA
-#define DBG(x, y) if ((x)) {y;}
-#else
-#define DBG(x, y)
-#endif
-
-#endif /* !HOSTS_C */
-
-int eata_detect(Scsi_Host_Template *);
-const char *eata_info(struct Scsi_Host *);
-int eata_command(Scsi_Cmnd *);
-int eata_queue(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
-int eata_abort(Scsi_Cmnd *);
-int eata_reset(Scsi_Cmnd *);
-int eata_proc_info(char *, char **, off_t, int, int, int);
-#ifdef MODULE
-int eata_release(struct Scsi_Host *);
-#else
-#define eata_release NULL
-#endif
-
-#include <linux/scsicam.h>
-
-#define EATA_DMA { \
- NULL, NULL, \
- NULL, /* proc_dir_entry */ \
- eata_proc_info, /* procinfo */ \
- "EATA (Extended Attachment) HBA driver", \
- eata_detect, \
- eata_release, \
- NULL, NULL, \
- eata_queue, \
- eata_abort, \
- eata_reset, \
- NULL, /* Slave attach */ \
- scsicam_bios_param, \
- 0, /* Canqueue */ \
- 0, /* this_id */ \
- 0, /* sg_tablesize */ \
- 0, /* cmd_per_lun */ \
- 0, /* present */ \
- 1, /* True if ISA */ \
- ENABLE_CLUSTERING }
-
-
-#endif /* _EATA_DMA_H */
-
-/*
- * Overrides for Emacs so that we almost follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 4
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * c-continued-statement-offset: 4
- * c-continued-brace-offset: 0
- * indent-tabs-mode: nil
- * tab-width: 8
- * End:
- */
diff --git a/i386/i386at/gpl/linux/scsi/eata_dma_proc.h b/i386/i386at/gpl/linux/scsi/eata_dma_proc.h
deleted file mode 100644
index d49f348e..00000000
--- a/i386/i386at/gpl/linux/scsi/eata_dma_proc.h
+++ /dev/null
@@ -1,260 +0,0 @@
-
-struct lun_map {
- __u8 id:5,
- chan:3;
- __u8 lun;
-};
-
-typedef struct emul_pp {
- __u8 p_code:6,
- null:1,
- p_save:1;
- __u8 p_length;
- __u16 cylinder;
- __u8 heads;
- __u8 sectors;
- __u8 null2;
- __u8 s_lunmap:4,
- ems:1;
- __u16 drive_type; /* In Little Endian ! */
- struct lun_map lunmap[4];
-}emulpp;
-
-
-/* Log Sense pages */
-
-typedef struct log_sheader {
- __u8 page_code,
- reserved;
- __u16 length;
-}logsh;
-
-
-/* Log Sense Statistics */
-
-typedef struct read_command_statistics {
- __u16 code; /* 0x01 */
- __u8 flags;
- __u8 length; /* 0x24 */
- __u32 h_commands,
- uncached,
- la_cmds,
- la_blks,
- la_hits,
- missed,
- hits,
- seq_la_blks,
- seq_la_hits;
-}r_cmd_stat;
-
-typedef struct write_command_statistics {
- __u16 code; /* 0x03 */
- __u8 flags;
- __u8 length; /* 0x28 */
- __u32 h_commands,
- uncached,
- thru,
- bypass,
- soft_err,
- hits,
- b_idle,
- b_activ,
- b_blks,
- b_blks_clean;
-}w_cmd_stat;
-
-typedef struct host_command_statistics {
- __u16 code; /* 0x02, 0x04 */
- __u8 flags;
- __u8 length; /* 0x30 */
- __u32 sizes[12];
-}hst_cmd_stat;
-
-typedef struct physical_command_statistics {
- __u16 code; /* 0x06, 0x07 */
- __u8 flags;
- __u8 length; /* 0x34 */
- __u32 sizes[13];
-}phy_cmd_stat;
-
-typedef struct misc_device_statistics {
- __u16 code; /* 0x05 */
- __u8 flags;
- __u8 length; /* 0x10 */
- __u32 disconnect,
- pass_thru,
- sg_commands,
- stripe_boundary_crosses;
-}msc_stats;
-
-/* Configuration Pages */
-
-typedef struct controller_configuration {
- __u16 code; /* 0x01 */
- __u8 flags;
- __u8 length; /* 0x02 */
- __u8 intt:1,
- sec:1,
- csh:1,
- key:1,
- tmr:1,
- srs:1,
- nvr:1;
- __u8 interrupt;
-}coco;
-
-typedef struct controller_hardware_errors {
- __u16 code; /* 0x02 */
- __u8 flags;
- __u8 length; /* 0x02 */
- __u8 unused:1,
- per:1;
- __u8 interrupt;
-}coher;
-
-typedef struct memory_map {
- __u16 code; /* 0x03, 0x04 */
- __u8 flags;
- __u8 length; /* 0x04 */
- __u32 memory_map;
-}mema;
-
-typedef struct scsi_transfer {
- __u16 code; /* 0x05 */
- __u8 flags;
- __u8 length; /* 0x04 */
- __u8 offset,
- period;
- __u16 speed;
-}scsitrans;
-
-typedef struct scsi_modes {
- __u16 code; /* 0x06 */
- __u8 flags;
- __u8 length; /* 0x02 */
- __u8 que:1,
- cdis:1,
- wtru:1,
- dasd:1,
- ncr:1,
- awre:1;
- __u8 reserved;
-}scsimod;
-
-typedef struct host_bus {
- __u16 code; /* 0x07 */
- __u8 flags;
- __u8 length; /* 0x02 */
- __u8 speed:6,
- pci:1,
- eisa:1;
- __u8 reserved;
-}hobu;
-
-typedef struct scsi_bus {
- __u16 code; /* 0x08 */
- __u8 flags;
- __u8 length; /* 0x02 */
- __u8 speed:4,
- res:1,
- ext:1,
- wide:1,
- dif:1;
- __u8 busnum;
-}scbu;
-
-typedef struct board_type {
- __u16 code; /* 0x09 */
- __u8 flags;
- __u8 length; /* 0x04 */
- __u8 unused:1,
- cmi:1,
- dmi:1,
- cm4k:1,
- cm4:1,
- dm4k:1,
- dm4:1,
- hba:1;
- __u8 cpu_type,
- cpu_speed;
- __u8 sx1:1,
- sx2:1,
- unused2:4,
- alrm:1,
- srom:1;
-}boty;
-
-typedef struct memory_config {
- __u16 code; /* 0x0a */
- __u8 flags;
- __u8 length; /* 0x04 */
- __u8 banksize[4];
-}memco;
-
-typedef struct firmware_info {
- __u16 code; /* 0x0b */
- __u8 flags;
- __u8 length; /* 0x04 */
- __u8 dnld:1,
- bs528:1,
- fmt:1,
- fw528:1;
- __u8 unused1,
- fw_type,
- unused;
-}firm;
-
-typedef struct subsystem_info {
- __u16 code; /* 0x0c */
- __u8 flags;
- __u8 length; /* 0x02 */
- __u8 shlf:1,
- swap:1,
- noss:1;
- __u8 reserved;
-}subinf;
-
-typedef struct per_channel_info {
- __u16 code; /* 0x0d */
- __u8 flags;
- __u8 length; /* 0x02 */
- __u8 channel;
- __u8 shlf:1,
- swap:1,
- noss:1,
- srs:1,
- que:1,
- ext:1,
- wide:1,
- diff:1;
-}pcinf;
-
-typedef struct array_limits {
- __u16 code; /* 0x0e */
- __u8 flags;
- __u8 length; /* 0x04 */
- __u8 max_groups,
- raid0_drv,
- raid35_drv,
- unused;
-}arrlim;
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 4
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * c-continued-statement-offset: 4
- * c-continued-brace-offset: 0
- * indent-tabs-mode: nil
- * tab-width: 8
- * End:
- */
-
diff --git a/i386/i386at/gpl/linux/scsi/eata_dma_proc.src b/i386/i386at/gpl/linux/scsi/eata_dma_proc.src
deleted file mode 100644
index b4936a67..00000000
--- a/i386/i386at/gpl/linux/scsi/eata_dma_proc.src
+++ /dev/null
@@ -1,488 +0,0 @@
-
-void swap_statistics(u8 *p)
-{
- u32 y;
- u32 *lp, h_lp;
- u16 *sp, h_sp;
- u8 *bp;
-
- lp = (u32 *)p;
- sp = ((short *)lp) + 1; /* Convert Header */
- h_sp = *sp = ntohs(*sp);
- lp++;
-
- do {
- sp = (u16 *)lp; /* Convert SubHeader */
- *sp = ntohs(*sp);
- bp = (u8 *) lp;
- y = *(bp + 3);
- lp++;
- for (h_lp = (u32)lp; (u32)lp < h_lp + ((u32)*(bp + 3)); lp++)
- *lp = ntohl(*lp);
- }while ((u32)lp < ((u32)p) + 4 + h_sp);
-
-}
-
-/*
- * eata_set_info
- * buffer : pointer to the data that has been written to the hostfile
- * length : number of bytes written to the hostfile
- * HBA_ptr: pointer to the Scsi_Host struct
- */
-int eata_set_info(char *buffer, int length, struct Scsi_Host *HBA_ptr)
-{
- int orig_length = length;
-
- if (length >= 8 && strncmp(buffer, "eata_dma", 8) == 0) {
- buffer += 9;
- length -= 9;
- if(length >= 8 && strncmp(buffer, "latency", 7) == 0) {
- SD(HBA_ptr)->do_latency = TRUE;
- return(orig_length);
- }
-
- if(length >=10 && strncmp(buffer, "nolatency", 9) == 0) {
- SD(HBA_ptr)->do_latency = FALSE;
- return(orig_length);
- }
-
- printk("Unknown command:%s length: %d\n", buffer, length);
- } else
- printk("Wrong Signature:%10s\n", buffer);
-
- return(-EINVAL);
-}
-
-/*
- * eata_proc_info
- * inout : decides on the direction of the dataflow and the meaning of the
- * variables
- * buffer: If inout==FALSE data is beeing written to it else read from it
- * *start: If inout==FALSE start of the valid data in the buffer
- * offset: If inout==FALSE offset from the beginning of the imaginary file
- * from which we start writing into the buffer
- * length: If inout==FALSE max number of bytes to be written into the buffer
- * else number of bytes in the buffer
- */
-int eata_proc_info(char *buffer, char **start, off_t offset, int length,
- int hostno, int inout)
-{
-
- Scsi_Device *scd, SDev;
- struct Scsi_Host *HBA_ptr;
- Scsi_Cmnd scmd;
- char cmnd[10];
- static u8 buff[512];
- static u8 buff2[512];
- hst_cmd_stat *rhcs, *whcs;
- coco *cc;
- scsitrans *st;
- scsimod *sm;
- hobu *hb;
- scbu *sb;
- boty *bt;
- memco *mc;
- firm *fm;
- subinf *si;
- pcinf *pi;
- arrlim *al;
- int i, x;
- int size, len = 0;
- off_t begin = 0;
- off_t pos = 0;
- scd = NULL;
-
- HBA_ptr = first_HBA;
- for (i = 1; i <= registered_HBAs; i++) {
- if (HBA_ptr->host_no == hostno)
- break;
- HBA_ptr = SD(HBA_ptr)->next;
- }
-
- if(inout == TRUE) /* Has data been writen to the file ? */
- return(eata_set_info(buffer, length, HBA_ptr));
-
- if (offset == 0)
- memset(buff, 0, sizeof(buff));
-
- cc = (coco *) (buff + 0x148);
- st = (scsitrans *)(buff + 0x164);
- sm = (scsimod *) (buff + 0x16c);
- hb = (hobu *) (buff + 0x172);
- sb = (scbu *) (buff + 0x178);
- bt = (boty *) (buff + 0x17e);
- mc = (memco *) (buff + 0x186);
- fm = (firm *) (buff + 0x18e);
- si = (subinf *) (buff + 0x196);
- pi = (pcinf *) (buff + 0x19c);
- al = (arrlim *) (buff + 0x1a2);
-
- size = sprintf(buffer+len, "EATA (Extended Attachment) driver version: "
- "%d.%d%s\n",VER_MAJOR, VER_MINOR, VER_SUB);
- len += size; pos = begin + len;
- size = sprintf(buffer + len, "queued commands: %10ld\n"
- "processed interrupts:%10ld\n", queue_counter, int_counter);
- len += size; pos = begin + len;
-
- size = sprintf(buffer + len, "\nscsi%-2d: HBA %.10s\n",
- HBA_ptr->host_no, SD(HBA_ptr)->name);
- len += size;
- pos = begin + len;
- size = sprintf(buffer + len, "Firmware revision: v%s\n",
- SD(HBA_ptr)->revision);
- len += size;
- pos = begin + len;
- size = sprintf(buffer + len, "Hardware Configuration:\n");
- len += size;
- pos = begin + len;
-
- if(SD(HBA_ptr)->broken_INQUIRY == TRUE) {
- if (HBA_ptr->dma_channel == BUSMASTER)
- size = sprintf(buffer + len, "DMA: BUSMASTER\n");
- else
- size = sprintf(buffer + len, "DMA: %d\n", HBA_ptr->dma_channel);
- len += size;
- pos = begin + len;
-
- size = sprintf(buffer + len, "Base IO : %#.4x\n", (u32) HBA_ptr->base);
- len += size;
- pos = begin + len;
-
- size = sprintf(buffer + len, "Host Bus: EISA\n");
- len += size;
- pos = begin + len;
-
- } else {
- memset(&SDev, 0, sizeof(Scsi_Device));
- memset(&scmd, 0, sizeof(Scsi_Cmnd));
-
- SDev.host = HBA_ptr;
- SDev.id = HBA_ptr->this_id;
- SDev.lun = 0;
- SDev.channel = 0;
-
- cmnd[0] = LOG_SENSE;
- cmnd[1] = 0;
- cmnd[2] = 0x33 + (3<<6);
- cmnd[3] = 0;
- cmnd[4] = 0;
- cmnd[5] = 0;
- cmnd[6] = 0;
- cmnd[7] = 0x00;
- cmnd[8] = 0x66;
- cmnd[9] = 0;
-
- scmd.cmd_len = 10;
-
- scmd.host = HBA_ptr;
- scmd.device = &SDev;
- scmd.target = HBA_ptr->this_id;
- scmd.lun = 0;
- scmd.channel = 0;
- scmd.use_sg = 0;
-
- /*
- * Do the command and wait for it to finish.
- */
- {
- struct semaphore sem = MUTEX_LOCKED;
- scmd.request.rq_status = RQ_SCSI_BUSY;
- scmd.request.sem = &sem;
- scsi_do_cmd (&scmd, cmnd, buff + 0x144, 0x66,
- eata_scsi_done, 1 * HZ, 1);
- down(&sem);
- }
-
- size = sprintf(buffer + len, "IRQ: %2d, %s triggered\n", cc->interrupt,
- (cc->intt == TRUE)?"level":"edge");
- len += size;
- pos = begin + len;
- if (HBA_ptr->dma_channel == 0xff)
- size = sprintf(buffer + len, "DMA: BUSMASTER\n");
- else
- size = sprintf(buffer + len, "DMA: %d\n", HBA_ptr->dma_channel);
- len += size;
- pos = begin + len;
- size = sprintf(buffer + len, "CPU: MC680%02d %dMHz\n", bt->cpu_type,
- bt->cpu_speed);
- len += size;
- pos = begin + len;
- size = sprintf(buffer + len, "Base IO : %#.4x\n", (u32) HBA_ptr->base);
- len += size;
- pos = begin + len;
- size = sprintf(buffer + len, "Host Bus: %s\n",
- (SD(HBA_ptr)->bustype == IS_PCI)?"PCI ":
- (SD(HBA_ptr)->bustype == IS_EISA)?"EISA":"ISA ");
-
- len += size;
- pos = begin + len;
- size = sprintf(buffer + len, "SCSI Bus:%s%s Speed: %sMB/sec. %s\n",
- (sb->wide == TRUE)?" WIDE":"",
- (sb->dif == TRUE)?" DIFFERENTIAL":"",
- (sb->speed == 0)?"5":(sb->speed == 1)?"10":"20",
- (sb->ext == TRUE)?"With external cable detection":"");
- len += size;
- pos = begin + len;
- size = sprintf(buffer + len, "SCSI channel expansion Module: %s present\n",
- (bt->sx1 == TRUE)?"SX1 (one channel)":
- ((bt->sx2 == TRUE)?"SX2 (two channels)":"not"));
- len += size;
- pos = begin + len;
- size = sprintf(buffer + len, "SmartRAID hardware: %spresent.\n",
- (cc->srs == TRUE)?"":"not ");
- len += size;
- pos = begin + len;
- size = sprintf(buffer + len, " Type: %s\n",
- ((cc->key == TRUE)?((bt->dmi == TRUE)?"integrated"
- :((bt->dm4 == TRUE)?"DM401X"
- :(bt->dm4k == TRUE)?"DM4000"
- :"-"))
- :"-"));
- len += size;
- pos = begin + len;
-
- size = sprintf(buffer + len, " Max array groups: %d\n",
- (al->code == 0x0e)?al->max_groups:7);
- len += size;
- pos = begin + len;
- size = sprintf(buffer + len, " Max drives per RAID 0 array: %d\n",
- (al->code == 0x0e)?al->raid0_drv:7);
- len += size;
- pos = begin + len;
- size = sprintf(buffer + len, " Max drives per RAID 3/5 array: %d\n",
- (al->code == 0x0e)?al->raid35_drv:7);
- len += size;
- pos = begin + len;
- size = sprintf(buffer + len, "Cache Module: %spresent.\n",
- (cc->csh)?"":"not ");
- len += size;
- pos = begin + len;
- size = sprintf(buffer + len, " Type: %s\n",
- ((cc->csh == TRUE)?((bt->cmi == TRUE)?"integrated"
- :((bt->cm4 == TRUE)?"CM401X"
- :((bt->cm4k == TRUE)?"CM4000"
- :"-")))
- :"-"));
- len += size;
- pos = begin + len;
- for (x = 0; x <= 3; x++) {
- size = sprintf(buffer + len, " Bank%d: %dMB with%s ECC\n",x,
- mc->banksize[x] & 0x7f,
- (mc->banksize[x] & 0x80)?"":"out");
- len += size;
- pos = begin + len;
- }
- size = sprintf(buffer + len, "Timer Mod.: %spresent\n",
- (cc->tmr == TRUE)?"":"not ");
- len += size;
- pos = begin + len;
- size = sprintf(buffer + len, "NVRAM : %spresent\n",
- (cc->nvr == TRUE)?"":"not ");
- len += size;
- pos = begin + len;
- size = sprintf(buffer + len, "SmartROM : %sabled\n",
- (bt->srom == TRUE)?"dis":"en");
- len += size;
- pos = begin + len;
- size = sprintf(buffer + len, "Alarm : %s\n",
- (bt->alrm == TRUE)?"on":"off");
- len += size;
- pos = begin + len;
-
- if (pos < offset) {
- len = 0;
- begin = pos;
- }
- if (pos > offset + length)
- goto stop_output;
-
- cmnd[0] = LOG_SENSE;
- cmnd[1] = 0;
- cmnd[2] = 0x32 + (3<<6);
- cmnd[3] = 0;
- cmnd[4] = 0;
- cmnd[5] = 0;
- cmnd[6] = 0;
- cmnd[7] = 0x01;
- cmnd[8] = 0x44;
- cmnd[9] = 0;
-
- scmd.cmd_len = 10;
-
- /*
- * Do the command and wait for it to finish.
- */
- {
- struct semaphore sem = MUTEX_LOCKED;
- scmd.request.rq_status = RQ_SCSI_BUSY;
- scmd.request.sem = &sem;
- scsi_do_cmd (&scmd, cmnd, buff2, 0x144,
- eata_scsi_done, 1 * HZ, 1);
- down(&sem);
- }
-
- swap_statistics(buff2);
- rhcs = (hst_cmd_stat *)(buff2 + 0x2c);
- whcs = (hst_cmd_stat *)(buff2 + 0x8c);
-
- for (x = 0; x <= 11; x++) {
- SD(HBA_ptr)->reads[x] += rhcs->sizes[x];
- SD(HBA_ptr)->writes[x] += whcs->sizes[x];
- SD(HBA_ptr)->reads[12] += rhcs->sizes[x];
- SD(HBA_ptr)->writes[12] += whcs->sizes[x];
- }
- size = sprintf(buffer + len, "Host<->Disk command statistics:\n"
- " Reads: Writes:\n");
- len += size;
- pos = begin + len;
- for (x = 0; x <= 10; x++) {
- size = sprintf(buffer+len,"%5dk:%12u %12u\n", 1 << x,
- SD(HBA_ptr)->reads[x],
- SD(HBA_ptr)->writes[x]);
- len += size;
- pos = begin + len;
- }
- size = sprintf(buffer+len,">1024k:%12u %12u\n",
- SD(HBA_ptr)->reads[11],
- SD(HBA_ptr)->writes[11]);
- len += size;
- pos = begin + len;
- size = sprintf(buffer+len,"Sum :%12u %12u\n",
- SD(HBA_ptr)->reads[12],
- SD(HBA_ptr)->writes[12]);
- len += size;
- pos = begin + len;
- }
-
- if (pos < offset) {
- len = 0;
- begin = pos;
- }
- if (pos > offset + length)
- goto stop_output;
-
- if(SD(HBA_ptr)->do_latency == TRUE) {
- size = sprintf(buffer + len, "Host Latency Command Statistics:\n"
- "Current timer resolution: 10ms\n"
- " Reads: Min:(ms) Max:(ms) Ave:(ms)\n");
- len += size;
- pos = begin + len;
- for (x = 0; x <= 10; x++) {
- size = sprintf(buffer+len,"%5dk:%12u %12u %12u %12u\n",
- 1 << x,
- SD(HBA_ptr)->reads_lat[x][0],
- (SD(HBA_ptr)->reads_lat[x][1] == 0xffffffff)
- ? 0:(SD(HBA_ptr)->reads_lat[x][1] * 10),
- SD(HBA_ptr)->reads_lat[x][2] * 10,
- SD(HBA_ptr)->reads_lat[x][3] * 10 /
- ((SD(HBA_ptr)->reads_lat[x][0])
- ? SD(HBA_ptr)->reads_lat[x][0]:1));
- len += size;
- pos = begin + len;
- }
- size = sprintf(buffer+len,">1024k:%12u %12u %12u %12u\n",
- SD(HBA_ptr)->reads_lat[11][0],
- (SD(HBA_ptr)->reads_lat[11][1] == 0xffffffff)
- ? 0:(SD(HBA_ptr)->reads_lat[11][1] * 10),
- SD(HBA_ptr)->reads_lat[11][2] * 10,
- SD(HBA_ptr)->reads_lat[11][3] * 10 /
- ((SD(HBA_ptr)->reads_lat[x][0])
- ? SD(HBA_ptr)->reads_lat[x][0]:1));
- len += size;
- pos = begin + len;
-
- if (pos < offset) {
- len = 0;
- begin = pos;
- }
- if (pos > offset + length)
- goto stop_output;
-
- size = sprintf(buffer + len,
- " Writes: Min:(ms) Max:(ms) Ave:(ms)\n");
- len += size;
- pos = begin + len;
- for (x = 0; x <= 10; x++) {
- size = sprintf(buffer+len,"%5dk:%12u %12u %12u %12u\n",
- 1 << x,
- SD(HBA_ptr)->writes_lat[x][0],
- (SD(HBA_ptr)->writes_lat[x][1] == 0xffffffff)
- ? 0:(SD(HBA_ptr)->writes_lat[x][1] * 10),
- SD(HBA_ptr)->writes_lat[x][2] * 10,
- SD(HBA_ptr)->writes_lat[x][3] * 10 /
- ((SD(HBA_ptr)->writes_lat[x][0])
- ? SD(HBA_ptr)->writes_lat[x][0]:1));
- len += size;
- pos = begin + len;
- }
- size = sprintf(buffer+len,">1024k:%12u %12u %12u %12u\n",
- SD(HBA_ptr)->writes_lat[11][0],
- (SD(HBA_ptr)->writes_lat[11][1] == 0xffffffff)
- ? 0:(SD(HBA_ptr)->writes_lat[x][1] * 10),
- SD(HBA_ptr)->writes_lat[11][2] * 10,
- SD(HBA_ptr)->writes_lat[11][3] * 10/
- ((SD(HBA_ptr)->writes_lat[x][0])
- ? SD(HBA_ptr)->writes_lat[x][0]:1));
- len += size;
- pos = begin + len;
-
- if (pos < offset) {
- len = 0;
- begin = pos;
- }
- if (pos > offset + length)
- goto stop_output;
- }
-
-#if 0
- scd = scsi_devices;
-
- size = sprintf(buffer+len,"Attached devices: %s\n", (scd)?"":"none");
- len += size;
- pos = begin + len;
-
- while (scd) {
- if (scd->host == HBA_ptr) {
- proc_print_scsidevice(scd, buffer, &size, len);
- len += size;
- pos = begin + len;
-
- if (pos < offset) {
- len = 0;
- begin = pos;
- }
- if (pos > offset + length)
- goto stop_output;
- }
- scd = scd->next;
- }
-#endif
-
- stop_output:
- DBG(DBG_PROC, printk("2pos: %ld offset: %ld len: %d\n", pos, offset, len));
- *start=buffer+(offset-begin); /* Start of wanted data */
- len-=(offset-begin); /* Start slop */
- if(len>length)
- len = length; /* Ending slop */
- DBG(DBG_PROC, printk("3pos: %ld offset: %ld len: %d\n", pos, offset, len));
-
- return (len);
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 4
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * c-continued-statement-offset: 4
- * c-continued-brace-offset: 0
- * tab-width: 8
- * End:
- */
diff --git a/i386/i386at/gpl/linux/scsi/eata_generic.h b/i386/i386at/gpl/linux/scsi/eata_generic.h
deleted file mode 100644
index 4d9fc497..00000000
--- a/i386/i386at/gpl/linux/scsi/eata_generic.h
+++ /dev/null
@@ -1,397 +0,0 @@
-/********************************************************
-* Header file for eata_dma.c and eata_pio.c *
-* Linux EATA SCSI drivers *
-* (c) 1993,94,95 Michael Neuffer *
-*********************************************************
-* last change: 95/11/07 *
-********************************************************/
-
-
-#ifndef _EATA_GENERIC_H
-#define _EATA_GENERIC_H
-
-
-
-/*********************************************
- * Misc. definitions *
- *********************************************/
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#define min(a,b) ((a<b)?(a):(b))
-
-#define R_LIMIT 0x20000
-
-#define MAXISA 4
-#define MAXEISA 16
-#define MAXPCI 16
-#define MAXIRQ 16
-#define MAXTARGET 16
-#define MAXCHANNEL 3
-
-#define IS_ISA 'I'
-#define IS_EISA 'E'
-#define IS_PCI 'P'
-
-#define BROKEN_INQUIRY 1
-
-#define BUSMASTER 0xff
-#define PIO 0xfe
-
-#define EATA_SIGNATURE 0x45415441 /* BIG ENDIAN coded "EATA" sig. */
-
-#define DPT_ID1 0x12
-#define DPT_ID2 0x14
-
-#define ATT_ID1 0x06
-#define ATT_ID2 0x94
-#define ATT_ID3 0x0
-
-#define NEC_ID1 0x38
-#define NEC_ID2 0xa3
-#define NEC_ID3 0x82
-
-
-#define EATA_CP_SIZE 44
-
-#define MAX_PCI_DEVICES 32 /* Maximum # Of Devices Per Bus */
-#define MAX_METHOD_2 16 /* Max Devices For Method 2 */
-#define MAX_PCI_BUS 16 /* Maximum # Of Busses Allowed */
-
-#define SG_SIZE 64
-#define SG_SIZE_BIG 509 /* max. 509 elements, one 4k page */
-
-#define C_P_L_DIV 2 /* 1 <= C_P_L_DIV <= 8
- * You can use this parameter to fine-tune
- * the driver. Depending on the number of
- * devices and their speed and ability to queue
- * commands, you will get the best results with a
- * value
- * ~= numdevices-(devices_unable_to_queue_commands/2)
- * The reason for this is that the disk driver
- * tends to flood the queue, so that other
- * drivers have problems to queue commands
- * themselves. This can for example result in
- * the effect that the tape stops during disk
- * accesses.
- */
-
-#define FREE 0
-#define OK 0
-#define NO_TIMEOUT 0
-#define USED 1
-#define TIMEOUT 2
-#define RESET 4
-#define LOCKED 8
-
-#define HD(cmd) ((hostdata *)&(cmd->host->hostdata))
-#define CD(cmd) ((struct eata_ccb *)(cmd->host_scribble))
-#define SD(host) ((hostdata *)&(host->hostdata))
-
-#define DELAY(x) { __u32 i; i = jiffies + (x * HZ); while (jiffies < i) barrier(); }
-#define DEL2(x) { __u32 i; for (i = 0; i < 0xffff * x; i++); }
-
-/***********************************************
- * EATA Command & Register definitions *
- ***********************************************/
-#define PCI_REG_DPTconfig 0x40
-#define PCI_REG_PumpModeAddress 0x44
-#define PCI_REG_PumpModeData 0x48
-#define PCI_REG_ConfigParam1 0x50
-#define PCI_REG_ConfigParam2 0x54
-
-
-#define EATA_CMD_PIO_SETUPTEST 0xc6
-#define EATA_CMD_PIO_READ_CONFIG 0xf0
-#define EATA_CMD_PIO_SET_CONFIG 0xf1
-#define EATA_CMD_PIO_SEND_CP 0xf2
-#define EATA_CMD_PIO_RECEIVE_SP 0xf3
-#define EATA_CMD_PIO_TRUNC 0xf4
-
-#define EATA_CMD_RESET 0xf9
-#define EATA_CMD_IMMEDIATE 0xfa
-
-#define EATA_CMD_DMA_READ_CONFIG 0xfd
-#define EATA_CMD_DMA_SET_CONFIG 0xfe
-#define EATA_CMD_DMA_SEND_CP 0xff
-
-#define ECS_EMULATE_SENSE 0xd4
-
-#define EATA_GENERIC_ABORT 0x00
-#define EATA_SPECIFIC_RESET 0x01
-#define EATA_BUS_RESET 0x02
-#define EATA_SPECIFIC_ABORT 0x03
-#define EATA_QUIET_INTR 0x04
-#define EATA_COLD_BOOT_HBA 0x06 /* Only as a last resort */
-#define EATA_FORCE_IO 0x07
-
-
-#define HA_WCOMMAND 0x07 /* command register offset */
-#define HA_WCOMMAND2 0x06 /* immediate command offset */
-#define HA_WSUBCODE 0x05
-#define HA_WSUBLUN 0x04
-#define HA_WDMAADDR 0x02 /* DMA address LSB offset */
-#define HA_RAUXSTAT 0x08 /* aux status register offset*/
-#define HA_RSTATUS 0x07 /* status register offset */
-#define HA_RDATA 0x00 /* data register (16bit) */
-
-#define HA_ABUSY 0x01 /* aux busy bit */
-#define HA_AIRQ 0x02 /* aux IRQ pending bit */
-#define HA_SERROR 0x01 /* pr. command ended in error*/
-#define HA_SMORE 0x02 /* more data soon to come */
-#define HA_SCORR 0x04 /* data corrected */
-#define HA_SDRQ 0x08 /* data request active */
-#define HA_SSC 0x10 /* seek complete */
-#define HA_SFAULT 0x20 /* write fault */
-#define HA_SREADY 0x40 /* drive ready */
-#define HA_SBUSY 0x80 /* drive busy */
-#define HA_SDRDY HA_SSC+HA_SREADY+HA_SDRQ
-
-/**********************************************
- * Message definitions *
- **********************************************/
-
-#define HA_NO_ERROR 0x00 /* No Error */
-#define HA_ERR_SEL_TO 0x01 /* Selection Timeout */
-#define HA_ERR_CMD_TO 0x02 /* Command Timeout */
-#define HA_ERR_RESET 0x03 /* SCSI Bus Reset Received */
-#define HA_INIT_POWERUP 0x04 /* Initial Controller Power-up */
-#define HA_UNX_BUSPHASE 0x05 /* Unexpected Bus Phase */
-#define HA_UNX_BUS_FREE 0x06 /* Unexpected Bus Free */
-#define HA_BUS_PARITY 0x07 /* Bus Parity Error */
-#define HA_SCSI_HUNG 0x08 /* SCSI Hung */
-#define HA_UNX_MSGRJCT 0x09 /* Unexpected Message Rejected */
-#define HA_RESET_STUCK 0x0a /* SCSI Bus Reset Stuck */
-#define HA_RSENSE_FAIL 0x0b /* Auto Request-Sense Failed */
-#define HA_PARITY_ERR 0x0c /* Controller Ram Parity Error */
-#define HA_CP_ABORT_NA 0x0d /* Abort Message sent to non-active cmd */
-#define HA_CP_ABORTED 0x0e /* Abort Message sent to active cmd */
-#define HA_CP_RESET_NA 0x0f /* Reset Message sent to non-active cmd */
-#define HA_CP_RESET 0x10 /* Reset Message sent to active cmd */
-#define HA_ECC_ERR 0x11 /* Controller Ram ECC Error */
-#define HA_PCI_PARITY 0x12 /* PCI Parity Error */
-#define HA_PCI_MABORT 0x13 /* PCI Master Abort */
-#define HA_PCI_TABORT 0x14 /* PCI Target Abort */
-#define HA_PCI_STABORT 0x15 /* PCI Signaled Target Abort */
-
-/**********************************************
- * Other definitions *
- **********************************************/
-
-struct reg_bit { /* reading this one will clear the interrupt */
- __u8 error:1; /* previous command ended in an error */
- __u8 more:1; /* more DATA coming soon, poll BSY & DRQ (PIO) */
- __u8 corr:1; /* data read was successfully corrected with ECC*/
- __u8 drq:1; /* data request active */
- __u8 sc:1; /* seek complete */
- __u8 fault:1; /* write fault */
- __u8 ready:1; /* drive ready */
- __u8 busy:1; /* controller busy */
-};
-
-struct reg_abit { /* reading this won't clear the interrupt */
- __u8 abusy:1; /* auxiliary busy */
- __u8 irq:1; /* set when drive interrupt is asserted */
- __u8 dummy:6;
-};
-
-struct eata_register { /* EATA register set */
- __u8 data_reg[2]; /* R, couldn't figure this one out */
- __u8 cp_addr[4]; /* W, CP address register */
- union {
- __u8 command; /* W, command code: [read|set] conf, send CP*/
- struct reg_bit status; /* R, see register_bit1 */
- __u8 statusbyte;
- } ovr;
- struct reg_abit aux_stat; /* R, see register_bit2 */
-};
-
-struct get_conf { /* Read Configuration Array */
- __u32 len; /* Should return 0x22, 0x24, etc */
- __u32 signature; /* Signature MUST be "EATA" */
- __u8 version2:4,
- version:4; /* EATA Version level */
- __u8 OCS_enabled:1, /* Overlap Command Support enabled */
- TAR_support:1, /* SCSI Target Mode supported */
- TRNXFR:1, /* Truncate Transfer Cmd not necessary *
- * Only used in PIO Mode */
- MORE_support:1, /* MORE supported (only PIO Mode) */
- DMA_support:1, /* DMA supported Driver uses only *
- * this mode */
- DMA_valid:1, /* DRQ value in Byte 30 is valid */
- ATA:1, /* ATA device connected (not supported) */
- HAA_valid:1; /* Hostadapter Address is valid */
-
- __u16 cppadlen; /* Number of pad bytes send after CD data *
- * set to zero for DMA commands */
- __u8 scsi_id[4]; /* SCSI ID of controller 2-0 Byte 0 res. *
- * if not, zero is returned */
- __u32 cplen; /* CP length: number of valid cp bytes */
- __u32 splen; /* Number of bytes returned after *
- * Receive SP command */
- __u16 queuesiz; /* max number of queueable CPs */
- __u16 dummy;
- __u16 SGsiz; /* max number of SG table entries */
- __u8 IRQ:4, /* IRQ used this HA */
- IRQ_TR:1, /* IRQ Trigger: 0=edge, 1=level */
- SECOND:1, /* This is a secondary controller */
- DMA_channel:2; /* DRQ index, DRQ is 2comp of DRQX */
- __u8 sync; /* device at ID 7 tru 0 is running in *
- * synchronous mode, this will disappear */
- __u8 DSBLE:1, /* ISA i/o addressing is disabled */
- FORCADR:1, /* i/o address has been forced */
- SG_64K:1,
- SG_UAE:1,
- :4;
- __u8 MAX_ID:5, /* Max number of SCSI target IDs */
- MAX_CHAN:3; /* Number of SCSI busses on HBA */
- __u8 MAX_LUN; /* Max number of LUNs */
- __u8 :3,
- AUTOTRM:1,
- M1_inst:1,
- ID_qest:1, /* Raidnum ID is questionable */
- is_PCI:1, /* HBA is PCI */
- is_EISA:1; /* HBA is EISA */
- __u8 unused[478];
-};
-
-struct eata_sg_list
-{
- __u32 data;
- __u32 len;
-};
-
-struct eata_ccb { /* Send Command Packet structure */
-
- __u8 SCSI_Reset:1, /* Cause a SCSI Bus reset on the cmd */
- HBA_Init:1, /* Cause Controller to reinitialize */
- Auto_Req_Sen:1, /* Do Auto Request Sense on errors */
- scatter:1, /* Data Ptr points to a SG Packet */
- Resrvd:1, /* RFU */
- Interpret:1, /* Interpret the SCSI cdb of own use */
- DataOut:1, /* Data Out phase with command */
- DataIn:1; /* Data In phase with command */
- __u8 reqlen; /* Request Sense Length *
- * Valid if Auto_Req_Sen=1 */
- __u8 unused[3];
- __u8 FWNEST:1, /* send cmd to phys RAID component */
- unused2:7;
- __u8 Phsunit:1, /* physical unit on mirrored pair */
- I_AT:1, /* inhibit address translation */
- I_HBA_C:1, /* HBA inhibit caching */
- unused3:5;
-
- __u8 cp_id:5, /* SCSI Device ID of target */
- cp_channel:3; /* SCSI Channel # of HBA */
- __u8 cp_lun:3,
- :2,
- cp_luntar:1, /* CP is for target ROUTINE */
- cp_dispri:1, /* Grant disconnect privilege */
- cp_identify:1; /* Always TRUE */
- __u8 cp_msg1; /* Message bytes 0-3 */
- __u8 cp_msg2;
- __u8 cp_msg3;
- __u8 cp_cdb[12]; /* Command Descriptor Block */
- __u32 cp_datalen; /* Data Transfer Length *
- * If scatter=1 len of sg package */
- void *cp_viraddr; /* address of this ccb */
- __u32 cp_dataDMA; /* Data Address, if scatter=1 *
- * address of scatter packet */
- __u32 cp_statDMA; /* address for Status Packet */
- __u32 cp_reqDMA; /* Request Sense Address, used if *
- * CP command ends with error */
- /* Additional CP info begins here */
- __u32 timestamp; /* Needed to measure command latency */
- __u32 timeout;
- __u8 sizeindex;
- __u8 rw_latency;
- __u8 retries;
- __u8 status; /* status of this queueslot */
- Scsi_Cmnd *cmd; /* address of cmd */
- struct eata_sg_list *sg_list;
-};
-
-
-struct eata_sp {
- __u8 hba_stat:7, /* HBA status */
- EOC:1; /* True if command finished */
- __u8 scsi_stat; /* Target SCSI status */
- __u8 reserved[2];
- __u32 residue_len; /* Number of bytes not transferred */
- struct eata_ccb *ccb; /* Address set in COMMAND PACKET */
- __u8 msg[12];
-};
-
-typedef struct hstd {
- __u8 vendor[9];
- __u8 name[18];
- __u8 revision[6];
- __u8 EATA_revision;
- __u8 bustype; /* bustype of HBA */
- __u8 channel; /* # of avail. scsi channels */
- __u8 state; /* state of HBA */
- __u8 primary; /* true if primary */
- __u8 broken_INQUIRY:1; /* This is an EISA HBA with *
- * broken INQUIRY */
- __u8 do_latency; /* Latency measurement flag */
- __u32 reads[13];
- __u32 writes[13];
- __u32 reads_lat[12][4];
- __u32 writes_lat[12][4];
- /* state of Target (RESET,..) */
- __u8 t_state[MAXCHANNEL][MAXTARGET];
- /* timeouts on target */
- __u32 t_timeout[MAXCHANNEL][MAXTARGET];
- __u32 last_ccb; /* Last used ccb */
- __u32 cplen; /* size of CP in words */
- __u16 cppadlen; /* pad length of cp in words */
- __u8 hostid; /* SCSI ID of HBA */
- __u8 devflags; /* bits set for detected devices */
- __u8 moresupport; /* HBA supports MORE flag */
- struct Scsi_Host *next;
- struct Scsi_Host *prev;
- struct eata_sp sp; /* status packet */
- struct eata_ccb ccb[0]; /* ccb array begins here */
-}hostdata;
-
-/* structure for max. 2 emulated drives */
-struct drive_geom_emul {
- __u8 trans; /* translation flag 1=transl */
- __u8 channel; /* SCSI channel number */
- __u8 HBA; /* HBA number (prim/sec) */
- __u8 id; /* drive id */
- __u8 lun; /* drive lun */
- __u32 heads; /* number of heads */
- __u32 sectors; /* number of sectors */
- __u32 cylinder; /* number of cylinders */
-};
-
-struct geom_emul {
- __u8 bios_drives; /* number of emulated drives */
- struct drive_geom_emul drv[2]; /* drive structures */
-};
-
-#endif /* _EATA_GENERIC_H */
-
-/*
- * Overrides for Emacs so that we almost follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 4
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * c-continued-statement-offset: 4
- * c-continued-brace-offset: 0
- * tab-width: 8
- * End:
- */
diff --git a/i386/i386at/gpl/linux/scsi/eata_pio.c b/i386/i386at/gpl/linux/scsi/eata_pio.c
deleted file mode 100644
index 95248ae7..00000000
--- a/i386/i386at/gpl/linux/scsi/eata_pio.c
+++ /dev/null
@@ -1,1051 +0,0 @@
-/************************************************************
- * *
- * Linux EATA SCSI PIO driver *
- * *
- * based on the CAM document CAM/89-004 rev. 2.0c, *
- * DPT's driver kit, some internal documents and source, *
- * and several other Linux scsi drivers and kernel docs. *
- * *
- * The driver currently: *
- * -supports all EATA-PIO boards *
- * -only supports DASD devices *
- * *
- * (c)1993,94,95 Michael Neuffer, Alfred Arnold *
- * neuffer@goofy.zdv.uni-mainz.de *
- * a.arnold@kfa-juelich.de *
- * *
- * This program is free software; you can redistribute it *
- * and/or modify it under the terms of the GNU General *
- * Public License as published by the Free Software *
- * Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be *
- * useful, but WITHOUT ANY WARRANTY; without even the *
- * implied warranty of MERCHANTABILITY or FITNESS FOR A *
- * PARTICULAR PURPOSE. See the GNU General Public License *
- * for more details. *
- * *
- * You should have received a copy of the GNU General *
- * Public License along with this kernel; if not, write to *
- * the Free Software Foundation, Inc., 675 Mass Ave, *
- * Cambridge, MA 02139, USA. *
- * *
- ************************************************************
- * last change: 95/08/04 OS: Linux 1.3.15 *
- ************************************************************/
-
-/* Look in eata_pio.h for configuration information */
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/malloc.h>
-#include <linux/in.h>
-#include <linux/bios32.h>
-#include <linux/pci.h>
-#include <linux/proc_fs.h>
-#include <asm/io.h>
-#include "eata_pio.h"
-#include "eata_dma_proc.h"
-#include "scsi.h"
-#include "sd.h"
-
-#include <linux/stat.h>
-#include <linux/config.h> /* for CONFIG_PCI */
-
-struct proc_dir_entry proc_scsi_eata_pio = {
- PROC_SCSI_EATA_PIO, 9, "eata_pio",
- S_IFDIR | S_IRUGO | S_IXUGO, 2
-};
-
-static uint ISAbases[MAXISA] =
-{0x1F0, 0x170, 0x330, 0x230};
-static uint ISAirqs[MAXISA] =
-{14,12,15,11};
-static unchar EISAbases[] =
-{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
-static uint registered_HBAs = 0;
-static struct Scsi_Host *last_HBA = NULL;
-static struct Scsi_Host *first_HBA = NULL;
-static unchar reg_IRQ[] =
-{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-static unchar reg_IRQL[] =
-{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-
-static ulong int_counter = 0;
-static ulong queue_counter = 0;
-
-void hprint(const char *str)
-{
- char *hptr =(char *) 0x000b0000;
- char *hptr2=(char *) 0x000b00a0;
- char *hptr3=(char *) 0x000b0f00;
- int z;
-
- memmove(hptr,hptr2,24*80*2);
- for (z=0; z<strlen(str); z++)
- hptr3[z*2]=str[z];
- for (; z<80; z++)
- hptr3[z*2]=' ';
-}
-
-#ifdef MACH
-#include "eata_pio_proc.src"
-#else
-#include "eata_pio_proc.c"
-#endif
-
-#ifdef MODULE
-int eata_pio_release(struct Scsi_Host *sh)
-{
- if (sh->irq && reg_IRQ[sh->irq] == 1) free_irq(sh->irq);
- else reg_IRQ[sh->irq]--;
- if (SD(sh)->channel == 0) {
- if (sh->io_port && sh->n_io_port)
- release_region(sh->io_port, sh->n_io_port);
- }
- return(TRUE);
-}
-#endif
-
-void IncStat(Scsi_Pointer *SCp, uint Increment)
-{
- SCp->ptr+=Increment;
- if ((SCp->this_residual-=Increment)==0)
- {
- if ((--SCp->buffers_residual)==0) SCp->Status=FALSE;
- else
- {
- SCp->buffer++;
- SCp->ptr=SCp->buffer->address;
- SCp->this_residual=SCp->buffer->length;
- }
- }
-}
-
-void eata_pio_int_handler(int irq, struct pt_regs * regs)
-{
- uint eata_stat = 0xfffff;
- Scsi_Cmnd *cmd;
- hostdata *hd;
- struct eata_ccb *cp;
- uint base;
- ulong flags;
- uint x,z;
- struct Scsi_Host *sh;
- ushort zwickel=0;
- unchar stat,odd;
-
- save_flags(flags);
- cli();
-
- for (x = 1, sh = first_HBA; x <= registered_HBAs; x++, sh = SD(sh)->prev) {
- if (sh->irq != irq)
- continue;
- if (inb((uint)sh->base + HA_RSTATUS) & HA_SBUSY)
- continue;
-
- int_counter++;
-
- hd=SD(sh);
-
- cp = &hd->ccb[0];
- cmd = cp->cmd;
- base = (uint) cmd->host->base;
-
- do
- {
- stat=inb(base+HA_RSTATUS);
- if (stat&HA_SDRQ)
- if (cp->DataIn)
- {
- z=256; odd=FALSE;
- while ((cmd->SCp.Status)&&((z>0)||(odd)))
- {
- if (odd)
- {
- *(cmd->SCp.ptr)=zwickel>>8;
- IncStat(&cmd->SCp,1);
- odd=FALSE;
- }
- x=min(z,cmd->SCp.this_residual/2);
- insw(base+HA_RDATA,cmd->SCp.ptr,x);
- z-=x;
- IncStat(&cmd->SCp,2*x);
- if ((z>0)&&(cmd->SCp.this_residual==1))
- {
- zwickel=inw(base+HA_RDATA);
- *(cmd->SCp.ptr)=zwickel&0xff;
- IncStat(&cmd->SCp,1); z--;
- odd=TRUE;
- }
- }
- while (z>0) {
- zwickel=inw(base+HA_RDATA);
- z--;
- }
- }
- else /* cp->DataOut */
- {
- odd=FALSE; z=256;
- while ((cmd->SCp.Status)&&((z>0)||(odd)))
- {
- if (odd)
- {
- zwickel+=*(cmd->SCp.ptr)<<8;
- IncStat(&cmd->SCp,1);
- outw(zwickel,base+HA_RDATA);
- z--;
- odd=FALSE;
- }
- x=min(z,cmd->SCp.this_residual/2);
- outsw(base+HA_RDATA,cmd->SCp.ptr,x);
- z-=x;
- IncStat(&cmd->SCp,2*x);
- if ((z>0)&&(cmd->SCp.this_residual==1))
- {
- zwickel=*(cmd->SCp.ptr);
- zwickel&=0xff;
- IncStat(&cmd->SCp,1);
- odd=TRUE;
- }
- }
- while (z>0||odd) {
- outw(zwickel,base+HA_RDATA);
- z--;
- odd=FALSE;
- }
- }
- }
- while ((stat&HA_SDRQ)||((stat&HA_SMORE)&&hd->moresupport));
-
- /* terminate handler if HBA goes busy again, i.e. transfers
- * more data */
-
- if (stat&HA_SBUSY) break;
-
- /* OK, this is quite stupid, but I haven't found any correct
- * way to get HBA&SCSI status so far */
-
- if (!(inb(base+HA_RSTATUS)&HA_SERROR))
- {
- cmd->result=(DID_OK<<16);
- hd->devflags|=(1<<cp->cp_id);
- }
- else if (hd->devflags&1<<cp->cp_id)
- cmd->result=(DID_OK<<16)+0x02;
- else cmd->result=(DID_NO_CONNECT<<16);
-
- if (cp->status == LOCKED) {
- cp->status = FREE;
- eata_stat = inb(base + HA_RSTATUS);
- printk("eata_pio: int_handler, freeing locked queueslot\n");
- DBG(DBG_INTR&&DBG_DELAY,DEL2(800));
- restore_flags(flags);
- return;
- }
-
-#if DBG_INTR2
- if (stat != 0x50)
- printk("stat: %#.2x, result: %#.8x\n", stat, cmd->result);
- DBG(DBG_INTR&&DBG_DELAY,DEL2(800));
-#endif
-
- cp->status = FREE; /* now we can release the slot */
-
- restore_flags(flags);
- cmd->scsi_done(cmd);
- save_flags(flags);
- cli();
- }
- restore_flags(flags);
-
- return;
-}
-
-inline uint eata_pio_send_command(uint base, unchar command)
-{
- uint loop = R_LIMIT;
-
- while (inb(base + HA_RSTATUS) & HA_SBUSY)
- if (--loop == 0)
- return(TRUE);
-
- outb(command, base + HA_WCOMMAND);
- return(FALSE);
-}
-
-int eata_pio_queue(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
-{
- uint x, y;
- long flags;
- uint base;
-
- hostdata *hd;
- struct Scsi_Host *sh;
- struct eata_ccb *cp;
-
- save_flags(flags);
- cli();
-
- queue_counter++;
-
- hd = HD(cmd);
- sh = cmd->host;
- base = (uint) sh->base;
-
- /* use only slot 0, as 2001 can handle only one cmd at a time */
-
- y = x = 0;
-
- if (hd->ccb[y].status!=FREE) {
-
- DBG(DBG_QUEUE, printk("can_queue %d, x %d, y %d\n",sh->can_queue,x,y));
-#if DEBUG_EATA
- panic("eata_pio: run out of queue slots cmdno:%ld intrno: %ld\n",
- queue_counter, int_counter);
-#else
- panic("eata_pio: run out of queue slots....\n");
-#endif
- }
-
- cp = &hd->ccb[y];
-
- memset(cp, 0, sizeof(struct eata_ccb));
- memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer));
-
- cp->status = USED; /* claim free slot */
-
- DBG(DBG_QUEUE, printk("eata_pio_queue pid %ld, target: %x, lun: %x, y %d\n",
- cmd->pid, cmd->target, cmd->lun, y));
- DBG(DBG_QUEUE && DBG_DELAY, DEL2(250));
-
- cmd->scsi_done = (void *)done;
-
- switch (cmd->cmnd[0]) {
- case CHANGE_DEFINITION: case COMPARE: case COPY:
- case COPY_VERIFY: case LOG_SELECT: case MODE_SELECT:
- case MODE_SELECT_10: case SEND_DIAGNOSTIC: case WRITE_BUFFER:
- case FORMAT_UNIT: case REASSIGN_BLOCKS: case RESERVE:
- case SEARCH_EQUAL: case SEARCH_HIGH: case SEARCH_LOW:
- case WRITE_6: case WRITE_10: case WRITE_VERIFY:
- case UPDATE_BLOCK: case WRITE_LONG: case WRITE_SAME:
- case SEARCH_HIGH_12: case SEARCH_EQUAL_12: case SEARCH_LOW_12:
- case WRITE_12: case WRITE_VERIFY_12: case SET_WINDOW:
- case MEDIUM_SCAN: case SEND_VOLUME_TAG:
- case 0xea: /* alternate number for WRITE LONG */
- cp->DataOut = TRUE; /* Output mode */
- break;
- case TEST_UNIT_READY:
- default:
- cp->DataIn = TRUE; /* Input mode */
- }
-
- cp->Interpret = (cmd->target == hd->hostid);
- cp->cp_datalen = htonl((ulong)cmd->request_bufflen);
- cp->Auto_Req_Sen = FALSE;
- cp->cp_reqDMA = htonl(0);
- cp->reqlen = 0;
-
- cp->cp_id = cmd->target;
- cp->cp_lun = cmd->lun;
- cp->cp_dispri = FALSE;
- cp->cp_identify = TRUE;
- memcpy(cp->cp_cdb, cmd->cmnd, COMMAND_SIZE(*cmd->cmnd));
-
- cp->cp_statDMA = htonl(0);
-
- cp->cp_viraddr = cp;
- cp->cmd = cmd;
- cmd->host_scribble = (char *)&hd->ccb[y];
-
- if (cmd->use_sg == 0)
- {
- cmd->SCp.buffers_residual=1;
- cmd->SCp.ptr = cmd->request_buffer;
- cmd->SCp.this_residual = cmd->request_bufflen;
- cmd->SCp.buffer = NULL;
- } else {
- cmd->SCp.buffer = cmd->request_buffer;
- cmd->SCp.buffers_residual = cmd->use_sg;
- cmd->SCp.ptr = cmd->SCp.buffer->address;
- cmd->SCp.this_residual = cmd->SCp.buffer->length;
- }
- cmd->SCp.Status = (cmd->SCp.this_residual != 0); /* TRUE as long as bytes
- * are to transfer */
-
- if (eata_pio_send_command(base, EATA_CMD_PIO_SEND_CP))
- {
- cmd->result = DID_BUS_BUSY << 16;
- printk("eata_pio_queue target %d, pid %ld, HBA busy, returning "
- "DID_BUS_BUSY, done.\n", cmd->target, cmd->pid);
- done(cmd);
- cp->status = FREE;
- restore_flags(flags);
- return (0);
- }
- while (!(inb(base + HA_RSTATUS) & HA_SDRQ));
- outsw(base + HA_RDATA, cp, hd->cplen);
- outb(EATA_CMD_PIO_TRUNC, base + HA_WCOMMAND);
- for (x = 0; x < hd->cppadlen; x++) outw(0, base + HA_RDATA);
-
- DBG(DBG_QUEUE,printk("Queued base %#.4lx pid: %ld target: %x lun: %x "
- "slot %d irq %d\n", (long)sh->base, cmd->pid,
- cmd->target, cmd->lun, y, sh->irq));
- DBG(DBG_QUEUE && DBG_DELAY, DEL2(200));
-
- restore_flags(flags);
- return (0);
-}
-
-int eata_pio_abort(Scsi_Cmnd * cmd)
-{
- ulong flags;
- uint loop = R_LIMIT;
-
- save_flags(flags);
- cli();
-
- DBG(DBG_ABNORM, printk("eata_pio_abort called pid: %ld target: %x lun: %x"
- " reason %x\n", cmd->pid, cmd->target, cmd->lun,
- cmd->abort_reason));
- DBG(DBG_ABNORM && DBG_DELAY, DEL2(500));
-
-
- while (inb((uint)(cmd->host->base) + HA_RAUXSTAT) & HA_ABUSY)
- if (--loop == 0) {
- printk("eata_pio: abort, timeout error.\n");
- restore_flags(flags);
- DBG(DBG_ABNORM && DBG_DELAY, DEL2(500));
- return (SCSI_ABORT_ERROR);
- }
- if (CD(cmd)->status == FREE) {
- DBG(DBG_ABNORM, printk("Returning: SCSI_ABORT_NOT_RUNNING\n"));
- restore_flags(flags);
- return (SCSI_ABORT_NOT_RUNNING);
- }
- if (CD(cmd)->status == USED) {
- DBG(DBG_ABNORM, printk("Returning: SCSI_ABORT_BUSY\n"));
- restore_flags(flags);
- return (SCSI_ABORT_BUSY); /* SNOOZE */
- }
- if (CD(cmd)->status == RESET) {
- restore_flags(flags);
- printk("eata_pio: abort, command reset error.\n");
- DBG(DBG_ABNORM && DBG_DELAY, DEL2(500));
- return (SCSI_ABORT_ERROR);
- }
- if (CD(cmd)->status == LOCKED) {
- restore_flags(flags);
- DBG(DBG_ABNORM, printk("eata_pio: abort, queue slot locked.\n"));
- DBG(DBG_ABNORM && DBG_DELAY, DEL2(500));
- return (SCSI_ABORT_NOT_RUNNING);
- }
- restore_flags(flags);
- panic("eata_pio: abort: invalid slot status\n");
-}
-
-int eata_pio_reset(Scsi_Cmnd * cmd)
-{
- uint x, z, time, limit = 0;
- ulong flags;
- unchar success = FALSE;
- Scsi_Cmnd *sp;
-
- save_flags(flags);
- cli();
- hprint("reset");
- DBG(DBG_ABNORM, printk("eata_pio_reset called pid:%ld target: %x lun: %x "
- "reason %x\n", cmd->pid, cmd->target, cmd->lun,
- cmd->abort_reason));
-
- if (HD(cmd)->state == RESET) {
- printk("eata_pio_reset: exit, already in reset.\n");
- restore_flags(flags);
- DBG(DBG_ABNORM && DBG_DELAY, DEL2(500));
- return (SCSI_RESET_ERROR);
- }
-
- for (z = 0; z < MAXTARGET; z++) {
- HD(cmd)->t_state[0][z] = RESET;
- HD(cmd)->t_timeout[0][z] = NO_TIMEOUT;
- }
-
- /* force all slots to be free */
-
- for (x = 0; x < cmd->host->can_queue; x++) {
-
- if (HD(cmd)->ccb[x].status == FREE)
- continue;
-
- sp = HD(cmd)->ccb[x].cmd;
- HD(cmd)->ccb[x].status = RESET;
- printk("eata_pio_reset: slot %d in reset, pid %ld.\n", x, sp->pid);
- DBG(DBG_ABNORM && DBG_DELAY, DEL2(500));
-
- if (sp == NULL)
- panic("eata_pio_reset: slot %d, sp==NULL.\n", x);
- DBG(DBG_ABNORM && DBG_DELAY, DEL2(500));
- }
-
- /* hard reset the HBA */
- outb((uint) cmd->host->base+HA_WCOMMAND, EATA_CMD_RESET);
-
- DBG(DBG_ABNORM, printk("eata_pio_reset: board reset done.\n"));
- HD(cmd)->state = RESET;
-
- time = jiffies;
- while (jiffies < (time + (3 * HZ)) && limit++ < 10000000);
-
- DBG(DBG_ABNORM, printk("eata_pio_reset: interrupts disabled, loops %d.\n", limit));
- DBG(DBG_ABNORM && DBG_DELAY, DEL2(500));
-
- for (x = 0; x < cmd->host->can_queue; x++) {
-
- /* Skip slots already set free by interrupt */
- if (HD(cmd)->ccb[x].status != RESET)
- continue;
-
- sp = HD(cmd)->ccb[x].cmd;
- sp->result = DID_RESET << 16;
-
- /* This mailbox is terminated */
- printk("eata_pio_reset: resetted ccb %d.\n",x);
- HD(cmd)->ccb[x].status = FREE;
-
- restore_flags(flags);
- sp->scsi_done(sp);
- cli();
- }
-
- HD(cmd)->state = FALSE;
- restore_flags(flags);
-
- if (success) { /* hmmm... */
- DBG(DBG_ABNORM, printk("eata_pio_reset: exit, success.\n"));
- DBG(DBG_ABNORM && DBG_DELAY, DEL2(500));
- return (SCSI_RESET_SUCCESS);
- } else {
- DBG(DBG_ABNORM, printk("eata_pio_reset: exit, wakeup.\n"));
- DBG(DBG_ABNORM && DBG_DELAY, DEL2(500));
- return (SCSI_RESET_PUNT);
- }
-}
-
-char * get_pio_board_data(ulong base, uint irq, uint id, ulong cplen, ushort cppadlen)
-{
- struct eata_ccb cp;
- static char buff[256];
- int z;
-
- memset(&cp, 0, sizeof(struct eata_ccb));
- memset(buff, 0, sizeof(buff));
-
- cp.DataIn = TRUE;
- cp.Interpret = TRUE; /* Interpret command */
-
- cp.cp_datalen = htonl(254);
- cp.cp_dataDMA = htonl(0);
-
- cp.cp_id = id;
- cp.cp_lun = 0;
-
- cp.cp_cdb[0] = INQUIRY;
- cp.cp_cdb[1] = 0;
- cp.cp_cdb[2] = 0;
- cp.cp_cdb[3] = 0;
- cp.cp_cdb[4] = 254;
- cp.cp_cdb[5] = 0;
-
- if (eata_pio_send_command((uint) base, EATA_CMD_PIO_SEND_CP))
- return (NULL);
- while (!(inb(base + HA_RSTATUS) & HA_SDRQ));
- outsw(base + HA_RDATA, &cp, cplen);
- outb(EATA_CMD_PIO_TRUNC, base + HA_WCOMMAND);
- for (z = 0; z < cppadlen; z++) outw(0, base + HA_RDATA);
-
- while (inb(base + HA_RSTATUS) & HA_SBUSY);
- if (inb(base + HA_RSTATUS) & HA_SERROR)
- return (NULL);
- else if (!(inb(base + HA_RSTATUS) & HA_SDRQ))
- return (NULL);
- else
- {
- insw(base+HA_RDATA, &buff, 127);
- while (inb(base + HA_RSTATUS)&HA_SDRQ) inw(base + HA_RDATA);
- return (buff);
- }
-}
-
-int get_pio_conf_PIO(u32 base, struct get_conf *buf)
-{
- ulong loop = R_LIMIT;
- int z;
- ushort *p;
-
- if(check_region(base, 9))
- return (FALSE);
-
- memset(buf, 0, sizeof(struct get_conf));
-
- while (inb(base + HA_RSTATUS) & HA_SBUSY)
- if (--loop == 0)
- return (FALSE);
-
- DBG(DBG_PIO && DBG_PROBE,
- printk("Issuing PIO READ CONFIG to HBA at %#x\n", base));
- eata_pio_send_command(base, EATA_CMD_PIO_READ_CONFIG);
-
- loop = R_LIMIT;
- for (p = (ushort *) buf;
- (long)p <= ((long)buf + (sizeof(struct get_conf) / 2)); p++) {
- while (!(inb(base + HA_RSTATUS) & HA_SDRQ))
- if (--loop == 0)
- return (FALSE);
-
- loop = R_LIMIT;
- *p = inw(base + HA_RDATA);
- }
- if (!(inb(base + HA_RSTATUS) & HA_SERROR)) { /* Error ? */
- if (htonl(EATA_SIGNATURE) == buf->signature) {
- DBG(DBG_PIO&&DBG_PROBE, printk("EATA Controller found at %#4x "
- "EATA Level: %x\n", base,
- (uint) (buf->version)));
-
- while (inb(base + HA_RSTATUS) & HA_SDRQ)
- inw(base + HA_RDATA);
- if(ALLOW_DMA_BOARDS == FALSE) {
- for (z = 0; z < MAXISA; z++)
- if (base == ISAbases[z]) {
- buf->IRQ = ISAirqs[z];
- break;
- }
- }
- return (TRUE);
- }
- } else {
- DBG(DBG_PROBE, printk("eata_dma: get_conf_PIO, error during transfer "
- "for HBA at %x\n", base));
- }
- return (FALSE);
-}
-
-void print_pio_config(struct get_conf *gc)
-{
- printk("Please check values: (read config data)\n");
- printk("LEN: %d ver:%d OCS:%d TAR:%d TRNXFR:%d MORES:%d\n",
- (uint) ntohl(gc->len), gc->version,
- gc->OCS_enabled, gc->TAR_support, gc->TRNXFR, gc->MORE_support);
- printk("HAAV:%d SCSIID0:%d ID1:%d ID2:%d QUEUE:%d SG:%d SEC:%d\n",
- gc->HAA_valid, gc->scsi_id[3], gc->scsi_id[2],
- gc->scsi_id[1], ntohs(gc->queuesiz), ntohs(gc->SGsiz), gc->SECOND);
- printk("IRQ:%d IRQT:%d FORCADR:%d MCH:%d RIDQ:%d\n",
- gc->IRQ, gc->IRQ_TR, gc->FORCADR,
- gc->MAX_CHAN, gc->ID_qest);
- DBG(DPT_DEBUG, DELAY(14));
-}
-
-static uint print_selftest(uint base)
-{
- unchar buffer[512];
-#ifdef VERBOSE_SETUP
- int z;
-#endif
-
- printk("eata_pio: executing controller self test & setup...\n");
- while (inb(base + HA_RSTATUS) & HA_SBUSY);
- outb(EATA_CMD_PIO_SETUPTEST, base + HA_WCOMMAND);
- do {
- while (inb(base + HA_RSTATUS) & HA_SBUSY)
- /* nothing */ ;
- if (inb(base + HA_RSTATUS) & HA_SDRQ)
- {
- insw(base + HA_RDATA, &buffer, 256);
-#ifdef VERBOSE_SETUP
- /* no beeps please... */
- for (z = 0; z < 511 && buffer[z]; z++)
- if (buffer[z] != 7) printk("%c", buffer[z]);
-#endif
- }
- } while (inb(base+HA_RSTATUS) & (HA_SBUSY|HA_SDRQ));
-
- return (!(inb(base+HA_RSTATUS) & HA_SERROR));
-}
-
-int register_pio_HBA(long base, struct get_conf *gc, Scsi_Host_Template * tpnt)
-{
- ulong size = 0;
- char *buff;
- ulong cplen;
- ushort cppadlen;
- struct Scsi_Host *sh;
- hostdata *hd;
-
- DBG(DBG_REGISTER, print_pio_config(gc));
-
- if (gc->DMA_support == TRUE) {
- printk("HBA at %#.4lx supports DMA. Please use EATA-DMA driver.\n",base);
- if(ALLOW_DMA_BOARDS == FALSE)
- return (FALSE);
- }
-
- if ((buff = get_pio_board_data((uint)base, gc->IRQ, gc->scsi_id[3],
- cplen =(htonl(gc->cplen )+1)/2,
- cppadlen=(htons(gc->cppadlen)+1)/2)) == NULL)
- {
- printk("HBA at %#lx didn't react on INQUIRY. Sorry.\n", (ulong) base);
- return (FALSE);
- }
-
- if (print_selftest(base) == FALSE && ALLOW_DMA_BOARDS == FALSE)
- {
- printk("HBA at %#lx failed while performing self test & setup.\n",
- (ulong) base);
- return (FALSE);
- }
-
- if (!reg_IRQ[gc->IRQ]) { /* Interrupt already registered ? */
- if (!request_irq(gc->IRQ, eata_pio_int_handler, SA_INTERRUPT,
- "EATA-PIO")){
- reg_IRQ[gc->IRQ]++;
- if (!gc->IRQ_TR)
- reg_IRQL[gc->IRQ] = TRUE; /* IRQ is edge triggered */
- } else {
- printk("Couldn't allocate IRQ %d, Sorry.", gc->IRQ);
- return (FALSE);
- }
- } else { /* More than one HBA on this IRQ */
- if (reg_IRQL[gc->IRQ] == TRUE) {
- printk("Can't support more than one HBA on this IRQ,\n"
- " if the IRQ is edge triggered. Sorry.\n");
- return (FALSE);
- } else
- reg_IRQ[gc->IRQ]++;
- }
-
- request_region(base, 8, "eata_pio");
-
- size = sizeof(hostdata) + (sizeof(struct eata_ccb) * ntohs(gc->queuesiz));
-
- sh = scsi_register(tpnt, size);
- hd = SD(sh);
-
- memset(hd->ccb, 0, (sizeof(struct eata_ccb) * ntohs(gc->queuesiz)));
- memset(hd->reads, 0, sizeof(ulong) * 26);
-
- strncpy(SD(sh)->vendor, &buff[8], 8);
- SD(sh)->vendor[8] = 0;
- strncpy(SD(sh)->name, &buff[16], 17);
- SD(sh)->name[17] = 0;
- SD(sh)->revision[0] = buff[32];
- SD(sh)->revision[1] = buff[33];
- SD(sh)->revision[2] = buff[34];
- SD(sh)->revision[3] = '.';
- SD(sh)->revision[4] = buff[35];
- SD(sh)->revision[5] = 0;
-
- switch (ntohl(gc->len)) {
- case 0x1c:
- SD(sh)->EATA_revision = 'a';
- break;
- case 0x1e:
- SD(sh)->EATA_revision = 'b';
- break;
- case 0x22:
- SD(sh)->EATA_revision = 'c';
- break;
- case 0x24:
- SD(sh)->EATA_revision = 'z';
- default:
- SD(sh)->EATA_revision = '?';
- }
-
- if(ntohl(gc->len) >= 0x22) {
- if (gc->is_PCI == TRUE)
- hd->bustype = IS_PCI;
- else if (gc->is_EISA == TRUE)
- hd->bustype = IS_EISA;
- else
- hd->bustype = IS_ISA;
- } else {
- if (buff[21] == '4')
- hd->bustype = IS_PCI;
- else if (buff[21] == '2')
- hd->bustype = IS_EISA;
- else
- hd->bustype = IS_ISA;
- }
-
- SD(sh)->cplen=cplen;
- SD(sh)->cppadlen=cppadlen;
- SD(sh)->hostid=gc->scsi_id[3];
- SD(sh)->devflags=1<<gc->scsi_id[3];
- SD(sh)->moresupport=gc->MORE_support;
- sh->unique_id = base;
- sh->base = (char *) base;
- sh->io_port = base;
- sh->n_io_port = 8;
- sh->irq = gc->IRQ;
- sh->dma_channel = PIO;
- sh->this_id = gc->scsi_id[3];
- sh->can_queue = 1;
- sh->cmd_per_lun = 1;
- sh->sg_tablesize = SG_ALL;
-
- hd->channel = 0;
-
- sh->max_id = 8;
- sh->max_lun = 8;
-
- if (gc->SECOND)
- hd->primary = FALSE;
- else
- hd->primary = TRUE;
-
- sh->unchecked_isa_dma = FALSE; /* We can only do PIO */
-
- hd->next = NULL; /* build a linked list of all HBAs */
- hd->prev = last_HBA;
- if(hd->prev != NULL)
- SD(hd->prev)->next = sh;
- last_HBA = sh;
- if (first_HBA == NULL)
- first_HBA = sh;
- registered_HBAs++;
- return (1);
-}
-
-void find_pio_ISA(struct get_conf *buf, Scsi_Host_Template * tpnt)
-{
- int i;
-
- for (i = 0; i < MAXISA; i++) {
- if (ISAbases[i]) {
- if (get_pio_conf_PIO(ISAbases[i], buf) == TRUE){
- register_pio_HBA(ISAbases[i], buf, tpnt);
- }
- ISAbases[i] = 0;
- }
- }
- return;
-}
-
-void find_pio_EISA(struct get_conf *buf, Scsi_Host_Template * tpnt)
-{
- u32 base;
- int i;
-
-#if CHECKPAL
- u8 pal1, pal2, pal3;
-#endif
-
- for (i = 0; i < MAXEISA; i++) {
- if (EISAbases[i] == TRUE) { /* Still a possibility ? */
-
- base = 0x1c88 + (i * 0x1000);
-#if CHECKPAL
- pal1 = inb((u16)base - 8);
- pal2 = inb((u16)base - 7);
- pal3 = inb((u16)base - 6);
-
- if (((pal1 == 0x12) && (pal2 == 0x14)) ||
- ((pal1 == 0x38) && (pal2 == 0xa3) && (pal3 == 0x82)) ||
- ((pal1 == 0x06) && (pal2 == 0x94) && (pal3 == 0x24))) {
- DBG(DBG_PROBE, printk("EISA EATA id tags found: %x %x %x \n",
- (int)pal1, (int)pal2, (int)pal3));
-#endif
- if (get_pio_conf_PIO(base, buf) == TRUE) {
- DBG(DBG_PROBE && DBG_EISA, print_pio_config(buf));
- if (buf->IRQ) {
- register_pio_HBA(base, buf, tpnt);
- } else
- printk("eata_dma: No valid IRQ. HBA removed from list\n");
- }
- /* Nothing found here so we take it from the list */
- EISAbases[i] = 0;
-#if CHECKPAL
- }
-#endif
- }
- }
- return;
-}
-
-void find_pio_PCI(struct get_conf *buf, Scsi_Host_Template * tpnt)
-{
-
-#ifndef CONFIG_PCI
- printk("eata_pio: kernel PCI support not enabled. Skipping scan for PCI HBAs.\n");
-#else
-
- u8 pci_bus, pci_device_fn;
- static s16 pci_index = 0; /* Device index to PCI BIOS calls */
- u32 base = 0;
- u16 com_adr;
- u16 rev_device;
- u32 error, i, x;
-
- if (pcibios_present()) {
- for (i = 0; i <= MAXPCI; ++i, ++pci_index) {
- if (pcibios_find_device(PCI_VENDOR_ID_DPT, PCI_DEVICE_ID_DPT,
- pci_index, &pci_bus, &pci_device_fn))
- break;
- DBG(DBG_PROBE && DBG_PCI,
- printk("eata_pio: HBA at bus %d, device %d,"
- " function %d, index %d\n", (s32)pci_bus,
- (s32)((pci_device_fn & 0xf8) >> 3),
- (s32)(pci_device_fn & 7), pci_index));
-
- if (!(error = pcibios_read_config_word(pci_bus, pci_device_fn,
- PCI_CLASS_DEVICE, &rev_device))) {
- if (rev_device == PCI_CLASS_STORAGE_SCSI) {
- if (!(error = pcibios_read_config_word(pci_bus,
- pci_device_fn, PCI_COMMAND,
- (u16 *) & com_adr))) {
- if (!((com_adr & PCI_COMMAND_IO) &&
- (com_adr & PCI_COMMAND_MASTER))) {
- printk("HBA has IO or BUSMASTER mode disabled\n");
- continue;
- }
- } else
- printk("eata_pio: error %x while reading "
- "PCI_COMMAND\n", error);
- } else
- printk("DEVICECLASSID %x didn't match\n", rev_device);
- } else {
- printk("eata_pio: error %x while reading PCI_CLASS_BASE\n",
- error);
- continue;
- }
-
- if (!(error = pcibios_read_config_dword(pci_bus, pci_device_fn,
- PCI_BASE_ADDRESS_0, (int *) &base))){
-
- /* Check if the address is valid */
- if (base & 0x01) {
- base &= 0xfffffffe;
- /* EISA tag there ? */
- if ((inb(base) == 0x12) && (inb(base + 1) == 0x14))
- continue; /* Jep, it's forced, so move on */
- base += 0x10; /* Now, THIS is the real address */
- if (base != 0x1f8) {
- /* We didn't find it in the primary search */
- if (get_pio_conf_PIO(base, buf) == TRUE) {
- if (buf->FORCADR) /* If the address is forced */
- continue; /* we'll find it later */
-
- /* OK. We made it till here, so we can go now
- * and register it. We only have to check and
- * eventually remove it from the EISA and ISA list
- */
-
- register_pio_HBA(base, buf, tpnt);
-
- if (base < 0x1000) {
- for (x = 0; x < MAXISA; ++x) {
- if (ISAbases[x] == base) {
- ISAbases[x] = 0;
- break;
- }
- }
- } else if ((base & 0x0fff) == 0x0c88) {
- x = (base >> 12) & 0x0f;
- EISAbases[x] = 0;
- }
- continue; /* break; */
- }
- }
- }
- } else
- printk("eata_pio: error %x while reading "
- "PCI_BASE_ADDRESS_0\n", error);
- }
- } else
- printk("eata_pio: No BIOS32 extensions present. This driver release "
- "still depends on it.\n"
- " Skipping scan for PCI HBAs.\n");
-#endif /* #ifndef CONFIG_PCI */
- return;
-}
-
-
-int eata_pio_detect(Scsi_Host_Template * tpnt)
-{
- struct Scsi_Host *HBA_ptr;
- struct get_conf gc;
- int i;
-
- DBG((DBG_PROBE && DBG_DELAY) || DPT_DEBUG,
- printk("Using lots of delays to let you read the debugging output\n"));
-
- tpnt->proc_dir = &proc_scsi_eata_pio;
-
- find_pio_PCI(&gc, tpnt);
-
- find_pio_EISA(&gc, tpnt);
-
- find_pio_ISA(&gc, tpnt);
-
- for (i = 0; i <= MAXIRQ; i++)
- if (reg_IRQ[i])
- request_irq(i, eata_pio_int_handler, SA_INTERRUPT, "EATA-PIO");
-
- HBA_ptr = first_HBA;
-
- if (registered_HBAs != 0) {
- printk("EATA (Extended Attachment) PIO driver version: %d.%d%s\n"
- "(c) 1993-95 Michael Neuffer, neuffer@goofy.zdv.uni-mainz.de\n"
- " Alfred Arnold, a.arnold@kfa-juelich.de\n"
- "This release only supports DASD devices (harddisks)\n",
- VER_MAJOR, VER_MINOR, VER_SUB);
-
- printk("Registered HBAs:\n");
- printk("HBA no. Boardtype: Revis: EATA: Bus: BaseIO: IRQ: Ch: ID: Pr:"
- " QS: SG: CPL:\n");
- for (i = 1; i <= registered_HBAs; i++) {
- printk("scsi%-2d: %.10s v%s 2.0%c %s %#.4x %2d %d %d %c"
- " %2d %2d %2d\n",
- HBA_ptr->host_no, SD(HBA_ptr)->name, SD(HBA_ptr)->revision,
- SD(HBA_ptr)->EATA_revision, (SD(HBA_ptr)->bustype == 'P')?
- "PCI ":(SD(HBA_ptr)->bustype == 'E')?"EISA":"ISA ",
- (uint) HBA_ptr->base, HBA_ptr->irq, SD(HBA_ptr)->channel,
- HBA_ptr->this_id, (SD(HBA_ptr)->primary == TRUE)?'Y':'N',
- HBA_ptr->can_queue, HBA_ptr->sg_tablesize,
- HBA_ptr->cmd_per_lun);
- HBA_ptr = SD(HBA_ptr)->next;
- }
- }
- DBG(DPT_DEBUG,DELAY(12));
-
- return (registered_HBAs);
-}
-
-#ifdef MODULE
-/* Eventually this will go into an include file, but this will be later */
-Scsi_Host_Template driver_template = EATA_PIO;
-
-#include "scsi_module.c"
-#endif
-
-/*
- * Overrides for Emacs so that we almost follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 4
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * c-continued-statement-offset: 4
- * c-continued-brace-offset: 0
- * indent-tabs-mode: nil
- * tab-width: 8
- * End:
- */
diff --git a/i386/i386at/gpl/linux/scsi/eata_pio.h b/i386/i386at/gpl/linux/scsi/eata_pio.h
deleted file mode 100644
index 8a626e0b..00000000
--- a/i386/i386at/gpl/linux/scsi/eata_pio.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/********************************************************
-* Header file for eata_pio.c Linux EATA-PIO SCSI driver *
-* (c) 1993,94,95 Michael Neuffer *
-*********************************************************
-* last change: 95/06/21 *
-********************************************************/
-
-
-#ifndef _EATA_PIO_H
-#define _EATA_PIO_H
-
-#include <linux/blk.h>
-#include "scsi.h"
-#include "hosts.h"
-#include <linux/scsicam.h>
-
-#ifndef HOSTS_C
-#include "eata_generic.h"
-
-#define VER_MAJOR 0
-#define VER_MINOR 0
-#define VER_SUB "1b"
-
-/************************************************************************
- * Here you can switch parts of the code on and of *
- ************************************************************************/
-
-#define VERBOSE_SETUP /* show startup screen of 2001 */
-#define ALLOW_DMA_BOARDS 1
-
-/************************************************************************
- * Debug options. *
- * Enable DEBUG and whichever options you require. *
- ************************************************************************/
-#define DEBUG_EATA 1 /* Enable debug code. */
-#define DPT_DEBUG 0 /* Bobs special */
-#define DBG_DELAY 0 /* Build in delays so debug messages can be
- * be read before they vanish of the top of
- * the screen!
- */
-#define DBG_PROBE 0 /* Debug probe routines. */
-#define DBG_ISA 0 /* Trace ISA routines */
-#define DBG_EISA 0 /* Trace EISA routines */
-#define DBG_PCI 0 /* Trace PCI routines */
-#define DBG_PIO 0 /* Trace get_config_PIO */
-#define DBG_COM 0 /* Trace command call */
-#define DBG_QUEUE 0 /* Trace command queueing. */
-#define DBG_INTR 0 /* Trace interrupt service routine. */
-#define DBG_INTR2 0 /* Trace interrupt service routine. */
-#define DBG_PROC 0 /* Debug proc-fs related statistics */
-#define DBG_PROC_WRITE 0
-#define DBG_REGISTER 0 /* */
-#define DBG_ABNORM 1 /* Debug abnormal actions (reset, abort) */
-
-#if DEBUG_EATA
-#define DBG(x, y) if ((x)) {y;}
-#else
-#define DBG(x, y)
-#endif
-
-#endif /* !HOSTS_C */
-
-int eata_pio_detect(Scsi_Host_Template *);
-const char *eata_pio_info(struct Scsi_Host *);
-int eata_pio_command(Scsi_Cmnd *);
-int eata_pio_queue(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-int eata_pio_abort(Scsi_Cmnd *);
-int eata_pio_reset(Scsi_Cmnd *);
-int eata_pio_proc_info(char *, char **, off_t, int, int, int);
-#ifdef MODULE
-int eata_pio_release(struct Scsi_Host *);
-#else
-#define eata_pio_release NULL
-#endif
-
-
-#define EATA_PIO { \
- NULL, NULL, \
- NULL, /* proc_dir_entry */ \
- eata_pio_proc_info, /* procinfo */ \
- "EATA (Extended Attachment) PIO driver", \
- eata_pio_detect, \
- eata_pio_release, \
- NULL, NULL, \
- eata_pio_queue, \
- eata_pio_abort, \
- eata_pio_reset, \
- NULL, /* Slave attach */ \
- scsicam_bios_param, \
- 0, /* Canqueue */ \
- 0, /* this_id */ \
- 0, /* sg_tablesize */ \
- 0, /* cmd_per_lun */ \
- 0, /* present */ \
- 1, /* True if ISA */ \
- ENABLE_CLUSTERING }
-
-#endif /* _EATA_PIO_H */
-
-/*
- * Overrides for Emacs so that we almost follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 4
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * c-continued-statement-offset: 4
- * c-continued-brace-offset: 0
- * tab-width: 8
- * End:
- */
diff --git a/i386/i386at/gpl/linux/scsi/eata_pio_proc.src b/i386/i386at/gpl/linux/scsi/eata_pio_proc.src
deleted file mode 100644
index b5480091..00000000
--- a/i386/i386at/gpl/linux/scsi/eata_pio_proc.src
+++ /dev/null
@@ -1,150 +0,0 @@
-
-#define MAX_SCSI_DEVICE_CODE 10
-const char *const pio_scsi_dev_types[MAX_SCSI_DEVICE_CODE] =
-{
- "Direct-Access ",
- "Sequential-Access",
- "Printer ",
- "Processor ",
- "WORM ",
- "CD-ROM ",
- "Scanner ",
- "Optical Device ",
- "Medium Changer ",
- "Communications "
-};
-
-/*
- * eata_set_info
- * buffer : pointer to the data that has been written to the hostfile
- * length : number of bytes written to the hostfile
- * HBA_ptr: pointer to the Scsi_Host struct
- */
-int eata_pio_set_info(char *buffer, int length, struct Scsi_Host *HBA_ptr)
-{
- DBG(DBG_PROC_WRITE, printk("%s\n", buffer));
- return(-ENOSYS); /* Currently this is a no-op */
-}
-
-/*
- * eata_proc_info
- * inout : decides on the direction of the dataflow and the meaning of the
- * variables
- * buffer: If inout==FALSE data is beeing written to it else read from it
- * *start: If inout==FALSE start of the valid data in the buffer
- * offset: If inout==FALSE offset from the beginning of the imaginary file
- * from which we start writing into the buffer
- * length: If inout==FALSE max number of bytes to be written into the buffer
- * else number of bytes in the buffer
- */
-int eata_pio_proc_info(char *buffer, char **start, off_t offset, int length,
- int hostno, int inout)
-{
-
- Scsi_Device *scd;
- struct Scsi_Host *HBA_ptr;
- static u8 buff[512];
- int i;
- int size, len = 0;
- off_t begin = 0;
- off_t pos = 0;
-
- HBA_ptr = first_HBA;
- for (i = 1; i <= registered_HBAs; i++) {
- if (HBA_ptr->host_no == hostno)
- break;
- HBA_ptr = SD(HBA_ptr)->next;
- }
-
- if(inout == TRUE) /* Has data been writen to the file ? */
- return(eata_pio_set_info(buffer, length, HBA_ptr));
-
- if (offset == 0)
- memset(buff, 0, sizeof(buff));
-
- size = sprintf(buffer+len, "EATA (Extended Attachment) PIO driver version: "
- "%d.%d%s\n",VER_MAJOR, VER_MINOR, VER_SUB);
- len += size; pos = begin + len;
- size = sprintf(buffer + len, "queued commands: %10ld\n"
- "processed interrupts:%10ld\n", queue_counter, int_counter);
- len += size; pos = begin + len;
-
- size = sprintf(buffer + len, "\nscsi%-2d: HBA %.10s\n",
- HBA_ptr->host_no, SD(HBA_ptr)->name);
- len += size;
- pos = begin + len;
- size = sprintf(buffer + len, "Firmware revision: v%s\n",
- SD(HBA_ptr)->revision);
- len += size;
- pos = begin + len;
- size = sprintf(buffer + len, "IO: PIO\n");
- len += size;
- pos = begin + len;
- size = sprintf(buffer + len, "Base IO : %#.4x\n", (u32) HBA_ptr->base);
- len += size;
- pos = begin + len;
- size = sprintf(buffer + len, "Host Bus: %s\n",
- (SD(HBA_ptr)->bustype == 'P')?"PCI ":
- (SD(HBA_ptr)->bustype == 'E')?"EISA":"ISA ");
-
- len += size;
- pos = begin + len;
-
- if (pos < offset) {
- len = 0;
- begin = pos;
- }
- if (pos > offset + length)
- goto stop_output;
-
- scd = scsi_devices;
-
- size = sprintf(buffer+len,"Attached devices: %s\n", (scd)?"":"none");
- len += size;
- pos = begin + len;
-
- while (scd) {
- if (scd->host == HBA_ptr) {
- proc_print_scsidevice(scd, buffer, &size, len);
- len += size;
- pos = begin + len;
-
- if (pos < offset) {
- len = 0;
- begin = pos;
- }
- if (pos > offset + length)
- goto stop_output;
- }
- scd = scd->next;
- }
-
- stop_output:
- DBG(DBG_PROC, printk("2pos: %ld offset: %ld len: %d\n", pos, offset, len));
- *start=buffer+(offset-begin); /* Start of wanted data */
- len-=(offset-begin); /* Start slop */
- if(len>length)
- len = length; /* Ending slop */
- DBG(DBG_PROC, printk("3pos: %ld offset: %ld len: %d\n", pos, offset, len));
-
- return (len);
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 4
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * c-continued-statement-offset: 4
- * c-continued-brace-offset: 0
- * tab-width: 8
- * End:
- */
-
diff --git a/i386/i386at/gpl/linux/scsi/fdomain.c b/i386/i386at/gpl/linux/scsi/fdomain.c
deleted file mode 100644
index 54507046..00000000
--- a/i386/i386at/gpl/linux/scsi/fdomain.c
+++ /dev/null
@@ -1,2016 +0,0 @@
-/* fdomain.c -- Future Domain TMC-16x0 SCSI driver
- * Created: Sun May 3 18:53:19 1992 by faith@cs.unc.edu
- * Revised: Thu Oct 12 15:59:37 1995 by r.faith@ieee.org
- * Author: Rickard E. Faith, faith@cs.unc.edu
- * Copyright 1992, 1993, 1994, 1995 Rickard E. Faith
- *
- * $Id: fdomain.c,v 1.1.1.1 1997/02/25 21:27:49 thomas Exp $
-
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
-
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
-
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
-
- **************************************************************************
-
- DESCRIPTION:
-
- This is the Linux low-level SCSI driver for Future Domain TMC-1660/1680
- TMC-1650/1670, and TMC-3260 SCSI host adapters. The 1650 and 1670 have a
- 25-pin external connector, whereas the 1660 and 1680 have a SCSI-2 50-pin
- high-density external connector. The 1670 and 1680 have floppy disk
- controllers built in. The TMC-3260 is a PCI bus card.
-
- Future Domain's older boards are based on the TMC-1800 chip, and this
- driver was originally written for a TMC-1680 board with the TMC-1800 chip.
- More recently, boards are being produced with the TMC-18C50 and TMC-18C30
- chips. The latest and greatest board may not work with this driver. If
- you have to patch this driver so that it will recognize your board's BIOS
- signature, then the driver may fail to function after the board is
- detected.
-
- The following BIOS versions are supported: 2.0, 3.0, 3.2, 3.4, and 3.5.
- The following chips are supported: TMC-1800, TMC-18C50, TMC-18C30.
- Reports suggest that the driver will also work with the 36C70 chip and
- with the Quantum ISA-200S and ISA-250MG SCSI adapters.
-
- Please note that the drive ordering that Future Domain implemented in BIOS
- versions 3.4 and 3.5 is the opposite of the order (currently) used by the
- rest of the SCSI industry. If you have BIOS version 3.4 or 3.5, and have
- more then one drive, then the drive ordering will be the reverse of that
- which you see under DOS. For example, under DOS SCSI ID 0 will be D: and
- SCSI ID 1 will be C: (the boot device). Under Linux, SCSI ID 0 will be
- /dev/sda and SCSI ID 1 will be /dev/sdb. The Linux ordering is consistent
- with that provided by all the other SCSI drivers for Linux. If you want
- this changed, send me patches that are protected by #ifdefs.
-
- If you have a TMC-8xx or TMC-9xx board, then this is not the driver for
- your board. Please refer to the Seagate driver for more information and
- possible support.
-
-
-
- REFERENCES USED:
-
- "TMC-1800 SCSI Chip Specification (FDC-1800T)", Future Domain Corporation,
- 1990.
-
- "Technical Reference Manual: 18C50 SCSI Host Adapter Chip", Future Domain
- Corporation, January 1992.
-
- "LXT SCSI Products: Specifications and OEM Technical Manual (Revision
- B/September 1991)", Maxtor Corporation, 1991.
-
- "7213S product Manual (Revision P3)", Maxtor Corporation, 1992.
-
- "Draft Proposed American National Standard: Small Computer System
- Interface - 2 (SCSI-2)", Global Engineering Documents. (X3T9.2/86-109,
- revision 10h, October 17, 1991)
-
- Private communications, Drew Eckhardt (drew@cs.colorado.edu) and Eric
- Youngdale (ericy@cais.com), 1992.
-
- Private communication, Tuong Le (Future Domain Engineering department),
- 1994. (Disk geometry computations for Future Domain BIOS version 3.4, and
- TMC-18C30 detection.)
-
- Hogan, Thom. The Programmer's PC Sourcebook. Microsoft Press, 1988. Page
- 60 (2.39: Disk Partition Table Layout).
-
- "18C30 Technical Reference Manual", Future Domain Corporation, 1993, page
- 6-1.
-
-
-
- NOTES ON REFERENCES:
-
- The Maxtor manuals were free. Maxtor telephone technical support is
- great!
-
- The Future Domain manuals were $25 and $35. They document the chip, not
- the TMC-16x0 boards, so some information I had to guess at. In 1992,
- Future Domain sold DOS BIOS source for $250 and the UN*X driver source was
- $750, but these required a non-disclosure agreement, so even if I could
- have afforded them, they would *not* have been useful for writing this
- publically distributable driver. Future Domain technical support has
- provided some information on the phone and have sent a few useful FAXs.
- They have been much more helpful since they started to recognize that the
- word "Linux" refers to an operating system :-).
-
-
-
- ALPHA TESTERS:
-
- There are many other alpha testers that come and go as the driver
- develops. The people listed here were most helpful in times of greatest
- need (mostly early on -- I've probably left out a few worthy people in
- more recent times):
-
- Todd Carrico (todd@wutc.wustl.edu), Dan Poirier (poirier@cs.unc.edu ), Ken
- Corey (kenc@sol.acs.unt.edu), C. de Bruin (bruin@bruin@sterbbs.nl), Sakari
- Aaltonen (sakaria@vipunen.hit.fi), John Rice (rice@xanth.cs.odu.edu), Brad
- Yearwood (brad@optilink.com), and Ray Toy (toy@soho.crd.ge.com).
-
- Special thanks to Tien-Wan Yang (twyang@cs.uh.edu), who graciously lent me
- his 18C50-based card for debugging. He is the sole reason that this
- driver works with the 18C50 chip.
-
- Thanks to Dave Newman (dnewman@crl.com) for providing initial patches for
- the version 3.4 BIOS.
-
- Thanks to James T. McKinley (mckinley@msupa.pa.msu.edu) for providing
- patches that support the TMC-3260, a PCI bus card with the 36C70 chip.
- The 36C70 chip appears to be "completely compatible" with the 18C30 chip.
-
- Thanks to Eric Kasten (tigger@petroglyph.cl.msu.edu) for providing the
- patch for the version 3.5 BIOS.
-
- Thanks for Stephen Henson (shenson@nyx10.cs.du.edu) for providing the
- patch for the Quantum ISA-200S SCSI adapter.
-
- Thanks to Adam Bowen for the signature to the 1610M/MER/MEX scsi cards, to
- Martin Andrews (andrewm@ccfadm.eeg.ccf.org) for the signature to some
- random TMC-1680 repackaged by IBM; and to Mintak Ng (mintak@panix.com) for
- the version 3.61 BIOS siganture.
-
- Thanks for Mark Singer (elf@netcom.com) and Richard Simpson
- (rsimpson@ewrcsdra.demon.co.uk) for more Quantum signatures and detective
- work on the Quantum RAM layout.
-
- Special thanks to James T. McKinley (mckinley@msupa.pa.msu.edu) for
- providing patches for proper PCI BIOS32-mediated detection of the TMC-3260
- card (a PCI bus card with the 36C70 chip). Please send James PCI-related
- bug reports.
-
- Thanks to Tom Cavin (tec@usa1.com) for preliminary command-line option
- patches.
-
- All of the alpha testers deserve much thanks.
-
-
-
- NOTES ON USER DEFINABLE OPTIONS:
-
- DEBUG: This turns on the printing of various debug information.
-
- ENABLE_PARITY: This turns on SCSI parity checking. With the current
- driver, all attached devices must support SCSI parity. If none of your
- devices support parity, then you can probably get the driver to work by
- turning this option off. I have no way of testing this, however.
-
- FIFO_COUNT: The host adapter has an 8K cache (host adapters based on the
- 18C30 chip have a 2k cache). When this many 512 byte blocks are filled by
- the SCSI device, an interrupt will be raised. Therefore, this could be as
- low as 0, or as high as 16. Note, however, that values which are too high
- or too low seem to prevent any interrupts from occurring, and thereby lock
- up the machine. I have found that 2 is a good number, but throughput may
- be increased by changing this value to values which are close to 2.
- Please let me know if you try any different values.
-
- DO_DETECT: This activates some old scan code which was needed before the
- high level drivers got fixed. If you are having trouble with the driver,
- turning this on should not hurt, and might help. Please let me know if
- this is the case, since this code will be removed from future drivers.
-
- RESELECTION: This is no longer an option, since I gave up trying to
- implement it in version 4.x of this driver. It did not improve
- performance at all and made the driver unstable (because I never found one
- of the two race conditions which were introduced by the multiple
- outstanding command code). The instability seems a very high price to pay
- just so that you don't have to wait for the tape to rewind. If you want
- this feature implemented, send me patches. I'll be happy to send a copy
- of my (broken) driver to anyone who would like to see a copy.
-
- **************************************************************************/
-
-#ifdef MODULE
-#include <linux/module.h>
-#endif
-
-#include <linux/sched.h>
-#include <asm/io.h>
-#include <linux/blk.h>
-#include "scsi.h"
-#include "hosts.h"
-#include "fdomain.h"
-#include <asm/system.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/proc_fs.h>
-#include <linux/bios32.h>
-#include <linux/pci.h>
-#include <linux/stat.h>
-
-#include <linux/config.h> /* for CONFIG_PCI */
-
-struct proc_dir_entry proc_scsi_fdomain = {
- PROC_SCSI_FDOMAIN, 7, "fdomain",
- S_IFDIR | S_IRUGO | S_IXUGO, 2
-};
-
-#define VERSION "$Revision: 1.1.1.1 $"
-
-/* START OF USER DEFINABLE OPTIONS */
-
-#define DEBUG 1 /* Enable debugging output */
-#define ENABLE_PARITY 1 /* Enable SCSI Parity */
-#define FIFO_COUNT 2 /* Number of 512 byte blocks before INTR */
-#define DO_DETECT 0 /* Do device detection here (see scsi.c) */
-
-/* END OF USER DEFINABLE OPTIONS */
-
-#if DEBUG
-#define EVERY_ACCESS 0 /* Write a line on every scsi access */
-#define ERRORS_ONLY 1 /* Only write a line if there is an error */
-#define DEBUG_DETECT 0 /* Debug fdomain_16x0_detect() */
-#define DEBUG_MESSAGES 1 /* Debug MESSAGE IN phase */
-#define DEBUG_ABORT 1 /* Debug abort() routine */
-#define DEBUG_RESET 1 /* Debug reset() routine */
-#define DEBUG_RACE 1 /* Debug interrupt-driven race condition */
-#else
-#define EVERY_ACCESS 0 /* LEAVE THESE ALONE--CHANGE THE ONES ABOVE */
-#define ERRORS_ONLY 0
-#define DEBUG_DETECT 0
-#define DEBUG_MESSAGES 0
-#define DEBUG_ABORT 0
-#define DEBUG_RESET 0
-#define DEBUG_RACE 0
-#endif
-
-/* Errors are reported on the line, so we don't need to report them again */
-#if EVERY_ACCESS
-#undef ERRORS_ONLY
-#define ERRORS_ONLY 0
-#endif
-
-#if ENABLE_PARITY
-#define PARITY_MASK 0x08
-#else
-#define PARITY_MASK 0x00
-#endif
-
-enum chip_type {
- unknown = 0x00,
- tmc1800 = 0x01,
- tmc18c50 = 0x02,
- tmc18c30 = 0x03,
-};
-
-enum {
- in_arbitration = 0x02,
- in_selection = 0x04,
- in_other = 0x08,
- disconnect = 0x10,
- aborted = 0x20,
- sent_ident = 0x40,
-};
-
-enum in_port_type {
- Read_SCSI_Data = 0,
- SCSI_Status = 1,
- TMC_Status = 2,
- FIFO_Status = 3, /* tmc18c50/tmc18c30 only */
- Interrupt_Cond = 4, /* tmc18c50/tmc18c30 only */
- LSB_ID_Code = 5,
- MSB_ID_Code = 6,
- Read_Loopback = 7,
- SCSI_Data_NoACK = 8,
- Interrupt_Status = 9,
- Configuration1 = 10,
- Configuration2 = 11, /* tmc18c50/tmc18c30 only */
- Read_FIFO = 12,
- FIFO_Data_Count = 14
-};
-
-enum out_port_type {
- Write_SCSI_Data = 0,
- SCSI_Cntl = 1,
- Interrupt_Cntl = 2,
- SCSI_Mode_Cntl = 3,
- TMC_Cntl = 4,
- Memory_Cntl = 5, /* tmc18c50/tmc18c30 only */
- Write_Loopback = 7,
- IO_Control = 11, /* tmc18c30 only */
- Write_FIFO = 12
-};
-
-static int port_base = 0;
-static void *bios_base = NULL;
-static int bios_major = 0;
-static int bios_minor = 0;
-static int PCI_bus = 0;
-static int Quantum = 0; /* Quantum board variant */
-static int interrupt_level = 0;
-static volatile int in_command = 0;
-static Scsi_Cmnd *current_SC = NULL;
-static enum chip_type chip = unknown;
-static int adapter_mask = 0;
-static int this_id = 0;
-static int setup_called = 0;
-
-#if DEBUG_RACE
-static volatile int in_interrupt_flag = 0;
-#endif
-
-static int SCSI_Mode_Cntl_port;
-static int FIFO_Data_Count_port;
-static int Interrupt_Cntl_port;
-static int Interrupt_Status_port;
-static int Read_FIFO_port;
-static int Read_SCSI_Data_port;
-static int SCSI_Cntl_port;
-static int SCSI_Data_NoACK_port;
-static int SCSI_Status_port;
-static int TMC_Cntl_port;
-static int TMC_Status_port;
-static int Write_FIFO_port;
-static int Write_SCSI_Data_port;
-
-static int FIFO_Size = 0x2000; /* 8k FIFO for
- pre-tmc18c30 chips */
-
-extern void fdomain_16x0_intr( int irq, struct pt_regs * regs );
-
-static void *addresses[] = {
- (void *)0xc8000,
- (void *)0xca000,
- (void *)0xce000,
- (void *)0xde000,
- (void *)0xd0000, /* Extra addresses for PCI boards */
- (void *)0xe0000,
-};
-#define ADDRESS_COUNT (sizeof( addresses ) / sizeof( unsigned ))
-
-static unsigned short ports[] = { 0x140, 0x150, 0x160, 0x170 };
-#define PORT_COUNT (sizeof( ports ) / sizeof( unsigned short ))
-
-static unsigned short ints[] = { 3, 5, 10, 11, 12, 14, 15, 0 };
-
-/*
-
- READ THIS BEFORE YOU ADD A SIGNATURE!
-
- READING THIS SHORT NOTE CAN SAVE YOU LOTS OF TIME!
-
- READ EVERY WORD, ESPECIALLY THE WORD *NOT*
-
- This driver works *ONLY* for Future Domain cards using the TMC-1800,
- TMC-18C50, or TMC-18C30 chip. This includes models TMC-1650, 1660, 1670,
- and 1680.
-
- The following BIOS signature signatures are for boards which do *NOT*
- work with this driver (these TMC-8xx and TMC-9xx boards may work with the
- Seagate driver):
-
- FUTURE DOMAIN CORP. (C) 1986-1988 V4.0I 03/16/88
- FUTURE DOMAIN CORP. (C) 1986-1989 V5.0C2/14/89
- FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/89
- FUTURE DOMAIN CORP. (C) 1986-1990 V6.0105/31/90
- FUTURE DOMAIN CORP. (C) 1986-1990 V6.0209/18/90
- FUTURE DOMAIN CORP. (C) 1986-1990 V7.009/18/90
- FUTURE DOMAIN CORP. (C) 1992 V8.00.004/02/92
-
-*/
-
-struct signature {
- const char *signature;
- int sig_offset;
- int sig_length;
- int major_bios_version;
- int minor_bios_version;
- int flag; /* 1 == PCI_bus, 2 == ISA_200S, 3 == ISA_250MG, 4 == ISA_200S */
-} signatures[] = {
- /* 1 2 3 4 5 6 */
- /* 123456789012345678901234567890123456789012345678901234567890 */
- { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.07/28/89", 5, 50, 2, 0, 0 },
- { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V1.07/28/89", 5, 50, 2, 0, 0 },
- { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.07/28/89", 72, 50, 2, 0, 2 },
- { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.0", 73, 43, 2, 0, 3 },
- { "FUTURE DOMAIN CORP. (C) 1991 1800-V2.0.", 72, 39, 2, 0, 4 },
- { "FUTURE DOMAIN CORP. (C) 1992 V3.00.004/02/92", 5, 44, 3, 0, 0 },
- { "FUTURE DOMAIN TMC-18XX (C) 1993 V3.203/12/93", 5, 44, 3, 2, 0 },
- { "IBM F1 P2 BIOS v1.0104/29/93", 5, 28, 3, -1, 0 },
- { "Future Domain Corp. V1.0008/18/93", 5, 33, 3, 4, 0 },
- { "Future Domain Corp. V1.0008/18/93", 26, 33, 3, 4, 1 },
- /* This next signature may not be a 3.5 bios */
- { "Future Domain Corp. V2.0108/18/93", 5, 33, 3, 5, 0 },
- { "FUTURE DOMAIN CORP. V3.5008/18/93", 5, 34, 3, 5, 0 },
- { "FUTURE DOMAIN 18c30/18c50/1800 (C) 1994 V3.5", 5, 44, 3, 5, 0 },
- { "FUTURE DOMAIN CORP. V3.6008/18/93", 5, 34, 3, 6, 0 },
- { "FUTURE DOMAIN CORP. V3.6108/18/93", 5, 34, 3, 6, 0 },
- { "FUTURE DOMAIN TMC-18XX", 5, 22, -1, -1, 0 },
-
- /* READ NOTICE ABOVE *BEFORE* YOU WASTE YOUR TIME ADDING A SIGNATURE
- Also, fix the disk geometry code for your signature and send your
- changes for faith@cs.unc.edu. Above all, do *NOT* change any old
- signatures!
-
- Note that the last line will match a "generic" 18XX bios. Because
- Future Domain has changed the host SCSI ID and/or the location of the
- geometry information in the on-board RAM area for each of the first
- three BIOS's, it is still important to enter a fully qualified
- signature in the table for any new BIOS's (after the host SCSI ID and
- geometry location are verified). */
-};
-
-#define SIGNATURE_COUNT (sizeof( signatures ) / sizeof( struct signature ))
-
-static void print_banner( struct Scsi_Host *shpnt )
-{
- if (!shpnt) return; /* This won't ever happen */
-
- if (bios_major < 0 && bios_minor < 0) {
- printk( "scsi%d <fdomain>: No BIOS; using scsi id %d\n",
- shpnt->host_no, shpnt->this_id );
- } else {
- printk( "scsi%d <fdomain>: BIOS version ", shpnt->host_no );
-
- if (bios_major >= 0) printk( "%d.", bios_major );
- else printk( "?." );
-
- if (bios_minor >= 0) printk( "%d", bios_minor );
- else printk( "?." );
-
- printk( " at 0x%x using scsi id %d\n",
- (unsigned)bios_base, shpnt->this_id );
- }
-
- /* If this driver works for later FD PCI
- boards, we will have to modify banner
- for additional PCI cards, but for now if
- it's PCI it's a TMC-3260 - JTM */
- printk( "scsi%d <fdomain>: %s chip at 0x%x irq ",
- shpnt->host_no,
- chip == tmc1800 ? "TMC-1800"
- : (chip == tmc18c50 ? "TMC-18C50"
- : (chip == tmc18c30 ?
- (PCI_bus ? "TMC-36C70 (PCI bus)" : "TMC-18C30")
- : "Unknown")),
- port_base );
-
- if (interrupt_level) printk( "%d", interrupt_level );
- else printk( "<none>" );
-
- printk( "\n" );
-}
-
-void fdomain_setup( char *str, int *ints )
-{
- if (setup_called++ || ints[0] < 2 || ints[0] > 3) {
- printk( "fdomain: usage: fdomain=<PORT_BASE>,<IRQ>[,<ADAPTER_ID>]\n" );
- printk( "fdomain: bad LILO parameters?\n" );
- }
-
- port_base = ints[0] >= 1 ? ints[1] : 0;
- interrupt_level = ints[0] >= 2 ? ints[2] : 0;
- this_id = ints[0] >= 3 ? ints[3] : 0;
-
- bios_major = bios_minor = -1; /* Use geometry for BIOS version >= 3.4 */
-}
-
-
-static void do_pause( unsigned amount ) /* Pause for amount*10 milliseconds */
-{
- unsigned long the_time = jiffies + amount; /* 0.01 seconds per jiffy */
-
- while (jiffies < the_time);
-}
-
-inline static void fdomain_make_bus_idle( void )
-{
- outb( 0, SCSI_Cntl_port );
- outb( 0, SCSI_Mode_Cntl_port );
- if (chip == tmc18c50 || chip == tmc18c30)
- outb( 0x21 | PARITY_MASK, TMC_Cntl_port ); /* Clear forced intr. */
- else
- outb( 0x01 | PARITY_MASK, TMC_Cntl_port );
-}
-
-static int fdomain_is_valid_port( int port )
-{
-#if DEBUG_DETECT
- printk( " (%x%x),",
- inb( port + MSB_ID_Code ), inb( port + LSB_ID_Code ) );
-#endif
-
- /* The MCA ID is a unique id for each MCA compatible board. We
- are using ISA boards, but Future Domain provides the MCA ID
- anyway. We can use this ID to ensure that this is a Future
- Domain TMC-1660/TMC-1680.
- */
-
- if (inb( port + LSB_ID_Code ) != 0xe9) { /* test for 0x6127 id */
- if (inb( port + LSB_ID_Code ) != 0x27) return 0;
- if (inb( port + MSB_ID_Code ) != 0x61) return 0;
- chip = tmc1800;
- } else { /* test for 0xe960 id */
- if (inb( port + MSB_ID_Code ) != 0x60) return 0;
- chip = tmc18c50;
-
-#if 0
-
- /* Try to toggle 32-bit mode. This only
- works on an 18c30 chip. (User reports
- say that this doesn't work at all, so
- we'll use the other method.) */
-
- outb( 0x80, port + IO_Control );
- if ((inb( port + Configuration2 ) & 0x80) == 0x80) {
- outb( 0x00, port + IO_Control );
- if ((inb( port + Configuration2 ) & 0x80) == 0x00) {
- chip = tmc18c30;
- FIFO_Size = 0x800; /* 2k FIFO */
- }
- }
-#else
-
- /* That should have worked, but appears to
- have problems. Lets assume it is an
- 18c30 if the RAM is disabled. */
-
- if (inb( port + Configuration2 ) & 0x02) {
- chip = tmc18c30;
- FIFO_Size = 0x800; /* 2k FIFO */
- }
-#endif
- /* If that failed, we are an 18c50. */
- }
-
- return 1;
-}
-
-static int fdomain_test_loopback( void )
-{
- int i;
- int result;
-
- for (i = 0; i < 255; i++) {
- outb( i, port_base + Write_Loopback );
- result = inb( port_base + Read_Loopback );
- if (i != result)
- return 1;
- }
- return 0;
-}
-
-/* fdomain_get_irq assumes that we have a valid MCA ID for a
- TMC-1660/TMC-1680 Future Domain board. Now, check to be sure the
- bios_base matches these ports. If someone was unlucky enough to have
- purchased more than one Future Domain board, then they will have to
- modify this code, as we only detect one board here. [The one with the
- lowest bios_base.]
-
- Note that this routine is only used for systems without a PCI BIOS32
- (e.g., ISA bus). For PCI bus systems, this routine will likely fail
- unless one of the IRQs listed in the ints array is used by the board.
- Sometimes it is possible to use the computer's BIOS setup screen to
- configure a PCI system so that one of these IRQs will be used by the
- Future Domain card. */
-
-static int fdomain_get_irq( int base )
-{
- int options = inb( base + Configuration1 );
-
-#if DEBUG_DETECT
- printk( " Options = %x\n", options );
-#endif
-
- /* Check for board with lowest bios_base --
- this isn't valid for the 18c30 or for
- boards on the PCI bus, so just assume we
- have the right board. */
-
- if (chip != tmc18c30
- && !PCI_bus
- && addresses[ (options & 0xc0) >> 6 ] != bios_base) return 0;
-
- return ints[ (options & 0x0e) >> 1 ];
-}
-
-static int fdomain_isa_detect( int *irq, int *iobase )
-{
- int i;
- int base;
- int flag = 0;
-
- if (bios_major == 2) {
- /* The TMC-1660/TMC-1680 has a RAM area just after the BIOS ROM.
- Assuming the ROM is enabled (otherwise we wouldn't have been
- able to read the ROM signature :-), then the ROM sets up the
- RAM area with some magic numbers, such as a list of port
- base addresses and a list of the disk "geometry" reported to
- DOS (this geometry has nothing to do with physical geometry).
- */
-
- switch (Quantum) {
- case 2: /* ISA_200S */
- case 3: /* ISA_250MG */
- base = *((char *)bios_base + 0x1fa2)
- + (*((char *)bios_base + 0x1fa3) << 8);
- break;
- case 4: /* ISA_200S (another one) */
- base = *((char *)bios_base + 0x1fa3)
- + (*((char *)bios_base + 0x1fa4) << 8);
- break;
- default:
- base = *((char *)bios_base + 0x1fcc)
- + (*((char *)bios_base + 0x1fcd) << 8);
- break;
- }
-
-#if DEBUG_DETECT
- printk( " %x,", base );
-#endif
-
- for (flag = 0, i = 0; !flag && i < PORT_COUNT; i++) {
- if (base == ports[i])
- ++flag;
- }
-
- if (flag && fdomain_is_valid_port( base )) {
- *irq = fdomain_get_irq( base );
- *iobase = base;
- return 1;
- }
-
- /* This is a bad sign. It usually means that someone patched the
- BIOS signature list (the signatures variable) to contain a BIOS
- signature for a board *OTHER THAN* the TMC-1660/TMC-1680. */
-
-#if DEBUG_DETECT
- printk( " RAM FAILED, " );
-#endif
- }
-
- /* Anyway, the alternative to finding the address in the RAM is to just
- search through every possible port address for one that is attached
- to the Future Domain card. Don't panic, though, about reading all
- these random port addresses -- there are rumors that the Future
- Domain BIOS does something very similar.
-
- Do not, however, check ports which the kernel knows are being used by
- another driver. */
-
- for (i = 0; i < PORT_COUNT; i++) {
- base = ports[i];
- if (check_region( base, 0x10 )) {
-#if DEBUG_DETECT
- printk( " (%x inuse),", base );
-#endif
- continue;
- }
-#if DEBUG_DETECT
- printk( " %x,", base );
-#endif
- if ((flag = fdomain_is_valid_port( base ))) break;
- }
-
- if (!flag) return 0; /* iobase not found */
-
- *irq = fdomain_get_irq( base );
- *iobase = base;
-
- return 1; /* success */
-}
-
-static int fdomain_pci_nobios_detect( int *irq, int *iobase )
-{
- int i;
- int flag = 0;
-
- /* The proper way of doing this is to use ask the PCI bus for the device
- IRQ and interrupt level. But we can't do that if PCI BIOS32 support
- isn't compiled into the kernel, or if a PCI BIOS32 isn't present.
-
- Instead, we scan down a bunch of addresses (Future Domain tech
- support says we will probably find the address before we get to
- 0xf800). This works fine on some systems -- other systems may have
- to scan more addresses. If you have to modify this section for your
- installation, please send mail to faith@cs.unc.edu. */
-
- for (i = 0xfff8; i > 0xe000; i -= 8) {
- if (check_region( i, 0x10 )) {
-#if DEBUG_DETECT
- printk( " (%x inuse)," , i );
-#endif
- continue;
- }
- if ((flag = fdomain_is_valid_port( i ))) break;
- }
-
- if (!flag) return 0; /* iobase not found */
-
- *irq = fdomain_get_irq( i );
- *iobase = i;
-
- return 1; /* success */
-}
-
-/* PCI detection function: int fdomain_pci_bios_detect(int* irq, int*
- iobase) This function gets the Interrupt Level and I/O base address from
- the PCI configuration registers. The I/O base address is masked with
- 0xfff8 since on my card the address read from the PCI config registers
- is off by one from the actual I/O base address necessary for accessing
- the status and control registers on the card (PCI config register gives
- 0xf801, actual address is 0xf800). This is likely a bug in the FD
- config code that writes to the PCI registers, however using a mask
- should be safe since I think the scan done by the card to determine the
- I/O base is done in increments of 8 (i.e., 0xf800, 0xf808, ...), at
- least the old scan code we used to use to get the I/O base did... Also,
- the device ID from the PCI config registers is 0x0 and should be 0x60e9
- as it is in the status registers (offset 5 from I/O base). If this is
- changed in future hardware/BIOS changes it will need to be fixed in this
- detection function. Comments, bug reports, etc... on this function
- should be sent to mckinley@msupa.pa.msu.edu - James T. McKinley. */
-
-#ifdef CONFIG_PCI
-static int fdomain_pci_bios_detect( int *irq, int *iobase )
-{
- int error;
- unsigned char pci_bus, pci_dev_fn; /* PCI bus & device function */
- unsigned char pci_irq; /* PCI interrupt line */
- unsigned int pci_base; /* PCI I/O base address */
- unsigned short pci_vendor, pci_device; /* PCI vendor & device IDs */
-
- /* If the PCI BIOS doesn't exist, use the old-style detection routines.
- Otherwise, get the I/O base address and interrupt from the PCI config
- registers. */
-
- if (!pcibios_present()) return fdomain_pci_nobios_detect( irq, iobase );
-
-#if DEBUG_DETECT
- /* Tell how to print a list of the known PCI devices from bios32 and
- list vendor and device IDs being used if in debug mode. */
-
- printk( "\nINFO: cat /proc/pci to see list of PCI devices from bios32\n" );
- printk( "\nTMC-3260 detect:"
- " Using PCI Vendor ID: 0x%x, PCI Device ID: 0x%x\n",
- PCI_VENDOR_ID_FD,
- PCI_DEVICE_ID_FD_36C70 );
-#endif
-
- /* We will have to change this if more than 1 PCI bus is present and the
- FD scsi host is not on the first bus (i.e., a PCI to PCI bridge,
- which is not supported by bios32 right now anyway). This should
- probably be done by a call to pcibios_find_device but I can't get it
- to work... Also the device ID reported from the PCI config registers
- does not match the device ID quoted in the tech manual or available
- from offset 5 from the I/O base address. It should be 0x60E9, but it
- is 0x0 if read from the PCI config registers. I guess the FD folks
- neglected to write it to the PCI registers... This loop is necessary
- to get the device function (at least until someone can get
- pcibios_find_device to work, I cannot but 53c7,8xx.c uses it...). */
-
- pci_bus = 0;
-
- for (pci_dev_fn = 0x0; pci_dev_fn < 0xff; pci_dev_fn++) {
- pcibios_read_config_word( pci_bus,
- pci_dev_fn,
- PCI_VENDOR_ID,
- &pci_vendor );
-
- if (pci_vendor == PCI_VENDOR_ID_FD) {
- pcibios_read_config_word( pci_bus,
- pci_dev_fn,
- PCI_DEVICE_ID,
- &pci_device );
-
- if (pci_device == PCI_DEVICE_ID_FD_36C70) {
- /* Break out once we have the correct device. If other FD
- PCI devices are added to this driver we will need to add
- an or of the other PCI_DEVICE_ID_FD_XXXXX's here. */
- break;
- } else {
- /* If we can't find an FD scsi card we give up. */
- return 0;
- }
- }
- }
-
-#if DEBUG_DETECT
- printk( "Future Domain 36C70 : at PCI bus %u, device %u, function %u\n",
- pci_bus,
- (pci_dev_fn & 0xf8) >> 3,
- pci_dev_fn & 7 );
-#endif
-
- /* We now have the appropriate device function for the FD board so we
- just read the PCI config info from the registers. */
-
- if ((error = pcibios_read_config_dword( pci_bus,
- pci_dev_fn,
- PCI_BASE_ADDRESS_0,
- &pci_base ))
- || (error = pcibios_read_config_byte( pci_bus,
- pci_dev_fn,
- PCI_INTERRUPT_LINE,
- &pci_irq ))) {
- printk ( "PCI ERROR: Future Domain 36C70 not initializing"
- " due to error reading configuration space\n" );
- return 0;
- } else {
-#if DEBUG_DETECT
- printk( "TMC-3260 PCI: IRQ = %u, I/O base = 0x%lx\n",
- pci_irq, pci_base );
-#endif
-
- /* Now we have the I/O base address and interrupt from the PCI
- configuration registers. Unfortunately it seems that the I/O base
- address is off by one on my card so I mask it with 0xfff8. This
- must be some kind of goof in the FD code that does the autoconfig
- and writes to the PCI registers (or maybe I just don't understand
- something). If they fix it in later versions of the card or BIOS
- we may have to adjust the address based on the signature or
- something... */
-
- *irq = pci_irq;
- *iobase = (pci_base & 0xfff8);
-
-#if DEBUG_DETECT
- printk( "TMC-3260 fix: Masking I/O base address with 0xff00.\n" );
- printk( "TMC-3260: IRQ = %d, I/O base = 0x%x\n", *irq, *iobase );
-#endif
-
- if (!fdomain_is_valid_port( *iobase )) return 0;
- return 1;
- }
- return 0;
-}
-#endif
-
-int fdomain_16x0_detect( Scsi_Host_Template *tpnt )
-{
- int i, j;
- int retcode;
- struct Scsi_Host *shpnt;
-#if DO_DETECT
- const int buflen = 255;
- Scsi_Cmnd SCinit;
- unsigned char do_inquiry[] = { INQUIRY, 0, 0, 0, buflen, 0 };
- unsigned char do_request_sense[] = { REQUEST_SENSE, 0, 0, 0, buflen, 0 };
- unsigned char do_read_capacity[] = { READ_CAPACITY,
- 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- unsigned char buf[buflen];
-#endif
-
-#if DEBUG_DETECT
- printk( "fdomain_16x0_detect()," );
-#endif
- tpnt->proc_dir = &proc_scsi_fdomain;
-
- if (setup_called) {
-#if DEBUG_DETECT
- printk( "no BIOS, using port_base = 0x%x, irq = %d\n",
- port_base, interrupt_level );
-#endif
- if (!fdomain_is_valid_port( port_base )) {
- printk( "fdomain: cannot locate chip at port base 0x%x\n",
- port_base );
- printk( "fdomain: bad LILO parameters?\n" );
- return 0;
- }
- } else {
- int flag = 0;
-
- for (i = 0; !bios_base && i < ADDRESS_COUNT; i++) {
-#if DEBUG_DETECT
- printk( " %x(%x),", (unsigned)addresses[i], (unsigned)bios_base );
-#endif
- for (j = 0; !bios_base && j < SIGNATURE_COUNT; j++) {
- if (!memcmp( ((char *)addresses[i] + signatures[j].sig_offset),
- signatures[j].signature, signatures[j].sig_length )) {
- bios_major = signatures[j].major_bios_version;
- bios_minor = signatures[j].minor_bios_version;
- PCI_bus = (signatures[j].flag == 1);
- Quantum = (signatures[j].flag > 1) ? signatures[j].flag : 0;
- bios_base = addresses[i];
- }
- }
- }
-
- if (!bios_base) {
-#if DEBUG_DETECT
- printk( " FAILED: NO BIOS\n" );
-#endif
- return 0;
- }
-
- if (!PCI_bus) {
- flag = fdomain_isa_detect( &interrupt_level, &port_base );
- } else {
-#ifdef CONFIG_PCI
- flag = fdomain_pci_bios_detect( &interrupt_level, &port_base );
-#else
- flag = fdomain_pci_nobios_detect( &interrupt_level, &port_base );
-#endif
- }
-
- if (!flag) {
-#if DEBUG_DETECT
- printk( " FAILED: NO PORT\n" );
-#endif
-#ifdef CONFIG_PCI
- printk( "\nTMC-3260 36C70 PCI scsi chip detection failed.\n" );
- printk( "Send mail to mckinley@msupa.pa.msu.edu.\n" );
-#endif
- return 0; /* Cannot find valid set of ports */
- }
- }
-
- SCSI_Mode_Cntl_port = port_base + SCSI_Mode_Cntl;
- FIFO_Data_Count_port = port_base + FIFO_Data_Count;
- Interrupt_Cntl_port = port_base + Interrupt_Cntl;
- Interrupt_Status_port = port_base + Interrupt_Status;
- Read_FIFO_port = port_base + Read_FIFO;
- Read_SCSI_Data_port = port_base + Read_SCSI_Data;
- SCSI_Cntl_port = port_base + SCSI_Cntl;
- SCSI_Data_NoACK_port = port_base + SCSI_Data_NoACK;
- SCSI_Status_port = port_base + SCSI_Status;
- TMC_Cntl_port = port_base + TMC_Cntl;
- TMC_Status_port = port_base + TMC_Status;
- Write_FIFO_port = port_base + Write_FIFO;
- Write_SCSI_Data_port = port_base + Write_SCSI_Data;
-
- fdomain_16x0_reset( NULL );
-
- if (fdomain_test_loopback()) {
-#if DEBUG_DETECT
- printk( "fdomain: LOOPBACK TEST FAILED, FAILING DETECT!\n" );
-#endif
- if (setup_called) {
- printk( "fdomain: loopback test failed at port base 0x%x\n",
- port_base );
- printk( "fdomain: bad LILO parameters?\n" );
- }
- return 0;
- }
-
- if (this_id) {
- tpnt->this_id = (this_id & 0x07);
- adapter_mask = (1 << tpnt->this_id);
- } else {
- if ((bios_major == 3 && bios_minor >= 2) || bios_major < 0) {
- tpnt->this_id = 7;
- adapter_mask = 0x80;
- } else {
- tpnt->this_id = 6;
- adapter_mask = 0x40;
- }
- }
-
- /* Print out a banner here in case we can't
- get resources. */
-
- shpnt = scsi_register( tpnt, 0 );
- print_banner( shpnt );
-
- /* Log IRQ with kernel */
- if (!interrupt_level) {
- panic( "fdomain: *NO* interrupt level selected!\n" );
- } else {
- /* Register the IRQ with the kernel */
-
- retcode = request_irq( interrupt_level,
- fdomain_16x0_intr, SA_INTERRUPT, "fdomain" );
-
- if (retcode < 0) {
- if (retcode == -EINVAL) {
- printk( "fdomain: IRQ %d is bad!\n", interrupt_level );
- printk( " This shouldn't happen!\n" );
- printk( " Send mail to faith@cs.unc.edu\n" );
- } else if (retcode == -EBUSY) {
- printk( "fdomain: IRQ %d is already in use!\n", interrupt_level );
- printk( " Please use another IRQ!\n" );
- } else {
- printk( "fdomain: Error getting IRQ %d\n", interrupt_level );
- printk( " This shouldn't happen!\n" );
- printk( " Send mail to faith@cs.unc.edu\n" );
- }
- panic( "fdomain: Driver requires interruptions\n" );
- }
- }
-
- /* Log I/O ports with kernel */
- request_region( port_base, 0x10, "fdomain" );
-
-#if DO_DETECT
-
- /* These routines are here because of the way the SCSI bus behaves after
- a reset. This appropriate behavior was not handled correctly by the
- higher level SCSI routines when I first wrote this driver. Now,
- however, correct scan routines are part of scsi.c and these routines
- are no longer needed. However, this code is still good for
- debugging. */
-
- SCinit.request_buffer = SCinit.buffer = buf;
- SCinit.request_bufflen = SCinit.bufflen = sizeof(buf)-1;
- SCinit.use_sg = 0;
- SCinit.lun = 0;
-
- printk( "fdomain: detection routine scanning for devices:\n" );
- for (i = 0; i < 8; i++) {
- SCinit.target = i;
- if (i == tpnt->this_id) /* Skip host adapter */
- continue;
- memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
- retcode = fdomain_16x0_command(&SCinit);
- if (!retcode) {
- memcpy(SCinit.cmnd, do_inquiry, sizeof(do_inquiry));
- retcode = fdomain_16x0_command(&SCinit);
- if (!retcode) {
- printk( " SCSI ID %d: ", i );
- for (j = 8; j < (buf[4] < 32 ? buf[4] : 32); j++)
- printk( "%c", buf[j] >= 20 ? buf[j] : ' ' );
- memcpy(SCinit.cmnd, do_read_capacity, sizeof(do_read_capacity));
- retcode = fdomain_16x0_command(&SCinit);
- if (!retcode) {
- unsigned long blocks, size, capacity;
-
- blocks = (buf[0] << 24) | (buf[1] << 16)
- | (buf[2] << 8) | buf[3];
- size = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
- capacity = +( +(blocks / 1024L) * +(size * 10L)) / 1024L;
-
- printk( "%lu MB (%lu byte blocks)",
- ((capacity + 5L) / 10L), size );
- } else {
- memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
- retcode = fdomain_16x0_command(&SCinit);
- }
- printk ("\n" );
- } else {
- memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
- retcode = fdomain_16x0_command(&SCinit);
- }
- }
- }
-#endif
-
- return 1; /* Maximum of one adapter will be detected. */
-}
-
-const char *fdomain_16x0_info( struct Scsi_Host *ignore )
-{
- static char buffer[80];
- char *pt;
-
- strcpy( buffer, "Future Domain TMC-16x0 SCSI driver, version" );
- if (strchr( VERSION, ':')) { /* Assume VERSION is an RCS Revision string */
- strcat( buffer, strchr( VERSION, ':' ) + 1 );
- pt = strrchr( buffer, '$') - 1;
- if (!pt) /* Stripped RCS Revision string? */
- pt = buffer + strlen( buffer ) - 1;
- if (*pt != ' ')
- ++pt;
- *pt = '\0';
- } else { /* Assume VERSION is a number */
- strcat( buffer, " " VERSION );
- }
-
- return buffer;
-}
-
- /* First pass at /proc information routine. */
-/*
- * inout : decides on the direction of the dataflow and the meaning of the
- * variables
- * buffer: If inout==FALSE data is beeing written to it else read from it
- * *start: If inout==FALSE start of the valid data in the buffer
- * offset: If inout==FALSE offset from the beginning of the imaginary file
- * from which we start writing into the buffer
- * length: If inout==FALSE max number of bytes to be written into the buffer
- * else number of bytes in the buffer
- */
-int fdomain_16x0_proc_info( char *buffer, char **start, off_t offset,
- int length, int hostno, int inout )
-{
- const char *info = fdomain_16x0_info( NULL );
- int len;
- int pos;
- int begin;
-
- if (inout) return(-ENOSYS);
-
- begin = 0;
- strcpy( buffer, info );
- strcat( buffer, "\n" );
-
- pos = len = strlen( buffer );
-
- if(pos < offset) {
- len = 0;
- begin = pos;
- }
-
- *start = buffer + (offset - begin); /* Start of wanted data */
- len -= (offset - begin);
- if(len > length) len = length;
-
- return(len);
-}
-
-#if 0
-static int fdomain_arbitrate( void )
-{
- int status = 0;
- unsigned long timeout;
-
-#if EVERY_ACCESS
- printk( "fdomain_arbitrate()\n" );
-#endif
-
- outb( 0x00, SCSI_Cntl_port ); /* Disable data drivers */
- outb( adapter_mask, port_base + SCSI_Data_NoACK ); /* Set our id bit */
- outb( 0x04 | PARITY_MASK, TMC_Cntl_port ); /* Start arbitration */
-
- timeout = jiffies + 50; /* 500 mS */
- while (jiffies < timeout) {
- status = inb( TMC_Status_port ); /* Read adapter status */
- if (status & 0x02) /* Arbitration complete */
- return 0;
- }
-
- /* Make bus idle */
- fdomain_make_bus_idle();
-
-#if EVERY_ACCESS
- printk( "Arbitration failed, status = %x\n", status );
-#endif
-#if ERRORS_ONLY
- printk( "fdomain: Arbitration failed, status = %x\n", status );
-#endif
- return 1;
-}
-#endif
-
-static int fdomain_select( int target )
-{
- int status;
- unsigned long timeout;
- static int flag = 0;
-
-
- outb( 0x82, SCSI_Cntl_port ); /* Bus Enable + Select */
- outb( adapter_mask | (1 << target), SCSI_Data_NoACK_port );
-
- /* Stop arbitration and enable parity */
- outb( PARITY_MASK, TMC_Cntl_port );
-
- timeout = jiffies + 35; /* 350mS -- because of timeouts
- (was 250mS) */
-
- while (jiffies < timeout) {
- status = inb( SCSI_Status_port ); /* Read adapter status */
- if (status & 1) { /* Busy asserted */
- /* Enable SCSI Bus (on error, should make bus idle with 0) */
- outb( 0x80, SCSI_Cntl_port );
- return 0;
- }
- }
- /* Make bus idle */
- fdomain_make_bus_idle();
-#if EVERY_ACCESS
- if (!target) printk( "Selection failed\n" );
-#endif
-#if ERRORS_ONLY
- if (!target) {
- if (chip == tmc18c30 && !flag) /* Skip first failure for 18C30 chips. */
- ++flag;
- else
- printk( "fdomain: Selection failed\n" );
- }
-#endif
- return 1;
-}
-
-void my_done( int error )
-{
- if (in_command) {
- in_command = 0;
- outb( 0x00, Interrupt_Cntl_port );
- fdomain_make_bus_idle();
- current_SC->result = error;
- if (current_SC->scsi_done)
- current_SC->scsi_done( current_SC );
- else panic( "fdomain: current_SC->scsi_done() == NULL" );
- } else {
- panic( "fdomain: my_done() called outside of command\n" );
- }
-#if DEBUG_RACE
- in_interrupt_flag = 0;
-#endif
-}
-
-void fdomain_16x0_intr( int irq, struct pt_regs * regs )
-{
- int status;
- int done = 0;
- unsigned data_count;
-
- /* The fdomain_16x0_intr is only called via
- the interrupt handler. The goal of the
- sti() here is to allow other
- interruptions while this routine is
- running. */
-
- sti(); /* Yes, we really want sti() here */
-
- outb( 0x00, Interrupt_Cntl_port );
-
- /* We usually have one spurious interrupt after each command. Ignore it. */
- if (!in_command || !current_SC) { /* Spurious interrupt */
-#if EVERY_ACCESS
- printk( "Spurious interrupt, in_command = %d, current_SC = %x\n",
- in_command, current_SC );
-#endif
- return;
- }
-
- /* Abort calls my_done, so we do nothing here. */
- if (current_SC->SCp.phase & aborted) {
-#if DEBUG_ABORT
- printk( "Interrupt after abort, ignoring\n" );
-#endif
- /*
- return; */
- }
-
-#if DEBUG_RACE
- ++in_interrupt_flag;
-#endif
-
- if (current_SC->SCp.phase & in_arbitration) {
- status = inb( TMC_Status_port ); /* Read adapter status */
- if (!(status & 0x02)) {
-#if EVERY_ACCESS
- printk( " AFAIL " );
-#endif
- my_done( DID_BUS_BUSY << 16 );
- return;
- }
- current_SC->SCp.phase = in_selection;
-
- outb( 0x40 | FIFO_COUNT, Interrupt_Cntl_port );
-
- outb( 0x82, SCSI_Cntl_port ); /* Bus Enable + Select */
- outb( adapter_mask | (1 << current_SC->target), SCSI_Data_NoACK_port );
-
- /* Stop arbitration and enable parity */
- outb( 0x10 | PARITY_MASK, TMC_Cntl_port );
-#if DEBUG_RACE
- in_interrupt_flag = 0;
-#endif
- return;
- } else if (current_SC->SCp.phase & in_selection) {
- status = inb( SCSI_Status_port );
- if (!(status & 0x01)) {
- /* Try again, for slow devices */
- if (fdomain_select( current_SC->target )) {
-#if EVERY_ACCESS
- printk( " SFAIL " );
-#endif
- my_done( DID_NO_CONNECT << 16 );
- return;
- } else {
-#if EVERY_ACCESS
- printk( " AltSel " );
-#endif
- /* Stop arbitration and enable parity */
- outb( 0x10 | PARITY_MASK, TMC_Cntl_port );
- }
- }
- current_SC->SCp.phase = in_other;
- outb( 0x90 | FIFO_COUNT, Interrupt_Cntl_port );
- outb( 0x80, SCSI_Cntl_port );
-#if DEBUG_RACE
- in_interrupt_flag = 0;
-#endif
- return;
- }
-
- /* current_SC->SCp.phase == in_other: this is the body of the routine */
-
- status = inb( SCSI_Status_port );
-
- if (status & 0x10) { /* REQ */
-
- switch (status & 0x0e) {
-
- case 0x08: /* COMMAND OUT */
- outb( current_SC->cmnd[current_SC->SCp.sent_command++],
- Write_SCSI_Data_port );
-#if EVERY_ACCESS
- printk( "CMD = %x,",
- current_SC->cmnd[ current_SC->SCp.sent_command - 1] );
-#endif
- break;
- case 0x00: /* DATA OUT -- tmc18c50/tmc18c30 only */
- if (chip != tmc1800 && !current_SC->SCp.have_data_in) {
- current_SC->SCp.have_data_in = -1;
- outb( 0xd0 | PARITY_MASK, TMC_Cntl_port );
- }
- break;
- case 0x04: /* DATA IN -- tmc18c50/tmc18c30 only */
- if (chip != tmc1800 && !current_SC->SCp.have_data_in) {
- current_SC->SCp.have_data_in = 1;
- outb( 0x90 | PARITY_MASK, TMC_Cntl_port );
- }
- break;
- case 0x0c: /* STATUS IN */
- current_SC->SCp.Status = inb( Read_SCSI_Data_port );
-#if EVERY_ACCESS
- printk( "Status = %x, ", current_SC->SCp.Status );
-#endif
-#if ERRORS_ONLY
- if (current_SC->SCp.Status && current_SC->SCp.Status != 2) {
- printk( "fdomain: target = %d, command = %x, status = %x\n",
- current_SC->target,
- current_SC->cmnd[0],
- current_SC->SCp.Status );
- }
-#endif
- break;
- case 0x0a: /* MESSAGE OUT */
- outb( MESSAGE_REJECT, Write_SCSI_Data_port ); /* Reject */
- break;
- case 0x0e: /* MESSAGE IN */
- current_SC->SCp.Message = inb( Read_SCSI_Data_port );
-#if EVERY_ACCESS
- printk( "Message = %x, ", current_SC->SCp.Message );
-#endif
- if (!current_SC->SCp.Message) ++done;
-#if DEBUG_MESSAGES || EVERY_ACCESS
- if (current_SC->SCp.Message) {
- printk( "fdomain: message = %x\n", current_SC->SCp.Message );
- }
-#endif
- break;
- }
- }
-
- if (chip == tmc1800
- && !current_SC->SCp.have_data_in
- && (current_SC->SCp.sent_command
- >= current_SC->cmd_len)) {
- /* We have to get the FIFO direction
- correct, so I've made a table based
- on the SCSI Standard of which commands
- appear to require a DATA OUT phase.
- */
- /*
- p. 94: Command for all device types
- CHANGE DEFINITION 40 DATA OUT
- COMPARE 39 DATA OUT
- COPY 18 DATA OUT
- COPY AND VERIFY 3a DATA OUT
- INQUIRY 12
- LOG SELECT 4c DATA OUT
- LOG SENSE 4d
- MODE SELECT (6) 15 DATA OUT
- MODE SELECT (10) 55 DATA OUT
- MODE SENSE (6) 1a
- MODE SENSE (10) 5a
- READ BUFFER 3c
- RECEIVE DIAGNOSTIC RESULTS 1c
- REQUEST SENSE 03
- SEND DIAGNOSTIC 1d DATA OUT
- TEST UNIT READY 00
- WRITE BUFFER 3b DATA OUT
-
- p.178: Commands for direct-access devices (not listed on p. 94)
- FORMAT UNIT 04 DATA OUT
- LOCK-UNLOCK CACHE 36
- PRE-FETCH 34
- PREVENT-ALLOW MEDIUM REMOVAL 1e
- READ (6)/RECEIVE 08
- READ (10) 3c
- READ CAPACITY 25
- READ DEFECT DATA (10) 37
- READ LONG 3e
- REASSIGN BLOCKS 07 DATA OUT
- RELEASE 17
- RESERVE 16 DATA OUT
- REZERO UNIT/REWIND 01
- SEARCH DATA EQUAL (10) 31 DATA OUT
- SEARCH DATA HIGH (10) 30 DATA OUT
- SEARCH DATA LOW (10) 32 DATA OUT
- SEEK (6) 0b
- SEEK (10) 2b
- SET LIMITS (10) 33
- START STOP UNIT 1b
- SYNCHRONIZE CACHE 35
- VERIFY (10) 2f
- WRITE (6)/PRINT/SEND 0a DATA OUT
- WRITE (10)/SEND 2a DATA OUT
- WRITE AND VERIFY (10) 2e DATA OUT
- WRITE LONG 3f DATA OUT
- WRITE SAME 41 DATA OUT ?
-
- p. 261: Commands for sequential-access devices (not previously listed)
- ERASE 19
- LOAD UNLOAD 1b
- LOCATE 2b
- READ BLOCK LIMITS 05
- READ POSITION 34
- READ REVERSE 0f
- RECOVER BUFFERED DATA 14
- SPACE 11
- WRITE FILEMARKS 10 ?
-
- p. 298: Commands for printer devices (not previously listed)
- ****** NOT SUPPORTED BY THIS DRIVER, since 0b is SEEK (6) *****
- SLEW AND PRINT 0b DATA OUT -- same as seek
- STOP PRINT 1b
- SYNCHRONIZE BUFFER 10
-
- p. 315: Commands for processor devices (not previously listed)
-
- p. 321: Commands for write-once devices (not previously listed)
- MEDIUM SCAN 38
- READ (12) a8
- SEARCH DATA EQUAL (12) b1 DATA OUT
- SEARCH DATA HIGH (12) b0 DATA OUT
- SEARCH DATA LOW (12) b2 DATA OUT
- SET LIMITS (12) b3
- VERIFY (12) af
- WRITE (12) aa DATA OUT
- WRITE AND VERIFY (12) ae DATA OUT
-
- p. 332: Commands for CD-ROM devices (not previously listed)
- PAUSE/RESUME 4b
- PLAY AUDIO (10) 45
- PLAY AUDIO (12) a5
- PLAY AUDIO MSF 47
- PLAY TRACK RELATIVE (10) 49
- PLAY TRACK RELATIVE (12) a9
- READ HEADER 44
- READ SUB-CHANNEL 42
- READ TOC 43
-
- p. 370: Commands for scanner devices (not previously listed)
- GET DATA BUFFER STATUS 34
- GET WINDOW 25
- OBJECT POSITION 31
- SCAN 1b
- SET WINDOW 24 DATA OUT
-
- p. 391: Commands for optical memory devices (not listed)
- ERASE (10) 2c
- ERASE (12) ac
- MEDIUM SCAN 38 DATA OUT
- READ DEFECT DATA (12) b7
- READ GENERATION 29
- READ UPDATED BLOCK 2d
- UPDATE BLOCK 3d DATA OUT
-
- p. 419: Commands for medium changer devices (not listed)
- EXCHANGE MEDIUM 46
- INITIALIZE ELEMENT STATUS 07
- MOVE MEDIUM a5
- POSITION TO ELEMENT 2b
- READ ELEMENT STATUS b8
- REQUEST VOL. ELEMENT ADDRESS b5
- SEND VOLUME TAG b6 DATA OUT
-
- p. 454: Commands for communications devices (not listed previously)
- GET MESSAGE (6) 08
- GET MESSAGE (10) 28
- GET MESSAGE (12) a8
- */
-
- switch (current_SC->cmnd[0]) {
- case CHANGE_DEFINITION: case COMPARE: case COPY:
- case COPY_VERIFY: case LOG_SELECT: case MODE_SELECT:
- case MODE_SELECT_10: case SEND_DIAGNOSTIC: case WRITE_BUFFER:
-
- case FORMAT_UNIT: case REASSIGN_BLOCKS: case RESERVE:
- case SEARCH_EQUAL: case SEARCH_HIGH: case SEARCH_LOW:
- case WRITE_6: case WRITE_10: case WRITE_VERIFY:
- case 0x3f: case 0x41:
-
- case 0xb1: case 0xb0: case 0xb2:
- case 0xaa: case 0xae:
-
- case 0x24:
-
- case 0x38: case 0x3d:
-
- case 0xb6:
-
- case 0xea: /* alternate number for WRITE LONG */
-
- current_SC->SCp.have_data_in = -1;
- outb( 0xd0 | PARITY_MASK, TMC_Cntl_port );
- break;
-
- case 0x00:
- default:
-
- current_SC->SCp.have_data_in = 1;
- outb( 0x90 | PARITY_MASK, TMC_Cntl_port );
- break;
- }
- }
-
- if (current_SC->SCp.have_data_in == -1) { /* DATA OUT */
- while ( (data_count = FIFO_Size - inw( FIFO_Data_Count_port )) > 512 ) {
-#if EVERY_ACCESS
- printk( "DC=%d, ", data_count ) ;
-#endif
- if (data_count > current_SC->SCp.this_residual)
- data_count = current_SC->SCp.this_residual;
- if (data_count > 0) {
-#if EVERY_ACCESS
- printk( "%d OUT, ", data_count );
-#endif
- if (data_count == 1) {
- outb( *current_SC->SCp.ptr++, Write_FIFO_port );
- --current_SC->SCp.this_residual;
- } else {
- data_count >>= 1;
- outsw( Write_FIFO_port, current_SC->SCp.ptr, data_count );
- current_SC->SCp.ptr += 2 * data_count;
- current_SC->SCp.this_residual -= 2 * data_count;
- }
- }
- if (!current_SC->SCp.this_residual) {
- if (current_SC->SCp.buffers_residual) {
- --current_SC->SCp.buffers_residual;
- ++current_SC->SCp.buffer;
- current_SC->SCp.ptr = current_SC->SCp.buffer->address;
- current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
- } else
- break;
- }
- }
- }
-
- if (current_SC->SCp.have_data_in == 1) { /* DATA IN */
- while ((data_count = inw( FIFO_Data_Count_port )) > 0) {
-#if EVERY_ACCESS
- printk( "DC=%d, ", data_count );
-#endif
- if (data_count > current_SC->SCp.this_residual)
- data_count = current_SC->SCp.this_residual;
- if (data_count) {
-#if EVERY_ACCESS
- printk( "%d IN, ", data_count );
-#endif
- if (data_count == 1) {
- *current_SC->SCp.ptr++ = inb( Read_FIFO_port );
- --current_SC->SCp.this_residual;
- } else {
- data_count >>= 1; /* Number of words */
- insw( Read_FIFO_port, current_SC->SCp.ptr, data_count );
- current_SC->SCp.ptr += 2 * data_count;
- current_SC->SCp.this_residual -= 2 * data_count;
- }
- }
- if (!current_SC->SCp.this_residual
- && current_SC->SCp.buffers_residual) {
- --current_SC->SCp.buffers_residual;
- ++current_SC->SCp.buffer;
- current_SC->SCp.ptr = current_SC->SCp.buffer->address;
- current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
- }
- }
- }
-
- if (done) {
-#if EVERY_ACCESS
- printk( " ** IN DONE %d ** ", current_SC->SCp.have_data_in );
-#endif
-
-#if ERRORS_ONLY
- if (current_SC->cmnd[0] == REQUEST_SENSE && !current_SC->SCp.Status) {
- if ((unsigned char)(*((char *)current_SC->request_buffer+2)) & 0x0f) {
- unsigned char key;
- unsigned char code;
- unsigned char qualifier;
-
- key = (unsigned char)(*((char *)current_SC->request_buffer + 2))
- & 0x0f;
- code = (unsigned char)(*((char *)current_SC->request_buffer + 12));
- qualifier = (unsigned char)(*((char *)current_SC->request_buffer
- + 13));
-
- if (!(key == UNIT_ATTENTION && (code == 0x29 || !code))
- && !(key == NOT_READY
- && code == 0x04
- && (!qualifier || qualifier == 0x02 || qualifier == 0x01))
- && !(key == ILLEGAL_REQUEST && (code == 0x25
- || code == 0x24
- || !code)))
-
- printk( "fdomain: REQUEST SENSE "
- "Key = %x, Code = %x, Qualifier = %x\n",
- key, code, qualifier );
- }
- }
-#endif
-#if EVERY_ACCESS
- printk( "BEFORE MY_DONE. . ." );
-#endif
- my_done( (current_SC->SCp.Status & 0xff)
- | ((current_SC->SCp.Message & 0xff) << 8) | (DID_OK << 16) );
-#if EVERY_ACCESS
- printk( "RETURNING.\n" );
-#endif
-
- } else {
- if (current_SC->SCp.phase & disconnect) {
- outb( 0xd0 | FIFO_COUNT, Interrupt_Cntl_port );
- outb( 0x00, SCSI_Cntl_port );
- } else {
- outb( 0x90 | FIFO_COUNT, Interrupt_Cntl_port );
- }
- }
-#if DEBUG_RACE
- in_interrupt_flag = 0;
-#endif
- return;
-}
-
-int fdomain_16x0_queue( Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
-{
- if (in_command) {
- panic( "fdomain: fdomain_16x0_queue() NOT REENTRANT!\n" );
- }
-#if EVERY_ACCESS
- printk( "queue: target = %d cmnd = 0x%02x pieces = %d size = %u\n",
- SCpnt->target,
- *(unsigned char *)SCpnt->cmnd,
- SCpnt->use_sg,
- SCpnt->request_bufflen );
-#endif
-
- fdomain_make_bus_idle();
-
- current_SC = SCpnt; /* Save this for the done function */
- current_SC->scsi_done = done;
-
- /* Initialize static data */
-
- if (current_SC->use_sg) {
- current_SC->SCp.buffer =
- (struct scatterlist *)current_SC->request_buffer;
- current_SC->SCp.ptr = current_SC->SCp.buffer->address;
- current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
- current_SC->SCp.buffers_residual = current_SC->use_sg - 1;
- } else {
- current_SC->SCp.ptr = (char *)current_SC->request_buffer;
- current_SC->SCp.this_residual = current_SC->request_bufflen;
- current_SC->SCp.buffer = NULL;
- current_SC->SCp.buffers_residual = 0;
- }
-
-
- current_SC->SCp.Status = 0;
- current_SC->SCp.Message = 0;
- current_SC->SCp.have_data_in = 0;
- current_SC->SCp.sent_command = 0;
- current_SC->SCp.phase = in_arbitration;
-
- /* Start arbitration */
- outb( 0x00, Interrupt_Cntl_port );
- outb( 0x00, SCSI_Cntl_port ); /* Disable data drivers */
- outb( adapter_mask, SCSI_Data_NoACK_port ); /* Set our id bit */
- ++in_command;
- outb( 0x20, Interrupt_Cntl_port );
- outb( 0x14 | PARITY_MASK, TMC_Cntl_port ); /* Start arbitration */
-
- return 0;
-}
-
-/* The following code, which simulates the old-style command function, was
- taken from Tommy Thorn's aha1542.c file. This code is Copyright (C)
- 1992 Tommy Thorn. */
-
-static volatile int internal_done_flag = 0;
-static volatile int internal_done_errcode = 0;
-
-static void internal_done( Scsi_Cmnd *SCpnt )
-{
- internal_done_errcode = SCpnt->result;
- ++internal_done_flag;
-}
-
-int fdomain_16x0_command( Scsi_Cmnd *SCpnt )
-{
- fdomain_16x0_queue( SCpnt, internal_done );
-
- while (!internal_done_flag)
- ;
- internal_done_flag = 0;
- return internal_done_errcode;
-}
-
-/* End of code derived from Tommy Thorn's work. */
-
-void print_info( Scsi_Cmnd *SCpnt )
-{
- unsigned int imr;
- unsigned int irr;
- unsigned int isr;
-
- if (!SCpnt || !SCpnt->host) {
- printk( "fdomain: cannot provide detailed information\n" );
- }
-
- printk( "%s\n", fdomain_16x0_info( SCpnt->host ) );
- print_banner( SCpnt->host );
- switch (SCpnt->SCp.phase) {
- case in_arbitration: printk( "arbitration " ); break;
- case in_selection: printk( "selection " ); break;
- case in_other: printk( "other " ); break;
- default: printk( "unknown " ); break;
- }
-
- printk( "(%d), target = %d cmnd = 0x%02x pieces = %d size = %u\n",
- SCpnt->SCp.phase,
- SCpnt->target,
- *(unsigned char *)SCpnt->cmnd,
- SCpnt->use_sg,
- SCpnt->request_bufflen );
- printk( "sent_command = %d, have_data_in = %d, timeout = %d\n",
- SCpnt->SCp.sent_command,
- SCpnt->SCp.have_data_in,
- SCpnt->timeout );
-#if DEBUG_RACE
- printk( "in_interrupt_flag = %d\n", in_interrupt_flag );
-#endif
-
- imr = (inb( 0x0a1 ) << 8) + inb( 0x21 );
- outb( 0x0a, 0xa0 );
- irr = inb( 0xa0 ) << 8;
- outb( 0x0a, 0x20 );
- irr += inb( 0x20 );
- outb( 0x0b, 0xa0 );
- isr = inb( 0xa0 ) << 8;
- outb( 0x0b, 0x20 );
- isr += inb( 0x20 );
-
- /* Print out interesting information */
- printk( "IMR = 0x%04x", imr );
- if (imr & (1 << interrupt_level))
- printk( " (masked)" );
- printk( ", IRR = 0x%04x, ISR = 0x%04x\n", irr, isr );
-
- printk( "SCSI Status = 0x%02x\n", inb( SCSI_Status_port ) );
- printk( "TMC Status = 0x%02x", inb( TMC_Status_port ) );
- if (inb( TMC_Status_port & 1))
- printk( " (interrupt)" );
- printk( "\n" );
- printk( "Interrupt Status = 0x%02x", inb( Interrupt_Status_port ) );
- if (inb( Interrupt_Status_port ) & 0x08)
- printk( " (enabled)" );
- printk( "\n" );
- if (chip == tmc18c50 || chip == tmc18c30) {
- printk( "FIFO Status = 0x%02x\n", inb( port_base + FIFO_Status ) );
- printk( "Int. Condition = 0x%02x\n",
- inb( port_base + Interrupt_Cond ) );
- }
- printk( "Configuration 1 = 0x%02x\n", inb( port_base + Configuration1 ) );
- if (chip == tmc18c50 || chip == tmc18c30)
- printk( "Configuration 2 = 0x%02x\n",
- inb( port_base + Configuration2 ) );
-}
-
-int fdomain_16x0_abort( Scsi_Cmnd *SCpnt)
-{
- unsigned long flags;
-#if EVERY_ACCESS || ERRORS_ONLY || DEBUG_ABORT
- printk( "fdomain: abort " );
-#endif
-
- save_flags( flags );
- cli();
- if (!in_command) {
-#if EVERY_ACCESS || ERRORS_ONLY
- printk( " (not in command)\n" );
-#endif
- restore_flags( flags );
- return SCSI_ABORT_NOT_RUNNING;
- } else printk( "\n" );
-
-#if DEBUG_ABORT
- print_info( SCpnt );
-#endif
-
- fdomain_make_bus_idle();
-
- current_SC->SCp.phase |= aborted;
-
- current_SC->result = DID_ABORT << 16;
-
- restore_flags( flags );
-
- /* Aborts are not done well. . . */
- my_done( DID_ABORT << 16 );
-
- return SCSI_ABORT_SUCCESS;
-}
-
-int fdomain_16x0_reset( Scsi_Cmnd *SCpnt )
-{
-#if DEBUG_RESET
- static int called_once = 0;
-#endif
-
-#if ERRORS_ONLY
- if (SCpnt) printk( "fdomain: SCSI Bus Reset\n" );
-#endif
-
-#if DEBUG_RESET
- if (called_once) print_info( current_SC );
- called_once = 1;
-#endif
-
- outb( 1, SCSI_Cntl_port );
- do_pause( 2 );
- outb( 0, SCSI_Cntl_port );
- do_pause( 115 );
- outb( 0, SCSI_Mode_Cntl_port );
- outb( PARITY_MASK, TMC_Cntl_port );
-
- /* Unless this is the very first call (i.e., SCPnt == NULL), everything
- is probably hosed at this point. We will, however, try to keep
- things going by informing the high-level code that we need help. */
-
- return SCSI_RESET_WAKEUP;
-}
-
-#include "sd.h"
-#include "scsi_ioctl.h"
-
-int fdomain_16x0_biosparam( Scsi_Disk *disk, kdev_t dev, int *info_array )
-{
- int drive;
- unsigned char buf[512 + sizeof( int ) * 2];
- int size = disk->capacity;
- int *sizes = (int *)buf;
- unsigned char *data = (unsigned char *)(sizes + 2);
- unsigned char do_read[] = { READ_6, 0, 0, 0, 1, 0 };
- int retcode;
- struct drive_info {
- unsigned short cylinders;
- unsigned char heads;
- unsigned char sectors;
- } *i;
-
- /* NOTES:
- The RAM area starts at 0x1f00 from the bios_base address.
-
- For BIOS Version 2.0:
-
- The drive parameter table seems to start at 0x1f30.
- The first byte's purpose is not known.
- Next is the cylinder, head, and sector information.
- The last 4 bytes appear to be the drive's size in sectors.
- The other bytes in the drive parameter table are unknown.
- If anyone figures them out, please send me mail, and I will
- update these notes.
-
- Tape drives do not get placed in this table.
-
- There is another table at 0x1fea:
- If the byte is 0x01, then the SCSI ID is not in use.
- If the byte is 0x18 or 0x48, then the SCSI ID is in use,
- although tapes don't seem to be in this table. I haven't
- seen any other numbers (in a limited sample).
-
- 0x1f2d is a drive count (i.e., not including tapes)
-
- The table at 0x1fcc are I/O ports addresses for the various
- operations. I calculate these by hand in this driver code.
-
-
-
- For the ISA-200S version of BIOS Version 2.0:
-
- The drive parameter table starts at 0x1f33.
-
- WARNING: Assume that the table entry is 25 bytes long. Someone needs
- to check this for the Quantum ISA-200S card.
-
-
-
- For BIOS Version 3.2:
-
- The drive parameter table starts at 0x1f70. Each entry is
- 0x0a bytes long. Heads are one less than we need to report.
- */
-
- drive = MINOR(dev) / 16;
-
- if (bios_major == 2) {
- switch (Quantum) {
- case 2: /* ISA_200S */
- /* The value of 25 has never been verified.
- It should probably be 15. */
- i = (struct drive_info *)( (char *)bios_base + 0x1f33 + drive * 25 );
- break;
- case 3: /* ISA_250MG */
- i = (struct drive_info *)( (char *)bios_base + 0x1f36 + drive * 15 );
- break;
- case 4: /* ISA_200S (another one) */
- i = (struct drive_info *)( (char *)bios_base + 0x1f34 + drive * 15 );
- break;
- default:
- i = (struct drive_info *)( (char *)bios_base + 0x1f31 + drive * 25 );
- break;
- }
- info_array[0] = i->heads;
- info_array[1] = i->sectors;
- info_array[2] = i->cylinders;
- } else if (bios_major == 3
- && bios_minor >= 0
- && bios_minor < 4) { /* 3.0 and 3.2 BIOS */
- i = (struct drive_info *)( (char *)bios_base + 0x1f71 + drive * 10 );
- info_array[0] = i->heads + 1;
- info_array[1] = i->sectors;
- info_array[2] = i->cylinders;
- } else { /* 3.4 BIOS (and up?) */
- /* This algorithm was provided by Future Domain (much thanks!). */
-
- sizes[0] = 0; /* zero bytes out */
- sizes[1] = 512; /* one sector in */
- memcpy( data, do_read, sizeof( do_read ) );
- retcode = kernel_scsi_ioctl( disk->device,
- SCSI_IOCTL_SEND_COMMAND,
- (void *)buf );
- if (!retcode /* SCSI command ok */
- && data[511] == 0xaa && data[510] == 0x55 /* Partition table valid */
- && data[0x1c2]) { /* Partition type */
-
- /* The partition table layout is as follows:
-
- Start: 0x1b3h
- Offset: 0 = partition status
- 1 = starting head
- 2 = starting sector and cylinder (word, encoded)
- 4 = partition type
- 5 = ending head
- 6 = ending sector and cylinder (word, encoded)
- 8 = starting absolute sector (double word)
- c = number of sectors (double word)
- Signature: 0x1fe = 0x55aa
-
- So, this algorithm assumes:
- 1) the first partition table is in use,
- 2) the data in the first entry is correct, and
- 3) partitions never divide cylinders
-
- Note that (1) may be FALSE for NetBSD (and other BSD flavors),
- as well as for Linux. Note also, that Linux doesn't pay any
- attention to the fields that are used by this algorithm -- it
- only uses the absolute sector data. Recent versions of Linux's
- fdisk(1) will fill this data in correctly, and forthcoming
- versions will check for consistency.
-
- Checking for a non-zero partition type is not part of the
- Future Domain algorithm, but it seemed to be a reasonable thing
- to do, especially in the Linux and BSD worlds. */
-
- info_array[0] = data[0x1c3] + 1; /* heads */
- info_array[1] = data[0x1c4] & 0x3f; /* sectors */
- } else {
-
- /* Note that this new method guarantees that there will always be
- less than 1024 cylinders on a platter. This is good for drives
- up to approximately 7.85GB (where 1GB = 1024 * 1024 kB). */
-
- if ((unsigned int)size >= 0x7e0000U) {
- info_array[0] = 0xff; /* heads = 255 */
- info_array[1] = 0x3f; /* sectors = 63 */
- } else if ((unsigned int)size >= 0x200000U) {
- info_array[0] = 0x80; /* heads = 128 */
- info_array[1] = 0x3f; /* sectors = 63 */
- } else {
- info_array[0] = 0x40; /* heads = 64 */
- info_array[1] = 0x20; /* sectors = 32 */
- }
- }
- /* For both methods, compute the cylinders */
- info_array[2] = (unsigned int)size / (info_array[0] * info_array[1] );
- }
-
- return 0;
-}
-
-#ifdef MODULE
-/* Eventually this will go into an include file, but this will be later */
-Scsi_Host_Template driver_template = FDOMAIN_16X0;
-
-#include "scsi_module.c"
-#endif
diff --git a/i386/i386at/gpl/linux/scsi/fdomain.h b/i386/i386at/gpl/linux/scsi/fdomain.h
deleted file mode 100644
index e0c4e045..00000000
--- a/i386/i386at/gpl/linux/scsi/fdomain.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* fdomain.h -- Header for Future Domain TMC-16x0 driver
- * Created: Sun May 3 18:47:33 1992 by faith@cs.unc.edu
- * Revised: Thu Oct 12 13:21:35 1995 by r.faith@ieee.org
- * Author: Rickard E. Faith, faith@cs.unc.edu
- * Copyright 1992, 1993, 1994, 1995 Rickard E. Faith
- *
- * $Id: fdomain.h,v 1.1.1.1 1997/02/25 21:27:49 thomas Exp $
-
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
-
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
-
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
-
- */
-
-#ifndef _FDOMAIN_H
-#define _FDOMAIN_H
-
-int fdomain_16x0_detect( Scsi_Host_Template * );
-int fdomain_16x0_command( Scsi_Cmnd * );
-int fdomain_16x0_abort( Scsi_Cmnd * );
-const char *fdomain_16x0_info( struct Scsi_Host * );
-int fdomain_16x0_reset( Scsi_Cmnd * );
-int fdomain_16x0_queue( Scsi_Cmnd *, void (*done)(Scsi_Cmnd *) );
-int fdomain_16x0_biosparam( Disk *, kdev_t, int * );
-int fdomain_16x0_proc_info( char *buffer, char **start, off_t offset,
- int length, int hostno, int inout );
-
-extern struct proc_dir_entry proc_scsi_fdomain;
-
-#define FDOMAIN_16X0 { NULL, \
- NULL, \
- NULL, \
- fdomain_16x0_proc_info, \
- NULL, \
- fdomain_16x0_detect, \
- NULL, \
- fdomain_16x0_info, \
- fdomain_16x0_command, \
- fdomain_16x0_queue, \
- fdomain_16x0_abort, \
- fdomain_16x0_reset, \
- NULL, \
- fdomain_16x0_biosparam, \
- 1, \
- 6, \
- 64, \
- 1, \
- 0, \
- 0, \
- DISABLE_CLUSTERING }
-#endif
diff --git a/i386/i386at/gpl/linux/scsi/g_NCR5380.c b/i386/i386at/gpl/linux/scsi/g_NCR5380.c
deleted file mode 100644
index f7f2aabc..00000000
--- a/i386/i386at/gpl/linux/scsi/g_NCR5380.c
+++ /dev/null
@@ -1,588 +0,0 @@
-/*
- * Generic Generic NCR5380 driver
- *
- * Copyright 1993, Drew Eckhardt
- * Visionary Computing
- * (Unix and Linux consulting and custom programming)
- * drew@colorado.edu
- * +1 (303) 440-4894
- *
- * NCR53C400 extensions (c) 1994,1995,1996, Kevin Lentin
- * K.Lentin@cs.monash.edu.au
- *
- * ALPHA RELEASE 1.
- *
- * For more information, please consult
- *
- * NCR 5380 Family
- * SCSI Protocol Controller
- * Databook
- *
- * NCR Microelectronics
- * 1635 Aeroplaza Drive
- * Colorado Springs, CO 80916
- * 1+ (719) 578-3400
- * 1+ (800) 334-5454
- */
-
-/*
- * TODO : flesh out DMA support, find some one actually using this (I have
- * a memory mapped Trantor board that works fine)
- */
-
-/*
- * Options :
- *
- * PARITY - enable parity checking. Not supported.
- *
- * SCSI2 - enable support for SCSI-II tagged queueing. Untested.
- *
- * USLEEP - enable support for devices that don't disconnect. Untested.
- *
- * The card is detected and initialized in one of several ways :
- * 1. With command line overrides - NCR5380=port,irq may be
- * used on the LILO command line to override the defaults.
- *
- * 2. With the GENERIC_NCR5380_OVERRIDE compile time define. This is
- * specified as an array of address, irq, dma, board tuples. Ie, for
- * one board at 0x350, IRQ5, no dma, I could say
- * -DGENERIC_NCR5380_OVERRIDE={{0xcc000, 5, DMA_NONE, BOARD_NCR5380}}
- *
- * -1 should be specified for no or DMA interrupt, -2 to autoprobe for an
- * IRQ line if overridden on the command line.
- */
-
-/*
- * $Log: g_NCR5380.c,v $
- * Revision 1.1.1.1 1996/10/30 01:40:05 thomas
- * Imported from UK22
- *
- * Revision 1.1 1996/03/25 20:25:35 goel
- * Linux driver merge.
- *
- */
-
-#define AUTOPROBE_IRQ
-#define AUTOSENSE
-
-#include <linux/config.h>
-
-#ifdef MACH
-#define CONFIG_SCSI_G_NCR5380_MEM
-#endif
-
-#ifdef CONFIG_SCSI_GENERIC_NCR53C400
-#define NCR53C400_PSEUDO_DMA 1
-#define PSEUDO_DMA
-#define NCR53C400
-#endif
-#if defined(CONFIG_SCSI_G_NCR5380_PORT) && defined(CONFIG_SCSI_G_NCR5380_MEM)
-#error You can not configure the Generic NCR 5380 SCSI Driver for memory mapped I/O and port mapped I/O at the same time (yet)
-#endif
-#if !defined(CONFIG_SCSI_G_NCR5380_PORT) && !defined(CONFIG_SCSI_G_NCR5380_MEM)
-#error You must configure the Generic NCR 5380 SCSI Driver for one of memory mapped I/O and port mapped I/O.
-#endif
-
-#include <asm/system.h>
-#include <asm/io.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/blk.h>
-#include "scsi.h"
-#include "hosts.h"
-#include "g_NCR5380.h"
-#include "NCR5380.h"
-#include "constants.h"
-#include "sd.h"
-#include<linux/stat.h>
-
-struct proc_dir_entry proc_scsi_g_ncr5380 = {
- PROC_SCSI_GENERIC_NCR5380, 9, "g_NCR5380",
- S_IFDIR | S_IRUGO | S_IXUGO, 2
-};
-
-static struct override {
- NCR5380_implementation_fields;
- int irq;
- int dma;
- int board; /* Use NCR53c400, Ricoh, etc. extensions ? */
-} overrides
-#ifdef GENERIC_NCR5380_OVERRIDE
- [] = GENERIC_NCR5380_OVERRIDE
-#else
- [1] = {{0,},};
-#endif
-
-#define NO_OVERRIDES (sizeof(overrides) / sizeof(struct override))
-
-/*
- * Function : static internal_setup(int board, char *str, int *ints)
- *
- * Purpose : LILO command line initialization of the overrides array,
- *
- * Inputs : board - either BOARD_NCR5380 for a normal NCR5380 board,
- * or BOARD_NCR53C400 for a NCR53C400 board. str - unused, ints -
- * array of integer parameters with ints[0] equal to the number of ints.
- *
- */
-
-static void internal_setup(int board, char *str, int *ints) {
- static int commandline_current = 0;
- switch (board) {
- case BOARD_NCR5380:
- if (ints[0] != 2 && ints[0] != 3)
- printk("generic_NCR5380_setup : usage ncr5380=" STRVAL(NCR5380_map_name) ",irq,dma\n");
- return;
- case BOARD_NCR53C400:
- if (ints[0] != 2)
- printk("generic_NCR53C400_setup : usage ncr53c400= " STRVAL(NCR5380_map_name) ",irq\n");
- return;
- }
-
- if (commandline_current < NO_OVERRIDES) {
- overrides[commandline_current].NCR5380_map_name = (NCR5380_map_type)ints[1];
- overrides[commandline_current].irq = ints[2];
- if (ints[0] == 3)
- overrides[commandline_current].dma = ints[3];
- else
- overrides[commandline_current].dma = DMA_NONE;
- overrides[commandline_current].board = board;
- ++commandline_current;
- }
-}
-
-/*
- * Function : generic_NCR5380_setup (char *str, int *ints)
- *
- * Purpose : LILO command line initialization of the overrides array,
- *
- * Inputs : str - unused, ints - array of integer paramters with ints[0]
- * equal to the number of ints.
- */
-
-void generic_NCR5380_setup (char *str, int *ints) {
- internal_setup (BOARD_NCR5380, str, ints);
-}
-
-/*
- * Function : generic_NCR53C400_setup (char *str, int *ints)
- *
- * Purpose : LILO command line initialization of the overrides array,
- *
- * Inputs : str - unused, ints - array of integer paramters with ints[0]
- * equal to the number of ints.
- */
-
-void generic_NCR53C400_setup (char *str, int *ints) {
- internal_setup (BOARD_NCR53C400, str, ints);
-}
-
-/*
- * Function : int generic_NCR5380_detect(Scsi_Host_Template * tpnt)
- *
- * Purpose : initializes generic NCR5380 driver based on the
- * command line / compile time port and irq definitions.
- *
- * Inputs : tpnt - template for this SCSI adapter.
- *
- * Returns : 1 if a host adapter was found, 0 if not.
- *
- */
-
-int generic_NCR5380_detect(Scsi_Host_Template * tpnt) {
- static int current_override = 0;
- int count;
- int flags = 0;
- struct Scsi_Host *instance;
-
- tpnt->proc_dir = &proc_scsi_g_ncr5380;
-
- for (count = 0; current_override < NO_OVERRIDES; ++current_override) {
- if (!(overrides[current_override].NCR5380_map_name))
- continue;
-
- switch (overrides[current_override].board) {
- case BOARD_NCR5380:
- flags = FLAG_NO_PSEUDO_DMA;
- break;
- case BOARD_NCR53C400:
- flags = FLAG_NCR53C400;
- break;
- }
-
- instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
- instance->NCR5380_instance_name = overrides[current_override].NCR5380_map_name;
-
- NCR5380_init(instance, flags);
-
- if (overrides[current_override].irq != IRQ_AUTO)
- instance->irq = overrides[current_override].irq;
- else
- instance->irq = NCR5380_probe_irq(instance, 0xffff);
-
- if (instance->irq != IRQ_NONE)
- if (request_irq(instance->irq, generic_NCR5380_intr, SA_INTERRUPT, "NCR5380")) {
- printk("scsi%d : IRQ%d not free, interrupts disabled\n",
- instance->host_no, instance->irq);
- instance->irq = IRQ_NONE;
- }
-
- if (instance->irq == IRQ_NONE) {
- printk("scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
- printk("scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
- }
-
- printk("scsi%d : at " STRVAL(NCR5380_map_name) " 0x%x", instance->host_no, (unsigned int)instance->NCR5380_instance_name);
- if (instance->irq == IRQ_NONE)
- printk (" interrupts disabled");
- else
- printk (" irq %d", instance->irq);
- printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d",
- CAN_QUEUE, CMD_PER_LUN, GENERIC_NCR5380_PUBLIC_RELEASE);
- NCR5380_print_options(instance);
- printk("\n");
-
- ++current_override;
- ++count;
- }
- return count;
-}
-
-const char * generic_NCR5380_info (void) {
- static const char string[]="Generic NCR5380/53C400 Info";
- return string;
-}
-
-int generic_NCR5380_release_resources(struct Scsi_Host * instance)
-{
- NCR5380_local_declare();
-
- NCR5380_setup(instance);
-
- free_irq(instance->irq);
-
- return 0;
-}
-
-#ifdef BIOSPARAM
-/*
- * Function : int generic_NCR5380_biosparam(Disk * disk, kdev_t dev, int *ip)
- *
- * Purpose : Generates a BIOS / DOS compatable H-C-S mapping for
- * the specified device / size.
- *
- * Inputs : size = size of device in sectors (512 bytes), dev = block device
- * major / minor, ip[] = {heads, sectors, cylinders}
- *
- * Returns : allways 0 (success), initializes ip
- *
- */
-
-/*
- * XXX Most SCSI boards use this mapping, I could be incorrect. Some one
- * using hard disks on a trantor should verify that this mapping corresponds
- * to that used by the BIOS / ASPI driver by running the linux fdisk program
- * and matching the H_C_S coordinates to what DOS uses.
- */
-
-int generic_NCR5380_biosparam(Disk * disk, kdev_t dev, int *ip)
-{
- int size = disk->capacity;
- ip[0] = 64;
- ip[1] = 32;
- ip[2] = size >> 11;
- return 0;
-}
-#endif
-
-int generic_NCR5380_proc_info(char* buffer, char** start, off_t offset, int length, int hostno, int inout)
-{
- int len = 0;
- struct Scsi_Host *scsi_ptr;
-
- for (scsi_ptr = first_instance; scsi_ptr; scsi_ptr=scsi_ptr->next)
- if (scsi_ptr->host_no == hostno)
- break;
-
- len += sprintf(buffer+len, "SCSI host number %d : %s\n", scsi_ptr->host_no, scsi_ptr->hostt->name);
- len += sprintf(buffer+len, "Generic NCR5380 driver version %d\n", GENERIC_NCR5380_PUBLIC_RELEASE);
- len += sprintf(buffer+len, "NCR5380 driver core version %d\n", NCR5380_PUBLIC_RELEASE);
-#ifdef NCR53C400
- len += sprintf(buffer+len, "NCR53C400 driver extension version %d\n", NCR53C400_PUBLIC_RELEASE);
- len += sprintf(buffer+len, "NCR53C400 card%s detected\n", (((struct NCR5380_hostdata *)scsi_ptr->hostdata)->flags & FLAG_NCR53C400)?"":" not");
-# if NCR53C400_PSEUDO_DMA
- len += sprintf(buffer+len, "NCR53C400 pseudo DMA being used\n");
-# endif
-#else
- len += sprintf(buffer+len, "NO NCR53C400 driver extensions\n");
-#endif
- len += sprintf(buffer+len, "Using %s mapping at %s 0x%x, ", STRVAL(NCR5380_map_config), STRVAL(NCR5380_map_name), scsi_ptr->NCR5380_instance_name);
- if (scsi_ptr->irq == IRQ_NONE)
- len += sprintf(buffer+len, "interrupts disabled\n");
- else
- len += sprintf(buffer+len, "on interrupt %d\n", scsi_ptr->irq);
-
- *start = buffer + offset;
- len -= offset;
- if (len > length)
- len = length;
- return len;
-}
-
-#if NCR53C400_PSEUDO_DMA
-static inline int NCR5380_pread (struct Scsi_Host *instance, unsigned char *dst, int len)
-{
- int blocks = len / 128;
- int start = 0;
- int i;
- int bl;
- NCR5380_local_declare();
-
- NCR5380_setup(instance);
-
-#if (NDEBUG & NDEBUG_C400_PREAD)
- printk("53C400r: About to read %d blocks for %d bytes\n", blocks, len);
-#endif
-
- NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE | CSR_TRANS_DIR);
- NCR5380_write(C400_BLOCK_COUNTER_REG, blocks);
- while (1) {
-
-#if (NDEBUG & NDEBUG_C400_PREAD)
- printk("53C400r: %d blocks left\n", blocks);
-#endif
-
- if ((bl=NCR5380_read(C400_BLOCK_COUNTER_REG)) == 0) {
-#if (NDEBUG & NDEBUG_C400_PREAD)
- if (blocks)
- printk("53C400r: blocks still == %d\n", blocks);
- else
- printk("53C400r: Exiting loop\n");
-#endif
- break;
- }
-
-#if 1
- if (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ) {
- printk("53C400r: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks);
- return -1;
- }
-#endif
-
-#if (NDEBUG & NDEBUG_C400_PREAD)
- printk("53C400r: Waiting for buffer, bl=%d\n", bl);
-#endif
-
- while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
- ;
-#if (NDEBUG & NDEBUG_C400_PREAD)
- printk("53C400r: Transferring 128 bytes\n");
-#endif
-
-#ifdef CONFIG_SCSI_G_NCR5380_PORT
- for (i=0; i<128; i++)
- dst[start+i] = NCR5380_read(C400_HOST_BUFFER);
-#else
- /* implies CONFIG_SCSI_G_NCR5380_MEM */
- memmove(dst+start,NCR53C400_host_buffer+NCR5380_map_name,128);
-#endif
- start+=128;
- blocks--;
- }
-
-#if (NDEBUG & NDEBUG_C400_PREAD)
- printk("53C400r: EXTRA: Waiting for buffer\n");
-#endif
- while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
- ;
-
-#if (NDEBUG & NDEBUG_C400_PREAD)
- printk("53C400r: Transferring EXTRA 128 bytes\n");
-#endif
-#ifdef CONFIG_SCSI_G_NCR5380_PORT
- for (i=0; i<128; i++)
- dst[start+i] = NCR5380_read(C400_HOST_BUFFER);
-#else
- /* implies CONFIG_SCSI_G_NCR5380_MEM */
- memmove(dst+start,NCR53C400_host_buffer+NCR5380_map_name,128);
-#endif
- start+=128;
- blocks--;
-
-#if (NDEBUG & NDEBUG_C400_PREAD)
- printk("53C400r: Final values: blocks=%d start=%d\n", blocks, start);
-#endif
-
- if (!(NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ))
- printk("53C400r: no 53C80 gated irq after transfer");
-#if (NDEBUG & NDEBUG_C400_PREAD)
- else
- printk("53C400r: Got 53C80 interupt and tried to clear it\n");
-#endif
-
-/* DON'T DO THIS - THEY NEVER ARRIVE!
- printk("53C400r: Waiting for 53C80 registers\n");
- while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_53C80_REG)
- ;
-*/
-
- if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER))
- printk("53C400r: no end dma signal\n");
-#if (NDEBUG & NDEBUG_C400_PREAD)
- else
- printk("53C400r: end dma as expected\n");
-#endif
-
- NCR5380_write(MODE_REG, MR_BASE);
- NCR5380_read(RESET_PARITY_INTERRUPT_REG);
- return 0;
-}
-
-static inline int NCR5380_pwrite (struct Scsi_Host *instance, unsigned char *src, int len)
-{
- int blocks = len / 128;
- int start = 0;
- int i;
- int bl;
- NCR5380_local_declare();
-
- NCR5380_setup(instance);
-
-#if (NDEBUG & NDEBUG_C400_PWRITE)
- printk("53C400w: About to write %d blocks for %d bytes\n", blocks, len);
-#endif
-
- NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
- NCR5380_write(C400_BLOCK_COUNTER_REG, blocks);
- while (1) {
- if (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ) {
- printk("53C400w: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks);
- return -1;
- }
-
- if ((bl=NCR5380_read(C400_BLOCK_COUNTER_REG)) == 0) {
-#if (NDEBUG & NDEBUG_C400_PWRITE)
- if (blocks)
- printk("53C400w: exiting loop, blocks still == %d\n", blocks);
- else
- printk("53C400w: exiting loop\n");
-#endif
- break;
- }
-
-#if (NDEBUG & NDEBUG_C400_PWRITE)
- printk("53C400w: %d blocks left\n", blocks);
-
- printk("53C400w: waiting for buffer, bl=%d\n", bl);
-#endif
- while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
- ;
-
-#if (NDEBUG & NDEBUG_C400_PWRITE)
- printk("53C400w: transferring 128 bytes\n");
-#endif
-#ifdef CONFIG_SCSI_G_NCR5380_PORT
- for (i=0; i<128; i++)
- NCR5380_write(C400_HOST_BUFFER, src[start+i]);
-#else
- /* implies CONFIG_SCSI_G_NCR5380_MEM */
- memmove(NCR53C400_host_buffer+NCR5380_map_name,src+start,128);
-#endif
- start+=128;
- blocks--;
- }
- if (blocks) {
-#if (NDEBUG & NDEBUG_C400_PWRITE)
- printk("53C400w: EXTRA waiting for buffer\n");
-#endif
- while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
- ;
-
-#if (NDEBUG & NDEBUG_C400_PWRITE)
- printk("53C400w: transferring EXTRA 128 bytes\n");
-#endif
-#ifdef CONFIG_SCSI_G_NCR5380_PORT
- for (i=0; i<128; i++)
- NCR5380_write(C400_HOST_BUFFER, src[start+i]);
-#else
- /* implies CONFIG_SCSI_G_NCR5380_MEM */
- memmove(NCR53C400_host_buffer+NCR5380_map_name,src+start,128);
-#endif
- start+=128;
- blocks--;
- }
-#if (NDEBUG & NDEBUG_C400_PWRITE)
- else
- printk("53C400w: No EXTRA required\n");
-#endif
-
-#if (NDEBUG & NDEBUG_C400_PWRITE)
- printk("53C400w: Final values: blocks=%d start=%d\n", blocks, start);
-#endif
-
-#if 0
- printk("53C400w: waiting for registers to be available\n");
- THEY NEVER DO!
- while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_53C80_REG)
- ;
- printk("53C400w: Got em\n");
-#endif
-
- /* Let's wait for this instead - could be ugly */
- /* All documentation says to check for this. Maybe my hardware is too
- * fast. Waiting for it seems to work fine! KLL
- */
- while (!(i = NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ))
- ;
-
- /*
- * I know. i is certainly != 0 here but the loop is new. See previous
- * comment.
- */
- if (i) {
-#if (NDEBUG & NDEBUG_C400_PWRITE)
- prink("53C400w: got 53C80 gated irq (last block)\n");
-#endif
- if (!((i=NCR5380_read(BUS_AND_STATUS_REG)) & BASR_END_DMA_TRANSFER))
- printk("53C400w: No END OF DMA bit - WHOOPS! BASR=%0x\n",i);
-#if (NDEBUG & NDEBUG_C400_PWRITE)
- else
- printk("53C400w: Got END OF DMA\n");
-#endif
- }
- else
- printk("53C400w: no 53C80 gated irq after transfer (last block)\n");
-
-#if 0
- if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER)) {
- printk("53C400w: no end dma signal\n");
- }
-#endif
-
-#if (NDEBUG & NDEBUG_C400_PWRITE)
- printk("53C400w: waiting for last byte...\n");
-#endif
- while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT))
- ;
-
-#if (NDEBUG & NDEBUG_C400_PWRITE)
- printk("53C400w: got last byte.\n");
- printk("53C400w: pwrite exiting with status 0, whoopee!\n");
-#endif
- return 0;
-}
-#endif /* PSEUDO_DMA */
-
-#ifdef MACH
-#include "NCR5380.src"
-#else
-#include "NCR5380.c"
-#endif
-
-#ifdef MODULE
-/* Eventually this will go into an include file, but this will be later */
-Scsi_Host_Template driver_template = GENERIC_NCR5380;
-
-#include <linux/module.h>
-#include "scsi_module.c"
-#endif
diff --git a/i386/i386at/gpl/linux/scsi/g_NCR5380.h b/i386/i386at/gpl/linux/scsi/g_NCR5380.h
deleted file mode 100644
index 52e64499..00000000
--- a/i386/i386at/gpl/linux/scsi/g_NCR5380.h
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Generic Generic NCR5380 driver defines
- *
- * Copyright 1993, Drew Eckhardt
- * Visionary Computing
- * (Unix and Linux consulting and custom programming)
- * drew@colorado.edu
- * +1 (303) 440-4894
- *
- * NCR53C400 extensions (c) 1994,1995,1996, Kevin Lentin
- * K.Lentin@cs.monash.edu.au
- *
- * ALPHA RELEASE 1.
- *
- * For more information, please consult
- *
- * NCR 5380 Family
- * SCSI Protocol Controller
- * Databook
- *
- * NCR Microelectronics
- * 1635 Aeroplaza Drive
- * Colorado Springs, CO 80916
- * 1+ (719) 578-3400
- * 1+ (800) 334-5454
- */
-
-/*
- * $Log: g_NCR5380.h,v $
- * Revision 1.1.1.1 1996/10/30 01:40:05 thomas
- * Imported from UK22
- *
- * Revision 1.1 1996/03/25 20:25:35 goel
- * Linux driver merge.
- *
- */
-
-#ifndef GENERIC_NCR5380_H
-#define GENERIC_NCR5380_H
-
-#define GENERIC_NCR5380_PUBLIC_RELEASE 1
-
-#ifdef NCR53C400
-#define BIOSPARAM
-#define NCR5380_BIOSPARAM generic_NCR5380_biosparam
-#else
-#define NCR5380_BIOSPARAM NULL
-#endif
-
-#ifndef ASM
-int generic_NCR5380_abort(Scsi_Cmnd *);
-int generic_NCR5380_detect(Scsi_Host_Template *);
-int generic_NCR5380_release_resources(struct Scsi_Host *);
-int generic_NCR5380_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-int generic_NCR5380_reset(Scsi_Cmnd *);
-#ifdef BIOSPARAM
-int generic_NCR5380_biosparam(Disk *, kdev_t, int *);
-#endif
-
-int generic_NCR5380_proc_info(char* buffer, char** start, off_t offset, int length, int hostno, int inout);
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#ifndef CMD_PER_LUN
-#define CMD_PER_LUN 2
-#endif
-
-#ifndef CAN_QUEUE
-#define CAN_QUEUE 16
-#endif
-
-#if defined(HOSTS_C) || defined(MODULE)
-
-#define GENERIC_NCR5380 {NULL, NULL, NULL, \
- generic_NCR5380_proc_info, \
- "Generic NCR5380/NCR53C400 Scsi Driver", \
- generic_NCR5380_detect, generic_NCR5380_release_resources, \
- generic_NCR5380_info, NULL, \
- generic_NCR5380_queue_command, generic_NCR5380_abort, \
- generic_NCR5380_reset, NULL, \
- NCR5380_BIOSPARAM, \
- /* can queue */ CAN_QUEUE, /* id */ 7, SG_ALL, \
- /* cmd per lun */ CMD_PER_LUN , 0, 0, DISABLE_CLUSTERING}
-
-#endif
-
-#ifndef HOSTS_C
-
-#define __STRVAL(x) #x
-#define STRVAL(x) __STRVAL(x)
-
-#ifdef CONFIG_SCSI_G_NCR5380_PORT
-
-#define NCR5380_map_config port
-
-#define NCR5380_map_type int
-
-#define NCR5380_map_name port
-
-#define NCR5380_instance_name io_port
-
-#define NCR53C400_register_offset 0
-
-#define NCR53C400_address_adjust 8
-
-#ifdef NCR53C400
-#define NCR5380_region_size 16
-#else
-#define NCR5380_region_size 8
-#endif
-
-#define NCR5380_read(reg) (inb(NCR5380_map_name + (reg)))
-#define NCR5380_write(reg, value) (outb((value), (NCR5380_map_name + (reg))))
-
-#else
-/* therefore CONFIG_SCSI_G_NCR5380_MEM */
-
-#define NCR5380_map_config memory
-
-#define NCR5380_map_type volatile unsigned char*
-
-#define NCR5380_map_name base
-
-#define NCR5380_instance_name base
-
-#define NCR53C400_register_offset 0x108
-
-#define NCR53C400_address_adjust 0
-
-#define NCR53C400_mem_base 0x3880
-
-#define NCR53C400_host_buffer 0x3900
-
-#define NCR5380_region_size 0x3a00
-
-
-#define NCR5380_read(reg) (*(NCR5380_map_name + NCR53C400_mem_base + (reg)))
-#define NCR5380_write(reg, value) (*(NCR5380_map_name + NCR53C400_mem_base + (reg)) = value)
-
-#endif
-
-#define NCR5380_implementation_fields \
- NCR5380_map_type NCR5380_map_name
-
-#define NCR5380_local_declare() \
- register NCR5380_implementation_fields
-
-#define NCR5380_setup(instance) \
- NCR5380_map_name = (NCR5380_map_type)((instance)->NCR5380_instance_name)
-
-#define NCR5380_intr generic_NCR5380_intr
-#define NCR5380_queue_command generic_NCR5380_queue_command
-#define NCR5380_abort generic_NCR5380_abort
-#define NCR5380_reset generic_NCR5380_reset
-#define NCR5380_pread generic_NCR5380_pread
-#define NCR5380_pwrite generic_NCR5380_pwrite
-
-#define BOARD_NCR5380 0
-#define BOARD_NCR53C400 1
-
-#endif /* else def HOSTS_C */
-#endif /* ndef ASM */
-#endif /* GENERIC_NCR5380_H */
-
diff --git a/i386/i386at/gpl/linux/scsi/hosts.c b/i386/i386at/gpl/linux/scsi/hosts.c
deleted file mode 100644
index 72ae0cb6..00000000
--- a/i386/i386at/gpl/linux/scsi/hosts.c
+++ /dev/null
@@ -1,440 +0,0 @@
-/*
- * hosts.c Copyright (C) 1992 Drew Eckhardt
- * Copyright (C) 1993, 1994, 1995 Eric Youngdale
- *
- * mid to lowlevel SCSI driver interface
- * Initial versions: Drew Eckhardt
- * Subsequent revisions: Eric Youngdale
- *
- * <drew@colorado.edu>
- */
-
-
-/*
- * This file contains the medium level SCSI
- * host interface initialization, as well as the scsi_hosts array of SCSI
- * hosts currently present in the system.
- */
-
-/*
- * Don't import our own symbols, as this would severely mess up our
- * symbol tables.
- */
-#define _SCSI_SYMS_VER_
-#define __NO_VERSION__
-#include <linux/module.h>
-
-#include <linux/config.h>
-#include <linux/blk.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/proc_fs.h>
-
-#include "scsi.h"
-
-#ifndef NULL
-#define NULL 0L
-#endif
-
-#define HOSTS_C
-
-#include "hosts.h"
-
-#ifdef CONFIG_SCSI_ADVANSYS
-#include "advansys.h"
-#endif
-
-#ifdef CONFIG_SCSI_AHA152X
-#include "aha152x.h"
-#endif
-
-#ifdef CONFIG_SCSI_AHA1542
-#include "aha1542.h"
-#endif
-
-#ifdef CONFIG_SCSI_AHA1740
-#include "aha1740.h"
-#endif
-
-#ifdef CONFIG_SCSI_AIC7XXX
-#include "aic7xxx.h"
-#endif
-
-#ifdef CONFIG_SCSI_BUSLOGIC
-#include "BusLogic.h"
-#endif
-
-#ifdef CONFIG_SCSI_EATA_DMA
-#include "eata_dma.h"
-#endif
-
-#ifdef CONFIG_SCSI_EATA_PIO
-#include "eata_pio.h"
-#endif
-
-#ifdef CONFIG_SCSI_U14_34F
-#include "u14-34f.h"
-#endif
-
-#ifdef CONFIG_SCSI_FUTURE_DOMAIN
-#include "fdomain.h"
-#endif
-
-#ifdef CONFIG_SCSI_GENERIC_NCR5380
-#include "g_NCR5380.h"
-#endif
-
-#ifdef CONFIG_SCSI_IN2000
-#include "in2000.h"
-#endif
-
-#ifdef CONFIG_SCSI_PAS16
-#include "pas16.h"
-#endif
-
-#ifdef CONFIG_SCSI_QLOGIC
-#include "qlogic.h"
-#endif
-
-#ifdef CONFIG_SCSI_SEAGATE
-#include "seagate.h"
-#endif
-
-#ifdef CONFIG_SCSI_T128
-#include "t128.h"
-#endif
-
-#ifdef CONFIG_SCSI_NCR53C7xx
-#include "53c7,8xx.h"
-#endif
-
-#ifdef CONFIG_SCSI_ULTRASTOR
-#include "ultrastor.h"
-#endif
-
-#ifdef CONFIG_SCSI_7000FASST
-#include "wd7000.h"
-#endif
-
-#ifdef CONFIG_SCSI_EATA
-#include "eata.h"
-#endif
-
-#ifdef CONFIG_SCSI_NCR53C406A
-#include "NCR53c406a.h"
-#endif
-
-#ifdef CONFIG_SCSI_AM53C974
-#include "AM53C974.h"
-#endif
-
-#ifdef CONFIG_SCSI_DEBUG
-#include "scsi_debug.h"
-#endif
-
-/*
-static const char RCSid[] = "$Header: cvs/gnumach/i386/i386at/gpl/linux/scsi/Attic/hosts.c,v 1.2 1997/03/24 21:51:24 thomas Exp $";
-*/
-
-/*
- * The scsi host entries should be in the order you wish the
- * cards to be detected. A driver may appear more than once IFF
- * it can deal with being detected (and therefore initialized)
- * with more than one simultaneous host number, can handle being
- * reentrant, etc.
- *
- * They may appear in any order, as each SCSI host is told which host
- * number it is during detection.
- */
-
-/* This is a placeholder for controllers that are not configured into
- * the system - we do this to ensure that the controller numbering is
- * always consistent, no matter how the kernel is configured. */
-
-#define NO_CONTROLLER {NULL, NULL, NULL, NULL, NULL, NULL, NULL, \
- NULL, NULL, 0, 0, 0, 0, 0, 0}
-
-/*
- * When figure is run, we don't want to link to any object code. Since
- * the macro for each host will contain function pointers, we cannot
- * use it and instead must use a "blank" that does no such
- * idiocy.
- */
-
-Scsi_Host_Template * scsi_hosts = NULL;
-
-static Scsi_Host_Template builtin_scsi_hosts[] =
-{
-#ifdef CONFIG_SCSI_ADVANSYS
- ADVANSYS,
-#endif
-/* BusLogic must come before aha1542.c */
-#ifdef CONFIG_SCSI_BUSLOGIC
- BUSLOGIC,
-#endif
-#ifdef CONFIG_SCSI_U14_34F
- ULTRASTOR_14_34F,
-#endif
-#ifdef CONFIG_SCSI_ULTRASTOR
- ULTRASTOR_14F,
-#endif
-#ifdef CONFIG_SCSI_AHA152X
- AHA152X,
-#endif
-#ifdef CONFIG_SCSI_AHA1542
- AHA1542,
-#endif
-#ifdef CONFIG_SCSI_AHA1740
- AHA1740,
-#endif
-#ifdef CONFIG_SCSI_AIC7XXX
- AIC7XXX,
-#endif
-#ifdef CONFIG_SCSI_FUTURE_DOMAIN
- FDOMAIN_16X0,
-#endif
-#ifdef CONFIG_SCSI_IN2000
- IN2000,
-#endif
-#ifdef CONFIG_SCSI_GENERIC_NCR5380
- GENERIC_NCR5380,
-#endif
-#ifdef CONFIG_SCSI_NCR53C406A /* 53C406A should come before QLOGIC */
- NCR53c406a,
-#endif
-#ifdef CONFIG_SCSI_QLOGIC
- QLOGIC,
-#endif
-#ifdef CONFIG_SCSI_PAS16
- MV_PAS16,
-#endif
-#ifdef CONFIG_SCSI_SEAGATE
- SEAGATE_ST0X,
-#endif
-#ifdef CONFIG_SCSI_T128
- TRANTOR_T128,
-#endif
-#ifdef CONFIG_SCSI_NCR53C7xx
- NCR53c7xx,
-#endif
-#ifdef CONFIG_SCSI_EATA_DMA
- EATA_DMA,
-#endif
-#ifdef CONFIG_SCSI_EATA_PIO
- EATA_PIO,
-#endif
-#ifdef CONFIG_SCSI_7000FASST
- WD7000,
-#endif
-#ifdef CONFIG_SCSI_EATA
- EATA,
-#endif
-#ifdef CONFIG_SCSI_AM53C974
- AM53C974,
-#endif
-#ifdef CONFIG_SCSI_DEBUG
- SCSI_DEBUG,
-#endif
-};
-
-#define MAX_SCSI_HOSTS (sizeof(builtin_scsi_hosts) / sizeof(Scsi_Host_Template))
-
-
-/*
- * Our semaphores and timeout counters, where size depends on
- * MAX_SCSI_HOSTS here.
- */
-
-struct Scsi_Host * scsi_hostlist = NULL;
-struct Scsi_Device_Template * scsi_devicelist = NULL;
-
-int max_scsi_hosts = 0;
-int next_scsi_host = 0;
-
-void
-scsi_unregister(struct Scsi_Host * sh){
- struct Scsi_Host * shpnt;
-
- if(scsi_hostlist == sh)
- scsi_hostlist = sh->next;
- else {
- shpnt = scsi_hostlist;
- while(shpnt->next != sh) shpnt = shpnt->next;
- shpnt->next = shpnt->next->next;
- }
-
- /* If we are removing the last host registered, it is safe to reuse
- * its host number (this avoids "holes" at boot time) (DB)
- */
- if (max_scsi_hosts == next_scsi_host && !scsi_loadable_module_flag)
- max_scsi_hosts--;
-
- next_scsi_host--;
- scsi_init_free((char *) sh, sizeof(struct Scsi_Host) + sh->extra_bytes);
-}
-
-/* We call this when we come across a new host adapter. We only do this
- * once we are 100% sure that we want to use this host adapter - it is a
- * pain to reverse this, so we try and avoid it
- */
-
-struct Scsi_Host * scsi_register(Scsi_Host_Template * tpnt, int j){
- struct Scsi_Host * retval, *shpnt;
- retval = (struct Scsi_Host *)scsi_init_malloc(sizeof(struct Scsi_Host) + j,
- (tpnt->unchecked_isa_dma && j ? GFP_DMA : 0) | GFP_ATOMIC);
- retval->host_busy = 0;
- retval->block = NULL;
- retval->wish_block = 0;
- if(j > 0xffff) panic("Too many extra bytes requested\n");
- retval->extra_bytes = j;
- retval->loaded_as_module = scsi_loadable_module_flag;
- retval->host_no = max_scsi_hosts++; /* never reuse host_no (DB) */
- next_scsi_host++;
- retval->host_queue = NULL;
- retval->host_wait = NULL;
- retval->last_reset = 0;
- retval->irq = 0;
- retval->dma_channel = 0xff;
-
- /* These three are default values which can be overridden */
- retval->max_channel = 0;
- retval->max_id = 8;
- retval->max_lun = 8;
-
- retval->unique_id = 0;
- retval->io_port = 0;
- retval->hostt = tpnt;
- retval->next = NULL;
-#ifdef DEBUG
- printk("Register %x %x: %d\n", (int)retval, (int)retval->hostt, j);
-#endif
-
- /* The next six are the default values which can be overridden
- * if need be */
- retval->this_id = tpnt->this_id;
- retval->can_queue = tpnt->can_queue;
- retval->sg_tablesize = tpnt->sg_tablesize;
- retval->cmd_per_lun = tpnt->cmd_per_lun;
- retval->unchecked_isa_dma = tpnt->unchecked_isa_dma;
- retval->use_clustering = tpnt->use_clustering;
- if(!scsi_hostlist)
- scsi_hostlist = retval;
- else
- {
- shpnt = scsi_hostlist;
- while(shpnt->next) shpnt = shpnt->next;
- shpnt->next = retval;
- }
-
- return retval;
-}
-
-int
-scsi_register_device(struct Scsi_Device_Template * sdpnt)
-{
- if(sdpnt->next) panic("Device already registered");
- sdpnt->next = scsi_devicelist;
- scsi_devicelist = sdpnt;
- return 0;
-}
-
-unsigned int scsi_init()
-{
- static int called = 0;
- int i, pcount;
- Scsi_Host_Template * tpnt;
- struct Scsi_Host * shpnt;
- const char * name;
-
- if(called) return 0;
-
- called = 1;
- for (tpnt = &builtin_scsi_hosts[0], i = 0; i < MAX_SCSI_HOSTS; ++i, tpnt++)
- {
- /*
- * Initialize our semaphores. -1 is interpreted to mean
- * "inactive" - where as 0 will indicate a time out condition.
- */
-
- pcount = next_scsi_host;
- if ((tpnt->detect) &&
- (tpnt->present =
- tpnt->detect(tpnt)))
- {
- /* The only time this should come up is when people use
- * some kind of patched driver of some kind or another. */
- if(pcount == next_scsi_host) {
- if(tpnt->present > 1)
- panic("Failure to register low-level scsi driver");
- /* The low-level driver failed to register a driver. We
- * can do this now. */
- scsi_register(tpnt,0);
- }
- tpnt->next = scsi_hosts;
- scsi_hosts = tpnt;
-
- /* Add the driver to /proc/scsi */
-#if CONFIG_PROC_FS
- build_proc_dir_entries(tpnt);
-#endif
- }
- }
-
- for(shpnt=scsi_hostlist; shpnt; shpnt = shpnt->next)
- {
- if(shpnt->hostt->info)
- name = shpnt->hostt->info(shpnt);
- else
- name = shpnt->hostt->name;
-#if 0
- printk ("scsi%d : %s\n", /* And print a little message */
- shpnt->host_no, name);
-#endif
- }
-
-#if 0
- printk ("scsi : %d host%s.\n", next_scsi_host,
- (next_scsi_host == 1) ? "" : "s");
-#endif
-
- scsi_make_blocked_list();
-
- /* Now attach the high level drivers */
-#ifdef CONFIG_BLK_DEV_SD
- scsi_register_device(&sd_template);
-#endif
-#ifdef CONFIG_BLK_DEV_SR
- scsi_register_device(&sr_template);
-#endif
-#ifdef CONFIG_CHR_DEV_ST
- scsi_register_device(&st_template);
-#endif
-#ifdef CONFIG_CHR_DEV_SG
- scsi_register_device(&sg_template);
-#endif
-
-#if 0
- max_scsi_hosts = next_scsi_host;
-#endif
- return 0;
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 4
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * c-continued-statement-offset: 4
- * c-continued-brace-offset: 0
- * indent-tabs-mode: nil
- * tab-width: 8
- * End:
- */
diff --git a/i386/i386at/gpl/linux/scsi/hosts.h b/i386/i386at/gpl/linux/scsi/hosts.h
deleted file mode 100644
index 1da480de..00000000
--- a/i386/i386at/gpl/linux/scsi/hosts.h
+++ /dev/null
@@ -1,409 +0,0 @@
-/*
- * hosts.h Copyright (C) 1992 Drew Eckhardt
- * Copyright (C) 1993, 1994, 1995 Eric Youngdale
- *
- * mid to low-level SCSI driver interface header
- * Initial versions: Drew Eckhardt
- * Subsequent revisions: Eric Youngdale
- *
- * <drew@colorado.edu>
- *
- * Modified by Eric Youngdale eric@aib.com to
- * add scatter-gather, multiple outstanding request, and other
- * enhancements.
- *
- * Further modified by Eric Youngdale to support multiple host adapters
- * of the same type.
- */
-
-#ifndef _HOSTS_H
-#define _HOSTS_H
-
-/*
- $Header: cvs/gnumach/i386/i386at/gpl/linux/scsi/Attic/hosts.h,v 1.1.1.1 1997/02/25 21:27:49 thomas Exp $
-*/
-
-#include <linux/proc_fs.h>
-
-/* It is senseless to set SG_ALL any higher than this - the performance
- * does not get any better, and it wastes memory
- */
-#define SG_NONE 0
-#define SG_ALL 0xff
-
-#define DISABLE_CLUSTERING 0
-#define ENABLE_CLUSTERING 1
-
-/* The various choices mean:
- * NONE: Self evident. Host adapter is not capable of scatter-gather.
- * ALL: Means that the host adapter module can do scatter-gather,
- * and that there is no limit to the size of the table to which
- * we scatter/gather data.
- * Anything else: Indicates the maximum number of chains that can be
- * used in one scatter-gather request.
- */
-
-/*
- * The Scsi_Host_Template type has all that is needed to interface with a SCSI
- * host in a device independent matter. There is one entry for each different
- * type of host adapter that is supported on the system.
- */
-
-typedef struct scsi_disk Disk;
-
-typedef struct SHT
-{
-
- /* Used with loadable modules so we can construct a linked list. */
- struct SHT * next;
-
- /* Used with loadable modules so that we know when it is safe to unload */
- long * usage_count;
-
- /* The pointer to the /proc/scsi directory entry */
- struct proc_dir_entry *proc_dir;
-
- /* proc-fs info function.
- * Can be used to export driver statistics and other infos to the world
- * outside the kernel ie. userspace and it also provides an interface
- * to feed the driver with information. Check eata_dma_proc.c for reference
- */
- int (*proc_info)(char *, char **, off_t, int, int, int);
-
- /*
- * The name pointer is a pointer to the name of the SCSI
- * device detected.
- */
- const char *name;
-
- /*
- * The detect function shall return non zero on detection,
- * indicating the number of host adapters of this particular
- * type were found. It should also
- * initialize all data necessary for this particular
- * SCSI driver. It is passed the host number, so this host
- * knows where the first entry is in the scsi_hosts[] array.
- *
- * Note that the detect routine MUST not call any of the mid level
- * functions to queue commands because things are not guaranteed
- * to be set up yet. The detect routine can send commands to
- * the host adapter as long as the program control will not be
- * passed to scsi.c in the processing of the command. Note
- * especially that scsi_malloc/scsi_free must not be called.
- */
- int (* detect)(struct SHT *);
-
- /* Used with loadable modules to unload the host structures. Note:
- * there is a default action built into the modules code which may
- * be sufficient for most host adapters. Thus you may not have to supply
- * this at all.
- */
- int (*release)(struct Scsi_Host *);
-
- /*
- * The info function will return whatever useful
- * information the developer sees fit. If not provided, then
- * the name field will be used instead.
- */
- const char *(* info)(struct Scsi_Host *);
-
- /*
- * The command function takes a target, a command (this is a SCSI
- * command formatted as per the SCSI spec, nothing strange), a
- * data buffer pointer, and data buffer length pointer. The return
- * is a status int, bit fielded as follows :
- * Byte What
- * 0 SCSI status code
- * 1 SCSI 1 byte message
- * 2 host error return.
- * 3 mid level error return
- */
- int (* command)(Scsi_Cmnd *);
-
- /*
- * The QueueCommand function works in a similar manner
- * to the command function. It takes an additional parameter,
- * void (* done)(int host, int code) which is passed the host
- * # and exit result when the command is complete.
- * Host number is the POSITION IN THE hosts array of THIS
- * host adapter.
- */
- int (* queuecommand)(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-
- /*
- * Since the mid level driver handles time outs, etc, we want to
- * be able to abort the current command. Abort returns 0 if the
- * abortion was successful. The field SCpnt->abort reason
- * can be filled in with the appropriate reason why we wanted
- * the abort in the first place, and this will be used
- * in the mid-level code instead of the host_byte().
- * If non-zero, the code passed to it
- * will be used as the return code, otherwise
- * DID_ABORT should be returned.
- *
- * Note that the scsi driver should "clean up" after itself,
- * resetting the bus, etc. if necessary.
- */
- int (* abort)(Scsi_Cmnd *);
-
- /*
- * The reset function will reset the SCSI bus. Any executing
- * commands should fail with a DID_RESET in the host byte.
- * The Scsi_Cmnd is passed so that the reset routine can figure
- * out which host adapter should be reset, and also which command
- * within the command block was responsible for the reset in
- * the first place. Some hosts do not implement a reset function,
- * and these hosts must call scsi_request_sense(SCpnt) to keep
- * the command alive.
- */
- int (* reset)(Scsi_Cmnd *);
-
- /*
- * This function is used to select synchronous communications,
- * which will result in a higher data throughput. Not implemented
- * yet.
- */
- int (* slave_attach)(int, int);
-
- /*
- * This function determines the bios parameters for a given
- * harddisk. These tend to be numbers that are made up by
- * the host adapter. Parameters:
- * size, device number, list (heads, sectors, cylinders)
- */
- int (* bios_param)(Disk *, kdev_t, int []);
-
- /*
- * This determines if we will use a non-interrupt driven
- * or an interrupt driven scheme, It is set to the maximum number
- * of simultaneous commands a given host adapter will accept.
- */
- int can_queue;
-
- /*
- * In many instances, especially where disconnect / reconnect are
- * supported, our host also has an ID on the SCSI bus. If this is
- * the case, then it must be reserved. Please set this_id to -1 if
- * your setup is in single initiator mode, and the host lacks an
- * ID.
- */
- int this_id;
-
- /*
- * This determines the degree to which the host adapter is capable
- * of scatter-gather.
- */
- short unsigned int sg_tablesize;
-
- /*
- * True if this host adapter can make good use of linked commands.
- * This will allow more than one command to be queued to a given
- * unit on a given host. Set this to the maximum number of command
- * blocks to be provided for each device. Set this to 1 for one
- * command block per lun, 2 for two, etc. Do not set this to 0.
- * You should make sure that the host adapter will do the right thing
- * before you try setting this above 1.
- */
- short cmd_per_lun;
-
- /*
- * present contains counter indicating how many boards of this
- * type were found when we did the scan.
- */
- unsigned char present;
-
- /*
- * true if this host adapter uses unchecked DMA onto an ISA bus.
- */
- unsigned unchecked_isa_dma:1;
-
- /*
- * true if this host adapter can make good use of clustering.
- * I originally thought that if the tablesize was large that it
- * was a waste of CPU cycles to prepare a cluster list, but
- * it works out that the Buslogic is faster if you use a smaller
- * number of segments (i.e. use clustering). I guess it is
- * inefficient.
- */
- unsigned use_clustering:1;
-
-} Scsi_Host_Template;
-
-/*
- * The scsi_hosts array is the array containing the data for all
- * possible <supported> scsi hosts. This is similar to the
- * Scsi_Host_Template, except that we have one entry for each
- * actual physical host adapter on the system, stored as a linked
- * list. Note that if there are 2 aha1542 boards, then there will
- * be two Scsi_Host entries, but only 1 Scsi_Host_Template entries.
- */
-
-struct Scsi_Host
-{
- struct Scsi_Host * next;
- unsigned short extra_bytes;
- volatile unsigned char host_busy;
- char host_no; /* Used for IOCTL_GET_IDLUN, /proc/scsi et al. */
- int last_reset;
- struct wait_queue *host_wait;
- Scsi_Cmnd *host_queue;
- Scsi_Host_Template * hostt;
-
- /*
- * These three parameters can be used to allow for wide scsi,
- * and for host adapters that support multiple busses
- * The first two should be set to 1 more than the actual max id
- * or lun (i.e. 8 for normal systems).
- */
- unsigned int max_id;
- unsigned int max_lun;
- unsigned int max_channel;
-
- /*
- * Pointer to a circularly linked list - this indicates the hosts
- * that should be locked out of performing I/O while we have an active
- * command on this host.
- */
- struct Scsi_Host * block;
- unsigned wish_block:1;
-
- /* These parameters should be set by the detect routine */
- unsigned char *base;
- unsigned int io_port;
- unsigned char n_io_port;
- unsigned char irq;
- unsigned char dma_channel;
-
- /*
- * This is a unique identifier that must be assigned so that we
- * have some way of identifying each detected host adapter properly
- * and uniquely. For hosts that do not support more than one card
- * in the system at one time, this does not need to be set. It is
- * initialized to 0 in scsi_register.
- */
- unsigned int unique_id;
-
- /*
- * The rest can be copied from the template, or specifically
- * initialized, as required.
- */
-
- int this_id;
- int can_queue;
- short cmd_per_lun;
- short unsigned int sg_tablesize;
- unsigned unchecked_isa_dma:1;
- unsigned use_clustering:1;
- /*
- * True if this host was loaded as a loadable module
- */
- unsigned loaded_as_module:1;
-
- /*
- * True when we call the low-level reset function, and
- * the midlevel code suggests a full bus reset.
- */
- unsigned suggest_bus_reset:1;
-
- unsigned long hostdata[0]; /* Used for storage of host specific stuff */
-};
-
-extern struct Scsi_Host * scsi_hostlist;
-extern struct Scsi_Device_Template * scsi_devicelist;
-
-extern Scsi_Host_Template * scsi_hosts;
-
-extern void build_proc_dir_entries(Scsi_Host_Template *);
-
-
-/*
- * scsi_init initializes the scsi hosts.
- */
-
-/*
- * We use these goofy things because the MM is not set up when we init
- * the scsi subsystem. By using these functions we can write code that
- * looks normal. Also, it makes it possible to use the same code for a
- * loadable module.
- */
-
-extern void * scsi_init_malloc(unsigned int size, int priority);
-extern void scsi_init_free(char * ptr, unsigned int size);
-
-extern int next_scsi_host;
-
-extern int scsi_loadable_module_flag;
-unsigned int scsi_init(void);
-extern struct Scsi_Host * scsi_register(Scsi_Host_Template *, int j);
-extern void scsi_unregister(struct Scsi_Host * i);
-
-#define BLANK_HOST {"", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
-
-struct Scsi_Device_Template
-{
- struct Scsi_Device_Template * next;
- const char * name;
- const char * tag;
- long * usage_count; /* Used for loadable modules */
- unsigned char scsi_type;
- unsigned char major;
- unsigned char nr_dev; /* Number currently attached */
- unsigned char dev_noticed; /* Number of devices detected. */
- unsigned char dev_max; /* Current size of arrays */
- unsigned blk:1; /* 0 if character device */
- int (*detect)(Scsi_Device *); /* Returns 1 if we can attach this device */
- int (*init)(void); /* Sizes arrays based upon number of devices
- * detected */
- void (*finish)(void); /* Perform initialization after attachment */
- int (*attach)(Scsi_Device *); /* Attach devices to arrays */
- void (*detach)(Scsi_Device *);
-};
-
-extern struct Scsi_Device_Template sd_template;
-extern struct Scsi_Device_Template st_template;
-extern struct Scsi_Device_Template sr_template;
-extern struct Scsi_Device_Template sg_template;
-
-int scsi_register_device(struct Scsi_Device_Template * sdpnt);
-
-/* These are used by loadable modules */
-extern int scsi_register_module(int, void *);
-extern void scsi_unregister_module(int, void *);
-
-/* The different types of modules that we can load and unload */
-#define MODULE_SCSI_HA 1
-#define MODULE_SCSI_CONST 2
-#define MODULE_SCSI_IOCTL 3
-#define MODULE_SCSI_DEV 4
-
-
-/*
- * This is an ugly hack. If we expect to be able to load devices at run time,
- * we need to leave extra room in some of the data structures. Doing a
- * realloc to enlarge the structures would be riddled with race conditions,
- * so until a better solution is discovered, we use this crude approach
- */
-#define SD_EXTRA_DEVS 2
-#define ST_EXTRA_DEVS 2
-#define SR_EXTRA_DEVS 2
-#define SG_EXTRA_DEVS (SD_EXTRA_DEVS + SR_EXTRA_DEVS + ST_EXTRA_DEVS)
-
-#endif
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 4
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * c-continued-statement-offset: 4
- * c-continued-brace-offset: 0
- * indent-tabs-mode: nil
- * tab-width: 8
- * End:
- */
diff --git a/i386/i386at/gpl/linux/scsi/in2000.c b/i386/i386at/gpl/linux/scsi/in2000.c
deleted file mode 100644
index ac2cc656..00000000
--- a/i386/i386at/gpl/linux/scsi/in2000.c
+++ /dev/null
@@ -1,731 +0,0 @@
-/*
- * This file is in2000.c, written and
- * Copyright (C) 1993 Brad McLean
- * Last edit 1/19/95 TZ
- * Disclaimer:
- * Note: This is ugly. I know it, I wrote it, but my whole
- * focus was on getting the damn thing up and out quickly.
- * Future stuff that would be nice: Command chaining, and
- * a local queue of commands would speed stuff up considerably.
- * Disconnection needs some supporting code. All of this
- * is beyond the scope of what I wanted to address, but if you
- * have time and patience, more power to you.
- * Also, there are some constants scattered throughout that
- * should have defines, and I should have built functions to
- * address the registers on the WD chip.
- * Oh well, I'm out of time for this project.
- * The one good thing to be said is that you can use the card.
- */
-
-/*
- * This module was updated by Shaun Savage first on 5-13-93
- * At that time the write was fixed, irq detection, and some
- * timing stuff. since that time other problems were fixed.
- * On 7-20-93 this file was updated for patch level 11
- * There are still problems with it but it work on 95% of
- * the machines. There are still problems with it working with
- * IDE drives, as swap drive and HD that support reselection.
- * But for most people it will work.
- */
-/* More changes by Bill Earnest, wde@aluxpo.att.com
- * through 4/07/94. Includes rewrites of FIFO routines,
- * length-limited commands to make swap partitions work.
- * Merged the changes released by Larry Doolittle, based on input
- * from Jon Luckey, Roger Sunshine, John Shifflett. The FAST_FIFO
- * doesn't work for me. Scatter-gather code from Eric. The change to
- * an IF stmt. in the interrupt routine finally made it stable.
- * Limiting swap request size patch to ll_rw_blk.c not needed now.
- * Please ignore the clutter of debug stmts., pretty can come later.
- */
-/* Merged code from Matt Postiff improving the auto-sense validation
- * for all I/O addresses. Some reports of problems still come in, but
- * have been unable to reproduce or localize the cause. Some are from
- * LUN > 0 problems, but that is not host specific. Now 6/6/94.
- */
-/* Changes for 1.1.28 kernel made 7/19/94, code not affected. (WDE)
- */
-/* Changes for 1.1.43+ kernels made 8/25/94, code added to check for
- * new BIOS version, derived by jshiffle@netcom.com. (WDE)
- *
- * 1/7/95 Fix from Peter Lu (swift@world.std.com) for datalen vs. dataptr
- * logic, much more stable under load.
- *
- * 1/19/95 (zerucha@shell.portal.com) Added module and biosparam support for
- * larger SCSI hard drives (untested).
- */
-
-#ifdef MODULE
-#include <linux/module.h>
-#endif
-
-#include <linux/kernel.h>
-#include <linux/head.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/sched.h>
-#include <linux/proc_fs.h>
-#include <asm/dma.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <linux/blk.h>
-#include "scsi.h"
-#include "hosts.h"
-#include "sd.h"
-
-#include "in2000.h"
-#include<linux/stat.h>
-
-struct proc_dir_entry proc_scsi_in2000 = {
- PROC_SCSI_IN2000, 6, "in2000",
- S_IFDIR | S_IRUGO | S_IXUGO, 2
-};
-
-/*#define FAST_FIFO_IO*/
-
-/*#define DEBUG*/
-#ifdef DEBUG
-#define DEB(x) x
-#else
-#define DEB(x)
-#endif
-
-/* These functions are based on include/asm/io.h */
-#ifndef inw
-inline static unsigned short inw( unsigned short port )
-{
- unsigned short _v;
-
- __asm__ volatile ("inw %1,%0"
- :"=a" (_v):"d" ((unsigned short) port));
- return _v;
-}
-#endif
-
-#ifndef outw
-inline static void outw( unsigned short value, unsigned short port )
-{
- __asm__ volatile ("outw %0,%1"
- : /* no outputs */
- :"a" ((unsigned short) value),
- "d" ((unsigned short) port));
-}
-#endif
-
-/* These functions are lifted from drivers/block/hd.c */
-
-#define port_read(port,buf,nr) \
-__asm__("cld;rep;insw": :"d" (port),"D" (buf),"c" (nr):"cx","di")
-
-#define port_write(port,buf,nr) \
-__asm__("cld;rep;outsw": :"d" (port),"S" (buf),"c" (nr):"cx","si")
-
-static unsigned int base;
-static unsigned int ficmsk;
-static unsigned char irq_level;
-static int in2000_datalen;
-static unsigned int in2000_nsegment;
-static unsigned int in2000_current_segment;
-static unsigned short *in2000_dataptr;
-static char in2000_datawrite;
-static struct scatterlist * in2000_scatter;
-static Scsi_Cmnd *in2000_SCptr = 0;
-
-static void (*in2000_done)(Scsi_Cmnd *);
-
-static int in2000_test_port(int index)
-{
- static const int *bios_tab[] = {
- (int *) 0xc8000, (int *) 0xd0000, (int *) 0xd8000 };
- int i;
- char tmp;
-
- tmp = inb(INFLED);
- /* First, see if the DIP switch values are valid */
- /* The test of B7 may fail on some early boards, mine works. */
- if ( ((~tmp & 0x3) != index ) || (tmp & 0x80) || !(tmp & 0x4) )
- return 0;
- printk("IN-2000 probe got dip setting of %02X\n", tmp);
- tmp = inb(INVERS);
-/* Add some extra sanity checks here */
- for(i=0; i < 3; i++)
- if(*(bios_tab[i]+0x04) == 0x41564f4e ||
- *(bios_tab[i]+0xc) == 0x61776c41) {
- printk("IN-2000 probe found hdw. vers. %02x, BIOS at %06x\n",
- tmp, (unsigned int)bios_tab[i]);
- return 1;
- }
- printk("in2000 BIOS not found.\n");
- return 0;
-}
-
-
-/*
- * retrieve the current transaction counter from the WD
- */
-
-static unsigned in2000_txcnt(void)
-{
- unsigned total=0;
-
- if(inb(INSTAT) & 0x20) return 0xffffff; /* not readable now */
- outb(TXCNTH,INSTAT); /* then autoincrement */
- total = (inb(INDATA) & 0xff) << 16;
- outb(TXCNTM,INSTAT);
- total += (inb(INDATA) & 0xff) << 8;
- outb(TXCNTL,INSTAT);
- total += (inb(INDATA) & 0xff);
- return total;
-}
-
-/*
- * Note: the FIFO is screwy, and has a counter granularity of 16 bytes, so
- * we have to reconcile the FIFO counter, the transaction byte count from the
- * WD chip, and of course, our desired transaction size. It may look strange,
- * and could probably use improvement, but it works, for now.
- */
-
-static void in2000_fifo_out(void) /* uses FIFOCNTR */
-{
- unsigned count, infcnt, txcnt;
-
- infcnt = inb(INFCNT)& 0xfe; /* FIFO counter */
- do {
- txcnt = in2000_txcnt();
-/*DEB(printk("FIw:%d %02x %d\n", in2000_datalen, infcnt, txcnt));*/
- count = (infcnt << 3) - 32; /* don't fill completely */
- if ( count > in2000_datalen )
- count = in2000_datalen; /* limit to actual data on hand */
- count >>= 1; /* Words, not bytes */
-#ifdef FAST_FIFO_IO
- if ( count ) {
- port_write(INFIFO, in2000_dataptr, count);
- in2000_datalen -= (count<<1);
- }
-#else
- while ( count-- )
- {
- outw(*in2000_dataptr++, INFIFO);
- in2000_datalen -= 2;
- }
-#endif
- } while((in2000_datalen > 0) && ((infcnt = (inb(INFCNT)) & 0xfe) >= 0x20) );
- /* If scatter-gather, go on to next segment */
- if( !in2000_datalen && ++in2000_current_segment < in2000_nsegment)
- {
- in2000_scatter++;
- in2000_datalen = in2000_scatter->length;
- in2000_dataptr = (unsigned short*)in2000_scatter->address;
- }
- if ( in2000_datalen <= 0 )
- {
- ficmsk = 0;
- count = 32; /* Always says to use this much flush */
- while ( count-- )
- outw(0, INFIFO);
- outb(2, ININTR); /* Mask FIFO Interrupts when done */
- }
-}
-
-static void in2000_fifo_in(void) /* uses FIFOCNTR */
-{
- unsigned fic, count, count2;
-
- count = inb(INFCNT) & 0xe1;
- do{
- count2 = count;
- count = (fic = inb(INFCNT)) & 0xe1;
- } while ( count != count2 );
-DEB(printk("FIir:%d %02x %08x\n", in2000_datalen,fic,(unsigned int )in2000_dataptr));
- do {
- count2 = in2000_txcnt(); /* bytes yet to come over SCSI bus */
-DEB(printk("FIr:%d %02x %08x %08x\n", in2000_datalen,fic,count2,(unsigned int)in2000_dataptr));
- if(count2 > 65536) count2 = 0;
- if(fic > 128) count = 1024;
- else if(fic > 64) count = 512;
- else if (fic > 32) count = 256;
- else if ( count2 < in2000_datalen ) /* if drive has < what we want */
- count = in2000_datalen - count2; /* FIFO has the rest */
- if ( count > in2000_datalen ) /* count2 is lesser of FIFO & rqst */
- count2 = in2000_datalen >> 1; /* converted to word count */
- else
- count2 = count >> 1;
- count >>= 1; /* also to words */
- count -= count2; /* extra left over in FIFO */
-#ifdef FAST_FIFO_IO
- if ( count2 ) {
- port_read(INFIFO, in2000_dataptr, count2);
- in2000_datalen -= (count2<<1);
- }
-#else
- while ( count2-- )
- {
- *in2000_dataptr++ = inw(INFIFO);
- in2000_datalen -=2;
- }
-#endif
- } while((in2000_datalen > 0) && (fic = inb(INFCNT)) );
-DEB(printk("FIer:%d %02x %08x\n", in2000_datalen,fic,(unsigned int )in2000_dataptr));
-/* while ( count-- )
- inw(INFIFO);*/ /* Throw away some extra stuff */
- if( !in2000_datalen && ++in2000_current_segment < in2000_nsegment)
- {
- in2000_scatter++;
- in2000_datalen = in2000_scatter->length;
- in2000_dataptr = (unsigned short*)in2000_scatter->address;
- }
- if ( ! in2000_datalen ){
- outb(2, ININTR); /* Mask FIFO Interrupts when done */
- ficmsk = 0;}
-}
-
-static void in2000_intr_handle(int irq, struct pt_regs *regs)
-{
- int result=0;
- unsigned int count,auxstatus,scsistatus,cmdphase,scsibyte;
- int action=0;
- Scsi_Cmnd *SCptr;
-
- DEB(printk("INT:%d %02x %08x\n", in2000_datalen, inb(INFCNT),(unsigned int)in2000_dataptr));
-
- if (( (ficmsk & (count = inb(INFCNT))) == 0xfe ) ||
- ( (inb(INSTAT) & 0x8c) == 0x80))
- { /* FIFO interrupt or WD interrupt */
- auxstatus = inb(INSTAT); /* need to save now */
- outb(SCSIST,INSTAT);
- scsistatus = inb(INDATA); /* This clears the WD intrpt bit */
- outb(TARGETU,INSTAT); /* then autoincrement */
- scsibyte = inb(INDATA); /* Get the scsi status byte */
- outb(CMDPHAS,INSTAT);
- cmdphase = inb(INDATA);
- DEB(printk("(int2000:%02x %02x %02x %02x %02x)\n",count,auxstatus,
- scsistatus,cmdphase,scsibyte));
-
- /* Why do we assume that we need to send more data here??? ERY */
- if ( in2000_datalen ) /* data xfer pending */
- {
- if ( in2000_dataptr == NULL )
- printk("int2000: dataptr=NULL datalen=%d\n",
- in2000_datalen);
- else if ( in2000_datawrite )
- in2000_fifo_out();
- else
- in2000_fifo_in();
- }
- if ( (auxstatus & 0x8c) == 0x80 )
- { /* There is a WD Chip interrupt & register read good */
- outb(2,ININTR); /* Disable fifo interrupts */
- ficmsk = 0;
- result = DID_OK << 16;
- /* 16=Select & transfer complete, 85=got disconnect */
- if ((scsistatus != 0x16) && (scsistatus != 0x85)
- && (scsistatus != 0x42)){
-/* printk("(WDi2000:%02x %02x %02x %02x %02x)\n",count,auxstatus,
- scsistatus,cmdphase,scsibyte);*/
-/* printk("QDAT:%d %08x %02x\n",
- in2000_datalen,(unsigned int)in2000_dataptr,ficmsk);*/
- ;
- }
- switch ( scsistatus & 0xf0 )
- {
- case 0x00: /* Card Reset Completed */
- action = 3;
- break;
- case 0x10: /* Successful Command Completion */
- if ( scsistatus & 0x8 )
- action = 1;
- break;
- case 0x20: /* Command Paused or Aborted */
- if ( (scsistatus & 0x8) )
- action = 1;
- else if ( (scsistatus & 7) < 2 )
- action = 2;
- else
- result = DID_ABORT << 16;
- break;
- case 0x40: /* Terminated early */
- if ( scsistatus & 0x8 )
- action = 1;
- else if ( (scsistatus & 7) > 2 )
- action = 2;
- else
- result = DID_TIME_OUT << 16;
- break;
- case 0x80: /* Service Required from SCSI bus */
- if ( scsistatus & 0x8 )
- action = 1;
- else
- action = 2;
- break;
- } /* end switch(scsistatus) */
- outb(0,INFLED);
- switch ( action )
- {
- case 0x02: /* Issue an abort */
- outb(COMMAND,INSTAT);
- outb(1,INDATA); /* ABORT COMMAND */
- result = DID_ABORT << 16;
- case 0x00: /* Basically all done */
- if ( ! in2000_SCptr )
- return;
- in2000_SCptr->result = result | scsibyte;
- SCptr = in2000_SCptr;
- in2000_SCptr = 0;
- if ( in2000_done )
- (*in2000_done)(SCptr);
- break;
- case 0x01: /* We need to reissue a command */
- outb(CMDPHAS,INSTAT);
- switch ( scsistatus & 7 )
- {
- case 0: /* Data out phase */
- case 1: /* Data in phase */
- case 4: /* Unspec info out phase */
- case 5: /* Unspec info in phase */
- case 6: /* Message in phase */
- case 7: /* Message in phase */
- outb(0x41,INDATA); /* rdy to disconn */
- break;
- case 2: /* command phase */
- outb(0x30,INDATA); /* rdy to send cmd bytes */
- break;
- case 3: /* status phase */
- outb(0x45,INDATA); /* To go to status phase,*/
- outb(TXCNTH,INSTAT); /* elim. data, autoinc */
- outb(0,INDATA);
- outb(0,INDATA);
- outb(0,INDATA);
- in2000_datalen = 0;
- in2000_dataptr = 0;
- break;
- } /* end switch(scsistatus) */
- outb(COMMAND,INSTAT);
- outb(8,INDATA); /* RESTART THE COMMAND */
- break;
- case 0x03: /* Finish up a Card Reset */
- outb(TIMEOUT,INSTAT); /* I got these values */
- /* by reverse Engineering */
- outb(IN2000_TMOUT,INDATA); /* the Always' bios. */
- outb(CONTROL,INSTAT);
- outb(0,INDATA);
- outb(SYNCTXR,INSTAT);
- outb(0x40,INDATA); /* async, 4 cyc xfer per. */
- break;
- } /* end switch(action) */
- } /* end if auxstatus for WD int */
- } /* end while intrpt active */
-}
-
-int in2000_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
-{
- unchar direction;
- unchar *cmd = (unchar *) SCpnt->cmnd;
- unchar target = SCpnt->target;
- void *buff = SCpnt->request_buffer;
- unsigned long flags;
- int bufflen = SCpnt->request_bufflen;
- int timeout, size, loop;
- int i;
-
- /*
- * This SCSI command has no data phase, but unfortunately the mid-level
- * SCSI drivers ask for 256 bytes of data xfer. Our card hangs if you
- * do this, so we protect against it here. It would be nice if the mid-
- * level could be changed, but who knows if that would break other host
- * adapter drivers.
- */
- if ( *cmd == TEST_UNIT_READY )
- bufflen = 0;
-
- /*
- * What it looks like. Boy did I get tired of reading its output.
- */
- if (*cmd == READ_10 || *cmd == WRITE_10) {
- i = xscsi2int((cmd+1));
- } else if (*cmd == READ_6 || *cmd == WRITE_6) {
- i = scsi2int((cmd+1));
- } else {
- i = -1;
- }
-#ifdef DEBUG
- printk("in2000qcmd: pos %d len %d ", i, bufflen);
- printk("scsi cmd:");
- for (i = 0; i < SCpnt->cmd_len; i++) printk("%02x ", cmd[i]);
- printk("\n");
-#endif
- direction = 1; /* assume for most commands */
- if (*cmd == WRITE_10 || *cmd == WRITE_6)
- direction = 0;
- size = SCpnt->cmd_len; /* CDB length */
- /*
- * Setup our current pointers
- * This is where you would allocate a control structure in a queue,
- * If you were going to upgrade this to do multiple issue.
- * Note that datalen and dataptr exist because we can change the
- * values during the course of the operation, while managing the
- * FIFO.
- * Note the nasty little first clause. In theory, the mid-level
- * drivers should never hand us more than one command at a time,
- * but just in case someone gets cute in configuring the driver,
- * we'll protect them, although not very politely.
- */
- if ( in2000_SCptr )
- {
- printk("in2000_queue_command waiting for free command block!\n");
- while ( in2000_SCptr )
- barrier();
- }
- for ( timeout = jiffies + 5; timeout > jiffies; )
- {
- if ( ! ( inb(INSTAT) & 0xb0 ) )
- {
- timeout = 0;
- break;
- }
- else
- {
- inb(INSTAT);
- outb(SCSIST,INSTAT);
- inb(INDATA);
- outb(TARGETU,INSTAT); /* then autoinc */
- inb(INDATA);
- inb(INDATA);
- }
- }
- if ( timeout )
- {
- printk("in2000_queue_command timeout!\n");
- SCpnt->result = DID_TIME_OUT << 16;
- (*done)(SCpnt);
- return 1;
- }
- /* Added for scatter-gather support */
- in2000_nsegment = SCpnt->use_sg;
- in2000_current_segment = 0;
- if(SCpnt->use_sg){
- in2000_scatter = (struct scatterlist *) buff;
- in2000_datalen = in2000_scatter->length;
- in2000_dataptr = (unsigned short*)in2000_scatter->address;
- } else {
- in2000_scatter = NULL;
- in2000_datalen = bufflen;
- in2000_dataptr = (unsigned short*) buff;
- };
- in2000_done = done;
- in2000_SCptr = SCpnt;
- /*
- * Write the CDB to the card, then the LUN, the length, and the target.
- */
- outb(TOTSECT, INSTAT); /* start here then autoincrement */
- for ( loop=0; loop < size; loop++ )
- outb(cmd[loop],INDATA);
- outb(TARGETU,INSTAT);
- outb(SCpnt->lun & 7,INDATA);
- SCpnt->host_scribble = NULL;
- outb(TXCNTH,INSTAT); /* then autoincrement */
- outb(bufflen>>16,INDATA);
- outb(bufflen>>8,INDATA);
- outb(bufflen,INDATA);
- outb(target&7,INDATA);
- /*
- * Set up the FIFO
- */
- save_flags(flags);
- cli(); /* so FIFO init waits till WD set */
- outb(0,INFRST);
- if ( direction == 1 )
- {
- in2000_datawrite = 0;
- outb(0,INFWRT);
- }
- else
- {
- in2000_datawrite = 1;
- for ( loop=16; --loop; ) /* preload the outgoing fifo */
- {
- outw(*in2000_dataptr++,INFIFO);
- if(in2000_datalen > 0) in2000_datalen-=2;
- }
- }
- ficmsk = 0xff;
- /*
- * Start it up
- */
- outb(CONTROL,INSTAT); /* WD BUS Mode */
- outb(0x4C,INDATA);
- if ( in2000_datalen ) /* if data xfer cmd */
- outb(0,ININTR); /* Enable FIFO intrpt some boards? */
- outb(COMMAND,INSTAT);
- outb(0,INNLED);
- outb(8,INDATA); /* Select w/ATN & Transfer */
- restore_flags(flags); /* let the intrpt rip */
- return 0;
-}
-
-static volatile int internal_done_flag = 0;
-static volatile int internal_done_errcode = 0;
-
-static void internal_done(Scsi_Cmnd * SCpnt)
-{
- internal_done_errcode = SCpnt->result;
- ++internal_done_flag;
-}
-
-int in2000_command(Scsi_Cmnd * SCpnt)
-{
- in2000_queuecommand(SCpnt, internal_done);
-
- while (!internal_done_flag);
- internal_done_flag = 0;
- return internal_done_errcode;
-}
-
-int in2000_detect(Scsi_Host_Template * tpnt)
-{
-/* Order chosen to reduce conflicts with some multi-port serial boards */
- int base_tab[] = { 0x220,0x200,0x110,0x100 };
- int int_tab[] = { 15,14,11,10 };
- struct Scsi_Host * shpnt;
- int loop, tmp;
-
- DEB(printk("in2000_detect: \n"));
-
- tpnt->proc_dir = &proc_scsi_in2000;
-
- for ( loop=0; loop < 4; loop++ )
- {
- base = base_tab[loop];
- if ( in2000_test_port(loop)) break;
- }
- if ( loop == 4 )
- return 0;
-
- /* Read the dip switch values again for miscellaneous checking and
- informative messages */
- tmp = inb(INFLED);
-
- /* Bit 2 tells us if interrupts are disabled */
- if ( (tmp & 0x4) == 0 ) {
- printk("The IN-2000 is not configured for interrupt operation\n");
- printk("Change the DIP switch settings to enable interrupt operation\n");
- }
-
- /* Bit 6 tells us about floppy controller */
- printk("IN-2000 probe found floppy controller on IN-2000 ");
- if ( (tmp & 0x40) == 0)
- printk("enabled\n");
- else
- printk("disabled\n");
-
- /* Bit 5 tells us about synch/asynch mode */
- printk("IN-2000 probe found IN-2000 in ");
- if ( (tmp & 0x20) == 0)
- printk("synchronous mode\n");
- else
- printk("asynchronous mode\n");
-
- irq_level = int_tab [ ((~inb(INFLED)>>3)&0x3) ];
-
- printk("Configuring IN2000 at IO:%x, IRQ %d"
-#ifdef FAST_FIFO_IO
- " (using fast FIFO I/O code)"
-#endif
- "\n",base, irq_level);
-
- outb(2,ININTR); /* Shut off the FIFO first, so it won't ask for data.*/
- if (request_irq(irq_level,in2000_intr_handle, 0, "in2000"))
- {
- printk("in2000_detect: Unable to allocate IRQ.\n");
- return 0;
- }
- outb(0,INFWRT); /* read mode so WD can intrpt */
- outb(SCSIST,INSTAT);
- inb(INDATA); /* free status reg, clear WD intrpt */
- outb(OWNID,INSTAT);
- outb(0x7,INDATA); /* we use addr 7 */
- outb(COMMAND,INSTAT);
- outb(0,INDATA); /* do chip reset */
- shpnt = scsi_register(tpnt, 0);
- /* Set these up so that we can unload the driver properly. */
- shpnt->io_port = base;
- shpnt->n_io_port = 12;
- shpnt->irq = irq_level;
- request_region(base, 12,"in2000"); /* Prevent other drivers from using this space */
- return 1;
-}
-
-int in2000_abort(Scsi_Cmnd * SCpnt)
-{
- DEB(printk("in2000_abort\n"));
- /*
- * Ask no stupid questions, just order the abort.
- */
- outb(COMMAND,INSTAT);
- outb(1,INDATA); /* Abort Command */
- return 0;
-}
-
-static inline void delay( unsigned how_long )
-{
- unsigned long time = jiffies + how_long;
- while (jiffies < time) ;
-}
-
-int in2000_reset(Scsi_Cmnd * SCpnt)
-{
- DEB(printk("in2000_reset called\n"));
- /*
- * Note: this is finished off by an incoming interrupt
- */
- outb(0,INFWRT); /* read mode so WD can intrpt */
- outb(SCSIST,INSTAT);
- inb(INDATA);
- outb(OWNID,INSTAT);
- outb(0x7,INDATA); /* ID=7,noadv, no parity, clk div=2 (8-10Mhz clk) */
- outb(COMMAND,INSTAT);
- outb(0,INDATA); /* reset WD chip */
- delay(2);
-#ifdef SCSI_RESET_PENDING
- return SCSI_RESET_PENDING;
-#else
- if(SCpnt) SCpnt->flags |= NEEDS_JUMPSTART;
- return 0;
-#endif
-}
-
-int in2000_biosparam(Disk * disk, kdev_t dev, int* iinfo)
- {
- int size = disk->capacity;
- DEB(printk("in2000_biosparam\n"));
- iinfo[0] = 64;
- iinfo[1] = 32;
- iinfo[2] = size >> 11;
-/* This should approximate the large drive handling that the DOS ASPI manager
- uses. Drives very near the boundaries may not be handled correctly (i.e.
- near 2.0 Gb and 4.0 Gb) */
- if (iinfo[2] > 1024) {
- iinfo[0] = 64;
- iinfo[1] = 63;
- iinfo[2] = disk->capacity / (iinfo[0] * iinfo[1]);
- }
- if (iinfo[2] > 1024) {
- iinfo[0] = 128;
- iinfo[1] = 63;
- iinfo[2] = disk->capacity / (iinfo[0] * iinfo[1]);
- }
- if (iinfo[2] > 1024) {
- iinfo[0] = 255;
- iinfo[1] = 63;
- iinfo[2] = disk->capacity / (iinfo[0] * iinfo[1]);
- if (iinfo[2] > 1023)
- iinfo[2] = 1023;
- }
- return 0;
- }
-
-#ifdef MODULE
-/* Eventually this will go into an include file, but this will be later */
-Scsi_Host_Template driver_template = IN2000;
-
-#include "scsi_module.c"
-#endif
-
diff --git a/i386/i386at/gpl/linux/scsi/in2000.h b/i386/i386at/gpl/linux/scsi/in2000.h
deleted file mode 100644
index cf68db7f..00000000
--- a/i386/i386at/gpl/linux/scsi/in2000.h
+++ /dev/null
@@ -1,122 +0,0 @@
-#ifndef _IN2000_H
-
-/* $Id: in2000.h,v 1.1.1.1 1997/02/25 21:27:50 thomas Exp $
- *
- * Header file for the Always IN 2000 driver for Linux
- *
- */
-
-#include <linux/types.h>
-#include <linux/ioport.h>
-
-/* The IN-2000 is based on a WD33C93 */
-
-#define INSTAT (base + 0x0) /* R: Auxiliary Status; W: register select */
-#define INDATA (base + 0x1) /* R/W: Data port */
-#define INFIFO (base + 0x2) /* R/W FIFO, Word access only */
-#define INREST (base + 0x3) /* W: Reset everything */
-#define INFCNT (base + 0x4) /* R: FIFO byte count */
-#define INFRST (base + 0x5) /* W: Reset Fifo count and to write */
-#define INFWRT (base + 0x7) /* W: Set FIFO to read */
-#define INFLED (base + 0x8) /* W: Set LED; R: Dip Switch settings */
-#define INNLED (base + 0x9) /* W: reset LED */
-#define INVERS (base + 0xa) /* R: Read hw version, end-reset */
-#define ININTR (base + 0xc) /* W: Interrupt Mask Port */
-#define G2CNTRL_HRDY 0x20 /* Sets HOST ready */
-
-/* WD33C93 defines */
-#define OWNID 0
-#undef CONTROL
-#define CONTROL 1
-#define TIMEOUT 2
-#define TOTSECT 3
-#define TOTHEAD 4
-#define TOTCYLH 5
-#define TOTCYLL 6
-#define LADRSHH 7
-#define LADRSHL 8
-#define LADRSLH 9
-#define LADRSLL 10
-#define SECTNUM 11
-#define HEADNUM 12
-#define CYLNUMH 13
-#define CYLNUML 14
-#define TARGETU 15
-#define CMDPHAS 16
-#define SYNCTXR 17
-#define TXCNTH 18
-#define TXCNTM 19
-#define TXCNTL 20
-#define DESTID 21
-#define SRCID 22
-#define SCSIST 23
-#define COMMAND 24
-#define WDDATA 25
-#define AUXSTAT 31
-
-/* OWNID Register Bits */
-#define OWN_EAF 0x08
-#define OWN_EHP 0x10
-#define OWN_FS0 0x40
-#define OWN_FS1 0x80
-/* AUX Register Bits */
-#define AUX_DBR 0
-#define AUX_PE 1
-#define AUX_CIP 0x10
-#define AUX_BSY 0x20
-#define AUX_LCI 0x40
-#define AUX_INT 0x80
-
-/* Select timeout const, 1 count = 8ms */
-#define IN2000_TMOUT 0x1f
-
-/* These belong in scsi.h also */
-#undef any2scsi
-#define any2scsi(up, p) \
-(up)[0] = (((unsigned long)(p)) >> 16); \
-(up)[1] = (((unsigned long)(p)) >> 8); \
-(up)[2] = ((unsigned long)(p));
-
-#undef scsi2int
-#define scsi2int(up) ( ((((long)*(up))&0x1f) << 16) + (((long)(up)[1]) << 8) + ((long)(up)[2]) )
-
-#undef xany2scsi
-#define xany2scsi(up, p) \
-(up)[0] = ((long)(p)) >> 24; \
-(up)[1] = ((long)(p)) >> 16; \
-(up)[2] = ((long)(p)) >> 8; \
-(up)[3] = ((long)(p));
-
-#define xscsi2int(up) ( (((long)(up)[0]) << 24) + (((long)(up)[1]) << 16) \
- + (((long)(up)[2]) << 8) + ((long)(up)[3]) )
-
-#define MAX_CDB 12
-#define MAX_SENSE 14
-#define MAX_STATUS 32
-
-int in2000_detect(Scsi_Host_Template *);
-int in2000_command(Scsi_Cmnd *);
-int in2000_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-int in2000_abort(Scsi_Cmnd *);
-int in2000_reset(Scsi_Cmnd *);
-int in2000_biosparam(Disk *, kdev_t, int*);
-
-#ifndef NULL
- #define NULL 0
-#endif
-
-
-/* next may be "SG_NONE" or "SG_ALL" or nr. of (1k) blocks per R/W Cmd. */
-#define IN2000_SG SG_ALL
-#define IN2000 {NULL, NULL, \
- NULL, NULL, \
- "Always IN2000", in2000_detect, NULL, \
- NULL, in2000_command, \
- in2000_queuecommand, \
- in2000_abort, \
- in2000_reset, \
- NULL, \
- in2000_biosparam, \
- 1, 7, IN2000_SG, 1, 0, 0}
-
-#endif
diff --git a/i386/i386at/gpl/linux/scsi/pas16.c b/i386/i386at/gpl/linux/scsi/pas16.c
deleted file mode 100644
index 9f5d8826..00000000
--- a/i386/i386at/gpl/linux/scsi/pas16.c
+++ /dev/null
@@ -1,553 +0,0 @@
-#define AUTOSENSE
-#define PSEUDO_DMA
-#define FOO
-#define UNSAFE /* Not unsafe for PAS16 -- use it */
-
-/*
- * This driver adapted from Drew Eckhardt's Trantor T128 driver
- *
- * Copyright 1993, Drew Eckhardt
- * Visionary Computing
- * (Unix and Linux consulting and custom programming)
- * drew@colorado.edu
- * +1 (303) 666-5836
- *
- * ( Based on T128 - DISTRIBUTION RELEASE 3. )
- *
- * Modified to work with the Pro Audio Spectrum/Studio 16
- * by John Weidman.
- *
- *
- * For more information, please consult
- *
- * Media Vision
- * (510) 770-8600
- * (800) 348-7116
- *
- * and
- *
- * NCR 5380 Family
- * SCSI Protocol Controller
- * Databook
- *
- * NCR Microelectronics
- * 1635 Aeroplaza Drive
- * Colorado Springs, CO 80916
- * 1+ (719) 578-3400
- * 1+ (800) 334-5454
- */
-
-/*
- * Options :
- * AUTOSENSE - if defined, REQUEST SENSE will be performed automatically
- * for commands that return with a CHECK CONDITION status.
- *
- * LIMIT_TRANSFERSIZE - if defined, limit the pseudo-dma transfers to 512
- * bytes at a time. Since interrupts are disabled by default during
- * these transfers, we might need this to give reasonable interrupt
- * service time if the transfer size gets too large.
- *
- * PSEUDO_DMA - enables PSEUDO-DMA hardware, should give a 3-4X performance
- * increase compared to polled I/O.
- *
- * PARITY - enable parity checking. Not supported.
- *
- * SCSI2 - enable support for SCSI-II tagged queueing. Untested.
- *
- * UNSAFE - leave interrupts enabled during pseudo-DMA transfers. This
- * parameter comes from the NCR5380 code. It is NOT unsafe with
- * the PAS16 and you should use it. If you don't you will have
- * a problem with dropped characters during high speed
- * communications during SCSI transfers. If you really don't
- * want to use UNSAFE you can try defining LIMIT_TRANSFERSIZE or
- * twiddle with the transfer size in the high level code.
- *
- * USLEEP - enable support for devices that don't disconnect. Untested.
- *
- * The card is detected and initialized in one of several ways :
- * 1. Autoprobe (default) - There are many different models of
- * the Pro Audio Spectrum/Studio 16, and I only have one of
- * them, so this may require a little tweaking. An interrupt
- * is triggered to autoprobe for the interrupt line. Note:
- * with the newer model boards, the interrupt is set via
- * software after reset using the default_irq for the
- * current board number.
- *
- *
- * 2. With command line overrides - pas16=port,irq may be
- * used on the LILO command line to override the defaults.
- *
- * 3. With the PAS16_OVERRIDE compile time define. This is
- * specified as an array of address, irq tuples. Ie, for
- * one board at the default 0x388 address, IRQ10, I could say
- * -DPAS16_OVERRIDE={{0x388, 10}}
- * NOTE: Untested.
- *
- * Note that if the override methods are used, place holders must
- * be specified for other boards in the system.
- *
- *
- * Configuration notes :
- * The current driver does not support interrupt sharing with the
- * sound portion of the card. If you use the same irq for the
- * scsi port and sound you will have problems. Either use
- * a different irq for the scsi port or don't use interrupts
- * for the scsi port.
- *
- * If you have problems with your card not being recognized, use
- * the LILO command line override. Try to get it recognized without
- * interrupts. Ie, for a board at the default 0x388 base port,
- * boot: linux pas16=0x388,255
- *
- * (255 is the IRQ_NONE constant in NCR5380.h)
- */
-
-#ifdef MODULE
-#include <linux/module.h>
-#endif
-
-#include <asm/system.h>
-#include <linux/signal.h>
-#include <linux/proc_fs.h>
-#include <linux/sched.h>
-#include <asm/io.h>
-#include <linux/blk.h>
-#include "scsi.h"
-#include "hosts.h"
-#include "pas16.h"
-#define AUTOPROBE_IRQ
-#include "NCR5380.h"
-#include "constants.h"
-#include "sd.h"
-
-#include<linux/stat.h>
-
-struct proc_dir_entry proc_scsi_pas16 = {
- PROC_SCSI_PAS16, 5, "pas16",
- S_IFDIR | S_IRUGO | S_IXUGO, 2
-};
-
-int scsi_irq_translate[] =
- { 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 0, 10, 11 };
-
-/* The default_irqs array contains values used to set the irq into the
- * board via software (as must be done on newer model boards without
- * irq jumpers on the board). The first value in the array will be
- * assigned to logical board 0, the next to board 1, etc.
- */
-int default_irqs[] = { PAS16_DEFAULT_BOARD_1_IRQ,
- PAS16_DEFAULT_BOARD_2_IRQ,
- PAS16_DEFAULT_BOARD_3_IRQ,
- PAS16_DEFAULT_BOARD_4_IRQ
- };
-
-static struct override {
- unsigned short io_port;
- int irq;
-} overrides
-#ifdef PAS16_OVERRIDE
- [] = PAS16_OVERRIDE;
-#else
- [4] = {{0,IRQ_AUTO}, {0,IRQ_AUTO}, {0,IRQ_AUTO},
- {0,IRQ_AUTO}};
-#endif
-
-#define NO_OVERRIDES (sizeof(overrides) / sizeof(struct override))
-
-static struct base {
- unsigned short io_port;
- int noauto;
-} bases[] = { {PAS16_DEFAULT_BASE_1, 0},
- {PAS16_DEFAULT_BASE_2, 0},
- {PAS16_DEFAULT_BASE_3, 0},
- {PAS16_DEFAULT_BASE_4, 0}
- };
-
-#define NO_BASES (sizeof (bases) / sizeof (struct base))
-
-unsigned short pas16_offset[ 8 ] =
- {
- 0x1c00, /* OUTPUT_DATA_REG */
- 0x1c01, /* INITIATOR_COMMAND_REG */
- 0x1c02, /* MODE_REG */
- 0x1c03, /* TARGET_COMMAND_REG */
- 0x3c00, /* STATUS_REG ro, SELECT_ENABLE_REG wo */
- 0x3c01, /* BUS_AND_STATUS_REG ro, START_DMA_SEND_REG wo */
- 0x3c02, /* INPUT_DATA_REGISTER ro, (N/A on PAS16 ?)
- * START_DMA_TARGET_RECEIVE_REG wo
- */
- 0x3c03, /* RESET_PARITY_INTERRUPT_REG ro,
- * START_DMA_INITIATOR_RECEIVE_REG wo
- */
- };
-
-
-
-/*
- * Function : enable_board( int board_num, unsigned short port )
- *
- * Purpose : set address in new model board
- *
- * Inputs : board_num - logical board number 0-3, port - base address
- *
- */
-
-void enable_board( int board_num, unsigned short port )
-{
- outb( 0xbc + board_num, MASTER_ADDRESS_PTR );
- outb( port >> 2, MASTER_ADDRESS_PTR );
-}
-
-
-
-/*
- * Function : init_board( unsigned short port, int irq )
- *
- * Purpose : Set the board up to handle the SCSI interface
- *
- * Inputs : port - base address of the board,
- * irq - irq to assign to the SCSI port
- * force_irq - set it even if it conflicts with sound driver
- *
- */
-
-void init_board( unsigned short io_port, int irq, int force_irq )
-{
- unsigned int tmp;
- unsigned int pas_irq_code;
-
- /* Initialize the SCSI part of the board */
-
- outb( 0x30, io_port + P_TIMEOUT_COUNTER_REG ); /* Timeout counter */
- outb( 0x01, io_port + P_TIMEOUT_STATUS_REG_OFFSET ); /* Reset TC */
- outb( 0x01, io_port + WAIT_STATE ); /* 1 Wait state */
-
- NCR5380_read( RESET_PARITY_INTERRUPT_REG );
-
- /* Set the SCSI interrupt pointer without mucking up the sound
- * interrupt pointer in the same byte.
- */
- pas_irq_code = ( irq < 16 ) ? scsi_irq_translate[irq] : 0;
- tmp = inb( io_port + IO_CONFIG_3 );
-
- if( (( tmp & 0x0f ) == pas_irq_code) && pas_irq_code > 0
- && !force_irq )
- {
- printk( "pas16: WARNING: Can't use same irq as sound "
- "driver -- interrupts disabled\n" );
- /* Set up the drive parameters, disable 5380 interrupts */
- outb( 0x4d, io_port + SYS_CONFIG_4 );
- }
- else
- {
- tmp = ( tmp & 0x0f ) | ( pas_irq_code << 4 );
- outb( tmp, io_port + IO_CONFIG_3 );
-
- /* Set up the drive parameters and enable 5380 interrupts */
- outb( 0x6d, io_port + SYS_CONFIG_4 );
- }
-}
-
-
-/*
- * Function : pas16_hw_detect( unsigned short board_num )
- *
- * Purpose : determine if a pas16 board is present
- *
- * Inputs : board_num - logical board number ( 0 - 3 )
- *
- * Returns : 0 if board not found, 1 if found.
- */
-
-int pas16_hw_detect( unsigned short board_num )
-{
- unsigned char board_rev, tmp;
- unsigned short io_port = bases[ board_num ].io_port;
-
- /* See if we can find a PAS16 board at the address associated
- * with this logical board number.
- */
-
- /* First, attempt to take a newer model board out of reset and
- * give it a base address. This shouldn't affect older boards.
- */
- enable_board( board_num, io_port );
-
- /* Now see if it looks like a PAS16 board */
- board_rev = inb( io_port + PCB_CONFIG );
-
- if( board_rev == 0xff )
- return 0;
-
- tmp = board_rev ^ 0xe0;
-
- outb( tmp, io_port + PCB_CONFIG );
- tmp = inb( io_port + PCB_CONFIG );
- outb( board_rev, io_port + PCB_CONFIG );
-
- if( board_rev != tmp ) /* Not a PAS-16 */
- return 0;
-
- if( ( inb( io_port + OPERATION_MODE_1 ) & 0x03 ) != 0x03 )
- return 0; /* return if no SCSI interface found */
-
- /* Mediavision has some new model boards that return ID bits
- * that indicate a SCSI interface, but they're not (LMS). We'll
- * put in an additional test to try and weed them out.
- */
-
- outb( 0x01, io_port + WAIT_STATE ); /* 1 Wait state */
- NCR5380_write( MODE_REG, 0x20 ); /* Is it really SCSI? */
- if( NCR5380_read( MODE_REG ) != 0x20 ) /* Write to a reg. */
- return 0; /* and try to read */
- NCR5380_write( MODE_REG, 0x00 ); /* it back. */
- if( NCR5380_read( MODE_REG ) != 0x00 )
- return 0;
-
- return 1;
-}
-
-
-/*
- * Function : pas16_setup(char *str, int *ints)
- *
- * Purpose : LILO command line initialization of the overrides array,
- *
- * Inputs : str - unused, ints - array of integer parameters with ints[0]
- * equal to the number of ints.
- *
- */
-
-void pas16_setup(char *str, int *ints) {
- static int commandline_current = 0;
- int i;
- if (ints[0] != 2)
- printk("pas16_setup : usage pas16=io_port,irq\n");
- else
- if (commandline_current < NO_OVERRIDES) {
- overrides[commandline_current].io_port = (unsigned short) ints[1];
- overrides[commandline_current].irq = ints[2];
- for (i = 0; i < NO_BASES; ++i)
- if (bases[i].io_port == (unsigned short) ints[1]) {
- bases[i].noauto = 1;
- break;
- }
- ++commandline_current;
- }
-}
-
-/*
- * Function : int pas16_detect(Scsi_Host_Template * tpnt)
- *
- * Purpose : detects and initializes PAS16 controllers
- * that were autoprobed, overridden on the LILO command line,
- * or specified at compile time.
- *
- * Inputs : tpnt - template for this SCSI adapter.
- *
- * Returns : 1 if a host adapter was found, 0 if not.
- *
- */
-
-int pas16_detect(Scsi_Host_Template * tpnt) {
- static int current_override = 0;
- static unsigned short current_base = 0;
- struct Scsi_Host *instance;
- unsigned short io_port;
- int count;
-
- tpnt->proc_dir = &proc_scsi_pas16;
-
- for (count = 0; current_override < NO_OVERRIDES; ++current_override) {
- io_port = 0;
-
- if (overrides[current_override].io_port)
- {
- io_port = overrides[current_override].io_port;
- enable_board( current_override, io_port );
- init_board( io_port, overrides[current_override].irq, 1 );
- }
- else
- for (; !io_port && (current_base < NO_BASES); ++current_base) {
-#if (PDEBUG & PDEBUG_INIT)
- printk("scsi-pas16 : probing io_port %04x\n", (unsigned int) bases[current_base].io_port);
-#endif
- if ( !bases[current_base].noauto &&
- pas16_hw_detect( current_base ) ){
- io_port = bases[current_base].io_port;
- init_board( io_port, default_irqs[ current_base ], 0 );
-#if (PDEBUG & PDEBUG_INIT)
- printk("scsi-pas16 : detected board.\n");
-#endif
- }
- }
-
-
-#if defined(PDEBUG) && (PDEBUG & PDEBUG_INIT)
- printk("scsi-pas16 : io_port = %04x\n", (unsigned int) io_port);
-#endif
-
- if (!io_port)
- break;
-
- instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
- instance->io_port = io_port;
-
- NCR5380_init(instance, 0);
-
- if (overrides[current_override].irq != IRQ_AUTO)
- instance->irq = overrides[current_override].irq;
- else
- instance->irq = NCR5380_probe_irq(instance, PAS16_IRQS);
-
- if (instance->irq != IRQ_NONE)
- if (request_irq(instance->irq, pas16_intr, SA_INTERRUPT, "pas16")) {
- printk("scsi%d : IRQ%d not free, interrupts disabled\n",
- instance->host_no, instance->irq);
- instance->irq = IRQ_NONE;
- }
-
- if (instance->irq == IRQ_NONE) {
- printk("scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
- printk("scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
- /* Disable 5380 interrupts, leave drive params the same */
- outb( 0x4d, io_port + SYS_CONFIG_4 );
- outb( (inb(io_port + IO_CONFIG_3) & 0x0f), io_port + IO_CONFIG_3 );
- }
-
-#if defined(PDEBUG) && (PDEBUG & PDEBUG_INIT)
- printk("scsi%d : irq = %d\n", instance->host_no, instance->irq);
-#endif
-
- printk("scsi%d : at 0x%04x", instance->host_no, (int)
- instance->io_port);
- if (instance->irq == IRQ_NONE)
- printk (" interrupts disabled");
- else
- printk (" irq %d", instance->irq);
- printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d",
- CAN_QUEUE, CMD_PER_LUN, PAS16_PUBLIC_RELEASE);
- NCR5380_print_options(instance);
- printk("\n");
-
- ++current_override;
- ++count;
- }
- return count;
-}
-
-/*
- * Function : int pas16_biosparam(Disk *disk, kdev_t dev, int *ip)
- *
- * Purpose : Generates a BIOS / DOS compatible H-C-S mapping for
- * the specified device / size.
- *
- * Inputs : size = size of device in sectors (512 bytes), dev = block device
- * major / minor, ip[] = {heads, sectors, cylinders}
- *
- * Returns : always 0 (success), initializes ip
- *
- */
-
-/*
- * XXX Most SCSI boards use this mapping, I could be incorrect. Some one
- * using hard disks on a trantor should verify that this mapping corresponds
- * to that used by the BIOS / ASPI driver by running the linux fdisk program
- * and matching the H_C_S coordinates to what DOS uses.
- */
-
-int pas16_biosparam(Disk * disk, kdev_t dev, int * ip)
-{
- int size = disk->capacity;
- ip[0] = 64;
- ip[1] = 32;
- ip[2] = size >> 11; /* I think I have it as /(32*64) */
- if( ip[2] > 1024 ) { /* yes, >, not >= */
- ip[0]=255;
- ip[1]=63;
- ip[2]=size/(63*255);
- if( ip[2] > 1023 ) /* yes >1023... */
- ip[2] = 1023;
- }
-
- return 0;
-}
-
-/*
- * Function : int NCR5380_pread (struct Scsi_Host *instance,
- * unsigned char *dst, int len)
- *
- * Purpose : Fast 5380 pseudo-dma read function, transfers len bytes to
- * dst
- *
- * Inputs : dst = destination, len = length in bytes
- *
- * Returns : 0 on success, non zero on a failure such as a watchdog
- * timeout.
- */
-
-static inline int NCR5380_pread (struct Scsi_Host *instance, unsigned char *dst,
- int len) {
- register unsigned char *d = dst;
- register unsigned short reg = (unsigned short) (instance->io_port +
- P_DATA_REG_OFFSET);
- register i = len;
-
- while ( !(inb(instance->io_port + P_STATUS_REG_OFFSET) & P_ST_RDY) );
-
- insb( reg, d, i );
-
- if ( inb(instance->io_port + P_TIMEOUT_STATUS_REG_OFFSET) & P_TS_TIM) {
- outb( P_TS_CT, instance->io_port + P_TIMEOUT_STATUS_REG_OFFSET);
- printk("scsi%d : watchdog timer fired in NCR5380_pread()\n",
- instance->host_no);
- return -1;
- } else
- return 0;
-}
-
-/*
- * Function : int NCR5380_pwrite (struct Scsi_Host *instance,
- * unsigned char *src, int len)
- *
- * Purpose : Fast 5380 pseudo-dma write function, transfers len bytes from
- * src
- *
- * Inputs : src = source, len = length in bytes
- *
- * Returns : 0 on success, non zero on a failure such as a watchdog
- * timeout.
- */
-
-static inline int NCR5380_pwrite (struct Scsi_Host *instance, unsigned char *src,
- int len) {
- register unsigned char *s = src;
- register unsigned short reg = (instance->io_port + P_DATA_REG_OFFSET);
- register i = len;
-
- while ( !((inb(instance->io_port + P_STATUS_REG_OFFSET)) & P_ST_RDY) );
-
- outsb( reg, s, i );
-
- if (inb(instance->io_port + P_TIMEOUT_STATUS_REG_OFFSET) & P_TS_TIM) {
- outb( P_TS_CT, instance->io_port + P_TIMEOUT_STATUS_REG_OFFSET);
- printk("scsi%d : watchdog timer fired in NCR5380_pwrite()\n",
- instance->host_no);
- return -1;
- } else
- return 0;
-}
-
-#ifdef MACH
-#include "NCR5380.src"
-#else
-#include "NCR5380.c"
-#endif
-
-#ifdef MODULE
-/* Eventually this will go into an include file, but this will be later */
-Scsi_Host_Template driver_template = MV_PAS16;
-
-#include <linux/module.h>
-#include "scsi_module.c"
-#endif
diff --git a/i386/i386at/gpl/linux/scsi/pas16.h b/i386/i386at/gpl/linux/scsi/pas16.h
deleted file mode 100644
index 9733792b..00000000
--- a/i386/i386at/gpl/linux/scsi/pas16.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * This driver adapted from Drew Eckhardt's Trantor T128 driver
- *
- * Copyright 1993, Drew Eckhardt
- * Visionary Computing
- * (Unix and Linux consulting and custom programming)
- * drew@colorado.edu
- * +1 (303) 666-5836
- *
- * ( Based on T128 - DISTRIBUTION RELEASE 3. )
- *
- * Modified to work with the Pro Audio Spectrum/Studio 16
- * by John Weidman.
- *
- *
- * For more information, please consult
- *
- * Media Vision
- * (510) 770-8600
- * (800) 348-7116
- *
- * and
- *
- * NCR 5380 Family
- * SCSI Protocol Controller
- * Databook
- *
- * NCR Microelectronics
- * 1635 Aeroplaza Drive
- * Colorado Springs, CO 80916
- * 1+ (719) 578-3400
- * 1+ (800) 334-5454
- */
-
-
-#ifndef PAS16_H
-#define PAS16_H
-
-#define PAS16_PUBLIC_RELEASE 3
-
-#define PDEBUG_INIT 0x1
-#define PDEBUG_TRANSFER 0x2
-
-#define PAS16_DEFAULT_BASE_1 0x388
-#define PAS16_DEFAULT_BASE_2 0x384
-#define PAS16_DEFAULT_BASE_3 0x38c
-#define PAS16_DEFAULT_BASE_4 0x288
-
-#define PAS16_DEFAULT_BOARD_1_IRQ 10
-#define PAS16_DEFAULT_BOARD_2_IRQ 12
-#define PAS16_DEFAULT_BOARD_3_IRQ 14
-#define PAS16_DEFAULT_BOARD_4_IRQ 15
-
-
-/*
- * The Pro Audio Spectrum boards are I/O mapped. They use a Zilog 5380
- * SCSI controller, which is the equivalent of NCR's 5380. "Pseudo-DMA"
- * architecture is used, where a PAL drives the DMA signals on the 5380
- * allowing fast, blind transfers with proper handshaking.
- */
-
-
-/* The Time-out Counter register is used to safe-guard against a stuck
- * bus (in the case of RDY driven handshake) or a stuck byte (if 16-Bit
- * DMA conversion is used). The counter uses a 28.224MHz clock
- * divided by 14 as its clock source. In the case of a stuck byte in
- * the holding register, an interrupt is generated (and mixed with the
- * one with the drive) using the CD-ROM interrupt pointer.
- */
-
-#define P_TIMEOUT_COUNTER_REG 0x4000
-#define P_TC_DISABLE 0x80 /* Set to 0 to enable timeout int. */
- /* Bits D6-D0 contain timeout count */
-
-
-#define P_TIMEOUT_STATUS_REG_OFFSET 0x4001
-#define P_TS_TIM 0x80 /* check timeout status */
- /* Bits D6-D4 N/U */
-#define P_TS_ARM_DRQ_INT 0x08 /* Arm DRQ Int. When set high,
- * the next rising edge will
- * cause a CD-ROM interrupt.
- * When set low, the interrupt
- * will be cleared. There is
- * no status available for
- * this interrupt.
- */
-#define P_TS_ENABLE_TO_ERR_INTERRUPT /* Enable timeout error int. */
-#define P_TS_ENABLE_WAIT /* Enable Wait */
-
-#define P_TS_CT 0x01 /* clear timeout. Note: writing
- * to this register clears the
- * timeout error int. or status
- */
-
-
-/*
- * The data register reads/writes to/from the 5380 in pseudo-DMA mode
- */
-
-#define P_DATA_REG_OFFSET 0x5c00 /* rw */
-
-#define P_STATUS_REG_OFFSET 0x5c01 /* ro */
-#define P_ST_RDY 0x80 /* 5380 DDRQ Status */
-
-#define P_IRQ_STATUS 0x5c03
-#define P_IS_IRQ 0x80 /* DIRQ status */
-
-#define PCB_CONFIG 0x803
-#define MASTER_ADDRESS_PTR 0x9a01 /* Fixed position - no relo */
-#define SYS_CONFIG_4 0x8003
-#define WAIT_STATE 0xbc00
-#define OPERATION_MODE_1 0xec03
-#define IO_CONFIG_3 0xf002
-
-
-#ifndef ASM
-int pas16_abort(Scsi_Cmnd *);
-int pas16_biosparam(Disk *, kdev_t, int*);
-int pas16_detect(Scsi_Host_Template *);
-int pas16_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-int pas16_reset(Scsi_Cmnd *);
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#ifndef CMD_PER_LUN
-#define CMD_PER_LUN 2
-#endif
-
-#ifndef CAN_QUEUE
-#define CAN_QUEUE 32
-#endif
-
-/*
- * I hadn't thought of this with the earlier drivers - but to prevent
- * macro definition conflicts, we shouldn't define all of the internal
- * macros when this is being used solely for the host stub.
- */
-
-#if defined(HOSTS_C) || defined(MODULE)
-
-#define MV_PAS16 {NULL, NULL, NULL, NULL, \
- "Pro Audio Spectrum-16 SCSI", \
- pas16_detect, NULL, NULL, \
- NULL, pas16_queue_command, pas16_abort, pas16_reset, NULL, \
- pas16_biosparam, \
- /* can queue */ CAN_QUEUE, /* id */ 7, SG_ALL, \
- /* cmd per lun */ CMD_PER_LUN , 0, 0, DISABLE_CLUSTERING}
-
-#endif
-#ifndef HOSTS_C
-
-#define NCR5380_implementation_fields \
- volatile unsigned short io_port
-
-#define NCR5380_local_declare() \
- volatile unsigned short io_port
-
-#define NCR5380_setup(instance) \
- io_port = (instance)->io_port
-
-#define PAS16_io_port(reg) ( io_port + pas16_offset[(reg)] )
-
-#if !(PDEBUG & PDEBUG_TRANSFER)
-#define NCR5380_read(reg) ( inb(PAS16_io_port(reg)) )
-#define NCR5380_write(reg, value) ( outb((value),PAS16_io_port(reg)) )
-#else
-#define NCR5380_read(reg) \
- (((unsigned char) printk("scsi%d : read register %d at io_port %04x\n"\
- , instance->hostno, (reg), PAS16_io_port(reg))), inb( PAS16_io_port(reg)) )
-
-#define NCR5380_write(reg, value) \
- (printk("scsi%d : write %02x to register %d at io_port %04x\n", \
- instance->hostno, (value), (reg), PAS16_io_port(reg)), \
- outb( (value),PAS16_io_port(reg) ) )
-
-#endif
-
-
-#define NCR5380_intr pas16_intr
-#define NCR5380_queue_command pas16_queue_command
-#define NCR5380_abort pas16_abort
-#define NCR5380_reset pas16_reset
-
-/* 15 14 12 10 7 5 3
- 1101 0100 1010 1000 */
-
-#define PAS16_IRQS 0xd4a8
-
-#endif /* else def HOSTS_C */
-#endif /* ndef ASM */
-#endif /* PAS16_H */
diff --git a/i386/i386at/gpl/linux/scsi/qlogic.c b/i386/i386at/gpl/linux/scsi/qlogic.c
deleted file mode 100644
index 8333275b..00000000
--- a/i386/i386at/gpl/linux/scsi/qlogic.c
+++ /dev/null
@@ -1,678 +0,0 @@
-/*----------------------------------------------------------------*/
-/*
- Qlogic linux driver - work in progress. No Warranty express or implied.
- Use at your own risk. Support Tort Reform so you won't have to read all
- these silly disclaimers.
-
- Copyright 1994, Tom Zerucha.
- zerucha@shell.portal.com
-
- Additional Code, and much appreciated help by
- Michael A. Griffith
- grif@cs.ucr.edu
-
- Thanks to Eric Youngdale and Dave Hinds for loadable module and PCMCIA
- help respectively, and for suffering through my foolishness during the
- debugging process.
-
- Reference Qlogic FAS408 Technical Manual, 53408-510-00A, May 10, 1994
- (you can reference it, but it is incomplete and inaccurate in places)
-
- Version 0.43 4/6/95 - kernel 1.2.0+, pcmcia 2.5.4+
-
- Functions as standalone, loadable, and PCMCIA driver, the latter from
- Dave Hind's PCMCIA package.
-
- Redistributable under terms of the GNU Public License
-
-*/
-/*----------------------------------------------------------------*/
-/* Configuration */
-
-/* Set the following to 2 to use normal interrupt (active high/totempole-
- tristate), otherwise use 0 (REQUIRED FOR PCMCIA) for active low, open
- drain */
-#define QL_INT_ACTIVE_HIGH 2
-
-/* Set the following to 1 to enable the use of interrupts. Note that 0 tends
- to be more stable, but slower (or ties up the system more) */
-#define QL_USE_IRQ 1
-
-/* Set the following to max out the speed of the PIO PseudoDMA transfers,
- again, 0 tends to be slower, but more stable. */
-#define QL_TURBO_PDMA 1
-
-/* This should be 1 to enable parity detection */
-#define QL_ENABLE_PARITY 1
-
-/* This will reset all devices when the driver is initialized (during bootup).
- The other linux drivers don't do this, but the DOS drivers do, and after
- using DOS or some kind of crash or lockup this will bring things back
- without requiring a cold boot. It does take some time to recover from a
- reset, so it is slower, and I have seen timeouts so that devices weren't
- recognized when this was set. */
-#define QL_RESET_AT_START 0
-
-/* crystal frequency in megahertz (for offset 5 and 9)
- Please set this for your card. Most Qlogic cards are 40 Mhz. The
- Control Concepts ISA (not VLB) is 24 Mhz */
-#define XTALFREQ 40
-
-/**********/
-/* DANGER! modify these at your own risk */
-/* SLOWCABLE can usually be reset to zero if you have a clean setup and
- proper termination. The rest are for synchronous transfers and other
- advanced features if your device can transfer faster than 5Mb/sec.
- If you are really curious, email me for a quick howto until I have
- something official */
-/**********/
-
-/*****/
-/* config register 1 (offset 8) options */
-/* This needs to be set to 1 if your cabling is long or noisy */
-#define SLOWCABLE 1
-
-/*****/
-/* offset 0xc */
-/* This will set fast (10Mhz) synchronous timing when set to 1
- For this to have an effect, FASTCLK must also be 1 */
-#define FASTSCSI 0
-
-/* This when set to 1 will set a faster sync transfer rate */
-#define FASTCLK 0
-/*(XTALFREQ>25?1:0)*/
-
-/*****/
-/* offset 6 */
-/* This is the sync transfer divisor, XTALFREQ/X will be the maximum
- achievable data rate (assuming the rest of the system is capable
- and set properly) */
-#define SYNCXFRPD 5
-/*(XTALFREQ/5)*/
-
-/*****/
-/* offset 7 */
-/* This is the count of how many synchronous transfers can take place
- i.e. how many reqs can occur before an ack is given.
- The maximum value for this is 15, the upper bits can modify
- REQ/ACK assertion and deassertion during synchronous transfers
- If this is 0, the bus will only transfer asynchronously */
-#define SYNCOFFST 0
-/* for the curious, bits 7&6 control the deassertion delay in 1/2 cycles
- of the 40Mhz clock. If FASTCLK is 1, specifying 01 (1/2) will
- cause the deassertion to be early by 1/2 clock. Bits 5&4 control
- the assertion delay, also in 1/2 clocks (FASTCLK is ignored here). */
-
-/*----------------------------------------------------------------*/
-#ifdef PCMCIA
-#undef QL_INT_ACTIVE_HIGH
-#define QL_INT_ACTIVE_HIGH 0
-#define MODULE
-#endif
-
-#include <linux/module.h>
-
-#ifdef PCMCIA
-#undef MODULE
-#endif
-
-#include <linux/blk.h> /* to get disk capacity */
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/proc_fs.h>
-#include <linux/unistd.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include "sd.h"
-#include "hosts.h"
-#include "qlogic.h"
-#include<linux/stat.h>
-
-struct proc_dir_entry proc_scsi_qlogic = {
- PROC_SCSI_QLOGIC, 6, "qlogic",
- S_IFDIR | S_IRUGO | S_IXUGO, 2
-};
-
-/*----------------------------------------------------------------*/
-/* driver state info, local to driver */
-static int qbase = 0; /* Port */
-static int qinitid; /* initiator ID */
-static int qabort; /* Flag to cause an abort */
-static int qlirq = -1; /* IRQ being used */
-static char qinfo[80]; /* description */
-static Scsi_Cmnd *qlcmd; /* current command being processed */
-
-static int qlcfg5 = ( XTALFREQ << 5 ); /* 15625/512 */
-static int qlcfg6 = SYNCXFRPD;
-static int qlcfg7 = SYNCOFFST;
-static int qlcfg8 = ( SLOWCABLE << 7 ) | ( QL_ENABLE_PARITY << 4 );
-static int qlcfg9 = ( ( XTALFREQ + 4 ) / 5 );
-static int qlcfgc = ( FASTCLK << 3 ) | ( FASTSCSI << 4 );
-
-/*----------------------------------------------------------------*/
-/* The qlogic card uses two register maps - These macros select which one */
-#define REG0 ( outb( inb( qbase + 0xd ) & 0x7f , qbase + 0xd ), outb( 4 , qbase + 0xd ))
-#define REG1 ( outb( inb( qbase + 0xd ) | 0x80 , qbase + 0xd ), outb( 0xb4 | QL_INT_ACTIVE_HIGH , qbase + 0xd ))
-
-/* following is watchdog timeout in microseconds */
-#define WATCHDOG 5000000
-
-/*----------------------------------------------------------------*/
-/* the following will set the monitor border color (useful to find
- where something crashed or gets stuck at and as a simple profiler) */
-
-#if 0
-#define rtrc(i) {inb(0x3da);outb(0x31,0x3c0);outb((i),0x3c0);}
-#else
-#define rtrc(i) {}
-#endif
-
-/*----------------------------------------------------------------*/
-/* local functions */
-/*----------------------------------------------------------------*/
-static void ql_zap(void);
-/* error recovery - reset everything */
-void ql_zap()
-{
-int x;
-unsigned long flags;
- save_flags( flags );
- cli();
- x = inb(qbase + 0xd);
- REG0;
- outb(3, qbase + 3); /* reset SCSI */
- outb(2, qbase + 3); /* reset chip */
- if (x & 0x80)
- REG1;
- restore_flags( flags );
-}
-
-/*----------------------------------------------------------------*/
-/* do pseudo-dma */
-static int ql_pdma(int phase, char *request, int reqlen)
-{
-int j;
- j = 0;
- if (phase & 1) { /* in */
-#if QL_TURBO_PDMA
-rtrc(4)
- /* empty fifo in large chunks */
- if( reqlen >= 128 && (inb( qbase + 8 ) & 2) ) { /* full */
- insl( qbase + 4, request, 32 );
- reqlen -= 128;
- request += 128;
- }
- while( reqlen >= 84 && !( j & 0xc0 ) ) /* 2/3 */
- if( (j=inb( qbase + 8 )) & 4 ) {
- insl( qbase + 4, request, 21 );
- reqlen -= 84;
- request += 84;
- }
- if( reqlen >= 44 && (inb( qbase + 8 ) & 8) ) { /* 1/3 */
- insl( qbase + 4, request, 11 );
- reqlen -= 44;
- request += 44;
- }
-#endif
- /* until both empty and int (or until reclen is 0) */
-rtrc(7)
- j = 0;
- while( reqlen && !( (j & 0x10) && (j & 0xc0) ) ) {
- /* while bytes to receive and not empty */
- j &= 0xc0;
- while ( reqlen && !( (j=inb(qbase + 8)) & 0x10 ) ) {
- *request++ = inb(qbase + 4);
- reqlen--;
- }
- if( j & 0x10 )
- j = inb(qbase+8);
-
- }
- }
- else { /* out */
-#if QL_TURBO_PDMA
-rtrc(4)
- if( reqlen >= 128 && inb( qbase + 8 ) & 0x10 ) { /* empty */
- outsl(qbase + 4, request, 32 );
- reqlen -= 128;
- request += 128;
- }
- while( reqlen >= 84 && !( j & 0xc0 ) ) /* 1/3 */
- if( !((j=inb( qbase + 8 )) & 8) ) {
- outsl( qbase + 4, request, 21 );
- reqlen -= 84;
- request += 84;
- }
- if( reqlen >= 40 && !(inb( qbase + 8 ) & 4 ) ) { /* 2/3 */
- outsl( qbase + 4, request, 10 );
- reqlen -= 40;
- request += 40;
- }
-#endif
- /* until full and int (or until reclen is 0) */
-rtrc(7)
- j = 0;
- while( reqlen && !( (j & 2) && (j & 0xc0) ) ) {
- /* while bytes to send and not full */
- while ( reqlen && !( (j=inb(qbase + 8)) & 2 ) ) {
- outb(*request++, qbase + 4);
- reqlen--;
- }
- if( j & 2 )
- j = inb(qbase+8);
- }
- }
-/* maybe return reqlen */
- return inb( qbase + 8 ) & 0xc0;
-}
-
-/*----------------------------------------------------------------*/
-/* wait for interrupt flag (polled - not real hardware interrupt) */
-static int ql_wai(void)
-{
-int i,k;
- k = 0;
- i = jiffies + WATCHDOG;
- while ( i > jiffies && !qabort && !((k = inb(qbase + 4)) & 0xe0))
- barrier();
- if (i <= jiffies)
- return (DID_TIME_OUT);
- if (qabort)
- return (qabort == 1 ? DID_ABORT : DID_RESET);
- if (k & 0x60)
- ql_zap();
- if (k & 0x20)
- return (DID_PARITY);
- if (k & 0x40)
- return (DID_ERROR);
- return 0;
-}
-
-/*----------------------------------------------------------------*/
-/* initiate scsi command - queueing handler */
-static void ql_icmd(Scsi_Cmnd * cmd)
-{
-unsigned int i;
-unsigned long flags;
-
- qabort = 0;
-
- save_flags( flags );
- cli();
- REG0;
-/* clearing of interrupts and the fifo is needed */
- inb(qbase + 5); /* clear interrupts */
- if (inb(qbase + 5)) /* if still interrupting */
- outb(2, qbase + 3); /* reset chip */
- else if (inb(qbase + 7) & 0x1f)
- outb(1, qbase + 3); /* clear fifo */
- while (inb(qbase + 5)); /* clear ints */
- REG1;
- outb(1, qbase + 8); /* set for PIO pseudo DMA */
- outb(0, qbase + 0xb); /* disable ints */
- inb(qbase + 8); /* clear int bits */
- REG0;
- outb(0x40, qbase + 0xb); /* enable features */
-
-/* configurables */
- outb( qlcfgc , qbase + 0xc);
-/* config: no reset interrupt, (initiator) bus id */
- outb( 0x40 | qlcfg8 | qinitid, qbase + 8);
- outb( qlcfg7 , qbase + 7 );
- outb( qlcfg6 , qbase + 6 );
-/**/
- outb(qlcfg5, qbase + 5); /* select timer */
- outb(qlcfg9 & 7, qbase + 9); /* prescaler */
-/* outb(0x99, qbase + 5); */
- outb(cmd->target, qbase + 4);
-
- for (i = 0; i < cmd->cmd_len; i++)
- outb(cmd->cmnd[i], qbase + 2);
- qlcmd = cmd;
- outb(0x41, qbase + 3); /* select and send command */
- restore_flags( flags );
-}
-/*----------------------------------------------------------------*/
-/* process scsi command - usually after interrupt */
-static unsigned int ql_pcmd(Scsi_Cmnd * cmd)
-{
-unsigned int i, j, k;
-unsigned int result; /* ultimate return result */
-unsigned int status; /* scsi returned status */
-unsigned int message; /* scsi returned message */
-unsigned int phase; /* recorded scsi phase */
-unsigned int reqlen; /* total length of transfer */
-struct scatterlist *sglist; /* scatter-gather list pointer */
-unsigned int sgcount; /* sg counter */
-
-rtrc(1)
- j = inb(qbase + 6);
- i = inb(qbase + 5);
- if (i == 0x20) {
- return (DID_NO_CONNECT << 16);
- }
- i |= inb(qbase + 5); /* the 0x10 bit can be set after the 0x08 */
- if (i != 0x18) {
- printk("Ql:Bad Interrupt status:%02x\n", i);
- ql_zap();
- return (DID_BAD_INTR << 16);
- }
- j &= 7; /* j = inb( qbase + 7 ) >> 5; */
-/* correct status is supposed to be step 4 */
-/* it sometimes returns step 3 but with 0 bytes left to send */
-/* We can try stuffing the FIFO with the max each time, but we will get a
- sequence of 3 if any bytes are left (but we do flush the FIFO anyway */
- if(j != 3 && j != 4) {
- printk("Ql:Bad sequence for command %d, int %02X, cmdleft = %d\n", j, i, inb( qbase+7 ) & 0x1f );
- ql_zap();
- return (DID_ERROR << 16);
- }
- result = DID_OK;
- if (inb(qbase + 7) & 0x1f) /* if some bytes in fifo */
- outb(1, qbase + 3); /* clear fifo */
-/* note that request_bufflen is the total xfer size when sg is used */
- reqlen = cmd->request_bufflen;
-/* note that it won't work if transfers > 16M are requested */
- if (reqlen && !((phase = inb(qbase + 4)) & 6)) { /* data phase */
-rtrc(2)
- outb(reqlen, qbase); /* low-mid xfer cnt */
- outb(reqlen >> 8, qbase+1); /* low-mid xfer cnt */
- outb(reqlen >> 16, qbase + 0xe); /* high xfer cnt */
- outb(0x90, qbase + 3); /* command do xfer */
-/* PIO pseudo DMA to buffer or sglist */
- REG1;
- if (!cmd->use_sg)
- ql_pdma(phase, cmd->request_buffer, cmd->request_bufflen);
- else {
- sgcount = cmd->use_sg;
- sglist = cmd->request_buffer;
- while (sgcount--) {
- if (qabort) {
- REG0;
- return ((qabort == 1 ? DID_ABORT : DID_RESET) << 16);
- }
- if (ql_pdma(phase, sglist->address, sglist->length))
- break;
- sglist++;
- }
- }
- REG0;
-rtrc(2)
-/* wait for irq (split into second state of irq handler if this can take time) */
- if ((k = ql_wai()))
- return (k << 16);
- k = inb(qbase + 5); /* should be 0x10, bus service */
- }
-/*** Enter Status (and Message In) Phase ***/
- k = jiffies + WATCHDOG;
- while ( k > jiffies && !qabort && !(inb(qbase + 4) & 6)); /* wait for status phase */
- if ( k <= jiffies ) {
- ql_zap();
- return (DID_TIME_OUT << 16);
- }
- while (inb(qbase + 5)); /* clear pending ints */
- if (qabort)
- return ((qabort == 1 ? DID_ABORT : DID_RESET) << 16);
- outb(0x11, qbase + 3); /* get status and message */
- if ((k = ql_wai()))
- return (k << 16);
- i = inb(qbase + 5); /* get chip irq stat */
- j = inb(qbase + 7) & 0x1f; /* and bytes rec'd */
- status = inb(qbase + 2);
- message = inb(qbase + 2);
-/* should get function complete int if Status and message, else bus serv if only status */
- if (!((i == 8 && j == 2) || (i == 0x10 && j == 1))) {
- printk("Ql:Error during status phase, int=%02X, %d bytes recd\n", i, j);
- result = DID_ERROR;
- }
- outb(0x12, qbase + 3); /* done, disconnect */
-rtrc(1)
- if ((k = ql_wai()))
- return (k << 16);
-/* should get bus service interrupt and disconnect interrupt */
- i = inb(qbase + 5); /* should be bus service */
- while (!qabort && ((i & 0x20) != 0x20)) {
- barrier();
- i |= inb(qbase + 5);
- }
-rtrc(0)
- if (qabort)
- return ((qabort == 1 ? DID_ABORT : DID_RESET) << 16);
- return (result << 16) | (message << 8) | (status & STATUS_MASK);
-}
-
-#if QL_USE_IRQ
-/*----------------------------------------------------------------*/
-/* interrupt handler */
-static void ql_ihandl(int irq, struct pt_regs * regs)
-{
-Scsi_Cmnd *icmd;
- REG0;
- if (!(inb(qbase + 4) & 0x80)) /* false alarm? */
- return;
- if (qlcmd == NULL) { /* no command to process? */
- int i;
- i = 16;
- while (i-- && inb(qbase + 5)); /* maybe also ql_zap() */
- return;
- }
- icmd = qlcmd;
- icmd->result = ql_pcmd(icmd);
- qlcmd = NULL;
-/* if result is CHECK CONDITION done calls qcommand to request sense */
- (icmd->scsi_done) (icmd);
-}
-#endif
-
-/*----------------------------------------------------------------*/
-/* global functions */
-/*----------------------------------------------------------------*/
-/* non queued command */
-#if QL_USE_IRQ
-static void qlidone(Scsi_Cmnd * cmd) {}; /* null function */
-#endif
-
-/* command process */
-int qlogic_command(Scsi_Cmnd * cmd)
-{
-int k;
-#if QL_USE_IRQ
- if (qlirq >= 0) {
- qlogic_queuecommand(cmd, qlidone);
- while (qlcmd != NULL);
- return cmd->result;
- }
-#endif
-/* non-irq version */
- if (cmd->target == qinitid)
- return (DID_BAD_TARGET << 16);
- ql_icmd(cmd);
- if ((k = ql_wai()))
- return (k << 16);
- return ql_pcmd(cmd);
-
-}
-
-#if QL_USE_IRQ
-/*----------------------------------------------------------------*/
-/* queued command */
-int qlogic_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
-{
- if(cmd->target == qinitid) {
- cmd->result = DID_BAD_TARGET << 16;
- done(cmd);
- return 0;
- }
-
- cmd->scsi_done = done;
-/* wait for the last command's interrupt to finish */
- while (qlcmd != NULL)
- barrier();
- ql_icmd(cmd);
- return 0;
-}
-#else
-int qlogic_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
-{
- return 1;
-}
-#endif
-
-#ifdef PCMCIA
-/*----------------------------------------------------------------*/
-/* allow PCMCIA code to preset the port */
-/* port should be 0 and irq to -1 respectively for autoprobing */
-void qlogic_preset(int port, int irq)
-{
- qbase=port;
- qlirq=irq;
-}
-#endif
-
-/*----------------------------------------------------------------*/
-/* look for qlogic card and init if found */
-int qlogic_detect(Scsi_Host_Template * host)
-{
-int i, j; /* these are only used by IRQ detect */
-int qltyp; /* type of chip */
-struct Scsi_Host *hreg; /* registered host structure */
-unsigned long flags;
-
-host->proc_dir = &proc_scsi_qlogic;
-
-/* Qlogic Cards only exist at 0x230 or 0x330 (the chip itself decodes the
- address - I check 230 first since MIDI cards are typically at 330
-
- Theoretically, two Qlogic cards can coexist in the same system. This
- should work by simply using this as a loadable module for the second
- card, but I haven't tested this.
-*/
-
- if( !qbase ) {
- for (qbase = 0x230; qbase < 0x430; qbase += 0x100) {
- if( check_region( qbase , 0x10 ) )
- continue;
- REG1;
- if ( ( (inb(qbase + 0xe) ^ inb(qbase + 0xe)) == 7 )
- && ( (inb(qbase + 0xe) ^ inb(qbase + 0xe)) == 7 ) )
- break;
- }
- if (qbase == 0x430)
- return 0;
- }
- else
- printk( "Ql: Using preset base address of %03x\n", qbase );
-
- qltyp = inb(qbase + 0xe) & 0xf8;
- qinitid = host->this_id;
- if (qinitid < 0)
- qinitid = 7; /* if no ID, use 7 */
- outb(1, qbase + 8); /* set for PIO pseudo DMA */
- REG0;
- outb(0x40 | qlcfg8 | qinitid, qbase + 8); /* (ini) bus id, disable scsi rst */
- outb(qlcfg5, qbase + 5); /* select timer */
- outb(qlcfg9, qbase + 9); /* prescaler */
-#if QL_RESET_AT_START
- outb( 3 , qbase + 3 );
- REG1;
- while( inb( qbase + 0xf ) & 4 );
- REG0;
-#endif
-#if QL_USE_IRQ
-/* IRQ probe - toggle pin and check request pending */
-
- if( qlirq == -1 ) {
- save_flags( flags );
- cli();
- i = 0xffff;
- j = 3;
- outb(0x90, qbase + 3); /* illegal command - cause interrupt */
- REG1;
- outb(10, 0x20); /* access pending interrupt map */
- outb(10, 0xa0);
- while (j--) {
- outb(0xb0 | QL_INT_ACTIVE_HIGH , qbase + 0xd); /* int pin off */
- i &= ~(inb(0x20) | (inb(0xa0) << 8)); /* find IRQ off */
- outb(0xb4 | QL_INT_ACTIVE_HIGH , qbase + 0xd); /* int pin on */
- i &= inb(0x20) | (inb(0xa0) << 8); /* find IRQ on */
- }
- REG0;
- while (inb(qbase + 5)); /* purge int */
- j = -1;
- while (i) /* find on bit */
- i >>= 1, j++; /* should check for exactly 1 on */
- qlirq = j;
- restore_flags( flags );
- }
- else
- printk( "Ql: Using preset IRQ %d\n", qlirq );
-
- if (qlirq >= 0 && !request_irq(qlirq, ql_ihandl, 0, "qlogic"))
- host->can_queue = 1;
-#endif
- request_region( qbase , 0x10 ,"qlogic");
- hreg = scsi_register( host , 0 ); /* no host data */
- hreg->io_port = qbase;
- hreg->n_io_port = 16;
- hreg->dma_channel = -1;
- if( qlirq != -1 )
- hreg->irq = qlirq;
-
- sprintf(qinfo, "Qlogic Driver version 0.43, chip %02X at %03X, IRQ %d, TPdma:%d",
- qltyp, qbase, qlirq, QL_TURBO_PDMA );
- host->name = qinfo;
-
- return 1;
-}
-
-/*----------------------------------------------------------------*/
-/* return bios parameters */
-int qlogic_biosparam(Disk * disk, kdev_t dev, int ip[])
-{
-/* This should mimic the DOS Qlogic driver's behavior exactly */
- ip[0] = 0x40;
- ip[1] = 0x20;
- ip[2] = disk->capacity / (ip[0] * ip[1]);
- if (ip[2] > 1024) {
- ip[0] = 0xff;
- ip[1] = 0x3f;
- ip[2] = disk->capacity / (ip[0] * ip[1]);
- if (ip[2] > 1023)
- ip[2] = 1023;
- }
- return 0;
-}
-
-/*----------------------------------------------------------------*/
-/* abort command in progress */
-int qlogic_abort(Scsi_Cmnd * cmd)
-{
- qabort = 1;
- ql_zap();
- return 0;
-}
-
-/*----------------------------------------------------------------*/
-/* reset SCSI bus */
-int qlogic_reset(Scsi_Cmnd * cmd)
-{
- qabort = 2;
- ql_zap();
- return 1;
-}
-
-/*----------------------------------------------------------------*/
-/* return info string */
-const char *qlogic_info(struct Scsi_Host * host)
-{
- return qinfo;
-}
-
-#ifdef MODULE
-/* Eventually this will go into an include file, but this will be later */
-Scsi_Host_Template driver_template = QLOGIC;
-
-#include "scsi_module.c"
-#endif
diff --git a/i386/i386at/gpl/linux/scsi/qlogic.h b/i386/i386at/gpl/linux/scsi/qlogic.h
deleted file mode 100644
index 0ff119ae..00000000
--- a/i386/i386at/gpl/linux/scsi/qlogic.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef _QLOGIC_H
-#define _QLOGIC_H
-
-int qlogic_detect(Scsi_Host_Template * );
-const char * qlogic_info(struct Scsi_Host *);
-int qlogic_command(Scsi_Cmnd *);
-int qlogic_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
-int qlogic_abort(Scsi_Cmnd *);
-int qlogic_reset(Scsi_Cmnd *);
-int qlogic_biosparam(Disk *, kdev_t, int[]);
-
-#ifndef NULL
-#define NULL (0)
-#endif
-
-#define QLOGIC { \
- NULL, \
- NULL, \
- NULL, \
- NULL, \
- NULL, \
- qlogic_detect, \
- NULL, \
- qlogic_info, \
- qlogic_command, \
- qlogic_queuecommand, \
- qlogic_abort, \
- qlogic_reset, \
- NULL, \
- qlogic_biosparam, \
- 0, \
- -1, \
- SG_ALL, \
- 1, \
- 0, \
- 0, \
- DISABLE_CLUSTERING \
-}
-
-#endif /* _QLOGIC_H */
diff --git a/i386/i386at/gpl/linux/scsi/scsi.c b/i386/i386at/gpl/linux/scsi/scsi.c
deleted file mode 100644
index 7b29168f..00000000
--- a/i386/i386at/gpl/linux/scsi/scsi.c
+++ /dev/null
@@ -1,3206 +0,0 @@
-/*
- * scsi.c Copyright (C) 1992 Drew Eckhardt
- * Copyright (C) 1993, 1994, 1995 Eric Youngdale
- *
- * generic mid-level SCSI driver
- * Initial versions: Drew Eckhardt
- * Subsequent revisions: Eric Youngdale
- *
- * <drew@colorado.edu>
- *
- * Bug correction thanks go to :
- * Rik Faith <faith@cs.unc.edu>
- * Tommy Thorn <tthorn>
- * Thomas Wuensche <tw@fgb1.fgb.mw.tu-muenchen.de>
- *
- * Modified by Eric Youngdale eric@aib.com to
- * add scatter-gather, multiple outstanding request, and other
- * enhancements.
- *
- * Native multichannel and wide scsi support added
- * by Michael Neuffer neuffer@goofy.zdv.uni-mainz.de
- */
-
-/*
- * Don't import our own symbols, as this would severely mess up our
- * symbol tables.
- */
-#define _SCSI_SYMS_VER_
-#include <linux/module.h>
-
-#include <asm/system.h>
-#include <linux/sched.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/malloc.h>
-#include <asm/irq.h>
-#include <asm/dma.h>
-#include <linux/ioport.h>
-#include <linux/kernel.h>
-#include<linux/stat.h>
-
-#include <linux/blk.h>
-#include "scsi.h"
-#include "hosts.h"
-#include "constants.h"
-
-#include <linux/config.h>
-
-#undef USE_STATIC_SCSI_MEMORY
-
-/*
-static const char RCSid[] = "$Header: cvs/gnumach/i386/i386at/gpl/linux/scsi/Attic/scsi.c,v 1.2 1997/03/24 21:51:33 thomas Exp $";
-*/
-
-
-/* Command groups 3 and 4 are reserved and should never be used. */
-const unsigned char scsi_command_size[8] = { 6, 10, 10, 12, 12, 12, 10, 10 };
-
-#define INTERNAL_ERROR (panic ("Internal error in file %s, line %d.\n", __FILE__, __LINE__))
-
-/*
- * PAGE_SIZE must be a multiple of the sector size (512). True
- * for all reasonably recent architectures (even the VAX...).
- */
-#define SECTOR_SIZE 512
-#define SECTORS_PER_PAGE (PAGE_SIZE/SECTOR_SIZE)
-
-#if SECTORS_PER_PAGE <= 8
- typedef unsigned char FreeSectorBitmap;
-#elif SECTORS_PER_PAGE <= 32
- typedef unsigned int FreeSectorBitmap;
-#else
-# error You lose.
-#endif
-
-static void scsi_done (Scsi_Cmnd *SCpnt);
-static int update_timeout (Scsi_Cmnd *, int);
-static void print_inquiry(unsigned char *data);
-static void scsi_times_out (Scsi_Cmnd * SCpnt, int pid);
-static int scan_scsis_single (int channel,int dev,int lun,int * max_scsi_dev ,
- Scsi_Device ** SDpnt, Scsi_Cmnd * SCpnt,
- struct Scsi_Host *shpnt, char * scsi_result);
-void scsi_build_commandblocks(Scsi_Device * SDpnt);
-
-#ifdef CONFIG_MODULES
-extern struct symbol_table scsi_symbol_table;
-#endif
-
-static FreeSectorBitmap * dma_malloc_freelist = NULL;
-static int scsi_need_isa_bounce_buffers;
-static unsigned int dma_sectors = 0;
-unsigned int dma_free_sectors = 0;
-unsigned int need_isa_buffer = 0;
-static unsigned char ** dma_malloc_pages = NULL;
-
-static int time_start;
-static int time_elapsed;
-static volatile struct Scsi_Host * host_active = NULL;
-#define SCSI_BLOCK(HOST) ((HOST->block && host_active && HOST != host_active) \
- || (HOST->can_queue && HOST->host_busy >= HOST->can_queue))
-
-#define MAX_SCSI_DEVICE_CODE 10
-const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE] =
-{
- "Direct-Access ",
- "Sequential-Access",
- "Printer ",
- "Processor ",
- "WORM ",
- "CD-ROM ",
- "Scanner ",
- "Optical Device ",
- "Medium Changer ",
- "Communications "
-};
-
-
-/*
- * global variables :
- * scsi_devices an array of these specifying the address for each
- * (host, id, LUN)
- */
-
-Scsi_Device * scsi_devices = NULL;
-
-/* Process ID of SCSI commands */
-unsigned long scsi_pid = 0;
-
-static unsigned char generic_sense[6] = {REQUEST_SENSE, 0,0,0, 255, 0};
-static void resize_dma_pool(void);
-
-/* This variable is merely a hook so that we can debug the kernel with gdb. */
-Scsi_Cmnd * last_cmnd = NULL;
-
-/* This is the pointer to the /proc/scsi code.
- * It is only initialized to !=0 if the scsi code is present
- */
-extern int (* dispatch_scsi_info_ptr)(int ino, char *buffer, char **start,
- off_t offset, int length, int inout);
-extern int dispatch_scsi_info(int ino, char *buffer, char **start,
- off_t offset, int length, int inout);
-
-struct proc_dir_entry proc_scsi_scsi = {
- PROC_SCSI_SCSI, 4, "scsi",
- S_IFREG | S_IRUGO | S_IWUSR, 2, 0, 0, 0,
- NULL,
- NULL, NULL,
- NULL, NULL, NULL
-};
-
-
-/*
- * As the scsi do command functions are intelligent, and may need to
- * redo a command, we need to keep track of the last command
- * executed on each one.
- */
-
-#define WAS_RESET 0x01
-#define WAS_TIMEDOUT 0x02
-#define WAS_SENSE 0x04
-#define IS_RESETTING 0x08
-#define IS_ABORTING 0x10
-#define ASKED_FOR_SENSE 0x20
-
-/*
- * This is the number of clock ticks we should wait before we time out
- * and abort the command. This is for where the scsi.c module generates
- * the command, not where it originates from a higher level, in which
- * case the timeout is specified there.
- *
- * ABORT_TIMEOUT and RESET_TIMEOUT are the timeouts for RESET and ABORT
- * respectively.
- */
-
-#ifdef DEBUG_TIMEOUT
-static void scsi_dump_status(void);
-#endif
-
-
-#ifdef DEBUG
- #define SCSI_TIMEOUT (5*HZ)
-#else
- #define SCSI_TIMEOUT (1*HZ)
-#endif
-
-#ifdef DEBUG
- #define SENSE_TIMEOUT SCSI_TIMEOUT
- #define ABORT_TIMEOUT SCSI_TIMEOUT
- #define RESET_TIMEOUT SCSI_TIMEOUT
-#else
- #define SENSE_TIMEOUT (5*HZ/10)
- #define RESET_TIMEOUT (5*HZ/10)
- #define ABORT_TIMEOUT (5*HZ/10)
-#endif
-
-#define MIN_RESET_DELAY (1*HZ)
-
-/* Do not call reset on error if we just did a reset within 10 sec. */
-#define MIN_RESET_PERIOD (10*HZ)
-
-/* The following devices are known not to tolerate a lun != 0 scan for
- * one reason or another. Some will respond to all luns, others will
- * lock up.
- */
-
-#define BLIST_NOLUN 0x01
-#define BLIST_FORCELUN 0x02
-#define BLIST_BORKEN 0x04
-#define BLIST_KEY 0x08
-#define BLIST_SINGLELUN 0x10
-
-struct dev_info{
- const char * vendor;
- const char * model;
- const char * revision; /* Latest revision known to be bad. Not used yet */
- unsigned flags;
-};
-
-/*
- * This is what was previously known as the blacklist. The concept
- * has been expanded so that we can specify other types of things we
- * need to be aware of.
- */
-static struct dev_info device_list[] =
-{
-{"CHINON","CD-ROM CDS-431","H42", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */
-{"CHINON","CD-ROM CDS-535","Q14", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */
-{"DENON","DRD-25X","V", BLIST_NOLUN}, /* Locks up if probed for lun != 0 */
-{"HITACHI","DK312C","CM81", BLIST_NOLUN}, /* Responds to all lun - dtg */
-{"HITACHI","DK314C","CR21" , BLIST_NOLUN}, /* responds to all lun */
-{"IMS", "CDD521/10","2.06", BLIST_NOLUN}, /* Locks-up when LUN>0 polled. */
-{"MAXTOR","XT-3280","PR02", BLIST_NOLUN}, /* Locks-up when LUN>0 polled. */
-{"MAXTOR","XT-4380S","B3C", BLIST_NOLUN}, /* Locks-up when LUN>0 polled. */
-{"MAXTOR","MXT-1240S","I1.2", BLIST_NOLUN}, /* Locks up when LUN>0 polled */
-{"MAXTOR","XT-4170S","B5A", BLIST_NOLUN}, /* Locks-up sometimes when LUN>0 polled. */
-{"MAXTOR","XT-8760S","B7B", BLIST_NOLUN}, /* guess what? */
-{"MEDIAVIS","RENO CD-ROMX2A","2.03",BLIST_NOLUN},/*Responds to all lun */
-{"NEC","CD-ROM DRIVE:841","1.0", BLIST_NOLUN}, /* Locks-up when LUN>0 polled. */
-{"RODIME","RO3000S","2.33", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */
-{"SEAGATE", "ST157N", "\004|j", BLIST_NOLUN}, /* causes failed REQUEST SENSE on lun 1
- * for aha152x controller, which causes
- * SCSI code to reset bus.*/
-{"SEAGATE", "ST296","921", BLIST_NOLUN}, /* Responds to all lun */
-{"SEAGATE","ST1581","6538",BLIST_NOLUN}, /* Responds to all lun */
-{"SONY","CD-ROM CDU-541","4.3d", BLIST_NOLUN},
-{"SONY","CD-ROM CDU-55S","1.0i", BLIST_NOLUN},
-{"SONY","CD-ROM CDU-561","1.7x", BLIST_NOLUN},
-{"TANDBERG","TDC 3600","U07", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */
-{"TEAC","CD-ROM","1.06", BLIST_NOLUN}, /* causes failed REQUEST SENSE on lun 1
- * for seagate controller, which causes
- * SCSI code to reset bus.*/
-{"TEXEL","CD-ROM","1.06", BLIST_NOLUN}, /* causes failed REQUEST SENSE on lun 1
- * for seagate controller, which causes
- * SCSI code to reset bus.*/
-{"QUANTUM","LPS525S","3110", BLIST_NOLUN}, /* Locks sometimes if polled for lun != 0 */
-{"QUANTUM","PD1225S","3110", BLIST_NOLUN}, /* Locks sometimes if polled for lun != 0 */
-{"MEDIAVIS","CDR-H93MV","1.31", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */
-{"SANKYO", "CP525","6.64", BLIST_NOLUN}, /* causes failed REQ SENSE, extra reset */
-{"HP", "C1750A", "3226", BLIST_NOLUN}, /* scanjet iic */
-{"HP", "C1790A", "", BLIST_NOLUN}, /* scanjet iip */
-{"HP", "C2500A", "", BLIST_NOLUN}, /* scanjet iicx */
-
-/*
- * Other types of devices that have special flags.
- */
-{"SONY","CD-ROM CDU-8001","*", BLIST_BORKEN},
-{"TEXEL","CD-ROM","1.06", BLIST_BORKEN},
-{"INSITE","Floptical F*8I","*", BLIST_KEY},
-{"INSITE","I325VM","*", BLIST_KEY},
-{"PIONEER","CD-ROMDRM-602X","*", BLIST_FORCELUN | BLIST_SINGLELUN},
-{"PIONEER","CD-ROMDRM-604X","*", BLIST_FORCELUN | BLIST_SINGLELUN},
-/*
- * Must be at end of list...
- */
-{NULL, NULL, NULL}
-};
-
-static int get_device_flags(unsigned char * response_data){
- int i = 0;
- unsigned char * pnt;
- for(i=0; 1; i++){
- if(device_list[i].vendor == NULL) return 0;
- pnt = &response_data[8];
- while(*pnt && *pnt == ' ') pnt++;
- if(memcmp(device_list[i].vendor, pnt,
- strlen(device_list[i].vendor))) continue;
- pnt = &response_data[16];
- while(*pnt && *pnt == ' ') pnt++;
- if(memcmp(device_list[i].model, pnt,
- strlen(device_list[i].model))) continue;
- return device_list[i].flags;
- }
- return 0;
-}
-
-void scsi_make_blocked_list(void) {
- int block_count = 0, index;
- unsigned int flags;
- struct Scsi_Host * sh[128], * shpnt;
-
- /*
- * Create a circular linked list from the scsi hosts which have
- * the "wish_block" field in the Scsi_Host structure set.
- * The blocked list should include all the scsi hosts using ISA DMA.
- * In some systems, using two dma channels simultaneously causes
- * unpredictable results.
- * Among the scsi hosts in the blocked list, only one host at a time
- * is allowed to have active commands queued. The transition from
- * one active host to the next one is allowed only when host_busy == 0
- * for the active host (which implies host_busy == 0 for all the hosts
- * in the list). Moreover for block devices the transition to a new
- * active host is allowed only when a request is completed, since a
- * block device request can be divided into multiple scsi commands
- * (when there are few sg lists or clustering is disabled).
- *
- * (DB, 4 Feb 1995)
- */
-
- save_flags(flags);
- cli();
- host_active = NULL;
-
- for(shpnt=scsi_hostlist; shpnt; shpnt = shpnt->next) {
-
-#if 0
- /*
- * Is this is a candidate for the blocked list?
- * Useful to put into the blocked list all the hosts whose driver
- * does not know about the host->block feature.
- */
- if (shpnt->unchecked_isa_dma) shpnt->wish_block = 1;
-#endif
-
- if (shpnt->wish_block) sh[block_count++] = shpnt;
- }
-
- if (block_count == 1) sh[0]->block = NULL;
-
- else if (block_count > 1) {
-
- for(index = 0; index < block_count - 1; index++) {
- sh[index]->block = sh[index + 1];
- printk("scsi%d : added to blocked host list.\n",
- sh[index]->host_no);
- }
-
- sh[block_count - 1]->block = sh[0];
- printk("scsi%d : added to blocked host list.\n",
- sh[index]->host_no);
- }
-
- restore_flags(flags);
-}
-
-static void scan_scsis_done (Scsi_Cmnd * SCpnt)
-{
-
-#ifdef DEBUG
- printk ("scan_scsis_done(%p, %06x)\n", SCpnt->host, SCpnt->result);
-#endif
- SCpnt->request.rq_status = RQ_SCSI_DONE;
-
- if (SCpnt->request.sem != NULL)
- up(SCpnt->request.sem);
-}
-
-#ifdef CONFIG_SCSI_MULTI_LUN
-static int max_scsi_luns = 8;
-#else
-static int max_scsi_luns = 1;
-#endif
-
-void scsi_luns_setup(char *str, int *ints) {
- if (ints[0] != 1)
- printk("scsi_luns_setup : usage max_scsi_luns=n (n should be between 1 and 8)\n");
- else
- max_scsi_luns = ints[1];
-}
-
-/*
- * Detecting SCSI devices :
- * We scan all present host adapter's busses, from ID 0 to ID (max_id).
- * We use the INQUIRY command, determine device type, and pass the ID /
- * lun address of all sequential devices to the tape driver, all random
- * devices to the disk driver.
- */
-static void scan_scsis (struct Scsi_Host *shpnt, unchar hardcoded,
- unchar hchannel, unchar hid, unchar hlun)
-{
- int dev, lun, channel;
- unsigned char scsi_result0[256];
- unsigned char *scsi_result;
- Scsi_Device *SDpnt;
- int max_dev_lun;
- Scsi_Cmnd *SCpnt;
-
- SCpnt = (Scsi_Cmnd *) scsi_init_malloc (sizeof (Scsi_Cmnd), GFP_ATOMIC | GFP_DMA);
- SDpnt = (Scsi_Device *) scsi_init_malloc (sizeof (Scsi_Device), GFP_ATOMIC);
- memset (SCpnt, 0, sizeof (Scsi_Cmnd));
-
-
- /* Make sure we have something that is valid for DMA purposes */
- scsi_result = ( ( !shpnt->unchecked_isa_dma )
- ? &scsi_result0[0] : scsi_init_malloc (512, GFP_DMA));
-
- if (scsi_result == NULL) {
- printk ("Unable to obtain scsi_result buffer\n");
- goto leave;
- }
-
- /* We must chain ourself in the host_queue, so commands can time out */
- if(shpnt->host_queue)
- shpnt->host_queue->prev = SCpnt;
- SCpnt->next = shpnt->host_queue;
- SCpnt->prev = NULL;
- shpnt->host_queue = SCpnt;
-
-
- if (hardcoded == 1) {
- Scsi_Device *oldSDpnt=SDpnt;
- struct Scsi_Device_Template * sdtpnt;
- channel = hchannel;
- if(channel > shpnt->max_channel) goto leave;
- dev = hid;
- if(dev >= shpnt->max_id) goto leave;
- lun = hlun;
- if(lun >= shpnt->max_lun) goto leave;
- scan_scsis_single (channel, dev, lun, &max_dev_lun,
- &SDpnt, SCpnt, shpnt, scsi_result);
- if(SDpnt!=oldSDpnt) {
-
- /* it could happen the blockdevice hasn't yet been inited */
- for(sdtpnt = scsi_devicelist; sdtpnt; sdtpnt = sdtpnt->next)
- if(sdtpnt->init && sdtpnt->dev_noticed) (*sdtpnt->init)();
-
- oldSDpnt->scsi_request_fn = NULL;
- for(sdtpnt = scsi_devicelist; sdtpnt; sdtpnt = sdtpnt->next)
- if(sdtpnt->attach) {
- (*sdtpnt->attach)(oldSDpnt);
- if(oldSDpnt->attached) scsi_build_commandblocks(oldSDpnt);}
- resize_dma_pool();
-
- for(sdtpnt = scsi_devicelist; sdtpnt; sdtpnt = sdtpnt->next) {
- if(sdtpnt->finish && sdtpnt->nr_dev)
- {(*sdtpnt->finish)();}
- }
- }
-
- }
- else {
- for (channel = 0; channel <= shpnt->max_channel; channel++) {
- for (dev = 0; dev < shpnt->max_id; ++dev) {
- if (shpnt->this_id != dev) {
-
- /*
- * We need the for so our continue, etc. work fine. We put this in
- * a variable so that we can override it during the scan if we
- * detect a device *KNOWN* to have multiple logical units.
- */
- max_dev_lun = (max_scsi_luns < shpnt->max_lun ?
- max_scsi_luns : shpnt->max_lun);
- for (lun = 0; lun < max_dev_lun; ++lun) {
- if (!scan_scsis_single (channel, dev, lun, &max_dev_lun,
- &SDpnt, SCpnt, shpnt, scsi_result))
- break; /* break means don't probe further for luns!=0 */
- } /* for lun ends */
- } /* if this_id != id ends */
- } /* for dev ends */
- } /* for channel ends */
- } /* if/else hardcoded */
-
- leave:
-
- {/* Unchain SCpnt from host_queue */
- Scsi_Cmnd *prev,*next,*hqptr;
- for(hqptr=shpnt->host_queue; hqptr!=SCpnt; hqptr=hqptr->next) ;
- if(hqptr) {
- prev=hqptr->prev;
- next=hqptr->next;
- if(prev)
- prev->next=next;
- else
- shpnt->host_queue=next;
- if(next) next->prev=prev;
- }
- }
-
- /* Last device block does not exist. Free memory. */
- if (SDpnt != NULL)
- scsi_init_free ((char *) SDpnt, sizeof (Scsi_Device));
-
- if (SCpnt != NULL)
- scsi_init_free ((char *) SCpnt, sizeof (Scsi_Cmnd));
-
- /* If we allocated a buffer so we could do DMA, free it now */
- if (scsi_result != &scsi_result0[0] && scsi_result != NULL)
- scsi_init_free (scsi_result, 512);
-
-}
-
-/*
- * The worker for scan_scsis.
- * Returning 0 means Please don't ask further for lun!=0, 1 means OK go on.
- * Global variables used : scsi_devices(linked list)
- */
-int scan_scsis_single (int channel, int dev, int lun, int *max_dev_lun,
- Scsi_Device **SDpnt2, Scsi_Cmnd * SCpnt, struct Scsi_Host * shpnt,
- char *scsi_result)
-{
- unsigned char scsi_cmd[12];
- struct Scsi_Device_Template *sdtpnt;
- Scsi_Device * SDtail, *SDpnt=*SDpnt2;
- int bflags, type=-1;
-
- SDtail = scsi_devices;
- if (scsi_devices)
- while (SDtail->next)
- SDtail = SDtail->next;
-
- memset (SDpnt, 0, sizeof (Scsi_Device));
- SDpnt->host = shpnt;
- SDpnt->id = dev;
- SDpnt->lun = lun;
- SDpnt->channel = channel;
-
- /* Some low level driver could use device->type (DB) */
- SDpnt->type = -1;
-
- /*
- * Assume that the device will have handshaking problems, and then fix this
- * field later if it turns out it doesn't
- */
- SDpnt->borken = 1;
- SDpnt->was_reset = 0;
- SDpnt->expecting_cc_ua = 0;
-
- scsi_cmd[0] = TEST_UNIT_READY;
- scsi_cmd[1] = lun << 5;
- scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[4] = scsi_cmd[5] = 0;
-
- SCpnt->host = SDpnt->host;
- SCpnt->device = SDpnt;
- SCpnt->target = SDpnt->id;
- SCpnt->lun = SDpnt->lun;
- SCpnt->channel = SDpnt->channel;
- {
- struct semaphore sem = MUTEX_LOCKED;
- SCpnt->request.sem = &sem;
- SCpnt->request.rq_status = RQ_SCSI_BUSY;
- scsi_do_cmd (SCpnt, (void *) scsi_cmd,
- (void *) scsi_result,
- 256, scan_scsis_done, SCSI_TIMEOUT + 4 * HZ, 5);
- down (&sem);
- }
-
-#if defined(DEBUG) || defined(DEBUG_INIT)
- printk ("scsi: scan_scsis_single id %d lun %d. Return code 0x%08x\n",
- dev, lun, SCpnt->result);
- print_driverbyte(SCpnt->result); print_hostbyte(SCpnt->result);
- printk("\n");
-#endif
-
- if (SCpnt->result) {
- if (((driver_byte (SCpnt->result) & DRIVER_SENSE) ||
- (status_byte (SCpnt->result) & CHECK_CONDITION)) &&
- ((SCpnt->sense_buffer[0] & 0x70) >> 4) == 7) {
- if (((SCpnt->sense_buffer[2] & 0xf) != NOT_READY) &&
- ((SCpnt->sense_buffer[2] & 0xf) != UNIT_ATTENTION) &&
- ((SCpnt->sense_buffer[2] & 0xf) != ILLEGAL_REQUEST || lun > 0))
- return 1;
- }
- else
- return 0;
- }
-
-#if defined (DEBUG) || defined(DEBUG_INIT)
- printk ("scsi: performing INQUIRY\n");
-#endif
- /*
- * Build an INQUIRY command block.
- */
- scsi_cmd[0] = INQUIRY;
- scsi_cmd[1] = (lun << 5) & 0xe0;
- scsi_cmd[2] = 0;
- scsi_cmd[3] = 0;
- scsi_cmd[4] = 255;
- scsi_cmd[5] = 0;
- SCpnt->cmd_len = 0;
- {
- struct semaphore sem = MUTEX_LOCKED;
- SCpnt->request.sem = &sem;
- SCpnt->request.rq_status = RQ_SCSI_BUSY;
- scsi_do_cmd (SCpnt, (void *) scsi_cmd,
- (void *) scsi_result,
- 256, scan_scsis_done, SCSI_TIMEOUT, 3);
- down (&sem);
- }
-
-#if defined(DEBUG) || defined(DEBUG_INIT)
- printk ("scsi: INQUIRY %s with code 0x%x\n",
- SCpnt->result ? "failed" : "successful", SCpnt->result);
-#endif
-
- if (SCpnt->result)
- return 0; /* assume no peripheral if any sort of error */
-
- /*
- * It would seem some TOSHIBA CDROM gets things wrong
- */
- if (!strncmp (scsi_result + 8, "TOSHIBA", 7) &&
- !strncmp (scsi_result + 16, "CD-ROM", 6) &&
- scsi_result[0] == TYPE_DISK) {
- scsi_result[0] = TYPE_ROM;
- scsi_result[1] |= 0x80; /* removable */
- }
-
- if (!strncmp (scsi_result + 8, "NEC", 3)) {
- if (!strncmp (scsi_result + 16, "CD-ROM DRIVE:84 ", 16) ||
- !strncmp (scsi_result + 16, "CD-ROM DRIVE:25", 15))
- SDpnt->manufacturer = SCSI_MAN_NEC_OLDCDR;
- else
- SDpnt->manufacturer = SCSI_MAN_NEC;
- }
- else if (!strncmp (scsi_result + 8, "TOSHIBA", 7))
- SDpnt->manufacturer = SCSI_MAN_TOSHIBA;
- else if (!strncmp (scsi_result + 8, "SONY", 4))
- SDpnt->manufacturer = SCSI_MAN_SONY;
- else if (!strncmp (scsi_result + 8, "PIONEER", 7))
- SDpnt->manufacturer = SCSI_MAN_PIONEER;
- else
- SDpnt->manufacturer = SCSI_MAN_UNKNOWN;
-
- memcpy (SDpnt->vendor, scsi_result + 8, 8);
- memcpy (SDpnt->model, scsi_result + 16, 16);
- memcpy (SDpnt->rev, scsi_result + 32, 4);
-
- SDpnt->removable = (0x80 & scsi_result[1]) >> 7;
- SDpnt->lockable = SDpnt->removable;
- SDpnt->changed = 0;
- SDpnt->access_count = 0;
- SDpnt->busy = 0;
- SDpnt->has_cmdblocks = 0;
- /*
- * Currently, all sequential devices are assumed to be tapes, all random
- * devices disk, with the appropriate read only flags set for ROM / WORM
- * treated as RO.
- */
- switch (type = (scsi_result[0] & 0x1f)) {
- case TYPE_TAPE:
- case TYPE_DISK:
- case TYPE_MOD:
- case TYPE_PROCESSOR:
- case TYPE_SCANNER:
- SDpnt->writeable = 1;
- break;
- case TYPE_WORM:
- case TYPE_ROM:
- SDpnt->writeable = 0;
- break;
- default:
- printk ("scsi: unknown type %d\n", type);
- }
-
- SDpnt->single_lun = 0;
- SDpnt->soft_reset =
- (scsi_result[7] & 1) && ((scsi_result[3] & 7) == 2);
- SDpnt->random = (type == TYPE_TAPE) ? 0 : 1;
- SDpnt->type = (type & 0x1f);
-
- print_inquiry (scsi_result);
-
- for (sdtpnt = scsi_devicelist; sdtpnt;
- sdtpnt = sdtpnt->next)
- if (sdtpnt->detect)
- SDpnt->attached +=
- (*sdtpnt->detect) (SDpnt);
-
- SDpnt->scsi_level = scsi_result[2] & 0x07;
- if (SDpnt->scsi_level >= 2 ||
- (SDpnt->scsi_level == 1 &&
- (scsi_result[3] & 0x0f) == 1))
- SDpnt->scsi_level++;
-
- /*
- * Set the tagged_queue flag for SCSI-II devices that purport to support
- * tagged queuing in the INQUIRY data.
- */
- SDpnt->tagged_queue = 0;
- if ((SDpnt->scsi_level >= SCSI_2) &&
- (scsi_result[7] & 2)) {
- SDpnt->tagged_supported = 1;
- SDpnt->current_tag = 0;
- }
-
- /*
- * Accommodate drivers that want to sleep when they should be in a polling
- * loop.
- */
- SDpnt->disconnect = 0;
-
- /*
- * Get any flags for this device.
- */
- bflags = get_device_flags (scsi_result);
-
- /*
- * Some revisions of the Texel CD ROM drives have handshaking problems when
- * used with the Seagate controllers. Before we know what type of device
- * we're talking to, we assume it's borken and then change it here if it
- * turns out that it isn't a TEXEL drive.
- */
- if ((bflags & BLIST_BORKEN) == 0)
- SDpnt->borken = 0;
-
- /*
- * These devices need this "key" to unlock the devices so we can use it
- */
- if ((bflags & BLIST_KEY) != 0) {
- printk ("Unlocked floptical drive.\n");
- SDpnt->lockable = 0;
- scsi_cmd[0] = MODE_SENSE;
- scsi_cmd[1] = (lun << 5) & 0xe0;
- scsi_cmd[2] = 0x2e;
- scsi_cmd[3] = 0;
- scsi_cmd[4] = 0x2a;
- scsi_cmd[5] = 0;
- SCpnt->cmd_len = 0;
- {
- struct semaphore sem = MUTEX_LOCKED;
- SCpnt->request.rq_status = RQ_SCSI_BUSY;
- SCpnt->request.sem = &sem;
- scsi_do_cmd (SCpnt, (void *) scsi_cmd,
- (void *) scsi_result, 0x2a,
- scan_scsis_done, SCSI_TIMEOUT, 3);
- down (&sem);
- }
- }
- /* Add this device to the linked list at the end */
- if (SDtail)
- SDtail->next = SDpnt;
- else
- scsi_devices = SDpnt;
- SDtail = SDpnt;
-
- SDpnt = (Scsi_Device *) scsi_init_malloc (sizeof (Scsi_Device), GFP_ATOMIC);
- *SDpnt2=SDpnt;
- if (!SDpnt)
- printk ("scsi: scan_scsis_single: Cannot malloc\n");
-
-
- /*
- * Some scsi devices cannot be polled for lun != 0 due to firmware bugs
- */
- if (bflags & BLIST_NOLUN)
- return 0; /* break; */
-
- /*
- * If we want to only allow I/O to one of the luns attached to this device
- * at a time, then we set this flag.
- */
- if (bflags & BLIST_SINGLELUN)
- SDpnt->single_lun = 1;
-
- /*
- * If this device is known to support multiple units, override the other
- * settings, and scan all of them.
- */
- if (bflags & BLIST_FORCELUN)
- *max_dev_lun = 8;
- /*
- * We assume the device can't handle lun!=0 if: - it reports scsi-0 (ANSI
- * SCSI Revision 0) (old drives like MAXTOR XT-3280) or - it reports scsi-1
- * (ANSI SCSI Revision 1) and Response Data Format 0
- */
- if (((scsi_result[2] & 0x07) == 0)
- ||
- ((scsi_result[2] & 0x07) == 1 &&
- (scsi_result[3] & 0x0f) == 0))
- return 0;
- return 1;
-}
-
-/*
- * Flag bits for the internal_timeout array
- */
-#define NORMAL_TIMEOUT 0
-#define IN_ABORT 1
-#define IN_RESET 2
-
-/*
- * This is our time out function, called when the timer expires for a
- * given host adapter. It will attempt to abort the currently executing
- * command, that failing perform a kernel panic.
- */
-
-static void scsi_times_out (Scsi_Cmnd * SCpnt, int pid)
-{
-
- switch (SCpnt->internal_timeout & (IN_ABORT | IN_RESET))
- {
- case NORMAL_TIMEOUT:
- {
-#ifdef DEBUG_TIMEOUT
- scsi_dump_status();
-#endif
- }
-
- if (!scsi_abort (SCpnt, DID_TIME_OUT, pid))
- return;
- case IN_ABORT:
- printk("SCSI host %d abort (pid %ld) timed out - resetting\n",
- SCpnt->host->host_no, SCpnt->pid);
- if (!scsi_reset (SCpnt, FALSE))
- return;
- case IN_RESET:
- case (IN_ABORT | IN_RESET):
- /* This might be controversial, but if there is a bus hang,
- * you might conceivably want the machine up and running
- * esp if you have an ide disk.
- */
- printk("Unable to reset scsi host %d - ", SCpnt->host->host_no);
- printk("probably a SCSI bus hang.\n");
- SCpnt->internal_timeout &= ~IN_RESET;
- scsi_reset (SCpnt, TRUE);
- return;
-
- default:
- INTERNAL_ERROR;
- }
-
-}
-
-
-/* This function takes a quick look at a request, and decides if it
- * can be queued now, or if there would be a stall while waiting for
- * something else to finish. This routine assumes that interrupts are
- * turned off when entering the routine. It is the responsibility
- * of the calling code to ensure that this is the case.
- */
-
-Scsi_Cmnd * request_queueable (struct request * req, Scsi_Device * device)
-{
- Scsi_Cmnd * SCpnt = NULL;
- int tablesize;
- Scsi_Cmnd * found = NULL;
- struct buffer_head * bh, *bhp;
-
- if (!device)
- panic ("No device passed to request_queueable().\n");
-
- if (req && req->rq_status == RQ_INACTIVE)
- panic("Inactive in request_queueable");
-
- SCpnt = device->host->host_queue;
-
- /*
- * Look for a free command block. If we have been instructed not to queue
- * multiple commands to multi-lun devices, then check to see what else is
- * going for this device first.
- */
-
- SCpnt = device->host->host_queue;
- if (!device->single_lun) {
- while(SCpnt){
- if(SCpnt->target == device->id &&
- SCpnt->lun == device->lun) {
- if(SCpnt->request.rq_status == RQ_INACTIVE) break;
- }
- SCpnt = SCpnt->next;
- }
- } else {
- while(SCpnt){
- if(SCpnt->target == device->id) {
- if (SCpnt->lun == device->lun) {
- if(found == NULL
- && SCpnt->request.rq_status == RQ_INACTIVE)
- {
- found=SCpnt;
- }
- }
- if(SCpnt->request.rq_status != RQ_INACTIVE) {
- /*
- * I think that we should really limit things to one
- * outstanding command per device - this is what tends
- * to trip up buggy firmware.
- */
- return NULL;
- }
- }
- SCpnt = SCpnt->next;
- }
- SCpnt = found;
- }
-
- if (!SCpnt) return NULL;
-
- if (SCSI_BLOCK(device->host)) return NULL;
-
- if (req) {
- memcpy(&SCpnt->request, req, sizeof(struct request));
- tablesize = device->host->sg_tablesize;
- bhp = bh = req->bh;
- if(!tablesize) bh = NULL;
- /* Take a quick look through the table to see how big it is.
- * We already have our copy of req, so we can mess with that
- * if we want to.
- */
- while(req->nr_sectors && bh){
- bhp = bhp->b_reqnext;
- if(!bhp || !CONTIGUOUS_BUFFERS(bh,bhp)) tablesize--;
- req->nr_sectors -= bh->b_size >> 9;
- req->sector += bh->b_size >> 9;
- if(!tablesize) break;
- bh = bhp;
- }
- if(req->nr_sectors && bh && bh->b_reqnext){ /* Any leftovers? */
- SCpnt->request.bhtail = bh;
- req->bh = bh->b_reqnext; /* Divide request */
- bh->b_reqnext = NULL;
- bh = req->bh;
-
- /* Now reset things so that req looks OK */
- SCpnt->request.nr_sectors -= req->nr_sectors;
- req->current_nr_sectors = bh->b_size >> 9;
- req->buffer = bh->b_data;
- SCpnt->request.sem = NULL; /* Wait until whole thing done */
- } else {
- req->rq_status = RQ_INACTIVE;
- wake_up(&wait_for_request);
- }
- } else {
- SCpnt->request.rq_status = RQ_SCSI_BUSY; /* Busy, but no request */
- SCpnt->request.sem = NULL; /* And no one is waiting for the device
- * either */
- }
-
- SCpnt->use_sg = 0; /* Reset the scatter-gather flag */
- SCpnt->old_use_sg = 0;
- SCpnt->transfersize = 0;
- SCpnt->underflow = 0;
- SCpnt->cmd_len = 0;
-
-/* Since not everyone seems to set the device info correctly
- * before Scsi_Cmnd gets send out to scsi_do_command, we do it here.
- */
- SCpnt->channel = device->channel;
- SCpnt->lun = device->lun;
- SCpnt->target = device->id;
-
- return SCpnt;
-}
-
-/* This function returns a structure pointer that will be valid for
- * the device. The wait parameter tells us whether we should wait for
- * the unit to become free or not. We are also able to tell this routine
- * not to return a descriptor if the host is unable to accept any more
- * commands for the time being. We need to keep in mind that there is no
- * guarantee that the host remain not busy. Keep in mind the
- * request_queueable function also knows the internal allocation scheme
- * of the packets for each device
- */
-
-Scsi_Cmnd * allocate_device (struct request ** reqp, Scsi_Device * device,
- int wait)
-{
- kdev_t dev;
- struct request * req = NULL;
- int tablesize;
- unsigned int flags;
- struct buffer_head * bh, *bhp;
- struct Scsi_Host * host;
- Scsi_Cmnd * SCpnt = NULL;
- Scsi_Cmnd * SCwait = NULL;
- Scsi_Cmnd * found = NULL;
-
- if (!device)
- panic ("No device passed to allocate_device().\n");
-
- if (reqp) req = *reqp;
-
- /* See if this request has already been queued by an interrupt routine */
- if (req) {
- if(req->rq_status == RQ_INACTIVE) return NULL;
- dev = req->rq_dev;
- } else
- dev = 0; /* unused */
-
- host = device->host;
-
- if (intr_count && SCSI_BLOCK(host)) return NULL;
-
- while (1==1){
- SCpnt = device->host->host_queue;
- if (!device->single_lun) {
- while(SCpnt){
- if(SCpnt->target == device->id &&
- SCpnt->lun == device->lun) {
- SCwait = SCpnt;
- if(SCpnt->request.rq_status == RQ_INACTIVE) break;
- }
- SCpnt = SCpnt->next;
- }
- } else {
- while(SCpnt){
- if(SCpnt->target == device->id) {
- if (SCpnt->lun == device->lun) {
- SCwait = SCpnt;
- if(found == NULL
- && SCpnt->request.rq_status == RQ_INACTIVE)
- {
- found=SCpnt;
- }
- }
- if(SCpnt->request.rq_status != RQ_INACTIVE) {
- /*
- * I think that we should really limit things to one
- * outstanding command per device - this is what tends
- * to trip up buggy firmware.
- */
- found = NULL;
- break;
- }
- }
- SCpnt = SCpnt->next;
- }
- SCpnt = found;
- }
-
- save_flags(flags);
- cli();
- /* See if this request has already been queued by an interrupt routine
- */
- if (req && (req->rq_status == RQ_INACTIVE || req->rq_dev != dev)) {
- restore_flags(flags);
- return NULL;
- }
- if (!SCpnt || SCpnt->request.rq_status != RQ_INACTIVE) /* Might have changed */
- {
- restore_flags(flags);
- if(!wait) return NULL;
- if (!SCwait) {
- printk("Attempt to allocate device channel %d, target %d, "
- "lun %d\n", device->channel, device->id, device->lun);
- panic("No device found in allocate_device\n");
- }
- SCSI_SLEEP(&device->device_wait,
- (SCwait->request.rq_status != RQ_INACTIVE));
- } else {
- if (req) {
- memcpy(&SCpnt->request, req, sizeof(struct request));
- tablesize = device->host->sg_tablesize;
- bhp = bh = req->bh;
- if(!tablesize) bh = NULL;
- /* Take a quick look through the table to see how big it is.
- * We already have our copy of req, so we can mess with that
- * if we want to.
- */
- while(req->nr_sectors && bh){
- bhp = bhp->b_reqnext;
- if(!bhp || !CONTIGUOUS_BUFFERS(bh,bhp)) tablesize--;
- req->nr_sectors -= bh->b_size >> 9;
- req->sector += bh->b_size >> 9;
- if(!tablesize) break;
- bh = bhp;
- }
- if(req->nr_sectors && bh && bh->b_reqnext){/* Any leftovers? */
- SCpnt->request.bhtail = bh;
- req->bh = bh->b_reqnext; /* Divide request */
- bh->b_reqnext = NULL;
- bh = req->bh;
- /* Now reset things so that req looks OK */
- SCpnt->request.nr_sectors -= req->nr_sectors;
- req->current_nr_sectors = bh->b_size >> 9;
- req->buffer = bh->b_data;
- SCpnt->request.sem = NULL; /* Wait until whole thing done*/
- }
- else
- {
- req->rq_status = RQ_INACTIVE;
- *reqp = req->next;
- wake_up(&wait_for_request);
- }
- } else {
- SCpnt->request.rq_status = RQ_SCSI_BUSY;
- SCpnt->request.sem = NULL; /* And no one is waiting for this
- * to complete */
- }
- restore_flags(flags);
- break;
- }
- }
-
- SCpnt->use_sg = 0; /* Reset the scatter-gather flag */
- SCpnt->old_use_sg = 0;
- SCpnt->transfersize = 0; /* No default transfer size */
- SCpnt->cmd_len = 0;
-
- SCpnt->underflow = 0; /* Do not flag underflow conditions */
-
- /* Since not everyone seems to set the device info correctly
- * before Scsi_Cmnd gets send out to scsi_do_command, we do it here.
- */
- SCpnt->channel = device->channel;
- SCpnt->lun = device->lun;
- SCpnt->target = device->id;
-
- return SCpnt;
-}
-
-/*
- * This is inline because we have stack problemes if we recurse to deeply.
- */
-
-inline void internal_cmnd (Scsi_Cmnd * SCpnt)
-{
- int temp;
- struct Scsi_Host * host;
- unsigned int flags;
-#ifdef DEBUG_DELAY
- int clock;
-#endif
-
- host = SCpnt->host;
-
- /*
- * We will wait MIN_RESET_DELAY clock ticks after the last reset so
- * we can avoid the drive not being ready.
- */
- save_flags(flags);
- sti();
- temp = host->last_reset + MIN_RESET_DELAY;
- while (jiffies < temp);
- restore_flags(flags);
-
- update_timeout(SCpnt, SCpnt->timeout_per_command);
-
- /*
- * We will use a queued command if possible, otherwise we will emulate the
- * queuing and calling of completion function ourselves.
- */
-#ifdef DEBUG
- printk("internal_cmnd (host = %d, channel = %d, target = %d, "
- "command = %p, buffer = %p, \nbufflen = %d, done = %p)\n",
- SCpnt->host->host_no, SCpnt->channel, SCpnt->target, SCpnt->cmnd,
- SCpnt->buffer, SCpnt->bufflen, SCpnt->done);
-#endif
-
- if (host->can_queue)
- {
-#ifdef DEBUG
- printk("queuecommand : routine at %p\n",
- host->hostt->queuecommand);
-#endif
- /* This locking tries to prevent all sorts of races between
- * queuecommand and the interrupt code. In effect,
- * we are only allowed to be in queuecommand once at
- * any given time, and we can only be in the interrupt
- * handler and the queuecommand function at the same time
- * when queuecommand is called while servicing the
- * interrupt.
- */
-
- if(!intr_count && SCpnt->host->irq)
- disable_irq(SCpnt->host->irq);
-
- host->hostt->queuecommand (SCpnt, scsi_done);
-
- if(!intr_count && SCpnt->host->irq)
- enable_irq(SCpnt->host->irq);
- }
- else
- {
-
-#ifdef DEBUG
- printk("command() : routine at %p\n", host->hostt->command);
-#endif
- temp=host->hostt->command (SCpnt);
- SCpnt->result = temp;
-#ifdef DEBUG_DELAY
- clock = jiffies + 4 * HZ;
- while (jiffies < clock);
- printk("done(host = %d, result = %04x) : routine at %p\n",
- host->host_no, temp, host->hostt->command);
-#endif
- scsi_done(SCpnt);
- }
-#ifdef DEBUG
- printk("leaving internal_cmnd()\n");
-#endif
-}
-
-static void scsi_request_sense (Scsi_Cmnd * SCpnt)
-{
- unsigned int flags;
-
- save_flags(flags);
- cli();
- SCpnt->flags |= WAS_SENSE | ASKED_FOR_SENSE;
- update_timeout(SCpnt, SENSE_TIMEOUT);
- restore_flags(flags);
-
-
- memcpy ((void *) SCpnt->cmnd , (void *) generic_sense,
- sizeof(generic_sense));
-
- SCpnt->cmnd[1] = SCpnt->lun << 5;
- SCpnt->cmnd[4] = sizeof(SCpnt->sense_buffer);
-
- SCpnt->request_buffer = &SCpnt->sense_buffer;
- SCpnt->request_bufflen = sizeof(SCpnt->sense_buffer);
- SCpnt->use_sg = 0;
- SCpnt->cmd_len = COMMAND_SIZE(SCpnt->cmnd[0]);
- internal_cmnd (SCpnt);
-}
-
-
-
-/*
- * scsi_do_cmd sends all the commands out to the low-level driver. It
- * handles the specifics required for each low level driver - ie queued
- * or non queued. It also prevents conflicts when different high level
- * drivers go for the same host at the same time.
- */
-
-void scsi_do_cmd (Scsi_Cmnd * SCpnt, const void *cmnd ,
- void *buffer, unsigned bufflen, void (*done)(Scsi_Cmnd *),
- int timeout, int retries)
-{
- unsigned long flags;
- struct Scsi_Host * host = SCpnt->host;
-
-#ifdef DEBUG
- {
- int i;
- int target = SCpnt->target;
- printk ("scsi_do_cmd (host = %d, channel = %d target = %d, "
- "buffer =%p, bufflen = %d, done = %p, timeout = %d, "
- "retries = %d)\n"
- "command : " , host->host_no, SCpnt->channel, target, buffer,
- bufflen, done, timeout, retries);
- for (i = 0; i < 10; ++i)
- printk ("%02x ", ((unsigned char *) cmnd)[i]);
- printk("\n");
- }
-#endif
-
- if (!host)
- {
- panic ("Invalid or not present host.\n");
- }
-
-
- /*
- * We must prevent reentrancy to the lowlevel host driver. This prevents
- * it - we enter a loop until the host we want to talk to is not busy.
- * Race conditions are prevented, as interrupts are disabled in between the
- * time we check for the host being not busy, and the time we mark it busy
- * ourselves.
- */
-
- save_flags(flags);
- cli();
- SCpnt->pid = scsi_pid++;
-
- while (SCSI_BLOCK(host)) {
- restore_flags(flags);
- SCSI_SLEEP(&host->host_wait, SCSI_BLOCK(host));
- cli();
- }
-
- if (host->block) host_active = host;
-
- host->host_busy++;
- restore_flags(flags);
-
- /*
- * Our own function scsi_done (which marks the host as not busy, disables
- * the timeout counter, etc) will be called by us or by the
- * scsi_hosts[host].queuecommand() function needs to also call
- * the completion function for the high level driver.
- */
-
- memcpy ((void *) SCpnt->data_cmnd , (const void *) cmnd, 12);
-#if 0
- SCpnt->host = host;
- SCpnt->channel = channel;
- SCpnt->target = target;
- SCpnt->lun = (SCpnt->data_cmnd[1] >> 5);
-#endif
- SCpnt->bufflen = bufflen;
- SCpnt->buffer = buffer;
- SCpnt->flags=0;
- SCpnt->retries=0;
- SCpnt->allowed=retries;
- SCpnt->done = done;
- SCpnt->timeout_per_command = timeout;
-
- memcpy ((void *) SCpnt->cmnd , (const void *) cmnd, 12);
- /* Zero the sense buffer. Some host adapters automatically request
- * sense on error. 0 is not a valid sense code.
- */
- memset ((void *) SCpnt->sense_buffer, 0, sizeof SCpnt->sense_buffer);
- SCpnt->request_buffer = buffer;
- SCpnt->request_bufflen = bufflen;
- SCpnt->old_use_sg = SCpnt->use_sg;
- if (SCpnt->cmd_len == 0)
- SCpnt->cmd_len = COMMAND_SIZE(SCpnt->cmnd[0]);
- SCpnt->old_cmd_len = SCpnt->cmd_len;
-
- /* Start the timer ticking. */
-
- SCpnt->internal_timeout = 0;
- SCpnt->abort_reason = 0;
- internal_cmnd (SCpnt);
-
-#ifdef DEBUG
- printk ("Leaving scsi_do_cmd()\n");
-#endif
-}
-
-static int check_sense (Scsi_Cmnd * SCpnt)
-{
- /* If there is no sense information, request it. If we have already
- * requested it, there is no point in asking again - the firmware must
- * be confused.
- */
- if (((SCpnt->sense_buffer[0] & 0x70) >> 4) != 7) {
- if(!(SCpnt->flags & ASKED_FOR_SENSE))
- return SUGGEST_SENSE;
- else
- return SUGGEST_RETRY;
- }
-
- SCpnt->flags &= ~ASKED_FOR_SENSE;
-
-#ifdef DEBUG_INIT
- printk("scsi%d, channel%d : ", SCpnt->host->host_no, SCpnt->channel);
- print_sense("", SCpnt);
- printk("\n");
-#endif
- if (SCpnt->sense_buffer[2] & 0xe0)
- return SUGGEST_ABORT;
-
- switch (SCpnt->sense_buffer[2] & 0xf)
- {
- case NO_SENSE:
- return 0;
- case RECOVERED_ERROR:
- return SUGGEST_IS_OK;
-
- case ABORTED_COMMAND:
- return SUGGEST_RETRY;
- case NOT_READY:
- case UNIT_ATTENTION:
- /*
- * If we are expecting a CC/UA because of a bus reset that we
- * performed, treat this just as a retry. Otherwise this is
- * information that we should pass up to the upper-level driver
- * so that we can deal with it there.
- */
- if( SCpnt->device->expecting_cc_ua )
- {
- SCpnt->device->expecting_cc_ua = 0;
- return SUGGEST_RETRY;
- }
- return SUGGEST_ABORT;
-
- /* these three are not supported */
- case COPY_ABORTED:
- case VOLUME_OVERFLOW:
- case MISCOMPARE:
-
- case MEDIUM_ERROR:
- return SUGGEST_REMAP;
- case BLANK_CHECK:
- case DATA_PROTECT:
- case HARDWARE_ERROR:
- case ILLEGAL_REQUEST:
- default:
- return SUGGEST_ABORT;
- }
-}
-
-/* This function is the mid-level interrupt routine, which decides how
- * to handle error conditions. Each invocation of this function must
- * do one and *only* one of the following:
- *
- * (1) Call last_cmnd[host].done. This is done for fatal errors and
- * normal completion, and indicates that the handling for this
- * request is complete.
- * (2) Call internal_cmnd to requeue the command. This will result in
- * scsi_done being called again when the retry is complete.
- * (3) Call scsi_request_sense. This asks the host adapter/drive for
- * more information about the error condition. When the information
- * is available, scsi_done will be called again.
- * (4) Call reset(). This is sort of a last resort, and the idea is that
- * this may kick things loose and get the drive working again. reset()
- * automatically calls scsi_request_sense, and thus scsi_done will be
- * called again once the reset is complete.
- *
- * If none of the above actions are taken, the drive in question
- * will hang. If more than one of the above actions are taken by
- * scsi_done, then unpredictable behavior will result.
- */
-static void scsi_done (Scsi_Cmnd * SCpnt)
-{
- int status=0;
- int exit=0;
- int checked;
- int oldto;
- struct Scsi_Host * host = SCpnt->host;
- int result = SCpnt->result;
- oldto = update_timeout(SCpnt, 0);
-
-#ifdef DEBUG_TIMEOUT
- if(result) printk("Non-zero result in scsi_done %x %d:%d\n",
- result, SCpnt->target, SCpnt->lun);
-#endif
-
- /* If we requested an abort, (and we got it) then fix up the return
- * status to say why
- */
- if(host_byte(result) == DID_ABORT && SCpnt->abort_reason)
- SCpnt->result = result = (result & 0xff00ffff) |
- (SCpnt->abort_reason << 16);
-
-
-#define FINISHED 0
-#define MAYREDO 1
-#define REDO 3
-#define PENDING 4
-
-#ifdef DEBUG
- printk("In scsi_done(host = %d, result = %06x)\n", host->host_no, result);
-#endif
-
- if(SCpnt->flags & WAS_SENSE)
- {
- SCpnt->use_sg = SCpnt->old_use_sg;
- SCpnt->cmd_len = SCpnt->old_cmd_len;
- }
-
- switch (host_byte(result))
- {
- case DID_OK:
- if (status_byte(result) && (SCpnt->flags & WAS_SENSE))
- /* Failed to obtain sense information */
- {
- SCpnt->flags &= ~WAS_SENSE;
- SCpnt->internal_timeout &= ~SENSE_TIMEOUT;
-
- if (!(SCpnt->flags & WAS_RESET))
- {
- printk("scsi%d : channel %d target %d lun %d request sense"
- " failed, performing reset.\n",
- SCpnt->host->host_no, SCpnt->channel, SCpnt->target,
- SCpnt->lun);
- scsi_reset(SCpnt, FALSE);
- return;
- }
- else
- {
- exit = (DRIVER_HARD | SUGGEST_ABORT);
- status = FINISHED;
- }
- }
- else switch(msg_byte(result))
- {
- case COMMAND_COMPLETE:
- switch (status_byte(result))
- {
- case GOOD:
- if (SCpnt->flags & WAS_SENSE)
- {
-#ifdef DEBUG
- printk ("In scsi_done, GOOD status, COMMAND COMPLETE, parsing sense information.\n");
-#endif
- SCpnt->flags &= ~WAS_SENSE;
- SCpnt->internal_timeout &= ~SENSE_TIMEOUT;
-
- switch (checked = check_sense(SCpnt))
- {
- case SUGGEST_SENSE:
- case 0:
-#ifdef DEBUG
- printk("NO SENSE. status = REDO\n");
-#endif
- update_timeout(SCpnt, oldto);
- status = REDO;
- break;
- case SUGGEST_IS_OK:
- break;
- case SUGGEST_REMAP:
- case SUGGEST_RETRY:
-#ifdef DEBUG
- printk("SENSE SUGGEST REMAP or SUGGEST RETRY - status = MAYREDO\n");
-#endif
- status = MAYREDO;
- exit = DRIVER_SENSE | SUGGEST_RETRY;
- break;
- case SUGGEST_ABORT:
-#ifdef DEBUG
- printk("SENSE SUGGEST ABORT - status = FINISHED");
-#endif
- status = FINISHED;
- exit = DRIVER_SENSE | SUGGEST_ABORT;
- break;
- default:
- printk ("Internal error %s %d \n", __FILE__,
- __LINE__);
- }
- } /* end WAS_SENSE */
- else
- {
-#ifdef DEBUG
- printk("COMMAND COMPLETE message returned, status = FINISHED. \n");
-#endif
- exit = DRIVER_OK;
- status = FINISHED;
- }
- break;
-
- case CHECK_CONDITION:
- switch (check_sense(SCpnt))
- {
- case 0:
- update_timeout(SCpnt, oldto);
- status = REDO;
- break;
- case SUGGEST_REMAP:
- case SUGGEST_RETRY:
- status = MAYREDO;
- exit = DRIVER_SENSE | SUGGEST_RETRY;
- break;
- case SUGGEST_ABORT:
- status = FINISHED;
- exit = DRIVER_SENSE | SUGGEST_ABORT;
- break;
- case SUGGEST_SENSE:
- scsi_request_sense (SCpnt);
- status = PENDING;
- break;
- }
- break;
-
- case CONDITION_GOOD:
- case INTERMEDIATE_GOOD:
- case INTERMEDIATE_C_GOOD:
- break;
-
- case BUSY:
- update_timeout(SCpnt, oldto);
- status = REDO;
- break;
-
- case RESERVATION_CONFLICT:
- printk("scsi%d, channel %d : RESERVATION CONFLICT performing"
- " reset.\n", SCpnt->host->host_no, SCpnt->channel);
- scsi_reset(SCpnt, FALSE);
- return;
-#if 0
- exit = DRIVER_SOFT | SUGGEST_ABORT;
- status = MAYREDO;
- break;
-#endif
- default:
- printk ("Internal error %s %d \n"
- "status byte = %d \n", __FILE__,
- __LINE__, status_byte(result));
-
- }
- break;
- default:
- panic("scsi: unsupported message byte %d received\n",
- msg_byte(result));
- }
- break;
- case DID_TIME_OUT:
-#ifdef DEBUG
- printk("Host returned DID_TIME_OUT - ");
-#endif
-
- if (SCpnt->flags & WAS_TIMEDOUT)
- {
-#ifdef DEBUG
- printk("Aborting\n");
-#endif
- /*
- Allow TEST_UNIT_READY and INQUIRY commands to timeout early
- without causing resets. All other commands should be retried.
- */
- if (SCpnt->cmnd[0] != TEST_UNIT_READY &&
- SCpnt->cmnd[0] != INQUIRY)
- status = MAYREDO;
- exit = (DRIVER_TIMEOUT | SUGGEST_ABORT);
- }
- else
- {
-#ifdef DEBUG
- printk ("Retrying.\n");
-#endif
- SCpnt->flags |= WAS_TIMEDOUT;
- SCpnt->internal_timeout &= ~IN_ABORT;
- status = REDO;
- }
- break;
- case DID_BUS_BUSY:
- case DID_PARITY:
- status = REDO;
- break;
- case DID_NO_CONNECT:
-#ifdef DEBUG
- printk("Couldn't connect.\n");
-#endif
- exit = (DRIVER_HARD | SUGGEST_ABORT);
- break;
- case DID_ERROR:
- status = MAYREDO;
- exit = (DRIVER_HARD | SUGGEST_ABORT);
- break;
- case DID_BAD_TARGET:
- case DID_ABORT:
- exit = (DRIVER_INVALID | SUGGEST_ABORT);
- break;
- case DID_RESET:
- if (SCpnt->flags & IS_RESETTING)
- {
- SCpnt->flags &= ~IS_RESETTING;
- status = REDO;
- break;
- }
-
- if(msg_byte(result) == GOOD &&
- status_byte(result) == CHECK_CONDITION) {
- switch (check_sense(SCpnt)) {
- case 0:
- update_timeout(SCpnt, oldto);
- status = REDO;
- break;
- case SUGGEST_REMAP:
- case SUGGEST_RETRY:
- status = MAYREDO;
- exit = DRIVER_SENSE | SUGGEST_RETRY;
- break;
- case SUGGEST_ABORT:
- status = FINISHED;
- exit = DRIVER_SENSE | SUGGEST_ABORT;
- break;
- case SUGGEST_SENSE:
- scsi_request_sense (SCpnt);
- status = PENDING;
- break;
- }
- } else {
- status=REDO;
- exit = SUGGEST_RETRY;
- }
- break;
- default :
- exit = (DRIVER_ERROR | SUGGEST_DIE);
- }
-
- switch (status)
- {
- case FINISHED:
- case PENDING:
- break;
- case MAYREDO:
-#ifdef DEBUG
- printk("In MAYREDO, allowing %d retries, have %d\n",
- SCpnt->allowed, SCpnt->retries);
-#endif
- if ((++SCpnt->retries) < SCpnt->allowed)
- {
- if ((SCpnt->retries >= (SCpnt->allowed >> 1))
- && !(jiffies < SCpnt->host->last_reset + MIN_RESET_PERIOD)
- && !(SCpnt->flags & WAS_RESET))
- {
- printk("scsi%d channel %d : resetting for second half of retries.\n",
- SCpnt->host->host_no, SCpnt->channel);
- scsi_reset(SCpnt, FALSE);
- break;
- }
-
- }
- else
- {
- status = FINISHED;
- break;
- }
- /* fall through to REDO */
-
- case REDO:
-
- if (SCpnt->flags & WAS_SENSE)
- scsi_request_sense(SCpnt);
- else
- {
- memcpy ((void *) SCpnt->cmnd,
- (void*) SCpnt->data_cmnd,
- sizeof(SCpnt->data_cmnd));
- SCpnt->request_buffer = SCpnt->buffer;
- SCpnt->request_bufflen = SCpnt->bufflen;
- SCpnt->use_sg = SCpnt->old_use_sg;
- SCpnt->cmd_len = SCpnt->old_cmd_len;
- internal_cmnd (SCpnt);
- }
- break;
- default:
- INTERNAL_ERROR;
- }
-
- if (status == FINISHED) {
-#ifdef DEBUG
- printk("Calling done function - at address %p\n", SCpnt->done);
-#endif
- host->host_busy--; /* Indicate that we are free */
-
- if (host->block && host->host_busy == 0) {
- host_active = NULL;
-
- /* For block devices "wake_up" is done in end_scsi_request */
- if (MAJOR(SCpnt->request.rq_dev) != SCSI_DISK_MAJOR &&
- MAJOR(SCpnt->request.rq_dev) != SCSI_CDROM_MAJOR) {
- struct Scsi_Host * next;
-
- for (next = host->block; next != host; next = next->block)
- wake_up(&next->host_wait);
- }
-
- }
-
- wake_up(&host->host_wait);
- SCpnt->result = result | ((exit & 0xff) << 24);
- SCpnt->use_sg = SCpnt->old_use_sg;
- SCpnt->cmd_len = SCpnt->old_cmd_len;
- SCpnt->done (SCpnt);
- }
-
-#undef FINISHED
-#undef REDO
-#undef MAYREDO
-#undef PENDING
-}
-
-/*
- * The scsi_abort function interfaces with the abort() function of the host
- * we are aborting, and causes the current command to not complete. The
- * caller should deal with any error messages or status returned on the
- * next call.
- *
- * This will not be called reentrantly for a given host.
- */
-
-/*
- * Since we're nice guys and specified that abort() and reset()
- * can be non-reentrant. The internal_timeout flags are used for
- * this.
- */
-
-
-int scsi_abort (Scsi_Cmnd * SCpnt, int why, int pid)
-{
- int oldto;
- unsigned long flags;
- struct Scsi_Host * host = SCpnt->host;
-
- while(1)
- {
- save_flags(flags);
- cli();
-
- /*
- * Protect against races here. If the command is done, or we are
- * on a different command forget it.
- */
- if (SCpnt->request.rq_status == RQ_INACTIVE || pid != SCpnt->pid) {
- restore_flags(flags);
- return 0;
- }
-
- if (SCpnt->internal_timeout & IN_ABORT)
- {
- restore_flags(flags);
- while (SCpnt->internal_timeout & IN_ABORT)
- barrier();
- }
- else
- {
- SCpnt->internal_timeout |= IN_ABORT;
- oldto = update_timeout(SCpnt, ABORT_TIMEOUT);
-
- if ((SCpnt->flags & IS_RESETTING) && SCpnt->device->soft_reset) {
- /* OK, this command must have died when we did the
- * reset. The device itself must have lied.
- */
- printk("Stale command on %d %d:%d appears to have died when"
- " the bus was reset\n",
- SCpnt->channel, SCpnt->target, SCpnt->lun);
- }
-
- restore_flags(flags);
- if (!host->host_busy) {
- SCpnt->internal_timeout &= ~IN_ABORT;
- update_timeout(SCpnt, oldto);
- return 0;
- }
- printk("scsi : aborting command due to timeout : pid %lu, scsi%d,"
- " channel %d, id %d, lun %d ",
- SCpnt->pid, SCpnt->host->host_no, (int) SCpnt->channel,
- (int) SCpnt->target, (int) SCpnt->lun);
- print_command (SCpnt->cmnd);
- if (SCpnt->request.rq_status == RQ_INACTIVE || pid != SCpnt->pid)
- return 0;
- SCpnt->abort_reason = why;
- switch(host->hostt->abort(SCpnt)) {
- /* We do not know how to abort. Try waiting another
- * time increment and see if this helps. Set the
- * WAS_TIMEDOUT flag set so we do not try this twice
- */
- case SCSI_ABORT_BUSY: /* Tough call - returning 1 from
- * this is too severe
- */
- case SCSI_ABORT_SNOOZE:
- if(why == DID_TIME_OUT) {
- save_flags(flags);
- cli();
- SCpnt->internal_timeout &= ~IN_ABORT;
- if(SCpnt->flags & WAS_TIMEDOUT) {
- restore_flags(flags);
- return 1; /* Indicate we cannot handle this.
- * We drop down into the reset handler
- * and try again
- */
- } else {
- SCpnt->flags |= WAS_TIMEDOUT;
- oldto = SCpnt->timeout_per_command;
- update_timeout(SCpnt, oldto);
- }
- restore_flags(flags);
- }
- return 0;
- case SCSI_ABORT_PENDING:
- if(why != DID_TIME_OUT) {
- save_flags(flags);
- cli();
- update_timeout(SCpnt, oldto);
- restore_flags(flags);
- }
- return 0;
- case SCSI_ABORT_SUCCESS:
- /* We should have already aborted this one. No
- * need to adjust timeout
- */
- SCpnt->internal_timeout &= ~IN_ABORT;
- return 0;
- case SCSI_ABORT_NOT_RUNNING:
- SCpnt->internal_timeout &= ~IN_ABORT;
- update_timeout(SCpnt, 0);
- return 0;
- case SCSI_ABORT_ERROR:
- default:
- SCpnt->internal_timeout &= ~IN_ABORT;
- return 1;
- }
- }
- }
-}
-
-
-/* Mark a single SCSI Device as having been reset. */
-
-static inline void scsi_mark_device_reset(Scsi_Device *Device)
-{
- Device->was_reset = 1;
- Device->expecting_cc_ua = 1;
-}
-
-
-/* Mark all SCSI Devices on a specific Host as having been reset. */
-
-void scsi_mark_host_bus_reset(struct Scsi_Host *Host)
-{
- Scsi_Cmnd *SCpnt;
- for(SCpnt = Host->host_queue; SCpnt; SCpnt = SCpnt->next)
- scsi_mark_device_reset(SCpnt->device);
-}
-
-
-int scsi_reset (Scsi_Cmnd * SCpnt, int bus_reset_flag)
-{
- int temp, oldto;
- unsigned long flags;
- Scsi_Cmnd * SCpnt1;
- struct Scsi_Host * host = SCpnt->host;
-
- printk("SCSI bus is being reset for host %d.\n",
- host->host_no);
-
- /*
- * First of all, we need to make a recommendation to the low-level
- * driver as to whether a BUS_DEVICE_RESET should be performed,
- * or whether we should do a full BUS_RESET. There is no simple
- * algorithm here - we basically use a series of heuristics
- * to determine what we should do.
- */
- SCpnt->host->suggest_bus_reset = FALSE;
-
- /*
- * First see if all of the active devices on the bus have
- * been jammed up so that we are attempting resets. If so,
- * then suggest a bus reset. Forcing a bus reset could
- * result in some race conditions, but no more than
- * you would usually get with timeouts. We will cross
- * that bridge when we come to it.
- */
- SCpnt1 = host->host_queue;
- while(SCpnt1) {
- if( SCpnt1->request.rq_status != RQ_INACTIVE
- && (SCpnt1->flags & (WAS_RESET | IS_RESETTING)) == 0 )
- break;
- SCpnt1 = SCpnt1->next;
- }
- if( SCpnt1 == NULL ) {
- SCpnt->host->suggest_bus_reset = TRUE;
- }
-
-
- /*
- * If the code that called us is suggesting a hard reset, then
- * definitely request it. This usually occurs because a
- * BUS_DEVICE_RESET times out.
- */
- if( bus_reset_flag ) {
- SCpnt->host->suggest_bus_reset = TRUE;
- }
-
- while (1) {
- save_flags(flags);
- cli();
- if (SCpnt->internal_timeout & IN_RESET)
- {
- restore_flags(flags);
- while (SCpnt->internal_timeout & IN_RESET)
- barrier();
- }
- else
- {
- SCpnt->internal_timeout |= IN_RESET;
- oldto = update_timeout(SCpnt, RESET_TIMEOUT);
-
- if (host->host_busy)
- {
- restore_flags(flags);
- SCpnt1 = host->host_queue;
- while(SCpnt1) {
- if (SCpnt1->request.rq_status != RQ_INACTIVE) {
-#if 0
- if (!(SCpnt1->flags & IS_RESETTING) &&
- !(SCpnt1->internal_timeout & IN_ABORT))
- scsi_abort(SCpnt1, DID_RESET, SCpnt->pid);
-#endif
- SCpnt1->flags |= (WAS_RESET | IS_RESETTING);
- }
- SCpnt1 = SCpnt1->next;
- }
-
- host->last_reset = jiffies;
- temp = host->hostt->reset(SCpnt);
- host->last_reset = jiffies;
- }
- else
- {
- if (!host->block) host->host_busy++;
- restore_flags(flags);
- host->last_reset = jiffies;
- SCpnt->flags |= (WAS_RESET | IS_RESETTING);
- temp = host->hostt->reset(SCpnt);
- host->last_reset = jiffies;
- if (!host->block) host->host_busy--;
- }
-
-#ifdef DEBUG
- printk("scsi reset function returned %d\n", temp);
-#endif
-
- /*
- * Now figure out what we need to do, based upon
- * what the low level driver said that it did.
- * If the result is SCSI_RESET_SUCCESS, SCSI_RESET_PENDING,
- * or SCSI_RESET_WAKEUP, then the low level driver did a
- * bus device reset or bus reset, so we should go through
- * and mark one or all of the devices on that bus
- * as having been reset.
- */
- switch(temp & SCSI_RESET_ACTION) {
- case SCSI_RESET_SUCCESS:
- if (temp & SCSI_RESET_BUS_RESET)
- scsi_mark_host_bus_reset(host);
- else scsi_mark_device_reset(SCpnt->device);
- save_flags(flags);
- cli();
- SCpnt->internal_timeout &= ~IN_RESET;
- update_timeout(SCpnt, oldto);
- restore_flags(flags);
- return 0;
- case SCSI_RESET_PENDING:
- if (temp & SCSI_RESET_BUS_RESET)
- scsi_mark_host_bus_reset(host);
- else scsi_mark_device_reset(SCpnt->device);
- return 0;
- case SCSI_RESET_PUNT:
- SCpnt->internal_timeout &= ~IN_RESET;
- scsi_request_sense (SCpnt);
- return 0;
- case SCSI_RESET_WAKEUP:
- if (temp & SCSI_RESET_BUS_RESET)
- scsi_mark_host_bus_reset(host);
- else scsi_mark_device_reset(SCpnt->device);
- SCpnt->internal_timeout &= ~IN_RESET;
- scsi_request_sense (SCpnt);
- /*
- * Since a bus reset was performed, we
- * need to wake up each and every command
- * that was active on the bus.
- */
- if( temp & SCSI_RESET_BUS_RESET )
- {
- SCpnt1 = host->host_queue;
- while(SCpnt1) {
- if( SCpnt->request.rq_status != RQ_INACTIVE
- && SCpnt1 != SCpnt)
- scsi_request_sense (SCpnt);
- SCpnt1 = SCpnt1->next;
- }
- }
- return 0;
- case SCSI_RESET_SNOOZE:
- /* In this case, we set the timeout field to 0
- * so that this command does not time out any more,
- * and we return 1 so that we get a message on the
- * screen.
- */
- save_flags(flags);
- cli();
- SCpnt->internal_timeout &= ~IN_RESET;
- update_timeout(SCpnt, 0);
- restore_flags(flags);
- /* If you snooze, you lose... */
- case SCSI_RESET_ERROR:
- default:
- return 1;
- }
-
- return temp;
- }
- }
-}
-
-
-static void scsi_main_timeout(void)
-{
- /*
- * We must not enter update_timeout with a timeout condition still pending.
- */
-
- int timed_out, pid;
- unsigned long flags;
- struct Scsi_Host * host;
- Scsi_Cmnd * SCpnt = NULL;
-
- do {
- save_flags(flags);
- cli();
-
- update_timeout(NULL, 0);
- /*
- * Find all timers such that they have 0 or negative (shouldn't happen)
- * time remaining on them.
- */
-
- timed_out = 0;
- for(host = scsi_hostlist; host; host = host->next) {
- for(SCpnt = host->host_queue; SCpnt; SCpnt = SCpnt->next)
- if (SCpnt->timeout == -1)
- {
- SCpnt->timeout = 0;
- pid = SCpnt->pid;
- restore_flags(flags);
- scsi_times_out(SCpnt, pid);
- ++timed_out;
- save_flags(flags);
- cli();
- }
- }
- } while (timed_out);
- restore_flags(flags);
-}
-
-/*
- * The strategy is to cause the timer code to call scsi_times_out()
- * when the soonest timeout is pending.
- * The arguments are used when we are queueing a new command, because
- * we do not want to subtract the time used from this time, but when we
- * set the timer, we want to take this value into account.
- */
-
-static int update_timeout(Scsi_Cmnd * SCset, int timeout)
-{
- unsigned int least, used;
- unsigned int oldto;
- unsigned long flags;
- struct Scsi_Host * host;
- Scsi_Cmnd * SCpnt = NULL;
-
- save_flags(flags);
- cli();
-
- /*
- * Figure out how much time has passed since the last time the timeouts
- * were updated
- */
- used = (time_start) ? (jiffies - time_start) : 0;
-
- /*
- * Find out what is due to timeout soonest, and adjust all timeouts for
- * the amount of time that has passed since the last time we called
- * update_timeout.
- */
-
- oldto = 0;
-
- if(SCset){
- oldto = SCset->timeout - used;
- SCset->timeout = timeout + used;
- }
-
- least = 0xffffffff;
-
- for(host = scsi_hostlist; host; host = host->next)
- for(SCpnt = host->host_queue; SCpnt; SCpnt = SCpnt->next)
- if (SCpnt->timeout > 0) {
- SCpnt->timeout -= used;
- if(SCpnt->timeout <= 0) SCpnt->timeout = -1;
- if(SCpnt->timeout > 0 && SCpnt->timeout < least)
- least = SCpnt->timeout;
- }
-
- /*
- * If something is due to timeout again, then we will set the next timeout
- * interrupt to occur. Otherwise, timeouts are disabled.
- */
-
- if (least != 0xffffffff)
- {
- time_start = jiffies;
- timer_table[SCSI_TIMER].expires = (time_elapsed = least) + jiffies;
- timer_active |= 1 << SCSI_TIMER;
- }
- else
- {
- timer_table[SCSI_TIMER].expires = time_start = time_elapsed = 0;
- timer_active &= ~(1 << SCSI_TIMER);
- }
- restore_flags(flags);
- return oldto;
-}
-
-#ifdef CONFIG_MODULES
-static int scsi_register_host(Scsi_Host_Template *);
-static void scsi_unregister_host(Scsi_Host_Template *);
-#endif
-
-void *scsi_malloc(unsigned int len)
-{
- unsigned int nbits, mask;
- unsigned long flags;
- int i, j;
- if(len % SECTOR_SIZE != 0 || len > PAGE_SIZE)
- return NULL;
-
- save_flags(flags);
- cli();
- nbits = len >> 9;
- mask = (1 << nbits) - 1;
-
- for(i=0;i < dma_sectors / SECTORS_PER_PAGE; i++)
- for(j=0; j<=SECTORS_PER_PAGE - nbits; j++){
- if ((dma_malloc_freelist[i] & (mask << j)) == 0){
- dma_malloc_freelist[i] |= (mask << j);
- restore_flags(flags);
- dma_free_sectors -= nbits;
-#ifdef DEBUG
- printk("SMalloc: %d %p\n",len, dma_malloc_pages[i] + (j << 9));
-#endif
- return (void *) ((unsigned long) dma_malloc_pages[i] + (j << 9));
- }
- }
- restore_flags(flags);
- return NULL; /* Nope. No more */
-}
-
-int scsi_free(void *obj, unsigned int len)
-{
- unsigned int page, sector, nbits, mask;
- unsigned long flags;
-
-#ifdef DEBUG
- printk("scsi_free %p %d\n",obj, len);
-#endif
-
- for (page = 0; page < dma_sectors / SECTORS_PER_PAGE; page++) {
- unsigned long page_addr = (unsigned long) dma_malloc_pages[page];
- if ((unsigned long) obj >= page_addr &&
- (unsigned long) obj < page_addr + PAGE_SIZE)
- {
- sector = (((unsigned long) obj) - page_addr) >> 9;
-
- nbits = len >> 9;
- mask = (1 << nbits) - 1;
-
- if ((mask << sector) >= (1 << SECTORS_PER_PAGE))
- panic ("scsi_free:Bad memory alignment");
-
- save_flags(flags);
- cli();
- if((dma_malloc_freelist[page] & (mask << sector)) != (mask<<sector))
- panic("scsi_free:Trying to free unused memory");
-
- dma_free_sectors += nbits;
- dma_malloc_freelist[page] &= ~(mask << sector);
- restore_flags(flags);
- return 0;
- }
- }
- panic("scsi_free:Bad offset");
-}
-
-
-int scsi_loadable_module_flag; /* Set after we scan builtin drivers */
-
-void * scsi_init_malloc(unsigned int size, int priority)
-{
- void * retval;
-
- /*
- * For buffers used by the DMA pool, we assume page aligned
- * structures.
- */
- if ((size % PAGE_SIZE) == 0) {
- int order, a_size;
- for (order = 0, a_size = PAGE_SIZE;
- a_size < size; order++, a_size <<= 1)
- ;
- retval = (void *) __get_dma_pages(priority & GFP_LEVEL_MASK,
- order);
- } else
- retval = kmalloc(size, priority);
-
- if (retval)
- memset(retval, 0, size);
- return retval;
-}
-
-
-void scsi_init_free(char * ptr, unsigned int size)
-{
- /*
- * We need this special code here because the DMA pool assumes
- * page aligned data. Besides, it is wasteful to allocate
- * page sized chunks with kmalloc.
- */
- if ((size % PAGE_SIZE) == 0) {
- int order, a_size;
-
- for (order = 0, a_size = PAGE_SIZE;
- a_size < size; order++, a_size <<= 1)
- ;
- free_pages((unsigned long)ptr, order);
- } else
- kfree(ptr);
-}
-
-void scsi_build_commandblocks(Scsi_Device * SDpnt)
-{
- int j;
- Scsi_Cmnd * SCpnt;
- struct Scsi_Host * host = NULL;
-
- for(j=0;j<SDpnt->host->cmd_per_lun;j++){
- SCpnt = (Scsi_Cmnd *) scsi_init_malloc(sizeof(Scsi_Cmnd), GFP_ATOMIC);
- SCpnt->host = SDpnt->host;
- SCpnt->device = SDpnt;
- SCpnt->target = SDpnt->id;
- SCpnt->lun = SDpnt->lun;
- SCpnt->channel = SDpnt->channel;
- SCpnt->request.rq_status = RQ_INACTIVE;
- SCpnt->use_sg = 0;
- SCpnt->old_use_sg = 0;
- SCpnt->old_cmd_len = 0;
- SCpnt->timeout = 0;
- SCpnt->underflow = 0;
- SCpnt->transfersize = 0;
- SCpnt->host_scribble = NULL;
- host = SDpnt->host;
- if(host->host_queue)
- host->host_queue->prev = SCpnt;
- SCpnt->next = host->host_queue;
- SCpnt->prev = NULL;
- host->host_queue = SCpnt;
- }
- SDpnt->has_cmdblocks = 1;
-}
-
-/*
- * scsi_dev_init() is our initialization routine, which in turn calls host
- * initialization, bus scanning, and sd/st initialization routines.
- */
-
-int scsi_dev_init(void)
-{
- Scsi_Device * SDpnt;
- struct Scsi_Host * shpnt;
- struct Scsi_Device_Template * sdtpnt;
-#ifdef FOO_ON_YOU
- return;
-#endif
-
- /* Yes we're here... */
- dispatch_scsi_info_ptr = dispatch_scsi_info;
-
- /* Init a few things so we can "malloc" memory. */
- scsi_loadable_module_flag = 0;
-
- timer_table[SCSI_TIMER].fn = scsi_main_timeout;
- timer_table[SCSI_TIMER].expires = 0;
-
-#ifdef CONFIG_MODULES
- register_symtab(&scsi_symbol_table);
-#endif
-
- /* Register the /proc/scsi/scsi entry */
-#if CONFIG_PROC_FS
- proc_scsi_register(0, &proc_scsi_scsi);
-#endif
-
- /* initialize all hosts */
- scsi_init();
-
- scsi_devices = (Scsi_Device *) NULL;
-
- for (shpnt = scsi_hostlist; shpnt; shpnt = shpnt->next)
- scan_scsis(shpnt,0,0,0,0); /* scan for scsi devices */
-
-#if 0
- printk("scsi : detected ");
- for (sdtpnt = scsi_devicelist; sdtpnt; sdtpnt = sdtpnt->next)
- if (sdtpnt->dev_noticed && sdtpnt->name)
- printk("%d SCSI %s%s ", sdtpnt->dev_noticed, sdtpnt->name,
- (sdtpnt->dev_noticed != 1) ? "s" : "");
- printk("total.\n");
-#endif
-
- for(sdtpnt = scsi_devicelist; sdtpnt; sdtpnt = sdtpnt->next)
- if(sdtpnt->init && sdtpnt->dev_noticed) (*sdtpnt->init)();
-
- for (SDpnt=scsi_devices; SDpnt; SDpnt = SDpnt->next) {
- SDpnt->scsi_request_fn = NULL;
- for(sdtpnt = scsi_devicelist; sdtpnt; sdtpnt = sdtpnt->next)
- if(sdtpnt->attach) (*sdtpnt->attach)(SDpnt);
- if(SDpnt->attached) scsi_build_commandblocks(SDpnt);
- }
-
-
- /*
- * This should build the DMA pool.
- */
- resize_dma_pool();
-
- /*
- * OK, now we finish the initialization by doing spin-up, read
- * capacity, etc, etc
- */
- for(sdtpnt = scsi_devicelist; sdtpnt; sdtpnt = sdtpnt->next)
- if(sdtpnt->finish && sdtpnt->nr_dev)
- (*sdtpnt->finish)();
-
- scsi_loadable_module_flag = 1;
-
- return 0;
-}
-
-static void print_inquiry(unsigned char *data)
-{
- int i;
-
- printk(" Vendor: ");
- for (i = 8; i < 16; i++)
- {
- if (data[i] >= 0x20 && i < data[4] + 5)
- printk("%c", data[i]);
- else
- printk(" ");
- }
-
- printk(" Model: ");
- for (i = 16; i < 32; i++)
- {
- if (data[i] >= 0x20 && i < data[4] + 5)
- printk("%c", data[i]);
- else
- printk(" ");
- }
-
- printk(" Rev: ");
- for (i = 32; i < 36; i++)
- {
- if (data[i] >= 0x20 && i < data[4] + 5)
- printk("%c", data[i]);
- else
- printk(" ");
- }
-
- printk("\n");
-
- i = data[0] & 0x1f;
-
- printk(" Type: %s ",
- i < MAX_SCSI_DEVICE_CODE ? scsi_device_types[i] : "Unknown " );
- printk(" ANSI SCSI revision: %02x", data[2] & 0x07);
- if ((data[2] & 0x07) == 1 && (data[3] & 0x0f) == 1)
- printk(" CCS\n");
- else
- printk("\n");
-}
-
-
-#ifdef CONFIG_PROC_FS
-int scsi_proc_info(char *buffer, char **start, off_t offset, int length,
- int hostno, int inout)
-{
- Scsi_Device *scd;
- struct Scsi_Host *HBA_ptr;
- int parameter[4];
- char *p;
- int i,size, len = 0;
- off_t begin = 0;
- off_t pos = 0;
-
- scd = scsi_devices;
- HBA_ptr = scsi_hostlist;
-
- if(inout == 0) {
- size = sprintf(buffer+len,"Attached devices: %s\n", (scd)?"":"none");
- len += size;
- pos = begin + len;
- while (HBA_ptr) {
-#if 0
- size += sprintf(buffer+len,"scsi%2d: %s\n", (int) HBA_ptr->host_no,
- HBA_ptr->hostt->procname);
- len += size;
- pos = begin + len;
-#endif
- scd = scsi_devices;
- while (scd) {
- if (scd->host == HBA_ptr) {
- proc_print_scsidevice(scd, buffer, &size, len);
- len += size;
- pos = begin + len;
-
- if (pos < offset) {
- len = 0;
- begin = pos;
- }
- if (pos > offset + length)
- goto stop_output;
- }
- scd = scd->next;
- }
- HBA_ptr = HBA_ptr->next;
- }
-
- stop_output:
- *start=buffer+(offset-begin); /* Start of wanted data */
- len-=(offset-begin); /* Start slop */
- if(len>length)
- len = length; /* Ending slop */
- return (len);
- }
-
- /*
- * Usage: echo "scsi singledevice 0 1 2 3" >/proc/scsi/scsi
- * with "0 1 2 3" replaced by your "Host Channel Id Lun".
- * Consider this feature BETA.
- * CAUTION: This is not for hotplugging your peripherals. As
- * SCSI was not designed for this you could damage your
- * hardware !
- * However perhaps it is legal to switch on an
- * already connected device. It is perhaps not
- * guaranteed this device doesn't corrupt an ongoing data transfer.
- */
- if(!buffer || length < 25 || strncmp("scsi", buffer, 4))
- return(-EINVAL);
-
- if(!strncmp("singledevice", buffer + 5, 12)) {
- p = buffer + 17;
-
- for(i=0; i<4; i++) {
- p++;
- parameter[i] = simple_strtoul(p, &p, 0);
- }
- printk("scsi singledevice %d %d %d %d\n", parameter[0], parameter[1],
- parameter[2], parameter[3]);
-
- while(scd && (scd->host->host_no != parameter[0]
- || scd->channel != parameter[1]
- || scd->id != parameter[2]
- || scd->lun != parameter[3])) {
- scd = scd->next;
- }
- if(scd)
- return(-ENOSYS); /* We do not yet support unplugging */
- while(HBA_ptr && HBA_ptr->host_no != parameter[0])
- HBA_ptr = HBA_ptr->next;
-
- if(!HBA_ptr)
- return(-ENXIO);
-
- scan_scsis (HBA_ptr, 1, parameter[1], parameter[2], parameter[3]);
- return(length);
- }
- return(-EINVAL);
-}
-#endif
-
-/*
- * Go through the device list and recompute the most appropriate size
- * for the dma pool. Then grab more memory (as required).
- */
-static void resize_dma_pool(void)
-{
- int i;
- unsigned long size;
- struct Scsi_Host * shpnt;
- struct Scsi_Host * host = NULL;
- Scsi_Device * SDpnt;
- unsigned long flags;
- FreeSectorBitmap * new_dma_malloc_freelist = NULL;
- unsigned int new_dma_sectors = 0;
- unsigned int new_need_isa_buffer = 0;
- unsigned char ** new_dma_malloc_pages = NULL;
-
- if( !scsi_devices )
- {
- /*
- * Free up the DMA pool.
- */
- if( dma_free_sectors != dma_sectors )
- panic("SCSI DMA pool memory leak %d %d\n",dma_free_sectors,dma_sectors);
-
- for(i=0; i < dma_sectors / SECTORS_PER_PAGE; i++)
- scsi_init_free(dma_malloc_pages[i], PAGE_SIZE);
- if (dma_malloc_pages)
- scsi_init_free((char *) dma_malloc_pages,
- (dma_sectors / SECTORS_PER_PAGE)*sizeof(*dma_malloc_pages));
- dma_malloc_pages = NULL;
- if (dma_malloc_freelist)
- scsi_init_free((char *) dma_malloc_freelist,
- (dma_sectors / SECTORS_PER_PAGE)*sizeof(*dma_malloc_freelist));
- dma_malloc_freelist = NULL;
- dma_sectors = 0;
- dma_free_sectors = 0;
- return;
- }
- /* Next, check to see if we need to extend the DMA buffer pool */
-
- new_dma_sectors = 2*SECTORS_PER_PAGE; /* Base value we use */
-
- if (high_memory-1 > ISA_DMA_THRESHOLD)
- scsi_need_isa_bounce_buffers = 1;
- else
- scsi_need_isa_bounce_buffers = 0;
-
- if (scsi_devicelist)
- for(shpnt=scsi_hostlist; shpnt; shpnt = shpnt->next)
- new_dma_sectors += SECTORS_PER_PAGE; /* Increment for each host */
-
- for (SDpnt=scsi_devices; SDpnt; SDpnt = SDpnt->next) {
- host = SDpnt->host;
-
- if(SDpnt->type != TYPE_TAPE)
- new_dma_sectors += ((host->sg_tablesize *
- sizeof(struct scatterlist) + 511) >> 9) *
- host->cmd_per_lun;
-
- if(host->unchecked_isa_dma &&
- scsi_need_isa_bounce_buffers &&
- SDpnt->type != TYPE_TAPE) {
- new_dma_sectors += (PAGE_SIZE >> 9) * host->sg_tablesize *
- host->cmd_per_lun;
- new_need_isa_buffer++;
- }
- }
-
- /* limit DMA memory to 32MB: */
- new_dma_sectors = (new_dma_sectors + 15) & 0xfff0;
-
- /*
- * We never shrink the buffers - this leads to
- * race conditions that I would rather not even think
- * about right now.
- */
- if( new_dma_sectors < dma_sectors )
- new_dma_sectors = dma_sectors;
-
- if (new_dma_sectors)
- {
- size = (new_dma_sectors / SECTORS_PER_PAGE)*sizeof(FreeSectorBitmap);
- new_dma_malloc_freelist = (FreeSectorBitmap *) scsi_init_malloc(size, GFP_ATOMIC);
- memset(new_dma_malloc_freelist, 0, size);
-
- size = (new_dma_sectors / SECTORS_PER_PAGE)*sizeof(*new_dma_malloc_pages);
- new_dma_malloc_pages = (unsigned char **) scsi_init_malloc(size, GFP_ATOMIC);
- memset(new_dma_malloc_pages, 0, size);
- }
-
- /*
- * If we need more buffers, expand the list.
- */
- if( new_dma_sectors > dma_sectors ) {
- for(i=dma_sectors / SECTORS_PER_PAGE; i< new_dma_sectors / SECTORS_PER_PAGE; i++)
- new_dma_malloc_pages[i] = (unsigned char *)
- scsi_init_malloc(PAGE_SIZE, GFP_ATOMIC | GFP_DMA);
- }
-
- /* When we dick with the actual DMA list, we need to
- * protect things
- */
- save_flags(flags);
- cli();
- if (dma_malloc_freelist)
- {
- size = (dma_sectors / SECTORS_PER_PAGE)*sizeof(FreeSectorBitmap);
- memcpy(new_dma_malloc_freelist, dma_malloc_freelist, size);
- scsi_init_free((char *) dma_malloc_freelist, size);
- }
- dma_malloc_freelist = new_dma_malloc_freelist;
-
- if (dma_malloc_pages)
- {
- size = (dma_sectors / SECTORS_PER_PAGE)*sizeof(*dma_malloc_pages);
- memcpy(new_dma_malloc_pages, dma_malloc_pages, size);
- scsi_init_free((char *) dma_malloc_pages, size);
- }
-
- dma_free_sectors += new_dma_sectors - dma_sectors;
- dma_malloc_pages = new_dma_malloc_pages;
- dma_sectors = new_dma_sectors;
- need_isa_buffer = new_need_isa_buffer;
- restore_flags(flags);
-}
-
-#ifdef CONFIG_MODULES /* a big #ifdef block... */
-
-/*
- * This entry point should be called by a loadable module if it is trying
- * add a low level scsi driver to the system.
- */
-static int scsi_register_host(Scsi_Host_Template * tpnt)
-{
- int pcount;
- struct Scsi_Host * shpnt;
- Scsi_Device * SDpnt;
- struct Scsi_Device_Template * sdtpnt;
- const char * name;
-
- if (tpnt->next || !tpnt->detect) return 1;/* Must be already loaded, or
- * no detect routine available
- */
- pcount = next_scsi_host;
- if ((tpnt->present = tpnt->detect(tpnt)))
- {
- if(pcount == next_scsi_host) {
- if(tpnt->present > 1) {
- printk("Failure to register low-level scsi driver");
- scsi_unregister_host(tpnt);
- return 1;
- }
- /* The low-level driver failed to register a driver. We
- * can do this now.
- */
- scsi_register(tpnt,0);
- }
- tpnt->next = scsi_hosts; /* Add to the linked list */
- scsi_hosts = tpnt;
-
- /* Add the new driver to /proc/scsi */
-#if CONFIG_PROC_FS
- build_proc_dir_entries(tpnt);
-#endif
-
- for(shpnt=scsi_hostlist; shpnt; shpnt = shpnt->next)
- if(shpnt->hostt == tpnt)
- {
- if(tpnt->info)
- name = tpnt->info(shpnt);
- else
- name = tpnt->name;
- printk ("scsi%d : %s\n", /* And print a little message */
- shpnt->host_no, name);
- }
-
- printk ("scsi : %d host%s.\n", next_scsi_host,
- (next_scsi_host == 1) ? "" : "s");
-
- scsi_make_blocked_list();
-
- /* The next step is to call scan_scsis here. This generates the
- * Scsi_Devices entries
- */
-
- for(shpnt=scsi_hostlist; shpnt; shpnt = shpnt->next)
- if(shpnt->hostt == tpnt) scan_scsis(shpnt,0,0,0,0);
-
- for(sdtpnt = scsi_devicelist; sdtpnt; sdtpnt = sdtpnt->next)
- if(sdtpnt->init && sdtpnt->dev_noticed) (*sdtpnt->init)();
-
- /* Next we create the Scsi_Cmnd structures for this host */
-
- for(SDpnt = scsi_devices; SDpnt; SDpnt = SDpnt->next)
- if(SDpnt->host->hostt == tpnt)
- {
- for(sdtpnt = scsi_devicelist; sdtpnt; sdtpnt = sdtpnt->next)
- if(sdtpnt->attach) (*sdtpnt->attach)(SDpnt);
- if(SDpnt->attached) scsi_build_commandblocks(SDpnt);
- }
-
- /*
- * Now that we have all of the devices, resize the DMA pool,
- * as required. */
- resize_dma_pool();
-
-
- /* This does any final handling that is required. */
- for(sdtpnt = scsi_devicelist; sdtpnt; sdtpnt = sdtpnt->next)
- if(sdtpnt->finish && sdtpnt->nr_dev)
- (*sdtpnt->finish)();
- }
-
-#if defined(USE_STATIC_SCSI_MEMORY)
- printk ("SCSI memory: total %ldKb, used %ldKb, free %ldKb.\n",
- (scsi_memory_upper_value - scsi_memory_lower_value) / 1024,
- (scsi_init_memory_start - scsi_memory_lower_value) / 1024,
- (scsi_memory_upper_value - scsi_init_memory_start) / 1024);
-#endif
-
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-/*
- * Similarly, this entry point should be called by a loadable module if it
- * is trying to remove a low level scsi driver from the system.
- */
-static void scsi_unregister_host(Scsi_Host_Template * tpnt)
-{
- Scsi_Host_Template * SHT, *SHTp;
- Scsi_Device *sdpnt, * sdppnt, * sdpnt1;
- Scsi_Cmnd * SCpnt;
- unsigned long flags;
- struct Scsi_Device_Template * sdtpnt;
- struct Scsi_Host * shpnt, *sh1;
- int pcount;
-
- /* First verify that this host adapter is completely free with no pending
- * commands */
-
- for(sdpnt = scsi_devices; sdpnt; sdpnt = sdpnt->next)
- if(sdpnt->host->hostt == tpnt && sdpnt->host->hostt->usage_count
- && *sdpnt->host->hostt->usage_count) return;
-
- for(shpnt = scsi_hostlist; shpnt; shpnt = shpnt->next)
- {
- if (shpnt->hostt != tpnt) continue;
- for(SCpnt = shpnt->host_queue; SCpnt; SCpnt = SCpnt->next)
- {
- save_flags(flags);
- cli();
- if(SCpnt->request.rq_status != RQ_INACTIVE) {
- restore_flags(flags);
- for(SCpnt = shpnt->host_queue; SCpnt; SCpnt = SCpnt->next)
- if(SCpnt->request.rq_status == RQ_SCSI_DISCONNECTING)
- SCpnt->request.rq_status = RQ_INACTIVE;
- printk("Device busy???\n");
- return;
- }
- SCpnt->request.rq_status = RQ_SCSI_DISCONNECTING; /* Mark as busy */
- restore_flags(flags);
- }
- }
- /* Next we detach the high level drivers from the Scsi_Device structures */
-
- for(sdpnt = scsi_devices; sdpnt; sdpnt = sdpnt->next)
- if(sdpnt->host->hostt == tpnt)
- {
- for(sdtpnt = scsi_devicelist; sdtpnt; sdtpnt = sdtpnt->next)
- if(sdtpnt->detach) (*sdtpnt->detach)(sdpnt);
- /* If something still attached, punt */
- if (sdpnt->attached) {
- printk("Attached usage count = %d\n", sdpnt->attached);
- return;
- }
- }
-
- /* Next we free up the Scsi_Cmnd structures for this host */
-
- for(sdpnt = scsi_devices; sdpnt; sdpnt = sdpnt->next)
- if(sdpnt->host->hostt == tpnt)
- while (sdpnt->host->host_queue) {
- SCpnt = sdpnt->host->host_queue->next;
- scsi_init_free((char *) sdpnt->host->host_queue, sizeof(Scsi_Cmnd));
- sdpnt->host->host_queue = SCpnt;
- if (SCpnt) SCpnt->prev = NULL;
- sdpnt->has_cmdblocks = 0;
- }
-
- /* Next free up the Scsi_Device structures for this host */
-
- sdppnt = NULL;
- for(sdpnt = scsi_devices; sdpnt; sdpnt = sdpnt1)
- {
- sdpnt1 = sdpnt->next;
- if (sdpnt->host->hostt == tpnt) {
- if (sdppnt)
- sdppnt->next = sdpnt->next;
- else
- scsi_devices = sdpnt->next;
- scsi_init_free((char *) sdpnt, sizeof (Scsi_Device));
- } else
- sdppnt = sdpnt;
- }
-
- /* Next we go through and remove the instances of the individual hosts
- * that were detected */
-
- shpnt = scsi_hostlist;
- while(shpnt) {
- sh1 = shpnt->next;
- if(shpnt->hostt == tpnt) {
- if(shpnt->loaded_as_module) {
- pcount = next_scsi_host;
- /* Remove the /proc/scsi directory entry */
-#if CONFIG_PROC_FS
- proc_scsi_unregister(tpnt->proc_dir,
- shpnt->host_no + PROC_SCSI_FILE);
-#endif
- if(tpnt->release)
- (*tpnt->release)(shpnt);
- else {
- /* This is the default case for the release function.
- * It should do the right thing for most correctly
- * written host adapters.
- */
- if (shpnt->irq) free_irq(shpnt->irq);
- if (shpnt->dma_channel != 0xff) free_dma(shpnt->dma_channel);
- if (shpnt->io_port && shpnt->n_io_port)
- release_region(shpnt->io_port, shpnt->n_io_port);
- }
- if(pcount == next_scsi_host) scsi_unregister(shpnt);
- tpnt->present--;
- }
- }
- shpnt = sh1;
- }
-
- /*
- * If there are absolutely no more hosts left, it is safe
- * to completely nuke the DMA pool. The resize operation will
- * do the right thing and free everything.
- */
- if( !scsi_devices )
- resize_dma_pool();
-
- printk ("scsi : %d host%s.\n", next_scsi_host,
- (next_scsi_host == 1) ? "" : "s");
-
-#if defined(USE_STATIC_SCSI_MEMORY)
- printk ("SCSI memory: total %ldKb, used %ldKb, free %ldKb.\n",
- (scsi_memory_upper_value - scsi_memory_lower_value) / 1024,
- (scsi_init_memory_start - scsi_memory_lower_value) / 1024,
- (scsi_memory_upper_value - scsi_init_memory_start) / 1024);
-#endif
-
- scsi_make_blocked_list();
-
- /* There were some hosts that were loaded at boot time, so we cannot
- do any more than this */
- if (tpnt->present) return;
-
- /* OK, this is the very last step. Remove this host adapter from the
- linked list. */
- for(SHTp=NULL, SHT=scsi_hosts; SHT; SHTp=SHT, SHT=SHT->next)
- if(SHT == tpnt) {
- if(SHTp)
- SHTp->next = SHT->next;
- else
- scsi_hosts = SHT->next;
- SHT->next = NULL;
- break;
- }
-
- /* Rebuild the /proc/scsi directory entries */
-#if CONFIG_PROC_FS
- proc_scsi_unregister(tpnt->proc_dir, tpnt->proc_dir->low_ino);
-#endif
- MOD_DEC_USE_COUNT;
-}
-
-/*
- * This entry point should be called by a loadable module if it is trying
- * add a high level scsi driver to the system.
- */
-static int scsi_register_device_module(struct Scsi_Device_Template * tpnt)
-{
- Scsi_Device * SDpnt;
-
- if (tpnt->next) return 1;
-
- scsi_register_device(tpnt);
- /*
- * First scan the devices that we know about, and see if we notice them.
- */
-
- for(SDpnt = scsi_devices; SDpnt; SDpnt = SDpnt->next)
- if(tpnt->detect) SDpnt->attached += (*tpnt->detect)(SDpnt);
-
- /*
- * If any of the devices would match this driver, then perform the
- * init function.
- */
- if(tpnt->init && tpnt->dev_noticed)
- if ((*tpnt->init)()) return 1;
-
- /*
- * Now actually connect the devices to the new driver.
- */
- for(SDpnt = scsi_devices; SDpnt; SDpnt = SDpnt->next)
- {
- if(tpnt->attach) (*tpnt->attach)(SDpnt);
- /*
- * If this driver attached to the device, and we no longer
- * have anything attached, release the scso command blocks.
- */
- if(SDpnt->attached && SDpnt->has_cmdblocks == 0)
- scsi_build_commandblocks(SDpnt);
- }
-
- /*
- * This does any final handling that is required.
- */
- if(tpnt->finish && tpnt->nr_dev) (*tpnt->finish)();
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-static int scsi_unregister_device(struct Scsi_Device_Template * tpnt)
-{
- Scsi_Device * SDpnt;
- Scsi_Cmnd * SCpnt;
- struct Scsi_Device_Template * spnt;
- struct Scsi_Device_Template * prev_spnt;
-
- /*
- * If we are busy, this is not going to fly.
- */
- if( *tpnt->usage_count != 0) return 0;
- /*
- * Next, detach the devices from the driver.
- */
-
- for(SDpnt = scsi_devices; SDpnt; SDpnt = SDpnt->next)
- {
- if(tpnt->detach) (*tpnt->detach)(SDpnt);
- if(SDpnt->attached == 0)
- {
- /*
- * Nobody is using this device any more. Free all of the
- * command structures.
- */
- for(SCpnt = SDpnt->host->host_queue; SCpnt; SCpnt = SCpnt->next)
- {
- if(SCpnt->device == SDpnt)
- {
- if(SCpnt->prev != NULL)
- SCpnt->prev->next = SCpnt->next;
- if(SCpnt->next != NULL)
- SCpnt->next->prev = SCpnt->prev;
- if(SCpnt == SDpnt->host->host_queue)
- SDpnt->host->host_queue = SCpnt->next;
- scsi_init_free((char *) SCpnt, sizeof(*SCpnt));
- }
- }
- SDpnt->has_cmdblocks = 0;
- }
- }
- /*
- * Extract the template from the linked list.
- */
- spnt = scsi_devicelist;
- prev_spnt = NULL;
- while(spnt != tpnt)
- {
- prev_spnt = spnt;
- spnt = spnt->next;
- }
- if(prev_spnt == NULL)
- scsi_devicelist = tpnt->next;
- else
- prev_spnt->next = spnt->next;
-
- MOD_DEC_USE_COUNT;
- /*
- * Final cleanup for the driver is done in the driver sources in the
- * cleanup function.
- */
- return 0;
-}
-
-
-int scsi_register_module(int module_type, void * ptr)
-{
- switch(module_type){
- case MODULE_SCSI_HA:
- return scsi_register_host((Scsi_Host_Template *) ptr);
-
- /* Load upper level device handler of some kind */
- case MODULE_SCSI_DEV:
- return scsi_register_device_module((struct Scsi_Device_Template *) ptr);
- /* The rest of these are not yet implemented */
-
- /* Load constants.o */
- case MODULE_SCSI_CONST:
-
- /* Load specialized ioctl handler for some device. Intended for
- * cdroms that have non-SCSI2 audio command sets. */
- case MODULE_SCSI_IOCTL:
-
- default:
- return 1;
- }
-}
-
-void scsi_unregister_module(int module_type, void * ptr)
-{
- switch(module_type) {
- case MODULE_SCSI_HA:
- scsi_unregister_host((Scsi_Host_Template *) ptr);
- break;
- case MODULE_SCSI_DEV:
- scsi_unregister_device((struct Scsi_Device_Template *) ptr);
- break;
- /* The rest of these are not yet implemented. */
- case MODULE_SCSI_CONST:
- case MODULE_SCSI_IOCTL:
- break;
- default:
- }
- return;
-}
-
-#endif /* CONFIG_MODULES */
-
-#ifdef DEBUG_TIMEOUT
-static void
-scsi_dump_status(void)
-{
- int i;
- struct Scsi_Host * shpnt;
- Scsi_Cmnd * SCpnt;
- printk("Dump of scsi parameters:\n");
- i = 0;
- for(shpnt = scsi_hostlist; shpnt; shpnt = shpnt->next)
- for(SCpnt=shpnt->host_queue; SCpnt; SCpnt = SCpnt->next)
- {
- /* (0) 0:0:0:0 (802 123434 8 8 0) (3 3 2) (%d %d %d) %d %x */
- printk("(%d) %d:%d:%d:%d (%s %ld %ld %ld %d) (%d %d %x) (%d %d %d) %x %x %x\n",
- i++, SCpnt->host->host_no,
- SCpnt->channel,
- SCpnt->target,
- SCpnt->lun,
- kdevname(SCpnt->request.rq_dev),
- SCpnt->request.sector,
- SCpnt->request.nr_sectors,
- SCpnt->request.current_nr_sectors,
- SCpnt->use_sg,
- SCpnt->retries,
- SCpnt->allowed,
- SCpnt->flags,
- SCpnt->timeout_per_command,
- SCpnt->timeout,
- SCpnt->internal_timeout,
- SCpnt->cmnd[0],
- SCpnt->sense_buffer[2],
- SCpnt->result);
- }
- printk("wait_for_request = %p\n", wait_for_request);
- /* Now dump the request lists for each block device */
- printk("Dump of pending block device requests\n");
- for(i=0; i<MAX_BLKDEV; i++)
- if(blk_dev[i].current_request)
- {
- struct request * req;
- printk("%d: ", i);
- req = blk_dev[i].current_request;
- while(req) {
- printk("(%s %d %ld %ld %ld) ",
- kdevname(req->rq_dev),
- req->cmd,
- req->sector,
- req->nr_sectors,
- req->current_nr_sectors);
- req = req->next;
- }
- printk("\n");
- }
-}
-#endif
-
-#ifdef MODULE
-
-int init_module(void) {
- unsigned long size;
-
- /*
- * This makes /proc/scsi visible.
- */
- dispatch_scsi_info_ptr = dispatch_scsi_info;
-
- timer_table[SCSI_TIMER].fn = scsi_main_timeout;
- timer_table[SCSI_TIMER].expires = 0;
- register_symtab(&scsi_symbol_table);
- scsi_loadable_module_flag = 1;
-
- /* Register the /proc/scsi/scsi entry */
-#if CONFIG_PROC_FS
- proc_scsi_register(0, &proc_scsi_scsi);
-#endif
-
-
- dma_sectors = PAGE_SIZE / SECTOR_SIZE;
- dma_free_sectors= dma_sectors;
- /*
- * Set up a minimal DMA buffer list - this will be used during scan_scsis
- * in some cases.
- */
-
- /* One bit per sector to indicate free/busy */
- size = (dma_sectors / SECTORS_PER_PAGE)*sizeof(FreeSectorBitmap);
- dma_malloc_freelist = (unsigned char *) scsi_init_malloc(size, GFP_ATOMIC);
- memset(dma_malloc_freelist, 0, size);
-
- /* One pointer per page for the page list */
- dma_malloc_pages = (unsigned char **)
- scsi_init_malloc((dma_sectors / SECTORS_PER_PAGE)*sizeof(*dma_malloc_pages), GFP_ATOMIC);
- dma_malloc_pages[0] = (unsigned char *)
- scsi_init_malloc(PAGE_SIZE, GFP_ATOMIC | GFP_DMA);
- return 0;
-}
-
-void cleanup_module( void)
-{
-#if CONFIG_PROC_FS
- proc_scsi_unregister(0, PROC_SCSI_SCSI);
-#endif
-
- /* No, we're not here anymore. Don't show the /proc/scsi files. */
- dispatch_scsi_info_ptr = 0L;
-
- /*
- * Free up the DMA pool.
- */
- resize_dma_pool();
-
- timer_table[SCSI_TIMER].fn = NULL;
- timer_table[SCSI_TIMER].expires = 0;
-}
-#endif /* MODULE */
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 4
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * c-continued-statement-offset: 4
- * c-continued-brace-offset: 0
- * indent-tabs-mode: nil
- * tab-width: 8
- * End:
- */
diff --git a/i386/i386at/gpl/linux/scsi/scsi.h b/i386/i386at/gpl/linux/scsi/scsi.h
deleted file mode 100644
index fefe1c73..00000000
--- a/i386/i386at/gpl/linux/scsi/scsi.h
+++ /dev/null
@@ -1,618 +0,0 @@
-/*
- * scsi.h Copyright (C) 1992 Drew Eckhardt
- * Copyright (C) 1993, 1994, 1995 Eric Youngdale
- * generic SCSI package header file by
- * Initial versions: Drew Eckhardt
- * Subsequent revisions: Eric Youngdale
- *
- * <drew@colorado.edu>
- *
- * Modified by Eric Youngdale eric@aib.com to
- * add scatter-gather, multiple outstanding request, and other
- * enhancements.
- */
-
-#ifndef _SCSI_H
-#define _SCSI_H
-
-/*
- * Some of the public constants are being moved to this file.
- * We include it here so that what came from where is transparent.
- */
-#include <linux/scsi.h>
-
-
-/*
- * Some defs, in case these are not defined elsewhere.
- */
-#ifndef TRUE
-# define TRUE 1
-#endif
-#ifndef FALSE
-# define FALSE 0
-#endif
-
-#ifdef MACH
-#ifndef LINUX_SCSI_DEBUG
-#undef DEBUG
-#endif
-#endif
-
-extern void scsi_make_blocked_list(void);
-extern volatile int in_scan_scsis;
-extern const unsigned char scsi_command_size[8];
-#define COMMAND_SIZE(opcode) scsi_command_size[((opcode) >> 5) & 7]
-
-#define IDENTIFY_BASE 0x80
-#define IDENTIFY(can_disconnect, lun) (IDENTIFY_BASE |\
- ((can_disconnect) ? 0x40 : 0) |\
- ((lun) & 0x07))
-
-
-
-/*
- * the return of the status word will be in the following format :
- * The low byte is the status returned by the SCSI command,
- * with vendor specific bits masked.
- *
- * The next byte is the message which followed the SCSI status.
- * This allows a stos to be used, since the Intel is a little
- * endian machine.
- *
- * The final byte is a host return code, which is one of the following.
- *
- * IE
- * lsb msb
- * status msg host code
- *
- * Our errors returned by OUR driver, NOT SCSI message. Or'd with
- * SCSI message passed back to driver <IF any>.
- */
-
-
-#define DID_OK 0x00 /* NO error */
-#define DID_NO_CONNECT 0x01 /* Couldn't connect before timeout period */
-#define DID_BUS_BUSY 0x02 /* BUS stayed busy through time out period */
-#define DID_TIME_OUT 0x03 /* TIMED OUT for other reason */
-#define DID_BAD_TARGET 0x04 /* BAD target. */
-#define DID_ABORT 0x05 /* Told to abort for some other reason */
-#define DID_PARITY 0x06 /* Parity error */
-#define DID_ERROR 0x07 /* Internal error */
-#define DID_RESET 0x08 /* Reset by somebody. */
-#define DID_BAD_INTR 0x09 /* Got an interrupt we weren't expecting. */
-#define DRIVER_OK 0x00 /* Driver status */
-
-/*
- * These indicate the error that occurred, and what is available.
- */
-
-#define DRIVER_BUSY 0x01
-#define DRIVER_SOFT 0x02
-#define DRIVER_MEDIA 0x03
-#define DRIVER_ERROR 0x04
-
-#define DRIVER_INVALID 0x05
-#define DRIVER_TIMEOUT 0x06
-#define DRIVER_HARD 0x07
-#define DRIVER_SENSE 0x08
-
-#define SUGGEST_RETRY 0x10
-#define SUGGEST_ABORT 0x20
-#define SUGGEST_REMAP 0x30
-#define SUGGEST_DIE 0x40
-#define SUGGEST_SENSE 0x80
-#define SUGGEST_IS_OK 0xff
-
-#define DRIVER_MASK 0x0f
-#define SUGGEST_MASK 0xf0
-
-#define MAX_COMMAND_SIZE 12
-
-/*
- * SCSI command sets
- */
-
-#define SCSI_UNKNOWN 0
-#define SCSI_1 1
-#define SCSI_1_CCS 2
-#define SCSI_2 3
-
-/*
- * Every SCSI command starts with a one byte OP-code.
- * The next byte's high three bits are the LUN of the
- * device. Any multi-byte quantities are stored high byte
- * first, and may have a 5 bit MSB in the same byte
- * as the LUN.
- */
-
-/*
- * Manufacturers list
- */
-
-#define SCSI_MAN_UNKNOWN 0
-#define SCSI_MAN_NEC 1
-#define SCSI_MAN_TOSHIBA 2
-#define SCSI_MAN_NEC_OLDCDR 3
-#define SCSI_MAN_SONY 4
-#define SCSI_MAN_PIONEER 5
-
-/*
- * As the scsi do command functions are intelligent, and may need to
- * redo a command, we need to keep track of the last command
- * executed on each one.
- */
-
-#define WAS_RESET 0x01
-#define WAS_TIMEDOUT 0x02
-#define WAS_SENSE 0x04
-#define IS_RESETTING 0x08
-#define IS_ABORTING 0x10
-#define ASKED_FOR_SENSE 0x20
-
-/*
- * The scsi_device struct contains what we know about each given scsi
- * device.
- */
-
-typedef struct scsi_device {
- struct scsi_device * next; /* Used for linked list */
-
- unsigned char id, lun, channel;
-
- unsigned int manufacturer; /* Manufacturer of device, for using
- * vendor-specific cmd's */
- int attached; /* # of high level drivers attached to
- * this */
- int access_count; /* Count of open channels/mounts */
- struct wait_queue * device_wait;/* Used to wait if device is busy */
- struct Scsi_Host * host;
- void (*scsi_request_fn)(void); /* Used to jumpstart things after an
- * ioctl */
- void *hostdata; /* available to low-level driver */
- char type;
- char scsi_level;
- char vendor[8], model[16], rev[4];
- unsigned char current_tag; /* current tag */
- unsigned char sync_min_period; /* Not less than this period */
- unsigned char sync_max_offset; /* Not greater than this offset */
-
- unsigned writeable:1;
- unsigned removable:1;
- unsigned random:1;
- unsigned has_cmdblocks:1;
- unsigned changed:1; /* Data invalid due to media change */
- unsigned busy:1; /* Used to prevent races */
- unsigned lockable:1; /* Able to prevent media removal */
- unsigned borken:1; /* Tell the Seagate driver to be
- * painfully slow on this device */
- unsigned tagged_supported:1; /* Supports SCSI-II tagged queuing */
- unsigned tagged_queue:1; /* SCSI-II tagged queuing enabled */
- unsigned disconnect:1; /* can disconnect */
- unsigned soft_reset:1; /* Uses soft reset option */
- unsigned sync:1; /* Negotiate for sync transfers */
- unsigned single_lun:1; /* Indicates we should only allow I/O to
- one of the luns for the device at a time. */
- unsigned was_reset:1; /* There was a bus reset on the bus for this
- device */
- unsigned expecting_cc_ua:1; /* Expecting a CHECK_CONDITION/UNIT_ATTN
- because we did a bus reset. */
-} Scsi_Device;
-
-/*
- * Use these to separate status msg and our bytes
- */
-
-#define status_byte(result) (((result) >> 1) & 0xf)
-#define msg_byte(result) (((result) >> 8) & 0xff)
-#define host_byte(result) (((result) >> 16) & 0xff)
-#define driver_byte(result) (((result) >> 24) & 0xff)
-#define suggestion(result) (driver_byte(result) & SUGGEST_MASK)
-
-#define sense_class(sense) (((sense) >> 4) & 0x7)
-#define sense_error(sense) ((sense) & 0xf)
-#define sense_valid(sense) ((sense) & 0x80);
-
-/*
- * These are the SCSI devices available on the system.
- */
-
-extern Scsi_Device * scsi_devices;
-
-/*
- * Initializes all SCSI devices. This scans all scsi busses.
- */
-
-extern int scsi_dev_init (void);
-
-struct scatterlist {
- char * address; /* Location data is to be transferred to */
- char * alt_address; /* Location of actual if address is a
- * dma indirect buffer. NULL otherwise */
- unsigned int length;
-};
-
-#ifdef __alpha__
-# define ISA_DMA_THRESHOLD (~0UL)
-#else
-# define ISA_DMA_THRESHOLD (0x00ffffff)
-#endif
-#define CONTIGUOUS_BUFFERS(X,Y) ((X->b_data+X->b_size) == Y->b_data)
-
-
-/*
- * These are the return codes for the abort and reset functions. The mid-level
- * code uses these to decide what to do next. Each of the low level abort
- * and reset functions must correctly indicate what it has done.
- * The descriptions are written from the point of view of the mid-level code,
- * so that the return code is telling the mid-level drivers exactly what
- * the low level driver has already done, and what remains to be done.
- */
-
-/* We did not do anything.
- * Wait some more for this command to complete, and if this does not work,
- * try something more serious. */
-#define SCSI_ABORT_SNOOZE 0
-
-/* This means that we were able to abort the command. We have already
- * called the mid-level done function, and do not expect an interrupt that
- * will lead to another call to the mid-level done function for this command */
-#define SCSI_ABORT_SUCCESS 1
-
-/* We called for an abort of this command, and we should get an interrupt
- * when this succeeds. Thus we should not restore the timer for this
- * command in the mid-level abort function. */
-#define SCSI_ABORT_PENDING 2
-
-/* Unable to abort - command is currently on the bus. Grin and bear it. */
-#define SCSI_ABORT_BUSY 3
-
-/* The command is not active in the low level code. Command probably
- * finished. */
-#define SCSI_ABORT_NOT_RUNNING 4
-
-/* Something went wrong. The low level driver will indicate the correct
- * error condition when it calls scsi_done, so the mid-level abort function
- * can simply wait until this comes through */
-#define SCSI_ABORT_ERROR 5
-
-/* We do not know how to reset the bus, or we do not want to. Bummer.
- * Anyway, just wait a little more for the command in question, and hope that
- * it eventually finishes. If it never finishes, the SCSI device could
- * hang, so use this with caution. */
-#define SCSI_RESET_SNOOZE 0
-
-/* We do not know how to reset the bus, or we do not want to. Bummer.
- * We have given up on this ever completing. The mid-level code will
- * request sense information to decide how to proceed from here. */
-#define SCSI_RESET_PUNT 1
-
-/* This means that we were able to reset the bus. We have restarted all of
- * the commands that should be restarted, and we should be able to continue
- * on normally from here. We do not expect any interrupts that will return
- * DID_RESET to any of the other commands in the host_queue, and the mid-level
- * code does not need to do anything special to keep the commands alive.
- * If a hard reset was performed then all outstanding commands on the
- * bus have been restarted. */
-#define SCSI_RESET_SUCCESS 2
-
-/* We called for a reset of this bus, and we should get an interrupt
- * when this succeeds. Each command should get its own status
- * passed up to scsi_done, but this has not happened yet.
- * If a hard reset was performed, then we expect an interrupt
- * for *each* of the outstanding commands that will have the
- * effect of restarting the commands.
- */
-#define SCSI_RESET_PENDING 3
-
-/* We did a reset, but do not expect an interrupt to signal DID_RESET.
- * This tells the upper level code to request the sense info, and this
- * should keep the command alive. */
-#define SCSI_RESET_WAKEUP 4
-
-/* Something went wrong, and we do not know how to fix it. */
-#define SCSI_RESET_ERROR 5
-
-/*
- * This is a bitmask that is ored with one of the above codes.
- * It tells the mid-level code that we did a hard reset.
- */
-#define SCSI_RESET_BUS_RESET 0x100
-/*
- * Used to mask off bits and to obtain the basic action that was
- * performed.
- */
-#define SCSI_RESET_ACTION 0xff
-
-void * scsi_malloc(unsigned int);
-int scsi_free(void *, unsigned int);
-extern unsigned int dma_free_sectors; /* How much room do we have left */
-extern unsigned int need_isa_buffer; /* True if some devices need indirection
- * buffers */
-
-/*
- * The Scsi_Cmnd structure is used by scsi.c internally, and for communication
- * with low level drivers that support multiple outstanding commands.
- */
-typedef struct scsi_pointer {
- char * ptr; /* data pointer */
- int this_residual; /* left in this buffer */
- struct scatterlist *buffer; /* which buffer */
- int buffers_residual; /* how many buffers left */
-
- volatile int Status;
- volatile int Message;
- volatile int have_data_in;
- volatile int sent_command;
- volatile int phase;
-} Scsi_Pointer;
-
-typedef struct scsi_cmnd {
- struct Scsi_Host * host;
- Scsi_Device * device;
- unsigned char target, lun, channel;
- unsigned char cmd_len;
- unsigned char old_cmd_len;
- struct scsi_cmnd *next, *prev;
-
- /* These elements define the operation we are about to perform */
- unsigned char cmnd[12];
- unsigned request_bufflen; /* Actual request size */
-
- void * request_buffer; /* Actual requested buffer */
-
- /* These elements define the operation we ultimately want to perform */
- unsigned char data_cmnd[12];
- unsigned short old_use_sg; /* We save use_sg here when requesting
- * sense info */
- unsigned short use_sg; /* Number of pieces of scatter-gather */
- unsigned short sglist_len; /* size of malloc'd scatter-gather list */
- unsigned short abort_reason;/* If the mid-level code requests an
- * abort, this is the reason. */
- unsigned bufflen; /* Size of data buffer */
- void *buffer; /* Data buffer */
-
- unsigned underflow; /* Return error if less than this amount is
- * transfered */
-
- unsigned transfersize; /* How much we are guaranteed to transfer with
- * each SCSI transfer (ie, between disconnect /
- * reconnects. Probably == sector size */
-
-
- struct request request; /* A copy of the command we are working on */
-
- unsigned char sense_buffer[16]; /* Sense for this command, if needed */
-
-
- int retries;
- int allowed;
- int timeout_per_command, timeout_total, timeout;
-
- /*
- * We handle the timeout differently if it happens when a reset,
- * abort, etc are in process.
- */
- unsigned volatile char internal_timeout;
-
- unsigned flags;
-
- /* These variables are for the cdrom only. Once we have variable size
- * buffers in the buffer cache, they will go away. */
- int this_count;
- /* End of special cdrom variables */
-
- /* Low-level done function - can be used by low-level driver to point
- * to completion function. Not used by mid/upper level code. */
- void (*scsi_done)(struct scsi_cmnd *);
- void (*done)(struct scsi_cmnd *); /* Mid-level done function */
-
- /*
- * The following fields can be written to by the host specific code.
- * Everything else should be left alone.
- */
-
- Scsi_Pointer SCp; /* Scratchpad used by some host adapters */
-
- unsigned char * host_scribble; /* The host adapter is allowed to
- * call scsi_malloc and get some memory
- * and hang it here. The host adapter
- * is also expected to call scsi_free
- * to release this memory. (The memory
- * obtained by scsi_malloc is guaranteed
- * to be at an address < 16Mb). */
-
- int result; /* Status code from lower level driver */
-
- unsigned char tag; /* SCSI-II queued command tag */
- unsigned long pid; /* Process ID, starts at 0 */
-} Scsi_Cmnd;
-
-/*
- * scsi_abort aborts the current command that is executing on host host.
- * The error code, if non zero is returned in the host byte, otherwise
- * DID_ABORT is returned in the hostbyte.
- */
-
-extern int scsi_abort (Scsi_Cmnd *, int code, int pid);
-
-extern void scsi_do_cmd (Scsi_Cmnd *, const void *cmnd ,
- void *buffer, unsigned bufflen,
- void (*done)(struct scsi_cmnd *),
- int timeout, int retries);
-
-
-extern Scsi_Cmnd * allocate_device(struct request **, Scsi_Device *, int);
-
-extern Scsi_Cmnd * request_queueable(struct request *, Scsi_Device *);
-extern int scsi_reset (Scsi_Cmnd *, int);
-
-extern int max_scsi_hosts;
-
-extern void proc_print_scsidevice(Scsi_Device *, char *, int *, int);
-
-extern void print_command(unsigned char *);
-extern void print_sense(const char *, Scsi_Cmnd *);
-extern void print_driverbyte(int scsiresult);
-extern void print_hostbyte(int scsiresult);
-
-extern void scsi_mark_host_bus_reset(struct Scsi_Host *Host);
-
-#if defined(MAJOR_NR) && (MAJOR_NR != SCSI_TAPE_MAJOR)
-#include "hosts.h"
-
-static Scsi_Cmnd * end_scsi_request(Scsi_Cmnd * SCpnt, int uptodate, int sectors)
-{
- struct request * req;
- struct buffer_head * bh;
-
- req = &SCpnt->request;
- if (!uptodate) {
- printk(DEVICE_NAME " I/O error: dev %s, sector %lu\n",
- kdevname(req->rq_dev), req->sector);
-#ifdef MACH
- req->errors = 1;
- while (req->bh) {
- bh = req->bh;
- req->bh = bh->b_reqnext;
- mark_buffer_uptodate(bh, 0);
- unlock_buffer(bh);
- }
- goto done;
-#endif
- }
-
- do {
- if ((bh = req->bh) != NULL) {
- req->bh = bh->b_reqnext;
- req->nr_sectors -= bh->b_size >> 9;
- req->sector += bh->b_size >> 9;
- bh->b_reqnext = NULL;
- mark_buffer_uptodate(bh, uptodate);
- unlock_buffer(bh);
- sectors -= bh->b_size >> 9;
- if ((bh = req->bh) != NULL) {
- req->current_nr_sectors = bh->b_size >> 9;
- if (req->nr_sectors < req->current_nr_sectors) {
- req->nr_sectors = req->current_nr_sectors;
- printk("end_scsi_request: buffer-list destroyed\n");
- }
- }
- }
- } while(sectors && bh);
- if (req->bh){
- req->buffer = bh->b_data;
- return SCpnt;
- };
-#ifdef MACH
- req->errors = 0;
-
-done:
-#endif
- DEVICE_OFF(req->rq_dev);
- if (req->sem != NULL) {
- up(req->sem);
- }
-
- if (SCpnt->host->block) {
- struct Scsi_Host * next;
-
- for (next = SCpnt->host->block; next != SCpnt->host;
- next = next->block)
- wake_up(&next->host_wait);
- }
-
- req->rq_status = RQ_INACTIVE;
-#ifndef MACH
- wake_up(&wait_for_request);
-#endif
- wake_up(&SCpnt->device->device_wait);
-#ifdef MACH
- {
- unsigned long flags;
-
- save_flags(flags);
- cli();
- (*blk_dev[MAJOR(req->rq_dev)].request_fn)();
- restore_flags(flags);
- }
-#endif
- return NULL;
-}
-
-
-/* This is just like INIT_REQUEST, but we need to be aware of the fact
- * that an interrupt may start another request, so we run this with interrupts
- * turned off
- */
-#define INIT_SCSI_REQUEST \
- if (!CURRENT) { \
- CLEAR_INTR; \
- restore_flags(flags); \
- return; \
- } \
- if (MAJOR(CURRENT->rq_dev) != MAJOR_NR) \
- panic(DEVICE_NAME ": request list destroyed");\
- if (CURRENT->bh) { \
- if (!buffer_locked(CURRENT->bh)) \
- panic(DEVICE_NAME ": block not locked"); \
- }
-#endif
-
-#ifdef MACH
-#define SCSI_SLEEP(QUEUE, CONDITION) { \
- if (CONDITION) { \
- struct wait_queue wait = { NULL, NULL}; \
- add_wait_queue(QUEUE, &wait); \
- for(;;) { \
- if (CONDITION) { \
- if (intr_count) \
- panic("scsi: trying to call schedule() in interrupt" \
- ", file %s, line %d.\n", __FILE__, __LINE__); \
- schedule(); \
- } \
- else \
- break; \
- } \
- remove_wait_queue(QUEUE, &wait);\
- }; }
-#else /* ! MACH */
-#define SCSI_SLEEP(QUEUE, CONDITION) { \
- if (CONDITION) { \
- struct wait_queue wait = { current, NULL}; \
- add_wait_queue(QUEUE, &wait); \
- for(;;) { \
- current->state = TASK_UNINTERRUPTIBLE; \
- if (CONDITION) { \
- if (intr_count) \
- panic("scsi: trying to call schedule() in interrupt" \
- ", file %s, line %d.\n", __FILE__, __LINE__); \
- schedule(); \
- } \
- else \
- break; \
- } \
- remove_wait_queue(QUEUE, &wait);\
- current->state = TASK_RUNNING; \
- }; }
-#endif /* ! MACH */
-
-#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 4
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * c-continued-statement-offset: 4
- * c-continued-brace-offset: 0
- * indent-tabs-mode: nil
- * tab-width: 8
- * End:
- */
diff --git a/i386/i386at/gpl/linux/scsi/scsi_debug.c b/i386/i386at/gpl/linux/scsi/scsi_debug.c
deleted file mode 100644
index e98f53e2..00000000
--- a/i386/i386at/gpl/linux/scsi/scsi_debug.c
+++ /dev/null
@@ -1,710 +0,0 @@
-/* $Id: scsi_debug.c,v 1.1.1.1 1997/02/25 21:27:51 thomas Exp $
- * linux/kernel/scsi_debug.c
- *
- * Copyright (C) 1992 Eric Youngdale
- * Simulate a host adapter with 2 disks attached. Do a lot of checking
- * to make sure that we are not getting blocks mixed up, and panic if
- * anything out of the ordinary is seen.
- */
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/errno.h>
-#include <linux/timer.h>
-#include <linux/head.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/genhd.h>
-#include <linux/fs.h>
-#include <linux/proc_fs.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-
-#ifdef MODULE
-#include <linux/module.h>
-#endif
-
-#include <linux/blk.h>
-#include "scsi.h"
-#include "hosts.h"
-
-#include "sd.h"
-
-#include<linux/stat.h>
-
-struct proc_dir_entry proc_scsi_scsi_debug = {
- PROC_SCSI_SCSI_DEBUG, 10, "scsi_debug",
- S_IFDIR | S_IRUGO | S_IXUGO, 2
-};
-
-
-/* A few options that we want selected */
-
-/* Do not attempt to use a timer to simulate a real disk with latency */
-/* Only use this in the actual kernel, not in the simulator. */
-#define IMMEDIATE
-
-/* Skip some consistency checking. Good for benchmarking */
-#define SPEEDY
-
-/* Number of real scsi disks that will be detected ahead of time */
-static int NR_REAL=-1;
-
-#define NR_BLK_DEV 12
-#ifndef MAJOR_NR
-#define MAJOR_NR 8
-#endif
-#define START_PARTITION 4
-#define SCSI_DEBUG_TIMER 20
-/* Number of jiffies to wait before completing a command */
-#define DISK_SPEED 10
-#define CAPACITY (0x80000)
-
-static int starts[] = {4, 1000, 50000, CAPACITY, 0};
-static int npart = 0;
-
-#include "scsi_debug.h"
-#ifdef DEBUG
-#define DEB(x) x
-#else
-#define DEB(x)
-#endif
-
-#ifdef SPEEDY
-#define VERIFY1_DEBUG(RW) 1
-#define VERIFY_DEBUG(RW) 1
-#else
-
-#define VERIFY1_DEBUG(RW) \
- if (bufflen != 1024) {printk("%d", bufflen); panic("(1)Bad bufflen");}; \
- start = 0; \
- if ((MINOR(SCpnt->request.rq_dev) & 0xf) != 0) start = starts[(MINOR(SCpnt->request.rq_dev) & 0xf) - 1]; \
- if (bh){ \
- if (bh->b_size != 1024) panic ("Wrong bh size"); \
- if ((bh->b_blocknr << 1) + start != block) \
- { printk("Wrong bh block# %d %d ",bh->b_blocknr, block); \
- panic ("Wrong bh block#"); \
- }; \
- if (bh->b_dev != SCpnt->request.rq_dev) \
- panic ("Bad bh target"); \
- };
-
-#define VERIFY_DEBUG(RW) \
- if (bufflen != 1024 && (!SCpnt->use_sg)) {printk("%x %d\n ",bufflen, SCpnt->use_sg); panic("Bad bufflen");}; \
- start = 0; \
- if ((MINOR(SCpnt->request.rq_dev) & 0xf) > npart) panic ("Bad partition"); \
- if ((MINOR(SCpnt->request.rq_dev) & 0xf) != 0) start = starts[(MINOR(SCpnt->request.rq_dev) & 0xf) - 1]; \
- if (SCpnt->request.cmd != RW) panic ("Wrong operation"); \
- if (SCpnt->request.sector + start != block) panic("Wrong block."); \
- if (SCpnt->request.current_nr_sectors != 2 && (!SCpnt->use_sg)) panic ("Wrong # blocks"); \
- if (SCpnt->request.bh){ \
- if (SCpnt->request.bh->b_size != 1024) panic ("Wrong bh size"); \
- if ((SCpnt->request.bh->b_blocknr << 1) + start != block) \
- { printk("Wrong bh block# %d %d ",SCpnt->request.bh->b_blocknr, block); \
- panic ("Wrong bh block#"); \
- }; \
- if (SCpnt->request.bh->b_dev != SCpnt->request.rq_dev) \
- panic ("Bad bh target");\
- };
-#endif
-
-static volatile void (*do_done[SCSI_DEBUG_MAILBOXES])(Scsi_Cmnd *) = {NULL, };
-extern void scsi_debug_interrupt();
-
-volatile Scsi_Cmnd * SCint[SCSI_DEBUG_MAILBOXES] = {NULL,};
-static char SCrst[SCSI_DEBUG_MAILBOXES] = {0,};
-static volatile unsigned int timeout[8] ={0,};
-
-/*
- * Semaphore used to simulate bus lockups.
- */
-static int scsi_debug_lockup = 0;
-
-static char sense_buffer[128] = {0,};
-
-static void scsi_dump(Scsi_Cmnd * SCpnt, int flag){
- int i;
-#if 0
- unsigned char * pnt;
-#endif
- unsigned int * lpnt;
- struct scatterlist * sgpnt = NULL;
- printk("use_sg: %d",SCpnt->use_sg);
- if (SCpnt->use_sg){
- sgpnt = (struct scatterlist *) SCpnt->buffer;
- for(i=0; i<SCpnt->use_sg; i++) {
- lpnt = (int *) sgpnt[i].alt_address;
- printk(":%x %x %d\n",sgpnt[i].alt_address, sgpnt[i].address, sgpnt[i].length);
- if (lpnt) printk(" (Alt %x) ",lpnt[15]);
- };
- } else {
- printk("nosg: %x %x %d\n",SCpnt->request.buffer, SCpnt->buffer,
- SCpnt->bufflen);
- lpnt = (int *) SCpnt->request.buffer;
- if (lpnt) printk(" (Alt %x) ",lpnt[15]);
- };
- lpnt = (unsigned int *) SCpnt;
- for (i=0;i<sizeof(Scsi_Cmnd)/4+1; i++) {
- if ((i & 7) == 0) printk("\n");
- printk("%x ",*lpnt++);
- };
- printk("\n");
- if (flag == 0) return;
- lpnt = (unsigned int *) sgpnt[0].alt_address;
- for (i=0;i<sizeof(Scsi_Cmnd)/4+1; i++) {
- if ((i & 7) == 0) printk("\n");
- printk("%x ",*lpnt++);
- };
-#if 0
- printk("\n");
- lpnt = (unsigned int *) sgpnt[0].address;
- for (i=0;i<sizeof(Scsi_Cmnd)/4+1; i++) {
- if ((i & 7) == 0) printk("\n");
- printk("%x ",*lpnt++);
- };
- printk("\n");
-#endif
- printk("DMA free %d sectors.\n", dma_free_sectors);
-}
-
-int scsi_debug_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
-{
- unchar *cmd = (unchar *) SCpnt->cmnd;
- struct partition * p;
- int block, start;
- struct buffer_head * bh = NULL;
- unsigned char * buff;
- int nbytes, sgcount;
- int scsi_debug_errsts;
- struct scatterlist * sgpnt;
- int target = SCpnt->target;
- int bufflen = SCpnt->request_bufflen;
- unsigned long flags;
- int i;
- sgcount = 0;
- sgpnt = NULL;
-
- DEB(if (target > 1) { SCpnt->result = DID_TIME_OUT << 16;done(SCpnt);return 0;});
-
- buff = (unsigned char *) SCpnt->request_buffer;
-
- if(target>=1 || SCpnt->lun != 0) {
- SCpnt->result = DID_NO_CONNECT << 16;
- done(SCpnt);
- return 0;
- };
-
- if( SCrst[target] != 0 && !scsi_debug_lockup )
- {
- SCrst[target] = 0;
- memset(SCpnt->sense_buffer, 0, sizeof(SCpnt->sense_buffer));
- SCpnt->sense_buffer[0] = 0x70;
- SCpnt->sense_buffer[2] = UNIT_ATTENTION;
- SCpnt->result = (CHECK_CONDITION << 1);
- done(SCpnt);
- }
- switch(*cmd){
- case REQUEST_SENSE:
- printk("Request sense...\n");
-#ifndef DEBUG
- {
- int i;
- printk("scsi_debug: Requesting sense buffer (%x %x %x %d):", SCpnt, buff, done, bufflen);
- for(i=0;i<12;i++) printk("%d ",sense_buffer[i]);
- printk("\n");
- };
-#endif
- memset(buff, 0, bufflen);
- memcpy(buff, sense_buffer, bufflen);
- memset(sense_buffer, 0, sizeof(sense_buffer));
- SCpnt->result = 0;
- done(SCpnt);
- return 0;
- case ALLOW_MEDIUM_REMOVAL:
- if(cmd[4]) printk("Medium removal inhibited...");
- else printk("Medium removal enabled...");
- scsi_debug_errsts = 0;
- break;
- case INQUIRY:
- printk("Inquiry...(%x %d)\n", buff, bufflen);
- memset(buff, 0, bufflen);
- buff[0] = TYPE_DISK;
- buff[1] = 0x80; /* Removable disk */
- buff[2] = 1;
- buff[4] = 33 - 5;
- memcpy(&buff[8],"Foo Inc",7);
- memcpy(&buff[16],"XYZZY",5);
- memcpy(&buff[32],"1",1);
- scsi_debug_errsts = 0;
- break;
- case TEST_UNIT_READY:
- printk("Test unit ready(%x %d)\n", buff, bufflen);
- if (buff)
- memset(buff, 0, bufflen);
- scsi_debug_errsts = 0;
- break;
- case READ_CAPACITY:
- printk("Read Capacity\n");
- if(NR_REAL < 0) NR_REAL = (MINOR(SCpnt->request.rq_dev) >> 4) & 0x0f;
- memset(buff, 0, bufflen);
- buff[0] = (CAPACITY >> 24);
- buff[1] = (CAPACITY >> 16) & 0xff;
- buff[2] = (CAPACITY >> 8) & 0xff;
- buff[3] = CAPACITY & 0xff;
- buff[6] = 2; /* 512 byte sectors */
- scsi_debug_errsts = 0;
- break;
- case READ_10:
- case READ_6:
-#ifdef DEBUG
- printk("Read...");
-#endif
- if ((*cmd) == READ_10)
- block = cmd[5] + (cmd[4] << 8) + (cmd[3] << 16) + (cmd[2] << 24);
- else
- block = cmd[3] + (cmd[2] << 8) + ((cmd[1] & 0x1f) << 16);
- VERIFY_DEBUG(READ);
-#if defined(SCSI_SETUP_LATENCY) || defined(SCSI_DATARATE)
- {
- int delay = SCSI_SETUP_LATENCY;
- double usec;
-
- usec = 0.0;
- usec = (SCpnt->request.nr_sectors << 9) * 1.0e6 / SCSI_DATARATE;
- delay += usec;
- if(delay) usleep(delay);
- };
-#endif
-
-#ifdef DEBUG
- printk("(r%d)",SCpnt->request.nr_sectors);
-#endif
- nbytes = bufflen;
- if(SCpnt->use_sg){
- sgcount = 0;
- sgpnt = (struct scatterlist *) buff;
- buff = sgpnt[sgcount].address;
- bufflen = sgpnt[sgcount].length;
- bh = SCpnt->request.bh;
- };
- scsi_debug_errsts = 0;
- do{
- VERIFY1_DEBUG(READ);
- /* For the speedy test, we do not even want to fill the buffer with anything */
-#ifndef SPEEDY
- memset(buff, 0, bufflen);
-#endif
- /* If this is block 0, then we want to read the partition table for this
- * device. Let's make one up */
- if(block == 0 && target == 0) {
- memset(buff, 0, bufflen);
- *((unsigned short *) (buff+510)) = 0xAA55;
- p = (struct partition* ) (buff + 0x1be);
- npart = 0;
- while(starts[npart+1]){
- p->start_sect = starts[npart];
- p->nr_sects = starts[npart+1] - starts [npart];
- p->sys_ind = 0x81; /* Linux partition */
- p++;
- npart++;
- };
- scsi_debug_errsts = 0;
- break;
- };
-#ifdef DEBUG
- if (SCpnt->use_sg) printk("Block %x (%d %d)\n",block, SCpnt->request.nr_sectors,
- SCpnt->request.current_nr_sectors);
-#endif
-
-#if 0
- /* Simulate a disk change */
- if(block == 0xfff0) {
- sense_buffer[0] = 0x70;
- sense_buffer[2] = UNIT_ATTENTION;
- starts[0] += 10;
- starts[1] += 10;
- starts[2] += 10;
-
-#ifdef DEBUG
- {
- int i;
- printk("scsi_debug: Filling sense buffer:");
- for(i=0;i<12;i++) printk("%d ",sense_buffer[i]);
- printk("\n");
- };
-#endif
- scsi_debug_errsts = (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1);
- break;
- } /* End phony disk change code */
-#endif
-
-#ifndef SPEEDY
- memcpy(buff, &target, sizeof(target));
- memcpy(buff+sizeof(target), cmd, 24);
- memcpy(buff+60, &block, sizeof(block));
- memcpy(buff+64, SCpnt, sizeof(Scsi_Cmnd));
-#endif
- nbytes -= bufflen;
- if(SCpnt->use_sg){
-#ifndef SPEEDY
- memcpy(buff+128, bh, sizeof(struct buffer_head));
-#endif
- block += bufflen >> 9;
- bh = bh->b_reqnext;
- sgcount++;
- if (nbytes) {
- if(!bh) panic("Too few blocks for linked request.");
- buff = sgpnt[sgcount].address;
- bufflen = sgpnt[sgcount].length;
- };
- }
- } while(nbytes);
-
- SCpnt->result = 0;
- (done)(SCpnt);
- return;
-
- if (SCpnt->use_sg && !scsi_debug_errsts)
- if(bh) scsi_dump(SCpnt, 0);
- break;
- case WRITE_10:
- case WRITE_6:
-#ifdef DEBUG
- printk("Write\n");
-#endif
- if ((*cmd) == WRITE_10)
- block = cmd[5] + (cmd[4] << 8) + (cmd[3] << 16) + (cmd[2] << 24);
- else
- block = cmd[3] + (cmd[2] << 8) + ((cmd[1] & 0x1f) << 16);
- VERIFY_DEBUG(WRITE);
- /* printk("(w%d)",SCpnt->request.nr_sectors); */
- if (SCpnt->use_sg){
- if ((bufflen >> 9) != SCpnt->request.nr_sectors)
- panic ("Trying to write wrong number of blocks\n");
- sgpnt = (struct scatterlist *) buff;
- buff = sgpnt[sgcount].address;
- };
-#if 0
- if (block != *((unsigned long *) (buff+60))) {
- printk("%x %x :",block, *((unsigned long *) (buff+60)));
- scsi_dump(SCpnt,1);
- panic("Bad block written.\n");
- };
-#endif
- scsi_debug_errsts = 0;
- break;
- default:
- printk("Unknown command %d\n",*cmd);
- SCpnt->result = DID_NO_CONNECT << 16;
- done(SCpnt);
- return 0;
- };
-
- save_flags(flags);
- cli();
- for(i=0;i<SCSI_DEBUG_MAILBOXES; i++){
- if (SCint[i] == 0) break;
- };
-
- if (i >= SCSI_DEBUG_MAILBOXES || SCint[i] != 0)
- panic("Unable to find empty SCSI_DEBUG command slot.\n");
-
- SCint[i] = SCpnt;
-
- if (done) {
- DEB(printk("scsi_debug_queuecommand: now waiting for interrupt "););
- if (do_done[i])
- printk("scsi_debug_queuecommand: Two concurrent queuecommand?\n");
- else
- do_done[i] = done;
- }
- else
- printk("scsi_debug_queuecommand: done cant be NULL\n");
-
-#ifdef IMMEDIATE
- if( !scsi_debug_lockup )
- {
- SCpnt->result = scsi_debug_errsts;
- scsi_debug_intr_handle(); /* No timer - do this one right away */
- }
- restore_flags(flags);
-#else
- timeout[i] = jiffies+DISK_SPEED;
-
- /* If no timers active, then set this one */
- if ((timer_active & (1 << SCSI_DEBUG_TIMER)) == 0) {
- timer_table[SCSI_DEBUG_TIMER].expires = timeout[i];
- timer_active |= 1 << SCSI_DEBUG_TIMER;
- };
-
- SCpnt->result = scsi_debug_errsts;
- restore_flags(flags);
-
-#if 0
- printk("Sending command (%d %x %d %d)...", i, done, timeout[i],jiffies);
-#endif
-#endif
-
- return 0;
-}
-
-volatile static int internal_done_flag = 0;
-volatile static int internal_done_errcode = 0;
-static void internal_done(Scsi_Cmnd * SCpnt)
-{
- internal_done_errcode = SCpnt->result;
- ++internal_done_flag;
-}
-
-int scsi_debug_command(Scsi_Cmnd * SCpnt)
-{
- DEB(printk("scsi_debug_command: ..calling scsi_debug_queuecommand\n"));
- scsi_debug_queuecommand(SCpnt, internal_done);
-
- while (!internal_done_flag);
- internal_done_flag = 0;
- return internal_done_errcode;
-}
-
-/* A "high" level interrupt handler. This should be called once per jiffy
- * to simulate a regular scsi disk. We use a timer to do this. */
-
-static void scsi_debug_intr_handle(void)
-{
- Scsi_Cmnd * SCtmp;
- int i, pending;
- void (*my_done)(Scsi_Cmnd *);
- unsigned long flags;
- int to;
-
-#ifndef IMMEDIATE
- timer_table[SCSI_DEBUG_TIMER].expires = 0;
- timer_active &= ~(1 << SCSI_DEBUG_TIMER);
-#endif
-
- repeat:
- save_flags(flags);
- cli();
- for(i=0;i<SCSI_DEBUG_MAILBOXES; i++) {
- if (SCint[i] == 0) continue;
-#ifndef IMMEDIATE
- if (timeout[i] == 0) continue;
- if (timeout[i] <= jiffies) break;
-#else
- break;
-#endif
- };
-
- if(i == SCSI_DEBUG_MAILBOXES){
-#ifndef IMMEDIATE
- pending = INT_MAX;
- for(i=0;i<SCSI_DEBUG_MAILBOXES; i++) {
- if (SCint[i] == 0) continue;
- if (timeout[i] == 0) continue;
- if (timeout[i] <= jiffies) {restore_flags(flags); goto repeat;};
- if (timeout[i] > jiffies) {
- if (pending > timeout[i]) pending = timeout[i];
- continue;
- };
- };
- if (pending && pending != INT_MAX) {
- timer_table[SCSI_DEBUG_TIMER].expires =
- (pending <= jiffies ? jiffies+1 : pending);
- timer_active |= 1 << SCSI_DEBUG_TIMER;
- };
- restore_flags(flags);
-#endif
- return;
- };
-
- if(i < SCSI_DEBUG_MAILBOXES){
- timeout[i] = 0;
- my_done = do_done[i];
- do_done[i] = NULL;
- to = timeout[i];
- timeout[i] = 0;
- SCtmp = (Scsi_Cmnd *) SCint[i];
- SCint[i] = NULL;
- restore_flags(flags);
-
- if (!my_done) {
- printk("scsi_debug_intr_handle: Unexpected interrupt\n");
- return;
- }
-
-#ifdef DEBUG
- printk("In intr_handle...");
- printk("...done %d %x %d %d\n",i , my_done, to, jiffies);
- printk("In intr_handle: %d %x %x\n",i, SCtmp, my_done);
-#endif
-
- my_done(SCtmp);
-#ifdef DEBUG
- printk("Called done.\n");
-#endif
- };
- goto repeat;
-}
-
-
-int scsi_debug_detect(Scsi_Host_Template * tpnt)
-{
- tpnt->proc_dir = &proc_scsi_scsi_debug;
-#ifndef IMMEDIATE
- timer_table[SCSI_DEBUG_TIMER].fn = scsi_debug_intr_handle;
- timer_table[SCSI_DEBUG_TIMER].expires = 0;
-#endif
- return 1;
-}
-
-int scsi_debug_abort(Scsi_Cmnd * SCpnt)
-{
- int j;
- void (*my_done)(Scsi_Cmnd *);
- unsigned long flags;
-
- DEB(printk("scsi_debug_abort\n"));
-#if 0
- SCpnt->result = SCpnt->abort_reason << 16;
- for(j=0;j<SCSI_DEBUG_MAILBOXES; j++) {
- if(SCpnt == SCint[j]) {
- my_done = do_done[j];
- my_done(SCpnt);
- save_flags(flags);
- cli();
- timeout[j] = 0;
- SCint[j] = NULL;
- do_done[j] = NULL;
- restore_flags(flags);
- };
- };
-#endif
- return SCSI_ABORT_SNOOZE;
-}
-
-int scsi_debug_biosparam(Disk * disk, kdev_t dev, int* info){
- int size = disk->capacity;
- info[0] = 32;
- info[1] = 64;
- info[2] = (size + 2047) >> 11;
- if (info[2] >= 1024) info[2] = 1024;
- return 0;
-}
-
-int scsi_debug_reset(Scsi_Cmnd * SCpnt)
-{
- int i;
- unsigned long flags;
-
- void (*my_done)(Scsi_Cmnd *);
- printk("Bus unlocked by reset(%d)\n", SCpnt->host->suggest_bus_reset);
- scsi_debug_lockup = 0;
- DEB(printk("scsi_debug_reset called\n"));
- for(i=0;i<SCSI_DEBUG_MAILBOXES; i++) {
- if (SCint[i] == NULL) continue;
- SCint[i]->result = DID_RESET << 16;
- my_done = do_done[i];
- my_done(SCint[i]);
- save_flags(flags);
- cli();
- SCint[i] = NULL;
- do_done[i] = NULL;
- timeout[i] = 0;
- restore_flags(flags);
- }
- return SCSI_RESET_SUCCESS;
-}
-
-const char *scsi_debug_info(void)
-{
- static char buffer[] = " "; /* looks nicer without anything here */
- return buffer;
-}
-
-/* scsi_debug_proc_info
- * Used if the driver currently has no own support for /proc/scsi
- */
-int scsi_debug_proc_info(char *buffer, char **start, off_t offset,
- int length, int inode, int inout)
-{
- int len, pos, begin;
- int orig_length;
-
- if(inout == 1)
- {
- /* First check for the Signature */
- if (length >= 10 && strncmp(buffer, "scsi_debug", 10) == 0) {
- buffer += 11;
- length -= 11;
- /*
- * OK, we are getting some kind of command. Figure out
- * what we are supposed to do here. Simulate bus lockups
- * to test our reset capability.
- */
- if( length == 6 && strncmp(buffer, "lockup", length) == 0 )
- {
- scsi_debug_lockup = 1;
- return length;
- }
-
- if( length == 6 && strncmp(buffer, "unlock", length) == 0 )
- {
- scsi_debug_lockup = 0;
- return length;
- }
-
- printk("Unknown command:%s\n", buffer);
- } else
- printk("Wrong Signature:%10s\n", (char *) ((ulong)buffer-11));
-
- return -EINVAL;
-
- }
-
- begin = 0;
- pos = len = sprintf(buffer,
- "This driver is not a real scsi driver, but it plays one on TV.\n"
- "It is very handy for debugging specific problems because you\n"
- "can simulate a variety of error conditions\n");
- if(pos < offset)
- {
- len = 0;
- begin = pos;
- }
-
- *start = buffer + (offset - begin); /* Start of wanted data */
- len -= (offset - begin);
- if(len > length)
- len = length;
-
- return(len);
-}
-
-#ifdef MODULE
-/* Eventually this will go into an include file, but this will be later */
-Scsi_Host_Template driver_template = SCSI_DEBUG;
-
-#include "scsi_module.c"
-#endif
-
-/*
- * Overrides for Emacs so that we almost follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 4
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * c-continued-statement-offset: 4
- * c-continued-brace-offset: 0
- * indent-tabs-mode: nil
- * tab-width: 8
- * End:
- */
diff --git a/i386/i386at/gpl/linux/scsi/scsi_debug.h b/i386/i386at/gpl/linux/scsi/scsi_debug.h
deleted file mode 100644
index 87ae155f..00000000
--- a/i386/i386at/gpl/linux/scsi/scsi_debug.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef _SCSI_DEBUG_H
-
-#include <linux/types.h>
-#include <linux/kdev_t.h>
-
-int scsi_debug_detect(Scsi_Host_Template *);
-int scsi_debug_command(Scsi_Cmnd *);
-int scsi_debug_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-int scsi_debug_abort(Scsi_Cmnd *);
-int scsi_debug_biosparam(Disk *, kdev_t, int[]);
-int scsi_debug_reset(Scsi_Cmnd *);
-int scsi_debug_proc_info(char *, char **, off_t, int, int, int);
-
-#ifndef NULL
- #define NULL 0
-#endif
-
-
-#define SCSI_DEBUG_MAILBOXES 8
-
-#define SCSI_DEBUG {NULL, NULL, NULL, scsi_debug_proc_info, \
- "SCSI DEBUG", scsi_debug_detect, NULL, \
- NULL, scsi_debug_command, \
- scsi_debug_queuecommand, \
- scsi_debug_abort, \
- scsi_debug_reset, \
- NULL, \
- scsi_debug_biosparam, \
- SCSI_DEBUG_MAILBOXES, 7, SG_ALL, 1, 0, 1, ENABLE_CLUSTERING}
-#endif
diff --git a/i386/i386at/gpl/linux/scsi/scsi_ioctl.c b/i386/i386at/gpl/linux/scsi/scsi_ioctl.c
deleted file mode 100644
index 11d57bae..00000000
--- a/i386/i386at/gpl/linux/scsi/scsi_ioctl.c
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
- * Don't import our own symbols, as this would severely mess up our
- * symbol tables.
- */
-#define _SCSI_SYMS_VER_
-#define __NO_VERSION__
-#include <linux/module.h>
-
-#include <asm/io.h>
-#include <asm/segment.h>
-#include <asm/system.h>
-
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-
-#include <linux/blk.h>
-#include "scsi.h"
-#include "hosts.h"
-#include "scsi_ioctl.h"
-
-#define MAX_RETRIES 5
-#define MAX_TIMEOUT 900
-#define MAX_BUF 4096
-
-#define max(a,b) (((a) > (b)) ? (a) : (b))
-
-/*
- * If we are told to probe a host, we will return 0 if the host is not
- * present, 1 if the host is present, and will return an identifying
- * string at *arg, if arg is non null, filling to the length stored at
- * (int *) arg
- */
-
-static int ioctl_probe(struct Scsi_Host * host, void *buffer)
-{
- int temp, result;
- unsigned int len,slen;
- const char * string;
-
- if ((temp = host->hostt->present) && buffer) {
- result = verify_area(VERIFY_READ, buffer, sizeof(long));
- if (result) return result;
-
- len = get_user ((unsigned int *) buffer);
- if(host->hostt->info)
- string = host->hostt->info(host);
- else
- string = host->hostt->name;
- if(string) {
- slen = strlen(string);
- if (len > slen)
- len = slen + 1;
- result = verify_area(VERIFY_WRITE, buffer, len);
- if (result) return result;
-
- memcpy_tofs (buffer, string, len);
- }
- }
- return temp;
-}
-
-/*
- *
- * The SCSI_IOCTL_SEND_COMMAND ioctl sends a command out to the SCSI host.
- * The MAX_TIMEOUT and MAX_RETRIES variables are used.
- *
- * dev is the SCSI device struct ptr, *(int *) arg is the length of the
- * input data, if any, not including the command string & counts,
- * *((int *)arg + 1) is the output buffer size in bytes.
- *
- * *(char *) ((int *) arg)[2] the actual command byte.
- *
- * Note that no more than MAX_BUF data bytes will be transfered. Since
- * SCSI block device size is 512 bytes, I figured 1K was good.
- * but (WDE) changed it to 8192 to handle large bad track buffers.
- * ERY: I changed this to a dynamic allocation using scsi_malloc - we were
- * getting a kernel stack overflow which was crashing the system when we
- * were using 8192 bytes.
- *
- * This size *does not* include the initial lengths that were passed.
- *
- * The SCSI command is read from the memory location immediately after the
- * length words, and the input data is right after the command. The SCSI
- * routines know the command size based on the opcode decode.
- *
- * The output area is then filled in starting from the command byte.
- */
-
-static void scsi_ioctl_done (Scsi_Cmnd * SCpnt)
-{
- struct request * req;
-
- req = &SCpnt->request;
- req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */
-
- if (req->sem != NULL) {
- up(req->sem);
- }
-}
-
-static int ioctl_internal_command(Scsi_Device *dev, char * cmd)
-{
- int result;
- Scsi_Cmnd * SCpnt;
-
- SCpnt = allocate_device(NULL, dev, 1);
- {
- struct semaphore sem = MUTEX_LOCKED;
- SCpnt->request.sem = &sem;
- scsi_do_cmd(SCpnt, cmd, NULL, 0,
- scsi_ioctl_done, MAX_TIMEOUT,
- MAX_RETRIES);
- down(&sem);
- }
-
- if(driver_byte(SCpnt->result) != 0)
- switch(SCpnt->sense_buffer[2] & 0xf) {
- case ILLEGAL_REQUEST:
- if(cmd[0] == ALLOW_MEDIUM_REMOVAL) dev->lockable = 0;
- else printk("SCSI device (ioctl) reports ILLEGAL REQUEST.\n");
- break;
- case NOT_READY: /* This happens if there is no disc in drive */
- if(dev->removable){
- printk(KERN_INFO "Device not ready. Make sure there is a disc in the drive.\n");
- break;
- };
- case UNIT_ATTENTION:
- if (dev->removable){
- dev->changed = 1;
- SCpnt->result = 0; /* This is no longer considered an error */
- printk(KERN_INFO "Disc change detected.\n");
- break;
- };
- default: /* Fall through for non-removable media */
- printk("SCSI error: host %d id %d lun %d return code = %x\n",
- dev->host->host_no,
- dev->id,
- dev->lun,
- SCpnt->result);
- printk("\tSense class %x, sense error %x, extended sense %x\n",
- sense_class(SCpnt->sense_buffer[0]),
- sense_error(SCpnt->sense_buffer[0]),
- SCpnt->sense_buffer[2] & 0xf);
-
- };
-
- result = SCpnt->result;
- SCpnt->request.rq_status = RQ_INACTIVE;
- wake_up(&SCpnt->device->device_wait);
- return result;
-}
-
-/*
- * This interface is depreciated - users should use the scsi generics
- * interface instead, as this is a more flexible approach to performing
- * generic SCSI commands on a device.
- */
-static int ioctl_command(Scsi_Device *dev, void *buffer)
-{
- char * buf;
- char cmd[12];
- char * cmd_in;
- Scsi_Cmnd * SCpnt;
- unsigned char opcode;
- int inlen, outlen, cmdlen;
- int needed, buf_needed;
- int result;
-
- if (!buffer)
- return -EINVAL;
-
-
- /*
- * Verify that we can read at least this much.
- */
- result = verify_area(VERIFY_READ, buffer, 2*sizeof(long) + 1);
- if (result) return result;
-
- /*
- * The structure that we are passed should look like:
- *
- * struct sdata{
- * int inlen;
- * int outlen;
- * char cmd[]; # However many bytes are used for cmd.
- * char data[];
- */
- inlen = get_user((unsigned int *) buffer);
- outlen = get_user( ((unsigned int *) buffer) + 1);
-
- /*
- * We do not transfer more than MAX_BUF with this interface.
- * If the user needs to transfer more data than this, they
- * should use scsi_generics instead.
- */
- if( inlen > MAX_BUF ) inlen = MAX_BUF;
- if( outlen > MAX_BUF ) outlen = MAX_BUF;
-
- cmd_in = (char *) ( ((int *)buffer) + 2);
- opcode = get_user(cmd_in);
-
- needed = buf_needed = (inlen > outlen ? inlen : outlen);
- if(buf_needed){
- buf_needed = (buf_needed + 511) & ~511;
- if (buf_needed > MAX_BUF) buf_needed = MAX_BUF;
- buf = (char *) scsi_malloc(buf_needed);
- if (!buf) return -ENOMEM;
- memset(buf, 0, buf_needed);
- } else
- buf = NULL;
-
- /*
- * Obtain the command from the user's address space.
- */
- cmdlen = COMMAND_SIZE(opcode);
-
- result = verify_area(VERIFY_READ, cmd_in,
- cmdlen + inlen > MAX_BUF ? MAX_BUF : inlen);
- if (result) return result;
-
- memcpy_fromfs ((void *) cmd, cmd_in, cmdlen);
-
- /*
- * Obtain the data to be sent to the device (if any).
- */
- memcpy_fromfs ((void *) buf,
- (void *) (cmd_in + cmdlen),
- inlen);
-
- /*
- * Set the lun field to the correct value.
- */
- cmd[1] = ( cmd[1] & 0x1f ) | (dev->lun << 5);
-
-#ifndef DEBUG_NO_CMD
-
- SCpnt = allocate_device(NULL, dev, 1);
-
- {
- struct semaphore sem = MUTEX_LOCKED;
- SCpnt->request.sem = &sem;
- scsi_do_cmd(SCpnt, cmd, buf, needed, scsi_ioctl_done, MAX_TIMEOUT,
- MAX_RETRIES);
- down(&sem);
- }
-
- /*
- * If there was an error condition, pass the info back to the user.
- */
- if(SCpnt->result) {
- result = verify_area(VERIFY_WRITE,
- cmd_in,
- sizeof(SCpnt->sense_buffer));
- if (result) return result;
- memcpy_tofs((void *) cmd_in,
- SCpnt->sense_buffer,
- sizeof(SCpnt->sense_buffer));
- } else {
- result = verify_area(VERIFY_WRITE, cmd_in, outlen);
- if (result) return result;
- memcpy_tofs ((void *) cmd_in, buf, outlen);
- }
- result = SCpnt->result;
-
- SCpnt->request.rq_status = RQ_INACTIVE;
-
- if (buf) scsi_free(buf, buf_needed);
-
- if(SCpnt->device->scsi_request_fn)
- (*SCpnt->device->scsi_request_fn)();
-
- wake_up(&SCpnt->device->device_wait);
- return result;
-#else
- {
- int i;
- printk("scsi_ioctl : device %d. command = ", dev->id);
- for (i = 0; i < 12; ++i)
- printk("%02x ", cmd[i]);
- printk("\nbuffer =");
- for (i = 0; i < 20; ++i)
- printk("%02x ", buf[i]);
- printk("\n");
- printk("inlen = %d, outlen = %d, cmdlen = %d\n",
- inlen, outlen, cmdlen);
- printk("buffer = %d, cmd_in = %d\n", buffer, cmd_in);
- }
- return 0;
-#endif
-}
-
-/*
- * the scsi_ioctl() function differs from most ioctls in that it does
- * not take a major/minor number as the dev filed. Rather, it takes
- * a pointer to a scsi_devices[] element, a structure.
- */
-int scsi_ioctl (Scsi_Device *dev, int cmd, void *arg)
-{
- int result;
- char scsi_cmd[12];
-
- /* No idea how this happens.... */
- if (!dev) return -ENXIO;
-
- switch (cmd) {
- case SCSI_IOCTL_GET_IDLUN:
- result = verify_area(VERIFY_WRITE, (void *) arg, 2*sizeof(long));
- if (result) return result;
-
- put_user(dev->id
- + (dev->lun << 8)
- + (dev->channel << 16)
- + ((dev->host->hostt->proc_dir->low_ino & 0xff) << 24),
- (unsigned long *) arg);
- put_user( dev->host->unique_id, (unsigned long *) arg+1);
- return 0;
- case SCSI_IOCTL_TAGGED_ENABLE:
- if(!suser()) return -EACCES;
- if(!dev->tagged_supported) return -EINVAL;
- dev->tagged_queue = 1;
- dev->current_tag = 1;
- break;
- case SCSI_IOCTL_TAGGED_DISABLE:
- if(!suser()) return -EACCES;
- if(!dev->tagged_supported) return -EINVAL;
- dev->tagged_queue = 0;
- dev->current_tag = 0;
- break;
- case SCSI_IOCTL_PROBE_HOST:
- return ioctl_probe(dev->host, arg);
- case SCSI_IOCTL_SEND_COMMAND:
- if(!suser()) return -EACCES;
- return ioctl_command((Scsi_Device *) dev, arg);
- case SCSI_IOCTL_DOORLOCK:
- if (!dev->removable || !dev->lockable) return 0;
- scsi_cmd[0] = ALLOW_MEDIUM_REMOVAL;
- scsi_cmd[1] = dev->lun << 5;
- scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[5] = 0;
- scsi_cmd[4] = SCSI_REMOVAL_PREVENT;
- return ioctl_internal_command((Scsi_Device *) dev, scsi_cmd);
- break;
- case SCSI_IOCTL_DOORUNLOCK:
- if (!dev->removable || !dev->lockable) return 0;
- scsi_cmd[0] = ALLOW_MEDIUM_REMOVAL;
- scsi_cmd[1] = dev->lun << 5;
- scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[5] = 0;
- scsi_cmd[4] = SCSI_REMOVAL_ALLOW;
- return ioctl_internal_command((Scsi_Device *) dev, scsi_cmd);
- case SCSI_IOCTL_TEST_UNIT_READY:
- scsi_cmd[0] = TEST_UNIT_READY;
- scsi_cmd[1] = dev->lun << 5;
- scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[5] = 0;
- scsi_cmd[4] = 0;
- return ioctl_internal_command((Scsi_Device *) dev, scsi_cmd);
- break;
- default :
- return -EINVAL;
- }
- return -EINVAL;
-}
-
-/*
- * Just like scsi_ioctl, only callable from kernel space with no
- * fs segment fiddling.
- */
-
-int kernel_scsi_ioctl (Scsi_Device *dev, int cmd, void *arg) {
- unsigned long oldfs;
- int tmp;
- oldfs = get_fs();
- set_fs(get_ds());
- tmp = scsi_ioctl (dev, cmd, arg);
- set_fs(oldfs);
- return tmp;
-}
-
-/*
- * Overrides for Emacs so that we almost follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 4
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * c-continued-statement-offset: 4
- * c-continued-brace-offset: 0
- * indent-tabs-mode: nil
- * tab-width: 8
- * End:
- */
diff --git a/i386/i386at/gpl/linux/scsi/scsi_ioctl.h b/i386/i386at/gpl/linux/scsi/scsi_ioctl.h
deleted file mode 100644
index a42fed00..00000000
--- a/i386/i386at/gpl/linux/scsi/scsi_ioctl.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef _SCSI_IOCTL_H
-#define _SCSI_IOCTL_H
-
-#define SCSI_IOCTL_SEND_COMMAND 1
-#define SCSI_IOCTL_TEST_UNIT_READY 2
-#define SCSI_IOCTL_BENCHMARK_COMMAND 3
-#define SCSI_IOCTL_SYNC 4 /* Request synchronous parameters */
-/* The door lock/unlock constants are compatible with Sun constants for
- the cdrom */
-#define SCSI_IOCTL_DOORLOCK 0x5380 /* lock the eject mechanism */
-#define SCSI_IOCTL_DOORUNLOCK 0x5381 /* unlock the mechanism */
-
-#define SCSI_REMOVAL_PREVENT 1
-#define SCSI_REMOVAL_ALLOW 0
-
-extern int scsi_ioctl (Scsi_Device *dev, int cmd, void *arg);
-extern int kernel_scsi_ioctl (Scsi_Device *dev, int cmd, void *arg);
-
-#endif
-
-
diff --git a/i386/i386at/gpl/linux/scsi/scsi_proc.c b/i386/i386at/gpl/linux/scsi/scsi_proc.c
deleted file mode 100644
index 6650cec9..00000000
--- a/i386/i386at/gpl/linux/scsi/scsi_proc.c
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * linux/drivers/scsi/scsi_proc.c
- *
- * The functions in this file provide an interface between
- * the PROC file system and the SCSI device drivers
- * It is mainly used for debugging, statistics and to pass
- * information directly to the lowlevel driver.
- *
- * (c) 1995 Michael Neuffer neuffer@goofy.zdv.uni-mainz.de
- * Version: 0.99.8 last change: 95/09/13
- *
- * generic command parser provided by:
- * Andreas Heilwagen <crashcar@informatik.uni-koblenz.de>
- */
-
-/*
- * Don't import our own symbols, as this would severely mess up our
- * symbol tables.
- */
-#define _SCSI_SYMS_VER_
-#define __NO_VERSION__
-#include <linux/module.h>
-
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/malloc.h>
-#include <linux/proc_fs.h>
-#include <linux/errno.h>
-#include <linux/stat.h>
-#include <linux/blk.h>
-#include "scsi.h"
-#include "hosts.h"
-
-#ifndef TRUE
-#define TRUE 1
-#define FALSE 0
-#endif
-
-extern int scsi_proc_info(char *, char **, off_t, int, int, int);
-
-struct scsi_dir {
- struct proc_dir_entry entry;
- char name[4];
-};
-
-
-/* generic_proc_info
- * Used if the driver currently has no own support for /proc/scsi
- */
-int generic_proc_info(char *buffer, char **start, off_t offset,
- int length, int inode, int inout)
-{
- int len, pos, begin;
-
- if(inout == TRUE)
- return(-ENOSYS); /* This is a no-op */
-
- begin = 0;
- pos = len = sprintf(buffer,
- "The driver does not yet support the proc-fs\n");
- if(pos < offset) {
- len = 0;
- begin = pos;
- }
-
- *start = buffer + (offset - begin); /* Start of wanted data */
- len -= (offset - begin);
- if(len > length)
- len = length;
-
- return(len);
-}
-
-/* dispatch_scsi_info is the central dispatcher
- * It is the interface between the proc-fs and the SCSI subsystem code
- */
-extern int dispatch_scsi_info(int ino, char *buffer, char **start,
- off_t offset, int length, int func)
-{
- struct Scsi_Host *hpnt = scsi_hostlist;
-
- if(ino == PROC_SCSI_SCSI) {
- /*
- * This is for the scsi core, rather than any specific
- * lowlevel driver.
- */
- return(scsi_proc_info(buffer, start, offset, length, 0, func));
- }
-
- while(hpnt) {
- if (ino == (hpnt->host_no + PROC_SCSI_FILE)) {
- if(hpnt->hostt->proc_info == NULL)
- return generic_proc_info(buffer, start, offset, length,
- hpnt->host_no, func);
- else
- return(hpnt->hostt->proc_info(buffer, start, offset,
- length, hpnt->host_no, func));
- }
- hpnt = hpnt->next;
- }
- return(-EBADF);
-}
-
-void build_proc_dir_entries(Scsi_Host_Template *tpnt)
-{
- struct Scsi_Host *hpnt;
-
- struct scsi_dir *scsi_hba_dir;
-
- proc_scsi_register(0, tpnt->proc_dir);
-
- hpnt = scsi_hostlist;
- while (hpnt) {
- if (tpnt == hpnt->hostt) {
- scsi_hba_dir = scsi_init_malloc(sizeof(struct scsi_dir), GFP_KERNEL);
- if(scsi_hba_dir == NULL)
- panic("Not enough memory to register SCSI HBA in /proc/scsi !\n");
- memset(scsi_hba_dir, 0, sizeof(struct scsi_dir));
- scsi_hba_dir->entry.low_ino = PROC_SCSI_FILE + hpnt->host_no;
- scsi_hba_dir->entry.namelen = sprintf(scsi_hba_dir->name,"%d",
- hpnt->host_no);
- scsi_hba_dir->entry.name = scsi_hba_dir->name;
- scsi_hba_dir->entry.mode = S_IFREG | S_IRUGO | S_IWUSR;
- proc_scsi_register(tpnt->proc_dir, &scsi_hba_dir->entry);
- }
- hpnt = hpnt->next;
- }
-}
-
-/*
- * parseHandle *parseInit(char *buf, char *cmdList, int cmdNum);
- * gets a pointer to a null terminated data buffer
- * and a list of commands with blanks as delimiter
- * in between.
- * The commands have to be alphanumerically sorted.
- * cmdNum has to contain the number of commands.
- * On success, a pointer to a handle structure
- * is returned, NULL on failure
- *
- * int parseOpt(parseHandle *handle, char **param);
- * processes the next parameter. On success, the
- * index of the appropriate command in the cmdList
- * is returned, starting with zero.
- * param points to the null terminated parameter string.
- * On failure, -1 is returned.
- *
- * The databuffer buf may only contain pairs of commands
- * options, separated by blanks:
- * <Command> <Parameter> [<Command> <Parameter>]*
- */
-
-typedef struct
-{
- char *buf, /* command buffer */
- *cmdList, /* command list */
- *bufPos, /* actual position */
- **cmdPos, /* cmdList index */
- cmdNum; /* cmd number */
-} parseHandle;
-
-
-inline int parseFree (parseHandle *handle) /* free memory */
-{
- kfree (handle->cmdPos);
- kfree (handle);
-
- return(-1);
-}
-
-
-parseHandle *parseInit(char *buf, char *cmdList, int cmdNum)
-{
- char *ptr; /* temp pointer */
- parseHandle *handle; /* new handle */
-
- if (!buf || !cmdList) /* bad input ? */
- return(NULL);
- if ((handle = (parseHandle*) kmalloc(sizeof(parseHandle), 1)) == 0)
- return(NULL); /* out of memory */
- if ((handle->cmdPos = (char**) kmalloc(sizeof(int), cmdNum)) == 0) {
- kfree(handle);
- return(NULL); /* out of memory */
- }
-
- handle->buf = handle->bufPos = buf; /* init handle */
- handle->cmdList = cmdList;
- handle->cmdNum = cmdNum;
-
- handle->cmdPos[cmdNum = 0] = cmdList;
- for (ptr = cmdList; *ptr; ptr++) { /* scan command string */
- if(*ptr == ' ') { /* and insert zeroes */
- *ptr++ = 0;
- handle->cmdPos[++cmdNum] = ptr++;
- }
- }
- return(handle);
-}
-
-
-int parseOpt(parseHandle *handle, char **param)
-{
- int cmdIndex = 0,
- cmdLen = 0;
- char *startPos;
-
- if (!handle) /* invalid handle */
- return(parseFree(handle));
- /* skip spaces */
- for (; *(handle->bufPos) && *(handle->bufPos) == ' '; handle->bufPos++);
- if (!*(handle->bufPos))
- return(parseFree(handle)); /* end of data */
-
- startPos = handle->bufPos; /* store cmd start */
- for (; handle->cmdPos[cmdIndex][cmdLen] && *(handle->bufPos); handle->bufPos++)
- { /* no string end? */
- for (;;)
- {
- if (*(handle->bufPos) == handle->cmdPos[cmdIndex][cmdLen])
- break; /* char matches ? */
- else
- if (memcmp(startPos, (char*)(handle->cmdPos[++cmdIndex]), cmdLen))
- return(parseFree(handle)); /* unknown command */
-
- if (cmdIndex >= handle->cmdNum)
- return(parseFree(handle)); /* unknown command */
- }
-
- cmdLen++; /* next char */
- }
-
- /* Get param. First skip all blanks, then insert zero after param */
-
- for (; *(handle->bufPos) && *(handle->bufPos) == ' '; handle->bufPos++);
- *param = handle->bufPos;
-
- for (; *(handle->bufPos) && *(handle->bufPos) != ' '; handle->bufPos++);
- *(handle->bufPos++) = 0;
-
- return(cmdIndex);
-}
-
-#define MAX_SCSI_DEVICE_CODE 10
-const char *const scsi_dev_types[MAX_SCSI_DEVICE_CODE] =
-{
- "Direct-Access ",
- "Sequential-Access",
- "Printer ",
- "Processor ",
- "WORM ",
- "CD-ROM ",
- "Scanner ",
- "Optical Device ",
- "Medium Changer ",
- "Communications "
-};
-
-void proc_print_scsidevice(Scsi_Device *scd, char *buffer, int *size, int len)
-{
- int x, y = *size;
-
- y = sprintf(buffer + len,
- "Host: scsi%d Channel: %02d Id: %02d Lun: %02d\n Vendor: ",
- scd->host->host_no, scd->channel, scd->id, scd->lun);
- for (x = 0; x < 8; x++) {
- if (scd->vendor[x] >= 0x20)
- y += sprintf(buffer + len + y, "%c", scd->vendor[x]);
- else
- y += sprintf(buffer + len + y," ");
- }
- y += sprintf(buffer + len + y, " Model: ");
- for (x = 0; x < 16; x++) {
- if (scd->model[x] >= 0x20)
- y += sprintf(buffer + len + y, "%c", scd->model[x]);
- else
- y += sprintf(buffer + len + y, " ");
- }
- y += sprintf(buffer + len + y, " Rev: ");
- for (x = 0; x < 4; x++) {
- if (scd->rev[x] >= 0x20)
- y += sprintf(buffer + len + y, "%c", scd->rev[x]);
- else
- y += sprintf(buffer + len + y, " ");
- }
- y += sprintf(buffer + len + y, "\n");
-
- y += sprintf(buffer + len + y, " Type: %s ",
- scd->type < MAX_SCSI_DEVICE_CODE ?
- scsi_dev_types[(int)scd->type] : "Unknown " );
- y += sprintf(buffer + len + y, " ANSI"
- " SCSI revision: %02x", (scd->scsi_level < 3)?1:2);
- if (scd->scsi_level == 2)
- y += sprintf(buffer + len + y, " CCS\n");
- else
- y += sprintf(buffer + len + y, "\n");
-
- *size = y;
- return;
-}
-
-/*
- * Overrides for Emacs so that we get a uniform tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 4
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * c-continued-statement-offset: 4
- * c-continued-brace-offset: 0
- * indent-tabs-mode: nil
- * tab-width: 8
- * End:
- */
diff --git a/i386/i386at/gpl/linux/scsi/scsicam.c b/i386/i386at/gpl/linux/scsi/scsicam.c
deleted file mode 100644
index e4e4e764..00000000
--- a/i386/i386at/gpl/linux/scsi/scsicam.c
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * scsicam.c - SCSI CAM support functions, use for HDIO_GETGEO, etc.
- *
- * Copyright 1993, 1994 Drew Eckhardt
- * Visionary Computing
- * (Unix and Linux consulting and custom programming)
- * drew@Colorado.EDU
- * +1 (303) 786-7975
- *
- * For more information, please consult the SCSI-CAM draft.
- */
-
-/*
- * Don't import our own symbols, as this would severely mess up our
- * symbol tables.
- */
-#define _SCSI_SYMS_VER_
-#define __NO_VERSION__
-#include <linux/module.h>
-
-#include <linux/fs.h>
-#include <linux/genhd.h>
-#include <linux/kernel.h>
-#include <linux/blk.h>
-#include "scsi.h"
-#include "hosts.h"
-#include "sd.h"
-
-static int partsize(struct buffer_head *bh, unsigned long capacity,
- unsigned int *cyls, unsigned int *hds, unsigned int *secs);
-static int setsize(unsigned long capacity,unsigned int *cyls,unsigned int *hds,
- unsigned int *secs);
-
-/*
- * Function : int scsicam_bios_param (Disk *disk, int dev, int *ip)
- *
- * Purpose : to determine the BIOS mapping used for a drive in a
- * SCSI-CAM system, storing the results in ip as required
- * by the HDIO_GETGEO ioctl().
- *
- * Returns : -1 on failure, 0 on success.
- *
- */
-
-int scsicam_bios_param (Disk *disk, /* SCSI disk */
- kdev_t dev, /* Device major, minor */
- int *ip /* Heads, sectors, cylinders in that order */) {
-
- struct buffer_head *bh;
- int ret_code;
- int size = disk->capacity;
-
- if (!(bh = bread(MKDEV(MAJOR(dev), MINOR(dev)&~0xf), 0, 1024)))
- return -1;
-
-#ifdef DEBUG
- printk ("scsicam_bios_param : trying existing mapping\n");
-#endif
- ret_code = partsize (bh, (unsigned long) size, (unsigned int *) ip + 2,
- (unsigned int *) ip + 0, (unsigned int *) ip + 1);
- brelse (bh);
-
- if (ret_code == -1) {
-#ifdef DEBUG
- printk ("scsicam_bios_param : trying optimal mapping\n");
-#endif
- ret_code = setsize ((unsigned long) size, (unsigned int *) ip + 2,
- (unsigned int *) ip + 0, (unsigned int *) ip + 1);
- }
-
- return ret_code;
-}
-
-/*
- * Function : static int partsize(struct buffer_head *bh, unsigned long
- * capacity,unsigned int *cyls, unsigned int *hds, unsigned int *secs);
- *
- * Purpose : to determine the BIOS mapping used to create the partition
- * table, storing the results in *cyls, *hds, and *secs
- *
- * Returns : -1 on failure, 0 on success.
- *
- */
-
-static int partsize(struct buffer_head *bh, unsigned long capacity,
- unsigned int *cyls, unsigned int *hds, unsigned int *secs) {
- struct partition *p, *largest = NULL;
- int i, largest_cyl;
- int cyl, ext_cyl, end_head, end_cyl, end_sector;
- unsigned int logical_end, physical_end, ext_physical_end;
-
-
- if (*(unsigned short *) (bh->b_data+510) == 0xAA55) {
- for (largest_cyl = -1, p = (struct partition *)
- (0x1BE + bh->b_data), i = 0; i < 4; ++i, ++p) {
- if (!p->sys_ind)
- continue;
-#ifdef DEBUG
- printk ("scsicam_bios_param : partition %d has system \n",
- i);
-#endif
- cyl = p->cyl + ((p->sector & 0xc0) << 2);
- if (cyl > largest_cyl) {
- largest_cyl = cyl;
- largest = p;
- }
- }
- }
-
- if (largest) {
- end_cyl = largest->end_cyl + ((largest->end_sector & 0xc0) << 2);
- end_head = largest->end_head;
- end_sector = largest->end_sector & 0x3f;
-
-#ifdef DEBUG
- printk ("scsicam_bios_param : end at h = %d, c = %d, s = %d\n",
- end_head, end_cyl, end_sector);
-#endif
-
- physical_end = end_cyl * (end_head + 1) * end_sector +
- end_head * end_sector + end_sector;
-
- /* This is the actual _sector_ number at the end */
- logical_end = largest->start_sect + largest->nr_sects;
-
- /* This is for >1023 cylinders */
- ext_cyl= (logical_end-(end_head * end_sector + end_sector))
- /(end_head + 1) / end_sector;
- ext_physical_end = ext_cyl * (end_head + 1) * end_sector +
- end_head * end_sector + end_sector;
-
-#ifdef DEBUG
- printk("scsicam_bios_param : logical_end=%d physical_end=%d ext_physical_end=%d ext_cyl=%d\n"
- ,logical_end,physical_end,ext_physical_end,ext_cyl);
-#endif
-
- if ((logical_end == physical_end) ||
- (end_cyl==1023 && ext_physical_end==logical_end)) {
- *secs = end_sector;
- *hds = end_head + 1;
- *cyls = capacity / ((end_head + 1) * end_sector);
- return 0;
- }
-
-#ifdef DEBUG
- printk ("scsicam_bios_param : logical (%u) != physical (%u)\n",
- logical_end, physical_end);
-#endif
- }
- return -1;
-}
-
-/*
- * Function : static int setsize(unsigned long capacity,unsigned int *cyls,
- * unsigned int *hds, unsigned int *secs);
- *
- * Purpose : to determine a near-optimal int 0x13 mapping for a
- * SCSI disk in terms of lost space of size capacity, storing
- * the results in *cyls, *hds, and *secs.
- *
- * Returns : -1 on failure, 0 on success.
- *
- * Extracted from
- *
- * WORKING X3T9.2
- * DRAFT 792D
- *
- *
- * Revision 6
- * 10-MAR-94
- * Information technology -
- * SCSI-2 Common access method
- * transport and SCSI interface module
- *
- * ANNEX A :
- *
- * setsize() converts a read capacity value to int 13h
- * head-cylinder-sector requirements. It minimizes the value for
- * number of heads and maximizes the number of cylinders. This
- * will support rather large disks before the number of heads
- * will not fit in 4 bits (or 6 bits). This algorithm also
- * minimizes the number of sectors that will be unused at the end
- * of the disk while allowing for very large disks to be
- * accommodated. This algorithm does not use physical geometry.
- */
-
-static int setsize(unsigned long capacity,unsigned int *cyls,unsigned int *hds,
- unsigned int *secs) {
- unsigned int rv = 0;
- unsigned long heads, sectors, cylinders, temp;
-
- cylinders = 1024L; /* Set number of cylinders to max */
- sectors = 62L; /* Maximize sectors per track */
-
- temp = cylinders * sectors; /* Compute divisor for heads */
- heads = capacity / temp; /* Compute value for number of heads */
- if (capacity % temp) { /* If no remainder, done! */
- heads++; /* Else, increment number of heads */
- temp = cylinders * heads; /* Compute divisor for sectors */
- sectors = capacity / temp; /* Compute value for sectors per
- track */
- if (capacity % temp) { /* If no remainder, done! */
- sectors++; /* Else, increment number of sectors */
- temp = heads * sectors; /* Compute divisor for cylinders */
- cylinders = capacity / temp;/* Compute number of cylinders */
- }
- }
- if (cylinders == 0) rv=(unsigned)-1;/* Give error if 0 cylinders */
-
- *cyls = (unsigned int) cylinders; /* Stuff return values */
- *secs = (unsigned int) sectors;
- *hds = (unsigned int) heads;
- return(rv);
-}
diff --git a/i386/i386at/gpl/linux/scsi/sd.c b/i386/i386at/gpl/linux/scsi/sd.c
deleted file mode 100644
index 47bf2263..00000000
--- a/i386/i386at/gpl/linux/scsi/sd.c
+++ /dev/null
@@ -1,1543 +0,0 @@
-/*
- * sd.c Copyright (C) 1992 Drew Eckhardt
- * Copyright (C) 1993, 1994, 1995 Eric Youngdale
- *
- * Linux scsi disk driver
- * Initial versions: Drew Eckhardt
- * Subsequent revisions: Eric Youngdale
- *
- * <drew@colorado.edu>
- *
- * Modified by Eric Youngdale ericy@cais.com to
- * add scatter-gather, multiple outstanding request, and other
- * enhancements.
- *
- * Modified by Eric Youngdale eric@aib.com to support loadable
- * low-level scsi drivers.
- */
-
-#include <linux/module.h>
-#ifdef MODULE
-/*
- * This is a variable in scsi.c that is set when we are processing something
- * after boot time. By definition, this is true when we are a loadable module
- * ourselves.
- */
-#define MODULE_FLAG 1
-#else
-#define MODULE_FLAG scsi_loadable_module_flag
-#endif /* MODULE */
-
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <asm/system.h>
-
-#define MAJOR_NR SCSI_DISK_MAJOR
-#include <linux/blk.h>
-#include "scsi.h"
-#include "hosts.h"
-#include "sd.h"
-#include "scsi_ioctl.h"
-#include "constants.h"
-
-#include <linux/genhd.h>
-
-/*
- * static const char RCSid[] = "$Header:";
- */
-
-#define MAX_RETRIES 5
-
-/*
- * Time out in seconds for disks and Magneto-opticals (which are slower).
- */
-
-#define SD_TIMEOUT (7 * HZ)
-#define SD_MOD_TIMEOUT (8 * HZ)
-
-#define CLUSTERABLE_DEVICE(SC) (SC->host->use_clustering && \
- SC->device->type != TYPE_MOD)
-
-struct hd_struct * sd;
-
-Scsi_Disk * rscsi_disks = NULL;
-static int * sd_sizes;
-static int * sd_blocksizes;
-static int * sd_hardsizes; /* Hardware sector size */
-
-extern int sd_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
-
-static int check_scsidisk_media_change(kdev_t);
-static int fop_revalidate_scsidisk(kdev_t);
-
-static sd_init_onedisk(int);
-
-static void requeue_sd_request (Scsi_Cmnd * SCpnt);
-
-static int sd_init(void);
-static void sd_finish(void);
-static int sd_attach(Scsi_Device *);
-static int sd_detect(Scsi_Device *);
-static void sd_detach(Scsi_Device *);
-
-struct Scsi_Device_Template sd_template =
-{ NULL, "disk", "sd", NULL, TYPE_DISK,
- SCSI_DISK_MAJOR, 0, 0, 0, 1,
- sd_detect, sd_init,
- sd_finish, sd_attach, sd_detach
-};
-
-static int sd_open(struct inode * inode, struct file * filp)
-{
- int target;
- target = DEVICE_NR(inode->i_rdev);
-
- if(target >= sd_template.dev_max || !rscsi_disks[target].device)
- return -ENXIO; /* No such device */
-
- /*
- * Make sure that only one process can do a check_change_disk at one time.
- * This is also used to lock out further access when the partition table
- * is being re-read.
- */
-
- while (rscsi_disks[target].device->busy)
- barrier();
- if(rscsi_disks[target].device->removable) {
- check_disk_change(inode->i_rdev);
-
- /*
- * If the drive is empty, just let the open fail.
- */
- if ( !rscsi_disks[target].ready ) {
- return -ENXIO;
- }
-
- /*
- * Similarily, if the device has the write protect tab set,
- * have the open fail if the user expects to be able to write
- * to the thing.
- */
- if ( (rscsi_disks[target].write_prot) && (filp->f_mode & 2) ) {
- return -EROFS;
- }
-
- if(!rscsi_disks[target].device->access_count)
- sd_ioctl(inode, NULL, SCSI_IOCTL_DOORLOCK, 0);
- };
-
- /*
- * See if we are requesting a non-existent partition. Do this
- * after checking for disk change.
- */
- if(sd_sizes[MINOR(inode->i_rdev)] == 0)
- return -ENXIO;
-
- rscsi_disks[target].device->access_count++;
- if (rscsi_disks[target].device->host->hostt->usage_count)
- (*rscsi_disks[target].device->host->hostt->usage_count)++;
- if(sd_template.usage_count) (*sd_template.usage_count)++;
- return 0;
-}
-
-static void sd_release(struct inode * inode, struct file * file)
-{
- int target;
- sync_dev(inode->i_rdev);
-
- target = DEVICE_NR(inode->i_rdev);
-
- rscsi_disks[target].device->access_count--;
- if (rscsi_disks[target].device->host->hostt->usage_count)
- (*rscsi_disks[target].device->host->hostt->usage_count)--;
- if(sd_template.usage_count) (*sd_template.usage_count)--;
-
- if(rscsi_disks[target].device->removable) {
- if(!rscsi_disks[target].device->access_count)
- sd_ioctl(inode, NULL, SCSI_IOCTL_DOORUNLOCK, 0);
- }
-}
-
-static void sd_geninit(struct gendisk *);
-
-static struct file_operations sd_fops = {
- NULL, /* lseek - default */
- block_read, /* read - general block-dev read */
- block_write, /* write - general block-dev write */
- NULL, /* readdir - bad */
- NULL, /* select */
- sd_ioctl, /* ioctl */
- NULL, /* mmap */
- sd_open, /* open code */
- sd_release, /* release */
- block_fsync, /* fsync */
- NULL, /* fasync */
- check_scsidisk_media_change, /* Disk change */
- fop_revalidate_scsidisk /* revalidate */
-};
-
-static struct gendisk sd_gendisk = {
- MAJOR_NR, /* Major number */
- "sd", /* Major name */
- 4, /* Bits to shift to get real from partition */
- 1 << 4, /* Number of partitions per real */
- 0, /* maximum number of real */
- sd_geninit, /* init function */
- NULL, /* hd struct */
- NULL, /* block sizes */
- 0, /* number */
- NULL, /* internal */
- NULL /* next */
-};
-
-static void sd_geninit (struct gendisk *ignored)
-{
- int i;
-
- for (i = 0; i < sd_template.dev_max; ++i)
- if(rscsi_disks[i].device)
- sd[i << 4].nr_sects = rscsi_disks[i].capacity;
-#if 0
- /* No longer needed - we keep track of this as we attach/detach */
- sd_gendisk.nr_real = sd_template.dev_max;
-#endif
-}
-
-/*
- * rw_intr is the interrupt routine for the device driver. It will
- * be notified on the end of a SCSI read / write, and
- * will take on of several actions based on success or failure.
- */
-
-static void rw_intr (Scsi_Cmnd *SCpnt)
-{
- int result = SCpnt->result;
- int this_count = SCpnt->bufflen >> 9;
-
-#ifdef DEBUG
- printk("sd%c : rw_intr(%d, %d)\n", 'a' + MINOR(SCpnt->request.rq_dev),
- SCpnt->host->host_no, result);
-#endif
-
- /*
- * First case : we assume that the command succeeded. One of two things
- * will happen here. Either we will be finished, or there will be more
- * sectors that we were unable to read last time.
- */
-
- if (!result) {
-
-#ifdef DEBUG
- printk("sd%c : %d sectors remain.\n", 'a' + MINOR(SCpnt->request.rq_dev),
- SCpnt->request.nr_sectors);
- printk("use_sg is %d\n ",SCpnt->use_sg);
-#endif
- if (SCpnt->use_sg) {
- struct scatterlist * sgpnt;
- int i;
- sgpnt = (struct scatterlist *) SCpnt->buffer;
- for(i=0; i<SCpnt->use_sg; i++) {
-#ifdef DEBUG
- printk(":%x %x %d\n",sgpnt[i].alt_address, sgpnt[i].address,
- sgpnt[i].length);
-#endif
- if (sgpnt[i].alt_address) {
- if (SCpnt->request.cmd == READ)
- memcpy(sgpnt[i].alt_address, sgpnt[i].address,
- sgpnt[i].length);
- scsi_free(sgpnt[i].address, sgpnt[i].length);
- };
- };
-
- /* Free list of scatter-gather pointers */
- scsi_free(SCpnt->buffer, SCpnt->sglist_len);
- } else {
- if (SCpnt->buffer != SCpnt->request.buffer) {
-#ifdef DEBUG
- printk("nosg: %x %x %d\n",SCpnt->request.buffer, SCpnt->buffer,
- SCpnt->bufflen);
-#endif
- if (SCpnt->request.cmd == READ)
- memcpy(SCpnt->request.buffer, SCpnt->buffer,
- SCpnt->bufflen);
- scsi_free(SCpnt->buffer, SCpnt->bufflen);
- };
- };
- /*
- * If multiple sectors are requested in one buffer, then
- * they will have been finished off by the first command.
- * If not, then we have a multi-buffer command.
- */
- if (SCpnt->request.nr_sectors > this_count)
- {
- SCpnt->request.errors = 0;
-
- if (!SCpnt->request.bh)
- {
-#ifdef DEBUG
- printk("sd%c : handling page request, no buffer\n",
- 'a' + MINOR(SCpnt->request.rq_dev));
-#endif
- /*
- * The SCpnt->request.nr_sectors field is always done in
- * 512 byte sectors, even if this really isn't the case.
- */
- panic("sd.c: linked page request (%lx %x)",
- SCpnt->request.sector, this_count);
- }
- }
- SCpnt = end_scsi_request(SCpnt, 1, this_count);
- requeue_sd_request(SCpnt);
- return;
- }
-
- /* Free up any indirection buffers we allocated for DMA purposes. */
- if (SCpnt->use_sg) {
- struct scatterlist * sgpnt;
- int i;
- sgpnt = (struct scatterlist *) SCpnt->buffer;
- for(i=0; i<SCpnt->use_sg; i++) {
-#ifdef DEBUG
- printk("err: %x %x %d\n",SCpnt->request.buffer, SCpnt->buffer,
- SCpnt->bufflen);
-#endif
- if (sgpnt[i].alt_address) {
- scsi_free(sgpnt[i].address, sgpnt[i].length);
- };
- };
- scsi_free(SCpnt->buffer, SCpnt->sglist_len); /* Free list of scatter-gather pointers */
- } else {
-#ifdef DEBUG
- printk("nosgerr: %x %x %d\n",SCpnt->request.buffer, SCpnt->buffer,
- SCpnt->bufflen);
-#endif
- if (SCpnt->buffer != SCpnt->request.buffer)
- scsi_free(SCpnt->buffer, SCpnt->bufflen);
- };
-
- /*
- * Now, if we were good little boys and girls, Santa left us a request
- * sense buffer. We can extract information from this, so we
- * can choose a block to remap, etc.
- */
-
- if (driver_byte(result) != 0) {
- if (suggestion(result) == SUGGEST_REMAP) {
-#ifdef REMAP
- /*
- * Not yet implemented. A read will fail after being remapped,
- * a write will call the strategy routine again.
- */
- if rscsi_disks[DEVICE_NR(SCpnt->request.rq_dev)].remap
- {
- result = 0;
- }
- else
-#endif
- }
-
- if ((SCpnt->sense_buffer[0] & 0x7f) == 0x70) {
- if ((SCpnt->sense_buffer[2] & 0xf) == UNIT_ATTENTION) {
- if(rscsi_disks[DEVICE_NR(SCpnt->request.rq_dev)].device->removable) {
- /* detected disc change. set a bit and quietly refuse
- * further access.
- */
- rscsi_disks[DEVICE_NR(SCpnt->request.rq_dev)].device->changed = 1;
- SCpnt = end_scsi_request(SCpnt, 0, this_count);
- requeue_sd_request(SCpnt);
- return;
- }
- else
- {
- /*
- * Must have been a power glitch, or a bus reset.
- * Could not have been a media change, so we just retry
- * the request and see what happens.
- */
- requeue_sd_request(SCpnt);
- return;
- }
- }
- }
-
-
- /* If we had an ILLEGAL REQUEST returned, then we may have
- * performed an unsupported command. The only thing this should be
- * would be a ten byte read where only a six byte read was supported.
- * Also, on a system where READ CAPACITY failed, we have have read
- * past the end of the disk.
- */
-
- if (SCpnt->sense_buffer[2] == ILLEGAL_REQUEST) {
- if (rscsi_disks[DEVICE_NR(SCpnt->request.rq_dev)].ten) {
- rscsi_disks[DEVICE_NR(SCpnt->request.rq_dev)].ten = 0;
- requeue_sd_request(SCpnt);
- result = 0;
- } else {
- /* ???? */
- }
- }
- } /* driver byte != 0 */
- if (result) {
- printk("SCSI disk error : host %d channel %d id %d lun %d return code = %x\n",
- rscsi_disks[DEVICE_NR(SCpnt->request.rq_dev)].device->host->host_no,
- rscsi_disks[DEVICE_NR(SCpnt->request.rq_dev)].device->channel,
- rscsi_disks[DEVICE_NR(SCpnt->request.rq_dev)].device->id,
- rscsi_disks[DEVICE_NR(SCpnt->request.rq_dev)].device->lun, result);
-
- if (driver_byte(result) & DRIVER_SENSE)
- print_sense("sd", SCpnt);
- SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.current_nr_sectors);
- requeue_sd_request(SCpnt);
- return;
- }
-}
-
-/*
- * requeue_sd_request() is the request handler function for the sd driver.
- * Its function in life is to take block device requests, and translate
- * them to SCSI commands.
- */
-
-static void do_sd_request (void)
-{
- Scsi_Cmnd * SCpnt = NULL;
- Scsi_Device * SDev;
- struct request * req = NULL;
- unsigned long flags;
- int flag = 0;
-
- save_flags(flags);
- while (1==1){
- cli();
- if (CURRENT != NULL && CURRENT->rq_status == RQ_INACTIVE) {
- restore_flags(flags);
- return;
- };
-
- INIT_SCSI_REQUEST;
- SDev = rscsi_disks[DEVICE_NR(CURRENT->rq_dev)].device;
-
- /*
- * I am not sure where the best place to do this is. We need
- * to hook in a place where we are likely to come if in user
- * space.
- */
- if( SDev->was_reset )
- {
- /*
- * We need to relock the door, but we might
- * be in an interrupt handler. Only do this
- * from user space, since we do not want to
- * sleep from an interrupt.
- */
- if( SDev->removable && !intr_count )
- {
- scsi_ioctl(SDev, SCSI_IOCTL_DOORLOCK, 0);
- }
- SDev->was_reset = 0;
- }
-
- /* We have to be careful here. allocate_device will get a free pointer,
- * but there is no guarantee that it is queueable. In normal usage,
- * we want to call this, because other types of devices may have the
- * host all tied up, and we want to make sure that we have at least
- * one request pending for this type of device. We can also come
- * through here while servicing an interrupt, because of the need to
- * start another command. If we call allocate_device more than once,
- * then the system can wedge if the command is not queueable. The
- * request_queueable function is safe because it checks to make sure
- * that the host is able to take another command before it returns
- * a pointer.
- */
-
- if (flag++ == 0)
- SCpnt = allocate_device(&CURRENT,
- rscsi_disks[DEVICE_NR(CURRENT->rq_dev)].device, 0);
- else SCpnt = NULL;
-
- /*
- * The following restore_flags leads to latency problems. FIXME.
- * Using a "sti()" gets rid of the latency problems but causes
- * race conditions and crashes.
- */
- restore_flags(flags);
-
- /* This is a performance enhancement. We dig down into the request
- * list and try and find a queueable request (i.e. device not busy,
- * and host able to accept another command. If we find one, then we
- * queue it. This can make a big difference on systems with more than
- * one disk drive. We want to have the interrupts off when monkeying
- * with the request list, because otherwise the kernel might try and
- * slip in a request in between somewhere.
- */
-
- if (!SCpnt && sd_template.nr_dev > 1){
- struct request *req1;
- req1 = NULL;
- cli();
- req = CURRENT;
- while(req){
- SCpnt = request_queueable(req, rscsi_disks[DEVICE_NR(req->rq_dev)].device);
- if(SCpnt) break;
- req1 = req;
- req = req->next;
- };
- if (SCpnt && req->rq_status == RQ_INACTIVE) {
- if (req == CURRENT)
- CURRENT = CURRENT->next;
- else
- req1->next = req->next;
- };
- restore_flags(flags);
- };
-
- if (!SCpnt) return; /* Could not find anything to do */
-
- /* Queue command */
- requeue_sd_request(SCpnt);
- }; /* While */
-}
-
-static void requeue_sd_request (Scsi_Cmnd * SCpnt)
-{
- int dev, devm, block, this_count;
- unsigned char cmd[10];
- int bounce_size, contiguous;
- int max_sg;
- struct buffer_head * bh, *bhp;
- char * buff, *bounce_buffer;
-
- repeat:
-
- if(!SCpnt || SCpnt->request.rq_status == RQ_INACTIVE) {
- do_sd_request();
- return;
- }
-
- devm = MINOR(SCpnt->request.rq_dev);
- dev = DEVICE_NR(SCpnt->request.rq_dev);
-
- block = SCpnt->request.sector;
- this_count = 0;
-
-#ifdef DEBUG
- printk("Doing sd request, dev = %d, block = %d\n", devm, block);
-#endif
-
- if (devm >= (sd_template.dev_max << 4) ||
- !rscsi_disks[dev].device ||
- block + SCpnt->request.nr_sectors > sd[devm].nr_sects)
- {
- SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
- goto repeat;
- }
-
- block += sd[devm].start_sect;
-
- if (rscsi_disks[dev].device->changed)
- {
- /*
- * quietly refuse to do anything to a changed disc until the changed
- * bit has been reset
- */
- /* printk("SCSI disk has been changed. Prohibiting further I/O.\n"); */
- SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
- goto repeat;
- }
-
-#ifdef DEBUG
- printk("sd%c : real dev = /dev/sd%c, block = %d\n",
- 'a' + devm, dev, block);
-#endif
-
- /*
- * If we have a 1K hardware sectorsize, prevent access to single
- * 512 byte sectors. In theory we could handle this - in fact
- * the scsi cdrom driver must be able to handle this because
- * we typically use 1K blocksizes, and cdroms typically have
- * 2K hardware sectorsizes. Of course, things are simpler
- * with the cdrom, since it is read-only. For performance
- * reasons, the filesystems should be able to handle this
- * and not force the scsi disk driver to use bounce buffers
- * for this.
- */
- if (rscsi_disks[dev].sector_size == 1024)
- if((block & 1) || (SCpnt->request.nr_sectors & 1)) {
- printk("sd.c:Bad block number requested");
- SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
- goto repeat;
- }
-
- switch (SCpnt->request.cmd)
- {
- case WRITE :
- if (!rscsi_disks[dev].device->writeable)
- {
- SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
- goto repeat;
- }
- cmd[0] = WRITE_6;
- break;
- case READ :
- cmd[0] = READ_6;
- break;
- default :
- panic ("Unknown sd command %d\n", SCpnt->request.cmd);
- }
-
- SCpnt->this_count = 0;
-
- /* If the host adapter can deal with very large scatter-gather
- * requests, it is a waste of time to cluster
- */
- contiguous = (!CLUSTERABLE_DEVICE(SCpnt) ? 0 :1);
- bounce_buffer = NULL;
- bounce_size = (SCpnt->request.nr_sectors << 9);
-
- /* First see if we need a bounce buffer for this request. If we do, make
- * sure that we can allocate a buffer. Do not waste space by allocating
- * a bounce buffer if we are straddling the 16Mb line
- */
- if (contiguous && SCpnt->request.bh &&
- ((long) SCpnt->request.bh->b_data)
- + (SCpnt->request.nr_sectors << 9) - 1 > ISA_DMA_THRESHOLD
- && SCpnt->host->unchecked_isa_dma) {
- if(((long) SCpnt->request.bh->b_data) > ISA_DMA_THRESHOLD)
- bounce_buffer = (char *) scsi_malloc(bounce_size);
- if(!bounce_buffer) contiguous = 0;
- };
-
- if(contiguous && SCpnt->request.bh && SCpnt->request.bh->b_reqnext)
- for(bh = SCpnt->request.bh, bhp = bh->b_reqnext; bhp; bh = bhp,
- bhp = bhp->b_reqnext) {
- if(!CONTIGUOUS_BUFFERS(bh,bhp)) {
- if(bounce_buffer) scsi_free(bounce_buffer, bounce_size);
- contiguous = 0;
- break;
- }
- };
- if (!SCpnt->request.bh || contiguous) {
-
- /* case of page request (i.e. raw device), or unlinked buffer */
- this_count = SCpnt->request.nr_sectors;
- buff = SCpnt->request.buffer;
- SCpnt->use_sg = 0;
-
- } else if (SCpnt->host->sg_tablesize == 0 ||
- (need_isa_buffer && dma_free_sectors <= 10)) {
-
- /* Case of host adapter that cannot scatter-gather. We also
- * come here if we are running low on DMA buffer memory. We set
- * a threshold higher than that we would need for this request so
- * we leave room for other requests. Even though we would not need
- * it all, we need to be conservative, because if we run low enough
- * we have no choice but to panic.
- */
- if (SCpnt->host->sg_tablesize != 0 &&
- need_isa_buffer &&
- dma_free_sectors <= 10)
- printk("Warning: SCSI DMA buffer space running low. Using non scatter-gather I/O.\n");
-
- this_count = SCpnt->request.current_nr_sectors;
- buff = SCpnt->request.buffer;
- SCpnt->use_sg = 0;
-
- } else {
-
- /* Scatter-gather capable host adapter */
- struct scatterlist * sgpnt;
- int count, this_count_max;
- int counted;
-
- bh = SCpnt->request.bh;
- this_count = 0;
- this_count_max = (rscsi_disks[dev].ten ? 0xffff : 0xff);
- count = 0;
- bhp = NULL;
- while(bh) {
- if ((this_count + (bh->b_size >> 9)) > this_count_max) break;
- if(!bhp || !CONTIGUOUS_BUFFERS(bhp,bh) ||
- !CLUSTERABLE_DEVICE(SCpnt) ||
- (SCpnt->host->unchecked_isa_dma &&
- ((unsigned long) bh->b_data-1) == ISA_DMA_THRESHOLD)) {
- if (count < SCpnt->host->sg_tablesize) count++;
- else break;
- };
- this_count += (bh->b_size >> 9);
- bhp = bh;
- bh = bh->b_reqnext;
- };
-#if 0
- if(SCpnt->host->unchecked_isa_dma &&
- ((unsigned int) SCpnt->request.bh->b_data-1) == ISA_DMA_THRESHOLD) count--;
-#endif
- SCpnt->use_sg = count; /* Number of chains */
- count = 512;/* scsi_malloc can only allocate in chunks of 512 bytes */
- while( count < (SCpnt->use_sg * sizeof(struct scatterlist)))
- count = count << 1;
- SCpnt->sglist_len = count;
- max_sg = count / sizeof(struct scatterlist);
- if(SCpnt->host->sg_tablesize < max_sg)
- max_sg = SCpnt->host->sg_tablesize;
- sgpnt = (struct scatterlist * ) scsi_malloc(count);
- if (!sgpnt) {
- printk("Warning - running *really* short on DMA buffers\n");
- SCpnt->use_sg = 0; /* No memory left - bail out */
- this_count = SCpnt->request.current_nr_sectors;
- buff = SCpnt->request.buffer;
- } else {
- memset(sgpnt, 0, count); /* Zero so it is easy to fill, but only
- * if memory is available
- */
- buff = (char *) sgpnt;
- counted = 0;
- for(count = 0, bh = SCpnt->request.bh, bhp = bh->b_reqnext;
- count < SCpnt->use_sg && bh;
- count++, bh = bhp) {
-
- bhp = bh->b_reqnext;
-
- if(!sgpnt[count].address) sgpnt[count].address = bh->b_data;
- sgpnt[count].length += bh->b_size;
- counted += bh->b_size >> 9;
-
- if (((long) sgpnt[count].address) + sgpnt[count].length - 1 >
- ISA_DMA_THRESHOLD && (SCpnt->host->unchecked_isa_dma) &&
- !sgpnt[count].alt_address) {
- sgpnt[count].alt_address = sgpnt[count].address;
- /* We try and avoid exhausting the DMA pool, since it is
- * easier to control usage here. In other places we might
- * have a more pressing need, and we would be screwed if
- * we ran out */
- if(dma_free_sectors < (sgpnt[count].length >> 9) + 10) {
- sgpnt[count].address = NULL;
- } else {
- sgpnt[count].address =
- (char *) scsi_malloc(sgpnt[count].length);
- };
- /* If we start running low on DMA buffers, we abort the
- * scatter-gather operation, and free all of the memory
- * we have allocated. We want to ensure that all scsi
- * operations are able to do at least a non-scatter/gather
- * operation */
- if(sgpnt[count].address == NULL){ /* Out of dma memory */
-#if 0
- printk("Warning: Running low on SCSI DMA buffers");
- /* Try switching back to a non s-g operation. */
- while(--count >= 0){
- if(sgpnt[count].alt_address)
- scsi_free(sgpnt[count].address,
- sgpnt[count].length);
- };
- this_count = SCpnt->request.current_nr_sectors;
- buff = SCpnt->request.buffer;
- SCpnt->use_sg = 0;
- scsi_free(sgpnt, SCpnt->sglist_len);
-#endif
- SCpnt->use_sg = count;
- this_count = counted -= bh->b_size >> 9;
- break;
- };
-
- };
-
- /* Only cluster buffers if we know that we can supply DMA
- * buffers large enough to satisfy the request. Do not cluster
- * a new request if this would mean that we suddenly need to
- * start using DMA bounce buffers */
- if(bhp && CONTIGUOUS_BUFFERS(bh,bhp)
- && CLUSTERABLE_DEVICE(SCpnt)) {
- char * tmp;
-
- if (((long) sgpnt[count].address) + sgpnt[count].length +
- bhp->b_size - 1 > ISA_DMA_THRESHOLD &&
- (SCpnt->host->unchecked_isa_dma) &&
- !sgpnt[count].alt_address) continue;
-
- if(!sgpnt[count].alt_address) {count--; continue; }
- if(dma_free_sectors > 10)
- tmp = (char *) scsi_malloc(sgpnt[count].length
- + bhp->b_size);
- else {
- tmp = NULL;
- max_sg = SCpnt->use_sg;
- };
- if(tmp){
- scsi_free(sgpnt[count].address, sgpnt[count].length);
- sgpnt[count].address = tmp;
- count--;
- continue;
- };
-
- /* If we are allowed another sg chain, then increment
- * counter so we can insert it. Otherwise we will end
- up truncating */
-
- if (SCpnt->use_sg < max_sg) SCpnt->use_sg++;
- }; /* contiguous buffers */
- }; /* for loop */
-
- /* This is actually how many we are going to transfer */
- this_count = counted;
-
- if(count < SCpnt->use_sg || SCpnt->use_sg
- > SCpnt->host->sg_tablesize){
- bh = SCpnt->request.bh;
- printk("Use sg, count %d %x %d\n",
- SCpnt->use_sg, count, dma_free_sectors);
- printk("maxsg = %x, counted = %d this_count = %d\n",
- max_sg, counted, this_count);
- while(bh){
- printk("[%p %lx] ", bh->b_data, bh->b_size);
- bh = bh->b_reqnext;
- };
- if(SCpnt->use_sg < 16)
- for(count=0; count<SCpnt->use_sg; count++)
- printk("{%d:%p %p %d} ", count,
- sgpnt[count].address,
- sgpnt[count].alt_address,
- sgpnt[count].length);
- panic("Ooops");
- };
-
- if (SCpnt->request.cmd == WRITE)
- for(count=0; count<SCpnt->use_sg; count++)
- if(sgpnt[count].alt_address)
- memcpy(sgpnt[count].address, sgpnt[count].alt_address,
- sgpnt[count].length);
- }; /* Able to malloc sgpnt */
- }; /* Host adapter capable of scatter-gather */
-
- /* Now handle the possibility of DMA to addresses > 16Mb */
-
- if(SCpnt->use_sg == 0){
- if (((long) buff) + (this_count << 9) - 1 > ISA_DMA_THRESHOLD &&
- (SCpnt->host->unchecked_isa_dma)) {
- if(bounce_buffer)
- buff = bounce_buffer;
- else
- buff = (char *) scsi_malloc(this_count << 9);
- if(buff == NULL) { /* Try backing off a bit if we are low on mem*/
- this_count = SCpnt->request.current_nr_sectors;
- buff = (char *) scsi_malloc(this_count << 9);
- if(!buff) panic("Ran out of DMA buffers.");
- };
- if (SCpnt->request.cmd == WRITE)
- memcpy(buff, (char *)SCpnt->request.buffer, this_count << 9);
- };
- };
-#ifdef DEBUG
- printk("sd%c : %s %d/%d 512 byte blocks.\n",
- 'a' + devm,
- (SCpnt->request.cmd == WRITE) ? "writing" : "reading",
- this_count, SCpnt->request.nr_sectors);
-#endif
-
- cmd[1] = (SCpnt->lun << 5) & 0xe0;
-
- if (rscsi_disks[dev].sector_size == 1024){
- if(block & 1) panic("sd.c:Bad block number requested");
- if(this_count & 1) panic("sd.c:Bad block number requested");
- block = block >> 1;
- this_count = this_count >> 1;
- };
-
- if (rscsi_disks[dev].sector_size == 256){
- block = block << 1;
- this_count = this_count << 1;
- };
-
- if (((this_count > 0xff) || (block > 0x1fffff)) && rscsi_disks[dev].ten)
- {
- if (this_count > 0xffff)
- this_count = 0xffff;
-
- cmd[0] += READ_10 - READ_6 ;
- cmd[2] = (unsigned char) (block >> 24) & 0xff;
- cmd[3] = (unsigned char) (block >> 16) & 0xff;
- cmd[4] = (unsigned char) (block >> 8) & 0xff;
- cmd[5] = (unsigned char) block & 0xff;
- cmd[6] = cmd[9] = 0;
- cmd[7] = (unsigned char) (this_count >> 8) & 0xff;
- cmd[8] = (unsigned char) this_count & 0xff;
- }
- else
- {
- if (this_count > 0xff)
- this_count = 0xff;
-
- cmd[1] |= (unsigned char) ((block >> 16) & 0x1f);
- cmd[2] = (unsigned char) ((block >> 8) & 0xff);
- cmd[3] = (unsigned char) block & 0xff;
- cmd[4] = (unsigned char) this_count;
- cmd[5] = 0;
- }
-
- /*
- * We shouldn't disconnect in the middle of a sector, so with a dumb
- * host adapter, it's safe to assume that we can at least transfer
- * this many bytes between each connect / disconnect.
- */
-
- SCpnt->transfersize = rscsi_disks[dev].sector_size;
- SCpnt->underflow = this_count << 9;
- scsi_do_cmd (SCpnt, (void *) cmd, buff,
- this_count * rscsi_disks[dev].sector_size,
- rw_intr,
- (SCpnt->device->type == TYPE_DISK ?
- SD_TIMEOUT : SD_MOD_TIMEOUT),
- MAX_RETRIES);
-}
-
-static int check_scsidisk_media_change(kdev_t full_dev){
- int retval;
- int target;
- struct inode inode;
- int flag = 0;
-
- target = DEVICE_NR(full_dev);
-
- if (target >= sd_template.dev_max ||
- !rscsi_disks[target].device) {
- printk("SCSI disk request error: invalid device.\n");
- return 0;
- };
-
- if(!rscsi_disks[target].device->removable) return 0;
-
- inode.i_rdev = full_dev; /* This is all we really need here */
- retval = sd_ioctl(&inode, NULL, SCSI_IOCTL_TEST_UNIT_READY, 0);
-
- if(retval){ /* Unable to test, unit probably not ready. This usually
- * means there is no disc in the drive. Mark as changed,
- * and we will figure it out later once the drive is
- * available again. */
-
- rscsi_disks[target].ready = 0;
- rscsi_disks[target].device->changed = 1;
- return 1; /* This will force a flush, if called from
- * check_disk_change */
- };
-
- /*
- * for removable scsi disk ( FLOPTICAL ) we have to recognise the
- * presence of disk in the drive. This is kept in the Scsi_Disk
- * struct and tested at open ! Daniel Roche ( dan@lectra.fr )
- */
-
- rscsi_disks[target].ready = 1; /* FLOPTICAL */
-
- retval = rscsi_disks[target].device->changed;
- if(!flag) rscsi_disks[target].device->changed = 0;
- return retval;
-}
-
-static void sd_init_done (Scsi_Cmnd * SCpnt)
-{
- struct request * req;
-
- req = &SCpnt->request;
- req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */
-
- if (req->sem != NULL) {
- up(req->sem);
- }
-}
-
-static int sd_init_onedisk(int i)
-{
- unsigned char cmd[10];
- unsigned char *buffer;
- unsigned long spintime;
- int the_result, retries;
- Scsi_Cmnd * SCpnt;
-
- /* We need to retry the READ_CAPACITY because a UNIT_ATTENTION is
- * considered a fatal error, and many devices report such an error
- * just after a scsi bus reset.
- */
-
- SCpnt = allocate_device(NULL, rscsi_disks[i].device, 1);
- buffer = (unsigned char *) scsi_malloc(512);
-
- spintime = 0;
-
- /* Spin up drives, as required. Only do this at boot time */
- if (!MODULE_FLAG){
- do{
- retries = 0;
- while(retries < 3)
- {
- cmd[0] = TEST_UNIT_READY;
- cmd[1] = (rscsi_disks[i].device->lun << 5) & 0xe0;
- memset ((void *) &cmd[2], 0, 8);
- SCpnt->cmd_len = 0;
- SCpnt->sense_buffer[0] = 0;
- SCpnt->sense_buffer[2] = 0;
-
- {
- struct semaphore sem = MUTEX_LOCKED;
- /* Mark as really busy again */
- SCpnt->request.rq_status = RQ_SCSI_BUSY;
- SCpnt->request.sem = &sem;
- scsi_do_cmd (SCpnt,
- (void *) cmd, (void *) buffer,
- 512, sd_init_done, SD_TIMEOUT,
- MAX_RETRIES);
- down(&sem);
- }
-
- the_result = SCpnt->result;
- retries++;
- if( the_result == 0
- || SCpnt->sense_buffer[2] != UNIT_ATTENTION)
- break;
- }
-
- /* Look for non-removable devices that return NOT_READY.
- * Issue command to spin up drive for these cases. */
- if(the_result && !rscsi_disks[i].device->removable &&
- SCpnt->sense_buffer[2] == NOT_READY) {
- int time1;
- if(!spintime){
- printk( "sd%c: Spinning up disk...", 'a' + i );
- cmd[0] = START_STOP;
- cmd[1] = (rscsi_disks[i].device->lun << 5) & 0xe0;
- cmd[1] |= 1; /* Return immediately */
- memset ((void *) &cmd[2], 0, 8);
- cmd[4] = 1; /* Start spin cycle */
- SCpnt->cmd_len = 0;
- SCpnt->sense_buffer[0] = 0;
- SCpnt->sense_buffer[2] = 0;
-
- {
- struct semaphore sem = MUTEX_LOCKED;
- /* Mark as really busy again */
- SCpnt->request.rq_status = RQ_SCSI_BUSY;
- SCpnt->request.sem = &sem;
- scsi_do_cmd (SCpnt,
- (void *) cmd, (void *) buffer,
- 512, sd_init_done, SD_TIMEOUT,
- MAX_RETRIES);
- down(&sem);
- }
-
- spintime = jiffies;
- }
-
- time1 = jiffies;
- while(jiffies < time1 + HZ); /* Wait 1 second for next try */
- printk( "." );
- };
- } while(the_result && spintime && spintime+100*HZ > jiffies);
- if (spintime) {
- if (the_result)
- printk( "not responding...\n" );
- else
- printk( "ready\n" );
- }
- }; /* !MODULE_FLAG */
-
-
- retries = 3;
- do {
- cmd[0] = READ_CAPACITY;
- cmd[1] = (rscsi_disks[i].device->lun << 5) & 0xe0;
- memset ((void *) &cmd[2], 0, 8);
- memset ((void *) buffer, 0, 8);
- SCpnt->cmd_len = 0;
- SCpnt->sense_buffer[0] = 0;
- SCpnt->sense_buffer[2] = 0;
-
- {
- struct semaphore sem = MUTEX_LOCKED;
- /* Mark as really busy again */
- SCpnt->request.rq_status = RQ_SCSI_BUSY;
- SCpnt->request.sem = &sem;
- scsi_do_cmd (SCpnt,
- (void *) cmd, (void *) buffer,
- 8, sd_init_done, SD_TIMEOUT,
- MAX_RETRIES);
- down(&sem); /* sleep until it is ready */
- }
-
- the_result = SCpnt->result;
- retries--;
-
- } while(the_result && retries);
-
- SCpnt->request.rq_status = RQ_INACTIVE; /* Mark as not busy */
-
- wake_up(&SCpnt->device->device_wait);
-
- /* Wake up a process waiting for device */
-
- /*
- * The SCSI standard says:
- * "READ CAPACITY is necessary for self configuring software"
- * While not mandatory, support of READ CAPACITY is strongly encouraged.
- * We used to die if we couldn't successfully do a READ CAPACITY.
- * But, now we go on about our way. The side effects of this are
- *
- * 1. We can't know block size with certainty. I have said "512 bytes
- * is it" as this is most common.
- *
- * 2. Recovery from when some one attempts to read past the end of the
- * raw device will be slower.
- */
-
- if (the_result)
- {
- printk ("sd%c : READ CAPACITY failed.\n"
- "sd%c : status = %x, message = %02x, host = %d, driver = %02x \n",
- 'a' + i, 'a' + i,
- status_byte(the_result),
- msg_byte(the_result),
- host_byte(the_result),
- driver_byte(the_result)
- );
- if (driver_byte(the_result) & DRIVER_SENSE)
- printk("sd%c : extended sense code = %1x \n",
- 'a' + i, SCpnt->sense_buffer[2] & 0xf);
- else
- printk("sd%c : sense not available. \n", 'a' + i);
-
- printk("sd%c : block size assumed to be 512 bytes, disk size 1GB. \n",
- 'a' + i);
- rscsi_disks[i].capacity = 0x1fffff;
- rscsi_disks[i].sector_size = 512;
-
- /* Set dirty bit for removable devices if not ready - sometimes drives
- * will not report this properly. */
- if(rscsi_disks[i].device->removable &&
- SCpnt->sense_buffer[2] == NOT_READY)
- rscsi_disks[i].device->changed = 1;
-
- }
- else
- {
- /*
- * FLOPTICAL , if read_capa is ok , drive is assumed to be ready
- */
- rscsi_disks[i].ready = 1;
-
- rscsi_disks[i].capacity = (buffer[0] << 24) |
- (buffer[1] << 16) |
- (buffer[2] << 8) |
- buffer[3];
-
- rscsi_disks[i].sector_size = (buffer[4] << 24) |
- (buffer[5] << 16) | (buffer[6] << 8) | buffer[7];
-
- if (rscsi_disks[i].sector_size == 0) {
- rscsi_disks[i].sector_size = 512;
- printk("sd%c : sector size 0 reported, assuming 512.\n", 'a' + i);
- }
-
-
- if (rscsi_disks[i].sector_size != 512 &&
- rscsi_disks[i].sector_size != 1024 &&
- rscsi_disks[i].sector_size != 256)
- {
- printk ("sd%c : unsupported sector size %d.\n",
- 'a' + i, rscsi_disks[i].sector_size);
- if(rscsi_disks[i].device->removable){
- rscsi_disks[i].capacity = 0;
- } else {
- printk ("scsi : deleting disk entry.\n");
- rscsi_disks[i].device = NULL;
- sd_template.nr_dev--;
- return i;
- };
- }
- {
- /*
- * The msdos fs need to know the hardware sector size
- * So I have created this table. See ll_rw_blk.c
- * Jacques Gelinas (Jacques@solucorp.qc.ca)
- */
- int m;
- int hard_sector = rscsi_disks[i].sector_size;
- /* There is 16 minor allocated for each devices */
- for (m=i<<4; m<((i+1)<<4); m++){
- sd_hardsizes[m] = hard_sector;
- }
- printk ("SCSI Hardware sector size is %d bytes on device sd%c\n",
- hard_sector,i+'a');
- }
- if(rscsi_disks[i].sector_size == 1024)
- rscsi_disks[i].capacity <<= 1; /* Change into 512 byte sectors */
- if(rscsi_disks[i].sector_size == 256)
- rscsi_disks[i].capacity >>= 1; /* Change into 512 byte sectors */
- }
-
-
- /*
- * Unless otherwise specified, this is not write protected.
- */
- rscsi_disks[i].write_prot = 0;
- if ( rscsi_disks[i].device->removable && rscsi_disks[i].ready ) {
- /* FLOPTICAL */
-
- /*
- * for removable scsi disk ( FLOPTICAL ) we have to recognise
- * the Write Protect Flag. This flag is kept in the Scsi_Disk struct
- * and tested at open !
- * Daniel Roche ( dan@lectra.fr )
- */
-
- memset ((void *) &cmd[0], 0, 8);
- cmd[0] = MODE_SENSE;
- cmd[1] = (rscsi_disks[i].device->lun << 5) & 0xe0;
- cmd[2] = 1; /* page code 1 ?? */
- cmd[4] = 12;
- SCpnt->cmd_len = 0;
- SCpnt->sense_buffer[0] = 0;
- SCpnt->sense_buffer[2] = 0;
-
- /* same code as READCAPA !! */
- {
- struct semaphore sem = MUTEX_LOCKED;
- SCpnt->request.rq_status = RQ_SCSI_BUSY; /* Mark as really busy again */
- SCpnt->request.sem = &sem;
- scsi_do_cmd (SCpnt,
- (void *) cmd, (void *) buffer,
- 512, sd_init_done, SD_TIMEOUT,
- MAX_RETRIES);
- down(&sem);
- }
-
- the_result = SCpnt->result;
- SCpnt->request.rq_status = RQ_INACTIVE; /* Mark as not busy */
- wake_up(&SCpnt->device->device_wait);
-
- if ( the_result ) {
- printk ("sd%c: test WP failed, assume Write Protected\n",i+'a');
- rscsi_disks[i].write_prot = 1;
- } else {
- rscsi_disks[i].write_prot = ((buffer[2] & 0x80) != 0);
- printk ("sd%c: Write Protect is %s\n",i+'a',
- rscsi_disks[i].write_prot ? "on" : "off");
- }
-
- } /* check for write protect */
-
- rscsi_disks[i].ten = 1;
- rscsi_disks[i].remap = 1;
- scsi_free(buffer, 512);
- return i;
-}
-
-/*
- * The sd_init() function looks at all SCSI drives present, determines
- * their size, and reads partition table entries for them.
- */
-
-static int sd_registered = 0;
-
-static int sd_init()
-{
- int i;
-
- if (sd_template.dev_noticed == 0) return 0;
-
- if(!sd_registered) {
- if (register_blkdev(MAJOR_NR,"sd",&sd_fops)) {
- printk("Unable to get major %d for SCSI disk\n",MAJOR_NR);
- return 1;
- }
- sd_registered++;
- }
-
- /* We do not support attaching loadable devices yet. */
- if(rscsi_disks) return 0;
-
- sd_template.dev_max = sd_template.dev_noticed + SD_EXTRA_DEVS;
-
- rscsi_disks = (Scsi_Disk *)
- scsi_init_malloc(sd_template.dev_max * sizeof(Scsi_Disk), GFP_ATOMIC);
- memset(rscsi_disks, 0, sd_template.dev_max * sizeof(Scsi_Disk));
-
- sd_sizes = (int *) scsi_init_malloc((sd_template.dev_max << 4) *
- sizeof(int), GFP_ATOMIC);
- memset(sd_sizes, 0, (sd_template.dev_max << 4) * sizeof(int));
-
- sd_blocksizes = (int *) scsi_init_malloc((sd_template.dev_max << 4) *
- sizeof(int), GFP_ATOMIC);
-
- sd_hardsizes = (int *) scsi_init_malloc((sd_template.dev_max << 4) *
- sizeof(int), GFP_ATOMIC);
-
- for(i=0;i<(sd_template.dev_max << 4);i++){
- sd_blocksizes[i] = 1024;
- sd_hardsizes[i] = 512;
- }
- blksize_size[MAJOR_NR] = sd_blocksizes;
- hardsect_size[MAJOR_NR] = sd_hardsizes;
- sd = (struct hd_struct *) scsi_init_malloc((sd_template.dev_max << 4) *
- sizeof(struct hd_struct),
- GFP_ATOMIC);
-
-
- sd_gendisk.max_nr = sd_template.dev_max;
- sd_gendisk.part = sd;
- sd_gendisk.sizes = sd_sizes;
- sd_gendisk.real_devices = (void *) rscsi_disks;
- return 0;
-}
-
-static void sd_finish()
-{
- int i;
-
- blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
-
- sd_gendisk.next = gendisk_head;
- gendisk_head = &sd_gendisk;
-
- for (i = 0; i < sd_template.dev_max; ++i)
- if (!rscsi_disks[i].capacity &&
- rscsi_disks[i].device)
- {
- if (MODULE_FLAG
- && !rscsi_disks[i].has_part_table) {
- sd_sizes[i << 4] = rscsi_disks[i].capacity;
- /* revalidate does sd_init_onedisk via MAYBE_REINIT*/
- revalidate_scsidisk(MKDEV(MAJOR_NR, i << 4), 0);
- }
- else
- i=sd_init_onedisk(i);
- rscsi_disks[i].has_part_table = 1;
- }
-
- /* If our host adapter is capable of scatter-gather, then we increase
- * the read-ahead to 16 blocks (32 sectors). If not, we use
- * a two block (4 sector) read ahead.
- */
- if(rscsi_disks[0].device && rscsi_disks[0].device->host->sg_tablesize)
- read_ahead[MAJOR_NR] = 120; /* 120 sector read-ahead */
- else
- read_ahead[MAJOR_NR] = 4; /* 4 sector read-ahead */
-
- return;
-}
-
-static int sd_detect(Scsi_Device * SDp){
- if(SDp->type != TYPE_DISK && SDp->type != TYPE_MOD) return 0;
-
- printk("Detected scsi disk sd%c at scsi%d, channel %d, id %d, lun %d\n",
- 'a'+ (sd_template.dev_noticed++),
- SDp->host->host_no, SDp->channel, SDp->id, SDp->lun);
-
- return 1;
-}
-
-static int sd_attach(Scsi_Device * SDp){
- Scsi_Disk * dpnt;
- int i;
-
- if(SDp->type != TYPE_DISK && SDp->type != TYPE_MOD) return 0;
-
- if(sd_template.nr_dev >= sd_template.dev_max) {
- SDp->attached--;
- return 1;
- }
-
- for(dpnt = rscsi_disks, i=0; i<sd_template.dev_max; i++, dpnt++)
- if(!dpnt->device) break;
-
- if(i >= sd_template.dev_max) panic ("scsi_devices corrupt (sd)");
-
- SDp->scsi_request_fn = do_sd_request;
- rscsi_disks[i].device = SDp;
- rscsi_disks[i].has_part_table = 0;
- sd_template.nr_dev++;
- sd_gendisk.nr_real++;
- return 0;
-}
-
-#define DEVICE_BUSY rscsi_disks[target].device->busy
-#define USAGE rscsi_disks[target].device->access_count
-#define CAPACITY rscsi_disks[target].capacity
-#define MAYBE_REINIT sd_init_onedisk(target)
-#define GENDISK_STRUCT sd_gendisk
-
-/* This routine is called to flush all partitions and partition tables
- * for a changed scsi disk, and then re-read the new partition table.
- * If we are revalidating a disk because of a media change, then we
- * enter with usage == 0. If we are using an ioctl, we automatically have
- * usage == 1 (we need an open channel to use an ioctl :-), so this
- * is our limit.
- */
-int revalidate_scsidisk(kdev_t dev, int maxusage){
- int target;
- struct gendisk * gdev;
- unsigned long flags;
- int max_p;
- int start;
- int i;
-
- target = DEVICE_NR(dev);
- gdev = &GENDISK_STRUCT;
-
- save_flags(flags);
- cli();
- if (DEVICE_BUSY || USAGE > maxusage) {
- restore_flags(flags);
- printk("Device busy for revalidation (usage=%d)\n", USAGE);
- return -EBUSY;
- };
- DEVICE_BUSY = 1;
- restore_flags(flags);
-
- max_p = gdev->max_p;
- start = target << gdev->minor_shift;
-
- for (i=max_p - 1; i >=0 ; i--) {
- int minor = start+i;
- kdev_t devi = MKDEV(MAJOR_NR, minor);
- sync_dev(devi);
- invalidate_inodes(devi);
- invalidate_buffers(devi);
- gdev->part[minor].start_sect = 0;
- gdev->part[minor].nr_sects = 0;
- /*
- * Reset the blocksize for everything so that we can read
- * the partition table.
- */
- blksize_size[MAJOR_NR][minor] = 1024;
- };
-
-#ifdef MAYBE_REINIT
- MAYBE_REINIT;
-#endif
-
- gdev->part[start].nr_sects = CAPACITY;
- resetup_one_dev(gdev, target);
-
- DEVICE_BUSY = 0;
- return 0;
-}
-
-static int fop_revalidate_scsidisk(kdev_t dev){
- return revalidate_scsidisk(dev, 0);
-}
-
-
-static void sd_detach(Scsi_Device * SDp)
-{
- Scsi_Disk * dpnt;
- int i;
- int max_p;
- int start;
-
- for(dpnt = rscsi_disks, i=0; i<sd_template.dev_max; i++, dpnt++)
- if(dpnt->device == SDp) {
-
- /* If we are disconnecting a disk driver, sync and invalidate
- * everything */
- max_p = sd_gendisk.max_p;
- start = i << sd_gendisk.minor_shift;
-
- for (i=max_p - 1; i >=0 ; i--) {
- int minor = start+i;
- kdev_t devi = MKDEV(MAJOR_NR, minor);
- sync_dev(devi);
- invalidate_inodes(devi);
- invalidate_buffers(devi);
- sd_gendisk.part[minor].start_sect = 0;
- sd_gendisk.part[minor].nr_sects = 0;
- sd_sizes[minor] = 0;
- };
-
- dpnt->has_part_table = 0;
- dpnt->device = NULL;
- dpnt->capacity = 0;
- SDp->attached--;
- sd_template.dev_noticed--;
- sd_template.nr_dev--;
- sd_gendisk.nr_real--;
- return;
- }
- return;
-}
-
-#ifdef MODULE
-
-int init_module(void) {
- sd_template.usage_count = &mod_use_count_;
- return scsi_register_module(MODULE_SCSI_DEV, &sd_template);
-}
-
-void cleanup_module( void)
-{
- struct gendisk * prev_sdgd;
- struct gendisk * sdgd;
-
- scsi_unregister_module(MODULE_SCSI_DEV, &sd_template);
- unregister_blkdev(SCSI_DISK_MAJOR, "sd");
- sd_registered--;
- if( rscsi_disks != NULL )
- {
- scsi_init_free((char *) rscsi_disks,
- (sd_template.dev_noticed + SD_EXTRA_DEVS)
- * sizeof(Scsi_Disk));
-
- scsi_init_free((char *) sd_sizes, sd_template.dev_max * sizeof(int));
- scsi_init_free((char *) sd_blocksizes, sd_template.dev_max * sizeof(int));
- scsi_init_free((char *) sd_hardsizes, sd_template.dev_max * sizeof(int));
- scsi_init_free((char *) sd,
- (sd_template.dev_max << 4) * sizeof(struct hd_struct));
- /*
- * Now remove sd_gendisk from the linked list
- */
- sdgd = gendisk_head;
- prev_sdgd = NULL;
- while(sdgd != &sd_gendisk)
- {
- prev_sdgd = sdgd;
- sdgd = sdgd->next;
- }
-
- if(sdgd != &sd_gendisk)
- printk("sd_gendisk not in disk chain.\n");
- else {
- if(prev_sdgd != NULL)
- prev_sdgd->next = sdgd->next;
- else
- gendisk_head = sdgd->next;
- }
- }
-
- blksize_size[MAJOR_NR] = NULL;
- blk_dev[MAJOR_NR].request_fn = NULL;
- blk_size[MAJOR_NR] = NULL;
- hardsect_size[MAJOR_NR] = NULL;
- read_ahead[MAJOR_NR] = 0;
- sd_template.dev_max = 0;
-}
-#endif /* MODULE */
-
-/*
- * Overrides for Emacs so that we almost follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 4
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * c-continued-statement-offset: 4
- * c-continued-brace-offset: 0
- * indent-tabs-mode: nil
- * tab-width: 8
- * End:
- */
diff --git a/i386/i386at/gpl/linux/scsi/sd.h b/i386/i386at/gpl/linux/scsi/sd.h
deleted file mode 100644
index 7a8219b7..00000000
--- a/i386/i386at/gpl/linux/scsi/sd.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * sd.h Copyright (C) 1992 Drew Eckhardt
- * SCSI disk driver header file by
- * Drew Eckhardt
- *
- * <drew@colorado.edu>
- *
- * Modified by Eric Youngdale eric@aib.com to
- * add scatter-gather, multiple outstanding request, and other
- * enhancements.
- */
-#ifndef _SD_H
-#define _SD_H
-/*
- $Header: cvs/gnumach/i386/i386at/gpl/linux/scsi/Attic/sd.h,v 1.1.1.1 1997/02/25 21:27:52 thomas Exp $
-*/
-
-#ifndef _SCSI_H
-#include "scsi.h"
-#endif
-
-#ifndef _GENDISK_H
-#include <linux/genhd.h>
-#endif
-
-extern struct hd_struct * sd;
-
-typedef struct scsi_disk {
- unsigned capacity; /* size in blocks */
- unsigned sector_size; /* size in bytes */
- Scsi_Device *device;
- unsigned char ready; /* flag ready for FLOPTICAL */
- unsigned char write_prot; /* flag write_protect for rmvable dev */
- unsigned char sector_bit_size; /* sector_size = 2 to the bit size power */
- unsigned char sector_bit_shift; /* power of 2 sectors per FS block */
- unsigned ten:1; /* support ten byte read / write */
- unsigned remap:1; /* support remapping */
- unsigned has_part_table:1; /* has partition table */
-} Scsi_Disk;
-
-extern Scsi_Disk * rscsi_disks;
-
-extern int revalidate_scsidisk(kdev_t dev, int maxusage);
-
-#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 4
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * c-continued-statement-offset: 4
- * c-continued-brace-offset: 0
- * indent-tabs-mode: nil
- * tab-width: 8
- * End:
- */
-
diff --git a/i386/i386at/gpl/linux/scsi/sd_ioctl.c b/i386/i386at/gpl/linux/scsi/sd_ioctl.c
deleted file mode 100644
index 1898af61..00000000
--- a/i386/i386at/gpl/linux/scsi/sd_ioctl.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * drivers/scsi/sd_ioctl.c
- *
- * ioctl handling for SCSI disks
- */
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/fs.h>
-#include <linux/hdreg.h>
-#include <linux/errno.h>
-
-#include <asm/segment.h>
-
-#include <linux/blk.h>
-#include "scsi.h"
-#include "scsi_ioctl.h"
-#include "hosts.h"
-#include "sd.h"
-
-int sd_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg)
-{
- kdev_t dev = inode->i_rdev;
- int error;
- struct Scsi_Host * host;
- int diskinfo[4];
- struct hd_geometry *loc = (struct hd_geometry *) arg;
-
- switch (cmd) {
- case HDIO_GETGEO: /* Return BIOS disk parameters */
- if (!loc) return -EINVAL;
- error = verify_area(VERIFY_WRITE, loc, sizeof(*loc));
- if (error)
- return error;
- host = rscsi_disks[MINOR(dev) >> 4].device->host;
- diskinfo[0] = 0;
- diskinfo[1] = 0;
- diskinfo[2] = 0;
- if(host->hostt->bios_param != NULL)
- host->hostt->bios_param(&rscsi_disks[MINOR(dev) >> 4],
- dev,
- &diskinfo[0]);
- put_user(diskinfo[0], &loc->heads);
- put_user(diskinfo[1], &loc->sectors);
- put_user(diskinfo[2], &loc->cylinders);
- put_user(sd[MINOR(inode->i_rdev)].start_sect, &loc->start);
- return 0;
- case BLKGETSIZE: /* Return device size */
- if (!arg) return -EINVAL;
- error = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long));
- if (error)
- return error;
- put_user(sd[MINOR(inode->i_rdev)].nr_sects,
- (long *) arg);
- return 0;
- case BLKRASET:
- if(!suser()) return -EACCES;
- if(!(inode->i_rdev)) return -EINVAL;
- if(arg > 0xff) return -EINVAL;
- read_ahead[MAJOR(inode->i_rdev)] = arg;
- return 0;
- case BLKFLSBUF:
- if(!suser()) return -EACCES;
- if(!(inode->i_rdev)) return -EINVAL;
- fsync_dev(inode->i_rdev);
- invalidate_buffers(inode->i_rdev);
- return 0;
-
- case BLKRRPART: /* Re-read partition tables */
- return revalidate_scsidisk(dev, 1);
- default:
- return scsi_ioctl(rscsi_disks[MINOR(dev) >> 4].device , cmd, (void *) arg);
- }
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 4
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * c-continued-statement-offset: 4
- * c-continued-brace-offset: 0
- * indent-tabs-mode: nil
- * tab-width: 8
- * End:
- */
diff --git a/i386/i386at/gpl/linux/scsi/seagate.c b/i386/i386at/gpl/linux/scsi/seagate.c
deleted file mode 100644
index 5b25a833..00000000
--- a/i386/i386at/gpl/linux/scsi/seagate.c
+++ /dev/null
@@ -1,1744 +0,0 @@
-/*
- * seagate.c Copyright (C) 1992, 1993 Drew Eckhardt
- * low level scsi driver for ST01/ST02, Future Domain TMC-885,
- * TMC-950 by
- *
- * Drew Eckhardt
- *
- * <drew@colorado.edu>
- *
- * Note : TMC-880 boards don't work because they have two bits in
- * the status register flipped, I'll fix this "RSN"
- *
- * This card does all the I/O via memory mapped I/O, so there is no need
- * to check or allocate a region of the I/O address space.
- */
-
-/*
- * Configuration :
- * To use without BIOS -DOVERRIDE=base_address -DCONTROLLER=FD or SEAGATE
- * -DIRQ will override the default of 5.
- * Note: You can now set these options from the kernel's "command line".
- * The syntax is:
- *
- * st0x=ADDRESS,IRQ (for a Seagate controller)
- * or:
- * tmc8xx=ADDRESS,IRQ (for a TMC-8xx or TMC-950 controller)
- * eg:
- * tmc8xx=0xC8000,15
- *
- * will configure the driver for a TMC-8xx style controller using IRQ 15
- * with a base address of 0xC8000.
- *
- * -DFAST or -DFAST32 will use blind transfers where possible
- *
- * -DARBITRATE will cause the host adapter to arbitrate for the
- * bus for better SCSI-II compatibility, rather than just
- * waiting for BUS FREE and then doing its thing. Should
- * let us do one command per Lun when I integrate my
- * reorganization changes into the distribution sources.
- *
- * -DSLOW_HANDSHAKE will allow compatibility with broken devices that don't
- * handshake fast enough (ie, some CD ROM's) for the Seagate
- * code.
- *
- * -DSLOW_RATE=x, x some number will let you specify a default
- * transfer rate if handshaking isn't working correctly.
- */
-
-#include <linux/module.h>
-
-#include <asm/io.h>
-#include <asm/system.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/config.h>
-#include <linux/proc_fs.h>
-
-#include <linux/blk.h>
-#include "scsi.h"
-#include "hosts.h"
-#include "seagate.h"
-#include "constants.h"
-#include<linux/stat.h>
-
-struct proc_dir_entry proc_scsi_seagate = {
- PROC_SCSI_SEAGATE, 7, "seagate",
- S_IFDIR | S_IRUGO | S_IXUGO, 2
-};
-
-
-#ifndef IRQ
-#define IRQ 5
-#endif
-
-#if (defined(FAST32) && !defined(FAST))
-#define FAST
-#endif
-
-#if defined(SLOW_RATE) && !defined(SLOW_HANDSHAKE)
-#define SLOW_HANDSHAKE
-#endif
-
-#if defined(SLOW_HANDSHAKE) && !defined(SLOW_RATE)
-#define SLOW_RATE 50
-#endif
-
-
-#if defined(LINKED)
-#undef LINKED /* Linked commands are currently broken ! */
-#endif
-
-static int internal_command(unsigned char target, unsigned char lun,
- const void *cmnd,
- void *buff, int bufflen, int reselect);
-
-static int incommand; /*
- set if arbitration has finished and we are
- in some command phase.
- */
-
-static const void *base_address = NULL; /*
- Where the card ROM starts,
- used to calculate memory mapped
- register location.
- */
-#ifdef notyet
-static volatile int abort_confirm = 0;
-#endif
-
-static volatile void *st0x_cr_sr; /*
- control register write,
- status register read.
- 256 bytes in length.
-
- Read is status of SCSI BUS,
- as per STAT masks.
-
- */
-
-
-static volatile void *st0x_dr; /*
- data register, read write
- 256 bytes in length.
- */
-
-
-static volatile int st0x_aborted=0; /*
- set when we are aborted, ie by a time out, etc.
- */
-
-static unsigned char controller_type = 0; /* set to SEAGATE for ST0x boards or FD for TMC-8xx boards */
-static unsigned char irq = IRQ;
-
-#define retcode(result) (((result) << 16) | (message << 8) | status)
-#define STATUS (*(volatile unsigned char *) st0x_cr_sr)
-#define CONTROL STATUS
-#define DATA (*(volatile unsigned char *) st0x_dr)
-
-void st0x_setup (char *str, int *ints) {
- controller_type = SEAGATE;
- base_address = (void *) ints[1];
- irq = ints[2];
-}
-
-void tmc8xx_setup (char *str, int *ints) {
- controller_type = FD;
- base_address = (void *) ints[1];
- irq = ints[2];
-}
-
-
-#ifndef OVERRIDE
-static const char * seagate_bases[] = {
- (char *) 0xc8000, (char *) 0xca000, (char *) 0xcc000,
- (char *) 0xce000, (char *) 0xdc000, (char *) 0xde000
-};
-
-typedef struct {
- const char *signature ;
- unsigned offset;
- unsigned length;
- unsigned char type;
-} Signature;
-
-static const Signature signatures[] = {
-#ifdef CONFIG_SCSI_SEAGATE
-{"ST01 v1.7 (C) Copyright 1987 Seagate", 15, 37, SEAGATE},
-{"SCSI BIOS 2.00 (C) Copyright 1987 Seagate", 15, 40, SEAGATE},
-
-/*
- * The following two lines are NOT mistakes. One detects ROM revision
- * 3.0.0, the other 3.2. Since seagate has only one type of SCSI adapter,
- * and this is not going to change, the "SEAGATE" and "SCSI" together
- * are probably "good enough"
- */
-
-{"SEAGATE SCSI BIOS ",16, 17, SEAGATE},
-{"SEAGATE SCSI BIOS ",17, 17, SEAGATE},
-
-/*
- * However, future domain makes several incompatible SCSI boards, so specific
- * signatures must be used.
- */
-
-{"FUTURE DOMAIN CORP. (C) 1986-1989 V5.0C2/14/89", 5, 46, FD},
-{"FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/89", 5, 46, FD},
-{"FUTURE DOMAIN CORP. (C) 1986-1990 V6.0105/31/90",5, 47, FD},
-{"FUTURE DOMAIN CORP. (C) 1986-1990 V6.0209/18/90",5, 47, FD},
-{"FUTURE DOMAIN CORP. (C) 1986-1990 V7.009/18/90", 5, 46, FD},
-{"FUTURE DOMAIN CORP. (C) 1992 V8.00.004/02/92", 5, 44, FD},
-{"IBM F1 BIOS V1.1004/30/92", 5, 25, FD},
-{"FUTURE DOMAIN TMC-950", 5, 21, FD},
-#endif /* CONFIG_SCSI_SEAGATE */
-}
-;
-
-#define NUM_SIGNATURES (sizeof(signatures) / sizeof(Signature))
-#endif /* n OVERRIDE */
-
-/*
- * hostno stores the hostnumber, as told to us by the init routine.
- */
-
-static int hostno = -1;
-static void seagate_reconnect_intr(int, struct pt_regs *);
-
-#ifdef FAST
-static int fast = 1;
-#endif
-
-#ifdef SLOW_HANDSHAKE
-/*
- * Support for broken devices :
- * The Seagate board has a handshaking problem. Namely, a lack
- * thereof for slow devices. You can blast 600K/second through
- * it if you are polling for each byte, more if you do a blind
- * transfer. In the first case, with a fast device, REQ will
- * transition high-low or high-low-high before your loop restarts
- * and you'll have no problems. In the second case, the board
- * will insert wait states for up to 13.2 usecs for REQ to
- * transition low->high, and everything will work.
- *
- * However, there's nothing in the state machine that says
- * you *HAVE* to see a high-low-high set of transitions before
- * sending the next byte, and slow things like the Trantor CD ROMS
- * will break because of this.
- *
- * So, we need to slow things down, which isn't as simple as it
- * seems. We can't slow things down period, because then people
- * who don't recompile their kernels will shoot me for ruining
- * their performance. We need to do it on a case per case basis.
- *
- * The best for performance will be to, only for borken devices
- * (this is stored on a per-target basis in the scsi_devices array)
- *
- * Wait for a low->high transition before continuing with that
- * transfer. If we timeout, continue anyways. We don't need
- * a long timeout, because REQ should only be asserted until the
- * corresponding ACK is received and processed.
- *
- * Note that we can't use the system timer for this, because of
- * resolution, and we *really* can't use the timer chip since
- * gettimeofday() and the beeper routines use that. So,
- * the best thing for us to do will be to calibrate a timing
- * loop in the initialization code using the timer chip before
- * gettimeofday() can screw with it.
- */
-
-static int borken_calibration = 0;
-static void borken_init (void) {
- register int count = 0, start = jiffies + 1, stop = start + 25;
-
- while (jiffies < start);
- for (;jiffies < stop; ++count);
-
-/*
- * Ok, we now have a count for .25 seconds. Convert to a
- * count per second and divide by transfer rate in K.
- */
-
- borken_calibration = (count * 4) / (SLOW_RATE*1024);
-
- if (borken_calibration < 1)
- borken_calibration = 1;
-#if (DEBUG & DEBUG_BORKEN)
- printk("scsi%d : borken calibrated to %dK/sec, %d cycles per transfer\n",
- hostno, BORKEN_RATE, borken_calibration);
-#endif
-}
-
-static inline void borken_wait(void) {
- register int count;
- for (count = borken_calibration; count && (STATUS & STAT_REQ);
- --count);
-#if (DEBUG & DEBUG_BORKEN)
- if (count)
- printk("scsi%d : borken timeout\n", hostno);
-#endif
-}
-
-#endif /* def SLOW_HANDSHAKE */
-
-int seagate_st0x_detect (Scsi_Host_Template * tpnt)
- {
- struct Scsi_Host *instance;
-#ifndef OVERRIDE
- int i,j;
-#endif
-
- tpnt->proc_dir = &proc_scsi_seagate;
-/*
- * First, we try for the manual override.
- */
-#ifdef DEBUG
- printk("Autodetecting ST0x / TMC-8xx\n");
-#endif
-
- if (hostno != -1)
- {
- printk ("ERROR : seagate_st0x_detect() called twice.\n");
- return 0;
- }
-
- /* If the user specified the controller type from the command line,
- controller_type will be non-zero, so don't try and detect one */
-
- if (!controller_type) {
-#ifdef OVERRIDE
- base_address = (void *) OVERRIDE;
-
-/* CONTROLLER is used to override controller (SEAGATE or FD). PM: 07/01/93 */
-#ifdef CONTROLLER
- controller_type = CONTROLLER;
-#else
-#error Please use -DCONTROLLER=SEAGATE or -DCONTROLLER=FD to override controller type
-#endif /* CONTROLLER */
-#ifdef DEBUG
- printk("Base address overridden to %x, controller type is %s\n",
- base_address,controller_type == SEAGATE ? "SEAGATE" : "FD");
-#endif
-#else /* OVERRIDE */
-/*
- * To detect this card, we simply look for the signature
- * from the BIOS version notice in all the possible locations
- * of the ROM's. This has a nice side effect of not trashing
- * any register locations that might be used by something else.
- *
- * XXX - note that we probably should be probing the address
- * space for the on-board RAM instead.
- */
-
- for (i = 0; i < (sizeof (seagate_bases) / sizeof (char * )); ++i)
- for (j = 0; !base_address && j < NUM_SIGNATURES; ++j)
- if (!memcmp ((const void *) (seagate_bases[i] +
- signatures[j].offset), (const void *) signatures[j].signature,
- signatures[j].length)) {
- base_address = (const void *) seagate_bases[i];
- controller_type = signatures[j].type;
- }
-#endif /* OVERRIDE */
- } /* (! controller_type) */
-
- tpnt->this_id = (controller_type == SEAGATE) ? 7 : 6;
- tpnt->name = (controller_type == SEAGATE) ? ST0X_ID_STR : FD_ID_STR;
-
- if (base_address)
- {
- st0x_cr_sr =(void *) (((const unsigned char *) base_address) + (controller_type == SEAGATE ? 0x1a00 : 0x1c00));
- st0x_dr = (void *) (((const unsigned char *) base_address ) + (controller_type == SEAGATE ? 0x1c00 : 0x1e00));
-#ifdef DEBUG
- printk("%s detected. Base address = %x, cr = %x, dr = %x\n", tpnt->name, base_address, st0x_cr_sr, st0x_dr);
-#endif
-/*
- * At all times, we will use IRQ 5. Should also check for IRQ3 if we
- * loose our first interrupt.
- */
- instance = scsi_register(tpnt, 0);
- hostno = instance->host_no;
- if (request_irq((int) irq, seagate_reconnect_intr, SA_INTERRUPT,
- (controller_type == SEAGATE) ? "seagate" : "tmc-8xx")) {
- printk("scsi%d : unable to allocate IRQ%d\n",
- hostno, (int) irq);
- return 0;
- }
- instance->irq = irq;
- instance->io_port = (unsigned int) base_address;
-#ifdef SLOW_HANDSHAKE
- borken_init();
-#endif
-
- printk("%s options:"
-#ifdef ARBITRATE
- " ARBITRATE"
-#endif
-#ifdef SLOW_HANDSHAKE
- " SLOW_HANDSHAKE"
-#endif
-#ifdef FAST
-#ifdef FAST32
- " FAST32"
-#else
- " FAST"
-#endif
-#endif
-#ifdef LINKED
- " LINKED"
-#endif
- "\n", tpnt->name);
- return 1;
- }
- else
- {
-#ifdef DEBUG
- printk("ST0x / TMC-8xx not detected.\n");
-#endif
- return 0;
- }
- }
-
-const char *seagate_st0x_info(struct Scsi_Host * shpnt) {
- static char buffer[64];
- sprintf(buffer, "%s at irq %d, address 0x%05X",
- (controller_type == SEAGATE) ? ST0X_ID_STR : FD_ID_STR,
- irq, (unsigned int)base_address);
- return buffer;
-}
-
-int seagate_st0x_proc_info(char *buffer, char **start, off_t offset,
- int length, int hostno, int inout)
-{
- const char *info = seagate_st0x_info(NULL);
- int len;
- int pos;
- int begin;
-
- if (inout) return(-ENOSYS);
-
- begin = 0;
- strcpy(buffer,info);
- strcat(buffer,"\n");
-
- pos = len = strlen(buffer);
-
- if (pos<offset) {
- len = 0;
- begin = pos;
- }
-
- *start = buffer + (offset - begin);
- len -= (offset - begin);
- if ( len > length ) len = length;
- return(len);
-}
-
-/*
- * These are our saved pointers for the outstanding command that is
- * waiting for a reconnect
- */
-
-static unsigned char current_target, current_lun;
-static unsigned char *current_cmnd, *current_data;
-static int current_nobuffs;
-static struct scatterlist *current_buffer;
-static int current_bufflen;
-
-#ifdef LINKED
-
-/*
- * linked_connected indicates whether or not we are currently connected to
- * linked_target, linked_lun and in an INFORMATION TRANSFER phase,
- * using linked commands.
- */
-
-static int linked_connected = 0;
-static unsigned char linked_target, linked_lun;
-#endif
-
-
-static void (*done_fn)(Scsi_Cmnd *) = NULL;
-static Scsi_Cmnd * SCint = NULL;
-
-/*
- * These control whether or not disconnect / reconnect will be attempted,
- * or are being attempted.
- */
-
-#define NO_RECONNECT 0
-#define RECONNECT_NOW 1
-#define CAN_RECONNECT 2
-
-#ifdef LINKED
-
-/*
- * LINKED_RIGHT indicates that we are currently connected to the correct target
- * for this command, LINKED_WRONG indicates that we are connected to the wrong
- * target. Note that these imply CAN_RECONNECT.
- */
-
-#define LINKED_RIGHT 3
-#define LINKED_WRONG 4
-#endif
-
-/*
- * This determines if we are expecting to reconnect or not.
- */
-
-static int should_reconnect = 0;
-
-/*
- * The seagate_reconnect_intr routine is called when a target reselects the
- * host adapter. This occurs on the interrupt triggered by the target
- * asserting SEL.
- */
-
-static void seagate_reconnect_intr(int irq, struct pt_regs * regs)
- {
- int temp;
- Scsi_Cmnd * SCtmp;
-
-/* enable all other interrupts. */
- sti();
-#if (DEBUG & PHASE_RESELECT)
- printk("scsi%d : seagate_reconnect_intr() called\n", hostno);
-#endif
-
- if (!should_reconnect)
- printk("scsi%d: unexpected interrupt.\n", hostno);
- else {
- should_reconnect = 0;
-
-#if (DEBUG & PHASE_RESELECT)
- printk("scsi%d : internal_command("
- "%d, %08x, %08x, %d, RECONNECT_NOW\n", hostno,
- current_target, current_data, current_bufflen);
-#endif
-
- temp = internal_command (current_target, current_lun,
- current_cmnd, current_data, current_bufflen,
- RECONNECT_NOW);
-
- if (msg_byte(temp) != DISCONNECT) {
- if (done_fn) {
-#if (DEBUG & PHASE_RESELECT)
- printk("scsi%d : done_fn(%d,%08x)", hostno,
- hostno, temp);
-#endif
- if(!SCint) panic("SCint == NULL in seagate");
- SCtmp = SCint;
- SCint = NULL;
- SCtmp->result = temp;
- done_fn (SCtmp);
- } else
- printk("done_fn() not defined.\n");
- }
- }
- }
-
-/*
- * The seagate_st0x_queue_command() function provides a queued interface
- * to the seagate SCSI driver. Basically, it just passes control onto the
- * seagate_command() function, after fixing it so that the done_fn()
- * is set to the one passed to the function. We have to be very careful,
- * because there are some commands on some devices that do not disconnect,
- * and if we simply call the done_fn when the command is done then another
- * command is started and queue_command is called again... We end up
- * overflowing the kernel stack, and this tends not to be such a good idea.
- */
-
-static int recursion_depth = 0;
-
-int seagate_st0x_queue_command (Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
- {
- int result, reconnect;
- Scsi_Cmnd * SCtmp;
-
- done_fn = done;
- current_target = SCpnt->target;
- current_lun = SCpnt->lun;
- (const void *) current_cmnd = SCpnt->cmnd;
- current_data = (unsigned char *) SCpnt->request_buffer;
- current_bufflen = SCpnt->request_bufflen;
- SCint = SCpnt;
- if(recursion_depth) {
- return 0;
- };
- recursion_depth++;
- do{
-#ifdef LINKED
-/*
- * Set linked command bit in control field of SCSI command.
- */
-
- current_cmnd[SCpnt->cmd_len] |= 0x01;
- if (linked_connected) {
-#if (DEBUG & DEBUG_LINKED)
- printk("scsi%d : using linked commands, current I_T_L nexus is ",
- hostno);
-#endif
- if ((linked_target == current_target) &&
- (linked_lun == current_lun)) {
-#if (DEBUG & DEBUG_LINKED)
- printk("correct\n");
-#endif
- reconnect = LINKED_RIGHT;
- } else {
-#if (DEBUG & DEBUG_LINKED)
- printk("incorrect\n");
-#endif
- reconnect = LINKED_WRONG;
- }
- } else
-#endif /* LINKED */
- reconnect = CAN_RECONNECT;
-
-
-
-
-
- result = internal_command (SCint->target, SCint->lun, SCint->cmnd, SCint->request_buffer,
- SCint->request_bufflen,
- reconnect);
- if (msg_byte(result) == DISCONNECT) break;
- SCtmp = SCint;
- SCint = NULL;
- SCtmp->result = result;
- done_fn (SCtmp);
- } while(SCint);
- recursion_depth--;
- return 0;
- }
-
-int seagate_st0x_command (Scsi_Cmnd * SCpnt) {
- return internal_command (SCpnt->target, SCpnt->lun, SCpnt->cmnd, SCpnt->request_buffer,
- SCpnt->request_bufflen,
- (int) NO_RECONNECT);
-}
-
-static int internal_command(unsigned char target, unsigned char lun, const void *cmnd,
- void *buff, int bufflen, int reselect) {
- int len = 0;
- unsigned char *data = NULL;
- struct scatterlist *buffer = NULL;
- int nobuffs = 0;
- int clock;
- int temp;
-#ifdef SLOW_HANDSHAKE
- int borken; /* Does the current target require Very Slow I/O ? */
-#endif
-
-
-#if (DEBUG & PHASE_DATAIN) || (DEBUG & PHASE_DATOUT)
- int transfered = 0;
-#endif
-
-#if (((DEBUG & PHASE_ETC) == PHASE_ETC) || (DEBUG & PRINT_COMMAND) || \
- (DEBUG & PHASE_EXIT))
- int i;
-#endif
-
-#if ((DEBUG & PHASE_ETC) == PHASE_ETC)
- int phase=0, newphase;
-#endif
-
- int done = 0;
- unsigned char status = 0;
- unsigned char message = 0;
- register unsigned char status_read;
-
- unsigned transfersize = 0, underflow = 0;
-
- incommand = 0;
- st0x_aborted = 0;
-
-#ifdef SLOW_HANDSHAKE
- borken = (int) SCint->device->borken;
-#endif
-
-#if (DEBUG & PRINT_COMMAND)
- printk ("scsi%d : target = %d, command = ", hostno, target);
- print_command((unsigned char *) cmnd);
- printk("\n");
-#endif
-
-#if (DEBUG & PHASE_RESELECT)
- switch (reselect) {
- case RECONNECT_NOW :
- printk("scsi%d : reconnecting\n", hostno);
- break;
-#ifdef LINKED
- case LINKED_RIGHT :
- printk("scsi%d : connected, can reconnect\n", hostno);
- break;
- case LINKED_WRONG :
- printk("scsi%d : connected to wrong target, can reconnect\n",
- hostno);
- break;
-#endif
- case CAN_RECONNECT :
- printk("scsi%d : allowed to reconnect\n", hostno);
- break;
- default :
- printk("scsi%d : not allowed to reconnect\n", hostno);
- }
-#endif
-
-
- if (target == (controller_type == SEAGATE ? 7 : 6))
- return DID_BAD_TARGET;
-
-/*
- * We work it differently depending on if this is is "the first time,"
- * or a reconnect. If this is a reselect phase, then SEL will
- * be asserted, and we must skip selection / arbitration phases.
- */
-
- switch (reselect) {
- case RECONNECT_NOW:
-#if (DEBUG & PHASE_RESELECT)
- printk("scsi%d : phase RESELECT \n", hostno);
-#endif
-
-/*
- * At this point, we should find the logical or of our ID and the original
- * target's ID on the BUS, with BSY, SEL, and I/O signals asserted.
- *
- * After ARBITRATION phase is completed, only SEL, BSY, and the
- * target ID are asserted. A valid initiator ID is not on the bus
- * until IO is asserted, so we must wait for that.
- */
- clock = jiffies + 10;
- for (;;) {
- temp = STATUS;
- if ((temp & STAT_IO) && !(temp & STAT_BSY))
- break;
-
- if (jiffies > clock) {
-#if (DEBUG & PHASE_RESELECT)
- printk("scsi%d : RESELECT timed out while waiting for IO .\n",
- hostno);
-#endif
- return (DID_BAD_INTR << 16);
- }
- }
-
-/*
- * After I/O is asserted by the target, we can read our ID and its
- * ID off of the BUS.
- */
-
- if (!((temp = DATA) & (controller_type == SEAGATE ? 0x80 : 0x40)))
- {
-#if (DEBUG & PHASE_RESELECT)
- printk("scsi%d : detected reconnect request to different target.\n"
- "\tData bus = %d\n", hostno, temp);
-#endif
- return (DID_BAD_INTR << 16);
- }
-
- if (!(temp & (1 << current_target)))
- {
- printk("scsi%d : Unexpected reselect interrupt. Data bus = %d\n",
- hostno, temp);
- return (DID_BAD_INTR << 16);
- }
-
- buffer=current_buffer;
- cmnd=current_cmnd; /* WDE add */
- data=current_data; /* WDE add */
- len=current_bufflen; /* WDE add */
- nobuffs=current_nobuffs;
-
-/*
- * We have determined that we have been selected. At this point,
- * we must respond to the reselection by asserting BSY ourselves
- */
-
-#if 1
- CONTROL = (BASE_CMD | CMD_DRVR_ENABLE | CMD_BSY);
-#else
- CONTROL = (BASE_CMD | CMD_BSY);
-#endif
-
-/*
- * The target will drop SEL, and raise BSY, at which time we must drop
- * BSY.
- */
-
- for (clock = jiffies + 10; (jiffies < clock) && (STATUS & STAT_SEL););
-
- if (jiffies >= clock)
- {
- CONTROL = (BASE_CMD | CMD_INTR);
-#if (DEBUG & PHASE_RESELECT)
- printk("scsi%d : RESELECT timed out while waiting for SEL.\n",
- hostno);
-#endif
- return (DID_BAD_INTR << 16);
- }
-
- CONTROL = BASE_CMD;
-
-/*
- * At this point, we have connected with the target and can get
- * on with our lives.
- */
- break;
- case CAN_RECONNECT:
-
-#ifdef LINKED
-/*
- * This is a bletcherous hack, just as bad as the Unix #! interpreter stuff.
- * If it turns out we are using the wrong I_T_L nexus, the easiest way to deal
- * with it is to go into our INFORMATION TRANSFER PHASE code, send a ABORT
- * message on MESSAGE OUT phase, and then loop back to here.
- */
-
-connect_loop :
-
-#endif
-
-#if (DEBUG & PHASE_BUS_FREE)
- printk ("scsi%d : phase = BUS FREE \n", hostno);
-#endif
-
-/*
- * BUS FREE PHASE
- *
- * On entry, we make sure that the BUS is in a BUS FREE
- * phase, by insuring that both BSY and SEL are low for
- * at least one bus settle delay. Several reads help
- * eliminate wire glitch.
- */
-
- clock = jiffies + ST0X_BUS_FREE_DELAY;
-
-#if !defined (ARBITRATE)
- while (((STATUS | STATUS | STATUS) &
- (STAT_BSY | STAT_SEL)) &&
- (!st0x_aborted) && (jiffies < clock));
-
- if (jiffies > clock)
- return retcode(DID_BUS_BUSY);
- else if (st0x_aborted)
- return retcode(st0x_aborted);
-#endif
-
-#if (DEBUG & PHASE_SELECTION)
- printk("scsi%d : phase = SELECTION\n", hostno);
-#endif
-
- clock = jiffies + ST0X_SELECTION_DELAY;
-
-/*
- * Arbitration/selection procedure :
- * 1. Disable drivers
- * 2. Write HOST adapter address bit
- * 3. Set start arbitration.
- * 4. We get either ARBITRATION COMPLETE or SELECT at this
- * point.
- * 5. OR our ID and targets on bus.
- * 6. Enable SCSI drivers and asserted SEL and ATTN
- */
-
-#if defined(ARBITRATE)
- cli();
- CONTROL = 0;
- DATA = (controller_type == SEAGATE) ? 0x80 : 0x40;
- CONTROL = CMD_START_ARB;
- sti();
- while (!((status_read = STATUS) & (STAT_ARB_CMPL | STAT_SEL)) &&
- (jiffies < clock) && !st0x_aborted);
-
- if (!(status_read & STAT_ARB_CMPL)) {
-#if (DEBUG & PHASE_SELECTION)
- if (status_read & STAT_SEL)
- printk("scsi%d : arbitration lost\n", hostno);
- else
- printk("scsi%d : arbitration timeout.\n", hostno);
-#endif
- CONTROL = BASE_CMD;
- return retcode(DID_NO_CONNECT);
- };
-
-#if (DEBUG & PHASE_SELECTION)
- printk("scsi%d : arbitration complete\n", hostno);
-#endif
-#endif
-
-
-/*
- * When the SCSI device decides that we're gawking at it, it will
- * respond by asserting BUSY on the bus.
- *
- * Note : the Seagate ST-01/02 product manual says that we should
- * twiddle the DATA register before the control register. However,
- * this does not work reliably so we do it the other way around.
- *
- * Probably could be a problem with arbitration too, we really should
- * try this with a SCSI protocol or logic analyzer to see what is
- * going on.
- */
- cli();
- DATA = (unsigned char) ((1 << target) | (controller_type == SEAGATE ? 0x80 : 0x40));
- CONTROL = BASE_CMD | CMD_DRVR_ENABLE | CMD_SEL |
- (reselect ? CMD_ATTN : 0);
- sti();
- while (!((status_read = STATUS) & STAT_BSY) &&
- (jiffies < clock) && !st0x_aborted)
-
-#if 0 && (DEBUG & PHASE_SELECTION)
- {
- temp = clock - jiffies;
-
- if (!(jiffies % 5))
- printk("seagate_st0x_timeout : %d \r",temp);
-
- }
- printk("Done. \n");
- printk("scsi%d : status = %02x, seagate_st0x_timeout = %d, aborted = %02x \n",
- hostno, status_read, temp, st0x_aborted);
-#else
- ;
-#endif
-
-
- if ((jiffies >= clock) && !(status_read & STAT_BSY))
- {
-#if (DEBUG & PHASE_SELECTION)
- printk ("scsi%d : NO CONNECT with target %d, status = %x \n",
- hostno, target, STATUS);
-#endif
- return retcode(DID_NO_CONNECT);
- }
-
-/*
- * If we have been aborted, and we have a command in progress, IE the
- * target still has BSY asserted, then we will reset the bus, and
- * notify the midlevel driver to expect sense.
- */
-
- if (st0x_aborted) {
- CONTROL = BASE_CMD;
- if (STATUS & STAT_BSY) {
- printk("scsi%d : BST asserted after we've been aborted.\n",
- hostno);
- seagate_st0x_reset(NULL);
- return retcode(DID_RESET);
- }
- return retcode(st0x_aborted);
- }
-
-/* Establish current pointers. Take into account scatter / gather */
-
- if ((nobuffs = SCint->use_sg)) {
-#if (DEBUG & DEBUG_SG)
- {
- int i;
- printk("scsi%d : scatter gather requested, using %d buffers.\n",
- hostno, nobuffs);
- for (i = 0; i < nobuffs; ++i)
- printk("scsi%d : buffer %d address = %08x length = %d\n",
- hostno, i, buffer[i].address, buffer[i].length);
- }
-#endif
-
- buffer = (struct scatterlist *) SCint->buffer;
- len = buffer->length;
- data = (unsigned char *) buffer->address;
- } else {
-#if (DEBUG & DEBUG_SG)
- printk("scsi%d : scatter gather not requested.\n", hostno);
-#endif
- buffer = NULL;
- len = SCint->request_bufflen;
- data = (unsigned char *) SCint->request_buffer;
- }
-
-#if (DEBUG & (PHASE_DATAIN | PHASE_DATAOUT))
- printk("scsi%d : len = %d\n", hostno, len);
-#endif
-
- break;
-#ifdef LINKED
- case LINKED_RIGHT:
- break;
- case LINKED_WRONG:
- break;
-#endif
- }
-
-/*
- * There are several conditions under which we wish to send a message :
- * 1. When we are allowing disconnect / reconnect, and need to establish
- * the I_T_L nexus via an IDENTIFY with the DiscPriv bit set.
- *
- * 2. When we are doing linked commands, are have the wrong I_T_L nexus
- * established and want to send an ABORT message.
- */
-
-
- CONTROL = BASE_CMD | CMD_DRVR_ENABLE |
- (((reselect == CAN_RECONNECT)
-#ifdef LINKED
- || (reselect == LINKED_WRONG)
-#endif
- ) ? CMD_ATTN : 0) ;
-
-/*
- * INFORMATION TRANSFER PHASE
- *
- * The nasty looking read / write inline assembler loops we use for
- * DATAIN and DATAOUT phases are approximately 4-5 times as fast as
- * the 'C' versions - since we're moving 1024 bytes of data, this
- * really adds up.
- */
-
-#if ((DEBUG & PHASE_ETC) == PHASE_ETC)
- printk("scsi%d : phase = INFORMATION TRANSFER\n", hostno);
-#endif
-
- incommand = 1;
- transfersize = SCint->transfersize;
- underflow = SCint->underflow;
-
-
-/*
- * Now, we poll the device for status information,
- * and handle any requests it makes. Note that since we are unsure of
- * how much data will be flowing across the system, etc and cannot
- * make reasonable timeouts, that we will instead have the midlevel
- * driver handle any timeouts that occur in this phase.
- */
-
- while (((status_read = STATUS) & STAT_BSY) && !st0x_aborted && !done)
- {
-#ifdef PARITY
- if (status_read & STAT_PARITY)
- {
- printk("scsi%d : got parity error\n", hostno);
- st0x_aborted = DID_PARITY;
- }
-#endif
-
- if (status_read & STAT_REQ)
- {
-#if ((DEBUG & PHASE_ETC) == PHASE_ETC)
- if ((newphase = (status_read & REQ_MASK)) != phase)
- {
- phase = newphase;
- switch (phase)
- {
- case REQ_DATAOUT:
- printk("scsi%d : phase = DATA OUT\n",
- hostno);
- break;
- case REQ_DATAIN :
- printk("scsi%d : phase = DATA IN\n",
- hostno);
- break;
- case REQ_CMDOUT :
- printk("scsi%d : phase = COMMAND OUT\n",
- hostno);
- break;
- case REQ_STATIN :
- printk("scsi%d : phase = STATUS IN\n",
- hostno);
- break;
- case REQ_MSGOUT :
- printk("scsi%d : phase = MESSAGE OUT\n",
- hostno);
- break;
- case REQ_MSGIN :
- printk("scsi%d : phase = MESSAGE IN\n",
- hostno);
- break;
- default :
- printk("scsi%d : phase = UNKNOWN\n",
- hostno);
- st0x_aborted = DID_ERROR;
- }
- }
-#endif
- switch (status_read & REQ_MASK)
- {
- case REQ_DATAOUT :
-/*
- * If we are in fast mode, then we simply splat the data out
- * in word-sized chunks as fast as we can.
- */
-
-#ifdef FAST
-if (!len) {
-#if 0
- printk("scsi%d: underflow to target %d lun %d \n",
- hostno, target, lun);
- st0x_aborted = DID_ERROR;
- fast = 0;
-#endif
- break;
-}
-
-if (fast && transfersize && !(len % transfersize) && (len >= transfersize)
-#ifdef FAST32
- && !(transfersize % 4)
-#endif
- ) {
-#if (DEBUG & DEBUG_FAST)
- printk("scsi%d : FAST transfer, underflow = %d, transfersize = %d\n"
- " len = %d, data = %08x\n", hostno, SCint->underflow,
- SCint->transfersize, len, data);
-#endif
-
- __asm__("
- cld;
-"
-#ifdef FAST32
-" shr $2, %%ecx;
-1: lodsl;
- movl %%eax, (%%edi);
-"
-#else
-"1: lodsb;
- movb %%al, (%%edi);
-"
-#endif
-" loop 1b;" : :
- /* input */
- "D" (st0x_dr), "S" (data), "c" (SCint->transfersize) :
- /* clobbered */
- "eax", "ecx", "esi" );
-
- len -= transfersize;
- data += transfersize;
-
-#if (DEBUG & DEBUG_FAST)
- printk("scsi%d : FAST transfer complete len = %d data = %08x\n",
- hostno, len, data);
-#endif
-
-
-} else
-#endif
-
-{
-/*
- * We loop as long as we are in a data out phase, there is data to send,
- * and BSY is still active.
- */
- __asm__ (
-
-/*
- Local variables :
- len = ecx
- data = esi
- st0x_cr_sr = ebx
- st0x_dr = edi
-
- Test for any data here at all.
-*/
- "\torl %%ecx, %%ecx
- jz 2f
-
- cld
-
- movl " SYMBOL_NAME_STR(st0x_cr_sr) ", %%ebx
- movl " SYMBOL_NAME_STR(st0x_dr) ", %%edi
-
-1: movb (%%ebx), %%al\n"
-/*
- Test for BSY
-*/
-
- "\ttest $1, %%al
- jz 2f\n"
-
-/*
- Test for data out phase - STATUS & REQ_MASK should be REQ_DATAOUT, which is 0.
-*/
- "\ttest $0xe, %%al
- jnz 2f \n"
-/*
- Test for REQ
-*/
- "\ttest $0x10, %%al
- jz 1b
- lodsb
- movb %%al, (%%edi)
- loop 1b
-
-2:
- ":
-/* output */
-"=S" (data), "=c" (len) :
-/* input */
-"0" (data), "1" (len) :
-/* clobbered */
-"eax", "ebx", "edi");
-}
-
- if (!len && nobuffs) {
- --nobuffs;
- ++buffer;
- len = buffer->length;
- data = (unsigned char *) buffer->address;
-#if (DEBUG & DEBUG_SG)
- printk("scsi%d : next scatter-gather buffer len = %d address = %08x\n",
- hostno, len, data);
-#endif
- }
- break;
-
- case REQ_DATAIN :
-#ifdef SLOW_HANDSHAKE
- if (borken) {
-#if (DEBUG & (PHASE_DATAIN))
- transfered += len;
-#endif
- for (; len && (STATUS & (REQ_MASK | STAT_REQ)) == (REQ_DATAIN |
- STAT_REQ); --len) {
- *data++ = DATA;
- borken_wait();
-}
-#if (DEBUG & (PHASE_DATAIN))
- transfered -= len;
-#endif
- } else
-#endif
-#ifdef FAST
-if (fast && transfersize && !(len % transfersize) && (len >= transfersize)
-#ifdef FAST32
- && !(transfersize % 4)
-#endif
- ) {
-#if (DEBUG & DEBUG_FAST)
- printk("scsi%d : FAST transfer, underflow = %d, transfersize = %d\n"
- " len = %d, data = %08x\n", hostno, SCint->underflow,
- SCint->transfersize, len, data);
-#endif
- __asm__("
- cld;
-"
-#ifdef FAST32
-" shr $2, %%ecx;
-1: movl (%%esi), %%eax;
- stosl;
-"
-#else
-"1: movb (%%esi), %%al;
- stosb;
-"
-#endif
-
-" loop 1b;" : :
- /* input */
- "S" (st0x_dr), "D" (data), "c" (SCint->transfersize) :
- /* clobbered */
- "eax", "ecx", "edi");
-
- len -= transfersize;
- data += transfersize;
-
-#if (DEBUG & PHASE_DATAIN)
- printk("scsi%d: transfered += %d\n", hostno, transfersize);
- transfered += transfersize;
-#endif
-
-#if (DEBUG & DEBUG_FAST)
- printk("scsi%d : FAST transfer complete len = %d data = %08x\n",
- hostno, len, data);
-#endif
-
-} else
-#endif
-{
-
-#if (DEBUG & PHASE_DATAIN)
- printk("scsi%d: transfered += %d\n", hostno, len);
- transfered += len; /* Assume we'll transfer it all, then
- subtract what we *didn't* transfer */
-#endif
-
-/*
- * We loop as long as we are in a data in phase, there is room to read,
- * and BSY is still active
- */
-
- __asm__ (
-/*
- Local variables :
- ecx = len
- edi = data
- esi = st0x_cr_sr
- ebx = st0x_dr
-
- Test for room to read
-*/
- "\torl %%ecx, %%ecx
- jz 2f
-
- cld
- movl " SYMBOL_NAME_STR(st0x_cr_sr) ", %%esi
- movl " SYMBOL_NAME_STR(st0x_dr) ", %%ebx
-
-1: movb (%%esi), %%al\n"
-/*
- Test for BSY
-*/
-
- "\ttest $1, %%al
- jz 2f\n"
-
-/*
- Test for data in phase - STATUS & REQ_MASK should be REQ_DATAIN, = STAT_IO, which is 4.
-*/
- "\tmovb $0xe, %%ah
- andb %%al, %%ah
- cmpb $0x04, %%ah
- jne 2f\n"
-
-/*
- Test for REQ
-*/
- "\ttest $0x10, %%al
- jz 1b
-
- movb (%%ebx), %%al
- stosb
- loop 1b\n"
-
-"2:\n"
- :
-/* output */
-"=D" (data), "=c" (len) :
-/* input */
-"0" (data), "1" (len) :
-/* clobbered */
-"eax","ebx", "esi");
-
-#if (DEBUG & PHASE_DATAIN)
- printk("scsi%d: transfered -= %d\n", hostno, len);
- transfered -= len; /* Since we assumed all of Len got
- * transfered, correct our mistake */
-#endif
-}
-
- if (!len && nobuffs) {
- --nobuffs;
- ++buffer;
- len = buffer->length;
- data = (unsigned char *) buffer->address;
-#if (DEBUG & DEBUG_SG)
- printk("scsi%d : next scatter-gather buffer len = %d address = %08x\n",
- hostno, len, data);
-#endif
- }
-
- break;
-
- case REQ_CMDOUT :
- while (((status_read = STATUS) & STAT_BSY) &&
- ((status_read & REQ_MASK) == REQ_CMDOUT))
- if (status_read & STAT_REQ) {
- DATA = *(const unsigned char *) cmnd;
- cmnd = 1+(const unsigned char *) cmnd;
-#ifdef SLOW_HANDSHAKE
- if (borken)
- borken_wait();
-#endif
- }
- break;
-
- case REQ_STATIN :
- status = DATA;
- break;
-
- case REQ_MSGOUT :
-/*
- * We can only have sent a MSG OUT if we requested to do this
- * by raising ATTN. So, we must drop ATTN.
- */
-
- CONTROL = BASE_CMD | CMD_DRVR_ENABLE;
-/*
- * If we are reconnecting, then we must send an IDENTIFY message in
- * response to MSGOUT.
- */
- switch (reselect) {
- case CAN_RECONNECT:
- DATA = IDENTIFY(1, lun);
-
-#if (DEBUG & (PHASE_RESELECT | PHASE_MSGOUT))
- printk("scsi%d : sent IDENTIFY message.\n", hostno);
-#endif
- break;
-#ifdef LINKED
- case LINKED_WRONG:
- DATA = ABORT;
- linked_connected = 0;
- reselect = CAN_RECONNECT;
- goto connect_loop;
-#if (DEBUG & (PHASE_MSGOUT | DEBUG_LINKED))
- printk("scsi%d : sent ABORT message to cancel incorrect I_T_L nexus.\n", hostno);
-#endif
-#endif /* LINKED */
-#if (DEBUG & DEBUG_LINKED)
- printk("correct\n");
-#endif
- default:
- DATA = NOP;
- printk("scsi%d : target %d requested MSGOUT, sent NOP message.\n", hostno, target);
- }
- break;
-
- case REQ_MSGIN :
- switch (message = DATA) {
- case DISCONNECT :
- should_reconnect = 1;
- current_data = data; /* WDE add */
- current_buffer = buffer;
- current_bufflen = len; /* WDE add */
- current_nobuffs = nobuffs;
-#ifdef LINKED
- linked_connected = 0;
-#endif
- done=1;
-#if (DEBUG & (PHASE_RESELECT | PHASE_MSGIN))
- printk("scsi%d : disconnected.\n", hostno);
-#endif
- break;
-
-#ifdef LINKED
- case LINKED_CMD_COMPLETE:
- case LINKED_FLG_CMD_COMPLETE:
-#endif
- case COMMAND_COMPLETE :
-/*
- * Note : we should check for underflow here.
- */
-#if (DEBUG & PHASE_MSGIN)
- printk("scsi%d : command complete.\n", hostno);
-#endif
- done = 1;
- break;
- case ABORT :
-#if (DEBUG & PHASE_MSGIN)
- printk("scsi%d : abort message.\n", hostno);
-#endif
- done=1;
- break;
- case SAVE_POINTERS :
- current_buffer = buffer;
- current_bufflen = len; /* WDE add */
- current_data = data; /* WDE mod */
- current_nobuffs = nobuffs;
-#if (DEBUG & PHASE_MSGIN)
- printk("scsi%d : pointers saved.\n", hostno);
-#endif
- break;
- case RESTORE_POINTERS:
- buffer=current_buffer;
- cmnd=current_cmnd;
- data=current_data; /* WDE mod */
- len=current_bufflen;
- nobuffs=current_nobuffs;
-#if (DEBUG & PHASE_MSGIN)
- printk("scsi%d : pointers restored.\n", hostno);
-#endif
- break;
- default:
-
-/*
- * IDENTIFY distinguishes itself from the other messages by setting the
- * high byte.
- *
- * Note : we need to handle at least one outstanding command per LUN,
- * and need to hash the SCSI command for that I_T_L nexus based on the
- * known ID (at this point) and LUN.
- */
-
- if (message & 0x80) {
-#if (DEBUG & PHASE_MSGIN)
- printk("scsi%d : IDENTIFY message received from id %d, lun %d.\n",
- hostno, target, message & 7);
-#endif
- } else {
-
-/*
- * We should go into a MESSAGE OUT phase, and send a MESSAGE_REJECT
- * if we run into a message that we don't like. The seagate driver
- * needs some serious restructuring first though.
- */
-
-#if (DEBUG & PHASE_MSGIN)
- printk("scsi%d : unknown message %d from target %d.\n",
- hostno, message, target);
-#endif
- }
- }
- break;
-
- default :
- printk("scsi%d : unknown phase.\n", hostno);
- st0x_aborted = DID_ERROR;
- }
-
-#ifdef SLOW_HANDSHAKE
-/*
- * I really don't care to deal with borken devices in each single
- * byte transfer case (ie, message in, message out, status), so
- * I'll do the wait here if necessary.
- */
- if (borken)
- borken_wait();
-#endif
-
- } /* if ends */
- } /* while ends */
-
-#if (DEBUG & (PHASE_DATAIN | PHASE_DATAOUT | PHASE_EXIT))
- printk("scsi%d : Transfered %d bytes\n", hostno, transfered);
-#endif
-
-#if (DEBUG & PHASE_EXIT)
-#if 0 /* Doesn't work for scatter / gather */
- printk("Buffer : \n");
- for (i = 0; i < 20; ++i)
- printk ("%02x ", ((unsigned char *) data)[i]); /* WDE mod */
- printk("\n");
-#endif
- printk("scsi%d : status = ", hostno);
- print_status(status);
- printk("message = %02x\n", message);
-#endif
-
-
-/* We shouldn't reach this until *after* BSY has been deasserted */
-#ifdef notyet
- if (st0x_aborted) {
- if (STATUS & STAT_BSY) {
- seagate_st0x_reset(NULL);
- st0x_aborted = DID_RESET;
- }
- abort_confirm = 1;
- }
-#endif
-
-#ifdef LINKED
-else {
-/*
- * Fix the message byte so that unsuspecting high level drivers don't
- * puke when they see a LINKED COMMAND message in place of the COMMAND
- * COMPLETE they may be expecting. Shouldn't be necessary, but it's
- * better to be on the safe side.
- *
- * A non LINKED* message byte will indicate that the command completed,
- * and we are now disconnected.
- */
-
- switch (message) {
- case LINKED_CMD_COMPLETE :
- case LINKED_FLG_CMD_COMPLETE :
- message = COMMAND_COMPLETE;
- linked_target = current_target;
- linked_lun = current_lun;
- linked_connected = 1;
-#if (DEBUG & DEBUG_LINKED)
- printk("scsi%d : keeping I_T_L nexus established for linked command.\n",
- hostno);
-#endif
-/*
- * We also will need to adjust status to accommodate intermediate conditions.
- */
- if ((status == INTERMEDIATE_GOOD) ||
- (status == INTERMEDIATE_C_GOOD))
- status = GOOD;
-
- break;
-/*
- * We should also handle what are "normal" termination messages
- * here (ABORT, BUS_DEVICE_RESET?, and COMMAND_COMPLETE individually,
- * and flake if things aren't right.
- */
-
- default :
-#if (DEBUG & DEBUG_LINKED)
- printk("scsi%d : closing I_T_L nexus.\n", hostno);
-#endif
- linked_connected = 0;
- }
- }
-#endif /* LINKED */
-
-
-
-
- if (should_reconnect) {
-#if (DEBUG & PHASE_RESELECT)
- printk("scsi%d : exiting seagate_st0x_queue_command() with reconnect enabled.\n",
- hostno);
-#endif
- CONTROL = BASE_CMD | CMD_INTR ;
- } else
- CONTROL = BASE_CMD;
-
- return retcode (st0x_aborted);
- }
-
-int seagate_st0x_abort (Scsi_Cmnd * SCpnt)
- {
- st0x_aborted = DID_ABORT;
-
- return SCSI_ABORT_PENDING;
- }
-
-/*
- the seagate_st0x_reset function resets the SCSI bus
-*/
-
-int seagate_st0x_reset (Scsi_Cmnd * SCpnt)
- {
- unsigned clock;
- /*
- No timeouts - this command is going to fail because
- it was reset.
- */
-
-#ifdef DEBUG
- printk("In seagate_st0x_reset()\n");
-#endif
-
-
- /* assert RESET signal on SCSI bus. */
-
- CONTROL = BASE_CMD | CMD_RST;
- clock=jiffies+2;
-
-
- /* Wait. */
-
- while (jiffies < clock);
-
- CONTROL = BASE_CMD;
-
- st0x_aborted = DID_RESET;
-
-#ifdef DEBUG
- printk("SCSI bus reset.\n");
-#endif
- return SCSI_RESET_WAKEUP;
- }
-
-#include <asm/segment.h>
-#include "sd.h"
-#include "scsi_ioctl.h"
-
-int seagate_st0x_biosparam(Disk * disk, kdev_t dev, int* ip) {
- unsigned char buf[256 + sizeof(int) * 2], cmd[6], *data, *page;
- int *sizes, result, formatted_sectors, total_sectors;
- int cylinders, heads, sectors;
-
-/*
- * Only SCSI-I CCS drives and later implement the necessary mode sense
- * pages.
- */
-
- if (disk->device->scsi_level < 2)
- return -1;
-
- sizes = (int *) buf;
- data = (unsigned char *) (sizes + 2);
-
- cmd[0] = MODE_SENSE;
- cmd[1] = (disk->device->lun << 5) & 0xe5;
- cmd[2] = 0x04; /* Read page 4, rigid disk geometry page current values */
- cmd[3] = 0;
- cmd[4] = 255;
- cmd[5] = 0;
-
-/*
- * We are transferring 0 bytes in the out direction, and expect to get back
- * 24 bytes for each mode page.
- */
-
- sizes[0] = 0;
- sizes[1] = 256;
-
- memcpy (data, cmd, 6);
-
- if (!(result = kernel_scsi_ioctl (disk->device, SCSI_IOCTL_SEND_COMMAND, (void *) buf))) {
-/*
- * The mode page lies beyond the MODE SENSE header, with length 4, and
- * the BLOCK DESCRIPTOR, with length header[3].
- */
-
- page = data + 4 + data[3];
- heads = (int) page[5];
- cylinders = (page[2] << 16) | (page[3] << 8) | page[4];
-
- cmd[2] = 0x03; /* Read page 3, format page current values */
- memcpy (data, cmd, 6);
-
- if (!(result = kernel_scsi_ioctl (disk->device, SCSI_IOCTL_SEND_COMMAND, (void *) buf))) {
- page = data + 4 + data[3];
- sectors = (page[10] << 8) | page[11];
-
-
-/*
- * Get the total number of formatted sectors from the block descriptor,
- * so we can tell how many are being used for alternates.
- */
-
- formatted_sectors = (data[4 + 1] << 16) | (data[4 + 2] << 8) |
- data[4 + 3] ;
-
- total_sectors = (heads * cylinders * sectors);
-
-/*
- * Adjust the real geometry by subtracting
- * (spare sectors / (heads * tracks)) cylinders from the number of cylinders.
- *
- * It appears that the CE cylinder CAN be a partial cylinder.
- */
-
-
-printk("scsi%d : heads = %d cylinders = %d sectors = %d total = %d formatted = %d\n",
- hostno, heads, cylinders, sectors, total_sectors, formatted_sectors);
-
- if (!heads || !sectors || !cylinders)
- result = -1;
- else
- cylinders -= ((total_sectors - formatted_sectors) / (heads * sectors));
-
-/*
- * Now, we need to do a sanity check on the geometry to see if it is
- * BIOS compatible. The maximum BIOS geometry is 1024 cylinders *
- * 256 heads * 64 sectors.
- */
-
- if ((cylinders > 1024) || (sectors > 64))
- result = -1;
- else {
- ip[0] = heads;
- ip[1] = sectors;
- ip[2] = cylinders;
- }
-
-/*
- * There should be an alternate mapping for things the seagate doesn't
- * understand, but I couldn't say what it is with reasonable certainty.
- */
-
- }
- }
-
- return result;
-}
-
-#ifdef MODULE
-/* Eventually this will go into an include file, but this will be later */
-Scsi_Host_Template driver_template = SEAGATE_ST0X;
-
-#include "scsi_module.c"
-#endif
diff --git a/i386/i386at/gpl/linux/scsi/seagate.h b/i386/i386at/gpl/linux/scsi/seagate.h
deleted file mode 100644
index 8d9e1a42..00000000
--- a/i386/i386at/gpl/linux/scsi/seagate.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * seagate.h Copyright (C) 1992 Drew Eckhardt
- * low level scsi driver header for ST01/ST02 by
- * Drew Eckhardt
- *
- * <drew@colorado.edu>
- */
-
-#ifndef _SEAGATE_H
- #define SEAGATE_H
-/*
- $Header
-*/
-#ifndef ASM
-int seagate_st0x_detect(Scsi_Host_Template *);
-int seagate_st0x_command(Scsi_Cmnd *);
-int seagate_st0x_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-
-int seagate_st0x_abort(Scsi_Cmnd *);
-const char *seagate_st0x_info(struct Scsi_Host *);
-int seagate_st0x_reset(Scsi_Cmnd *);
-int seagate_st0x_proc_info(char *,char **,off_t,int,int,int);
-
-#ifndef NULL
- #define NULL 0
-#endif
-
-#include <linux/kdev_t.h>
-int seagate_st0x_biosparam(Disk *, kdev_t, int*);
-
-#define SEAGATE_ST0X { NULL, NULL, NULL, seagate_st0x_proc_info, \
- NULL, seagate_st0x_detect, \
- NULL, \
- seagate_st0x_info, seagate_st0x_command, \
- seagate_st0x_queue_command, seagate_st0x_abort, \
- seagate_st0x_reset, NULL, seagate_st0x_biosparam, \
- 1, 7, SG_ALL, 1, 0, 0, DISABLE_CLUSTERING}
-#endif
-
-
-/*
- defining PARITY causes parity data to be checked
-*/
-
-#define PARITY
-
-
-/*
- Thanks to Brian Antoine for the example code in his Messy-Loss ST-01
- driver, and Mitsugu Suzuki for information on the ST-01
- SCSI host.
-*/
-
-/*
- CONTROL defines
-*/
-
-#define CMD_RST 0x01
-#define CMD_SEL 0x02
-#define CMD_BSY 0x04
-#define CMD_ATTN 0x08
-#define CMD_START_ARB 0x10
-#define CMD_EN_PARITY 0x20
-#define CMD_INTR 0x40
-#define CMD_DRVR_ENABLE 0x80
-
-/*
- STATUS
-*/
-
-#define STAT_BSY 0x01
-#define STAT_MSG 0x02
-#define STAT_IO 0x04
-#define STAT_CD 0x08
-#define STAT_REQ 0x10
-#define STAT_SEL 0x20
-#define STAT_PARITY 0x40
-#define STAT_ARB_CMPL 0x80
-
-/*
- REQUESTS
-*/
-
-#define REQ_MASK (STAT_CD | STAT_IO | STAT_MSG)
-#define REQ_DATAOUT 0
-#define REQ_DATAIN STAT_IO
-#define REQ_CMDOUT STAT_CD
-#define REQ_STATIN (STAT_CD | STAT_IO)
-#define REQ_MSGOUT (STAT_MSG | STAT_CD)
-#define REQ_MSGIN (STAT_MSG | STAT_CD | STAT_IO)
-
-extern volatile int seagate_st0x_timeout;
-
-#ifdef PARITY
- #define BASE_CMD CMD_EN_PARITY
-#else
- #define BASE_CMD 0
-#endif
-
-/*
- Debugging code
-*/
-
-#define PHASE_BUS_FREE 1
-#define PHASE_ARBITRATION 2
-#define PHASE_SELECTION 4
-#define PHASE_DATAIN 8
-#define PHASE_DATAOUT 0x10
-#define PHASE_CMDOUT 0x20
-#define PHASE_MSGIN 0x40
-#define PHASE_MSGOUT 0x80
-#define PHASE_STATUSIN 0x100
-#define PHASE_ETC (PHASE_DATAIN | PHASE_DATA_OUT | PHASE_CMDOUT | PHASE_MSGIN | PHASE_MSGOUT | PHASE_STATUSIN)
-#define PRINT_COMMAND 0x200
-#define PHASE_EXIT 0x400
-#define PHASE_RESELECT 0x800
-#define DEBUG_FAST 0x1000
-#define DEBUG_SG 0x2000
-#define DEBUG_LINKED 0x4000
-#define DEBUG_BORKEN 0x8000
-
-/*
- * Control options - these are timeouts specified in .01 seconds.
- */
-
-/* 30, 20 work */
-#define ST0X_BUS_FREE_DELAY 25
-#define ST0X_SELECTION_DELAY 25
-
-#define eoi() __asm__("push %%eax\nmovb $0x20, %%al\noutb %%al, $0x20\npop %%eax"::)
-
-#define SEAGATE 1 /* these determine the type of the controller */
-#define FD 2
-
-#define ST0X_ID_STR "Seagate ST-01/ST-02"
-#define FD_ID_STR "TMC-8XX/TMC-950"
-
-#endif
-
diff --git a/i386/i386at/gpl/linux/scsi/sr.c b/i386/i386at/gpl/linux/scsi/sr.c
deleted file mode 100644
index dc15cf58..00000000
--- a/i386/i386at/gpl/linux/scsi/sr.c
+++ /dev/null
@@ -1,1191 +0,0 @@
-/*
- * sr.c Copyright (C) 1992 David Giller
- * Copyright (C) 1993, 1994, 1995 Eric Youngdale
- *
- * adapted from:
- * sd.c Copyright (C) 1992 Drew Eckhardt
- * Linux scsi disk driver by
- * Drew Eckhardt <drew@colorado.edu>
- *
- * Modified by Eric Youngdale ericy@cais.com to
- * add scatter-gather, multiple outstanding request, and other
- * enhancements.
- *
- * Modified by Eric Youngdale eric@aib.com to support loadable
- * low-level scsi drivers.
- *
- * Modified by Thomas Quinot thomas@melchior.cuivre.fdn.fr to
- * provide auto-eject.
- *
- */
-
-#include <linux/module.h>
-
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/cdrom.h>
-#include <asm/system.h>
-
-#define MAJOR_NR SCSI_CDROM_MAJOR
-#include <linux/blk.h>
-#include "scsi.h"
-#include "hosts.h"
-#include "sr.h"
-#include "scsi_ioctl.h" /* For the door lock/unlock commands */
-#include "constants.h"
-
-#define MAX_RETRIES 3
-#define SR_TIMEOUT (150 * HZ)
-
-static int sr_init(void);
-static void sr_finish(void);
-static int sr_attach(Scsi_Device *);
-static int sr_detect(Scsi_Device *);
-static void sr_detach(Scsi_Device *);
-
-struct Scsi_Device_Template sr_template = {NULL, "cdrom", "sr", NULL, TYPE_ROM,
- SCSI_CDROM_MAJOR, 0, 0, 0, 1,
- sr_detect, sr_init,
- sr_finish, sr_attach, sr_detach};
-
-Scsi_CD * scsi_CDs = NULL;
-static int * sr_sizes;
-
-static int * sr_blocksizes;
-
-static int sr_open(struct inode *, struct file *);
-static void get_sectorsize(int);
-
-extern int sr_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
-
-void requeue_sr_request (Scsi_Cmnd * SCpnt);
-static int check_cdrom_media_change(kdev_t);
-
-static void sr_release(struct inode * inode, struct file * file)
-{
- sync_dev(inode->i_rdev);
- if(! --scsi_CDs[MINOR(inode->i_rdev)].device->access_count)
- {
- sr_ioctl(inode, NULL, SCSI_IOCTL_DOORUNLOCK, 0);
- if (scsi_CDs[MINOR(inode->i_rdev)].auto_eject)
- sr_ioctl(inode, NULL, CDROMEJECT, 0);
- }
- if (scsi_CDs[MINOR(inode->i_rdev)].device->host->hostt->usage_count)
- (*scsi_CDs[MINOR(inode->i_rdev)].device->host->hostt->usage_count)--;
- if(sr_template.usage_count) (*sr_template.usage_count)--;
-}
-
-static struct file_operations sr_fops =
-{
- NULL, /* lseek - default */
- block_read, /* read - general block-dev read */
- block_write, /* write - general block-dev write */
- NULL, /* readdir - bad */
- NULL, /* select */
- sr_ioctl, /* ioctl */
- NULL, /* mmap */
- sr_open, /* special open code */
- sr_release, /* release */
- NULL, /* fsync */
- NULL, /* fasync */
- check_cdrom_media_change, /* Disk change */
- NULL /* revalidate */
-};
-
-/*
- * This function checks to see if the media has been changed in the
- * CDROM drive. It is possible that we have already sensed a change,
- * or the drive may have sensed one and not yet reported it. We must
- * be ready for either case. This function always reports the current
- * value of the changed bit. If flag is 0, then the changed bit is reset.
- * This function could be done as an ioctl, but we would need to have
- * an inode for that to work, and we do not always have one.
- */
-
-int check_cdrom_media_change(kdev_t full_dev){
- int retval, target;
- struct inode inode;
- int flag = 0;
-
- target = MINOR(full_dev);
-
- if (target >= sr_template.nr_dev) {
- printk("CD-ROM request error: invalid device.\n");
- return 0;
- };
-
- inode.i_rdev = full_dev; /* This is all we really need here */
- retval = sr_ioctl(&inode, NULL, SCSI_IOCTL_TEST_UNIT_READY, 0);
-
- if(retval){ /* Unable to test, unit probably not ready. This usually
- * means there is no disc in the drive. Mark as changed,
- * and we will figure it out later once the drive is
- * available again. */
-
- scsi_CDs[target].device->changed = 1;
- return 1; /* This will force a flush, if called from
- * check_disk_change */
- };
-
- retval = scsi_CDs[target].device->changed;
- if(!flag) {
- scsi_CDs[target].device->changed = 0;
- /* If the disk changed, the capacity will now be different,
- * so we force a re-read of this information */
- if (retval) scsi_CDs[target].needs_sector_size = 1;
- };
- return retval;
-}
-
-/*
- * rw_intr is the interrupt routine for the device driver. It will be notified on the
- * end of a SCSI read / write, and will take on of several actions based on success or failure.
- */
-
-static void rw_intr (Scsi_Cmnd * SCpnt)
-{
- int result = SCpnt->result;
- int this_count = SCpnt->this_count;
-
-#ifdef DEBUG
- printk("sr.c done: %x %x\n",result, SCpnt->request.bh->b_data);
-#endif
- if (!result)
- { /* No error */
- if (SCpnt->use_sg == 0) {
- if (SCpnt->buffer != SCpnt->request.buffer)
- {
- int offset;
- offset = (SCpnt->request.sector % 4) << 9;
- memcpy((char *)SCpnt->request.buffer,
- (char *)SCpnt->buffer + offset,
- this_count << 9);
- /* Even though we are not using scatter-gather, we look
- * ahead and see if there is a linked request for the
- * other half of this buffer. If there is, then satisfy
- * it. */
- if((offset == 0) && this_count == 2 &&
- SCpnt->request.nr_sectors > this_count &&
- SCpnt->request.bh &&
- SCpnt->request.bh->b_reqnext &&
- SCpnt->request.bh->b_reqnext->b_size == 1024) {
- memcpy((char *)SCpnt->request.bh->b_reqnext->b_data,
- (char *)SCpnt->buffer + 1024,
- 1024);
- this_count += 2;
- };
-
- scsi_free(SCpnt->buffer, 2048);
- }
- } else {
- struct scatterlist * sgpnt;
- int i;
- sgpnt = (struct scatterlist *) SCpnt->buffer;
- for(i=0; i<SCpnt->use_sg; i++) {
- if (sgpnt[i].alt_address) {
- if (sgpnt[i].alt_address != sgpnt[i].address) {
- memcpy(sgpnt[i].alt_address, sgpnt[i].address, sgpnt[i].length);
- };
- scsi_free(sgpnt[i].address, sgpnt[i].length);
- };
- };
- scsi_free(SCpnt->buffer, SCpnt->sglist_len); /* Free list of scatter-gather pointers */
- if(SCpnt->request.sector % 4) this_count -= 2;
- /* See if there is a padding record at the end that needs to be removed */
- if(this_count > SCpnt->request.nr_sectors)
- this_count -= 2;
- };
-
-#ifdef DEBUG
- printk("(%x %x %x) ",SCpnt->request.bh, SCpnt->request.nr_sectors,
- this_count);
-#endif
- if (SCpnt->request.nr_sectors > this_count)
- {
- SCpnt->request.errors = 0;
- if (!SCpnt->request.bh)
- panic("sr.c: linked page request (%lx %x)",
- SCpnt->request.sector, this_count);
- }
-
- SCpnt = end_scsi_request(SCpnt, 1, this_count); /* All done */
- requeue_sr_request(SCpnt);
- return;
- } /* Normal completion */
-
- /* We only come through here if we have an error of some kind */
-
- /* Free up any indirection buffers we allocated for DMA purposes. */
- if (SCpnt->use_sg) {
- struct scatterlist * sgpnt;
- int i;
- sgpnt = (struct scatterlist *) SCpnt->buffer;
- for(i=0; i<SCpnt->use_sg; i++) {
- if (sgpnt[i].alt_address) {
- scsi_free(sgpnt[i].address, sgpnt[i].length);
- };
- };
- scsi_free(SCpnt->buffer, SCpnt->sglist_len); /* Free list of scatter-gather pointers */
- } else {
- if (SCpnt->buffer != SCpnt->request.buffer)
- scsi_free(SCpnt->buffer, SCpnt->bufflen);
- };
-
- if (driver_byte(result) != 0) {
- if ((SCpnt->sense_buffer[0] & 0x7f) == 0x70) {
- if ((SCpnt->sense_buffer[2] & 0xf) == UNIT_ATTENTION) {
- /* detected disc change. set a bit and quietly refuse
- * further access. */
-
- scsi_CDs[DEVICE_NR(SCpnt->request.rq_dev)].device->changed = 1;
- SCpnt = end_scsi_request(SCpnt, 0, this_count);
- requeue_sr_request(SCpnt);
- return;
- }
- }
-
- if (SCpnt->sense_buffer[2] == ILLEGAL_REQUEST) {
- printk("CD-ROM error: ");
- print_sense("sr", SCpnt);
- printk("command was: ");
- print_command(SCpnt->cmnd);
- if (scsi_CDs[DEVICE_NR(SCpnt->request.rq_dev)].ten) {
- scsi_CDs[DEVICE_NR(SCpnt->request.rq_dev)].ten = 0;
- requeue_sr_request(SCpnt);
- result = 0;
- return;
- } else {
- SCpnt = end_scsi_request(SCpnt, 0, this_count);
- requeue_sr_request(SCpnt); /* Do next request */
- return;
- }
-
- }
-
- if (SCpnt->sense_buffer[2] == NOT_READY) {
- printk("CDROM not ready. Make sure you have a disc in the drive.\n");
- SCpnt = end_scsi_request(SCpnt, 0, this_count);
- requeue_sr_request(SCpnt); /* Do next request */
- return;
- };
- }
-
- /* We only get this far if we have an error we have not recognized */
- if(result) {
- printk("SCSI CD error : host %d id %d lun %d return code = %03x\n",
- scsi_CDs[DEVICE_NR(SCpnt->request.rq_dev)].device->host->host_no,
- scsi_CDs[DEVICE_NR(SCpnt->request.rq_dev)].device->id,
- scsi_CDs[DEVICE_NR(SCpnt->request.rq_dev)].device->lun,
- result);
-
- if (status_byte(result) == CHECK_CONDITION)
- print_sense("sr", SCpnt);
-
- SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.current_nr_sectors);
- requeue_sr_request(SCpnt);
- }
-}
-
-/*
- * Here I tried to implement better support for PhotoCD's.
- *
- * Much of this has do be done with vendor-specific SCSI-commands.
- * So I have to complete it step by step. Useful information is welcome.
- *
- * Actually works:
- * - NEC: Detection and support of multisession CD's. Special handling
- * for XA-disks is not necessary.
- *
- * - TOSHIBA: setting density is done here now, mounting PhotoCD's should
- * work now without running the program "set_density"
- * Multisession CD's are supported too.
- *
- * kraxel@cs.tu-berlin.de (Gerd Knorr)
- */
-/*
- * 19950704 operator@melchior.cuivre.fdn.fr (Thomas Quinot)
- *
- * - SONY: Same as Nec.
- *
- * - PIONEER: works with SONY code
- */
-
-static void sr_photocd(struct inode *inode)
-{
- unsigned long sector,min,sec,frame;
- unsigned char buf[40]; /* the buffer for the ioctl */
- unsigned char *cmd; /* the scsi-command */
- unsigned char *send; /* the data we send to the drive ... */
- unsigned char *rec; /* ... and get back */
- int rc,is_xa,no_multi;
-
- if (scsi_CDs[MINOR(inode->i_rdev)].xa_flags & 0x02) {
-#ifdef DEBUG
- printk("sr_photocd: CDROM and/or the driver does not support multisession CD's");
-#endif
- return;
- }
-
- if (!suser()) {
- /* I'm not the superuser, so SCSI_IOCTL_SEND_COMMAND isn't allowed for me.
- * That's why mpcd_sector will be initialized with zero, because I'm not
- * able to get the right value. Necessary only if access_count is 1, else
- * no disk change happened since the last call of this function and we can
- * keep the old value.
- */
- if (1 == scsi_CDs[MINOR(inode->i_rdev)].device->access_count) {
- scsi_CDs[MINOR(inode->i_rdev)].mpcd_sector = 0;
- scsi_CDs[MINOR(inode->i_rdev)].xa_flags &= ~0x01;
- }
- return;
- }
-
- sector = 0;
- is_xa = 0;
- no_multi = 0;
- cmd = rec = &buf[8];
-
- switch(scsi_CDs[MINOR(inode->i_rdev)].device->manufacturer) {
-
- case SCSI_MAN_NEC:
-#ifdef DEBUG
- printk("sr_photocd: use NEC code\n");
-#endif
- memset(buf,0,40);
- *((unsigned long*)buf) = 0x0; /* we send nothing... */
- *((unsigned long*)buf+1) = 0x16; /* and receive 0x16 bytes */
- cmd[0] = 0xde;
- cmd[1] = 0x03;
- cmd[2] = 0xb0;
- rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
- SCSI_IOCTL_SEND_COMMAND, buf);
- if (rc != 0) {
- printk("sr_photocd: ioctl error (NEC): 0x%x\n",rc);
- break;
- }
- if (rec[14] != 0 && rec[14] != 0xb0) {
- printk("sr_photocd: (NEC) Hmm, seems the CDROM doesn't support multisession CD's\n");
- no_multi = 1;
- break;
- }
- min = (unsigned long) rec[15]/16*10 + (unsigned long) rec[15]%16;
- sec = (unsigned long) rec[16]/16*10 + (unsigned long) rec[16]%16;
- frame = (unsigned long) rec[17]/16*10 + (unsigned long) rec[17]%16;
- sector = min*CD_SECS*CD_FRAMES + sec*CD_FRAMES + frame;
- is_xa = (rec[14] == 0xb0);
-#ifdef DEBUG
- if (sector) {
- printk("sr_photocd: multisession CD detected. start: %lu\n",sector);
- }
-#endif
- break;
-
- case SCSI_MAN_TOSHIBA:
-#ifdef DEBUG
- printk("sr_photocd: use TOSHIBA code\n");
-#endif
-
- /* we request some disc information (is it a XA-CD ?,
- * where starts the last session ?) */
- memset(buf,0,40);
- *((unsigned long*)buf) = 0;
- *((unsigned long*)buf+1) = 4; /* we receive 4 bytes from the drive */
- cmd[0] = 0xc7;
- cmd[1] = 3;
- rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
- SCSI_IOCTL_SEND_COMMAND, buf);
- if (rc != 0) {
- if (rc == 0x28000002) {
- /* Got a "not ready" - error. No chance to find out if this is
- * because there is no CD in the drive or because the drive
- * don't knows multisession CD's. So I need to do an extra check... */
- if (kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
- SCSI_IOCTL_TEST_UNIT_READY, NULL)) {
- printk("sr_photocd: drive not ready\n");
- } else {
- printk("sr_photocd: (TOSHIBA) Hmm, seems the CDROM doesn't support multisession CD's\n");
- no_multi = 1;
- }
- } else
- printk("sr_photocd: ioctl error (TOSHIBA #1): 0x%x\n",rc);
- break; /* if the first ioctl fails, we don't call the second one */
- }
- is_xa = (rec[0] == 0x20);
- min = (unsigned long) rec[1]/16*10 + (unsigned long) rec[1]%16;
- sec = (unsigned long) rec[2]/16*10 + (unsigned long) rec[2]%16;
- frame = (unsigned long) rec[3]/16*10 + (unsigned long) rec[3]%16;
- sector = min*CD_SECS*CD_FRAMES + sec*CD_FRAMES + frame;
- if (sector) {
- sector -= CD_BLOCK_OFFSET;
-#ifdef DEBUG
- printk("sr_photocd: multisession CD detected: start: %lu\n",sector);
-#endif
- }
-
- /* now we do a get_density... */
- memset(buf,0,40);
- *((unsigned long*)buf) = 0;
- *((unsigned long*)buf+1) = 12;
- cmd[0] = 0x1a;
- cmd[2] = 1;
- cmd[4] = 12;
- rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
- SCSI_IOCTL_SEND_COMMAND, buf);
- if (rc != 0) {
- printk("sr_photocd: ioctl error (TOSHIBA #2): 0x%x\n",rc);
- break;
- }
-#ifdef DEBUG
- printk("sr_photocd: get_density: 0x%x\n",rec[4]);
-#endif
-
- /* ...and only if necessary a set_density */
- if ((rec[4] != 0x81 && is_xa) || (rec[4] != 0 && !is_xa)) {
-#ifdef DEBUG
- printk("sr_photocd: doing set_density\n");
-#endif
- memset(buf,0,40);
- *((unsigned long*)buf) = 12; /* sending 12 bytes... */
- *((unsigned long*)buf+1) = 0;
- cmd[0] = 0x15;
- cmd[1] = (1 << 4);
- cmd[4] = 12;
- send = &cmd[6]; /* this is a 6-Byte command */
- send[ 3] = 0x08; /* the data for the command */
- send[ 4] = (is_xa) ? 0x81 : 0; /* density 0x81 for XA-CD's, 0 else */
- send[10] = 0x08;
- rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
- SCSI_IOCTL_SEND_COMMAND, buf);
- if (rc != 0) {
- printk("sr_photocd: ioctl error (TOSHIBA #3): 0x%x\n",rc);
- }
- /* The set_density command may have changed the sector size or capacity. */
- scsi_CDs[MINOR(inode->i_rdev)].needs_sector_size = 1;
- }
- break;
-
- case SCSI_MAN_SONY: /* Thomas QUINOT <thomas@melchior.cuivre.fdn.fr> */
- case SCSI_MAN_PIONEER:
-#ifdef DEBUG
- printk("sr_photocd: use SONY/PIONEER code\n");
-#endif
- memset(buf,0,40);
- *((unsigned long*)buf) = 0x0; /* we send nothing... */
- *((unsigned long*)buf+1) = 0x0c; /* and receive 0x0c bytes */
- cmd[0] = 0x43; /* Read TOC */
- cmd[8] = 0x0c;
- cmd[9] = 0x40;
- rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
- SCSI_IOCTL_SEND_COMMAND, buf);
-
- if (rc != 0) {
- printk("sr_photocd: ioctl error (SONY): 0x%x\n",rc);
- break;
- }
- if ((rec[0] << 8) + rec[1] != 0x0a) {
- printk("sr_photocd: (SONY) Hmm, seems the CDROM doesn't support multisession CD's\n");
- no_multi = 1;
- break;
- }
- sector = rec[11] + (rec[10] << 8) + (rec[9] << 16) + (rec[8] << 24);
- is_xa = !!sector;
-#ifdef DEBUG
- if (sector)
- printk ("sr_photocd: multisession CD detected. start: %lu\n",sector);
-#endif
- break;
-
- case SCSI_MAN_NEC_OLDCDR:
- case SCSI_MAN_UNKNOWN:
- default:
- sector = 0;
- no_multi = 1;
- break; }
-
- scsi_CDs[MINOR(inode->i_rdev)].mpcd_sector = sector;
- if (is_xa)
- scsi_CDs[MINOR(inode->i_rdev)].xa_flags |= 0x01;
- else
- scsi_CDs[MINOR(inode->i_rdev)].xa_flags &= ~0x01;
- if (no_multi)
- scsi_CDs[MINOR(inode->i_rdev)].xa_flags |= 0x02;
- return;
-}
-
-static int sr_open(struct inode * inode, struct file * filp)
-{
- if(MINOR(inode->i_rdev) >= sr_template.nr_dev ||
- !scsi_CDs[MINOR(inode->i_rdev)].device) return -ENXIO; /* No such device */
-
- if (filp->f_mode & 2)
- return -EROFS;
-
- check_disk_change(inode->i_rdev);
-
- if(!scsi_CDs[MINOR(inode->i_rdev)].device->access_count++)
- sr_ioctl(inode, NULL, SCSI_IOCTL_DOORLOCK, 0);
- if (scsi_CDs[MINOR(inode->i_rdev)].device->host->hostt->usage_count)
- (*scsi_CDs[MINOR(inode->i_rdev)].device->host->hostt->usage_count)++;
- if(sr_template.usage_count) (*sr_template.usage_count)++;
-
- sr_photocd(inode);
-
- /* If this device did not have media in the drive at boot time, then
- * we would have been unable to get the sector size. Check to see if
- * this is the case, and try again.
- */
-
- if(scsi_CDs[MINOR(inode->i_rdev)].needs_sector_size)
- get_sectorsize(MINOR(inode->i_rdev));
-
- return 0;
-}
-
-
-/*
- * do_sr_request() is the request handler function for the sr driver.
- * Its function in life is to take block device requests, and
- * translate them to SCSI commands.
- */
-
-static void do_sr_request (void)
-{
- Scsi_Cmnd * SCpnt = NULL;
- struct request * req = NULL;
- Scsi_Device * SDev;
- unsigned long flags;
- int flag = 0;
-
- while (1==1){
- save_flags(flags);
- cli();
- if (CURRENT != NULL && CURRENT->rq_status == RQ_INACTIVE) {
- restore_flags(flags);
- return;
- };
-
- INIT_SCSI_REQUEST;
-
- SDev = scsi_CDs[DEVICE_NR(CURRENT->rq_dev)].device;
-
- /*
- * I am not sure where the best place to do this is. We need
- * to hook in a place where we are likely to come if in user
- * space.
- */
- if( SDev->was_reset )
- {
- /*
- * We need to relock the door, but we might
- * be in an interrupt handler. Only do this
- * from user space, since we do not want to
- * sleep from an interrupt.
- */
- if( SDev->removable && !intr_count )
- {
- scsi_ioctl(SDev, SCSI_IOCTL_DOORLOCK, 0);
- }
- SDev->was_reset = 0;
- }
-
- if (flag++ == 0)
- SCpnt = allocate_device(&CURRENT,
- scsi_CDs[DEVICE_NR(CURRENT->rq_dev)].device, 0);
- else SCpnt = NULL;
- restore_flags(flags);
-
- /* This is a performance enhancement. We dig down into the request list and
- * try and find a queueable request (i.e. device not busy, and host able to
- * accept another command. If we find one, then we queue it. This can
- * make a big difference on systems with more than one disk drive. We want
- * to have the interrupts off when monkeying with the request list, because
- * otherwise the kernel might try and slip in a request in between somewhere. */
-
- if (!SCpnt && sr_template.nr_dev > 1){
- struct request *req1;
- req1 = NULL;
- save_flags(flags);
- cli();
- req = CURRENT;
- while(req){
- SCpnt = request_queueable(req,
- scsi_CDs[DEVICE_NR(req->rq_dev)].device);
- if(SCpnt) break;
- req1 = req;
- req = req->next;
- };
- if (SCpnt && req->rq_status == RQ_INACTIVE) {
- if (req == CURRENT)
- CURRENT = CURRENT->next;
- else
- req1->next = req->next;
- };
- restore_flags(flags);
- };
-
- if (!SCpnt)
- return; /* Could not find anything to do */
-
- wake_up(&wait_for_request);
-
- /* Queue command */
- requeue_sr_request(SCpnt);
- }; /* While */
-}
-
-void requeue_sr_request (Scsi_Cmnd * SCpnt)
-{
- unsigned int dev, block, realcount;
- unsigned char cmd[10], *buffer, tries;
- int this_count, start, end_rec;
-
- tries = 2;
-
- repeat:
- if(!SCpnt || SCpnt->request.rq_status == RQ_INACTIVE) {
- do_sr_request();
- return;
- }
-
- dev = MINOR(SCpnt->request.rq_dev);
- block = SCpnt->request.sector;
- buffer = NULL;
- this_count = 0;
-
- if (dev >= sr_template.nr_dev) {
- /* printk("CD-ROM request error: invalid device.\n"); */
- SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
- tries = 2;
- goto repeat;
- }
-
- if (!scsi_CDs[dev].use) {
- /* printk("CD-ROM request error: device marked not in use.\n"); */
- SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
- tries = 2;
- goto repeat;
- }
-
- if (scsi_CDs[dev].device->changed) {
- /*
- * quietly refuse to do anything to a changed disc
- * until the changed bit has been reset
- */
- /* printk("CD-ROM has been changed. Prohibiting further I/O.\n"); */
- SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
- tries = 2;
- goto repeat;
- }
-
- switch (SCpnt->request.cmd)
- {
- case WRITE:
- SCpnt = end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);
- goto repeat;
- break;
- case READ :
- cmd[0] = READ_6;
- break;
- default :
- panic ("Unknown sr command %d\n", SCpnt->request.cmd);
- }
-
- cmd[1] = (SCpnt->lun << 5) & 0xe0;
-
- /*
- * Now do the grungy work of figuring out which sectors we need, and
- * where in memory we are going to put them.
- *
- * The variables we need are:
- *
- * this_count= number of 512 byte sectors being read
- * block = starting cdrom sector to read.
- * realcount = # of cdrom sectors to read
- *
- * The major difference between a scsi disk and a scsi cdrom
- * is that we will always use scatter-gather if we can, because we can
- * work around the fact that the buffer cache has a block size of 1024,
- * and we have 2048 byte sectors. This code should work for buffers that
- * are any multiple of 512 bytes long.
- */
-
- SCpnt->use_sg = 0;
-
- if (SCpnt->host->sg_tablesize > 0 &&
- (!need_isa_buffer ||
- dma_free_sectors >= 10)) {
- struct buffer_head * bh;
- struct scatterlist * sgpnt;
- int count, this_count_max;
- bh = SCpnt->request.bh;
- this_count = 0;
- count = 0;
- this_count_max = (scsi_CDs[dev].ten ? 0xffff : 0xff) << 4;
- /* Calculate how many links we can use. First see if we need
- * a padding record at the start */
- this_count = SCpnt->request.sector % 4;
- if(this_count) count++;
- while(bh && count < SCpnt->host->sg_tablesize) {
- if ((this_count + (bh->b_size >> 9)) > this_count_max) break;
- this_count += (bh->b_size >> 9);
- count++;
- bh = bh->b_reqnext;
- };
- /* Fix up in case of an odd record at the end */
- end_rec = 0;
- if(this_count % 4) {
- if (count < SCpnt->host->sg_tablesize) {
- count++;
- end_rec = (4 - (this_count % 4)) << 9;
- this_count += 4 - (this_count % 4);
- } else {
- count--;
- this_count -= (this_count % 4);
- };
- };
- SCpnt->use_sg = count; /* Number of chains */
- count = 512;/* scsi_malloc can only allocate in chunks of 512 bytes*/
- while( count < (SCpnt->use_sg * sizeof(struct scatterlist)))
- count = count << 1;
- SCpnt->sglist_len = count;
- sgpnt = (struct scatterlist * ) scsi_malloc(count);
- if (!sgpnt) {
- printk("Warning - running *really* short on DMA buffers\n");
- SCpnt->use_sg = 0; /* No memory left - bail out */
- } else {
- buffer = (unsigned char *) sgpnt;
- count = 0;
- bh = SCpnt->request.bh;
- if(SCpnt->request.sector % 4) {
- sgpnt[count].length = (SCpnt->request.sector % 4) << 9;
- sgpnt[count].address = (char *) scsi_malloc(sgpnt[count].length);
- if(!sgpnt[count].address) panic("SCSI DMA pool exhausted.");
- sgpnt[count].alt_address = sgpnt[count].address; /* Flag to delete
- if needed */
- count++;
- };
- for(bh = SCpnt->request.bh; count < SCpnt->use_sg;
- count++, bh = bh->b_reqnext) {
- if (bh) { /* Need a placeholder at the end of the record? */
- sgpnt[count].address = bh->b_data;
- sgpnt[count].length = bh->b_size;
- sgpnt[count].alt_address = NULL;
- } else {
- sgpnt[count].address = (char *) scsi_malloc(end_rec);
- if(!sgpnt[count].address) panic("SCSI DMA pool exhausted.");
- sgpnt[count].length = end_rec;
- sgpnt[count].alt_address = sgpnt[count].address;
- if (count+1 != SCpnt->use_sg) panic("Bad sr request list");
- break;
- };
- if (((long) sgpnt[count].address) + sgpnt[count].length > ISA_DMA_THRESHOLD &&
- SCpnt->host->unchecked_isa_dma) {
- sgpnt[count].alt_address = sgpnt[count].address;
- /* We try and avoid exhausting the DMA pool, since it is easier
- * to control usage here. In other places we might have a more
- * pressing need, and we would be screwed if we ran out */
- if(dma_free_sectors < (sgpnt[count].length >> 9) + 5) {
- sgpnt[count].address = NULL;
- } else {
- sgpnt[count].address = (char *) scsi_malloc(sgpnt[count].length);
- };
- /* If we start running low on DMA buffers, we abort the scatter-gather
- * operation, and free all of the memory we have allocated. We want to
- * ensure that all scsi operations are able to do at least a non-scatter/gather
- * operation */
- if(sgpnt[count].address == NULL){ /* Out of dma memory */
- printk("Warning: Running low on SCSI DMA buffers");
- /* Try switching back to a non scatter-gather operation. */
- while(--count >= 0){
- if(sgpnt[count].alt_address)
- scsi_free(sgpnt[count].address, sgpnt[count].length);
- };
- SCpnt->use_sg = 0;
- scsi_free(buffer, SCpnt->sglist_len);
- break;
- }; /* if address == NULL */
- }; /* if need DMA fixup */
- }; /* for loop to fill list */
-#ifdef DEBUG
- printk("SR: %d %d %d %d %d *** ",SCpnt->use_sg, SCpnt->request.sector,
- this_count,
- SCpnt->request.current_nr_sectors,
- SCpnt->request.nr_sectors);
- for(count=0; count<SCpnt->use_sg; count++)
- printk("SGlist: %d %x %x %x\n", count,
- sgpnt[count].address,
- sgpnt[count].alt_address,
- sgpnt[count].length);
-#endif
- }; /* Able to allocate scatter-gather list */
- };
-
- if (SCpnt->use_sg == 0){
- /* We cannot use scatter-gather. Do this the old fashion way */
- if (!SCpnt->request.bh)
- this_count = SCpnt->request.nr_sectors;
- else
- this_count = (SCpnt->request.bh->b_size >> 9);
-
- start = block % 4;
- if (start)
- {
- this_count = ((this_count > 4 - start) ?
- (4 - start) : (this_count));
- buffer = (unsigned char *) scsi_malloc(2048);
- }
- else if (this_count < 4)
- {
- buffer = (unsigned char *) scsi_malloc(2048);
- }
- else
- {
- this_count -= this_count % 4;
- buffer = (unsigned char *) SCpnt->request.buffer;
- if (((long) buffer) + (this_count << 9) > ISA_DMA_THRESHOLD &&
- SCpnt->host->unchecked_isa_dma)
- buffer = (unsigned char *) scsi_malloc(this_count << 9);
- }
- };
-
- if (scsi_CDs[dev].sector_size == 2048)
- block = block >> 2; /* These are the sectors that the cdrom uses */
- else
- block = block & 0xfffffffc;
-
- realcount = (this_count + 3) / 4;
-
- if (scsi_CDs[dev].sector_size == 512) realcount = realcount << 2;
-
- if (((realcount > 0xff) || (block > 0x1fffff)) && scsi_CDs[dev].ten)
- {
- if (realcount > 0xffff)
- {
- realcount = 0xffff;
- this_count = realcount * (scsi_CDs[dev].sector_size >> 9);
- }
-
- cmd[0] += READ_10 - READ_6 ;
- cmd[2] = (unsigned char) (block >> 24) & 0xff;
- cmd[3] = (unsigned char) (block >> 16) & 0xff;
- cmd[4] = (unsigned char) (block >> 8) & 0xff;
- cmd[5] = (unsigned char) block & 0xff;
- cmd[6] = cmd[9] = 0;
- cmd[7] = (unsigned char) (realcount >> 8) & 0xff;
- cmd[8] = (unsigned char) realcount & 0xff;
- }
- else
- {
- if (realcount > 0xff)
- {
- realcount = 0xff;
- this_count = realcount * (scsi_CDs[dev].sector_size >> 9);
- }
-
- cmd[1] |= (unsigned char) ((block >> 16) & 0x1f);
- cmd[2] = (unsigned char) ((block >> 8) & 0xff);
- cmd[3] = (unsigned char) block & 0xff;
- cmd[4] = (unsigned char) realcount;
- cmd[5] = 0;
- }
-
-#ifdef DEBUG
- {
- int i;
- printk("ReadCD: %d %d %d %d\n",block, realcount, buffer, this_count);
- printk("Use sg: %d\n", SCpnt->use_sg);
- printk("Dumping command: ");
- for(i=0; i<12; i++) printk("%2.2x ", cmd[i]);
- printk("\n");
- };
-#endif
-
- /* Some dumb host adapters can speed transfers by knowing the
- * minimum transfersize in advance.
- *
- * We shouldn't disconnect in the middle of a sector, but the cdrom
- * sector size can be larger than the size of a buffer and the
- * transfer may be split to the size of a buffer. So it's safe to
- * assume that we can at least transfer the minimum of the buffer
- * size (1024) and the sector size between each connect / disconnect.
- */
-
- SCpnt->transfersize = (scsi_CDs[dev].sector_size > 1024) ?
- 1024 : scsi_CDs[dev].sector_size;
-
- SCpnt->this_count = this_count;
- scsi_do_cmd (SCpnt, (void *) cmd, buffer,
- realcount * scsi_CDs[dev].sector_size,
- rw_intr, SR_TIMEOUT, MAX_RETRIES);
-}
-
-static int sr_detect(Scsi_Device * SDp){
-
- if(SDp->type != TYPE_ROM && SDp->type != TYPE_WORM) return 0;
-
- printk("Detected scsi CD-ROM sr%d at scsi%d, channel %d, id %d, lun %d\n",
- sr_template.dev_noticed++,
- SDp->host->host_no, SDp->channel, SDp->id, SDp->lun);
-
- return 1;
-}
-
-static int sr_attach(Scsi_Device * SDp){
- Scsi_CD * cpnt;
- int i;
-
- if(SDp->type != TYPE_ROM && SDp->type != TYPE_WORM) return 1;
-
- if (sr_template.nr_dev >= sr_template.dev_max)
- {
- SDp->attached--;
- return 1;
- }
-
- for(cpnt = scsi_CDs, i=0; i<sr_template.dev_max; i++, cpnt++)
- if(!cpnt->device) break;
-
- if(i >= sr_template.dev_max) panic ("scsi_devices corrupt (sr)");
-
- SDp->scsi_request_fn = do_sr_request;
- scsi_CDs[i].device = SDp;
- sr_template.nr_dev++;
- if(sr_template.nr_dev > sr_template.dev_max)
- panic ("scsi_devices corrupt (sr)");
- return 0;
-}
-
-
-static void sr_init_done (Scsi_Cmnd * SCpnt)
-{
- struct request * req;
-
- req = &SCpnt->request;
- req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */
-
- if (req->sem != NULL) {
- up(req->sem);
- }
-}
-
-static void get_sectorsize(int i){
- unsigned char cmd[10];
- unsigned char *buffer;
- int the_result, retries;
- Scsi_Cmnd * SCpnt;
-
- buffer = (unsigned char *) scsi_malloc(512);
- SCpnt = allocate_device(NULL, scsi_CDs[i].device, 1);
-
- retries = 3;
- do {
- cmd[0] = READ_CAPACITY;
- cmd[1] = (scsi_CDs[i].device->lun << 5) & 0xe0;
- memset ((void *) &cmd[2], 0, 8);
- SCpnt->request.rq_status = RQ_SCSI_BUSY; /* Mark as really busy */
- SCpnt->cmd_len = 0;
-
- memset(buffer, 0, 8);
-
- /* Do the command and wait.. */
- {
- struct semaphore sem = MUTEX_LOCKED;
- SCpnt->request.sem = &sem;
- scsi_do_cmd (SCpnt,
- (void *) cmd, (void *) buffer,
- 512, sr_init_done, SR_TIMEOUT,
- MAX_RETRIES);
- down(&sem);
- }
-
- the_result = SCpnt->result;
- retries--;
-
- } while(the_result && retries);
-
- SCpnt->request.rq_status = RQ_INACTIVE; /* Mark as not busy */
-
- wake_up(&SCpnt->device->device_wait);
-
- if (the_result) {
- scsi_CDs[i].capacity = 0x1fffff;
- scsi_CDs[i].sector_size = 2048; /* A guess, just in case */
- scsi_CDs[i].needs_sector_size = 1;
- } else {
- scsi_CDs[i].capacity = (buffer[0] << 24) |
- (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
- scsi_CDs[i].sector_size = (buffer[4] << 24) |
- (buffer[5] << 16) | (buffer[6] << 8) | buffer[7];
- if(scsi_CDs[i].sector_size == 0) scsi_CDs[i].sector_size = 2048;
- /* Work around bug/feature in HP 4020i CD-Recorder... */
- if(scsi_CDs[i].sector_size == 2340) scsi_CDs[i].sector_size = 2048;
- if(scsi_CDs[i].sector_size != 2048 &&
- scsi_CDs[i].sector_size != 512) {
- printk ("scd%d : unsupported sector size %d.\n",
- i, scsi_CDs[i].sector_size);
- scsi_CDs[i].capacity = 0;
- scsi_CDs[i].needs_sector_size = 1;
- };
- if(scsi_CDs[i].sector_size == 2048)
- scsi_CDs[i].capacity *= 4;
- scsi_CDs[i].needs_sector_size = 0;
- sr_sizes[i] = scsi_CDs[i].capacity;
- };
- scsi_free(buffer, 512);
-}
-
-static int sr_registered = 0;
-
-static int sr_init()
-{
- int i;
-
- if(sr_template.dev_noticed == 0) return 0;
-
- if(!sr_registered) {
- if (register_blkdev(MAJOR_NR,"sr",&sr_fops)) {
- printk("Unable to get major %d for SCSI-CD\n",MAJOR_NR);
- return 1;
- }
- sr_registered++;
- }
-
-
- if (scsi_CDs) return 0;
- sr_template.dev_max = sr_template.dev_noticed + SR_EXTRA_DEVS;
- scsi_CDs = (Scsi_CD *) scsi_init_malloc(sr_template.dev_max * sizeof(Scsi_CD), GFP_ATOMIC);
- memset(scsi_CDs, 0, sr_template.dev_max * sizeof(Scsi_CD));
-
- sr_sizes = (int *) scsi_init_malloc(sr_template.dev_max * sizeof(int), GFP_ATOMIC);
- memset(sr_sizes, 0, sr_template.dev_max * sizeof(int));
-
- sr_blocksizes = (int *) scsi_init_malloc(sr_template.dev_max *
- sizeof(int), GFP_ATOMIC);
- for(i=0;i<sr_template.dev_max;i++) sr_blocksizes[i] = 2048;
- blksize_size[MAJOR_NR] = sr_blocksizes;
- return 0;
-}
-
-void sr_finish()
-{
- int i;
-
- blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
- blk_size[MAJOR_NR] = sr_sizes;
-
- for (i = 0; i < sr_template.nr_dev; ++i)
- {
- /* If we have already seen this, then skip it. Comes up
- * with loadable modules. */
- if (scsi_CDs[i].capacity) continue;
- scsi_CDs[i].capacity = 0x1fffff;
- scsi_CDs[i].sector_size = 2048; /* A guess, just in case */
- scsi_CDs[i].needs_sector_size = 1;
-#if 0
- /* seems better to leave this for later */
- get_sectorsize(i);
- printk("Scd sectorsize = %d bytes.\n", scsi_CDs[i].sector_size);
-#endif
- scsi_CDs[i].use = 1;
- scsi_CDs[i].ten = 1;
- scsi_CDs[i].remap = 1;
- scsi_CDs[i].auto_eject = 0; /* Default is not to eject upon unmount. */
- sr_sizes[i] = scsi_CDs[i].capacity;
- }
-
-
- /* If our host adapter is capable of scatter-gather, then we increase
- * the read-ahead to 16 blocks (32 sectors). If not, we use
- * a two block (4 sector) read ahead. */
- if(scsi_CDs[0].device && scsi_CDs[0].device->host->sg_tablesize)
- read_ahead[MAJOR_NR] = 32; /* 32 sector read-ahead. Always removable. */
- else
- read_ahead[MAJOR_NR] = 4; /* 4 sector read-ahead */
-
- return;
-}
-
-static void sr_detach(Scsi_Device * SDp)
-{
- Scsi_CD * cpnt;
- int i;
-
- for(cpnt = scsi_CDs, i=0; i<sr_template.dev_max; i++, cpnt++)
- if(cpnt->device == SDp) {
- kdev_t devi = MKDEV(MAJOR_NR, i);
-
- /*
- * Since the cdrom is read-only, no need to sync the device.
- * We should be kind to our buffer cache, however.
- */
- invalidate_inodes(devi);
- invalidate_buffers(devi);
-
- /*
- * Reset things back to a sane state so that one can re-load a new
- * driver (perhaps the same one).
- */
- cpnt->device = NULL;
- cpnt->capacity = 0;
- SDp->attached--;
- sr_template.nr_dev--;
- sr_template.dev_noticed--;
- sr_sizes[i] = 0;
- return;
- }
- return;
-}
-
-
-#ifdef MODULE
-
-int init_module(void) {
- sr_template.usage_count = &mod_use_count_;
- return scsi_register_module(MODULE_SCSI_DEV, &sr_template);
-}
-
-void cleanup_module( void)
-{
- scsi_unregister_module(MODULE_SCSI_DEV, &sr_template);
- unregister_blkdev(SCSI_CDROM_MAJOR, "sr");
- sr_registered--;
- if(scsi_CDs != NULL) {
- scsi_init_free((char *) scsi_CDs,
- (sr_template.dev_noticed + SR_EXTRA_DEVS)
- * sizeof(Scsi_CD));
-
- scsi_init_free((char *) sr_sizes, sr_template.dev_max * sizeof(int));
- scsi_init_free((char *) sr_blocksizes, sr_template.dev_max * sizeof(int));
- }
-
- blksize_size[MAJOR_NR] = NULL;
- blk_dev[MAJOR_NR].request_fn = NULL;
- blk_size[MAJOR_NR] = NULL;
- read_ahead[MAJOR_NR] = 0;
-
- sr_template.dev_max = 0;
-}
-#endif /* MODULE */
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 4
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * c-continued-statement-offset: 4
- * c-continued-brace-offset: 0
- * indent-tabs-mode: nil
- * tab-width: 8
- * End:
- */
diff --git a/i386/i386at/gpl/linux/scsi/sr.h b/i386/i386at/gpl/linux/scsi/sr.h
deleted file mode 100644
index 381678a6..00000000
--- a/i386/i386at/gpl/linux/scsi/sr.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * sr.h by David Giller
- * CD-ROM disk driver header file
- *
- * adapted from:
- * sd.h Copyright (C) 1992 Drew Eckhardt
- * SCSI disk driver header file by
- * Drew Eckhardt
- *
- * <drew@colorado.edu>
- *
- * Modified by Eric Youngdale eric@aib.com to
- * add scatter-gather, multiple outstanding request, and other
- * enhancements.
- */
-
-#ifndef _SR_H
-#define _SR_H
-
-#include "scsi.h"
-
-typedef struct
- {
- unsigned capacity; /* size in blocks */
- unsigned sector_size; /* size in bytes */
- Scsi_Device *device;
- unsigned long mpcd_sector; /* for reading multisession-CD's */
- char xa_flags; /* some flags for handling XA-CD's */
- unsigned char sector_bit_size; /* sector size = 2^sector_bit_size */
- unsigned char sector_bit_shift; /* sectors/FS block = 2^sector_bit_shift*/
- unsigned needs_sector_size:1; /* needs to get sector size */
- unsigned ten:1; /* support ten byte commands */
- unsigned remap:1; /* support remapping */
- unsigned use:1; /* is this device still supportable */
- unsigned auto_eject:1; /* auto-eject medium on last release. */
- } Scsi_CD;
-
-extern Scsi_CD * scsi_CDs;
-
-#endif
diff --git a/i386/i386at/gpl/linux/scsi/sr_ioctl.c b/i386/i386at/gpl/linux/scsi/sr_ioctl.c
deleted file mode 100644
index 2313cf8c..00000000
--- a/i386/i386at/gpl/linux/scsi/sr_ioctl.c
+++ /dev/null
@@ -1,489 +0,0 @@
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/fs.h>
-#include <asm/segment.h>
-#include <linux/errno.h>
-
-#include <linux/blk.h>
-#include "scsi.h"
-#include "hosts.h"
-#include "sr.h"
-#include "scsi_ioctl.h"
-
-#include <linux/cdrom.h>
-
-#define IOCTL_RETRIES 3
-/* The CDROM is fairly slow, so we need a little extra time */
-/* In fact, it is very slow if it has to spin up first */
-#define IOCTL_TIMEOUT 3000
-
-static void sr_ioctl_done(Scsi_Cmnd * SCpnt)
-{
- struct request * req;
-
- req = &SCpnt->request;
- req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */
-
- if (req->sem != NULL) {
- up(req->sem);
- }
-}
-
-/* We do our own retries because we want to know what the specific
- error code is. Normally the UNIT_ATTENTION code will automatically
- clear after one error */
-
-static int do_ioctl(int target, unsigned char * sr_cmd, void * buffer, unsigned buflength)
-{
- Scsi_Cmnd * SCpnt;
- int result;
-
- SCpnt = allocate_device(NULL, scsi_CDs[target].device, 1);
- {
- struct semaphore sem = MUTEX_LOCKED;
- SCpnt->request.sem = &sem;
- scsi_do_cmd(SCpnt,
- (void *) sr_cmd, buffer, buflength, sr_ioctl_done,
- IOCTL_TIMEOUT, IOCTL_RETRIES);
- down(&sem);
- }
-
- result = SCpnt->result;
-
- /* Minimal error checking. Ignore cases we know about, and report the rest. */
- if(driver_byte(result) != 0)
- switch(SCpnt->sense_buffer[2] & 0xf) {
- case UNIT_ATTENTION:
- scsi_CDs[target].device->changed = 1;
- printk("Disc change detected.\n");
- break;
- case NOT_READY: /* This happens if there is no disc in drive */
- printk("CDROM not ready. Make sure there is a disc in the drive.\n");
- break;
- case ILLEGAL_REQUEST:
- printk("CDROM (ioctl) reports ILLEGAL REQUEST.\n");
- break;
- default:
- printk("SCSI CD error: host %d id %d lun %d return code = %03x\n",
- scsi_CDs[target].device->host->host_no,
- scsi_CDs[target].device->id,
- scsi_CDs[target].device->lun,
- result);
- printk("\tSense class %x, sense error %x, extended sense %x\n",
- sense_class(SCpnt->sense_buffer[0]),
- sense_error(SCpnt->sense_buffer[0]),
- SCpnt->sense_buffer[2] & 0xf);
-
- };
-
- result = SCpnt->result;
- SCpnt->request.rq_status = RQ_INACTIVE; /* Deallocate */
- wake_up(&SCpnt->device->device_wait);
- /* Wake up a process waiting for device*/
- return result;
-}
-
-int sr_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg)
-{
- u_char sr_cmd[10];
-
- kdev_t dev = inode->i_rdev;
- int result, target, err;
-
- target = MINOR(dev);
-
- if (target >= sr_template.nr_dev ||
- !scsi_CDs[target].device) return -ENXIO;
-
- switch (cmd)
- {
- /* Sun-compatible */
- case CDROMPAUSE:
-
- sr_cmd[0] = SCMD_PAUSE_RESUME;
- sr_cmd[1] = scsi_CDs[target].device->lun << 5;
- sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = 0;
- sr_cmd[5] = sr_cmd[6] = sr_cmd[7] = 0;
- sr_cmd[8] = 0;
- sr_cmd[9] = 0;
-
- result = do_ioctl(target, sr_cmd, NULL, 255);
- return result;
-
- case CDROMRESUME:
-
- sr_cmd[0] = SCMD_PAUSE_RESUME;
- sr_cmd[1] = scsi_CDs[target].device->lun << 5;
- sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = 0;
- sr_cmd[5] = sr_cmd[6] = sr_cmd[7] = 0;
- sr_cmd[8] = 1;
- sr_cmd[9] = 0;
-
- result = do_ioctl(target, sr_cmd, NULL, 255);
-
- return result;
-
- case CDROMPLAYMSF:
- {
- struct cdrom_msf msf;
-
- err = verify_area (VERIFY_READ, (void *) arg, sizeof (msf));
- if (err) return err;
-
- memcpy_fromfs(&msf, (void *) arg, sizeof(msf));
-
- sr_cmd[0] = SCMD_PLAYAUDIO_MSF;
- sr_cmd[1] = scsi_CDs[target].device->lun << 5;
- sr_cmd[2] = 0;
- sr_cmd[3] = msf.cdmsf_min0;
- sr_cmd[4] = msf.cdmsf_sec0;
- sr_cmd[5] = msf.cdmsf_frame0;
- sr_cmd[6] = msf.cdmsf_min1;
- sr_cmd[7] = msf.cdmsf_sec1;
- sr_cmd[8] = msf.cdmsf_frame1;
- sr_cmd[9] = 0;
-
- result = do_ioctl(target, sr_cmd, NULL, 255);
- return result;
- }
-
- case CDROMPLAYBLK:
- {
- struct cdrom_blk blk;
-
- err = verify_area (VERIFY_READ, (void *) arg, sizeof (blk));
- if (err) return err;
-
- memcpy_fromfs(&blk, (void *) arg, sizeof(blk));
-
- sr_cmd[0] = SCMD_PLAYAUDIO10;
- sr_cmd[1] = scsi_CDs[target].device->lun << 5;
- sr_cmd[2] = blk.from >> 24;
- sr_cmd[3] = blk.from >> 16;
- sr_cmd[4] = blk.from >> 8;
- sr_cmd[5] = blk.from;
- sr_cmd[6] = 0;
- sr_cmd[7] = blk.len >> 8;
- sr_cmd[8] = blk.len;
- sr_cmd[9] = 0;
-
- result = do_ioctl(target, sr_cmd, NULL, 255);
- return result;
- }
-
- case CDROMPLAYTRKIND:
- {
- struct cdrom_ti ti;
-
- err = verify_area (VERIFY_READ, (void *) arg, sizeof (ti));
- if (err) return err;
-
- memcpy_fromfs(&ti, (void *) arg, sizeof(ti));
-
- sr_cmd[0] = SCMD_PLAYAUDIO_TI;
- sr_cmd[1] = scsi_CDs[target].device->lun << 5;
- sr_cmd[2] = 0;
- sr_cmd[3] = 0;
- sr_cmd[4] = ti.cdti_trk0;
- sr_cmd[5] = ti.cdti_ind0;
- sr_cmd[6] = 0;
- sr_cmd[7] = ti.cdti_trk1;
- sr_cmd[8] = ti.cdti_ind1;
- sr_cmd[9] = 0;
-
- result = do_ioctl(target, sr_cmd, NULL, 255);
-
- return result;
- }
-
- case CDROMREADTOCHDR:
- {
- struct cdrom_tochdr tochdr;
- char * buffer;
-
- sr_cmd[0] = SCMD_READ_TOC;
- sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 0x02; /* MSF format */
- sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = sr_cmd[5] = 0;
- sr_cmd[6] = 0;
- sr_cmd[7] = 0; /* MSB of length (12) */
- sr_cmd[8] = 12; /* LSB of length */
- sr_cmd[9] = 0;
-
- buffer = (unsigned char *) scsi_malloc(512);
- if(!buffer) return -ENOMEM;
-
- result = do_ioctl(target, sr_cmd, buffer, 12);
-
- tochdr.cdth_trk0 = buffer[2];
- tochdr.cdth_trk1 = buffer[3];
-
- scsi_free(buffer, 512);
-
- err = verify_area (VERIFY_WRITE, (void *) arg, sizeof (struct cdrom_tochdr));
- if (err)
- return err;
- memcpy_tofs ((void *) arg, &tochdr, sizeof (struct cdrom_tochdr));
-
- return result;
- }
-
- case CDROMREADTOCENTRY:
- {
- struct cdrom_tocentry tocentry;
- char * buffer;
-
- err = verify_area (VERIFY_READ, (void *) arg, sizeof (struct cdrom_tocentry));
- if (err) return err;
-
- memcpy_fromfs (&tocentry, (void *) arg, sizeof (struct cdrom_tocentry));
-
- sr_cmd[0] = SCMD_READ_TOC;
- sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 0x02; /* MSF format */
- sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = sr_cmd[5] = 0;
- sr_cmd[6] = tocentry.cdte_track;
- sr_cmd[7] = 0; /* MSB of length (12) */
- sr_cmd[8] = 12; /* LSB of length */
- sr_cmd[9] = 0;
-
- buffer = (unsigned char *) scsi_malloc(512);
- if(!buffer) return -ENOMEM;
-
- result = do_ioctl (target, sr_cmd, buffer, 12);
-
- if (tocentry.cdte_format == CDROM_MSF) {
- tocentry.cdte_addr.msf.minute = buffer[9];
- tocentry.cdte_addr.msf.second = buffer[10];
- tocentry.cdte_addr.msf.frame = buffer[11];
- tocentry.cdte_ctrl = buffer[5] & 0xf;
- }
- else
- tocentry.cdte_addr.lba = (int) buffer[0];
-
- scsi_free(buffer, 512);
-
- err = verify_area (VERIFY_WRITE, (void *) arg, sizeof (struct cdrom_tocentry));
- if (err)
- return err;
- memcpy_tofs ((void *) arg, &tocentry, sizeof (struct cdrom_tocentry));
-
- return result;
- }
-
- case CDROMSTOP:
- sr_cmd[0] = START_STOP;
- sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 1;
- sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
- sr_cmd[4] = 0;
-
- result = do_ioctl(target, sr_cmd, NULL, 255);
- return result;
-
- case CDROMSTART:
- sr_cmd[0] = START_STOP;
- sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 1;
- sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
- sr_cmd[4] = 1;
-
- result = do_ioctl(target, sr_cmd, NULL, 255);
- return result;
-
- case CDROMEJECT:
- /*
- * Allow 0 for access count for auto-eject feature.
- */
- if (scsi_CDs[target].device -> access_count > 1)
- return -EBUSY;
-
- sr_ioctl (inode, NULL, SCSI_IOCTL_DOORUNLOCK, 0);
- sr_cmd[0] = START_STOP;
- sr_cmd[1] = ((scsi_CDs[target].device -> lun) << 5) | 1;
- sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
- sr_cmd[4] = 0x02;
-
- if (!(result = do_ioctl(target, sr_cmd, NULL, 255)))
- scsi_CDs[target].device -> changed = 1;
-
- return result;
-
- case CDROMEJECT_SW:
- scsi_CDs[target].auto_eject = !!arg;
- return 0;
-
- case CDROMVOLCTRL:
- {
- char * buffer, * mask;
- struct cdrom_volctrl volctrl;
-
- err = verify_area (VERIFY_READ, (void *) arg, sizeof (struct cdrom_volctrl));
- if (err) return err;
-
- memcpy_fromfs (&volctrl, (void *) arg, sizeof (struct cdrom_volctrl));
-
- /* First we get the current params so we can just twiddle the volume */
-
- sr_cmd[0] = MODE_SENSE;
- sr_cmd[1] = (scsi_CDs[target].device -> lun) << 5;
- sr_cmd[2] = 0xe; /* Want mode page 0xe, CDROM audio params */
- sr_cmd[3] = 0;
- sr_cmd[4] = 28;
- sr_cmd[5] = 0;
-
- buffer = (unsigned char *) scsi_malloc(512);
- if(!buffer) return -ENOMEM;
-
- if ((result = do_ioctl (target, sr_cmd, buffer, 28))) {
- printk ("Hosed while obtaining audio mode page\n");
- scsi_free(buffer, 512);
- return result;
- }
-
- sr_cmd[0] = MODE_SENSE;
- sr_cmd[1] = (scsi_CDs[target].device -> lun) << 5;
- sr_cmd[2] = 0x4e; /* Want the mask for mode page 0xe */
- sr_cmd[3] = 0;
- sr_cmd[4] = 28;
- sr_cmd[5] = 0;
-
- mask = (unsigned char *) scsi_malloc(512);
- if(!mask) {
- scsi_free(buffer, 512);
- return -ENOMEM;
- };
-
- if ((result = do_ioctl (target, sr_cmd, mask, 28))) {
- printk ("Hosed while obtaining mask for audio mode page\n");
- scsi_free(buffer, 512);
- scsi_free(mask, 512);
- return result;
- }
-
- /* Now mask and substitute our own volume and reuse the rest */
- buffer[0] = 0; /* Clear reserved field */
-
- buffer[21] = volctrl.channel0 & mask[21];
- buffer[23] = volctrl.channel1 & mask[23];
- buffer[25] = volctrl.channel2 & mask[25];
- buffer[27] = volctrl.channel3 & mask[27];
-
- sr_cmd[0] = MODE_SELECT;
- sr_cmd[1] = ((scsi_CDs[target].device -> lun) << 5) | 0x10; /* Params are SCSI-2 */
- sr_cmd[2] = sr_cmd[3] = 0;
- sr_cmd[4] = 28;
- sr_cmd[5] = 0;
-
- result = do_ioctl (target, sr_cmd, buffer, 28);
- scsi_free(buffer, 512);
- scsi_free(mask, 512);
- return result;
- }
-
- case CDROMSUBCHNL:
- {
- struct cdrom_subchnl subchnl;
- char * buffer;
-
- sr_cmd[0] = SCMD_READ_SUBCHANNEL;
- sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 0x02; /* MSF format */
- sr_cmd[2] = 0x40; /* I do want the subchannel info */
- sr_cmd[3] = 0x01; /* Give me current position info */
- sr_cmd[4] = sr_cmd[5] = 0;
- sr_cmd[6] = 0;
- sr_cmd[7] = 0;
- sr_cmd[8] = 16;
- sr_cmd[9] = 0;
-
- buffer = (unsigned char*) scsi_malloc(512);
- if(!buffer) return -ENOMEM;
-
- result = do_ioctl(target, sr_cmd, buffer, 16);
-
- subchnl.cdsc_audiostatus = buffer[1];
- subchnl.cdsc_format = CDROM_MSF;
- subchnl.cdsc_ctrl = buffer[5] & 0xf;
- subchnl.cdsc_trk = buffer[6];
- subchnl.cdsc_ind = buffer[7];
-
- subchnl.cdsc_reladdr.msf.minute = buffer[13];
- subchnl.cdsc_reladdr.msf.second = buffer[14];
- subchnl.cdsc_reladdr.msf.frame = buffer[15];
- subchnl.cdsc_absaddr.msf.minute = buffer[9];
- subchnl.cdsc_absaddr.msf.second = buffer[10];
- subchnl.cdsc_absaddr.msf.frame = buffer[11];
-
- scsi_free(buffer, 512);
-
- err = verify_area (VERIFY_WRITE, (void *) arg, sizeof (struct cdrom_subchnl));
- if (err)
- return err;
- memcpy_tofs ((void *) arg, &subchnl, sizeof (struct cdrom_subchnl));
- return result;
- }
-
- case CDROMREADMODE2:
- return -EINVAL;
- case CDROMREADMODE1:
- return -EINVAL;
-
- /* block-copy from ../block/sbpcd.c with some adjustments... */
- case CDROMMULTISESSION: /* tell start-of-last-session to user */
- {
- struct cdrom_multisession ms_info;
- long lba;
-
- err = verify_area(VERIFY_READ, (void *) arg,
- sizeof(struct cdrom_multisession));
- if (err) return (err);
-
- memcpy_fromfs(&ms_info, (void *) arg, sizeof(struct cdrom_multisession));
-
- if (ms_info.addr_format==CDROM_MSF) { /* MSF-bin requested */
- lba = scsi_CDs[target].mpcd_sector+CD_BLOCK_OFFSET;
- ms_info.addr.msf.minute = lba / (CD_SECS*CD_FRAMES);
- lba %= CD_SECS*CD_FRAMES;
- ms_info.addr.msf.second = lba / CD_FRAMES;
- ms_info.addr.msf.frame = lba % CD_FRAMES;
- } else if (ms_info.addr_format==CDROM_LBA) /* lba requested */
- ms_info.addr.lba=scsi_CDs[target].mpcd_sector;
- else return (-EINVAL);
-
- ms_info.xa_flag=scsi_CDs[target].xa_flags & 0x01;
-
- err=verify_area(VERIFY_WRITE,(void *) arg,
- sizeof(struct cdrom_multisession));
- if (err) return (err);
-
- memcpy_tofs((void *) arg, &ms_info, sizeof(struct cdrom_multisession));
- return (0);
- }
-
- case BLKRASET:
- if(!suser()) return -EACCES;
- if(!(inode->i_rdev)) return -EINVAL;
- if(arg > 0xff) return -EINVAL;
- read_ahead[MAJOR(inode->i_rdev)] = arg;
- return 0;
- RO_IOCTLS(dev,arg);
- default:
- return scsi_ioctl(scsi_CDs[target].device,cmd,(void *) arg);
- }
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 4
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * c-continued-statement-offset: 4
- * c-continued-brace-offset: 0
- * indent-tabs-mode: nil
- * tab-width: 8
- * End:
- */
diff --git a/i386/i386at/gpl/linux/scsi/t128.c b/i386/i386at/gpl/linux/scsi/t128.c
deleted file mode 100644
index 9212b61e..00000000
--- a/i386/i386at/gpl/linux/scsi/t128.c
+++ /dev/null
@@ -1,413 +0,0 @@
-#define AUTOSENSE
-#define PSEUDO_DMA
-
-/*
- * Trantor T128/T128F/T228 driver
- * Note : architecturally, the T100 and T130 are different and won't
- * work
- *
- * Copyright 1993, Drew Eckhardt
- * Visionary Computing
- * (Unix and Linux consulting and custom programming)
- * drew@colorado.edu
- * +1 (303) 440-4894
- *
- * DISTRIBUTION RELEASE 3.
- *
- * For more information, please consult
- *
- * Trantor Systems, Ltd.
- * T128/T128F/T228 SCSI Host Adapter
- * Hardware Specifications
- *
- * Trantor Systems, Ltd.
- * 5415 Randall Place
- * Fremont, CA 94538
- * 1+ (415) 770-1400, FAX 1+ (415) 770-9910
- *
- * and
- *
- * NCR 5380 Family
- * SCSI Protocol Controller
- * Databook
- *
- * NCR Microelectronics
- * 1635 Aeroplaza Drive
- * Colorado Springs, CO 80916
- * 1+ (719) 578-3400
- * 1+ (800) 334-5454
- */
-
-/*
- * Options :
- * AUTOSENSE - if defined, REQUEST SENSE will be performed automatically
- * for commands that return with a CHECK CONDITION status.
- *
- * PSEUDO_DMA - enables PSEUDO-DMA hardware, should give a 3-4X performance
- * increase compared to polled I/O.
- *
- * PARITY - enable parity checking. Not supported.
- *
- * SCSI2 - enable support for SCSI-II tagged queueing. Untested.
- *
- *
- * UNSAFE - leave interrupts enabled during pseudo-DMA transfers. You
- * only really want to use this if you're having a problem with
- * dropped characters during high speed communications, and even
- * then, you're going to be better off twiddling with transfersize.
- *
- * USLEEP - enable support for devices that don't disconnect. Untested.
- *
- * The card is detected and initialized in one of several ways :
- * 1. Autoprobe (default) - since the board is memory mapped,
- * a BIOS signature is scanned for to locate the registers.
- * An interrupt is triggered to autoprobe for the interrupt
- * line.
- *
- * 2. With command line overrides - t128=address,irq may be
- * used on the LILO command line to override the defaults.
- *
- * 3. With the T128_OVERRIDE compile time define. This is
- * specified as an array of address, irq tuples. Ie, for
- * one board at the default 0xcc000 address, IRQ5, I could say
- * -DT128_OVERRIDE={{0xcc000, 5}}
- *
- * Note that if the override methods are used, place holders must
- * be specified for other boards in the system.
- *
- * T128/T128F jumper/dipswitch settings (note : on my sample, the switches
- * were epoxy'd shut, meaning I couldn't change the 0xcc000 base address) :
- *
- * T128 Sw7 Sw8 Sw6 = 0ws Sw5 = boot
- * T128F Sw6 Sw7 Sw5 = 0ws Sw4 = boot Sw8 = floppy disable
- * cc000 off off
- * c8000 off on
- * dc000 on off
- * d8000 on on
- *
- *
- * Interrupts
- * There is a 12 pin jumper block, jp1, numbered as follows :
- * T128 (JP1) T128F (J5)
- * 2 4 6 8 10 12 11 9 7 5 3 1
- * 1 3 5 7 9 11 12 10 8 6 4 2
- *
- * 3 2-4
- * 5 1-3
- * 7 3-5
- * T128F only
- * 10 8-10
- * 12 7-9
- * 14 10-12
- * 15 9-11
- */
-
-/*
- * $Log: t128.c,v $
- * Revision 1.1.1.1 1996/10/30 01:40:07 thomas
- * Imported from UK22
- *
- * Revision 1.1 1996/03/25 20:25:52 goel
- * Linux driver merge.
- *
- */
-
-#include <asm/system.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <asm/io.h>
-#include <linux/blk.h>
-#include "scsi.h"
-#include "hosts.h"
-#include "t128.h"
-#define AUTOPROBE_IRQ
-#include "NCR5380.h"
-#include "constants.h"
-#include "sd.h"
-#include<linux/stat.h>
-
-struct proc_dir_entry proc_scsi_t128 = {
- PROC_SCSI_T128, 4, "t128",
- S_IFDIR | S_IRUGO | S_IXUGO, 2
-};
-
-
-static struct override {
- unsigned char *address;
- int irq;
-} overrides
-#ifdef T128_OVERRIDE
- [] = T128_OVERRIDE;
-#else
- [4] = {{NULL,IRQ_AUTO}, {NULL,IRQ_AUTO}, {NULL,IRQ_AUTO},
- {NULL,IRQ_AUTO}};
-#endif
-
-#define NO_OVERRIDES (sizeof(overrides) / sizeof(struct override))
-
-static struct base {
- unsigned char *address;
- int noauto;
-} bases[] = {{(unsigned char *) 0xcc000, 0}, {(unsigned char *) 0xc8000, 0},
- {(unsigned char *) 0xdc000, 0}, {(unsigned char *) 0xd8000, 0}};
-
-#define NO_BASES (sizeof (bases) / sizeof (struct base))
-
-static const struct signature {
- const char *string;
- int offset;
-} signatures[] = {
-{"TSROM: SCSI BIOS, Version 1.12", 0x36},
-};
-
-#define NO_SIGNATURES (sizeof (signatures) / sizeof (struct signature))
-
-/*
- * Function : t128_setup(char *str, int *ints)
- *
- * Purpose : LILO command line initialization of the overrides array,
- *
- * Inputs : str - unused, ints - array of integer parameters with ints[0]
- * equal to the number of ints.
- *
- */
-
-void t128_setup(char *str, int *ints) {
- static int commandline_current = 0;
- int i;
- if (ints[0] != 2)
- printk("t128_setup : usage t128=address,irq\n");
- else
- if (commandline_current < NO_OVERRIDES) {
- overrides[commandline_current].address = (unsigned char *) ints[1];
- overrides[commandline_current].irq = ints[2];
- for (i = 0; i < NO_BASES; ++i)
- if (bases[i].address == (unsigned char *) ints[1]) {
- bases[i].noauto = 1;
- break;
- }
- ++commandline_current;
- }
-}
-
-/*
- * Function : int t128_detect(Scsi_Host_Template * tpnt)
- *
- * Purpose : detects and initializes T128,T128F, or T228 controllers
- * that were autoprobed, overridden on the LILO command line,
- * or specified at compile time.
- *
- * Inputs : tpnt - template for this SCSI adapter.
- *
- * Returns : 1 if a host adapter was found, 0 if not.
- *
- */
-
-int t128_detect(Scsi_Host_Template * tpnt) {
- static int current_override = 0, current_base = 0;
- struct Scsi_Host *instance;
- unsigned char *base;
- int sig, count;
-
- tpnt->proc_dir = &proc_scsi_t128;
-
- for (count = 0; current_override < NO_OVERRIDES; ++current_override) {
- base = NULL;
-
- if (overrides[current_override].address)
- base = overrides[current_override].address;
- else
- for (; !base && (current_base < NO_BASES); ++current_base) {
-#if (TDEBUG & TDEBUG_INIT)
- printk("scsi : probing address %08x\n", (unsigned int) bases[current_base].address);
-#endif
- for (sig = 0; sig < NO_SIGNATURES; ++sig)
- if (!bases[current_base].noauto && !memcmp
- (bases[current_base].address + signatures[sig].offset,
- signatures[sig].string, strlen(signatures[sig].string))) {
- base = bases[current_base].address;
-#if (TDEBUG & TDEBUG_INIT)
- printk("scsi-t128 : detected board.\n");
-#endif
- break;
- }
- }
-
-#if defined(TDEBUG) && (TDEBUG & TDEBUG_INIT)
- printk("scsi-t128 : base = %08x\n", (unsigned int) base);
-#endif
-
- if (!base)
- break;
-
- instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
- instance->base = base;
-
- NCR5380_init(instance, 0);
-
- if (overrides[current_override].irq != IRQ_AUTO)
- instance->irq = overrides[current_override].irq;
- else
- instance->irq = NCR5380_probe_irq(instance, T128_IRQS);
-
- if (instance->irq != IRQ_NONE)
- if (request_irq(instance->irq, t128_intr, SA_INTERRUPT, "t128")) {
- printk("scsi%d : IRQ%d not free, interrupts disabled\n",
- instance->host_no, instance->irq);
- instance->irq = IRQ_NONE;
- }
-
- if (instance->irq == IRQ_NONE) {
- printk("scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
- printk("scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
- }
-
-#if defined(TDEBUG) && (TDEBUG & TDEBUG_INIT)
- printk("scsi%d : irq = %d\n", instance->host_no, instance->irq);
-#endif
-
- printk("scsi%d : at 0x%08x", instance->host_no, (int)
- instance->base);
- if (instance->irq == IRQ_NONE)
- printk (" interrupts disabled");
- else
- printk (" irq %d", instance->irq);
- printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d",
- CAN_QUEUE, CMD_PER_LUN, T128_PUBLIC_RELEASE);
- NCR5380_print_options(instance);
- printk("\n");
-
- ++current_override;
- ++count;
- }
- return count;
-}
-
-/*
- * Function : int t128_biosparam(Disk * disk, kdev_t dev, int *ip)
- *
- * Purpose : Generates a BIOS / DOS compatible H-C-S mapping for
- * the specified device / size.
- *
- * Inputs : size = size of device in sectors (512 bytes), dev = block device
- * major / minor, ip[] = {heads, sectors, cylinders}
- *
- * Returns : always 0 (success), initializes ip
- *
- */
-
-/*
- * XXX Most SCSI boards use this mapping, I could be incorrect. Some one
- * using hard disks on a trantor should verify that this mapping corresponds
- * to that used by the BIOS / ASPI driver by running the linux fdisk program
- * and matching the H_C_S coordinates to what DOS uses.
- */
-
-int t128_biosparam(Disk * disk, kdev_t dev, int * ip)
-{
- int size = disk->capacity;
- ip[0] = 64;
- ip[1] = 32;
- ip[2] = size >> 11;
- return 0;
-}
-
-/*
- * Function : int NCR5380_pread (struct Scsi_Host *instance,
- * unsigned char *dst, int len)
- *
- * Purpose : Fast 5380 pseudo-dma read function, transfers len bytes to
- * dst
- *
- * Inputs : dst = destination, len = length in bytes
- *
- * Returns : 0 on success, non zero on a failure such as a watchdog
- * timeout.
- */
-
-static inline int NCR5380_pread (struct Scsi_Host *instance, unsigned char *dst,
- int len) {
- register unsigned char *reg = (unsigned char *) (instance->base +
- T_DATA_REG_OFFSET), *d = dst;
- register i = len;
-
-
-#if 0
- for (; i; --i) {
- while (!(instance->base[T_STATUS_REG_OFFSET]) & T_ST_RDY) barrier();
-#else
- while (!(instance->base[T_STATUS_REG_OFFSET]) & T_ST_RDY) barrier();
- for (; i; --i) {
-#endif
- *d++ = *reg;
- }
-
- if (*(instance->base + T_STATUS_REG_OFFSET) & T_ST_TIM) {
- unsigned char tmp;
- volatile unsigned char *foo;
- foo = instance->base + T_CONTROL_REG_OFFSET;
- tmp = *foo;
- *foo = tmp | T_CR_CT;
- *foo = tmp;
- printk("scsi%d : watchdog timer fired in NCR5380_pread()\n",
- instance->host_no);
- return -1;
- } else
- return 0;
-}
-
-/*
- * Function : int NCR5380_pwrite (struct Scsi_Host *instance,
- * unsigned char *src, int len)
- *
- * Purpose : Fast 5380 pseudo-dma write function, transfers len bytes from
- * src
- *
- * Inputs : src = source, len = length in bytes
- *
- * Returns : 0 on success, non zero on a failure such as a watchdog
- * timeout.
- */
-
-static inline int NCR5380_pwrite (struct Scsi_Host *instance, unsigned char *src,
- int len) {
- register unsigned char *reg = (unsigned char *) (instance->base +
- T_DATA_REG_OFFSET), *s = src;
- register i = len;
-
-#if 0
- for (; i; --i) {
- while (!(instance->base[T_STATUS_REG_OFFSET]) & T_ST_RDY) barrier();
-#else
- while (!(instance->base[T_STATUS_REG_OFFSET]) & T_ST_RDY) barrier();
- for (; i; --i) {
-#endif
- *reg = *s++;
- }
-
- if (*(instance->base + T_STATUS_REG_OFFSET) & T_ST_TIM) {
- unsigned char tmp;
- volatile unsigned char *foo;
- foo = instance->base + T_CONTROL_REG_OFFSET;
- tmp = *foo;
- *foo = tmp | T_CR_CT;
- *foo = tmp;
- printk("scsi%d : watchdog timer fired in NCR5380_pwrite()\n",
- instance->host_no);
- return -1;
- } else
- return 0;
-}
-
-#ifdef MACH
-#include "NCR5380.src"
-#else
-#include "NCR5380.c"
-#endif
-
-#ifdef MODULE
-/* Eventually this will go into an include file, but this will be later */
-Scsi_Host_Template driver_template = TRANTOR_T128;
-
-#include "scsi_module.c"
-#endif
diff --git a/i386/i386at/gpl/linux/scsi/t128.h b/i386/i386at/gpl/linux/scsi/t128.h
deleted file mode 100644
index 8c7cb579..00000000
--- a/i386/i386at/gpl/linux/scsi/t128.h
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Trantor T128/T128F/T228 defines
- * Note : architecturally, the T100 and T128 are different and won't work
- *
- * Copyright 1993, Drew Eckhardt
- * Visionary Computing
- * (Unix and Linux consulting and custom programming)
- * drew@colorado.edu
- * +1 (303) 440-4894
- *
- * DISTRIBUTION RELEASE 3.
- *
- * For more information, please consult
- *
- * Trantor Systems, Ltd.
- * T128/T128F/T228 SCSI Host Adapter
- * Hardware Specifications
- *
- * Trantor Systems, Ltd.
- * 5415 Randall Place
- * Fremont, CA 94538
- * 1+ (415) 770-1400, FAX 1+ (415) 770-9910
- *
- * and
- *
- * NCR 5380 Family
- * SCSI Protocol Controller
- * Databook
- *
- * NCR Microelectronics
- * 1635 Aeroplaza Drive
- * Colorado Springs, CO 80916
- * 1+ (719) 578-3400
- * 1+ (800) 334-5454
- */
-
-/*
- * $Log: t128.h,v $
- * Revision 1.1.1.1 1996/10/30 01:40:07 thomas
- * Imported from UK22
- *
- * Revision 1.1 1996/03/25 20:25:52 goel
- * Linux driver merge.
- *
- */
-
-#ifndef T128_H
-#define T128_H
-
-#define T128_PUBLIC_RELEASE 3
-
-#define TDEBUG_INIT 0x1
-#define TDEBUG_TRANSFER 0x2
-
-/*
- * The trantor boards are memory mapped. They use an NCR5380 or
- * equivalent (my sample board had part second sourced from ZILOG).
- * NCR's recommended "Pseudo-DMA" architecture is used, where
- * a PAL drives the DMA signals on the 5380 allowing fast, blind
- * transfers with proper handshaking.
- */
-
-/*
- * Note : a boot switch is provided for the purpose of informing the
- * firmware to boot or not boot from attached SCSI devices. So, I imagine
- * there are fewer people who've yanked the ROM like they do on the Seagate
- * to make bootup faster, and I'll probably use this for autodetection.
- */
-#define T_ROM_OFFSET 0
-
-/*
- * Note : my sample board *WAS NOT* populated with the SRAM, so this
- * can't be used for autodetection without a ROM present.
- */
-#define T_RAM_OFFSET 0x1800
-
-/*
- * All of the registers are allocated 32 bytes of address space, except
- * for the data register (read/write to/from the 5380 in pseudo-DMA mode)
- */
-#define T_CONTROL_REG_OFFSET 0x1c00 /* rw */
-#define T_CR_INT 0x10 /* Enable interrupts */
-#define T_CR_CT 0x02 /* Reset watchdog timer */
-
-#define T_STATUS_REG_OFFSET 0x1c20 /* ro */
-#define T_ST_BOOT 0x80 /* Boot switch */
-#define T_ST_S3 0x40 /* User settable switches, */
-#define T_ST_S2 0x20 /* read 0 when switch is on, 1 off */
-#define T_ST_S1 0x10
-#define T_ST_PS2 0x08 /* Set for Microchannel 228 */
-#define T_ST_RDY 0x04 /* 5380 DRQ */
-#define T_ST_TIM 0x02 /* indicates 40us watchdog timer fired */
-#define T_ST_ZERO 0x01 /* Always zero */
-
-#define T_5380_OFFSET 0x1d00 /* 8 registers here, see NCR5380.h */
-
-#define T_DATA_REG_OFFSET 0x1e00 /* rw 512 bytes long */
-
-#ifndef ASM
-int t128_abort(Scsi_Cmnd *);
-int t128_biosparam(Disk *, kdev_t, int*);
-int t128_detect(Scsi_Host_Template *);
-int t128_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-int t128_reset(Scsi_Cmnd *);
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#ifndef CMD_PER_LUN
-#define CMD_PER_LUN 2
-#endif
-
-#ifndef CAN_QUEUE
-#define CAN_QUEUE 32
-#endif
-
-/*
- * I hadn't thought of this with the earlier drivers - but to prevent
- * macro definition conflicts, we shouldn't define all of the internal
- * macros when this is being used solely for the host stub.
- */
-
-#if defined(HOSTS_C) || defined(MODULE)
-
-#define TRANTOR_T128 {NULL, NULL, NULL, NULL, \
- "Trantor T128/T128F/T228", t128_detect, NULL, \
- NULL, \
- NULL, t128_queue_command, t128_abort, t128_reset, NULL, \
- t128_biosparam, \
- /* can queue */ CAN_QUEUE, /* id */ 7, SG_ALL, \
- /* cmd per lun */ CMD_PER_LUN , 0, 0, DISABLE_CLUSTERING}
-
-#endif
-
-#ifndef(HOSTS_C)
-
-#define NCR5380_implementation_fields \
- volatile unsigned char *base
-
-#define NCR5380_local_declare() \
- volatile unsigned char *base
-
-#define NCR5380_setup(instance) \
- base = (volatile unsigned char *) (instance)->base
-
-#define T128_address(reg) (base + T_5380_OFFSET + ((reg) * 0x20))
-
-#if !(TDEBUG & TDEBUG_TRANSFER)
-#define NCR5380_read(reg) (*(T128_address(reg)))
-#define NCR5380_write(reg, value) (*(T128_address(reg)) = (value))
-#else
-#define NCR5380_read(reg) \
- (((unsigned char) printk("scsi%d : read register %d at address %08x\n"\
- , instance->hostno, (reg), T128_address(reg))), *(T128_address(reg)))
-
-#define NCR5380_write(reg, value) { \
- printk("scsi%d : write %02x to register %d at address %08x\n", \
- instance->hostno, (value), (reg), T128_address(reg)); \
- *(T128_address(reg)) = (value); \
-}
-#endif
-
-#define NCR5380_intr t128_intr
-#define NCR5380_queue_command t128_queue_command
-#define NCR5380_abort t128_abort
-#define NCR5380_reset t128_reset
-
-/* 15 14 12 10 7 5 3
- 1101 0100 1010 1000 */
-
-#define T128_IRQS 0xc4a8
-
-#endif /* else def HOSTS_C */
-#endif /* ndef ASM */
-#endif /* T128_H */
diff --git a/i386/i386at/gpl/linux/scsi/u14-34f.c b/i386/i386at/gpl/linux/scsi/u14-34f.c
deleted file mode 100644
index ce0e378e..00000000
--- a/i386/i386at/gpl/linux/scsi/u14-34f.c
+++ /dev/null
@@ -1,1044 +0,0 @@
-/*
- * u14-34f.c - Low-level driver for UltraStor 14F/34F SCSI host adapters.
- *
- * 13 Jun 1995 rev. 2.01 for linux 1.2.10
- * HAVE_OLD_UX4F_FIRMWARE should be defined for U34F boards when
- * the firmware prom is not the lastest one (28008-006).
- *
- * 11 Mar 1995 rev. 2.00 for linux 1.2.0
- * Fixed a bug which prevented media change detection for removable
- * disk drives.
- *
- * 23 Feb 1995 rev. 1.18 for linux 1.1.94
- * Added a check for scsi_register returning NULL.
- *
- * 11 Feb 1995 rev. 1.17 for linux 1.1.91
- * U14F qualified to run with 32 sglists.
- * Now DEBUG_RESET is disabled by default.
- *
- * 9 Feb 1995 rev. 1.16 for linux 1.1.90
- * Use host->wish_block instead of host->block.
- *
- * 8 Feb 1995 rev. 1.15 for linux 1.1.89
- * Cleared target_time_out counter while performing a reset.
- *
- * 28 Jan 1995 rev. 1.14 for linux 1.1.86
- * Added module support.
- * Log and do a retry when a disk drive returns a target status
- * different from zero on a recovered error.
- * Auto detects if U14F boards have an old firmware revision.
- * Max number of scatter/gather lists set to 16 for all boards
- * (most installation run fine using 33 sglists, while other
- * has problems when using more then 16).
- *
- * 16 Jan 1995 rev. 1.13 for linux 1.1.81
- * Display a message if check_region detects a port address
- * already in use.
- *
- * 15 Dec 1994 rev. 1.12 for linux 1.1.74
- * The host->block flag is set for all the detected ISA boards.
- *
- * 30 Nov 1994 rev. 1.11 for linux 1.1.68
- * Redo i/o on target status CHECK_CONDITION for TYPE_DISK only.
- * Added optional support for using a single board at a time.
- *
- * 14 Nov 1994 rev. 1.10 for linux 1.1.63
- *
- * 28 Oct 1994 rev. 1.09 for linux 1.1.58 Final BETA release.
- * 16 Jul 1994 rev. 1.00 for linux 1.1.29 Initial ALPHA release.
- *
- * This driver is a total replacement of the original UltraStor
- * scsi driver, but it supports ONLY the 14F and 34F boards.
- * It can be configured in the same kernel in which the original
- * ultrastor driver is configured to allow the original U24F
- * support.
- *
- * Multiple U14F and/or U34F host adapters are supported.
- *
- * Copyright (C) 1994, 1995 Dario Ballabio (dario@milano.europe.dg.com)
- *
- * WARNING: if your 14/34F board has an old firmware revision (see below)
- * you must change "#undef" into "#define" in the following
- * statement.
- */
-#undef HAVE_OLD_UX4F_FIRMWARE
-/*
- * The UltraStor 14F, 24F, and 34F are a family of intelligent, high
- * performance SCSI-2 host adapters.
- * Here is the scoop on the various models:
- *
- * 14F - ISA first-party DMA HA with floppy support and WD1003 emulation.
- * 24F - EISA Bus Master HA with floppy support and WD1003 emulation.
- * 34F - VESA Local-Bus Bus Master HA (no WD1003 emulation).
- *
- * This code has been tested with up to two U14F boards, using both
- * firmware 28004-005/38004-004 (BIOS rev. 2.00) and the latest firmware
- * 28004-006/38004-005 (BIOS rev. 2.01).
- *
- * The latest firmware is required in order to get reliable operations when
- * clustering is enabled. ENABLE_CLUSTERING provides a performance increase
- * up to 50% on sequential access.
- *
- * Since the Scsi_Host_Template structure is shared among all 14F and 34F,
- * the last setting of use_clustering is in effect for all of these boards.
- *
- * Here a sample configuration using two U14F boards:
- *
- U14F0: PORT 0x330, BIOS 0xc8000, IRQ 11, DMA 5, SG 32, Mbox 16, CmdLun 2, C1.
- U14F1: PORT 0x340, BIOS 0x00000, IRQ 10, DMA 6, SG 32, Mbox 16, CmdLun 2, C1.
- *
- * The boot controller must have its BIOS enabled, while other boards can
- * have their BIOS disabled, or enabled to an higher address.
- * Boards are named Ux4F0, Ux4F1..., according to the port address order in
- * the io_port[] array.
- *
- * The following facts are based on real testing results (not on
- * documentation) on the above U14F board.
- *
- * - The U14F board should be jumpered for bus on time less or equal to 7
- * microseconds, while the default is 11 microseconds. This is order to
- * get acceptable performance while using floppy drive and hard disk
- * together. The jumpering for 7 microseconds is: JP13 pin 15-16,
- * JP14 pin 7-8 and pin 9-10.
- * The reduction has a little impact on scsi performance.
- *
- * - If scsi bus length exceeds 3m., the scsi bus speed needs to be reduced
- * from 10Mhz to 5Mhz (do this by inserting a jumper on JP13 pin 7-8).
- *
- * - If U14F on board firmware is older than 28004-006/38004-005,
- * the U14F board is unable to provide reliable operations if the scsi
- * request length exceeds 16Kbyte. When this length is exceeded the
- * behavior is:
- * - adapter_status equal 0x96 or 0xa3 or 0x93 or 0x94;
- * - adapter_status equal 0 and target_status equal 2 on for all targets
- * in the next operation following the reset.
- * This sequence takes a long time (>3 seconds), so in the meantime
- * the SD_TIMEOUT in sd.c could expire giving rise to scsi aborts
- * (SD_TIMEOUT has been increased from 3 to 6 seconds in 1.1.31).
- * Because of this I had to DISABLE_CLUSTERING and to work around the
- * bus reset in the interrupt service routine, returning DID_BUS_BUSY
- * so that the operations are retried without complains from the scsi.c
- * code.
- * Any reset of the scsi bus is going to kill tape operations, since
- * no retry is allowed for tapes. Bus resets are more likely when the
- * scsi bus is under heavy load.
- * Requests using scatter/gather have a maximum length of 16 x 1024 bytes
- * when DISABLE_CLUSTERING is in effect, but unscattered requests could be
- * larger than 16Kbyte.
- *
- * The new firmware has fixed all the above problems.
- *
- * For U34F boards the latest bios prom is 38008-002 (BIOS rev. 2.01),
- * the latest firmware prom is 28008-006. Older firmware 28008-005 has
- * problems when using more then 16 scatter/gather lists.
- *
- * In order to support multiple ISA boards in a reliable way,
- * the driver sets host->wish_block = TRUE for all ISA boards.
- */
-
-#if defined(MODULE)
-#include <linux/module.h>
-#include <linux/version.h>
-#endif
-
-#include <linux/string.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/ioport.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include <linux/proc_fs.h>
-#include <linux/blk.h>
-#include "scsi.h"
-#include "hosts.h"
-#include "sd.h"
-#include <asm/dma.h>
-#include <asm/irq.h>
-#include "u14-34f.h"
-#include<linux/stat.h>
-
-struct proc_dir_entry proc_scsi_u14_34f = {
- PROC_SCSI_U14_34F, 6, "u14_34f",
- S_IFDIR | S_IRUGO | S_IXUGO, 2
-};
-
-/* Values for the PRODUCT_ID ports for the 14/34F */
-#define PRODUCT_ID1 0x56
-#define PRODUCT_ID2 0x40 /* NOTE: Only upper nibble is used */
-
-/* Subversion values */
-#define ISA 0
-#define ESA 1
-
-#define OP_HOST_ADAPTER 0x1
-#define OP_SCSI 0x2
-#define OP_RESET 0x4
-#define DTD_SCSI 0x0
-#define DTD_IN 0x1
-#define DTD_OUT 0x2
-#define DTD_NONE 0x3
-#define HA_CMD_INQUIRY 0x1
-#define HA_CMD_SELF_DIAG 0x2
-#define HA_CMD_READ_BUFF 0x3
-#define HA_CMD_WRITE_BUFF 0x4
-
-#undef DEBUG_DETECT
-#undef DEBUG_INTERRUPT
-#undef DEBUG_STATISTICS
-#undef DEBUG_RESET
-
-#define MAX_TARGET 8
-#define MAX_IRQ 16
-#define MAX_BOARDS 4
-#define MAX_MAILBOXES 16
-#define MAX_SGLIST 32
-#define MAX_SAFE_SGLIST 16
-#define MAX_CMD_PER_LUN 2
-
-#define FALSE 0
-#define TRUE 1
-#define FREE 0
-#define IN_USE 1
-#define LOCKED 2
-#define IN_RESET 3
-#define IGNORE 4
-#define NO_IRQ 0xff
-#define NO_DMA 0xff
-#define MAXLOOP 200000
-
-#define REG_LCL_MASK 0
-#define REG_LCL_INTR 1
-#define REG_SYS_MASK 2
-#define REG_SYS_INTR 3
-#define REG_PRODUCT_ID1 4
-#define REG_PRODUCT_ID2 5
-#define REG_CONFIG1 6
-#define REG_CONFIG2 7
-#define REG_OGM 8
-#define REG_ICM 12
-#define REGION_SIZE 13
-#define BSY_ASSERTED 0x01
-#define IRQ_ASSERTED 0x01
-#define CMD_RESET 0xc0
-#define CMD_OGM_INTR 0x01
-#define CMD_CLR_INTR 0x01
-#define CMD_ENA_INTR 0x81
-#define ASOK 0x00
-#define ASST 0x91
-
-#define PACKED __attribute__((packed))
-
-/* MailBox SCSI Command Packet */
-struct mscp {
- unsigned char opcode: 3; /* type of command */
- unsigned char xdir: 2; /* data transfer direction */
- unsigned char dcn: 1; /* disable disconnect */
- unsigned char ca: 1; /* use cache (if available) */
- unsigned char sg: 1; /* scatter/gather operation */
- unsigned char target: 3; /* target SCSI id */
- unsigned char ch_no: 2; /* SCSI channel (always 0 for 14f) */
- unsigned char lun: 3; /* logical unit number */
- unsigned int data_address PACKED; /* transfer data pointer */
- unsigned int data_len PACKED; /* length in bytes */
- unsigned int command_link PACKED; /* for linking command chains */
- unsigned char scsi_command_link_id; /* identifies command in chain */
- unsigned char use_sg; /* (if sg is set) 8 bytes per list */
- unsigned char sense_len;
- unsigned char scsi_cdbs_len; /* 6, 10, or 12 */
- unsigned char scsi_cdbs[12]; /* SCSI commands */
- unsigned char adapter_status; /* non-zero indicates HA error */
- unsigned char target_status; /* non-zero indicates target error */
- unsigned int sense_addr PACKED;
-
- Scsi_Cmnd *SCpnt;
-
- struct sg_list {
- unsigned int address; /* Segment Address */
- unsigned int num_bytes; /* Segment Length */
- } sglist[MAX_SGLIST];
-
- unsigned int index; /* cp index */
- };
-
-struct hostdata {
- struct mscp cp[MAX_MAILBOXES]; /* Mailboxes for this board */
- unsigned int cp_stat[MAX_MAILBOXES]; /* FREE, IN_USE, LOCKED, IN_RESET */
- unsigned int last_cp_used; /* Index of last mailbox used */
- unsigned int iocount; /* Total i/o done for this board */
- unsigned int multicount; /* Total ... in second ihdlr loop */
- int board_number; /* Number of this board */
- char board_name[16]; /* Name of this board */
- char board_id[256]; /* data from INQUIRY on this board */
- int in_reset; /* True if board is doing a reset */
- int target_time_out[MAX_TARGET]; /* N. of timeout errors on target */
- int target_reset[MAX_TARGET]; /* If TRUE redo operation on target */
- unsigned char subversion; /* Bus type, either ISA or ESA */
- unsigned char heads;
- unsigned char sectors;
-
- /* slot != 0 for the U24F, slot == 0 for both the U14F and U34F */
- unsigned char slot;
- };
-
-static struct Scsi_Host * sh[MAX_BOARDS + 1];
-static const char* driver_name = "Ux4F";
-static unsigned int irqlist[MAX_IRQ], calls[MAX_IRQ];
-
-#define HD(board) ((struct hostdata *) &sh[board]->hostdata)
-#define BN(board) (HD(board)->board_name)
-
-static void u14_34f_interrupt_handler(int, struct pt_regs *);
-static int do_trace = FALSE;
-
-static inline unchar wait_on_busy(ushort iobase) {
- unsigned int loop = MAXLOOP;
-
- while (inb(iobase + REG_LCL_INTR) & BSY_ASSERTED)
- if (--loop == 0) return TRUE;
-
- return FALSE;
-}
-
-static int board_inquiry(unsigned int j) {
- struct mscp *cpp;
- unsigned int time, limit = 0;
-
- cpp = &HD(j)->cp[0];
- memset(cpp, 0, sizeof(struct mscp));
- cpp->opcode = OP_HOST_ADAPTER;
- cpp->xdir = DTD_IN;
- cpp->data_address = (unsigned int) HD(j)->board_id;
- cpp->data_len = sizeof(HD(j)->board_id);
- cpp->scsi_cdbs_len = 6;
- cpp->scsi_cdbs[0] = HA_CMD_INQUIRY;
-
- if (wait_on_busy(sh[j]->io_port)) {
- printk("%s: board_inquiry, adapter busy.\n", BN(j));
- return TRUE;
- }
-
- HD(j)->cp_stat[0] = IGNORE;
-
- /* Clear the interrupt indication */
- outb(CMD_CLR_INTR, sh[j]->io_port + REG_SYS_INTR);
-
- /* Store pointer in OGM address bytes */
- outl((unsigned int)cpp, sh[j]->io_port + REG_OGM);
-
- /* Issue OGM interrupt */
- outb(CMD_OGM_INTR, sh[j]->io_port + REG_LCL_INTR);
-
- sti();
- time = jiffies;
- while (jiffies < (time + 100) && limit++ < 100000000);
- cli();
-
- if (cpp->adapter_status || HD(j)->cp_stat[0] != FREE) {
- HD(j)->cp_stat[0] = FREE;
- printk("%s: board_inquiry, err 0x%x.\n", BN(j), cpp->adapter_status);
- return TRUE;
- }
-
- return FALSE;
-}
-
-static inline int port_detect(ushort *port_base, unsigned int j,
- Scsi_Host_Template * tpnt) {
- unsigned char irq, dma_channel, subversion;
- unsigned char in_byte;
-
- /* Allowed BIOS base addresses (NULL indicates reserved) */
- void *bios_segment_table[8] = {
- NULL,
- (void *) 0xc4000, (void *) 0xc8000, (void *) 0xcc000, (void *) 0xd0000,
- (void *) 0xd4000, (void *) 0xd8000, (void *) 0xdc000
- };
-
- /* Allowed IRQs */
- unsigned char interrupt_table[4] = { 15, 14, 11, 10 };
-
- /* Allowed DMA channels for ISA (0 indicates reserved) */
- unsigned char dma_channel_table[4] = { 5, 6, 7, 0 };
-
- /* Head/sector mappings */
- struct {
- unsigned char heads;
- unsigned char sectors;
- } mapping_table[4] = {
- { 16, 63 }, { 64, 32 }, { 64, 63 }, { 64, 32 }
- };
-
- struct config_1 {
- unsigned char bios_segment: 3;
- unsigned char removable_disks_as_fixed: 1;
- unsigned char interrupt: 2;
- unsigned char dma_channel: 2;
- } config_1;
-
- struct config_2 {
- unsigned char ha_scsi_id: 3;
- unsigned char mapping_mode: 2;
- unsigned char bios_drive_number: 1;
- unsigned char tfr_port: 2;
- } config_2;
-
- char name[16];
-
- sprintf(name, "%s%d", driver_name, j);
-
- if(check_region(*port_base, REGION_SIZE)) {
- printk("%s: address 0x%03x in use, skipping probe.\n",
- name, *port_base);
- return FALSE;
- }
-
- if (inb(*port_base + REG_PRODUCT_ID1) != PRODUCT_ID1) return FALSE;
-
- in_byte = inb(*port_base + REG_PRODUCT_ID2);
-
- if ((in_byte & 0xf0) != PRODUCT_ID2) return FALSE;
-
- *(char *)&config_1 = inb(*port_base + REG_CONFIG1);
- *(char *)&config_2 = inb(*port_base + REG_CONFIG2);
-
- irq = interrupt_table[config_1.interrupt];
- dma_channel = dma_channel_table[config_1.dma_channel];
- subversion = (in_byte & 0x0f);
-
- /* Board detected, allocate its IRQ if not already done */
- if ((irq >= MAX_IRQ) || ((irqlist[irq] == NO_IRQ) && request_irq
- (irq, u14_34f_interrupt_handler, SA_INTERRUPT, driver_name))) {
- printk("%s: unable to allocate IRQ %u, detaching.\n", name, irq);
- return FALSE;
- }
-
- if (subversion == ISA && request_dma(dma_channel, driver_name)) {
- printk("%s: unable to allocate DMA channel %u, detaching.\n",
- name, dma_channel);
- free_irq(irq);
- return FALSE;
- }
-
- sh[j] = scsi_register(tpnt, sizeof(struct hostdata));
-
- if (sh[j] == NULL) {
- printk("%s: unable to register host, detaching.\n", name);
-
- if (irqlist[irq] == NO_IRQ) free_irq(irq);
-
- if (subversion == ISA) free_dma(dma_channel);
-
- return FALSE;
- }
-
- sh[j]->io_port = *port_base;
- sh[j]->n_io_port = REGION_SIZE;
- sh[j]->base = bios_segment_table[config_1.bios_segment];
- sh[j]->irq = irq;
- sh[j]->sg_tablesize = MAX_SGLIST;
- sh[j]->this_id = config_2.ha_scsi_id;
- sh[j]->can_queue = MAX_MAILBOXES;
- sh[j]->cmd_per_lun = MAX_CMD_PER_LUN;
-
-#if defined(DEBUG_DETECT)
- {
- unsigned char sys_mask, lcl_mask;
-
- sys_mask = inb(sh[j]->io_port + REG_SYS_MASK);
- lcl_mask = inb(sh[j]->io_port + REG_LCL_MASK);
- printk("SYS_MASK 0x%x, LCL_MASK 0x%x.\n", sys_mask, lcl_mask);
- }
-#endif
-
- /* If BIOS is disabled, force enable interrupts */
- if (sh[j]->base == 0) outb(CMD_ENA_INTR, sh[j]->io_port + REG_SYS_MASK);
-
- /* Register the I/O space that we use */
- request_region(sh[j]->io_port, REGION_SIZE, driver_name);
-
- memset(HD(j), 0, sizeof(struct hostdata));
- HD(j)->heads = mapping_table[config_2.mapping_mode].heads;
- HD(j)->sectors = mapping_table[config_2.mapping_mode].sectors;
- HD(j)->subversion = subversion;
- HD(j)->board_number = j;
- irqlist[irq] = j;
-
- if (HD(j)->subversion == ESA) {
-
-#if defined (HAVE_OLD_UX4F_FIRMWARE)
- sh[j]->sg_tablesize = MAX_SAFE_SGLIST;
-#endif
-
- sh[j]->dma_channel = NO_DMA;
- sh[j]->unchecked_isa_dma = FALSE;
- sprintf(BN(j), "U34F%d", j);
- }
- else {
- sh[j]->wish_block = TRUE;
-
-#if defined (HAVE_OLD_UX4F_FIRMWARE)
- sh[j]->hostt->use_clustering = DISABLE_CLUSTERING;
- sh[j]->sg_tablesize = MAX_SAFE_SGLIST;
-#endif
-
- sh[j]->dma_channel = dma_channel;
- sh[j]->unchecked_isa_dma = TRUE;
- sprintf(BN(j), "U14F%d", j);
- disable_dma(dma_channel);
- clear_dma_ff(dma_channel);
- set_dma_mode(dma_channel, DMA_MODE_CASCADE);
- enable_dma(dma_channel);
- }
-
- if (HD(j)->subversion == ISA && !board_inquiry(j)) {
- HD(j)->board_id[40] = 0;
-
- if (strcmp(&HD(j)->board_id[32], "06000600")) {
- printk("%s: %s.\n", BN(j), &HD(j)->board_id[8]);
- printk("%s: firmware %s is outdated, FW PROM should be 28004-006.\n",
- BN(j), &HD(j)->board_id[32]);
- sh[j]->hostt->use_clustering = DISABLE_CLUSTERING;
- sh[j]->sg_tablesize = MAX_SAFE_SGLIST;
- }
- }
-
- printk("%s: PORT 0x%03x, BIOS 0x%05x, IRQ %u, DMA %u, SG %d, "\
- "Mbox %d, CmdLun %d, C%d.\n", BN(j), sh[j]->io_port,
- (int)sh[j]->base, sh[j]->irq,
- sh[j]->dma_channel, sh[j]->sg_tablesize,
- sh[j]->can_queue, sh[j]->cmd_per_lun,
- sh[j]->hostt->use_clustering);
- return TRUE;
-}
-
-int u14_34f_detect (Scsi_Host_Template * tpnt) {
- unsigned int j = 0, k, flags;
-
- ushort io_port[] = {
- 0x330, 0x340, 0x230, 0x240, 0x210, 0x130, 0x140, 0x0
- };
-
- ushort *port_base = io_port;
-
- tpnt->proc_dir = &proc_scsi_u14_34f;
-
- save_flags(flags);
- cli();
-
- for (k = 0; k < MAX_IRQ; k++) {
- irqlist[k] = NO_IRQ;
- calls[k] = 0;
- }
-
- for (k = 0; k < MAX_BOARDS + 1; k++) sh[k] = NULL;
-
- while (*port_base) {
-
- if (j < MAX_BOARDS && port_detect(port_base, j, tpnt)) j++;
-
- port_base++;
- }
-
- if (j > 0)
- printk("UltraStor 14F/34F: Copyright (C) 1994, 1995 Dario Ballabio.\n");
-
- restore_flags(flags);
- return j;
-}
-
-static inline void build_sg_list(struct mscp *cpp, Scsi_Cmnd *SCpnt) {
- unsigned int k, data_len = 0;
- struct scatterlist * sgpnt;
-
- sgpnt = (struct scatterlist *) SCpnt->request_buffer;
-
- for (k = 0; k < SCpnt->use_sg; k++) {
- cpp->sglist[k].address = (unsigned int) sgpnt[k].address;
- cpp->sglist[k].num_bytes = sgpnt[k].length;
- data_len += sgpnt[k].length;
- }
-
- cpp->use_sg = SCpnt->use_sg;
- cpp->data_address = (unsigned int) cpp->sglist;
- cpp->data_len = data_len;
-}
-
-int u14_34f_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
- unsigned int i, j, k, flags;
- struct mscp *cpp;
-
- save_flags(flags);
- cli();
- /* j is the board number */
- j = ((struct hostdata *) SCpnt->host->hostdata)->board_number;
-
- if (!done) panic("%s: qcomm, pid %ld, null done.\n", BN(j), SCpnt->pid);
-
- /* i is the mailbox number, look for the first free mailbox
- starting from last_cp_used */
- i = HD(j)->last_cp_used + 1;
-
- for (k = 0; k < sh[j]->can_queue; k++, i++) {
-
- if (i >= sh[j]->can_queue) i = 0;
-
- if (HD(j)->cp_stat[i] == FREE) {
- HD(j)->last_cp_used = i;
- break;
- }
- }
-
- if (k == sh[j]->can_queue) {
- printk("%s: qcomm, no free mailbox, resetting.\n", BN(j));
-
- if (HD(j)->in_reset)
- printk("%s: qcomm, already in reset.\n", BN(j));
- else if (u14_34f_reset(SCpnt) == SCSI_RESET_SUCCESS)
- panic("%s: qcomm, SCSI_RESET_SUCCESS.\n", BN(j));
-
- SCpnt->result = DID_BUS_BUSY << 16;
- SCpnt->host_scribble = NULL;
- printk("%s: qcomm, pid %ld, DID_BUS_BUSY, done.\n", BN(j), SCpnt->pid);
- restore_flags(flags);
- done(SCpnt);
- return 0;
- }
-
- /* Set pointer to control packet structure */
- cpp = &HD(j)->cp[i];
-
- memset(cpp, 0, sizeof(struct mscp));
- SCpnt->scsi_done = done;
- cpp->index = i;
- SCpnt->host_scribble = (unsigned char *) &cpp->index;
-
- if (do_trace) printk("%s: qcomm, mbox %d, target %d, pid %ld.\n",
- BN(j), i, SCpnt->target, SCpnt->pid);
-
- cpp->opcode = OP_SCSI;
- cpp->xdir = DTD_SCSI;
- cpp->target = SCpnt->target;
- cpp->lun = SCpnt->lun;
- cpp->SCpnt = SCpnt;
- cpp->sense_addr = (unsigned int) SCpnt->sense_buffer;
- cpp->sense_len = sizeof SCpnt->sense_buffer;
-
- if (SCpnt->use_sg) {
- cpp->sg = TRUE;
- build_sg_list(cpp, SCpnt);
- }
- else {
- cpp->data_address = (unsigned int)SCpnt->request_buffer;
- cpp->data_len = SCpnt->request_bufflen;
- }
-
- cpp->scsi_cdbs_len = SCpnt->cmd_len;
- memcpy(cpp->scsi_cdbs, SCpnt->cmnd, cpp->scsi_cdbs_len);
-
- if (wait_on_busy(sh[j]->io_port)) {
- SCpnt->result = DID_ERROR << 16;
- SCpnt->host_scribble = NULL;
- printk("%s: qcomm, target %d, pid %ld, adapter busy, DID_ERROR, done.\n",
- BN(j), SCpnt->target, SCpnt->pid);
- restore_flags(flags);
- done(SCpnt);
- return 0;
- }
-
- /* Store pointer in OGM address bytes */
- outl((unsigned int)cpp, sh[j]->io_port + REG_OGM);
-
- /* Issue OGM interrupt */
- outb(CMD_OGM_INTR, sh[j]->io_port + REG_LCL_INTR);
-
- HD(j)->cp_stat[i] = IN_USE;
- restore_flags(flags);
- return 0;
-}
-
-int u14_34f_abort(Scsi_Cmnd *SCarg) {
- unsigned int i, j, flags;
-
- save_flags(flags);
- cli();
- j = ((struct hostdata *) SCarg->host->hostdata)->board_number;
-
- if (SCarg->host_scribble == NULL) {
- printk("%s: abort, target %d, pid %ld inactive.\n",
- BN(j), SCarg->target, SCarg->pid);
- restore_flags(flags);
- return SCSI_ABORT_NOT_RUNNING;
- }
-
- i = *(unsigned int *)SCarg->host_scribble;
- printk("%s: abort, mbox %d, target %d, pid %ld.\n",
- BN(j), i, SCarg->target, SCarg->pid);
-
- if (i >= sh[j]->can_queue)
- panic("%s: abort, invalid SCarg->host_scribble.\n", BN(j));
-
- if (wait_on_busy(sh[j]->io_port)) {
- printk("%s: abort, timeout error.\n", BN(j));
- restore_flags(flags);
- return SCSI_ABORT_ERROR;
- }
-
- if (HD(j)->cp_stat[i] == FREE) {
- printk("%s: abort, mbox %d is free.\n", BN(j), i);
- restore_flags(flags);
- return SCSI_ABORT_NOT_RUNNING;
- }
-
- if (HD(j)->cp_stat[i] == IN_USE) {
- printk("%s: abort, mbox %d is in use.\n", BN(j), i);
-
- if (SCarg != HD(j)->cp[i].SCpnt)
- panic("%s: abort, mbox %d, SCarg %p, cp SCpnt %p.\n",
- BN(j), i, SCarg, HD(j)->cp[i].SCpnt);
-
- restore_flags(flags);
- return SCSI_ABORT_SNOOZE;
- }
-
- if (HD(j)->cp_stat[i] == IN_RESET) {
- printk("%s: abort, mbox %d is in reset.\n", BN(j), i);
- restore_flags(flags);
- return SCSI_ABORT_ERROR;
- }
-
- if (HD(j)->cp_stat[i] == LOCKED) {
- printk("%s: abort, mbox %d is locked.\n", BN(j), i);
- restore_flags(flags);
- return SCSI_ABORT_NOT_RUNNING;
- }
- restore_flags(flags);
- panic("%s: abort, mbox %d, invalid cp_stat.\n", BN(j), i);
-}
-
-int u14_34f_reset(Scsi_Cmnd * SCarg) {
- unsigned int i, j, flags, time, k, limit = 0;
- int arg_done = FALSE;
- Scsi_Cmnd *SCpnt;
-
- save_flags(flags);
- cli();
- j = ((struct hostdata *) SCarg->host->hostdata)->board_number;
- printk("%s: reset, enter, target %d, pid %ld.\n",
- BN(j), SCarg->target, SCarg->pid);
-
- if (SCarg->host_scribble == NULL)
- printk("%s: reset, pid %ld inactive.\n", BN(j), SCarg->pid);
-
- if (HD(j)->in_reset) {
- printk("%s: reset, exit, already in reset.\n", BN(j));
- restore_flags(flags);
- return SCSI_RESET_ERROR;
- }
-
- if (wait_on_busy(sh[j]->io_port)) {
- printk("%s: reset, exit, timeout error.\n", BN(j));
- restore_flags(flags);
- return SCSI_RESET_ERROR;
- }
-
- for (k = 0; k < MAX_TARGET; k++) HD(j)->target_reset[k] = TRUE;
-
- for (k = 0; k < MAX_TARGET; k++) HD(j)->target_time_out[k] = 0;
-
- for (i = 0; i < sh[j]->can_queue; i++) {
-
- if (HD(j)->cp_stat[i] == FREE) continue;
-
- if (HD(j)->cp_stat[i] == LOCKED) {
- HD(j)->cp_stat[i] = FREE;
- printk("%s: reset, locked mbox %d forced free.\n", BN(j), i);
- continue;
- }
-
- SCpnt = HD(j)->cp[i].SCpnt;
- HD(j)->cp_stat[i] = IN_RESET;
- printk("%s: reset, mbox %d in reset, pid %ld.\n",
- BN(j), i, SCpnt->pid);
-
- if (SCpnt == NULL)
- panic("%s: reset, mbox %d, SCpnt == NULL.\n", BN(j), i);
-
- if (SCpnt->host_scribble == NULL)
- panic("%s: reset, mbox %d, garbled SCpnt.\n", BN(j), i);
-
- if (*(unsigned int *)SCpnt->host_scribble != i)
- panic("%s: reset, mbox %d, index mismatch.\n", BN(j), i);
-
- if (SCpnt->scsi_done == NULL)
- panic("%s: reset, mbox %d, SCpnt->scsi_done == NULL.\n", BN(j), i);
-
- if (SCpnt == SCarg) arg_done = TRUE;
- }
-
- if (wait_on_busy(sh[j]->io_port)) {
- printk("%s: reset, cannot reset, timeout error.\n", BN(j));
- restore_flags(flags);
- return SCSI_RESET_ERROR;
- }
-
- outb(CMD_RESET, sh[j]->io_port + REG_LCL_INTR);
- printk("%s: reset, board reset done, enabling interrupts.\n", BN(j));
-
-#if defined (DEBUG_RESET)
- do_trace = TRUE;
-#endif
-
- HD(j)->in_reset = TRUE;
- sti();
- time = jiffies;
- while (jiffies < (time + 100) && limit++ < 100000000);
- cli();
- printk("%s: reset, interrupts disabled, loops %d.\n", BN(j), limit);
-
- for (i = 0; i < sh[j]->can_queue; i++) {
-
- /* Skip mailboxes already set free by interrupt */
- if (HD(j)->cp_stat[i] != IN_RESET) continue;
-
- SCpnt = HD(j)->cp[i].SCpnt;
- SCpnt->result = DID_RESET << 16;
- SCpnt->host_scribble = NULL;
-
- /* This mailbox is still waiting for its interrupt */
- HD(j)->cp_stat[i] = LOCKED;
-
- printk("%s, reset, mbox %d locked, DID_RESET, pid %ld done.\n",
- BN(j), i, SCpnt->pid);
- restore_flags(flags);
- SCpnt->scsi_done(SCpnt);
- cli();
- }
-
- HD(j)->in_reset = FALSE;
- do_trace = FALSE;
- restore_flags(flags);
-
- if (arg_done) {
- printk("%s: reset, exit, success.\n", BN(j));
- return SCSI_RESET_SUCCESS;
- }
- else {
- printk("%s: reset, exit, wakeup.\n", BN(j));
- return SCSI_RESET_PUNT;
- }
-}
-
-int u14_34f_biosparam(Disk * disk, kdev_t dev, int * dkinfo) {
- unsigned int j = 0;
- int size = disk->capacity;
-
- dkinfo[0] = HD(j)->heads;
- dkinfo[1] = HD(j)->sectors;
- dkinfo[2] = size / (HD(j)->heads * HD(j)->sectors);
- return 0;
-}
-
-static void u14_34f_interrupt_handler(int irq, struct pt_regs * regs) {
- Scsi_Cmnd *SCpnt;
- unsigned int i, j, k, flags, status, tstatus, loops, total_loops = 0;
- struct mscp *spp;
-
- save_flags(flags);
- cli();
-
- if (irqlist[irq] == NO_IRQ) {
- printk("%s, ihdlr, irq %d, unexpected interrupt.\n", driver_name, irq);
- restore_flags(flags);
- return;
- }
-
- if (do_trace) printk("%s: ihdlr, enter, irq %d, calls %d.\n",
- driver_name, irq, calls[irq]);
-
- /* Service all the boards configured on this irq */
- for (j = 0; sh[j] != NULL; j++) {
-
- if (sh[j]->irq != irq) continue;
-
- loops = 0;
-
- /* Loop until all interrupts for a board are serviced */
- while (inb(sh[j]->io_port + REG_SYS_INTR) & IRQ_ASSERTED) {
- total_loops++;
- loops++;
-
- if (do_trace) printk("%s: ihdlr, start service, count %d.\n",
- BN(j), HD(j)->iocount);
-
- spp = (struct mscp *)inl(sh[j]->io_port + REG_ICM);
-
- /* Clear interrupt pending flag */
- outb(CMD_CLR_INTR, sh[j]->io_port + REG_SYS_INTR);
-
- i = spp - HD(j)->cp;
-
- if (i >= sh[j]->can_queue)
- panic("%s: ihdlr, invalid mscp address.\n", BN(j));
-
- if (HD(j)->cp_stat[i] == IGNORE) {
- HD(j)->cp_stat[i] = FREE;
- continue;
- }
- else if (HD(j)->cp_stat[i] == LOCKED) {
- HD(j)->cp_stat[i] = FREE;
- printk("%s: ihdlr, mbox %d unlocked, count %d.\n",
- BN(j), i, HD(j)->iocount);
- continue;
- }
- else if (HD(j)->cp_stat[i] == FREE) {
- printk("%s: ihdlr, mbox %d is free, count %d.\n",
- BN(j), i, HD(j)->iocount);
- continue;
- }
- else if (HD(j)->cp_stat[i] == IN_RESET)
- printk("%s: ihdlr, mbox %d is in reset.\n", BN(j), i);
- else if (HD(j)->cp_stat[i] != IN_USE)
- panic("%s: ihdlr, mbox %d, invalid cp_stat.\n", BN(j), i);
-
- HD(j)->cp_stat[i] = FREE;
- SCpnt = spp->SCpnt;
-
- if (SCpnt == NULL)
- panic("%s: ihdlr, mbox %d, SCpnt == NULL.\n", BN(j), i);
-
- if (SCpnt->host_scribble == NULL)
- panic("%s: ihdlr, mbox %d, pid %ld, SCpnt %p garbled.\n",
- BN(j), i, SCpnt->pid, SCpnt);
-
- if (*(unsigned int *)SCpnt->host_scribble != i)
- panic("%s: ihdlr, mbox %d, pid %ld, index mismatch %d,"\
- " irq %d.\n", BN(j), i, SCpnt->pid,
- *(unsigned int *)SCpnt->host_scribble, irq);
-
- tstatus = status_byte(spp->target_status);
-
- switch (spp->adapter_status) {
- case ASOK: /* status OK */
-
- /* Forces a reset if a disk drive keeps returning BUSY */
- if (tstatus == BUSY && SCpnt->device->type != TYPE_TAPE)
- status = DID_ERROR << 16;
-
- /* If there was a bus reset, redo operation on each target */
- else if (tstatus != GOOD
- && SCpnt->device->type == TYPE_DISK
- && HD(j)->target_reset[SCpnt->target])
- status = DID_BUS_BUSY << 16;
-
- /* Works around a flaw in scsi.c */
- else if (tstatus == CHECK_CONDITION
- && SCpnt->device->type == TYPE_DISK
- && (SCpnt->sense_buffer[2] & 0xf) == RECOVERED_ERROR)
- status = DID_BUS_BUSY << 16;
-
- else
- status = DID_OK << 16;
-
- if (tstatus == GOOD)
- HD(j)->target_reset[SCpnt->target] = FALSE;
-
- if (spp->target_status && SCpnt->device->type == TYPE_DISK)
- printk("%s: ihdlr, target %d:%d, pid %ld, target_status "\
- "0x%x, sense key 0x%x.\n", BN(j),
- SCpnt->target, SCpnt->lun, SCpnt->pid,
- spp->target_status, SCpnt->sense_buffer[2]);
-
- HD(j)->target_time_out[SCpnt->target] = 0;
-
- break;
- case ASST: /* Selection Time Out */
-
- if (HD(j)->target_time_out[SCpnt->target] > 1)
- status = DID_ERROR << 16;
- else {
- status = DID_TIME_OUT << 16;
- HD(j)->target_time_out[SCpnt->target]++;
- }
-
- break;
- case 0x92: /* Data over/under-run */
- case 0x93: /* Unexpected bus free */
- case 0x94: /* Target bus phase sequence failure */
- case 0x96: /* Illegal SCSI command */
- case 0xa3: /* SCSI bus reset error */
-
- if (SCpnt->device->type != TYPE_TAPE)
- status = DID_BUS_BUSY << 16;
- else
- status = DID_ERROR << 16;
-
- for (k = 0; k < MAX_TARGET; k++)
- HD(j)->target_reset[k] = TRUE;
-
- break;
- case 0x01: /* Invalid command */
- case 0x02: /* Invalid parameters */
- case 0x03: /* Invalid data list */
- case 0x84: /* SCSI bus abort error */
- case 0x9b: /* Auto request sense error */
- case 0x9f: /* Unexpected command complete message error */
- case 0xff: /* Invalid parameter in the S/G list */
- default:
- status = DID_ERROR << 16;
- break;
- }
-
- SCpnt->result = status | spp->target_status;
- HD(j)->iocount++;
-
- if (loops > 1) HD(j)->multicount++;
-
-#if defined (DEBUG_INTERRUPT)
- if (SCpnt->result || do_trace)
-#else
- if ((spp->adapter_status != ASOK && HD(j)->iocount > 1000) ||
- (spp->adapter_status != ASOK &&
- spp->adapter_status != ASST && HD(j)->iocount <= 1000) ||
- do_trace)
-#endif
- printk("%s: ihdlr, mbox %d, err 0x%x:%x,"\
- " target %d:%d, pid %ld, count %d.\n",
- BN(j), i, spp->adapter_status, spp->target_status,
- SCpnt->target, SCpnt->lun, SCpnt->pid, HD(j)->iocount);
-
- /* Set the command state to inactive */
- SCpnt->host_scribble = NULL;
-
- restore_flags(flags);
- SCpnt->scsi_done(SCpnt);
- cli();
-
- } /* Multiple command loop */
-
- } /* Boards loop */
-
- calls[irq]++;
-
- if (total_loops == 0)
- printk("%s: ihdlr, irq %d, no command completed, calls %d.\n",
- driver_name, irq, calls[irq]);
-
- if (do_trace) printk("%s: ihdlr, exit, irq %d, calls %d.\n",
- driver_name, irq, calls[irq]);
-
-#if defined (DEBUG_STATISTICS)
- if ((calls[irq] % 100000) == 10000)
- for (j = 0; sh[j] != NULL; j++)
- printk("%s: ihdlr, calls %d, count %d, multi %d.\n", BN(j),
- calls[(sh[j]->irq)], HD(j)->iocount, HD(j)->multicount);
-#endif
-
- restore_flags(flags);
- return;
-}
-
-#if defined(MODULE)
-Scsi_Host_Template driver_template = ULTRASTOR_14_34F;
-
-#include "scsi_module.c"
-#endif
diff --git a/i386/i386at/gpl/linux/scsi/u14-34f.h b/i386/i386at/gpl/linux/scsi/u14-34f.h
deleted file mode 100644
index 2988824e..00000000
--- a/i386/i386at/gpl/linux/scsi/u14-34f.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * u14-34f.h - used by the low-level driver for UltraStor 14F/34F
- */
-#ifndef _U14_34F_H
-#define _U14_34F_H
-
-int u14_34f_detect(Scsi_Host_Template *);
-int u14_34f_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-int u14_34f_abort(Scsi_Cmnd *);
-int u14_34f_reset(Scsi_Cmnd *);
-int u14_34f_biosparam(Disk *, kdev_t, int *);
-
-#define U14_34F_VERSION "2.01.00"
-
-#define ULTRASTOR_14_34F { \
- NULL, /* Ptr for modules */ \
- NULL, /* usage count for modules */ \
- NULL, \
- NULL, \
- "UltraStor 14F/34F rev. " U14_34F_VERSION " ", \
- u14_34f_detect, \
- NULL, /* Release */ \
- NULL, \
- NULL, \
- u14_34f_queuecommand, \
- u14_34f_abort, \
- u14_34f_reset, \
- NULL, \
- u14_34f_biosparam, \
- 0, /* can_queue, reset by detect */ \
- 7, /* this_id, reset by detect */ \
- 0, /* sg_tablesize, reset by detect */ \
- 0, /* cmd_per_lun, reset by detect */ \
- 0, /* number of boards present */ \
- 1, /* unchecked isa dma, reset by detect */ \
- ENABLE_CLUSTERING \
- }
-#endif
diff --git a/i386/i386at/gpl/linux/scsi/ultrastor.c b/i386/i386at/gpl/linux/scsi/ultrastor.c
deleted file mode 100644
index 23e94a91..00000000
--- a/i386/i386at/gpl/linux/scsi/ultrastor.c
+++ /dev/null
@@ -1,1160 +0,0 @@
-/*
- * ultrastor.c Copyright (C) 1992 David B. Gentzel
- * Low-level SCSI driver for UltraStor 14F, 24F, and 34F
- * by David B. Gentzel, Whitfield Software Services, Carnegie, PA
- * (gentzel@nova.enet.dec.com)
- * scatter/gather added by Scott Taylor (n217cg@tamuts.tamu.edu)
- * 24F and multiple command support by John F. Carr (jfc@athena.mit.edu)
- * John's work modified by Caleb Epstein (cae@jpmorgan.com) and
- * Eric Youngdale (ericy@cais.com).
- * Thanks to UltraStor for providing the necessary documentation
- */
-
-/*
- * TODO:
- * 1. Find out why scatter/gather is limited to 16 requests per command.
- * This is fixed, at least on the 24F, as of version 1.12 - CAE.
- * 2. Look at command linking (mscp.command_link and
- * mscp.command_link_id). (Does not work with many disks,
- * and no performance increase. ERY).
- * 3. Allow multiple adapters.
- */
-
-/*
- * NOTES:
- * The UltraStor 14F, 24F, and 34F are a family of intelligent, high
- * performance SCSI-2 host adapters. They all support command queueing
- * and scatter/gather I/O. Some of them can also emulate the standard
- * WD1003 interface for use with OS's which don't support SCSI. Here
- * is the scoop on the various models:
- * 14F - ISA first-party DMA HA with floppy support and WD1003 emulation.
- * 14N - ISA HA with floppy support. I think that this is a non-DMA
- * HA. Nothing further known.
- * 24F - EISA Bus Master HA with floppy support and WD1003 emulation.
- * 34F - VL-Bus Bus Master HA with floppy support (no WD1003 emulation).
- *
- * The 14F, 24F, and 34F are supported by this driver.
- *
- * Places flagged with a triple question-mark are things which are either
- * unfinished, questionable, or wrong.
- */
-
-/* Changes from version 1.11 alpha to 1.12
- *
- * Increased the size of the scatter-gather list to 33 entries for
- * the 24F adapter (it was 16). I don't have the specs for the 14F
- * or the 34F, so they may support larger s-g lists as well.
- *
- * Caleb Epstein <cae@jpmorgan.com>
- */
-
-/* Changes from version 1.9 to 1.11
- *
- * Patches to bring this driver up to speed with the default kernel
- * driver which supports only the 14F and 34F adapters. This version
- * should compile cleanly into 0.99.13, 0.99.12 and probably 0.99.11.
- *
- * Fixes from Eric Youngdale to fix a few possible race conditions and
- * several problems with bit testing operations (insufficient
- * parentheses).
- *
- * Removed the ultrastor_abort() and ultrastor_reset() functions
- * (enclosed them in #if 0 / #endif). These functions, at least on
- * the 24F, cause the SCSI bus to do odd things and generally lead to
- * kernel panics and machine hangs. This is like the Adaptec code.
- *
- * Use check/snarf_region for 14f, 34f to avoid I/O space address conflicts.
- */
-
-/* Changes from version 1.8 to version 1.9
- *
- * 0.99.11 patches (cae@jpmorgan.com) */
-
-/* Changes from version 1.7 to version 1.8
- *
- * Better error reporting.
- */
-
-/* Changes from version 1.6 to version 1.7
- *
- * Removed CSIR command code.
- *
- * Better race condition avoidance (xchgb function added).
- *
- * Set ICM and OGM status to zero at probe (24F)
- *
- * reset sends soft reset to UltraStor adapter
- *
- * reset adapter if adapter interrupts with an invalid MSCP address
- *
- * handle aborted command interrupt (24F)
- *
- */
-
-/* Changes from version 1.5 to version 1.6:
- *
- * Read MSCP address from ICM _before_ clearing the interrupt flag.
- * This fixes a race condition.
- */
-
-/* Changes from version 1.4 to version 1.5:
- *
- * Abort now calls done when multiple commands are enabled.
- *
- * Clear busy when aborted command finishes, not when abort is called.
- *
- * More debugging messages for aborts.
- */
-
-/* Changes from version 1.3 to version 1.4:
- *
- * Enable automatic request of sense data on error (requires newer version
- * of scsi.c to be useful).
- *
- * Fix PORT_OVERRIDE for 14F.
- *
- * Fix abort and reset to work properly (config.aborted wasn't cleared
- * after it was tested, so after a command abort no further commands would
- * work).
- *
- * Boot time test to enable SCSI bus reset (defaults to not allowing reset).
- *
- * Fix test for OGM busy -- the busy bit is in different places on the 24F.
- *
- * Release ICM slot by clearing first byte on 24F.
- */
-
-#ifdef MODULE
-#include <linux/module.h>
-#endif
-
-#include <linux/stddef.h>
-#include <linux/string.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/ioport.h>
-#include <linux/proc_fs.h>
-#include <asm/io.h>
-#include <asm/bitops.h>
-#include <asm/system.h>
-#include <asm/dma.h>
-
-#define ULTRASTOR_PRIVATE /* Get the private stuff from ultrastor.h */
-#include <linux/blk.h>
-#include "scsi.h"
-#include "hosts.h"
-#include "ultrastor.h"
-#include "sd.h"
-#include<linux/stat.h>
-
-struct proc_dir_entry proc_scsi_ultrastor = {
- PROC_SCSI_ULTRASTOR, 9, "ultrastor",
- S_IFDIR | S_IRUGO | S_IXUGO, 2
-};
-
-#define FALSE 0
-#define TRUE 1
-
-#ifndef ULTRASTOR_DEBUG
-#define ULTRASTOR_DEBUG (UD_ABORT|UD_CSIR|UD_RESET)
-#endif
-
-#define VERSION "1.12"
-
-#define ARRAY_SIZE(arr) (sizeof (arr) / sizeof (arr)[0])
-
-#define PACKED __attribute__((packed))
-#define ALIGNED(x) __attribute__((aligned(x)))
-
-
-/* The 14F uses an array of 4-byte ints for its scatter/gather list.
- The data can be unaligned, but need not be. It's easier to give
- the list normal alignment since it doesn't need to fit into a
- packed structure. */
-
-typedef struct {
- unsigned int address;
- unsigned int num_bytes;
-} ultrastor_sg_list;
-
-
-/* MailBox SCSI Command Packet. Basic command structure for communicating
- with controller. */
-struct mscp {
- unsigned char opcode: 3; /* type of command */
- unsigned char xdir: 2; /* data transfer direction */
- unsigned char dcn: 1; /* disable disconnect */
- unsigned char ca: 1; /* use cache (if available) */
- unsigned char sg: 1; /* scatter/gather operation */
- unsigned char target_id: 3; /* target SCSI id */
- unsigned char ch_no: 2; /* SCSI channel (always 0 for 14f) */
- unsigned char lun: 3; /* logical unit number */
- unsigned int transfer_data PACKED; /* transfer data pointer */
- unsigned int transfer_data_length PACKED; /* length in bytes */
- unsigned int command_link PACKED; /* for linking command chains */
- unsigned char scsi_command_link_id; /* identifies command in chain */
- unsigned char number_of_sg_list; /* (if sg is set) 8 bytes per list */
- unsigned char length_of_sense_byte;
- unsigned char length_of_scsi_cdbs; /* 6, 10, or 12 */
- unsigned char scsi_cdbs[12]; /* SCSI commands */
- unsigned char adapter_status; /* non-zero indicates HA error */
- unsigned char target_status; /* non-zero indicates target error */
- unsigned int sense_data PACKED;
- /* The following fields are for software only. They are included in
- the MSCP structure because they are associated with SCSI requests. */
- void (*done)(Scsi_Cmnd *);
- Scsi_Cmnd *SCint;
- ultrastor_sg_list sglist[ULTRASTOR_24F_MAX_SG]; /* use larger size for 24F */
-};
-
-
-/* Port addresses (relative to the base address) */
-#define U14F_PRODUCT_ID(port) ((port) + 0x4)
-#define CONFIG(port) ((port) + 0x6)
-
-/* Port addresses relative to the doorbell base address. */
-#define LCL_DOORBELL_MASK(port) ((port) + 0x0)
-#define LCL_DOORBELL_INTR(port) ((port) + 0x1)
-#define SYS_DOORBELL_MASK(port) ((port) + 0x2)
-#define SYS_DOORBELL_INTR(port) ((port) + 0x3)
-
-
-/* Used to store configuration info read from config i/o registers. Most of
- this is not used yet, but might as well save it.
-
- This structure also holds port addresses that are not at the same offset
- on the 14F and 24F.
-
- This structure holds all data that must be duplicated to support multiple
- adapters. */
-
-static struct ultrastor_config
-{
- unsigned short port_address; /* base address of card */
- unsigned short doorbell_address; /* base address of doorbell CSRs */
- unsigned short ogm_address; /* base address of OGM */
- unsigned short icm_address; /* base address of ICM */
- const void *bios_segment;
- unsigned char interrupt: 4;
- unsigned char dma_channel: 3;
- unsigned char bios_drive_number: 1;
- unsigned char heads;
- unsigned char sectors;
- unsigned char ha_scsi_id: 3;
- unsigned char subversion: 4;
- unsigned char revision;
- /* The slot number is used to distinguish the 24F (slot != 0) from
- the 14F and 34F (slot == 0). */
- unsigned char slot;
-
-#ifdef PRINT_U24F_VERSION
- volatile int csir_done;
-#endif
-
- /* A pool of MSCP structures for this adapter, and a bitmask of
- busy structures. (If ULTRASTOR_14F_MAX_CMDS == 1, a 1 byte
- busy flag is used instead.) */
-
-#if ULTRASTOR_MAX_CMDS == 1
- unsigned char mscp_busy;
-#else
- unsigned short mscp_free;
-#endif
- volatile unsigned char aborted[ULTRASTOR_MAX_CMDS];
- struct mscp mscp[ULTRASTOR_MAX_CMDS];
-} config = {0};
-
-/* Set this to 1 to reset the SCSI bus on error. */
-int ultrastor_bus_reset = 0;
-
-
-/* Allowed BIOS base addresses (NULL indicates reserved) */
-static const void *const bios_segment_table[8] = {
- NULL, (void *)0xC4000, (void *)0xC8000, (void *)0xCC000,
- (void *)0xD0000, (void *)0xD4000, (void *)0xD8000, (void *)0xDC000,
-};
-
-/* Allowed IRQs for 14f */
-static const unsigned char interrupt_table_14f[4] = { 15, 14, 11, 10 };
-
-/* Allowed DMA channels for 14f (0 indicates reserved) */
-static const unsigned char dma_channel_table_14f[4] = { 5, 6, 7, 0 };
-
-/* Head/sector mappings allowed by 14f */
-static const struct {
- unsigned char heads;
- unsigned char sectors;
-} mapping_table[4] = { { 16, 63 }, { 64, 32 }, { 64, 63 }, { 64, 32 } };
-
-#ifndef PORT_OVERRIDE
-/* ??? A probe of address 0x310 screws up NE2000 cards */
-static const unsigned short ultrastor_ports_14f[] = {
- 0x330, 0x340, /*0x310,*/ 0x230, 0x240, 0x210, 0x130, 0x140,
-};
-#endif
-
-static void ultrastor_interrupt(int, struct pt_regs *);
-static inline void build_sg_list(struct mscp *, Scsi_Cmnd *SCpnt);
-
-
-static inline int find_and_clear_bit_16(unsigned short *field)
-{
- int rv;
- unsigned long flags;
-
- save_flags(flags);
- cli();
- if (*field == 0) panic("No free mscp");
- asm("xorl %0,%0\n0:\tbsfw %1,%w0\n\tbtr %0,%1\n\tjnc 0b"
- : "=&r" (rv), "=m" (*field) : "1" (*field));
- restore_flags(flags);
- return rv;
-}
-
-/* This has been re-implemented with the help of Richard Earnshaw,
- <rwe@pegasus.esprit.ec.org> and works with gcc-2.5.8 and gcc-2.6.0.
- The instability noted by jfc below appears to be a bug in
- gcc-2.5.x when compiling w/o optimization. --Caleb
-
- This asm is fragile: it doesn't work without the casts and it may
- not work without optimization. Maybe I should add a swap builtin
- to gcc. --jfc */
-static inline unsigned char xchgb(unsigned char reg,
- volatile unsigned char *mem)
-{
- __asm__ ("xchgb %0,%1" : "=q" (reg), "=m" (*mem) : "0" (reg));
- return reg;
-}
-
-#if ULTRASTOR_DEBUG & (UD_COMMAND | UD_ABORT)
-
-static void log_ultrastor_abort(register struct ultrastor_config *config,
- int command)
-{
- static char fmt[80] = "abort %d (%x); MSCP free pool: %x;";
- register int i;
- int flags;
- save_flags(flags);
- cli();
-
- for (i = 0; i < ULTRASTOR_MAX_CMDS; i++)
- {
- fmt[20 + i*2] = ' ';
- if (! (config->mscp_free & (1 << i)))
- fmt[21 + i*2] = '0' + config->mscp[i].target_id;
- else
- fmt[21 + i*2] = '-';
- }
- fmt[20 + ULTRASTOR_MAX_CMDS * 2] = '\n';
- fmt[21 + ULTRASTOR_MAX_CMDS * 2] = 0;
- printk(fmt, command, &config->mscp[command], config->mscp_free);
- restore_flags(flags);
-}
-#endif
-
-static int ultrastor_14f_detect(Scsi_Host_Template * tpnt)
-{
- size_t i;
- unsigned char in_byte, version_byte = 0;
- struct config_1 {
- unsigned char bios_segment: 3;
- unsigned char removable_disks_as_fixed: 1;
- unsigned char interrupt: 2;
- unsigned char dma_channel: 2;
- } config_1;
- struct config_2 {
- unsigned char ha_scsi_id: 3;
- unsigned char mapping_mode: 2;
- unsigned char bios_drive_number: 1;
- unsigned char tfr_port: 2;
- } config_2;
-
-#if (ULTRASTOR_DEBUG & UD_DETECT)
- printk("US14F: detect: called\n");
-#endif
-
- /* If a 24F has already been configured, don't look for a 14F. */
- if (config.bios_segment)
- return FALSE;
-
-#ifdef PORT_OVERRIDE
- if(check_region(PORT_OVERRIDE, 0xc)) {
- printk("Ultrastor I/O space already in use\n");
- return FALSE;
- };
- config.port_address = PORT_OVERRIDE;
-#else
- for (i = 0; i < ARRAY_SIZE(ultrastor_ports_14f); i++) {
- if(check_region(ultrastor_ports_14f[i], 0x0c)) continue;
- config.port_address = ultrastor_ports_14f[i];
-#endif
-
-#if (ULTRASTOR_DEBUG & UD_DETECT)
- printk("US14F: detect: testing port address %03X\n", config.port_address);
-#endif
-
- in_byte = inb(U14F_PRODUCT_ID(config.port_address));
- if (in_byte != US14F_PRODUCT_ID_0) {
-#if (ULTRASTOR_DEBUG & UD_DETECT)
-# ifdef PORT_OVERRIDE
- printk("US14F: detect: wrong product ID 0 - %02X\n", in_byte);
-# else
- printk("US14F: detect: no adapter at port %03X\n", config.port_address);
-# endif
-#endif
-#ifdef PORT_OVERRIDE
- return FALSE;
-#else
- continue;
-#endif
- }
- in_byte = inb(U14F_PRODUCT_ID(config.port_address) + 1);
- /* Only upper nibble is significant for Product ID 1 */
- if ((in_byte & 0xF0) != US14F_PRODUCT_ID_1) {
-#if (ULTRASTOR_DEBUG & UD_DETECT)
-# ifdef PORT_OVERRIDE
- printk("US14F: detect: wrong product ID 1 - %02X\n", in_byte);
-# else
- printk("US14F: detect: no adapter at port %03X\n", config.port_address);
-# endif
-#endif
-#ifdef PORT_OVERRIDE
- return FALSE;
-#else
- continue;
-#endif
- }
- version_byte = in_byte;
-#ifndef PORT_OVERRIDE
- break;
- }
- if (i == ARRAY_SIZE(ultrastor_ports_14f)) {
-# if (ULTRASTOR_DEBUG & UD_DETECT)
- printk("US14F: detect: no port address found!\n");
-# endif
- return FALSE;
- }
-#endif
-
-#if (ULTRASTOR_DEBUG & UD_DETECT)
- printk("US14F: detect: adapter found at port address %03X\n",
- config.port_address);
-#endif
-
- /* Set local doorbell mask to disallow bus reset unless
- ultrastor_bus_reset is true. */
- outb(ultrastor_bus_reset ? 0xc2 : 0x82, LCL_DOORBELL_MASK(config.port_address));
-
- /* All above tests passed, must be the right thing. Get some useful
- info. */
-
- request_region(config.port_address, 0x0c,"ultrastor");
- /* Register the I/O space that we use */
-
- *(char *)&config_1 = inb(CONFIG(config.port_address + 0));
- *(char *)&config_2 = inb(CONFIG(config.port_address + 1));
- config.bios_segment = bios_segment_table[config_1.bios_segment];
- config.doorbell_address = config.port_address;
- config.ogm_address = config.port_address + 0x8;
- config.icm_address = config.port_address + 0xC;
- config.interrupt = interrupt_table_14f[config_1.interrupt];
- config.ha_scsi_id = config_2.ha_scsi_id;
- config.heads = mapping_table[config_2.mapping_mode].heads;
- config.sectors = mapping_table[config_2.mapping_mode].sectors;
- config.bios_drive_number = config_2.bios_drive_number;
- config.subversion = (version_byte & 0x0F);
- if (config.subversion == U34F)
- config.dma_channel = 0;
- else
- config.dma_channel = dma_channel_table_14f[config_1.dma_channel];
-
- if (!config.bios_segment) {
-#if (ULTRASTOR_DEBUG & UD_DETECT)
- printk("US14F: detect: not detected.\n");
-#endif
- return FALSE;
- }
-
- /* Final consistency check, verify previous info. */
- if (config.subversion != U34F)
- if (!config.dma_channel || !(config_2.tfr_port & 0x2)) {
-#if (ULTRASTOR_DEBUG & UD_DETECT)
- printk("US14F: detect: consistency check failed\n");
-#endif
- return FALSE;
- }
-
- /* If we were TRULY paranoid, we could issue a host adapter inquiry
- command here and verify the data returned. But frankly, I'm
- exhausted! */
-
- /* Finally! Now I'm satisfied... */
-#if (ULTRASTOR_DEBUG & UD_DETECT)
- printk("US14F: detect: detect succeeded\n"
- " Port address: %03X\n"
- " BIOS segment: %05X\n"
- " Interrupt: %u\n"
- " DMA channel: %u\n"
- " H/A SCSI ID: %u\n"
- " Subversion: %u\n",
- config.port_address, config.bios_segment, config.interrupt,
- config.dma_channel, config.ha_scsi_id, config.subversion);
-#endif
- tpnt->this_id = config.ha_scsi_id;
- tpnt->unchecked_isa_dma = (config.subversion != U34F);
-
-#if ULTRASTOR_MAX_CMDS > 1
- config.mscp_free = ~0;
-#endif
-
- if (request_irq(config.interrupt, ultrastor_interrupt, 0, "Ultrastor")) {
- printk("Unable to allocate IRQ%u for UltraStor controller.\n",
- config.interrupt);
- return FALSE;
- }
- if (config.dma_channel && request_dma(config.dma_channel,"Ultrastor")) {
- printk("Unable to allocate DMA channel %u for UltraStor controller.\n",
- config.dma_channel);
- free_irq(config.interrupt);
- return FALSE;
- }
- tpnt->sg_tablesize = ULTRASTOR_14F_MAX_SG;
- printk("UltraStor driver version" VERSION ". Using %d SG lists.\n",
- ULTRASTOR_14F_MAX_SG);
-
- return TRUE;
-}
-
-static int ultrastor_24f_detect(Scsi_Host_Template * tpnt)
-{
- register int i;
- struct Scsi_Host * shpnt = NULL;
-
-#if (ULTRASTOR_DEBUG & UD_DETECT)
- printk("US24F: detect");
-#endif
-
- /* probe each EISA slot at slot address C80 */
- for (i = 1; i < 15; i++)
- {
- unsigned char config_1, config_2;
- unsigned short addr = (i << 12) | ULTRASTOR_24F_PORT;
-
- if (inb(addr) != US24F_PRODUCT_ID_0 &&
- inb(addr+1) != US24F_PRODUCT_ID_1 &&
- inb(addr+2) != US24F_PRODUCT_ID_2)
- continue;
-
- config.revision = inb(addr+3);
- config.slot = i;
- if (! (inb(addr+4) & 1))
- {
-#if (ULTRASTOR_DEBUG & UD_DETECT)
- printk("U24F: found disabled card in slot %u\n", i);
-#endif
- continue;
- }
-#if (ULTRASTOR_DEBUG & UD_DETECT)
- printk("U24F: found card in slot %u\n", i);
-#endif
- config_1 = inb(addr + 5);
- config.bios_segment = bios_segment_table[config_1 & 7];
- switch(config_1 >> 4)
- {
- case 1:
- config.interrupt = 15;
- break;
- case 2:
- config.interrupt = 14;
- break;
- case 4:
- config.interrupt = 11;
- break;
- case 8:
- config.interrupt = 10;
- break;
- default:
- printk("U24F: invalid IRQ\n");
- return FALSE;
- }
- if (request_irq(config.interrupt, ultrastor_interrupt, 0, "Ultrastor"))
- {
- printk("Unable to allocate IRQ%u for UltraStor controller.\n",
- config.interrupt);
- return FALSE;
- }
- /* BIOS addr set */
- /* base port set */
- config.port_address = addr;
- config.doorbell_address = addr + 12;
- config.ogm_address = addr + 0x17;
- config.icm_address = addr + 0x1C;
- config_2 = inb(addr + 7);
- config.ha_scsi_id = config_2 & 7;
- config.heads = mapping_table[(config_2 >> 3) & 3].heads;
- config.sectors = mapping_table[(config_2 >> 3) & 3].sectors;
-#if (ULTRASTOR_DEBUG & UD_DETECT)
- printk("US24F: detect: detect succeeded\n"
- " Port address: %03X\n"
- " BIOS segment: %05X\n"
- " Interrupt: %u\n"
- " H/A SCSI ID: %u\n",
- config.port_address, config.bios_segment,
- config.interrupt, config.ha_scsi_id);
-#endif
- tpnt->this_id = config.ha_scsi_id;
- tpnt->unchecked_isa_dma = 0;
- tpnt->sg_tablesize = ULTRASTOR_24F_MAX_SG;
-
- shpnt = scsi_register(tpnt, 0);
- shpnt->irq = config.interrupt;
- shpnt->dma_channel = config.dma_channel;
- shpnt->io_port = config.port_address;
-
-#if ULTRASTOR_MAX_CMDS > 1
- config.mscp_free = ~0;
-#endif
- /* Mark ICM and OGM free */
- outb(0, addr + 0x16);
- outb(0, addr + 0x1B);
-
- /* Set local doorbell mask to disallow bus reset unless
- ultrastor_bus_reset is true. */
- outb(ultrastor_bus_reset ? 0xc2 : 0x82, LCL_DOORBELL_MASK(addr+12));
- outb(0x02, SYS_DOORBELL_MASK(addr+12));
- printk("UltraStor driver version " VERSION ". Using %d SG lists.\n",
- tpnt->sg_tablesize);
- return TRUE;
- }
- return FALSE;
-}
-
-int ultrastor_detect(Scsi_Host_Template * tpnt)
-{
- tpnt->proc_dir = &proc_scsi_ultrastor;
- return ultrastor_14f_detect(tpnt) || ultrastor_24f_detect(tpnt);
-}
-
-const char *ultrastor_info(struct Scsi_Host * shpnt)
-{
- static char buf[64];
-
- if (config.slot)
- sprintf(buf, "UltraStor 24F SCSI @ Slot %u IRQ%u\n",
- config.slot, config.interrupt);
- else if (config.subversion)
- sprintf(buf, "UltraStor 34F SCSI @ Port %03X BIOS %05X IRQ%u\n",
- config.port_address, (int)config.bios_segment,
- config.interrupt);
- else
- sprintf(buf, "UltraStor 14F SCSI @ Port %03X BIOS %05X IRQ%u DMA%u\n",
- config.port_address, (int)config.bios_segment,
- config.interrupt, config.dma_channel);
- return buf;
-}
-
-static inline void build_sg_list(register struct mscp *mscp, Scsi_Cmnd *SCpnt)
-{
- struct scatterlist *sl;
- long transfer_length = 0;
- int i, max;
-
- sl = (struct scatterlist *) SCpnt->request_buffer;
- max = SCpnt->use_sg;
- for (i = 0; i < max; i++) {
- mscp->sglist[i].address = (unsigned int)sl[i].address;
- mscp->sglist[i].num_bytes = sl[i].length;
- transfer_length += sl[i].length;
- }
- mscp->number_of_sg_list = max;
- mscp->transfer_data = (unsigned int)mscp->sglist;
- /* ??? May not be necessary. Docs are unclear as to whether transfer
- length field is ignored or whether it should be set to the total
- number of bytes of the transfer. */
- mscp->transfer_data_length = transfer_length;
-}
-
-int ultrastor_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
-{
- register struct mscp *my_mscp;
-#if ULTRASTOR_MAX_CMDS > 1
- int mscp_index;
-#endif
- unsigned int status;
- int flags;
-
- /* Next test is for debugging; "can't happen" */
- if ((config.mscp_free & ((1U << ULTRASTOR_MAX_CMDS) - 1)) == 0)
- panic("ultrastor_queuecommand: no free MSCP\n");
- mscp_index = find_and_clear_bit_16(&config.mscp_free);
-
- /* Has the command been aborted? */
- if (xchgb(0xff, &config.aborted[mscp_index]) != 0)
- {
- status = DID_ABORT << 16;
- goto aborted;
- }
-
- my_mscp = &config.mscp[mscp_index];
-
-#if 1
- /* This way is faster. */
- *(unsigned char *)my_mscp = OP_SCSI | (DTD_SCSI << 3);
-#else
- my_mscp->opcode = OP_SCSI;
- my_mscp->xdir = DTD_SCSI;
- my_mscp->dcn = FALSE;
-#endif
- /* Tape drives don't work properly if the cache is used. The SCSI
- READ command for a tape doesn't have a block offset, and the adapter
- incorrectly assumes that all reads from the tape read the same
- blocks. Results will depend on read buffer size and other disk
- activity.
-
- ??? Which other device types should never use the cache? */
- my_mscp->ca = SCpnt->device->type != TYPE_TAPE;
- my_mscp->target_id = SCpnt->target;
- my_mscp->ch_no = 0;
- my_mscp->lun = SCpnt->lun;
- if (SCpnt->use_sg) {
- /* Set scatter/gather flag in SCSI command packet */
- my_mscp->sg = TRUE;
- build_sg_list(my_mscp, SCpnt);
- } else {
- /* Unset scatter/gather flag in SCSI command packet */
- my_mscp->sg = FALSE;
- my_mscp->transfer_data = (unsigned int)SCpnt->request_buffer;
- my_mscp->transfer_data_length = SCpnt->request_bufflen;
- }
- my_mscp->command_link = 0; /*???*/
- my_mscp->scsi_command_link_id = 0; /*???*/
- my_mscp->length_of_sense_byte = sizeof SCpnt->sense_buffer;
- my_mscp->length_of_scsi_cdbs = SCpnt->cmd_len;
- memcpy(my_mscp->scsi_cdbs, SCpnt->cmnd, my_mscp->length_of_scsi_cdbs);
- my_mscp->adapter_status = 0;
- my_mscp->target_status = 0;
- my_mscp->sense_data = (unsigned int)&SCpnt->sense_buffer;
- my_mscp->done = done;
- my_mscp->SCint = SCpnt;
- SCpnt->host_scribble = (unsigned char *)my_mscp;
-
- /* Find free OGM slot. On 24F, look for OGM status byte == 0.
- On 14F and 34F, wait for local interrupt pending flag to clear. */
-
- retry:
- if (config.slot)
- while (inb(config.ogm_address - 1) != 0 &&
- config.aborted[mscp_index] == 0xff) barrier();
-
- /* else??? */
-
- while ((inb(LCL_DOORBELL_INTR(config.doorbell_address)) &
- (config.slot ? 2 : 1))
- && config.aborted[mscp_index] == 0xff) barrier();
-
- /* To avoid race conditions, make the code to write to the adapter
- atomic. This simplifies the abort code. */
-
- save_flags(flags);
- cli();
-
- if (inb(LCL_DOORBELL_INTR(config.doorbell_address)) &
- (config.slot ? 2 : 1))
- {
- restore_flags(flags);
- goto retry;
- }
-
- status = xchgb(0, &config.aborted[mscp_index]);
- if (status != 0xff) {
- restore_flags(flags);
-
-#if ULTRASTOR_DEBUG & (UD_COMMAND | UD_ABORT)
- printk("USx4F: queuecommand: aborted\n");
-#if ULTRASTOR_MAX_CMDS > 1
- log_ultrastor_abort(&config, mscp_index);
-#endif
-#endif
- status <<= 16;
-
- aborted:
- set_bit(mscp_index, &config.mscp_free);
- /* If the driver queues commands, call the done proc here. Otherwise
- return an error. */
-#if ULTRASTOR_MAX_CMDS > 1
- SCpnt->result = status;
- done(SCpnt);
- return 0;
-#else
- return status;
-#endif
- }
-
- /* Store pointer in OGM address bytes */
- outl((unsigned int)my_mscp, config.ogm_address);
-
- /* Issue OGM interrupt */
- if (config.slot) {
- /* Write OGM command register on 24F */
- outb(1, config.ogm_address - 1);
- outb(0x2, LCL_DOORBELL_INTR(config.doorbell_address));
- } else {
- outb(0x1, LCL_DOORBELL_INTR(config.doorbell_address));
- }
-
- restore_flags(flags);
-
-#if (ULTRASTOR_DEBUG & UD_COMMAND)
- printk("USx4F: queuecommand: returning\n");
-#endif
-
- return 0;
-}
-
-/* This code must deal with 2 cases:
-
- 1. The command has not been written to the OGM. In this case, set
- the abort flag and return.
-
- 2. The command has been written to the OGM and is stuck somewhere in
- the adapter.
-
- 2a. On a 24F, ask the adapter to abort the command. It will interrupt
- when it does.
-
- 2b. Call the command's done procedure.
-
- */
-
-int ultrastor_abort(Scsi_Cmnd *SCpnt)
-{
-#if ULTRASTOR_DEBUG & UD_ABORT
- char out[108];
- unsigned char icm_status = 0, ogm_status = 0;
- unsigned int icm_addr = 0, ogm_addr = 0;
-#endif
- unsigned int mscp_index;
- unsigned char old_aborted;
- void (*done)(Scsi_Cmnd *);
-
- if(config.slot)
- return SCSI_ABORT_SNOOZE; /* Do not attempt an abort for the 24f */
-
- /* Simple consistency checking */
- if(!SCpnt->host_scribble)
- return SCSI_ABORT_NOT_RUNNING;
-
- mscp_index = ((struct mscp *)SCpnt->host_scribble) - config.mscp;
- if (mscp_index >= ULTRASTOR_MAX_CMDS)
- panic("Ux4F aborting invalid MSCP");
-
-#if ULTRASTOR_DEBUG & UD_ABORT
- if (config.slot)
- {
- int port0 = (config.slot << 12) | 0xc80;
- int i;
- int flags;
- save_flags(flags);
- cli();
- strcpy(out, "OGM %d:%x ICM %d:%x ports: ");
- for (i = 0; i < 16; i++)
- {
- unsigned char p = inb(port0 + i);
- out[28 + i * 3] = "0123456789abcdef"[p >> 4];
- out[29 + i * 3] = "0123456789abcdef"[p & 15];
- out[30 + i * 3] = ' ';
- }
- out[28 + i * 3] = '\n';
- out[29 + i * 3] = 0;
- ogm_status = inb(port0 + 22);
- ogm_addr = inl(port0 + 23);
- icm_status = inb(port0 + 27);
- icm_addr = inl(port0 + 28);
- restore_flags(flags);
- }
-
- /* First check to see if an interrupt is pending. I suspect the SiS
- chipset loses interrupts. (I also suspect is mangles data, but
- one bug at a time... */
- if (config.slot ? inb(config.icm_address - 1) == 2 :
- (inb(SYS_DOORBELL_INTR(config.doorbell_address)) & 1))
- {
- int flags;
- save_flags(flags);
- printk("Ux4F: abort while completed command pending\n");
- restore_flags(flags);
- cli();
- ultrastor_interrupt(0, NULL);
- restore_flags(flags);
- return SCSI_ABORT_SUCCESS; /* FIXME - is this correct? -ERY */
- }
-#endif
-
- old_aborted = xchgb(DID_ABORT, &config.aborted[mscp_index]);
-
- /* aborted == 0xff is the signal that queuecommand has not yet sent
- the command. It will notice the new abort flag and fail. */
- if (old_aborted == 0xff)
- return SCSI_ABORT_SUCCESS;
-
- /* On 24F, send an abort MSCP request. The adapter will interrupt
- and the interrupt handler will call done. */
- if (config.slot && inb(config.ogm_address - 1) == 0)
- {
- int flags;
-
- save_flags(flags);
- cli();
- outl((int)&config.mscp[mscp_index], config.ogm_address);
- inb(0xc80); /* delay */
- outb(0x80, config.ogm_address - 1);
- outb(0x2, LCL_DOORBELL_INTR(config.doorbell_address));
-#if ULTRASTOR_DEBUG & UD_ABORT
- log_ultrastor_abort(&config, mscp_index);
- printk(out, ogm_status, ogm_addr, icm_status, icm_addr);
-#endif
- restore_flags(flags);
- return SCSI_ABORT_PENDING;
- }
-
-#if ULTRASTOR_DEBUG & UD_ABORT
- log_ultrastor_abort(&config, mscp_index);
-#endif
-
- /* Can't request a graceful abort. Either this is not a 24F or
- the OGM is busy. Don't free the command -- the adapter might
- still be using it. Setting SCint = 0 causes the interrupt
- handler to ignore the command. */
-
- /* FIXME - devices that implement soft resets will still be running
- the command after a bus reset. We would probably rather leave
- the command in the queue. The upper level code will automatically
- leave the command in the active state instead of requeueing it. ERY */
-
-#if ULTRASTOR_DEBUG & UD_ABORT
- if (config.mscp[mscp_index].SCint != SCpnt)
- printk("abort: command mismatch, %p != %p\n",
- config.mscp[mscp_index].SCint, SCpnt);
-#endif
- if (config.mscp[mscp_index].SCint == 0)
- return SCSI_ABORT_NOT_RUNNING;
-
- if (config.mscp[mscp_index].SCint != SCpnt) panic("Bad abort");
- config.mscp[mscp_index].SCint = 0;
- done = config.mscp[mscp_index].done;
- config.mscp[mscp_index].done = 0;
- SCpnt->result = DID_ABORT << 16;
- /* I worry about reentrancy in scsi.c */
- done(SCpnt);
-
- /* Need to set a timeout here in case command never completes. */
- return SCSI_ABORT_SUCCESS;
-}
-
-int ultrastor_reset(Scsi_Cmnd * SCpnt)
-{
- int flags;
- register int i;
-#if (ULTRASTOR_DEBUG & UD_RESET)
- printk("US14F: reset: called\n");
-#endif
-
- if(config.slot)
- return SCSI_RESET_PUNT; /* Do not attempt a reset for the 24f */
-
- save_flags(flags);
- cli();
-
- /* Reset the adapter and SCSI bus. The SCSI bus reset can be
- inhibited by clearing ultrastor_bus_reset before probe. */
- outb(0xc0, LCL_DOORBELL_INTR(config.doorbell_address));
- if (config.slot)
- {
- outb(0, config.ogm_address - 1);
- outb(0, config.icm_address - 1);
- }
-
-#if ULTRASTOR_MAX_CMDS == 1
- if (config.mscp_busy && config.mscp->done && config.mscp->SCint)
- {
- config.mscp->SCint->result = DID_RESET << 16;
- config.mscp->done(config.mscp->SCint);
- }
- config.mscp->SCint = 0;
-#else
- for (i = 0; i < ULTRASTOR_MAX_CMDS; i++)
- {
- if (! (config.mscp_free & (1 << i)) &&
- config.mscp[i].done && config.mscp[i].SCint)
- {
- config.mscp[i].SCint->result = DID_RESET << 16;
- config.mscp[i].done(config.mscp[i].SCint);
- config.mscp[i].done = 0;
- }
- config.mscp[i].SCint = 0;
- }
-#endif
-
- /* FIXME - if the device implements soft resets, then the command
- will still be running. ERY */
-
- memset((unsigned char *)config.aborted, 0, sizeof config.aborted);
-#if ULTRASTOR_MAX_CMDS == 1
- config.mscp_busy = 0;
-#else
- config.mscp_free = ~0;
-#endif
-
- restore_flags(flags);
- return SCSI_RESET_SUCCESS;
-
-}
-
-int ultrastor_biosparam(Disk * disk, kdev_t dev, int * dkinfo)
-{
- int size = disk->capacity;
- unsigned int s = config.heads * config.sectors;
-
- dkinfo[0] = config.heads;
- dkinfo[1] = config.sectors;
- dkinfo[2] = size / s; /* Ignore partial cylinders */
-#if 0
- if (dkinfo[2] > 1024)
- dkinfo[2] = 1024;
-#endif
- return 0;
-}
-
-static void ultrastor_interrupt(int irq, struct pt_regs *regs)
-{
- unsigned int status;
-#if ULTRASTOR_MAX_CMDS > 1
- unsigned int mscp_index;
-#endif
- register struct mscp *mscp;
- void (*done)(Scsi_Cmnd *);
- Scsi_Cmnd *SCtmp;
-
-#if ULTRASTOR_MAX_CMDS == 1
- mscp = &config.mscp[0];
-#else
- mscp = (struct mscp *)inl(config.icm_address);
- mscp_index = mscp - config.mscp;
- if (mscp_index >= ULTRASTOR_MAX_CMDS) {
- printk("Ux4F interrupt: bad MSCP address %x\n", (unsigned int) mscp);
- /* A command has been lost. Reset and report an error
- for all commands. */
- ultrastor_reset(NULL);
- return;
- }
-#endif
-
- /* Clean ICM slot (set ICMINT bit to 0) */
- if (config.slot) {
- unsigned char icm_status = inb(config.icm_address - 1);
-#if ULTRASTOR_DEBUG & (UD_INTERRUPT|UD_ERROR|UD_ABORT)
- if (icm_status != 1 && icm_status != 2)
- printk("US24F: ICM status %x for MSCP %d (%x)\n", icm_status,
- mscp_index, (unsigned int) mscp);
-#endif
- /* The manual says clear interrupt then write 0 to ICM status.
- This seems backwards, but I'll do it anyway. --jfc */
- outb(2, SYS_DOORBELL_INTR(config.doorbell_address));
- outb(0, config.icm_address - 1);
- if (icm_status == 4) {
- printk("UltraStor abort command failed\n");
- return;
- }
- if (icm_status == 3) {
- void (*done)(Scsi_Cmnd *) = mscp->done;
- if (done) {
- mscp->done = 0;
- mscp->SCint->result = DID_ABORT << 16;
- done(mscp->SCint);
- }
- return;
- }
- } else {
- outb(1, SYS_DOORBELL_INTR(config.doorbell_address));
- }
-
- SCtmp = mscp->SCint;
- mscp->SCint = NULL;
-
- if (SCtmp == 0)
- {
-#if ULTRASTOR_DEBUG & (UD_ABORT|UD_INTERRUPT)
- printk("MSCP %d (%x): no command\n", mscp_index, (unsigned int) mscp);
-#endif
-#if ULTRASTOR_MAX_CMDS == 1
- config.mscp_busy = FALSE;
-#else
- set_bit(mscp_index, &config.mscp_free);
-#endif
- config.aborted[mscp_index] = 0;
- return;
- }
-
- /* Save done locally and zero before calling. This is needed as
- once we call done, we may get another command queued before this
- interrupt service routine can return. */
- done = mscp->done;
- mscp->done = 0;
-
- /* Let the higher levels know that we're done */
- switch (mscp->adapter_status)
- {
- case 0:
- status = DID_OK << 16;
- break;
- case 0x01: /* invalid command */
- case 0x02: /* invalid parameters */
- case 0x03: /* invalid data list */
- default:
- status = DID_ERROR << 16;
- break;
- case 0x84: /* SCSI bus abort */
- status = DID_ABORT << 16;
- break;
- case 0x91:
- status = DID_TIME_OUT << 16;
- break;
- }
-
- SCtmp->result = status | mscp->target_status;
-
- SCtmp->host_scribble = 0;
-
- /* Free up mscp block for next command */
-#if ULTRASTOR_MAX_CMDS == 1
- config.mscp_busy = FALSE;
-#else
- set_bit(mscp_index, &config.mscp_free);
-#endif
-
-#if ULTRASTOR_DEBUG & (UD_ABORT|UD_INTERRUPT)
- if (config.aborted[mscp_index])
- printk("Ux4 interrupt: MSCP %d (%x) aborted = %d\n",
- mscp_index, (unsigned int) mscp, config.aborted[mscp_index]);
-#endif
- config.aborted[mscp_index] = 0;
-
- if (done)
- done(SCtmp);
- else
- printk("US14F: interrupt: unexpected interrupt\n");
-
- if (config.slot ? inb(config.icm_address - 1) : (inb(SYS_DOORBELL_INTR(config.doorbell_address)) & 1))
- printk("Ux4F: multiple commands completed\n");
-
-#if (ULTRASTOR_DEBUG & UD_INTERRUPT)
- printk("USx4F: interrupt: returning\n");
-#endif
-}
-
-#ifdef MODULE
-/* Eventually this will go into an include file, but this will be later */
-Scsi_Host_Template driver_template = ULTRASTOR_14F;
-
-#include "scsi_module.c"
-#endif
diff --git a/i386/i386at/gpl/linux/scsi/ultrastor.h b/i386/i386at/gpl/linux/scsi/ultrastor.h
deleted file mode 100644
index 10cf63f2..00000000
--- a/i386/i386at/gpl/linux/scsi/ultrastor.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * ultrastor.c (C) 1991 David B. Gentzel
- * Low-level scsi driver for UltraStor 14F
- * by David B. Gentzel, Whitfield Software Services, Carnegie, PA
- * (gentzel@nova.enet.dec.com)
- * scatter/gather added by Scott Taylor (n217cg@tamuts.tamu.edu)
- * 24F support by John F. Carr (jfc@athena.mit.edu)
- * John's work modified by Caleb Epstein (cae@jpmorgan.com) and
- * Eric Youngdale (eric@tantalus.nrl.navy.mil).
- * Thanks to UltraStor for providing the necessary documentation
- */
-
-#ifndef _ULTRASTOR_H
-#define _ULTRASTOR_H
-#include <linux/kdev_t.h>
-
-int ultrastor_detect(Scsi_Host_Template *);
-const char *ultrastor_info(struct Scsi_Host * shpnt);
-int ultrastor_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-int ultrastor_abort(Scsi_Cmnd *);
-int ultrastor_reset(Scsi_Cmnd *);
-int ultrastor_biosparam(Disk *, kdev_t, int *);
-
-
-#define ULTRASTOR_14F_MAX_SG 16
-#define ULTRASTOR_24F_MAX_SG 33
-
-#define ULTRASTOR_MAX_CMDS_PER_LUN 5
-#define ULTRASTOR_MAX_CMDS 16
-
-#define ULTRASTOR_24F_PORT 0xC80
-
-
-#define ULTRASTOR_14F { NULL, NULL, /* Ptr for modules*/ \
- NULL, \
- NULL, \
- "UltraStor 14F/24F/34F", \
- ultrastor_detect, \
- NULL, /* Release */ \
- ultrastor_info, \
- 0, \
- ultrastor_queuecommand, \
- ultrastor_abort, \
- ultrastor_reset, \
- 0, \
- ultrastor_biosparam, \
- ULTRASTOR_MAX_CMDS, \
- 0, \
- ULTRASTOR_14F_MAX_SG, \
- ULTRASTOR_MAX_CMDS_PER_LUN, \
- 0, \
- 1, \
- ENABLE_CLUSTERING }
-
-
-#ifdef ULTRASTOR_PRIVATE
-
-#define UD_ABORT 0x0001
-#define UD_COMMAND 0x0002
-#define UD_DETECT 0x0004
-#define UD_INTERRUPT 0x0008
-#define UD_RESET 0x0010
-#define UD_MULTI_CMD 0x0020
-#define UD_CSIR 0x0040
-#define UD_ERROR 0x0080
-
-/* #define PORT_OVERRIDE 0x330 */
-
-/* Values for the PRODUCT_ID ports for the 14F */
-#define US14F_PRODUCT_ID_0 0x56
-#define US14F_PRODUCT_ID_1 0x40 /* NOTE: Only upper nibble is used */
-
-#define US24F_PRODUCT_ID_0 0x56
-#define US24F_PRODUCT_ID_1 0x63
-#define US24F_PRODUCT_ID_2 0x02
-
-/* Subversion values */
-#define U14F 0
-#define U34F 1
-
-/* MSCP field values */
-
-/* Opcode */
-#define OP_HOST_ADAPTER 0x1
-#define OP_SCSI 0x2
-#define OP_RESET 0x4
-
-/* Date Transfer Direction */
-#define DTD_SCSI 0x0
-#define DTD_IN 0x1
-#define DTD_OUT 0x2
-#define DTD_NONE 0x3
-
-/* Host Adapter command subcodes */
-#define HA_CMD_INQUIRY 0x1
-#define HA_CMD_SELF_DIAG 0x2
-#define HA_CMD_READ_BUFF 0x3
-#define HA_CMD_WRITE_BUFF 0x4
-
-#endif
-
-#endif
diff --git a/i386/i386at/gpl/linux/scsi/wd7000.c b/i386/i386at/gpl/linux/scsi/wd7000.c
deleted file mode 100644
index 61d92b10..00000000
--- a/i386/i386at/gpl/linux/scsi/wd7000.c
+++ /dev/null
@@ -1,1237 +0,0 @@
-/* $Id: wd7000.c,v 1.1.1.1 1997/02/25 21:27:53 thomas Exp $
- * linux/drivers/scsi/wd7000.c
- *
- * Copyright (C) 1992 Thomas Wuensche
- * closely related to the aha1542 driver from Tommy Thorn
- * ( as close as different hardware allows on a lowlevel-driver :-) )
- *
- * Revised (and renamed) by John Boyd <boyd@cis.ohio-state.edu> to
- * accommodate Eric Youngdale's modifications to scsi.c. Nov 1992.
- *
- * Additional changes to support scatter/gather. Dec. 1992. tw/jb
- *
- * No longer tries to reset SCSI bus at boot (it wasn't working anyway).
- * Rewritten to support multiple host adapters.
- * Miscellaneous cleanup.
- * So far, still doesn't do reset or abort correctly, since I have no idea
- * how to do them with this board (8^(. Jan 1994 jb
- *
- * This driver now supports both of the two standard configurations (per
- * the 3.36 Owner's Manual, my latest reference) by the same method as
- * before; namely, by looking for a BIOS signature. Thus, the location of
- * the BIOS signature determines the board configuration. Until I have
- * time to do something more flexible, users should stick to one of the
- * following:
- *
- * Standard configuration for single-adapter systems:
- * - BIOS at CE00h
- * - I/O base address 350h
- * - IRQ level 15
- * - DMA channel 6
- * Standard configuration for a second adapter in a system:
- * - BIOS at C800h
- * - I/O base address 330h
- * - IRQ level 11
- * - DMA channel 5
- *
- * Anyone who can recompile the kernel is welcome to add others as need
- * arises, but unpredictable results may occur if there are conflicts.
- * In any event, if there are multiple adapters in a system, they MUST
- * use different I/O bases, IRQ levels, and DMA channels, since they will be
- * indistinguishable (and in direct conflict) otherwise.
- *
- * As a point of information, the NO_OP command toggles the CMD_RDY bit
- * of the status port, and this fact could be used as a test for the I/O
- * base address (or more generally, board detection). There is an interrupt
- * status port, so IRQ probing could also be done. I suppose the full
- * DMA diagnostic could be used to detect the DMA channel being used. I
- * haven't done any of this, though, because I think there's too much of
- * a chance that such explorations could be destructive, if some other
- * board's resources are used inadvertently. So, call me a wimp, but I
- * don't want to try it. The only kind of exploration I trust is memory
- * exploration, since it's more certain that reading memory won't be
- * destructive.
- *
- * More to my liking would be a LILO boot command line specification, such
- * as is used by the aha152x driver (and possibly others). I'll look into
- * it, as I have time...
- *
- * I get mail occasionally from people who either are using or are
- * considering using a WD7000 with Linux. There is a variety of
- * nomenclature describing WD7000's. To the best of my knowledge, the
- * following is a brief summary (from an old WD doc - I don't work for
- * them or anything like that):
- *
- * WD7000-FASST2: This is a WD7000 board with the real-mode SST ROM BIOS
- * installed. Last I heard, the BIOS was actually done by Columbia
- * Data Products. The BIOS is only used by this driver (and thus
- * by Linux) to identify the board; none of it can be executed under
- * Linux.
- *
- * WD7000-ASC: This is the original adapter board, with or without BIOS.
- * The board uses a WD33C93 or WD33C93A SBIC, which in turn is
- * controlled by an onboard Z80 processor. The board interface
- * visible to the host CPU is defined effectively by the Z80's
- * firmware, and it is this firmware's revision level that is
- * determined and reported by this driver. (The version of the
- * on-board BIOS is of no interest whatsoever.) The host CPU has
- * no access to the SBIC; hence the fact that it is a WD33C93 is
- * also of no interest to this driver.
- *
- * WD7000-AX:
- * WD7000-MX:
- * WD7000-EX: These are newer versions of the WD7000-ASC. The -ASC is
- * largely built from discrete components; these boards use more
- * integration. The -AX is an ISA bus board (like the -ASC),
- * the -MX is an MCA (i.e., PS/2) bus board), and the -EX is an
- * EISA bus board.
- *
- * At the time of my documentation, the -?X boards were "future" products,
- * and were not yet available. However, I vaguely recall that Thomas
- * Wuensche had an -AX, so I believe at least it is supported by this
- * driver. I have no personal knowledge of either -MX or -EX boards.
- *
- * P.S. Just recently, I've discovered (directly from WD and Future
- * Domain) that all but the WD7000-EX have been out of production for
- * two years now. FD has production rights to the 7000-EX, and are
- * producing it under a new name, and with a new BIOS. If anyone has
- * one of the FD boards, it would be nice to come up with a signature
- * for it.
- * J.B. Jan 1994.
- */
-
-#ifdef MODULE
-#include <linux/module.h>
-#endif
-
-#include <stdarg.h>
-#include <linux/kernel.h>
-#include <linux/head.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/sched.h>
-#include <linux/malloc.h>
-#include <asm/system.h>
-#include <asm/dma.h>
-#include <asm/io.h>
-#include <linux/ioport.h>
-#include <linux/proc_fs.h>
-#include <linux/blk.h>
-#include "scsi.h"
-#include "hosts.h"
-#include "sd.h"
-
-#define ANY2SCSI_INLINE /* undef this to use old macros */
-#undef DEBUG
-
-#include "wd7000.h"
-
-#include<linux/stat.h>
-
-struct proc_dir_entry proc_scsi_wd7000 = {
- PROC_SCSI_7000FASST, 6, "wd7000",
- S_IFDIR | S_IRUGO | S_IXUGO, 2
-};
-
-
-/*
- * Mailbox structure sizes.
- * I prefer to keep the number of ICMBs much larger than the number of
- * OGMBs. OGMBs are used very quickly by the driver to start one or
- * more commands, while ICMBs are used by the host adapter per command.
- */
-#define OGMB_CNT 16
-#define ICMB_CNT 32
-
-/*
- * Scb's are shared by all active adapters. So, if they all become busy,
- * callers may be made to wait in alloc_scbs for them to free. That can
- * be avoided by setting MAX_SCBS to NUM_CONFIG * WD7000_Q. If you'd
- * rather conserve memory, use a smaller number (> 0, of course) - things
- * will should still work OK.
- */
-#define MAX_SCBS 32
-
-/*
- * WD7000-specific mailbox structure
- *
- */
-typedef volatile struct mailbox{
- unchar status;
- unchar scbptr[3]; /* SCSI-style - MSB first (big endian) */
-} Mailbox;
-
-/*
- * This structure should contain all per-adapter global data. I.e., any
- * new global per-adapter data should put in here.
- *
- */
-typedef struct adapter {
- struct Scsi_Host *sh; /* Pointer to Scsi_Host structure */
- int iobase; /* This adapter's I/O base address */
- int irq; /* This adapter's IRQ level */
- int dma; /* This adapter's DMA channel */
- struct { /* This adapter's mailboxes */
- Mailbox ogmb[OGMB_CNT]; /* Outgoing mailboxes */
- Mailbox icmb[ICMB_CNT]; /* Incoming mailboxes */
- } mb;
- int next_ogmb; /* to reduce contention at mailboxes */
- unchar control; /* shadows CONTROL port value */
- unchar rev1, rev2; /* filled in by wd7000_revision */
-} Adapter;
-
-/*
- * The following is set up by wd7000_detect, and used thereafter by
- * wd7000_intr_handle to map the irq level to the corresponding Adapter.
- * Note that if SA_INTERRUPT is not used, wd7000_intr_handle must be
- * changed to pick up the IRQ level correctly.
- */
-Adapter *irq2host[16] = {NULL}; /* Possible IRQs are 0-15 */
-
-/*
- * Standard Adapter Configurations - used by wd7000_detect
- */
-typedef struct {
- const void *bios; /* (linear) base address for ROM BIOS */
- int iobase; /* I/O ports base address */
- int irq; /* IRQ level */
- int dma; /* DMA channel */
-} Config;
-
-static const Config configs[] = {
- {(void *) 0xce000, 0x350, 15, 6}, /* defaults for single adapter */
- {(void *) 0xc8000, 0x330, 11, 5}, /* defaults for second adapter */
- {(void *) 0xd8000, 0x350, 15, 6}, /* Arghhh.... who added this ? */
-};
-#define NUM_CONFIGS (sizeof(configs)/sizeof(Config))
-
-/*
- * The following list defines strings to look for in the BIOS that identify
- * it as the WD7000-FASST2 SST BIOS. I suspect that something should be
- * added for the Future Domain version.
- */
-typedef struct signature {
- const void *sig; /* String to look for */
- unsigned ofs; /* offset from BIOS base address */
- unsigned len; /* length of string */
-} Signature;
-
-static const Signature signatures[] = {
- {"SSTBIOS",0x0000d,7} /* "SSTBIOS" @ offset 0x0000d */
-};
-#define NUM_SIGNATURES (sizeof(signatures)/sizeof(Signature))
-
-
-/*
- * I/O Port Offsets and Bit Definitions
- * 4 addresses are used. Those not defined here are reserved.
- */
-#define ASC_STAT 0 /* Status, Read */
-#define ASC_COMMAND 0 /* Command, Write */
-#define ASC_INTR_STAT 1 /* Interrupt Status, Read */
-#define ASC_INTR_ACK 1 /* Acknowledge, Write */
-#define ASC_CONTROL 2 /* Control, Write */
-
-/* ASC Status Port
- */
-#define INT_IM 0x80 /* Interrupt Image Flag */
-#define CMD_RDY 0x40 /* Command Port Ready */
-#define CMD_REJ 0x20 /* Command Port Byte Rejected */
-#define ASC_INIT 0x10 /* ASC Initialized Flag */
-#define ASC_STATMASK 0xf0 /* The lower 4 Bytes are reserved */
-
-/* COMMAND opcodes
- *
- * Unfortunately, I have no idea how to properly use some of these commands,
- * as the OEM manual does not make it clear. I have not been able to use
- * enable/disable unsolicited interrupts or the reset commands with any
- * discernible effect whatsoever. I think they may be related to certain
- * ICB commands, but again, the OEM manual doesn't make that clear.
- */
-#define NO_OP 0 /* NO-OP toggles CMD_RDY bit in ASC_STAT */
-#define INITIALIZATION 1 /* initialization (10 bytes) */
-#define DISABLE_UNS_INTR 2 /* disable unsolicited interrupts */
-#define ENABLE_UNS_INTR 3 /* enable unsolicited interrupts */
-#define INTR_ON_FREE_OGMB 4 /* interrupt on free OGMB */
-#define SOFT_RESET 5 /* SCSI bus soft reset */
-#define HARD_RESET_ACK 6 /* SCSI bus hard reset acknowledge */
-#define START_OGMB 0x80 /* start command in OGMB (n) */
-#define SCAN_OGMBS 0xc0 /* start multiple commands, signature (n) */
- /* where (n) = lower 6 bits */
-/* For INITIALIZATION:
- */
-typedef struct initCmd {
- unchar op; /* command opcode (= 1) */
- unchar ID; /* Adapter's SCSI ID */
- unchar bus_on; /* Bus on time, x 125ns (see below) */
- unchar bus_off; /* Bus off time, "" "" */
- unchar rsvd; /* Reserved */
- unchar mailboxes[3]; /* Address of Mailboxes, MSB first */
- unchar ogmbs; /* Number of outgoing MBs, max 64, 0,1 = 1 */
- unchar icmbs; /* Number of incoming MBs, "" "" */
-} InitCmd;
-
-#define BUS_ON 64 /* x 125ns = 8000ns (BIOS default) */
-#define BUS_OFF 15 /* x 125ns = 1875ns (BIOS default) */
-
-/* Interrupt Status Port - also returns diagnostic codes at ASC reset
- *
- * if msb is zero, the lower bits are diagnostic status
- * Diagnostics:
- * 01 No diagnostic error occurred
- * 02 RAM failure
- * 03 FIFO R/W failed
- * 04 SBIC register read/write failed
- * 05 Initialization D-FF failed
- * 06 Host IRQ D-FF failed
- * 07 ROM checksum error
- * Interrupt status (bitwise):
- * 10NNNNNN outgoing mailbox NNNNNN is free
- * 11NNNNNN incoming mailbox NNNNNN needs service
- */
-#define MB_INTR 0xC0 /* Mailbox Service possible/required */
-#define IMB_INTR 0x40 /* 1 Incoming / 0 Outgoing */
-#define MB_MASK 0x3f /* mask for mailbox number */
-
-/* CONTROL port bits
- */
-#define INT_EN 0x08 /* Interrupt Enable */
-#define DMA_EN 0x04 /* DMA Enable */
-#define SCSI_RES 0x02 /* SCSI Reset */
-#define ASC_RES 0x01 /* ASC Reset */
-
-/*
- Driver data structures:
- - mb and scbs are required for interfacing with the host adapter.
- An SCB has extra fields not visible to the adapter; mb's
- _cannot_ do this, since the adapter assumes they are contiguous in
- memory, 4 bytes each, with ICMBs following OGMBs, and uses this fact
- to access them.
- - An icb is for host-only (non-SCSI) commands. ICBs are 16 bytes each;
- the additional bytes are used only by the driver.
- - For now, a pool of SCBs are kept in global storage by this driver,
- and are allocated and freed as needed.
-
- The 7000-FASST2 marks OGMBs empty as soon as it has _started_ a command,
- not when it has finished. Since the SCB must be around for completion,
- problems arise when SCBs correspond to OGMBs, which may be reallocated
- earlier (or delayed unnecessarily until a command completes).
- Mailboxes are used as transient data structures, simply for
- carrying SCB addresses to/from the 7000-FASST2.
-
- Note also since SCBs are not "permanently" associated with mailboxes,
- there is no need to keep a global list of Scsi_Cmnd pointers indexed
- by OGMB. Again, SCBs reference their Scsi_Cmnds directly, so mailbox
- indices need not be involved.
-*/
-
-/*
- * WD7000-specific scatter/gather element structure
- */
-typedef struct sgb {
- unchar len[3];
- unchar ptr[3]; /* Also SCSI-style - MSB first */
-} Sgb;
-
-typedef struct scb { /* Command Control Block 5.4.1 */
- unchar op; /* Command Control Block Operation Code */
- unchar idlun; /* op=0,2:Target Id, op=1:Initiator Id */
- /* Outbound data transfer, length is checked*/
- /* Inbound data transfer, length is checked */
- /* Logical Unit Number */
- unchar cdb[12]; /* SCSI Command Block */
- volatile unchar status; /* SCSI Return Status */
- volatile unchar vue; /* Vendor Unique Error Code */
- unchar maxlen[3]; /* Maximum Data Transfer Length */
- unchar dataptr[3]; /* SCSI Data Block Pointer */
- unchar linkptr[3]; /* Next Command Link Pointer */
- unchar direc; /* Transfer Direction */
- unchar reserved2[6]; /* SCSI Command Descriptor Block */
- /* end of hardware SCB */
- Scsi_Cmnd *SCpnt; /* Scsi_Cmnd using this SCB */
- Sgb sgb[WD7000_SG]; /* Scatter/gather list for this SCB */
- Adapter *host; /* host adapter */
- struct scb *next; /* for lists of scbs */
-} Scb;
-
-/*
- * This driver is written to allow host-only commands to be executed.
- * These use a 16-byte block called an ICB. The format is extended by the
- * driver to 18 bytes, to support the status returned in the ICMB and
- * an execution phase code.
- *
- * There are other formats besides these; these are the ones I've tried
- * to use. Formats for some of the defined ICB opcodes are not defined
- * (notably, get/set unsolicited interrupt status) in my copy of the OEM
- * manual, and others are ambiguous/hard to follow.
- */
-#define ICB_OP_MASK 0x80 /* distinguishes scbs from icbs */
-#define ICB_OP_OPEN_RBUF 0x80 /* open receive buffer */
-#define ICB_OP_RECV_CMD 0x81 /* receive command from initiator */
-#define ICB_OP_RECV_DATA 0x82 /* receive data from initiator */
-#define ICB_OP_RECV_SDATA 0x83 /* receive data with status from init. */
-#define ICB_OP_SEND_DATA 0x84 /* send data with status to initiator */
-#define ICB_OP_SEND_STAT 0x86 /* send command status to initiator */
- /* 0x87 is reserved */
-#define ICB_OP_READ_INIT 0x88 /* read initialization bytes */
-#define ICB_OP_READ_ID 0x89 /* read adapter's SCSI ID */
-#define ICB_OP_SET_UMASK 0x8A /* set unsolicited interrupt mask */
-#define ICB_OP_GET_UMASK 0x8B /* read unsolicited interrupt mask */
-#define ICB_OP_GET_REVISION 0x8C /* read firmware revision level */
-#define ICB_OP_DIAGNOSTICS 0x8D /* execute diagnostics */
-#define ICB_OP_SET_EPARMS 0x8E /* set execution parameters */
-#define ICB_OP_GET_EPARMS 0x8F /* read execution parameters */
-
-typedef struct icbRecvCmd {
- unchar op;
- unchar IDlun; /* Initiator SCSI ID/lun */
- unchar len[3]; /* command buffer length */
- unchar ptr[3]; /* command buffer address */
- unchar rsvd[7]; /* reserved */
- volatile unchar vue; /* vendor-unique error code */
- volatile unchar status; /* returned (icmb) status */
- volatile unchar phase; /* used by interrupt handler */
-} IcbRecvCmd;
-
-typedef struct icbSendStat {
- unchar op;
- unchar IDlun; /* Target SCSI ID/lun */
- unchar stat; /* (outgoing) completion status byte 1 */
- unchar rsvd[12]; /* reserved */
- volatile unchar vue; /* vendor-unique error code */
- volatile unchar status; /* returned (icmb) status */
- volatile unchar phase; /* used by interrupt handler */
-} IcbSendStat;
-
-typedef struct icbRevLvl {
- unchar op;
- volatile unchar primary; /* primary revision level (returned) */
- volatile unchar secondary; /* secondary revision level (returned) */
- unchar rsvd[12]; /* reserved */
- volatile unchar vue; /* vendor-unique error code */
- volatile unchar status; /* returned (icmb) status */
- volatile unchar phase; /* used by interrupt handler */
-} IcbRevLvl;
-
-typedef struct icbUnsMask { /* I'm totally guessing here */
- unchar op;
- volatile unchar mask[14]; /* mask bits */
-#ifdef 0
- unchar rsvd[12]; /* reserved */
-#endif
- volatile unchar vue; /* vendor-unique error code */
- volatile unchar status; /* returned (icmb) status */
- volatile unchar phase; /* used by interrupt handler */
-} IcbUnsMask;
-
-typedef struct icbDiag {
- unchar op;
- unchar type; /* diagnostics type code (0-3) */
- unchar len[3]; /* buffer length */
- unchar ptr[3]; /* buffer address */
- unchar rsvd[7]; /* reserved */
- volatile unchar vue; /* vendor-unique error code */
- volatile unchar status; /* returned (icmb) status */
- volatile unchar phase; /* used by interrupt handler */
-} IcbDiag;
-
-#define ICB_DIAG_POWERUP 0 /* Power-up diags only */
-#define ICB_DIAG_WALKING 1 /* walking 1's pattern */
-#define ICB_DIAG_DMA 2 /* DMA - system memory diags */
-#define ICB_DIAG_FULL 3 /* do both 1 & 2 */
-
-typedef struct icbParms {
- unchar op;
- unchar rsvd1; /* reserved */
- unchar len[3]; /* parms buffer length */
- unchar ptr[3]; /* parms buffer address */
- unchar idx[2]; /* index (MSB-LSB) */
- unchar rsvd2[5]; /* reserved */
- volatile unchar vue; /* vendor-unique error code */
- volatile unchar status; /* returned (icmb) status */
- volatile unchar phase; /* used by interrupt handler */
-} IcbParms;
-
-typedef struct icbAny {
- unchar op;
- unchar data[14]; /* format-specific data */
- volatile unchar vue; /* vendor-unique error code */
- volatile unchar status; /* returned (icmb) status */
- volatile unchar phase; /* used by interrupt handler */
-} IcbAny;
-
-typedef union icb {
- unchar op; /* ICB opcode */
- IcbRecvCmd recv_cmd; /* format for receive command */
- IcbSendStat send_stat; /* format for send status */
- IcbRevLvl rev_lvl; /* format for get revision level */
- IcbDiag diag; /* format for execute diagnostics */
- IcbParms eparms; /* format for get/set exec parms */
- IcbAny icb; /* generic format */
- unchar data[18];
-} Icb;
-
-
-/*
- * Driver SCB structure pool.
- *
- * The SCBs declared here are shared by all host adapters; hence, this
- * structure is not part of the Adapter structure.
- */
-static Scb scbs[MAX_SCBS];
-static Scb *scbfree = NULL; /* free list */
-static int freescbs = MAX_SCBS; /* free list counter */
-
-/*
- * END of data/declarations - code follows.
- */
-
-
-#ifdef ANY2SCSI_INLINE
-/*
- Since they're used a lot, I've redone the following from the macros
- formerly in wd7000.h, hopefully to speed them up by getting rid of
- all the shifting (it may not matter; GCC might have done as well anyway).
-
- xany2scsi and xscsi2int were not being used, and are no longer defined.
- (They were simply 4-byte versions of these routines).
-*/
-
-typedef union { /* let's cheat... */
- int i;
- unchar u[sizeof(int)]; /* the sizeof(int) makes it more portable */
-} i_u;
-
-
-static inline void any2scsi( unchar *scsi, int any )
-{
- *scsi++ = ((i_u) any).u[2];
- *scsi++ = ((i_u) any).u[1];
- *scsi++ = ((i_u) any).u[0];
-}
-
-
-static inline int scsi2int( unchar *scsi )
-{
- i_u result;
-
- result.i = 0; /* clears unused bytes */
- *(result.u+2) = *scsi++;
- *(result.u+1) = *scsi++;
- *(result.u) = *scsi++;
- return result.i;
-}
-#else
-/*
- These are the old ones - I've just moved them here...
-*/
-#undef any2scsi
-#define any2scsi(up, p) \
-(up)[0] = (((unsigned long)(p)) >> 16); \
-(up)[1] = ((unsigned long)(p)) >> 8; \
-(up)[2] = ((unsigned long)(p));
-
-#undef scsi2int
-#define scsi2int(up) ( (((unsigned long)*(up)) << 16) + \
- (((unsigned long)(up)[1]) << 8) + ((unsigned long)(up)[2]) )
-#endif
-
-
-static inline void wd7000_enable_intr(Adapter *host)
-{
- host->control |= INT_EN;
- outb(host->control, host->iobase+ASC_CONTROL);
-}
-
-
-static inline void wd7000_enable_dma(Adapter *host)
-{
- host->control |= DMA_EN;
- outb(host->control,host->iobase+ASC_CONTROL);
- set_dma_mode(host->dma, DMA_MODE_CASCADE);
- enable_dma(host->dma);
-}
-
-
-#define WAITnexttimeout 200 /* 2 seconds */
-
-#define WAIT(port, mask, allof, noneof) \
- { register volatile unsigned WAITbits; \
- register unsigned long WAITtimeout = jiffies + WAITnexttimeout; \
- while (1) { \
- WAITbits = inb(port) & (mask); \
- if ((WAITbits & (allof)) == (allof) && ((WAITbits & (noneof)) == 0)) \
- break; \
- if (jiffies > WAITtimeout) goto fail; \
- } \
- }
-
-
-static inline void delay( unsigned how_long )
-{
- register unsigned long time = jiffies + how_long;
-
- while (jiffies < time);
-}
-
-
-static inline int command_out(Adapter *host, unchar *cmd, int len)
-{
- WAIT(host->iobase+ASC_STAT,ASC_STATMASK,CMD_RDY,0);
- while (len--) {
- do {
- outb(*cmd, host->iobase+ASC_COMMAND);
- WAIT(host->iobase+ASC_STAT, ASC_STATMASK, CMD_RDY, 0);
- } while (inb(host->iobase+ASC_STAT) & CMD_REJ);
- cmd++;
- }
- return 1;
-
-fail:
- printk("wd7000 command_out: WAIT failed(%d)\n", len+1);
- return 0;
-}
-
-
-/*
- * This version of alloc_scbs is in preparation for supporting multiple
- * commands per lun and command chaining, by queueing pending commands.
- * We will need to allocate Scbs in blocks since they will wait to be
- * executed so there is the possibility of deadlock otherwise.
- * Also, to keep larger requests from being starved by smaller requests,
- * we limit access to this routine with an internal busy flag, so that
- * the satisfiability of a request is not dependent on the size of the
- * request.
- */
-static inline Scb *alloc_scbs(int needed)
-{
- register Scb *scb, *p;
- register unsigned long flags;
- register unsigned long timeout = jiffies + WAITnexttimeout;
- register unsigned long now;
- static int busy = 0;
- int i;
-
- if (needed <= 0) return NULL; /* sanity check */
-
- save_flags(flags);
- cli();
- while (busy) { /* someone else is allocating */
- sti(); /* Yes this is really needed here */
- now = jiffies; while (jiffies == now) /* wait a jiffy */;
- cli();
- }
- busy = 1; /* not busy now; it's our turn */
-
- while (freescbs < needed) {
- timeout = jiffies + WAITnexttimeout;
- do {
- sti(); /* Yes this is really needed here */
- now = jiffies; while (jiffies == now) /* wait a jiffy */;
- cli();
- } while (freescbs < needed && jiffies <= timeout);
- /*
- * If we get here with enough free Scbs, we can take them.
- * Otherwise, we timed out and didn't get enough.
- */
- if (freescbs < needed) {
- busy = 0;
- panic("wd7000: can't get enough free SCBs.\n");
- restore_flags(flags);
- return NULL;
- }
- }
- scb = scbfree; freescbs -= needed;
- for (i = 0; i < needed; i++) { p = scbfree; scbfree = p->next; }
- p->next = NULL;
-
- busy = 0; /* we're done */
-
- restore_flags(flags);
-
- return scb;
-}
-
-
-static inline void free_scb( Scb *scb )
-{
- register unsigned long flags;
-
- save_flags(flags);
- cli();
-
- memset(scb, 0, sizeof(Scb));
- scb->next = scbfree; scbfree = scb;
- freescbs++;
-
- restore_flags(flags);
-}
-
-
-static inline void init_scbs(void)
-{
- int i;
- unsigned long flags;
-
- save_flags(flags);
- cli();
-
- scbfree = &(scbs[0]);
- memset(scbs, 0, sizeof(scbs));
- for (i = 0; i < MAX_SCBS-1; i++) {
- scbs[i].next = &(scbs[i+1]); scbs[i].SCpnt = NULL;
- }
- scbs[MAX_SCBS-1].next = NULL;
- scbs[MAX_SCBS-1].SCpnt = NULL;
-
- restore_flags(flags);
-}
-
-
-static int mail_out( Adapter *host, Scb *scbptr )
-/*
- * Note: this can also be used for ICBs; just cast to the parm type.
- */
-{
- register int i, ogmb;
- register unsigned long flags;
- unchar start_ogmb;
- Mailbox *ogmbs = host->mb.ogmb;
- int *next_ogmb = &(host->next_ogmb);
-#ifdef DEBUG
- printk("wd7000 mail_out: %06x",(unsigned int) scbptr);
-#endif
- /* We first look for a free outgoing mailbox */
- save_flags(flags);
- cli();
- ogmb = *next_ogmb;
- for (i = 0; i < OGMB_CNT; i++) {
- if (ogmbs[ogmb].status == 0) {
-#ifdef DEBUG
- printk(" using OGMB %x",ogmb);
-#endif
- ogmbs[ogmb].status = 1;
- any2scsi((unchar *) ogmbs[ogmb].scbptr, (int) scbptr);
-
- *next_ogmb = (ogmb+1) % OGMB_CNT;
- break;
- } else
- ogmb = (++ogmb) % OGMB_CNT;
- }
- restore_flags(flags);
-#ifdef DEBUG
- printk(", scb is %x",(unsigned int) scbptr);
-#endif
- if (i >= OGMB_CNT) {
- /*
- * Alternatively, we might issue the "interrupt on free OGMB",
- * and sleep, but it must be ensured that it isn't the init
- * task running. Instead, this version assumes that the caller
- * will be persistent, and try again. Since it's the adapter
- * that marks OGMB's free, waiting even with interrupts off
- * should work, since they are freed very quickly in most cases.
- */
- #ifdef DEBUG
- printk(", no free OGMBs.\n");
-#endif
- return 0;
- }
-
- wd7000_enable_intr(host);
-
- start_ogmb = START_OGMB | ogmb;
- command_out( host, &start_ogmb, 1 );
-#ifdef DEBUG
- printk(", awaiting interrupt.\n");
-#endif
- return 1;
-}
-
-
-int make_code(unsigned hosterr, unsigned scsierr)
-{
-#ifdef DEBUG
- int in_error = hosterr;
-#endif
-
- switch ((hosterr>>8)&0xff){
- case 0: /* Reserved */
- hosterr = DID_ERROR;
- break;
- case 1: /* Command Complete, no errors */
- hosterr = DID_OK;
- break;
- case 2: /* Command complete, error logged in scb status (scsierr) */
- hosterr = DID_OK;
- break;
- case 4: /* Command failed to complete - timeout */
- hosterr = DID_TIME_OUT;
- break;
- case 5: /* Command terminated; Bus reset by external device */
- hosterr = DID_RESET;
- break;
- case 6: /* Unexpected Command Received w/ host as target */
- hosterr = DID_BAD_TARGET;
- break;
- case 80: /* Unexpected Reselection */
- case 81: /* Unexpected Selection */
- hosterr = DID_BAD_INTR;
- break;
- case 82: /* Abort Command Message */
- hosterr = DID_ABORT;
- break;
- case 83: /* SCSI Bus Software Reset */
- case 84: /* SCSI Bus Hardware Reset */
- hosterr = DID_RESET;
- break;
- default: /* Reserved */
- hosterr = DID_ERROR;
- break;
- }
-#ifdef DEBUG
- if (scsierr||hosterr)
- printk("\nSCSI command error: SCSI %02x host %04x return %d",
- scsierr,in_error,hosterr);
-#endif
- return scsierr | (hosterr << 16);
-}
-
-
-static void wd7000_scsi_done(Scsi_Cmnd * SCpnt)
-{
-#ifdef DEBUG
- printk("wd7000_scsi_done: %06x\n",(unsigned int) SCpnt);
-#endif
- SCpnt->SCp.phase = 0;
-}
-
-
-#define wd7000_intr_ack(host) outb(0,host->iobase+ASC_INTR_ACK)
-
-void wd7000_intr_handle(int irq, struct pt_regs * regs)
-{
- register int flag, icmb, errstatus, icmb_status;
- register int host_error, scsi_error;
- register Scb *scb; /* for SCSI commands */
- register IcbAny *icb; /* for host commands */
- register Scsi_Cmnd *SCpnt;
- Adapter *host = irq2host[irq]; /* This MUST be set!!! */
- Mailbox *icmbs = host->mb.icmb;
-
-#ifdef DEBUG
- printk("wd7000_intr_handle: irq = %d, host = %06x\n", irq, host);
-#endif
-
- flag = inb(host->iobase+ASC_INTR_STAT);
-#ifdef DEBUG
- printk("wd7000_intr_handle: intr stat = %02x\n",flag);
-#endif
-
- if (!(inb(host->iobase+ASC_STAT) & INT_IM)) {
- /* NB: these are _very_ possible if IRQ 15 is being used, since
- it's the "garbage collector" on the 2nd 8259 PIC. Specifically,
- any interrupt signal into the 8259 which can't be identified
- comes out as 7 from the 8259, which is 15 to the host. Thus, it
- is a good thing the WD7000 has an interrupt status port, so we
- can sort these out. Otherwise, electrical noise and other such
- problems would be indistinguishable from valid interrupts...
- */
-#ifdef DEBUG
- printk("wd7000_intr_handle: phantom interrupt...\n");
-#endif
- wd7000_intr_ack(host);
- return;
- }
-
- if (flag & MB_INTR) {
- /* The interrupt is for a mailbox */
- if (!(flag & IMB_INTR)) {
-#ifdef DEBUG
- printk("wd7000_intr_handle: free outgoing mailbox");
-#endif
- /*
- * If sleep_on() and the "interrupt on free OGMB" command are
- * used in mail_out(), wake_up() should correspondingly be called
- * here. For now, we don't need to do anything special.
- */
- wd7000_intr_ack(host);
- return;
- } else {
- /* The interrupt is for an incoming mailbox */
- icmb = flag & MB_MASK;
- icmb_status = icmbs[icmb].status;
- if (icmb_status & 0x80) { /* unsolicited - result in ICMB */
-#ifdef DEBUG
- printk("wd7000_intr_handle: unsolicited interrupt %02xh\n",
- icmb_status);
-#endif
- wd7000_intr_ack(host);
- return;
- }
- scb = (struct scb *) scsi2int((unchar *)icmbs[icmb].scbptr);
- icmbs[icmb].status = 0;
- if (!(scb->op & ICB_OP_MASK)) { /* an SCB is done */
- SCpnt = scb->SCpnt;
- if (--(SCpnt->SCp.phase) <= 0) { /* all scbs are done */
- host_error = scb->vue | (icmb_status << 8);
- scsi_error = scb->status;
- errstatus = make_code(host_error,scsi_error);
- SCpnt->result = errstatus;
-
- free_scb(scb);
-
- SCpnt->scsi_done(SCpnt);
- }
- } else { /* an ICB is done */
- icb = (IcbAny *) scb;
- icb->status = icmb_status;
- icb->phase = 0;
- }
- } /* incoming mailbox */
- }
-
- wd7000_intr_ack(host);
- return;
-}
-
-
-int wd7000_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
-{
- register Scb *scb;
- register Sgb *sgb;
- register unchar *cdb = (unchar *) SCpnt->cmnd;
- register unchar idlun;
- register short cdblen;
- Adapter *host = (Adapter *) SCpnt->host->hostdata;
-
- cdblen = SCpnt->cmd_len;
- idlun = ((SCpnt->target << 5) & 0xe0) | (SCpnt->lun & 7);
- SCpnt->scsi_done = done;
- SCpnt->SCp.phase = 1;
- scb = alloc_scbs(1);
- scb->idlun = idlun;
- memcpy(scb->cdb, cdb, cdblen);
- scb->direc = 0x40; /* Disable direction check */
-
- scb->SCpnt = SCpnt; /* so we can find stuff later */
- SCpnt->host_scribble = (unchar *) scb;
- scb->host = host;
-
- if (SCpnt->use_sg) {
- struct scatterlist *sg = (struct scatterlist *) SCpnt->request_buffer;
- unsigned i;
-
- if (SCpnt->host->sg_tablesize == SG_NONE) {
- panic("wd7000_queuecommand: scatter/gather not supported.\n");
- }
-#ifdef DEBUG
- printk("Using scatter/gather with %d elements.\n",SCpnt->use_sg);
-#endif
-
- sgb = scb->sgb;
- scb->op = 1;
- any2scsi(scb->dataptr, (int) sgb);
- any2scsi(scb->maxlen, SCpnt->use_sg * sizeof (Sgb) );
-
- for (i = 0; i < SCpnt->use_sg; i++) {
- any2scsi(sgb[i].ptr, (int) sg[i].address);
- any2scsi(sgb[i].len, sg[i].length);
- }
- } else {
- scb->op = 0;
- any2scsi(scb->dataptr, (int) SCpnt->request_buffer);
- any2scsi(scb->maxlen, SCpnt->request_bufflen);
- }
- while (!mail_out(host, scb)) /* keep trying */;
-
- return 1;
-}
-
-
-int wd7000_command(Scsi_Cmnd *SCpnt)
-{
- wd7000_queuecommand(SCpnt, wd7000_scsi_done);
-
- while (SCpnt->SCp.phase > 0) barrier(); /* phase counts scbs down to 0 */
-
- return SCpnt->result;
-}
-
-
-int wd7000_diagnostics( Adapter *host, int code )
-{
- static IcbDiag icb = {ICB_OP_DIAGNOSTICS};
- static unchar buf[256];
- unsigned long timeout;
-
- icb.type = code;
- any2scsi(icb.len, sizeof(buf));
- any2scsi(icb.ptr, (int) &buf);
- icb.phase = 1;
- /*
- * This routine is only called at init, so there should be OGMBs
- * available. I'm assuming so here. If this is going to
- * fail, I can just let the timeout catch the failure.
- */
- mail_out(host, (struct scb *) &icb);
- timeout = jiffies + WAITnexttimeout; /* wait up to 2 seconds */
- while (icb.phase && jiffies < timeout)
- barrier(); /* wait for completion */
-
- if (icb.phase) {
- printk("wd7000_diagnostics: timed out.\n");
- return 0;
- }
- if (make_code(icb.vue|(icb.status << 8),0)) {
- printk("wd7000_diagnostics: failed (%02x,%02x)\n",
- icb.vue, icb.status);
- return 0;
- }
-
- return 1;
-}
-
-
-int wd7000_init( Adapter *host )
-{
- InitCmd init_cmd = {
- INITIALIZATION, 7, BUS_ON, BUS_OFF, 0, {0,0,0}, OGMB_CNT, ICMB_CNT
- };
- int diag;
-
- /*
- Reset the adapter - only. The SCSI bus was initialized at power-up,
- and we need to do this just so we control the mailboxes, etc.
- */
- outb(ASC_RES, host->iobase+ASC_CONTROL);
- delay(1); /* reset pulse: this is 10ms, only need 25us */
- outb(0,host->iobase+ASC_CONTROL);
- host->control = 0; /* this must always shadow ASC_CONTROL */
- WAIT(host->iobase+ASC_STAT, ASC_STATMASK, CMD_RDY, 0);
-
- if ((diag = inb(host->iobase+ASC_INTR_STAT)) != 1) {
- printk("wd7000_init: ");
- switch (diag) {
- case 2:
- printk("RAM failure.\n");
- break;
- case 3:
- printk("FIFO R/W failed\n");
- break;
- case 4:
- printk("SBIC register R/W failed\n");
- break;
- case 5:
- printk("Initialization D-FF failed.\n");
- break;
- case 6:
- printk("Host IRQ D-FF failed.\n");
- break;
- case 7:
- printk("ROM checksum error.\n");
- break;
- default:
- printk("diagnostic code %02Xh received.\n", diag);
- break;
- }
- return 0;
- }
-
- /* Clear mailboxes */
- memset(&(host->mb), 0, sizeof(host->mb));
-
- /* Execute init command */
- any2scsi((unchar *) &(init_cmd.mailboxes), (int) &(host->mb));
- if (!command_out(host, (unchar *) &init_cmd, sizeof(init_cmd))) {
- printk("wd7000_init: adapter initialization failed.\n");
- return 0;
- }
- WAIT(host->iobase+ASC_STAT, ASC_STATMASK, ASC_INIT, 0);
-
- if (request_irq(host->irq, wd7000_intr_handle, SA_INTERRUPT, "wd7000")) {
- printk("wd7000_init: can't get IRQ %d.\n", host->irq);
- return 0;
- }
- if (request_dma(host->dma,"wd7000")) {
- printk("wd7000_init: can't get DMA channel %d.\n", host->dma);
- free_irq(host->irq);
- return 0;
- }
- wd7000_enable_dma(host);
- wd7000_enable_intr(host);
-
- if (!wd7000_diagnostics(host,ICB_DIAG_FULL)) {
- free_dma(host->dma);
- free_irq(host->irq);
- return 0;
- }
-
- return 1;
-
- fail:
- printk("wd7000_init: WAIT timed out.\n");
- return 0; /* 0 = not ok */
-}
-
-
-void wd7000_revision(Adapter *host)
-{
- static IcbRevLvl icb = {ICB_OP_GET_REVISION};
-
- icb.phase = 1;
- /*
- * Like diagnostics, this is only done at init time, in fact, from
- * wd7000_detect, so there should be OGMBs available. If it fails,
- * the only damage will be that the revision will show up as 0.0,
- * which in turn means that scatter/gather will be disabled.
- */
- mail_out(host, (struct scb *) &icb);
- while (icb.phase)
- barrier(); /* wait for completion */
- host->rev1 = icb.primary;
- host->rev2 = icb.secondary;
-}
-
-
-int wd7000_detect(Scsi_Host_Template * tpnt)
-/*
- * Returns the number of adapters this driver is supporting.
- *
- * The source for hosts.c says to wait to call scsi_register until 100%
- * sure about an adapter. We need to do it a little sooner here; we
- * need the storage set up by scsi_register before wd7000_init, and
- * changing the location of an Adapter structure is more trouble than
- * calling scsi_unregister.
- *
- */
-{
- int i,j, present = 0;
- const Config *cfg;
- const Signature *sig;
- Adapter *host = NULL;
- struct Scsi_Host *sh;
-
- tpnt->proc_dir = &proc_scsi_wd7000;
-
- /* Set up SCB free list, which is shared by all adapters */
- init_scbs();
-
- cfg = configs;
- for (i = 0; i < NUM_CONFIGS; i++) {
- sig = signatures;
- for (j = 0; j < NUM_SIGNATURES; j++) {
- if (!memcmp(cfg->bios+sig->ofs, sig->sig, sig->len)) {
- /* matched this one */
-#ifdef DEBUG
- printk("WD-7000 SST BIOS detected at %04X: checking...\n",
- (int) cfg->bios);
-#endif
- /*
- * We won't explicitly test the configuration (in this
- * version); instead, we'll just see if it works to
- * setup the adapter; if it does, we'll use it.
- */
- if (check_region(cfg->iobase, 4)) { /* ports in use */
- printk("IO %xh already in use.\n", host->iobase);
- continue;
- }
- /*
- * We register here, to get a pointer to the extra space,
- * which we'll use as the Adapter structure (host) for
- * this adapter. It is located just after the registered
- * Scsi_Host structure (sh), and is located by the empty
- * array hostdata.
- */
- sh = scsi_register(tpnt, sizeof(Adapter) );
- host = (Adapter *) sh->hostdata;
-#ifdef DEBUG
- printk("wd7000_detect: adapter allocated at %06x\n",
- (int)host);
-#endif
- memset( host, 0, sizeof(Adapter) );
- host->sh = sh;
- host->irq = cfg->irq;
- host->iobase = cfg->iobase;
- host->dma = cfg->dma;
- irq2host[host->irq] = host;
-
- if (!wd7000_init(host)) { /* Initialization failed */
- scsi_unregister (sh);
- continue;
- }
-
- /*
- * OK from here - we'll use this adapter/configuration.
- */
- wd7000_revision(host); /* important for scatter/gather */
-
- printk("Western Digital WD-7000 (%d.%d) ",
- host->rev1, host->rev2);
- printk("using IO %xh IRQ %d DMA %d.\n",
- host->iobase, host->irq, host->dma);
-
- request_region(host->iobase, 4,"wd7000"); /* Register our ports */
- /*
- * For boards before rev 6.0, scatter/gather isn't supported.
- */
- if (host->rev1 < 6) sh->sg_tablesize = SG_NONE;
-
- present++; /* count it */
- break; /* don't try any more sigs */
- }
- sig++; /* try next signature with this configuration */
- }
- cfg++; /* try next configuration */
- }
-
- return present;
-}
-
-
-/*
- * I have absolutely NO idea how to do an abort with the WD7000...
- */
-int wd7000_abort(Scsi_Cmnd * SCpnt)
-{
- Adapter *host = (Adapter *) SCpnt->host->hostdata;
-
- if (inb(host->iobase+ASC_STAT) & INT_IM) {
- printk("wd7000_abort: lost interrupt\n");
- wd7000_intr_handle(host->irq, NULL);
- return SCSI_ABORT_SUCCESS;
- }
-
- return SCSI_ABORT_SNOOZE;
-}
-
-
-/*
- * I also have no idea how to do a reset...
- */
-int wd7000_reset(Scsi_Cmnd * SCpnt)
-{
- return SCSI_RESET_PUNT;
-}
-
-
-/*
- * This was borrowed directly from aha1542.c, but my disks are organized
- * this way, so I think it will work OK. Someone who is ambitious can
- * borrow a newer or more complete version from another driver.
- */
-int wd7000_biosparam(Disk * disk, kdev_t dev, int* ip)
-{
- int size = disk->capacity;
- ip[0] = 64;
- ip[1] = 32;
- ip[2] = size >> 11;
-/* if (ip[2] >= 1024) ip[2] = 1024; */
- return 0;
-}
-
-#ifdef MODULE
-/* Eventually this will go into an include file, but this will be later */
-Scsi_Host_Template driver_template = WD7000;
-
-#include "scsi_module.c"
-#endif
diff --git a/i386/i386at/gpl/linux/scsi/wd7000.h b/i386/i386at/gpl/linux/scsi/wd7000.h
deleted file mode 100644
index 5a194dbc..00000000
--- a/i386/i386at/gpl/linux/scsi/wd7000.h
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifndef _WD7000_H
-
-/* $Id: wd7000.h,v 1.1.1.1 1997/02/25 21:27:53 thomas Exp $
- *
- * Header file for the WD-7000 driver for Linux
- *
- * John Boyd <boyd@cis.ohio-state.edu> Jan 1994:
- * This file has been reduced to only the definitions needed for the
- * WD7000 host structure.
- *
- */
-
-#include <linux/types.h>
-#include <linux/kdev_t.h>
-
-int wd7000_detect(Scsi_Host_Template *);
-int wd7000_command(Scsi_Cmnd *);
-int wd7000_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-int wd7000_abort(Scsi_Cmnd *);
-int wd7000_reset(Scsi_Cmnd *);
-int wd7000_biosparam(Disk *, kdev_t, int *);
-
-#ifndef NULL
-#define NULL 0L
-#endif
-
-/*
- * In this version, sg_tablesize now defaults to WD7000_SG, and will
- * be set to SG_NONE for older boards. This is the reverse of the
- * previous default, and was changed so that the driver-level
- * Scsi_Host_Template would reflect the driver's support for scatter/
- * gather.
- *
- * Also, it has been reported that boards at Revision 6 support scatter/
- * gather, so the new definition of an "older" board has been changed
- * accordingly.
- */
-#define WD7000_Q 16
-#define WD7000_SG 16
-
-#define WD7000 { NULL, NULL, \
- NULL, \
- NULL, \
- "Western Digital WD-7000", \
- wd7000_detect, \
- NULL, \
- NULL, \
- wd7000_command, \
- wd7000_queuecommand, \
- wd7000_abort, \
- wd7000_reset, \
- NULL, \
- wd7000_biosparam, \
- WD7000_Q, 7, WD7000_SG, 1, 0, 1, ENABLE_CLUSTERING}
-#endif