1 /* 2 backpack.c (c) 2001 Micro Solutions Inc. 3 Released under the terms of the GNU General Public license 4 5 backpack.c is a low-level protocol driver for the Micro Solutions 6 "BACKPACK" parallel port IDE adapter 7 (Works on Series 6 drives) 8 9 Written by: Ken Hahn (linux-dev@micro-solutions.com) 10 Clive Turvey (linux-dev@micro-solutions.com) 11 12 */ 13 14 #include <linux/module.h> 15 #include <linux/init.h> 16 #include <linux/kernel.h> 17 #include <linux/types.h> 18 #include <linux/parport.h> 19 #include "pata_parport.h" 20 #include "ppc6lnx.c" 21 22 static int bpck6_read_regr(struct pi_adapter *pi, int cont, int reg) 23 { 24 return ppc6_rd_port(pi, cont?reg|8:reg); 25 } 26 27 static void bpck6_write_regr(struct pi_adapter *pi, int cont, int reg, int val) 28 { 29 ppc6_wr_port(pi, cont?reg|8:reg, val); 30 } 31 32 static void bpck6_write_block(struct pi_adapter *pi, char *buf, int len) 33 { 34 ppc6_wr_port16_blk(pi, ATA_REG_DATA, buf, (u32)len>>1); 35 } 36 37 static void bpck6_read_block(struct pi_adapter *pi, char *buf, int len) 38 { 39 ppc6_rd_port16_blk(pi, ATA_REG_DATA, buf, (u32)len>>1); 40 } 41 42 static void bpck6_connect(struct pi_adapter *pi) 43 { 44 dev_dbg(&pi->dev, "connect\n"); 45 46 ppc6_open(pi); 47 ppc6_wr_extout(pi, 0x3); 48 } 49 50 static void bpck6_disconnect(struct pi_adapter *pi) 51 { 52 dev_dbg(&pi->dev, "disconnect\n"); 53 ppc6_wr_extout(pi, 0x0); 54 ppc6_close(pi); 55 } 56 57 static int bpck6_test_port(struct pi_adapter *pi) /* check for 8-bit port */ 58 { 59 dev_dbg(&pi->dev, "PARPORT indicates modes=%x for lp=0x%lx\n", 60 pi->pardev->port->modes, pi->pardev->port->base); 61 62 /* look at the parport device to see what modes we can use */ 63 if (pi->pardev->port->modes & PARPORT_MODE_EPP) 64 return 5; /* Can do EPP */ 65 if (pi->pardev->port->modes & PARPORT_MODE_TRISTATE) 66 return 2; 67 return 1; /* Just flat SPP */ 68 } 69 70 static int bpck6_probe_unit(struct pi_adapter *pi) 71 { 72 int out, saved_mode; 73 74 dev_dbg(&pi->dev, "PROBE UNIT %x on port:%x\n", pi->unit, pi->port); 75 76 saved_mode = pi->mode; 77 /*LOWER DOWN TO UNIDIRECTIONAL*/ 78 pi->mode = 0; 79 80 out = ppc6_open(pi); 81 82 dev_dbg(&pi->dev, "ppc_open returned %2x\n", out); 83 84 if(out) 85 { 86 ppc6_close(pi); 87 dev_dbg(&pi->dev, "leaving probe\n"); 88 pi->mode = saved_mode; 89 return(1); 90 } 91 else 92 { 93 dev_dbg(&pi->dev, "Failed open\n"); 94 pi->mode = saved_mode; 95 return(0); 96 } 97 } 98 99 static void bpck6_log_adapter(struct pi_adapter *pi) 100 { 101 char *mode_string[5]= 102 {"4-bit","8-bit","EPP-8","EPP-16","EPP-32"}; 103 104 dev_info(&pi->dev, "Micro Solutions BACKPACK Drive unit %d at 0x%x, mode:%d (%s), delay %d\n", 105 pi->unit, pi->port, pi->mode, mode_string[pi->mode], pi->delay); 106 } 107 108 static struct pi_protocol bpck6 = { 109 .owner = THIS_MODULE, 110 .name = "bpck6", 111 .max_mode = 5, 112 .epp_first = 2, /* 2-5 use epp (need 8 ports) */ 113 .max_units = 255, 114 .write_regr = bpck6_write_regr, 115 .read_regr = bpck6_read_regr, 116 .write_block = bpck6_write_block, 117 .read_block = bpck6_read_block, 118 .connect = bpck6_connect, 119 .disconnect = bpck6_disconnect, 120 .test_port = bpck6_test_port, 121 .probe_unit = bpck6_probe_unit, 122 .log_adapter = bpck6_log_adapter, 123 }; 124 125 MODULE_LICENSE("GPL"); 126 MODULE_AUTHOR("Micro Solutions Inc."); 127 MODULE_DESCRIPTION("BACKPACK Protocol module, compatible with PARIDE"); 128 module_pata_parport_driver(bpck6); 129