Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
scsi
mvme147.c
Go to the documentation of this file.
1
#include <linux/types.h>
2
#include <
linux/mm.h
>
3
#include <
linux/blkdev.h
>
4
#include <
linux/interrupt.h
>
5
6
#include <asm/page.h>
7
#include <asm/pgtable.h>
8
#include <
asm/mvme147hw.h
>
9
#include <asm/irq.h>
10
11
#include "
scsi.h
"
12
#include <
scsi/scsi_host.h
>
13
#include "
wd33c93.h
"
14
#include "
mvme147.h
"
15
16
#include <linux/stat.h>
17
18
19
static
irqreturn_t
mvme147_intr(
int
irq,
void
*
data
)
20
{
21
struct
Scsi_Host
*instance =
data
;
22
23
if
(irq ==
MVME147_IRQ_SCSI_PORT
)
24
wd33c93_intr
(instance);
25
else
26
m147_pcc
->dma_intr = 0x89;
/* Ack and enable ints */
27
return
IRQ_HANDLED
;
28
}
29
30
static
int
dma_setup(
struct
scsi_cmnd
*
cmd
,
int
dir_in)
31
{
32
struct
Scsi_Host
*instance = cmd->
device
->host;
33
struct
WD33C93_hostdata
*hdata = shost_priv(instance);
34
unsigned
char
flags
= 0x01;
35
unsigned
long
addr
=
virt_to_bus
(cmd->
SCp
.ptr);
36
37
/* setup dma direction */
38
if
(!dir_in)
39
flags |= 0x04;
40
41
/* remember direction */
42
hdata->
dma_dir
= dir_in;
43
44
if
(dir_in) {
45
/* invalidate any cache */
46
cache_clear
(addr, cmd->
SCp
.this_residual);
47
}
else
{
48
/* push any dirty cache */
49
cache_push
(addr, cmd->
SCp
.this_residual);
50
}
51
52
/* start DMA */
53
m147_pcc
->dma_bcr = cmd->
SCp
.this_residual | (1 << 24);
54
m147_pcc
->dma_dadr =
addr
;
55
m147_pcc
->dma_cntrl =
flags
;
56
57
/* return success */
58
return
0;
59
}
60
61
static
void
dma_stop
(
struct
Scsi_Host
*instance,
struct
scsi_cmnd
*SCpnt,
62
int
status
)
63
{
64
m147_pcc
->dma_cntrl = 0;
65
}
66
67
int
mvme147_detect
(
struct
scsi_host_template
*tpnt)
68
{
69
static
unsigned
char
called = 0;
70
struct
Scsi_Host
*instance;
71
wd33c93_regs
regs
;
72
struct
WD33C93_hostdata
*hdata;
73
74
if
(!
MACH_IS_MVME147
|| called)
75
return
0;
76
called++;
77
78
tpnt->
proc_name
=
"MVME147"
;
79
tpnt->
proc_info
= &
wd33c93_proc_info
;
80
81
instance =
scsi_register
(tpnt,
sizeof
(
struct
WD33C93_hostdata
));
82
if
(!instance)
83
goto
err_out;
84
85
instance->
base
= 0xfffe4000;
86
instance->
irq
=
MVME147_IRQ_SCSI_PORT
;
87
regs.
SASR
= (
volatile
unsigned
char
*)0xfffe4000;
88
regs.
SCMD
= (
volatile
unsigned
char
*)0xfffe4001;
89
hdata = shost_priv(instance);
90
hdata->
no_sync
= 0xff;
91
hdata->
fast
= 0;
92
hdata->
dma_mode
=
CTRL_DMA
;
93
wd33c93_init
(instance, regs,
dma_setup
,
dma_stop
,
WD33C93_FS_8_10
);
94
95
if
(
request_irq
(
MVME147_IRQ_SCSI_PORT
, mvme147_intr, 0,
96
"MVME147 SCSI PORT"
, instance))
97
goto
err_unregister;
98
if
(
request_irq
(
MVME147_IRQ_SCSI_DMA
, mvme147_intr, 0,
99
"MVME147 SCSI DMA"
, instance))
100
goto
err_free_irq;
101
#if 0
/* Disabled; causes problems booting */
102
m147_pcc
->scsi_interrupt = 0x10;
/* Assert SCSI bus reset */
103
udelay
(100);
104
m147_pcc
->scsi_interrupt = 0x00;
/* Negate SCSI bus reset */
105
udelay
(2000);
106
m147_pcc
->scsi_interrupt = 0x40;
/* Clear bus reset interrupt */
107
#endif
108
m147_pcc
->scsi_interrupt = 0x09;
/* Enable interrupt */
109
110
m147_pcc
->dma_cntrl = 0x00;
/* ensure DMA is stopped */
111
m147_pcc
->dma_intr = 0x89;
/* Ack and enable ints */
112
113
return
1;
114
115
err_free_irq:
116
free_irq
(
MVME147_IRQ_SCSI_PORT
, mvme147_intr);
117
err_unregister:
118
scsi_unregister
(instance);
119
err_out:
120
return
0;
121
}
122
123
static
int
mvme147_bus_reset(
struct
scsi_cmnd
*cmd)
124
{
125
/* FIXME perform bus-specific reset */
126
127
/* FIXME 2: kill this function, and let midlayer fallback to
128
the same result, calling wd33c93_host_reset() */
129
130
spin_lock_irq(cmd->
device
->host->host_lock);
131
wd33c93_host_reset
(cmd);
132
spin_unlock_irq(cmd->
device
->host->host_lock);
133
134
return
SUCCESS
;
135
}
136
137
138
static
struct
scsi_host_template
driver_template
= {
139
.proc_name =
"MVME147"
,
140
.name =
"MVME147 built-in SCSI"
,
141
.detect =
mvme147_detect
,
142
.release =
mvme147_release
,
143
.queuecommand =
wd33c93_queuecommand
,
144
.eh_abort_handler =
wd33c93_abort
,
145
.eh_bus_reset_handler = mvme147_bus_reset,
146
.eh_host_reset_handler =
wd33c93_host_reset
,
147
.can_queue =
CAN_QUEUE
,
148
.this_id = 7,
149
.sg_tablesize =
SG_ALL
,
150
.cmd_per_lun =
CMD_PER_LUN
,
151
.use_clustering =
ENABLE_CLUSTERING
152
};
153
154
155
#include "
scsi_module.c
"
156
157
int
mvme147_release
(
struct
Scsi_Host
*instance)
158
{
159
#ifdef MODULE
160
/* XXX Make sure DMA is stopped! */
161
free_irq
(
MVME147_IRQ_SCSI_PORT
, mvme147_intr);
162
free_irq
(
MVME147_IRQ_SCSI_DMA
, mvme147_intr);
163
#endif
164
return
1;
165
}
Generated on Thu Jan 10 2013 13:58:29 for Linux Kernel by
1.8.2