linux/drivers/block/paride/bpck6.c
<<
>>
Prefs
   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/*
  15   This is Ken's linux wrapper for the PPC library
  16   Version 1.0.0 is the backpack driver for which source is not available
  17   Version 2.0.0 is the first to have source released 
  18   Version 2.0.1 is the "Cox-ified" source code 
  19   Version 2.0.2 - fixed version string usage, and made ppc functions static 
  20*/
  21
  22
  23#define BACKPACK_VERSION "2.0.2"
  24
  25#include <linux/module.h>
  26#include <linux/init.h>
  27#include <linux/kernel.h>
  28#include <linux/slab.h>
  29#include <linux/types.h>
  30#include <asm/io.h>
  31#include <linux/parport.h>
  32
  33#include "ppc6lnx.c"
  34#include "paride.h"
  35
  36/* PARAMETERS */
  37static bool verbose; /* set this to 1 to see debugging messages and whatnot */
  38 
  39
  40#define PPCSTRUCT(pi) ((Interface *)(pi->private))
  41
  42/****************************************************************/
  43/*
  44 ATAPI CDROM DRIVE REGISTERS
  45*/
  46#define ATAPI_DATA       0      /* data port                  */
  47#define ATAPI_ERROR      1      /* error register (read)      */
  48#define ATAPI_FEATURES   1      /* feature register (write)   */
  49#define ATAPI_INT_REASON 2      /* interrupt reason register  */
  50#define ATAPI_COUNT_LOW  4      /* byte count register (low)  */
  51#define ATAPI_COUNT_HIGH 5      /* byte count register (high) */
  52#define ATAPI_DRIVE_SEL  6      /* drive select register      */
  53#define ATAPI_STATUS     7      /* status port (read)         */
  54#define ATAPI_COMMAND    7      /* command port (write)       */
  55#define ATAPI_ALT_STATUS 0x0e /* alternate status reg (read) */
  56#define ATAPI_DEVICE_CONTROL 0x0e /* device control (write)   */
  57/****************************************************************/
  58
  59static int bpck6_read_regr(PIA *pi, int cont, int reg)
  60{
  61        unsigned int out;
  62
  63        /* check for bad settings */
  64        if (reg<0 || reg>7 || cont<0 || cont>2)
  65        {
  66                return(-1);
  67        }
  68        out=ppc6_rd_port(PPCSTRUCT(pi),cont?reg|8:reg);
  69        return(out);
  70}
  71
  72static void bpck6_write_regr(PIA *pi, int cont, int reg, int val)
  73{
  74        /* check for bad settings */
  75        if (reg>=0 && reg<=7 && cont>=0 && cont<=1)
  76        {
  77                ppc6_wr_port(PPCSTRUCT(pi),cont?reg|8:reg,(u8)val);
  78        }
  79}
  80
  81static void bpck6_write_block( PIA *pi, char * buf, int len )
  82{
  83        ppc6_wr_port16_blk(PPCSTRUCT(pi),ATAPI_DATA,buf,(u32)len>>1); 
  84}
  85
  86static void bpck6_read_block( PIA *pi, char * buf, int len )
  87{
  88        ppc6_rd_port16_blk(PPCSTRUCT(pi),ATAPI_DATA,buf,(u32)len>>1);
  89}
  90
  91static void bpck6_connect ( PIA *pi  )
  92{
  93        if(verbose)
  94        {
  95                printk(KERN_DEBUG "connect\n");
  96        }
  97
  98        if(pi->mode >=2)
  99        {
 100                PPCSTRUCT(pi)->mode=4+pi->mode-2;       
 101        }
 102        else if(pi->mode==1)
 103        {
 104                PPCSTRUCT(pi)->mode=3;  
 105        }
 106        else
 107        {
 108                PPCSTRUCT(pi)->mode=1;          
 109        }
 110
 111        ppc6_open(PPCSTRUCT(pi));  
 112        ppc6_wr_extout(PPCSTRUCT(pi),0x3);
 113}
 114
 115static void bpck6_disconnect ( PIA *pi )
 116{
 117        if(verbose)
 118        {
 119                printk("disconnect\n");
 120        }
 121        ppc6_wr_extout(PPCSTRUCT(pi),0x0);
 122        ppc6_close(PPCSTRUCT(pi));
 123}
 124
 125static int bpck6_test_port ( PIA *pi )   /* check for 8-bit port */
 126{
 127        if(verbose)
 128        {
 129                printk(KERN_DEBUG "PARPORT indicates modes=%x for lp=0x%lx\n",
 130                        ((struct pardevice*)(pi->pardev))->port->modes,
 131                        ((struct pardevice *)(pi->pardev))->port->base); 
 132        }
 133
 134        /*copy over duplicate stuff.. initialize state info*/
 135        PPCSTRUCT(pi)->ppc_id=pi->unit;
 136        PPCSTRUCT(pi)->lpt_addr=pi->port;
 137
 138        /* look at the parport device to see if what modes we can use */
 139        if(((struct pardevice *)(pi->pardev))->port->modes & 
 140                (PARPORT_MODE_EPP)
 141          )
 142        {
 143                return 5; /* Can do EPP*/
 144        }
 145        else if(((struct pardevice *)(pi->pardev))->port->modes & 
 146                        (PARPORT_MODE_TRISTATE)
 147               )
 148        {
 149                return 2;
 150        }
 151        else /*Just flat SPP*/
 152        {
 153                return 1;
 154        }
 155}
 156
 157static int bpck6_probe_unit ( PIA *pi )
 158{
 159        int out;
 160
 161        if(verbose)
 162        {
 163                printk(KERN_DEBUG "PROBE UNIT %x on port:%x\n",pi->unit,pi->port);
 164        }
 165
 166        /*SET PPC UNIT NUMBER*/
 167        PPCSTRUCT(pi)->ppc_id=pi->unit;
 168
 169        /*LOWER DOWN TO UNIDIRECTIONAL*/
 170        PPCSTRUCT(pi)->mode=1;          
 171
 172        out=ppc6_open(PPCSTRUCT(pi));
 173
 174        if(verbose)
 175        {
 176                printk(KERN_DEBUG "ppc_open returned %2x\n",out);
 177        }
 178
 179        if(out)
 180        {
 181                ppc6_close(PPCSTRUCT(pi));
 182                if(verbose)
 183                {
 184                        printk(KERN_DEBUG "leaving probe\n");
 185                }
 186               return(1);
 187        }
 188        else
 189        {
 190                if(verbose)
 191                {
 192                        printk(KERN_DEBUG "Failed open\n");
 193                }
 194                return(0);
 195        }
 196}
 197
 198static void bpck6_log_adapter( PIA *pi, char * scratch, int verbose )
 199{
 200        char *mode_string[5]=
 201                {"4-bit","8-bit","EPP-8","EPP-16","EPP-32"};
 202
 203        printk("%s: BACKPACK Protocol Driver V"BACKPACK_VERSION"\n",pi->device);
 204        printk("%s: Copyright 2001 by Micro Solutions, Inc., DeKalb IL.\n",pi->device);
 205        printk("%s: BACKPACK %s, Micro Solutions BACKPACK Drive at 0x%x\n",
 206                pi->device,BACKPACK_VERSION,pi->port);
 207        printk("%s: Unit: %d Mode:%d (%s) Delay %d\n",pi->device,
 208                pi->unit,pi->mode,mode_string[pi->mode],pi->delay);
 209}
 210
 211static int bpck6_init_proto(PIA *pi)
 212{
 213        Interface *p = kzalloc(sizeof(Interface), GFP_KERNEL);
 214
 215        if (p) {
 216                pi->private = (unsigned long)p;
 217                return 0;
 218        }
 219
 220        printk(KERN_ERR "%s: ERROR COULDN'T ALLOCATE MEMORY\n", pi->device); 
 221        return -1;
 222}
 223
 224static void bpck6_release_proto(PIA *pi)
 225{
 226        kfree((void *)(pi->private)); 
 227}
 228
 229static struct pi_protocol bpck6 = {
 230        .owner          = THIS_MODULE,
 231        .name           = "bpck6",
 232        .max_mode       = 5,
 233        .epp_first      = 2, /* 2-5 use epp (need 8 ports) */
 234        .max_units      = 255,
 235        .write_regr     = bpck6_write_regr,
 236        .read_regr      = bpck6_read_regr,
 237        .write_block    = bpck6_write_block,
 238        .read_block     = bpck6_read_block,
 239        .connect        = bpck6_connect,
 240        .disconnect     = bpck6_disconnect,
 241        .test_port      = bpck6_test_port,
 242        .probe_unit     = bpck6_probe_unit,
 243        .log_adapter    = bpck6_log_adapter,
 244        .init_proto     = bpck6_init_proto,
 245        .release_proto  = bpck6_release_proto,
 246};
 247
 248static int __init bpck6_init(void)
 249{
 250        printk(KERN_INFO "bpck6: BACKPACK Protocol Driver V"BACKPACK_VERSION"\n");
 251        printk(KERN_INFO "bpck6: Copyright 2001 by Micro Solutions, Inc., DeKalb IL. USA\n");
 252        if(verbose)
 253                printk(KERN_DEBUG "bpck6: verbose debug enabled.\n");
 254        return paride_register(&bpck6);
 255}
 256
 257static void __exit bpck6_exit(void)
 258{
 259        paride_unregister(&bpck6);
 260}
 261
 262MODULE_LICENSE("GPL");
 263MODULE_AUTHOR("Micro Solutions Inc.");
 264MODULE_DESCRIPTION("BACKPACK Protocol module, compatible with PARIDE");
 265module_param(verbose, bool, 0644);
 266module_init(bpck6_init)
 267module_exit(bpck6_exit)
 268