OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [acorn/] [scsi/] [oak.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
#define AUTOSENSE
2
/*#define PSEUDO_DMA*/
3
 
4
/*
5
 * Oak Generic NCR5380 driver
6
 *
7
 * Copyright 1995, Russell King
8
 *
9
 * ALPHA RELEASE 1.
10
 *
11
 * For more information, please consult
12
 *
13
 * NCR 5380 Family
14
 * SCSI Protocol Controller
15
 * Databook
16
 *
17
 * NCR Microelectronics
18
 * 1635 Aeroplaza Drive
19
 * Colorado Springs, CO 80916
20
 * 1+ (719) 578-3400
21
 * 1+ (800) 334-5454
22
 */
23
 
24
/*
25
 * Options :
26
 *
27
 * PARITY - enable parity checking.  Not supported.
28
 *
29
 * SCSI2 - enable support for SCSI-II tagged queueing.  Untested.
30
 *
31
 * USLEEP - enable support for devices that don't disconnect.  Untested.
32
 */
33
 
34
/*
35
 * $Log: not supported by cvs2svn $
36
 * Revision 1.3  1998/05/03 20:45:37  alan
37
 * ARM SCSI update. This adds the eesox driver and massively updates the
38
 * Cumana driver. The folks who bought cumana arent anal retentive all
39
 * docs are secret weenies so now there are docs ..
40
 *
41
 * Revision 1.2  1998/03/08 05:49:48  davem
42
 * Merge to 2.1.89
43
 *
44
 * Revision 1.1  1998/02/23 02:45:27  davem
45
 * Merge to 2.1.88
46
 *
47
 */
48
 
49
#include <linux/module.h>
50
#include <linux/signal.h>
51
#include <linux/sched.h>
52
#include <linux/ioport.h>
53
#include <linux/blk.h>
54
#include <linux/init.h>
55
 
56
#include <asm/ecard.h>
57
#include <asm/io.h>
58
#include <asm/system.h>
59
 
60
#include "../../scsi/scsi.h"
61
#include "../../scsi/hosts.h"
62
#include "../../scsi/constants.h"
63
 
64
#define OAKSCSI_PUBLIC_RELEASE 1
65
 
66
#define NCR5380_read(reg)               oakscsi_read(_instance, reg)
67
#define NCR5380_write(reg, value)       oakscsi_write(_instance, reg, value)
68
#define do_NCR5380_intr                 do_oakscsi_intr
69
#define NCR5380_queue_command           oakscsi_queue_command
70
#define NCR5380_abort                   oakscsi_abort
71
#define NCR5380_reset                   oakscsi_reset
72
#define NCR5380_proc_info               oakscsi_proc_info
73
 
74
int NCR5380_proc_info(char *buffer, char **start, off_t offset,
75
                      int length, int hostno, int inout);
76
 
77
#define NCR5380_implementation_fields \
78
        int port, ctrl
79
 
80
#define NCR5380_local_declare() \
81
        struct Scsi_Host *_instance
82
 
83
#define NCR5380_setup(instance) \
84
        _instance = instance
85
 
86
#define BOARD_NORMAL    0
87
#define BOARD_NCR53C400 1
88
 
89
#include "../../scsi/NCR5380.h"
90
 
91
#undef START_DMA_INITIATOR_RECEIVE_REG
92
#define START_DMA_INITIATOR_RECEIVE_REG (7 + 128)
93
 
94
static const card_ids oakscsi_cids[] = {
95
        { MANU_OAK, PROD_OAK_SCSI },
96
        { 0xffff, 0xffff }
97
};
98
 
99
#define OAK_ADDRESS(card) (ecard_address((card), ECARD_MEMC, 0))
100
#define OAK_IRQ(card)     (IRQ_NONE)
101
/*
102
 * Function : int oakscsi_detect(Scsi_Host_Template * tpnt)
103
 *
104
 * Purpose : initializes oak NCR5380 driver based on the
105
 *      command line / compile time port and irq definitions.
106
 *
107
 * Inputs : tpnt - template for this SCSI adapter.
108
 *
109
 * Returns : 1 if a host adapter was found, 0 if not.
110
 *
111
 */
112
static struct expansion_card *ecs[4];
113
 
114
int oakscsi_detect(Scsi_Host_Template * tpnt)
115
{
116
    int count = 0;
117
    struct Scsi_Host *instance;
118
 
119
    tpnt->proc_name = "oakscsi";
120
 
121
    memset (ecs, 0, sizeof (ecs));
122
 
123
    ecard_startfind ();
124
 
125
    while(1) {
126
        if ((ecs[count] = ecard_find(0, oakscsi_cids)) == NULL)
127
            break;
128
 
129
        instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
130
        instance->io_port = OAK_ADDRESS(ecs[count]);
131
        instance->irq = OAK_IRQ(ecs[count]);
132
 
133
        NCR5380_init(instance, 0);
134
        ecard_claim(ecs[count]);
135
 
136
        instance->n_io_port = 255;
137
        request_region (instance->io_port, instance->n_io_port, "Oak SCSI");
138
 
139
        if (instance->irq != IRQ_NONE)
140
            if (request_irq(instance->irq, do_oakscsi_intr, SA_INTERRUPT, "Oak SCSI", NULL)) {
141
                printk("scsi%d: IRQ%d not free, interrupts disabled\n",
142
                    instance->host_no, instance->irq);
143
                instance->irq = IRQ_NONE;
144
            }
145
 
146
        if (instance->irq != IRQ_NONE) {
147
            printk("scsi%d: eek! Interrupts enabled, but I don't think\n", instance->host_no);
148
            printk("scsi%d: that the board had an interrupt!\n", instance->host_no);
149
        }
150
 
151
        printk("scsi%d: at port %lX irq", instance->host_no, instance->io_port);
152
        if (instance->irq == IRQ_NONE)
153
            printk ("s disabled");
154
        else
155
            printk (" %d", instance->irq);
156
        printk(" options CAN_QUEUE=%d  CMD_PER_LUN=%d release=%d",
157
            tpnt->can_queue, tpnt->cmd_per_lun, OAKSCSI_PUBLIC_RELEASE);
158
        printk("\nscsi%d:", instance->host_no);
159
        NCR5380_print_options(instance);
160
        printk("\n");
161
 
162
        ++count;
163
    }
164
#ifdef MODULE
165
    if(count == 0)
166
        printk("No oak scsi devices found\n");
167
#endif
168
    return count;
169
}
170
 
171
int oakscsi_release (struct Scsi_Host *shpnt)
172
{
173
        int i;
174
 
175
        if (shpnt->irq != IRQ_NONE)
176
                free_irq (shpnt->irq, NULL);
177
        if (shpnt->io_port)
178
                release_region (shpnt->io_port, shpnt->n_io_port);
179
 
180
        for (i = 0; i < 4; i++)
181
                if (shpnt->io_port == OAK_ADDRESS(ecs[i]))
182
                        ecard_release (ecs[i]);
183
        return 0;
184
}
185
 
186
const char * oakscsi_info (struct Scsi_Host *spnt) {
187
    return "";
188
}
189
 
190
#define STAT(p)   inw(p + 144)
191
extern void inswb(int from, void *to, int len);
192
 
193
static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *addr,
194
              int len)
195
{
196
  int iobase = instance->io_port;
197
printk("writing %p len %d\n",addr, len);
198
  if(!len) return -1;
199
 
200
  while(1)
201
  {
202
    int status;
203
    while(((status = STAT(iobase)) & 0x100)==0);
204
  }
205
}
206
 
207
static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *addr,
208
              int len)
209
{
210
  int iobase = instance->io_port;
211
printk("reading %p len %d\n", addr, len);
212
  while(len > 0)
213
  {
214
    int status, timeout;
215
    unsigned long b;
216
 
217
    timeout = 0x01FFFFFF;
218
 
219
    while(((status = STAT(iobase)) & 0x100)==0)
220
    {
221
      timeout--;
222
      if(status & 0x200 || !timeout)
223
      {
224
        printk("status = %08X\n",status);
225
        return 1;
226
      }
227
    }
228
    if(len >= 128)
229
    {
230
      inswb(iobase + 136, addr, 128);
231
      addr += 128;
232
      len -= 128;
233
    }
234
    else
235
    {
236
      b = (unsigned long) inw(iobase + 136);
237
      *addr ++ = b;
238
      len -= 1;
239
      if(len)
240
        *addr ++ = b>>8;
241
      len -= 1;
242
    }
243
  }
244
  return 0;
245
}
246
 
247
#define oakscsi_read(instance,reg)      (inb((instance)->io_port + (reg)))
248
#define oakscsi_write(instance,reg,val) (outb((val), (instance)->io_port + (reg)))
249
 
250
#undef STAT
251
 
252
#include "../../scsi/NCR5380.c"
253
 
254
static Scsi_Host_Template oakscsi_template = {
255
        module:         THIS_MODULE,
256
        proc_info:      oakscsi_proc_info,
257
        name:           "Oak 16-bit SCSI",
258
        detect:         oakscsi_detect,
259
        release:        oakscsi_release,
260
        info:           oakscsi_info,
261
        queuecommand:   oakscsi_queue_command,
262
        abort:          oakscsi_abort,
263
        reset:          oakscsi_reset,
264
        can_queue:      16,
265
        this_id:        7,
266
        sg_tablesize:   SG_ALL,
267
        cmd_per_lun:    2,
268
        use_clustering: DISABLE_CLUSTERING
269
};
270
 
271
static int __init oakscsi_init(void)
272
{
273
        scsi_register_module(MODULE_SCSI_HA, &oakscsi_template);
274
        if (oakscsi_template.present)
275
                return 0;
276
 
277
        scsi_unregister_module(MODULE_SCSI_HA, &oakscsi_template);
278
        return -ENODEV;
279
}
280
 
281
static void __exit oakscsi_exit(void)
282
{
283
        scsi_unregister_module(MODULE_SCSI_HA, &oakscsi_template);
284
}
285
 
286
module_init(oakscsi_init);
287
module_exit(oakscsi_exit);
288
 
289
MODULE_AUTHOR("Russell King");
290
MODULE_DESCRIPTION("Oak SCSI driver");
291
MODULE_LICENSE("GPL");
292
EXPORT_NO_SYMBOLS;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.