Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
57e34bbb
Commit
57e34bbb
authored
Oct 27, 2002
by
Alan Cox
Committed by
Linus Torvalds
Oct 27, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] nsp_cs update from maintainer
parent
515a6f24
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
722 additions
and
291 deletions
+722
-291
drivers/scsi/pcmcia/nsp_cs.c
drivers/scsi/pcmcia/nsp_cs.c
+556
-259
drivers/scsi/pcmcia/nsp_cs.h
drivers/scsi/pcmcia/nsp_cs.h
+53
-24
drivers/scsi/pcmcia/nsp_debug.c
drivers/scsi/pcmcia/nsp_debug.c
+11
-4
drivers/scsi/pcmcia/nsp_io.h
drivers/scsi/pcmcia/nsp_io.h
+100
-2
drivers/scsi/pcmcia/nsp_message.c
drivers/scsi/pcmcia/nsp_message.c
+2
-2
No files found.
drivers/scsi/pcmcia/nsp_cs.c
View file @
57e34bbb
/*======================================================================
NinjaSCSI-3 / NinjaSCSI-32Bi PCMCIA SCSI hostadapter card driver
NinjaSCSI-3 / NinjaSCSI-32Bi PCMCIA SCSI host
adapter card driver
By: YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>
Ver.2.8 Support 32bit MMIO mode
Support Synchronous Data TRansfer (SDTR) mode
Ver.2.0 Support 32bit PIO mode
Ver.1.1.2 Fix for scatter list buffer exceeds
Ver.1.1 Support scatter list
...
...
@@ -23,7 +25,7 @@
***********************************************************************/
/* $Id: nsp_cs.c,v 1.4
2 2001/09/10 10:30:58
elca Exp $ */
/* $Id: nsp_cs.c,v 1.4
2002/10/15 15:57:01
elca Exp $ */
#ifdef NSP_KERNEL_2_2
#include <pcmcia/config.h>
...
...
@@ -39,7 +41,6 @@
#include <linux/timer.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/tqueue.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/major.h>
...
...
@@ -51,7 +52,6 @@
#include <../drivers/scsi/scsi.h>
#include <../drivers/scsi/hosts.h>
#include <../drivers/scsi/sd.h>
#include <scsi/scsi.h>
#include <scsi/scsi_ioctl.h>
...
...
@@ -60,20 +60,24 @@
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h>
#include <pcmcia/ds.h>
#include <pcmcia/bus_ops.h>
#include "nsp_cs.h"
MODULE_AUTHOR
(
"YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>"
);
MODULE_DESCRIPTION
(
"WorkBit NinjaSCSI-3 / NinjaSCSI-32Bi(16bit) PCMCIA SCSI host adapter module"
);
MODULE_DESCRIPTION
(
"WorkBit NinjaSCSI-3 / NinjaSCSI-32Bi(16bit) PCMCIA SCSI host adapter module
$Revision: 1.4 $
"
);
MODULE_SUPPORTED_DEVICE
(
"sd,sr,sg,st"
);
#ifdef MODULE_LICENSE
MODULE_LICENSE
(
"GPL"
);
#endif
#ifdef PCMCIA_DEBUG
static
int
pc_debug
=
PCMCIA_DEBUG
;
MODULE_PARM
(
pc_debug
,
"i"
);
MODULE_PARM_DESC
(
pc_debug
,
"set debug level"
);
static
char
*
version
=
"$Id: nsp_cs.c,v 1.4
2 2001/09/10 10:30:58
elca Exp $"
;
static
char
*
version
=
"$Id: nsp_cs.c,v 1.4
2002/10/15 15:57:01
elca Exp $"
;
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
#else
#define DEBUG(n, args...)
/* */
...
...
@@ -108,48 +112,56 @@ static struct proc_dir_entry proc_scsi_nsp = {
static
unsigned
int
irq_mask
=
0xffff
;
MODULE_PARM
(
irq_mask
,
"i"
);
MODULE_PARM_DESC
(
irq_mask
,
"IRQ mask bits"
);
MODULE_PARM_DESC
(
irq_mask
,
"IRQ mask bits
(default: 0xffff)
"
);
static
int
irq_list
[
4
]
=
{
-
1
};
MODULE_PARM
(
irq_list
,
"1-4i"
);
MODULE_PARM_DESC
(
irq_list
,
"
IRQ number list
"
);
MODULE_PARM_DESC
(
irq_list
,
"
Use specified IRQ number. (default: auto select)
"
);
/*----------------------------------------------------------------*/
/* driver state info, local to driver */
static
char
nspinfo
[
100
];
/* description */
static
int
nsp_burst_mode
=
2
;
MODULE_PARM
(
nsp_burst_mode
,
"i"
);
MODULE_PARM_DESC
(
nsp_burst_mode
,
"Burst transfer mode (0=io8, 1=io32, 2=mem32(default))"
);
/* Release IO ports after configuration? */
static
int
free_ports
=
0
;
MODULE_PARM
(
free_ports
,
"i"
);
MODULE_PARM_DESC
(
free_ports
,
"Release IO ports after configuration? (default: 0 (=no))"
);
/* /usr/src/linux/drivers/scsi/hosts.h */
static
Scsi_Host_Template
driver_template
=
{
/*
next:
NULL,*/
#if (
KERNEL_VERSION(2,3,99) > LINUX_VERSION_CODE
)
proc_dir:
&
proc_scsi_nsp
,
/* kernel 2.2
*/
/*
.next =
NULL,*/
#if (
LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
)
.
proc_name
=
"nsp_cs"
,
/* kernel 2.4
*/
#else
proc_name:
"nsp_cs"
,
/* kernel 2.4
*/
.
proc_dir
=
&
proc_scsi_nsp
,
/* kernel 2.2
*/
#endif
/* proc_info: NULL,*/
name:
"WorkBit NinjaSCSI-3/32Bi"
,
detect:
nsp_detect
,
release:
nsp_release
,
info:
nsp_info
,
/* command: NULL,*/
queuecommand:
nsp_queuecommand
,
/* eh_strategy_handler: nsp_eh_strategy,*/
eh_abort_handler:
nsp_eh_abort
,
eh_device_reset_handler:
nsp_eh_device_reset
,
eh_bus_reset_handler:
nsp_eh_bus_reset
,
eh_host_reset_handler:
nsp_eh_host_reset
,
abort:
nsp_abort
,
reset:
nsp_reset
,
/* slave_attach: NULL,*/
/* bios_param: NULL,*/
can_queue:
1
,
this_id:
SCSI_INITIATOR_ID
,
sg_tablesize:
SG_ALL
,
cmd_per_lun:
1
,
/* present: 0,*/
/* unchecked_isa_dma: 0,*/
use_clustering:
DISABLE_CLUSTERING
,
/* emulated: 0,*/
.
proc_info
=
nsp_proc_info
,
.
name
=
"WorkBit NinjaSCSI-3/32Bi"
,
.
detect
=
nsp_detect
,
.
release
=
nsp_release
,
.
info
=
nsp_info
,
/* .command = NULL,*/
.
queuecommand
=
nsp_queuecommand
,
/* .eh_strategy_handler = nsp_eh_strategy,*/
/* .eh_abort_handler = nsp_eh_abort,*/
/* .eh_device_reset_handler = nsp_eh_device_reset,*/
.
eh_bus_reset_handler
=
nsp_eh_bus_reset
,
.
eh_host_reset_handler
=
nsp_eh_host_reset
,
.
abort
=
nsp_abort
,
.
reset
=
nsp_reset
,
/* .slave_attach = NULL,*/
/* .bios_param = NULL,*/
.
can_queue
=
1
,
.
this_id
=
NSP_INITIATOR_ID
,
.
sg_tablesize
=
SG_ALL
,
.
cmd_per_lun
=
1
,
/* .present = 0,*/
/* .unchecked_isa_dma = 0,*/
.
use_clustering
=
DISABLE_CLUSTERING
,
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,2))
.
use_new_eh_code
=
1
,
#endif
/* .emulated = 0,*/
};
static
dev_link_t
*
dev_list
=
NULL
;
...
...
@@ -162,18 +174,18 @@ static nsp_hw_data nsp_data;
static
int
nsp_queuecommand
(
Scsi_Cmnd
*
SCpnt
,
void
(
*
done
)(
Scsi_Cmnd
*
))
{
#ifdef PCMCIA_DEBUG
/
/unsigned int host_id = SCpnt->host->this_id;
/
/unsigned int base = SCpnt->host->io_port;
/
*unsigned int host_id = SCpnt->host->this_id;*/
/
*unsigned int base = SCpnt->host->io_port;*/
unsigned
char
target
=
SCpnt
->
target
;
#endif
nsp_hw_data
*
data
=
&
nsp_data
;
DEBUG
(
0
,
__FUNCTION__
"
() SCpnt=0x%p target=%d lun=%d buff=0x%p bufflen=%d use_sg=%d
\n
"
,
SCpnt
,
target
,
SCpnt
->
lun
,
SCpnt
->
request_buffer
,
SCpnt
->
request_bufflen
,
SCpnt
->
use_sg
);
DEBUG
(
0
,
"%s
() SCpnt=0x%p target=%d lun=%d buff=0x%p bufflen=%d use_sg=%d
\n
"
,
__FUNCTION__
,
SCpnt
,
target
,
SCpnt
->
lun
,
SCpnt
->
request_buffer
,
SCpnt
->
request_bufflen
,
SCpnt
->
use_sg
);
//DEBUG(0, " before CurrentSC=0x%p\n", data->CurrentSC);
if
(
data
->
CurrentSC
!=
NULL
)
{
printk
(
KERN_DEBUG
"
"
__FUNCTION__
"() CurrentSC!=NULL this can't be happen
\n
"
);
printk
(
KERN_DEBUG
"
%s() CurrentSC!=NULL cannot happen!
\n
"
,
__FUNCTION__
);
data
->
CurrentSC
=
NULL
;
SCpnt
->
result
=
DID_BAD_TARGET
<<
16
;
done
(
SCpnt
);
...
...
@@ -184,13 +196,13 @@ static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
SCpnt
->
scsi_done
=
done
;
data
->
CurrentSC
=
SCpnt
;
RESID
=
SCpnt
->
request_bufflen
;
SCpnt
->
SCp
.
Status
=
-
1
;
SCpnt
->
SCp
.
Message
=
-
1
;
SCpnt
->
SCp
.
Status
=
CHECK_CONDITION
;
SCpnt
->
SCp
.
Message
=
0
;
SCpnt
->
SCp
.
have_data_in
=
IO_UNKNOWN
;
SCpnt
->
SCp
.
sent_command
=
0
;
SCpnt
->
SCp
.
phase
=
PH_UNDETERMINED
;
RESID
=
SCpnt
->
request_bufflen
;
/* setup scratch area
SCp.ptr : buffer pointer
...
...
@@ -200,7 +212,7 @@ static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
SCp.phase : current state of the command */
if
(
SCpnt
->
use_sg
)
{
SCpnt
->
SCp
.
buffer
=
(
struct
scatterlist
*
)
SCpnt
->
request_buffer
;
SCpnt
->
SCp
.
ptr
=
SCpnt
->
SCp
.
buffer
->
address
;
SCpnt
->
SCp
.
ptr
=
BUFFER_ADDR
;
SCpnt
->
SCp
.
this_residual
=
SCpnt
->
SCp
.
buffer
->
length
;
SCpnt
->
SCp
.
buffers_residual
=
SCpnt
->
use_sg
-
1
;
}
else
{
...
...
@@ -219,7 +231,7 @@ static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
}
//DEBUG(0, __
FUNCTION
__ "() out\n");
//DEBUG(0, __
func
__ "() out\n");
return
0
;
}
...
...
@@ -231,7 +243,7 @@ static void nsp_setup_fifo(nsp_hw_data *data, int enabled)
unsigned
int
base
=
data
->
BaseAddress
;
unsigned
char
transfer_mode_reg
;
//DEBUG(0, __
FUNCTION
__ "() enabled=%d\n", enabled);
//DEBUG(0, __
func
__ "() enabled=%d\n", enabled);
if
(
enabled
!=
FALSE
)
{
transfer_mode_reg
=
TRANSFER_GO
|
BRAIND
;
...
...
@@ -244,31 +256,35 @@ static void nsp_setup_fifo(nsp_hw_data *data, int enabled)
nsp_index_write
(
base
,
TRANSFERMODE
,
transfer_mode_reg
);
}
static
void
nsphw_init_sync
(
nsp_hw_data
*
data
)
{
sync_data
tmp_sync
=
{
.
SyncNegotiation
=
SYNC_NOT_YET
,
.
SyncPeriod
=
0
,
.
SyncOffset
=
0
};
int
i
;
/* setup sync data */
for
(
i
=
0
;
i
<
N_TARGET
;
i
++
)
{
data
->
Sync
[
i
]
=
tmp_sync
;
}
}
/*
* Initialize Ninja hardware
*/
static
int
nsphw_init
(
nsp_hw_data
*
data
)
{
unsigned
int
base
=
data
->
BaseAddress
;
int
i
,
j
;
sync_data
tmp_sync
=
{
SyncNegotiation
:
SYNC_NOT_YET
,
SyncPeriod:
0
,
SyncOffset:
0
};
DEBUG
(
0
,
__FUNCTION__
"() in base=0x%x
\n
"
,
base
);
DEBUG
(
0
,
"%s() in base=0x%x
\n
"
,
__FUNCTION__
,
base
);
data
->
ScsiClockDiv
=
CLOCK_40M
;
data
->
ScsiClockDiv
=
CLOCK_40M
|
FAST_20
;
data
->
CurrentSC
=
NULL
;
data
->
FifoCount
=
0
;
data
->
TransferMode
=
MODE_IO8
;
/* setup sync data */
for
(
i
=
0
;
i
<
N_TARGET
;
i
++
)
{
for
(
j
=
0
;
j
<
N_LUN
;
j
++
)
{
data
->
Sync
[
i
][
j
]
=
tmp_sync
;
}
}
nsphw_init_sync
(
data
);
/* block all interrupts */
nsp_write
(
base
,
IRQCONTROL
,
IRQCONTROL_ALLMASK
);
...
...
@@ -321,10 +337,10 @@ static unsigned int nsphw_start_selection(Scsi_Cmnd *SCpnt,
unsigned
int
host_id
=
SCpnt
->
host
->
this_id
;
unsigned
int
base
=
SCpnt
->
host
->
io_port
;
unsigned
char
target
=
SCpnt
->
target
;
int
wait_coun
t
;
int
time_ou
t
;
unsigned
char
phase
,
arbit
;
//DEBUG(0, __
FUNCTION
__ "()in\n");
//DEBUG(0, __
func
__ "()in\n");
phase
=
nsp_index_read
(
base
,
SCSIBUSMON
);
if
(
phase
!=
BUSMON_BUS_FREE
)
{
...
...
@@ -337,14 +353,14 @@ static unsigned int nsphw_start_selection(Scsi_Cmnd *SCpnt,
SCpnt
->
SCp
.
phase
=
PH_ARBSTART
;
nsp_index_write
(
base
,
SETARBIT
,
ARBIT_GO
);
wait_count
=
jiffies
+
10
*
HZ
;
time_out
=
1000
;
do
{
/* XXX: what a stupid chip! */
arbit
=
nsp_index_read
(
base
,
ARBITSTATUS
);
//DEBUG(0, " arbit=%d, wait_count=%d\n", arbit, wait_count);
udelay
(
1
);
/* hold 1.2us */
}
while
((
arbit
&
(
ARBIT_WIN
|
ARBIT_FAIL
))
==
0
&&
time_before
(
jiffies
,
wait_count
));
(
time_out
--
!=
0
));
if
((
arbit
&
ARBIT_WIN
)
==
0
)
{
//DEBUG(0, " arbit fail\n");
...
...
@@ -356,13 +372,13 @@ static unsigned int nsphw_start_selection(Scsi_Cmnd *SCpnt,
//DEBUG(0, " assert SEL line\n");
SCpnt
->
SCp
.
phase
=
PH_SELSTART
;
udelay
(
3
);
nsp_index_write
(
base
,
SCSIDATALATCH
,
(
1
<<
host_id
)
|
(
1
<<
target
));
nsp_index_write
(
base
,
SCSIBUSCTRL
,
SCSI_SEL
|
SCSI_BSY
|
SCSI_ATN
);
nsp_index_write
(
base
,
SCSIDATALATCH
,
BIT
(
host_id
)
|
BIT
(
target
));
nsp_index_write
(
base
,
SCSIBUSCTRL
,
SCSI_SEL
|
SCSI_BSY
|
SCSI_ATN
);
udelay
(
3
);
nsp_index_write
(
base
,
SCSIBUSCTRL
,
SCSI_SEL
|
SCSI_BSY
|
SCSI_DATAOUT_ENB
|
SCSI_ATN
);
nsp_index_write
(
base
,
SETARBIT
,
ARBIT_FLAG_CLEAR
);
udelay
(
3
);
nsp_index_write
(
base
,
SCSIBUSCTRL
,
SCSI_SEL
|
SCSI_DATAOUT_ENB
|
SCSI_ATN
);
nsp_index_write
(
base
,
SCSIBUSCTRL
,
SCSI_SEL
|
SCSI_DATAOUT_ENB
|
SCSI_ATN
);
/* check selection timeout */
nsp_start_timer
(
SCpnt
,
data
,
1000
/
51
);
...
...
@@ -399,23 +415,21 @@ static struct nsp_sync_table nsp_sync_table_20M[] = {
static
int
nsp_msg
(
Scsi_Cmnd
*
SCpnt
,
nsp_hw_data
*
data
)
{
unsigned
char
target
=
SCpnt
->
target
;
unsigned
char
lun
=
SCpnt
->
lun
;
sync_data
*
sync
=
&
(
data
->
Sync
[
target
]
[
lun
]
);
//
unsigned char lun = SCpnt->lun;
sync_data
*
sync
=
&
(
data
->
Sync
[
target
]);
struct
nsp_sync_table
*
sync_table
;
unsigned
int
period
,
offset
;
int
i
;
DEBUG
(
0
,
__FUNCTION__
"()
\n
"
);
/**!**/
DEBUG
(
0
,
"%s()
\n
"
,
__FUNCTION__
);
period
=
sync
->
SyncPeriod
;
offset
=
sync
->
SyncOffset
;
DEBUG
(
0
,
" period=0x%x, offset=0x%x
\n
"
,
period
,
offset
);
if
(
data
->
ScsiClockDiv
==
CLOCK_20M
)
{
if
(
(
data
->
ScsiClockDiv
&
(
BIT
(
0
)
|
BIT
(
1
)))
==
CLOCK_20M
)
{
sync_table
=
&
nsp_sync_table_20M
[
0
];
}
else
{
sync_table
=
&
nsp_sync_table_40M
[
0
];
...
...
@@ -438,7 +452,6 @@ static int nsp_msg(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
sync
->
SyncOffset
=
0
;
sync
->
SyncRegister
=
0
;
sync
->
AckWidth
=
0
;
sync
->
SyncNegotiation
=
SYNC_OK
;
return
FALSE
;
}
...
...
@@ -446,7 +459,6 @@ static int nsp_msg(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
sync
->
SyncRegister
=
(
sync_table
->
chip_period
<<
SYNCREG_PERIOD_SHIFT
)
|
(
offset
&
SYNCREG_OFFSET_MASK
);
sync
->
AckWidth
=
sync_table
->
ack_width
;
sync
->
SyncNegotiation
=
SYNC_OK
;
DEBUG
(
0
,
" sync_reg=0x%x, ack_width=0x%x
\n
"
,
sync
->
SyncRegister
,
sync
->
AckWidth
);
...
...
@@ -461,7 +473,7 @@ static void nsp_start_timer(Scsi_Cmnd *SCpnt, nsp_hw_data *data, int time)
{
unsigned
int
base
=
SCpnt
->
host
->
io_port
;
//DEBUG(0, __
FUNCTION
__ "() in SCpnt=0x%p, time=%d\n", SCpnt, time);
//DEBUG(0, __
func
__ "() in SCpnt=0x%p, time=%d\n", SCpnt, time);
data
->
TimerCount
=
time
;
nsp_index_write
(
base
,
TIMERCOUNT
,
time
);
}
...
...
@@ -473,21 +485,21 @@ static int nsp_negate_signal(Scsi_Cmnd *SCpnt, unsigned char mask, char *str)
{
unsigned
int
base
=
SCpnt
->
host
->
io_port
;
unsigned
char
reg
;
int
count
,
i
=
TRUE
;
int
time_out
;
//DEBUG(0, __
FUNCTION
__ "()\n");
//DEBUG(0, __
func
__ "()\n");
count
=
jiffies
+
HZ
;
time_out
=
100
;
do
{
reg
=
nsp_index_read
(
base
,
SCSIBUSMON
);
if
(
reg
==
0xff
)
{
break
;
}
}
while
((
i
=
time_before
(
jiffies
,
count
)
)
&&
(
reg
&
mask
)
!=
0
);
}
while
((
time_out
--
!=
0
)
&&
(
reg
&
mask
)
!=
0
);
if
(
!
i
)
{
printk
(
KERN_DEBUG
__FUNCTION__
" %s signal off timeut
\n
"
,
str
);
if
(
time_out
==
0
)
{
printk
(
KERN_DEBUG
"%s: %s signal off timeut
\n
"
,
__FUNCTION__
,
str
);
}
return
0
;
...
...
@@ -501,12 +513,12 @@ static int nsp_expect_signal(Scsi_Cmnd *SCpnt,
unsigned
char
mask
)
{
unsigned
int
base
=
SCpnt
->
host
->
io_port
;
int
wait_coun
t
;
int
time_ou
t
;
unsigned
char
phase
,
i_src
;
//DEBUG(0, __
FUNCTION
__ "() current_phase=0x%x, mask=0x%x\n", current_phase, mask);
//DEBUG(0, __
func
__ "() current_phase=0x%x, mask=0x%x\n", current_phase, mask);
wait_count
=
jiffies
+
HZ
;
time_out
=
100
;
do
{
phase
=
nsp_index_read
(
base
,
SCSIBUSMON
);
if
(
phase
==
0xff
)
{
...
...
@@ -522,9 +534,9 @@ static int nsp_expect_signal(Scsi_Cmnd *SCpnt,
//DEBUG(0, " ret 1 phase=0x%x\n", phase);
return
1
;
}
}
while
(
time_
before
(
jiffies
,
wait_count
)
);
}
while
(
time_
out
--
!=
0
);
//DEBUG(0, __
FUNCTION__ " : " __FUNCTION
__ " timeout\n");
//DEBUG(0, __
func__ " : " __func
__ " timeout\n");
return
-
1
;
}
...
...
@@ -539,7 +551,7 @@ static int nsp_xfer(Scsi_Cmnd *SCpnt, nsp_hw_data *data, int phase)
int
ptr
;
int
ret
;
//DEBUG(0, __
FUNCTION
__ "()\n");
//DEBUG(0, __
func
__ "()\n");
for
(
ptr
=
0
;
len
>
0
;
len
--
,
ptr
++
)
{
ret
=
nsp_expect_signal
(
SCpnt
,
phase
,
BUSMON_REQ
);
...
...
@@ -574,7 +586,7 @@ static int nsp_dataphase_bypass(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
{
unsigned
int
count
;
//DEBUG(0, __
FUNCTION
__ "()\n");
//DEBUG(0, __
func
__ "()\n");
if
(
SCpnt
->
SCp
.
have_data_in
!=
IO_IN
)
{
return
0
;
...
...
@@ -590,11 +602,11 @@ static int nsp_dataphase_bypass(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
* XXX: NSP_QUIRK
* data phase skip only occures in case of SCSI_LOW_READ
*/
DEBUG
(
0
,
" use bypass quirk
\n
"
);
SCpnt
->
SCp
.
phase
=
PH_DATA
;
nsp_pio_read
(
SCpnt
,
data
);
nsp_setup_fifo
(
data
,
FALSE
);
DEBUG
(
0
,
" use bypass quirk
\n
"
);
return
0
;
}
...
...
@@ -606,7 +618,7 @@ static int nsp_reselected(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
unsigned
int
base
=
SCpnt
->
host
->
io_port
;
unsigned
char
reg
;
//DEBUG(0, __
FUNCTION
__ "()\n");
//DEBUG(0, __
func
__ "()\n");
nsp_negate_signal
(
SCpnt
,
BUSMON_SEL
,
"reselect<SEL>"
);
...
...
@@ -625,17 +637,18 @@ static int nsp_fifo_count(Scsi_Cmnd *SCpnt)
{
unsigned
int
base
=
SCpnt
->
host
->
io_port
;
unsigned
int
count
;
unsigned
int
l
,
m
,
h
;
unsigned
int
l
,
m
,
h
,
dummy
;
nsp_index_write
(
base
,
POINTERCLR
,
POINTER_CLEAR
);
nsp_index_write
(
base
,
POINTERCLR
,
POINTER_CLEAR
|
ACK_COUNTER
);
l
=
(
unsigned
int
)
nsp_read
(
base
,
DATAREG
);
m
=
(
unsigned
int
)
nsp_read
(
base
,
DATAREG
);
h
=
(
unsigned
int
)
nsp_read
(
base
,
DATAREG
);
l
=
nsp_index_read
(
base
,
TRANSFERCOUNT
);
m
=
nsp_index_read
(
base
,
TRANSFERCOUNT
);
h
=
nsp_index_read
(
base
,
TRANSFERCOUNT
);
dummy
=
nsp_index_read
(
base
,
TRANSFERCOUNT
);
count
=
(
h
<<
16
)
|
(
m
<<
8
)
|
(
l
<<
0
);
//DEBUG(0, __
FUNCTION
__ "() =0x%x\n", count);
//DEBUG(0, __
func
__ "() =0x%x\n", count);
return
count
;
}
...
...
@@ -649,25 +662,27 @@ static int nsp_fifo_count(Scsi_Cmnd *SCpnt)
*/
static
void
nsp_pio_read
(
Scsi_Cmnd
*
SCpnt
,
nsp_hw_data
*
data
)
{
unsigned
int
base
=
SCpnt
->
host
->
io_port
;
int
time_out
,
i
;
unsigned
int
base
=
SCpnt
->
host
->
io_port
;
unsigned
long
mmio_base
=
SCpnt
->
host
->
base
;
long
time_out
;
int
ocount
,
res
;
unsigned
char
stat
,
fifo_stat
;
ocount
=
data
->
FifoCount
;
DEBUG
(
0
,
__FUNCTION__
"() in SCpnt=0x%p resid=%d ocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d
\n
"
,
SCpnt
,
RESID
,
ocount
,
SCpnt
->
SCp
.
ptr
,
SCpnt
->
SCp
.
this_residual
,
SCpnt
->
SCp
.
buffer
,
SCpnt
->
SCp
.
buffers_residual
);
DEBUG
(
0
,
"%s() in SCpnt=0x%p resid=%d ocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d
\n
"
,
__FUNCTION__
,
SCpnt
,
RESID
,
ocount
,
SCpnt
->
SCp
.
ptr
,
SCpnt
->
SCp
.
this_residual
,
SCpnt
->
SCp
.
buffer
,
SCpnt
->
SCp
.
buffers_residual
);
time_out
=
jiffies
+
10
*
HZ
;
time_out
=
1000
;
while
((
i
=
time_before
(
jiffies
,
time_out
)
)
&&
while
((
time_out
--
!=
0
)
&&
(
SCpnt
->
SCp
.
this_residual
>
0
||
SCpnt
->
SCp
.
buffers_residual
>
0
)
)
{
stat
=
nsp_index_read
(
base
,
SCSIBUSMON
);
stat
&=
BUSMON_PHASE_MASK
;
res
=
nsp_fifo_count
(
SCpnt
)
-
ocount
;
res
=
nsp_fifo_count
(
SCpnt
)
-
ocount
;
//DEBUG(0, " ptr=0x%p this=0x%x ocount=0x%x res=0x%x\n", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, ocount, res);
if
(
res
==
0
)
{
/* if some data avilable ? */
if
(
stat
==
BUSPHASE_DATA_IN
)
{
/* phase changed? */
...
...
@@ -695,9 +710,15 @@ static void nsp_pio_read(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
case
MODE_IO8
:
nsp_fifo8_read
(
base
,
SCpnt
->
SCp
.
ptr
,
res
);
break
;
case
MODE_MEM32
:
res
&=
~
(
BIT
(
1
)
|
BIT
(
0
));
/* align 4 */
nsp_mmio_fifo32_read
(
mmio_base
,
SCpnt
->
SCp
.
ptr
,
res
>>
2
);
break
;
default:
DEBUG
(
0
,
"unknown read mode
\n
"
);
break
;
return
;
}
RESID
-=
res
;
...
...
@@ -712,17 +733,19 @@ static void nsp_pio_read(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
//DEBUG(0, " scatterlist next timeout=%d\n", time_out);
SCpnt
->
SCp
.
buffers_residual
--
;
SCpnt
->
SCp
.
buffer
++
;
SCpnt
->
SCp
.
ptr
=
SCpnt
->
SCp
.
buffer
->
address
;
SCpnt
->
SCp
.
ptr
=
BUFFER_ADDR
;
SCpnt
->
SCp
.
this_residual
=
SCpnt
->
SCp
.
buffer
->
length
;
}
time_out
=
1000
;
time_out
=
jiffies
+
10
*
HZ
;
//DEBUG(0, "page: 0x%p, off: 0x%x\n", SCpnt->SCp.buffer->page, SCpnt->SCp.buffer->offset);
}
}
data
->
FifoCount
=
ocount
;
if
(
!
i
)
{
printk
(
KERN_DEBUG
__FUNCTION__
"() pio read timeout resid=%d this_residual=%d buffers_residual=%d
\n
"
,
RESID
,
SCpnt
->
SCp
.
this_residual
,
SCpnt
->
SCp
.
buffers_residual
);
if
(
time_out
==
0
)
{
printk
(
KERN_DEBUG
"%s() pio read timeout resid=%d this_residual=%d buffers_residual=%d
\n
"
,
__FUNCTION__
,
RESID
,
SCpnt
->
SCp
.
this_residual
,
SCpnt
->
SCp
.
buffers_residual
);
}
DEBUG
(
0
,
" read ocount=0x%x
\n
"
,
ocount
);
}
...
...
@@ -733,22 +756,32 @@ static void nsp_pio_read(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
static
void
nsp_pio_write
(
Scsi_Cmnd
*
SCpnt
,
nsp_hw_data
*
data
)
{
unsigned
int
base
=
SCpnt
->
host
->
io_port
;
int
time_out
,
i
;
unsigned
int
ocount
,
res
;
unsigned
long
mmio_base
=
SCpnt
->
host
->
base
;
int
time_out
;
int
ocount
,
res
;
unsigned
char
stat
;
ocount
=
data
->
FifoCount
;
DEBUG
(
0
,
__FUNCTION__
"() in fifocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d resid=0x%x
\n
"
,
data
->
FifoCount
,
SCpnt
->
SCp
.
ptr
,
SCpnt
->
SCp
.
this_residual
,
SCpnt
->
SCp
.
buffer
,
SCpnt
->
SCp
.
buffers_residual
,
RESID
);
DEBUG
(
0
,
"%s() in fifocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d resid=0x%x
\n
"
,
__FUNCTION__
,
data
->
FifoCount
,
SCpnt
->
SCp
.
ptr
,
SCpnt
->
SCp
.
this_residual
,
SCpnt
->
SCp
.
buffer
,
SCpnt
->
SCp
.
buffers_residual
,
RESID
);
time_out
=
jiffies
+
10
*
HZ
;
time_out
=
1000
;
while
((
i
=
time_before
(
jiffies
,
time_out
))
&&
while
((
time_out
--
!=
0
)
&&
(
SCpnt
->
SCp
.
this_residual
>
0
||
SCpnt
->
SCp
.
buffers_residual
>
0
))
{
stat
=
nsp_index_read
(
base
,
SCSIBUSMON
);
stat
&=
BUSMON_PHASE_MASK
;
if
(
stat
!=
BUSPHASE_DATA_OUT
)
{
DEBUG
(
0
,
" phase changed stat=0x%x
\n
"
,
stat
);
res
=
ocount
-
nsp_fifo_count
(
SCpnt
);
DEBUG
(
0
,
" phase changed stat=0x%x, res=%d
\n
"
,
stat
,
res
);
/* Put back pointer */
RESID
+=
res
;
SCpnt
->
SCp
.
ptr
-=
res
;
SCpnt
->
SCp
.
this_residual
+=
res
;
ocount
-=
res
;
break
;
}
...
...
@@ -769,6 +802,12 @@ static void nsp_pio_write(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
case
MODE_IO8
:
nsp_fifo8_write
(
base
,
SCpnt
->
SCp
.
ptr
,
res
);
break
;
case
MODE_MEM32
:
res
&=
~
(
BIT
(
1
)
|
BIT
(
0
));
/* align 4 */
nsp_mmio_fifo32_write
(
mmio_base
,
SCpnt
->
SCp
.
ptr
,
res
>>
2
);
break
;
default:
DEBUG
(
0
,
"unknown write mode
\n
"
);
break
;
...
...
@@ -785,19 +824,18 @@ static void nsp_pio_write(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
//DEBUG(0, " scatterlist next\n");
SCpnt
->
SCp
.
buffers_residual
--
;
SCpnt
->
SCp
.
buffer
++
;
SCpnt
->
SCp
.
ptr
=
SCpnt
->
SCp
.
buffer
->
address
;
SCpnt
->
SCp
.
ptr
=
BUFFER_ADDR
;
SCpnt
->
SCp
.
this_residual
=
SCpnt
->
SCp
.
buffer
->
length
;
time_out
=
1000
;
}
time_out
=
jiffies
+
10
*
HZ
;
}
data
->
FifoCount
=
ocount
;
if
(
!
i
)
{
printk
(
KERN_DEBUG
__FUNCTION__
"() pio write timeout resid=%d
\n
"
,
RESID
);
if
(
time_out
==
0
)
{
printk
(
KERN_DEBUG
"%s() pio write timeout resid=0x%x
\n
"
,
__FUNCTION__
,
RESID
);
}
//DEBUG(0, " write ocount=%d
\n", ocount);
DEBUG
(
0
,
" write ocount=0x%x
\n
"
,
ocount
);
}
#undef RFIFO_CRIT
...
...
@@ -810,20 +848,25 @@ static int nsp_nexus(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
{
unsigned
int
base
=
SCpnt
->
host
->
io_port
;
unsigned
char
target
=
SCpnt
->
target
;
unsigned
char
lun
=
SCpnt
->
lun
;
sync_data
*
sync
=
&
(
data
->
Sync
[
target
]
[
lun
]
);
//
unsigned char lun = SCpnt->lun;
sync_data
*
sync
=
&
(
data
->
Sync
[
target
]);
//DEBUG(0, __
FUNCTION
__ "() in SCpnt=0x%p\n", SCpnt);
//DEBUG(0, __
func
__ "() in SCpnt=0x%p\n", SCpnt);
/* setup synch transfer registers */
nsp_index_write
(
base
,
SYNCREG
,
sync
->
SyncRegister
);
nsp_index_write
(
base
,
ACKWIDTH
,
sync
->
AckWidth
);
if
(
RESID
%
4
!=
0
||
RESID
<=
256
)
{
if
(
SCpnt
->
use_sg
==
0
||
RESID
%
4
!=
0
||
RESID
<=
PAGE_SIZE
)
{
data
->
TransferMode
=
MODE_IO8
;
}
else
{
}
else
if
(
nsp_burst_mode
==
BURST_MEM32
)
{
data
->
TransferMode
=
MODE_MEM32
;
}
else
if
(
nsp_burst_mode
==
BURST_IO32
)
{
data
->
TransferMode
=
MODE_IO32
;
}
else
{
data
->
TransferMode
=
MODE_IO8
;
}
/* setup pdma fifo */
...
...
@@ -848,24 +891,13 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
unsigned
int
base
;
unsigned
char
i_src
,
irq_phase
,
phase
;
Scsi_Cmnd
*
tmpSC
;
int
len
;
unsigned
char
target
,
lun
;
unsigned
int
*
sync_neg
;
int
i
,
tmp
;
nsp_hw_data
*
data
;
nsp_hw_data
*
data
=
dev_id
;
//printk("&nsp_data=0x%p, dev_id=0x%p\n", &nsp_data, dev_id);
/* sanity check */
if
(
&
nsp_data
!=
dev_id
)
{
DEBUG
(
0
,
" irq conflict? this can't happen
\n
"
);
return
;
}
data
=
dev_id
;
if
(
irq
!=
data
->
IrqNumber
)
{
return
;
}
base
=
data
->
BaseAddress
;
//DEBUG(0, " base=0x%x\n", base);
...
...
@@ -874,13 +906,13 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
*/
nsp_write
(
base
,
IRQCONTROL
,
IRQCONTROL_IRQDISABLE
);
i_src
=
nsp_read
(
base
,
IRQSTATUS
);
if
(
i_src
==
0xff
||
(
i_src
&
IRQSTATUS_MASK
)
==
0
)
{
//DEBUG(0, " i_src=0x%x\n", i_src);
if
((
i_src
==
0xff
)
||
((
i_src
&
IRQSTATUS_MASK
)
==
0
))
{
nsp_write
(
base
,
IRQCONTROL
,
0
);
//DEBUG(0, " no irq\n");
//DEBUG(0, " no irq
/shared irq
\n");
return
;
}
//DEBUG(0, " i_src=0x%x\n", i_src);
/* XXX: IMPORTANT
* Do not read an irq_phase register if no scsi phase interrupt.
...
...
@@ -916,13 +948,13 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
nsp_write
(
base
,
IRQCONTROL
,
IRQCONTROL_TIMER_CLEAR
|
IRQCONTROL_FIFO_CLEAR
);
if
(
data
->
CurrentSC
==
NULL
)
{
printk
(
KERN_DEBUG
__FUNCTION__
" CurrentSC==NULL irq_status=0x%x phase=0x%x irq_phase=0x%x this can't be happen
\n
"
,
i_src
,
phase
,
irq_phase
);
printk
(
KERN_DEBUG
"%s: CurrentSC==NULL irq_status=0x%x phase=0x%x irq_phase=0x%x cannot happen
\n
"
,
__FUNCTION__
,
i_src
,
phase
,
irq_phase
);
return
;
}
else
{
tmpSC
=
data
->
CurrentSC
;
target
=
tmpSC
->
target
;
lun
=
tmpSC
->
lun
;
sync_neg
=
&
(
data
->
Sync
[
target
]
[
lun
]
.
SyncNegotiation
);
sync_neg
=
&
(
data
->
Sync
[
target
].
SyncNegotiation
);
}
/*
...
...
@@ -930,10 +962,12 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
*/
if
((
i_src
&
IRQSTATUS_SCSI
)
!=
0
)
{
if
((
irq_phase
&
SCSI_RESET_IRQ
)
!=
0
)
{
printk
(
KERN_DEBUG
"
"
__FUNCTION__
"() bus reset (power off?)
\n
"
);
printk
(
KERN_DEBUG
"
%s() bus reset (power off?)
\n
"
,
__FUNCTION__
);
*
sync_neg
=
SYNC_NOT_YET
;
data
->
CurrentSC
=
NULL
;
tmpSC
->
result
=
DID_RESET
<<
16
;
tmpSC
->
result
=
(
DID_RESET
<<
16
)
|
((
tmpSC
->
SCp
.
Message
&
0xff
)
<<
8
)
|
((
tmpSC
->
SCp
.
Status
&
0xff
)
<<
0
);
tmpSC
->
scsi_done
(
tmpSC
);
return
;
}
...
...
@@ -955,7 +989,7 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
switch
(
tmpSC
->
SCp
.
phase
)
{
case
PH_SELSTART
:
*
sync_neg
=
SYNC_NOT_YET
;
//
*sync_neg = SYNC_NOT_YET;
if
((
phase
&
BUSMON_BSY
)
==
0
)
{
//DEBUG(0, " selection count=%d\n", data->SelectionTimeOut);
if
(
data
->
SelectionTimeOut
>=
NSP_SELTIMEOUT
)
{
...
...
@@ -987,7 +1021,7 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
case
PH_RESELECT
:
//DEBUG(0, " phase reselect\n");
*
sync_neg
=
SYNC_NOT_YET
;
//
*sync_neg = SYNC_NOT_YET;
if
((
phase
&
BUSMON_PHASE_MASK
)
!=
BUSPHASE_MESSAGE_IN
)
{
data
->
CurrentSC
=
NULL
;
...
...
@@ -1009,16 +1043,18 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
//DEBUG(0, " start scsi seq\n");
/* normal disconnect */
if
((
irq_phase
&
LATCHED_BUS_FREE
)
!=
0
)
{
//DEBUG(0, " normal disconnect i_src=0x%x, phase=0x%x, irq_phase=0x%x\n", i_src, phase, irq_phase);
if
(((
tmpSC
->
SCp
.
phase
==
PH_MSG_IN
)
||
(
tmpSC
->
SCp
.
phase
==
PH_MSG_OUT
))
&&
(
irq_phase
&
LATCHED_BUS_FREE
)
!=
0
)
{
DEBUG
(
0
,
" normal disconnect i_src=0x%x, phase=0x%x, irq_phase=0x%x
\n
"
,
i_src
,
phase
,
irq_phase
);
if
((
tmpSC
->
SCp
.
Message
==
MSG_COMMAND_COMPLETE
))
{
/* all command complete and return status */
*
sync_neg
=
SYNC_NOT_YET
;
//
*sync_neg = SYNC_NOT_YET;
data
->
CurrentSC
=
NULL
;
tmpSC
->
result
=
(
DID_OK
<<
16
)
|
(
tmpSC
->
SCp
.
Message
<<
8
)
|
(
tmpSC
->
SCp
.
Status
<<
0
);
tmpSC
->
result
=
(
DID_OK
<<
16
)
|
(
(
tmpSC
->
SCp
.
Message
&
0xff
)
<<
8
)
|
(
(
tmpSC
->
SCp
.
Status
&
0xff
)
<<
0
);
DEBUG
(
0
,
" command complete result=0x%x
\n
"
,
tmpSC
->
result
);
tmpSC
->
scsi_done
(
tmpSC
);
return
;
}
...
...
@@ -1028,7 +1064,7 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
/* check unexpected bus free state */
if
(
phase
==
0
)
{
printk
(
KERN_DEBUG
"
"
__FUNCTION__
" unexpected bus free. i_src=0x%x, phase=0x%x, irq_phase=0x%x
\n
"
,
i_src
,
phase
,
irq_phase
);
printk
(
KERN_DEBUG
"
%s: unexpected bus free. i_src=0x%x, phase=0x%x, irq_phase=0x%x
\n
"
,
__FUNCTION__
,
i_src
,
phase
,
irq_phase
);
*
sync_neg
=
SYNC_NOT_YET
;
data
->
CurrentSC
=
NULL
;
...
...
@@ -1050,9 +1086,10 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
nsp_nexus
(
tmpSC
,
data
);
/* write scsi command */
DEBUG
(
0
,
" cmd_len=%d
\n
"
,
tmpSC
->
cmd_len
);
nsp_index_write
(
base
,
COMMANDCTRL
,
CLEAR_COMMAND_POINTER
);
for
(
len
=
0
;
len
<
COMMAND_SIZE
(
tmpSC
->
cmnd
[
0
]);
len
++
)
{
nsp_index_write
(
base
,
COMMANDDATA
,
tmpSC
->
cmnd
[
len
]);
for
(
i
=
0
;
i
<
tmpSC
->
cmd_len
;
i
++
)
{
nsp_index_write
(
base
,
COMMANDDATA
,
tmpSC
->
cmnd
[
i
]);
}
nsp_index_write
(
base
,
COMMANDCTRL
,
CLEAR_COMMAND_POINTER
|
AUTO_COMMAND_GO
);
break
;
...
...
@@ -1084,7 +1121,7 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
tmpSC
->
SCp
.
phase
=
PH_STATUS
;
tmpSC
->
SCp
.
Status
=
nsp_index_read
(
base
,
SCSIDATAWITHACK
);
//
DEBUG(0, " message=0x%x status=0x%x\n", tmpSC->SCp.Message, tmpSC->SCp.Status);
DEBUG
(
0
,
" message=0x%x status=0x%x
\n
"
,
tmpSC
->
SCp
.
Message
,
tmpSC
->
SCp
.
Status
);
break
;
...
...
@@ -1096,26 +1133,24 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
tmpSC
->
SCp
.
phase
=
PH_MSG_OUT
;
data
->
MsgLen
=
len
=
0
;
if
(
*
sync_neg
==
SYNC_NOT_YET
)
{
data
->
Sync
[
target
][
lun
].
SyncPeriod
=
0
;
data
->
Sync
[
target
][
lun
].
SyncOffset
=
0
;
nsp_msg
(
tmpSC
,
data
);
data
->
MsgLen
=
i
=
0
;
data
->
MsgBuffer
[
i
]
=
IDENTIFY
(
TRUE
,
lun
);
i
++
;
data
->
MsgBuffer
[
len
]
=
IDENTIFY
(
TRUE
,
lun
);
len
++
;
/*
data->
MsgBuffer[len] = MSG_EXTENDED; len++
;
data->MsgBuffer[len] = 3; len++;
data->MsgBuffer[len] = MSG_EXT_SDTR; len++;
data->MsgBuffer[
len] = 0x0c; len
++;
data->MsgBuffer[
len] = 15; len
++;
*/
}
if
(
len
==
0
)
{
data
->
MsgBuffer
[
len
]
=
MSG_NO_OPERATION
;
len
++
;
if
(
*
sync_neg
==
SYNC_NOT_YET
)
{
data
->
Sync
[
target
].
SyncPeriod
=
0
;
data
->
Sync
[
target
].
SyncOffset
=
0
;
/**/
data
->
MsgBuffer
[
i
]
=
MSG_EXTENDED
;
i
++
;
data
->
MsgBuffer
[
i
]
=
3
;
i
++
;
data
->
MsgBuffer
[
i
]
=
MSG_EXT_SDTR
;
i
++
;
data
->
MsgBuffer
[
i
]
=
0x0c
;
i
++
;
data
->
MsgBuffer
[
i
]
=
15
;
i
++
;
/**/
}
data
->
MsgLen
=
len
;
data
->
MsgLen
=
i
;
nsp_msg
(
tmpSC
,
data
);
show_message
(
data
);
nsp_message_out
(
tmpSC
,
data
);
break
;
...
...
@@ -1130,16 +1165,26 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
tmpSC
->
SCp
.
phase
=
PH_MSG_IN
;
nsp_message_in
(
tmpSC
,
data
);
/*
if (data->MsgLen >= 5 &&
data->MsgBuffer[0] == MSG_EXTENDED &&
data->MsgBuffer[1] == 3 &&
data->MsgBuffer[2] == MSG_EXT_SDTR ) {
data->Sync[target][lun].SyncPeriod = data->MsgBuffer[3];
data->Sync[target][lun].SyncOffset = data->MsgBuffer[4];
/**/
if
(
*
sync_neg
==
SYNC_NOT_YET
)
{
//printk("%d,%d\n",target,lun);
if
(
data
->
MsgLen
>=
5
&&
data
->
MsgBuffer
[
0
]
==
MSG_EXTENDED
&&
data
->
MsgBuffer
[
1
]
==
3
&&
data
->
MsgBuffer
[
2
]
==
MSG_EXT_SDTR
)
{
data
->
Sync
[
target
].
SyncPeriod
=
data
->
MsgBuffer
[
3
];
data
->
Sync
[
target
].
SyncOffset
=
data
->
MsgBuffer
[
4
];
//printk("sync ok, %d %d\n", data->MsgBuffer[3], data->MsgBuffer[4]);
*
sync_neg
=
SYNC_OK
;
}
else
{
data
->
Sync
[
target
].
SyncPeriod
=
0
;
data
->
Sync
[
target
].
SyncOffset
=
0
;
*
sync_neg
=
SYNC_NG
;
}
nsp_msg
(
tmpSC
,
data
);
}
*/
/*
*/
/* search last messeage byte */
tmp
=
-
1
;
...
...
@@ -1163,7 +1208,7 @@ static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
break
;
}
//DEBUG(0, __
FUNCTION
__ "() out\n");
//DEBUG(0, __
func
__ "() out\n");
return
;
timer_out:
...
...
@@ -1183,41 +1228,52 @@ static int nsp_detect(Scsi_Host_Template *sht)
struct
Scsi_Host
*
host
;
/* registered host structure */
nsp_hw_data
*
data
=
&
nsp_data
;
DEBUG
(
0
,
__FUNCTION__
" this_id=%d
\n
"
,
sht
->
this_id
);
DEBUG
(
0
,
"%s: this_id=%d
\n
"
,
__FUNCTION__
,
sht
->
this_id
);
request_region
(
data
->
BaseAddress
,
data
->
NumAddress
,
"nsp_cs"
);
host
=
scsi_register
(
sht
,
0
);
host
->
io_port
=
data
->
BaseAddress
;
host
->
unique_id
=
data
->
BaseAddress
;
host
->
io_port
=
data
->
BaseAddress
;
host
->
n_io_port
=
data
->
NumAddress
;
host
->
irq
=
data
->
IrqNumber
;
host
->
dma_channel
=
0xff
;
/* not use dms */
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0))
host
->
base
=
data
->
MmioAddress
;
/* kernel 2.4 */
#else
host
->
base
=
(
char
*
)(
data
->
MmioAddress
);
/* 2.2 */
#endif
spin_lock_init
(
&
(
data
->
Lock
));
snprintf
(
data
->
nspinfo
,
sizeof
(
data
->
nspinfo
),
"NinjaSCSI-3/32Bi Driver $Revision: 1.4 $ IO:0x%04lx-0x%04lx MMIO(virt addr):0x%04lx IRQ:%02d"
,
host
->
io_port
,
host
->
io_port
+
host
->
n_io_port
-
1
,
host
->
base
,
host
->
irq
);
data
->
nspinfo
[
sizeof
(
data
->
nspinfo
)
-
1
]
=
'\0'
;
sht
->
name
=
data
->
nspinfo
;
sprintf
(
nspinfo
,
/* Buffer size is 100 bytes */
/* 0 1 2 3 4 5 6 7 8 9 0*/
/* 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890*/
"NinjaSCSI-3/32Bi Driver $Revision: 1.42 $, I/O 0x%04lx-0x%04lx IRQ %2d"
,
host
->
io_port
,
host
->
io_port
+
host
->
n_io_port
,
host
->
irq
);
sht
->
name
=
nspinfo
;
DEBUG
(
0
,
"%s: end
\n
"
,
__FUNCTION__
);
DEBUG
(
0
,
__FUNCTION__
" end
\n
"
)
;
//MOD_INC_USE_COUNT
;
return
1
;
/* detect done. */
}
/* nsp_cs requires own release handler because its uses dev_id (=data) */
static
int
nsp_release
(
struct
Scsi_Host
*
shpnt
)
{
nsp_hw_data
*
data
=
&
nsp_data
;
//nsp_hw_data *data = &nsp_data;
/* PCMCIA Card Service dose same things */
//if (shpnt->irq) {
// free_irq(shpnt->irq, data);
//}
//if (shpnt->io_port) {
// release_region(shpnt->io_port, shpnt->n_io_port);
//}
//MOD_DEC_USE_COUNT;
if
(
shpnt
->
irq
)
{
free_irq
(
shpnt
->
irq
,
data
);
}
if
(
shpnt
->
io_port
&&
shpnt
->
n_io_port
)
{
release_region
(
shpnt
->
io_port
,
shpnt
->
n_io_port
);
}
return
0
;
}
...
...
@@ -1226,25 +1282,152 @@ static int nsp_release(struct Scsi_Host *shpnt)
/*----------------------------------------------------------------*/
static
const
char
*
nsp_info
(
struct
Scsi_Host
*
shpnt
)
{
return
nspinfo
;
nsp_hw_data
*
data
=
&
nsp_data
;
return
data
->
nspinfo
;
}
#undef SPRINTF
#define SPRINTF(args...) \
do { if(pos < buffer + length) pos += sprintf(pos, ## args); } while(0)
static
int
nsp_proc_info
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
length
,
int
hostno
,
int
inout
)
{
int
id
;
char
*
pos
=
buffer
;
int
thislength
;
int
speed
;
unsigned
long
flags
;
nsp_hw_data
*
data
=
&
nsp_data
;
struct
Scsi_Host
*
host
;
if
(
inout
)
{
return
-
EINVAL
;
}
host
=
scsi_host_hn_get
(
hostno
);
SPRINTF
(
"NinjaSCSI status
\n\n
"
);
SPRINTF
(
"Driver version: $Revision: 1.4 $
\n
"
);
SPRINTF
(
"SCSI host No.: %d
\n
"
,
hostno
);
SPRINTF
(
"IRQ: %d
\n
"
,
host
->
irq
);
SPRINTF
(
"IO: 0x%lx-0x%lx
\n
"
,
host
->
io_port
,
host
->
io_port
+
host
->
n_io_port
-
1
);
SPRINTF
(
"MMIO(virtual address): 0x%lx
\n
"
,
host
->
base
);
SPRINTF
(
"sg_tablesize: %d
\n
"
,
host
->
sg_tablesize
);
SPRINTF
(
"burst transfer mode: "
);
switch
(
nsp_burst_mode
)
{
case
BURST_IO8
:
SPRINTF
(
"io8"
);
break
;
case
BURST_IO32
:
SPRINTF
(
"io32"
);
break
;
case
BURST_MEM32
:
SPRINTF
(
"mem32"
);
break
;
default:
SPRINTF
(
"???"
);
break
;
}
SPRINTF
(
"
\n
"
);
spin_lock_irqsave
(
&
(
data
->
Lock
),
flags
);
SPRINTF
(
"CurrentSC: 0x%p
\n\n
"
,
data
->
CurrentSC
);
spin_unlock_irqrestore
(
&
(
data
->
Lock
),
flags
);
SPRINTF
(
"SDTR status
\n
"
);
for
(
id
=
0
;
id
<
N_TARGET
;
id
++
)
{
SPRINTF
(
"id %d: "
,
id
);
if
(
id
==
host
->
this_id
)
{
SPRINTF
(
"----- NinjaSCSI-3 host adapter
\n
"
);
continue
;
}
switch
(
data
->
Sync
[
id
].
SyncNegotiation
)
{
case
SYNC_OK
:
SPRINTF
(
" sync"
);
break
;
case
SYNC_NG
:
SPRINTF
(
"async"
);
break
;
case
SYNC_NOT_YET
:
SPRINTF
(
" none"
);
break
;
default:
SPRINTF
(
"?????"
);
break
;
}
if
(
data
->
Sync
[
id
].
SyncPeriod
!=
0
)
{
speed
=
1000000
/
(
data
->
Sync
[
id
].
SyncPeriod
*
4
);
SPRINTF
(
" transfer %d.%dMB/s, offset %d"
,
speed
/
1000
,
speed
%
1000
,
data
->
Sync
[
id
].
SyncOffset
);
}
SPRINTF
(
"
\n
"
);
}
thislength
=
pos
-
(
buffer
+
offset
);
if
(
thislength
<
0
)
{
*
start
=
0
;
return
0
;
}
thislength
=
MIN
(
thislength
,
length
);
*
start
=
buffer
+
offset
;
return
thislength
;
}
#undef SPRINTF
/*---------------------------------------------------------------*/
/* error handler */
/*---------------------------------------------------------------*/
static
int
nsp_reset
(
Scsi_Cmnd
*
SCpnt
,
unsigned
int
why
)
static
int
nsp_reset
(
Scsi_Cmnd
*
SCpnt
,
unsigned
int
reset_flags
)
{
DEBUG
(
0
,
__FUNCTION__
" SCpnt=0x%p why=%d
\n
"
,
SCpnt
,
why
);
nsp_hw_data
*
data
=
&
nsp_data
;
int
ret
=
0
;
nsp_eh_bus_reset
(
SCpnt
);
DEBUG
(
0
,
"%s: SCpnt=0x%p why=%d
\n
"
,
__FUNCTION__
,
SCpnt
,
reset_flags
);
return
SCSI_RESET_SUCCESS
;
if
(
reset_flags
&
SCSI_RESET_SUGGEST_BUS_RESET
)
{
nsp_eh_bus_reset
(
SCpnt
);
ret
|=
SCSI_RESET_BUS_RESET
;
}
if
(
reset_flags
&
SCSI_RESET_SUGGEST_HOST_RESET
)
{
nsp_eh_host_reset
(
SCpnt
);
ret
|=
SCSI_RESET_HOST_RESET
;
}
if
(
ret
!=
0
)
{
return
SCSI_RESET_SUCCESS
|
ret
;
}
else
{
nsphw_init_sync
(
data
);
return
SCSI_RESET_PUNT
;
}
}
static
int
nsp_abort
(
Scsi_Cmnd
*
SCpnt
)
{
DEBUG
(
0
,
__FUNCTION__
" SCpnt=0x%p
\n
"
,
SCpnt
);
DEBUG
(
0
,
"%s: SCpnt=0x%p
\n
"
,
__FUNCTION__
,
SCpnt
);
nsp_eh_host_reset
(
SCpnt
);
nsp_eh_bus_reset
(
SCpnt
);
return
SCSI_ABORT_SUCCESS
;
...
...
@@ -1255,28 +1438,29 @@ static int nsp_abort(Scsi_Cmnd *SCpnt)
return FAILED;
}*/
/*
static int nsp_eh_abort(Scsi_Cmnd *SCpnt)
{
DEBUG
(
0
,
__FUNCTION__
" SCpnt=0x%p
\n
"
,
SCpnt
);
DEBUG(0,
"%s: SCpnt=0x%p\n", __FUNCTION__
, SCpnt);
nsp_eh_bus_reset
(
SCpnt
);
return
SUCCESS
;
}
return nsp_eh_bus_reset(SCpnt);
}*/
/*
static int nsp_eh_device_reset(Scsi_Cmnd *SCpnt)
{
DEBUG
(
0
,
__FUNCTION__
" SCpnt=0x%p
\n
"
,
SCpnt
);
DEBUG(0,
"%s: SCpnt=0x%p\n", __FUNCTION__
, SCpnt);
return FAILED;
}
}
*/
static
int
nsp_eh_bus_reset
(
Scsi_Cmnd
*
SCpnt
)
{
nsp_hw_data
*
data
=
&
nsp_data
;
unsigned
int
base
=
SCpnt
->
host
->
io_port
;
int
i
;
DEBUG
(
0
,
__FUNCTION__
"() SCpnt=0x%p base=0x%x
\n
"
,
SCpnt
,
base
);
DEBUG
(
0
,
"%s() SCpnt=0x%p base=0x%x
\n
"
,
__FUNCTION__
,
SCpnt
,
base
);
nsp_write
(
base
,
IRQCONTROL
,
IRQCONTROL_ALLMASK
);
...
...
@@ -1289,6 +1473,8 @@ static int nsp_eh_bus_reset(Scsi_Cmnd *SCpnt)
nsp_write
(
base
,
IRQCONTROL
,
IRQCONTROL_ALLCLEAR
);
nsphw_init_sync
(
data
);
return
SUCCESS
;
}
...
...
@@ -1296,17 +1482,17 @@ static int nsp_eh_host_reset(Scsi_Cmnd *SCpnt)
{
nsp_hw_data
*
data
=
&
nsp_data
;
DEBUG
(
0
,
__FUNCTION__
"
\n
"
);
DEBUG
(
0
,
"%s
\n
"
,
__FUNCTION__
);
nsphw_init
(
data
);
return
nsp_eh_bus_reset
(
SCpnt
)
;
return
SUCCESS
;
}
/**********************************************************************
PCMCIA functions
*********************************************************************/
*
*********************************************************************/
/*====================================================================*/
static
void
cs_error
(
client_handle_t
handle
,
int
func
,
int
ret
)
...
...
@@ -1331,7 +1517,7 @@ static dev_link_t *nsp_cs_attach(void)
dev_link_t
*
link
;
int
ret
,
i
;
DEBUG
(
0
,
__FUNCTION__
"()
\n
"
);
DEBUG
(
0
,
"%s()
\n
"
,
__FUNCTION__
);
/* Create new SCSI device */
info
=
kmalloc
(
sizeof
(
*
info
),
GFP_KERNEL
);
...
...
@@ -1359,8 +1545,15 @@ static dev_link_t *nsp_cs_attach(void)
link
->
irq
.
IRQInfo2
|=
1
<<
irq_list
[
i
];
}
}
/* IRQ $B$N3NJ]$O$3$3$G(B PCMCIA $B$N4X?t$rMQ$$$F9T$J$&$N$G(B
* host->hostdata $B$r(B irq.Instance $B$KBeF~$G$-$J$$!#(B
* host->hostdata $B$,;H$($l$PJ#?t$N(B NinjaSCSI $B$,(B
* $B;HMQ$G$-$k$N$@$,!#(B
*/
link
->
irq
.
Handler
=
&
nspintr
;
link
->
irq
.
Instance
=
&
nsp_data
;
link
->
irq
.
Attributes
|=
(
SA_SHIRQ
|
SA_SAMPLE_RANDOM
);
/* General socket configuration */
link
->
conf
.
Attributes
=
CONF_ENABLE_IRQ
;
...
...
@@ -1402,7 +1595,7 @@ static void nsp_cs_detach(dev_link_t *link)
{
dev_link_t
**
linkp
;
DEBUG
(
0
,
__FUNCTION__
"(0x%p)
\n
"
,
link
);
DEBUG
(
0
,
"%s(0x%p)
\n
"
,
__FUNCTION__
,
link
);
/* Locate device structure */
for
(
linkp
=
&
dev_list
;
*
linkp
;
linkp
=
&
(
*
linkp
)
->
next
)
{
...
...
@@ -1414,7 +1607,7 @@ static void nsp_cs_detach(dev_link_t *link)
return
;
}
del_timer
(
&
link
->
release
);
del_timer
_sync
(
&
link
->
release
);
if
(
link
->
state
&
DEV_CONFIG
)
{
nsp_cs_release
((
u_long
)
link
);
if
(
link
->
state
&
DEV_STALE_CONFIG
)
{
...
...
@@ -1431,6 +1624,7 @@ static void nsp_cs_detach(dev_link_t *link)
/* Unlink device structure, free bits */
*
linkp
=
link
->
next
;
kfree
(
link
->
priv
);
link
->
priv
=
NULL
;
}
/* nsp_cs_detach */
...
...
@@ -1452,15 +1646,20 @@ static void nsp_cs_config(dev_link_t *link)
scsi_info_t
*
info
=
link
->
priv
;
tuple_t
tuple
;
cisparse_t
parse
;
int
i
,
last_ret
,
last_fn
;
int
last_ret
,
last_fn
;
u_char
tuple_data
[
64
];
config_info_t
conf
;
win_req_t
req
;
memreq_t
map
;
cistpl_cftable_entry_t
dflt
=
{
0
};
Scsi_Device
*
dev
;
dev_node_t
**
tail
,
*
node
;
struct
Scsi_Host
*
host
;
nsp_hw_data
*
data
=
&
nsp_data
;
DEBUG
(
0
,
__FUNCTION__
"() in
\n
"
);
DEBUG
(
0
,
"%s() in
\n
"
,
__FUNCTION__
);
tuple
.
DesiredTuple
=
CISTPL_CONFIG
;
tuple
.
Attributes
=
0
;
...
...
@@ -1474,7 +1673,6 @@ static void nsp_cs_config(dev_link_t *link)
link
->
conf
.
Present
=
parse
.
config
.
rmask
[
0
];
/* Configure card */
driver_template
.
module
=
&
__this_module
;
link
->
state
|=
DEV_CONFIG
;
/* Look up the current Vcc */
...
...
@@ -1484,44 +1682,130 @@ static void nsp_cs_config(dev_link_t *link)
tuple
.
DesiredTuple
=
CISTPL_CFTABLE_ENTRY
;
CS_CHECK
(
GetFirstTuple
,
handle
,
&
tuple
);
while
(
1
)
{
cistpl_cftable_entry_t
*
cfg
=
&
(
parse
.
cftable_entry
);
CFG_CHECK
(
GetTupleData
,
handle
,
&
tuple
);
CFG_CHECK
(
ParseTuple
,
handle
,
&
tuple
,
&
parse
);
link
->
conf
.
ConfigIndex
=
parse
.
cftable_entry
.
index
;
link
->
io
.
BasePort1
=
parse
.
cftable_entry
.
io
.
win
[
0
].
base
;
i
=
CardServices
(
RequestIO
,
handle
,
&
link
->
io
);
if
(
i
==
CS_SUCCESS
)
{
break
;
if
(
cfg
->
flags
&
CISTPL_CFTABLE_DEFAULT
)
{
dflt
=
*
cfg
;
}
if
(
cfg
->
index
==
0
)
{
goto
next_entry
;
}
link
->
conf
.
ConfigIndex
=
cfg
->
index
;
/* Does this card need audio output? */
if
(
cfg
->
flags
&
CISTPL_CFTABLE_AUDIO
)
{
link
->
conf
.
Attributes
|=
CONF_ENABLE_SPKR
;
link
->
conf
.
Status
=
CCSR_AUDIO_ENA
;
}
/* Use power settings for Vcc and Vpp if present */
/* Note that the CIS values need to be rescaled */
if
(
cfg
->
vcc
.
present
&
(
1
<<
CISTPL_POWER_VNOM
))
{
if
(
conf
.
Vcc
!=
cfg
->
vcc
.
param
[
CISTPL_POWER_VNOM
]
/
10000
)
{
goto
next_entry
;
}
}
else
if
(
dflt
.
vcc
.
present
&
(
1
<<
CISTPL_POWER_VNOM
))
{
if
(
conf
.
Vcc
!=
dflt
.
vcc
.
param
[
CISTPL_POWER_VNOM
]
/
10000
)
{
goto
next_entry
;
}
}
if
(
cfg
->
vpp1
.
present
&
(
1
<<
CISTPL_POWER_VNOM
))
{
link
->
conf
.
Vpp1
=
link
->
conf
.
Vpp2
=
cfg
->
vpp1
.
param
[
CISTPL_POWER_VNOM
]
/
10000
;
}
else
if
(
dflt
.
vpp1
.
present
&
(
1
<<
CISTPL_POWER_VNOM
))
{
link
->
conf
.
Vpp1
=
link
->
conf
.
Vpp2
=
dflt
.
vpp1
.
param
[
CISTPL_POWER_VNOM
]
/
10000
;
}
/* Do we need to allocate an interrupt? */
if
(
cfg
->
irq
.
IRQInfo1
||
dflt
.
irq
.
IRQInfo1
)
{
link
->
conf
.
Attributes
|=
CONF_ENABLE_IRQ
;
}
/* IO window settings */
link
->
io
.
NumPorts1
=
link
->
io
.
NumPorts2
=
0
;
if
((
cfg
->
io
.
nwin
>
0
)
||
(
dflt
.
io
.
nwin
>
0
))
{
cistpl_io_t
*
io
=
(
cfg
->
io
.
nwin
)
?
&
cfg
->
io
:
&
dflt
.
io
;
link
->
io
.
Attributes1
=
IO_DATA_PATH_WIDTH_AUTO
;
if
(
!
(
io
->
flags
&
CISTPL_IO_8BIT
))
link
->
io
.
Attributes1
=
IO_DATA_PATH_WIDTH_16
;
if
(
!
(
io
->
flags
&
CISTPL_IO_16BIT
))
link
->
io
.
Attributes1
=
IO_DATA_PATH_WIDTH_8
;
link
->
io
.
IOAddrLines
=
io
->
flags
&
CISTPL_IO_LINES_MASK
;
link
->
io
.
BasePort1
=
io
->
win
[
0
].
base
;
link
->
io
.
NumPorts1
=
io
->
win
[
0
].
len
;
if
(
io
->
nwin
>
1
)
{
link
->
io
.
Attributes2
=
link
->
io
.
Attributes1
;
link
->
io
.
BasePort2
=
io
->
win
[
1
].
base
;
link
->
io
.
NumPorts2
=
io
->
win
[
1
].
len
;
}
/* This reserves IO space but doesn't actually enable it */
CFG_CHECK
(
RequestIO
,
link
->
handle
,
&
link
->
io
);
}
if
((
cfg
->
mem
.
nwin
>
0
)
||
(
dflt
.
mem
.
nwin
>
0
))
{
cistpl_mem_t
*
mem
=
(
cfg
->
mem
.
nwin
)
?
&
cfg
->
mem
:
&
dflt
.
mem
;
req
.
Attributes
=
WIN_DATA_WIDTH_16
|
WIN_MEMORY_TYPE_CM
;
req
.
Attributes
|=
WIN_ENABLE
;
req
.
Base
=
mem
->
win
[
0
].
host_addr
;
req
.
Size
=
mem
->
win
[
0
].
len
;
if
(
req
.
Size
<
0x1000
)
req
.
Size
=
0x1000
;
req
.
AccessSpeed
=
0
;
link
->
win
=
(
window_handle_t
)
link
->
handle
;
CFG_CHECK
(
RequestWindow
,
&
link
->
win
,
&
req
);
map
.
Page
=
0
;
map
.
CardOffset
=
mem
->
win
[
0
].
card_addr
;
CFG_CHECK
(
MapMemPage
,
link
->
win
,
&
map
);
data
->
MmioAddress
=
(
u_long
)
ioremap_nocache
(
req
.
Base
,
req
.
Size
);
}
/* If we got this far, we're cool! */
break
;
next_entry:
DEBUG
(
0
,
__FUNCTION__
" next
\n
"
);
DEBUG
(
0
,
"%s next
\n
"
,
__FUNCTION__
);
if
(
link
->
io
.
NumPorts1
)
CardServices
(
ReleaseIO
,
link
->
handle
,
&
link
->
io
);
CS_CHECK
(
GetNextTuple
,
handle
,
&
tuple
);
}
CS_CHECK
(
RequestIRQ
,
handle
,
&
link
->
irq
);
if
(
link
->
conf
.
Attributes
&
CONF_ENABLE_IRQ
)
CS_CHECK
(
RequestIRQ
,
link
->
handle
,
&
link
->
irq
);
CS_CHECK
(
RequestConfiguration
,
handle
,
&
link
->
conf
);
/* A bad hack... */
release_region
(
link
->
io
.
BasePort1
,
link
->
io
.
NumPorts1
);
if
(
free_ports
)
{
if
(
link
->
io
.
BasePort1
)
release_region
(
link
->
io
.
BasePort1
,
link
->
io
.
NumPorts1
);
if
(
link
->
io
.
BasePort2
)
release_region
(
link
->
io
.
BasePort2
,
link
->
io
.
NumPorts2
);
}
/* Set port and IRQ */
data
->
BaseAddress
=
link
->
io
.
BasePort1
;
data
->
NumAddress
=
link
->
io
.
NumPorts1
;
data
->
IrqNumber
=
link
->
irq
.
AssignedIRQ
;
data
->
BaseAddress
=
link
->
io
.
BasePort1
;
data
->
NumAddress
=
link
->
io
.
NumPorts1
;
data
->
IrqNumber
=
link
->
irq
.
AssignedIRQ
;
DEBUG
(
0
,
__FUNCTION__
" I/O[0x%x+0x%x] IRQ %d
\n
"
,
DEBUG
(
0
,
"%s I/O[0x%x+0x%x] IRQ %d
\n
"
,
__FUNCTION__
,
data
->
BaseAddress
,
data
->
NumAddress
,
data
->
IrqNumber
);
if
(
nsphw_init
(
data
)
==
FALSE
)
{
goto
cs_failed
;
}
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2))
scsi_register_host
(
&
driver_template
);
#else
scsi_register_module
(
MODULE_SCSI_HA
,
&
driver_template
);
#endif
DEBUG
(
0
,
"GET_SCSI_INFO
\n
"
);
tail
=
&
link
->
dev
;
info
->
ndev
=
0
;
for
(
host
=
scsi_host_get_next
(
NULL
);
host
;
host
=
scsi_host_get_next
(
host
))
host
=
scsi_host_get_next
(
host
))
{
if
(
host
->
hostt
==
&
driver_template
)
{
for
(
dev
=
host
->
host_queue
;
dev
!=
NULL
;
dev
=
dev
->
next
)
{
u_long
arg
[
2
],
id
;
...
...
@@ -1575,6 +1859,12 @@ static void nsp_cs_config(dev_link_t *link)
printk
(
", io 0x%04x-0x%04x"
,
link
->
io
.
BasePort1
,
link
->
io
.
BasePort1
+
link
->
io
.
NumPorts1
-
1
);
}
if
(
link
->
io
.
NumPorts2
)
printk
(
" & 0x%04x-0x%04x"
,
link
->
io
.
BasePort2
,
link
->
io
.
BasePort2
+
link
->
io
.
NumPorts2
-
1
);
if
(
link
->
win
)
printk
(
", mem 0x%06lx-0x%06lx"
,
req
.
Base
,
req
.
Base
+
req
.
Size
-
1
);
printk
(
"
\n
"
);
link
->
state
&=
~
DEV_CONFIG_PENDING
;
...
...
@@ -1598,7 +1888,7 @@ static void nsp_cs_release(u_long arg)
{
dev_link_t
*
link
=
(
dev_link_t
*
)
arg
;
DEBUG
(
0
,
__FUNCTION__
"(0x%p)
\n
"
,
link
);
DEBUG
(
0
,
"%s(0x%p)
\n
"
,
__FUNCTION__
,
link
);
/*
* If the device is currently in use, we won't release until it
...
...
@@ -1612,10 +1902,15 @@ static void nsp_cs_release(u_long arg)
}
/* Unlink the device chain */
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2))
scsi_unregister_host
(
&
driver_template
);
#else
scsi_unregister_module
(
MODULE_SCSI_HA
,
&
driver_template
);
#endif
link
->
dev
=
NULL
;
if
(
link
->
win
)
{
iounmap
((
void
*
)(
nsp_data
.
MmioAddress
));
CardServices
(
ReleaseWindow
,
link
->
win
);
}
CardServices
(
ReleaseConfiguration
,
link
->
handle
);
...
...
@@ -1645,14 +1940,15 @@ static void nsp_cs_release(u_long arg)
the card is still present.
======================================================================*/
static
int
nsp_cs_event
(
event_t
event
,
int
priority
,
event_callback_args_t
*
args
)
static
int
nsp_cs_event
(
event_t
event
,
int
priority
,
event_callback_args_t
*
args
)
{
dev_link_t
*
link
=
args
->
client_data
;
scsi_info_t
*
info
=
link
->
priv
;
Scsi_Cmnd
tmp
;
DEBUG
(
1
,
__FUNCTION__
"(0x%06x)
\n
"
,
event
);
DEBUG
(
1
,
"%s(0x%06x)
\n
"
,
__FUNCTION__
,
event
);
switch
(
event
)
{
case
CS_EVENT_CARD_REMOVAL
:
...
...
@@ -1688,20 +1984,21 @@ static int nsp_cs_event(event_t event,
case
CS_EVENT_CARD_RESET
:
DEBUG
(
0
,
" event: reset
\n
"
);
if
(
link
->
state
&
DEV_CONFIG
)
{
Scsi_Cmnd
tmp
;
CardServices
(
RequestConfiguration
,
link
->
handle
,
&
link
->
conf
);
tmp
.
host
=
info
->
host
;
nsp_eh_host_reset
(
&
tmp
);
}
info
->
stop
=
0
;
tmp
.
host
=
info
->
host
;
nsp_eh_host_reset
(
&
tmp
);
nsp_eh_bus_reset
(
&
tmp
);
break
;
default:
DEBUG
(
0
,
" event: unknown
\n
"
);
break
;
}
DEBUG
(
0
,
__FUNCTION__
" end
\n
"
);
DEBUG
(
0
,
"%s end
\n
"
,
__FUNCTION__
);
return
0
;
}
/* nsp_cs_event */
...
...
@@ -1712,7 +2009,7 @@ static int __init nsp_cs_init(void)
{
servinfo_t
serv
;
DEBUG
(
0
,
__FUNCTION__
"() in
\n
"
);
DEBUG
(
0
,
"%s() in
\n
"
,
__FUNCTION__
);
DEBUG
(
0
,
"%s
\n
"
,
version
);
CardServices
(
GetCardServicesInfo
,
&
serv
);
if
(
serv
.
Revision
!=
CS_RELEASE_CODE
)
{
...
...
@@ -1722,14 +2019,14 @@ static int __init nsp_cs_init(void)
}
register_pcmcia_driver
(
&
dev_info
,
&
nsp_cs_attach
,
&
nsp_cs_detach
);
DEBUG
(
0
,
__FUNCTION__
"() out
\n
"
);
DEBUG
(
0
,
"%s() out
\n
"
,
__FUNCTION__
);
return
0
;
}
static
void
__exit
nsp_cs_cleanup
(
void
)
{
DEBUG
(
0
,
__FUNCTION__
"() unloading
\n
"
);
DEBUG
(
0
,
"%s() unloading
\n
"
,
__FUNCTION__
);
unregister_pcmcia_driver
(
&
dev_info
);
while
(
dev_list
!=
NULL
)
{
if
(
dev_list
->
state
&
DEV_CONFIG
)
{
...
...
@@ -1739,8 +2036,8 @@ static void __exit nsp_cs_cleanup(void)
}
}
module_init
(
nsp_cs_init
)
;
module_exit
(
nsp_cs_cleanup
)
;
module_init
(
nsp_cs_init
)
module_exit
(
nsp_cs_cleanup
)
/*
*
...
...
drivers/scsi/pcmcia/nsp_cs.h
View file @
57e34bbb
...
...
@@ -10,13 +10,13 @@
=========================================================*/
/* $Id: nsp_cs.h,v 1.
27 2001/09/10 10:31:13
elca Exp $ */
/* $Id: nsp_cs.h,v 1.
3 2002/10/10 11:07:52
elca Exp $ */
#ifndef __nsp_cs__
#define __nsp_cs__
/* for debugging */
/
*#define PCMCIA_DEBUG 9*/
/
/#define PCMCIA_DEBUG 9
/*
#define static
...
...
@@ -27,11 +27,11 @@
* Some useful macros...
*/
#define Number(arr) ((int) (sizeof(arr) / sizeof(arr[0])))
#define BIT(x) (1
<<
(x))
#define BIT(x) (1
L <<
(x))
#define MIN(a,b) ((a) > (b) ? (b) : (a))
/* SCSI initiator must be 7 */
#define
SCSI
_INITIATOR_ID 7
/* SCSI initiator must be
ID
7 */
#define
NSP
_INITIATOR_ID 7
#define NSP_SELTIMEOUT 200
...
...
@@ -73,6 +73,7 @@
#define CLOCKDIV 0x11
# define CLOCK_40M 0x02
# define CLOCK_20M 0x01
# define FAST_20 BIT(2)
#define TERMPWRCTRL 0x13
# define POWER_ON BIT(0)
...
...
@@ -133,6 +134,9 @@
# define REQ_COUNTER_CLEAR BIT(2)
# define HOST_COUNTER_CLEAR BIT(3)
# define READ_SOURCE 0x30
# define ACK_COUNTER (0)
# define REQ_COUNTER (BIT(4))
# define HOST_COUNTER (BIT(5))
#define TRANSFERCOUNT 0x1E
/* R */
...
...
@@ -222,11 +226,14 @@ typedef struct _sync_data {
unsigned
char
AckWidth
;
}
sync_data
;
typedef
struct
_nsp_data
{
typedef
struct
_nsp_
hw_
data
{
unsigned
int
BaseAddress
;
unsigned
int
NumAddress
;
unsigned
int
IrqNumber
;
unsigned
long
MmioAddress
;
#define NSP_MMIO_OFFSET 0x0800
unsigned
char
ScsiClockDiv
;
unsigned
char
TransferMode
;
...
...
@@ -238,9 +245,9 @@ typedef struct _nsp_data {
int
FifoCount
;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0))
int
Residual
;
#define RESID
data->Residual
#define RESID
(data->Residual)
#else
#define RESID
SCpnt->resid
#define RESID
(SCpnt->resid)
#endif
#define MSGBUF_SIZE 20
...
...
@@ -248,10 +255,20 @@ typedef struct _nsp_data {
int
MsgLen
;
#define N_TARGET 8
#define N_LUN 8
sync_data
Sync
[
N_TARGET
][
N_LUN
];
sync_data
Sync
[
N_TARGET
];
char
nspinfo
[
110
];
/* description */
spinlock_t
Lock
;
}
nsp_hw_data
;
/* scatter-gather table */
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2))
# define BUFFER_ADDR ((char *)((unsigned int)(SCpnt->SCp.buffer->page) + SCpnt->SCp.buffer->offset))
#else
# define BUFFER_ADDR SCpnt->SCp.buffer->address
#endif
static
void
nsp_cs_release
(
u_long
arg
);
static
int
nsp_cs_event
(
event_t
event
,
int
priority
,
event_callback_args_t
*
args
);
...
...
@@ -263,14 +280,16 @@ static void nsp_start_timer(Scsi_Cmnd *SCpnt, nsp_hw_data *data, int time);
static
int
nsp_detect
(
Scsi_Host_Template
*
);
static
int
nsp_release
(
struct
Scsi_Host
*
shpnt
);
static
const
char
*
nsp_info
(
struct
Scsi_Host
*
shpnt
);
static
const
char
*
nsp_info
(
struct
Scsi_Host
*
shpnt
);
static
int
nsp_proc_info
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
length
,
int
hostno
,
int
inout
);
static
int
nsp_queuecommand
(
Scsi_Cmnd
*
,
void
(
*
done
)(
Scsi_Cmnd
*
));
static
int
nsp_abort
(
Scsi_Cmnd
*
);
static
int
nsp_reset
(
Scsi_Cmnd
*
,
unsigned
int
);
static
int
nsp_eh_abort
(
Scsi_Cmnd
*
SCpnt
);
static
int
nsp_eh_device_reset
(
Scsi_Cmnd
*
SCpnt
);
/*static int nsp_eh_abort(Scsi_Cmnd * SCpnt);*/
/*static int nsp_eh_device_reset(Scsi_Cmnd *SCpnt);*/
static
int
nsp_eh_bus_reset
(
Scsi_Cmnd
*
SCpnt
);
static
int
nsp_eh_host_reset
(
Scsi_Cmnd
*
SCpnt
);
...
...
@@ -294,17 +313,19 @@ static void show_message(nsp_hw_data *data);
* SCSI phase
*/
enum
_scsi_phase
{
PH_UNDETERMINED
,
PH_ARBSTART
,
PH_SELSTART
,
PH_SELECTED
,
PH_COMMAND
,
PH_DATA
,
PH_STATUS
,
PH_MSG_IN
,
PH_MSG_OUT
,
PH_DISCONNECT
,
PH_RESELECT
PH_UNDETERMINED
,
PH_ARBSTART
,
PH_SELSTART
,
PH_SELECTED
,
PH_COMMAND
,
PH_DATA
,
PH_STATUS
,
PH_MSG_IN
,
PH_MSG_OUT
,
PH_DISCONNECT
,
PH_RESELECT
,
PH_ABORT
,
PH_RESET
};
enum
_data_in_out
{
...
...
@@ -313,11 +334,19 @@ enum _data_in_out {
IO_OUT
};
enum
_burst_mode
{
BURST_IO8
=
0
,
BURST_IO32
,
BURST_MEM32
};
/* SCSI messaage */
#define MSG_COMMAND_COMPLETE 0x00
#define MSG_EXTENDED 0x01
#define MSG_ABORT 0x06
#define MSG_NO_OPERATION 0x08
#define MSG_BUS_DEVICE_RESET 0x0c
#define MSG_EXT_SDTR 0x01
...
...
drivers/scsi/pcmcia/nsp_debug.c
View file @
57e34bbb
...
...
@@ -6,7 +6,7 @@
the GNU General Public License.
=========================================================================*/
/* $Id: nsp_debug.c,v 1.
8 2001/09/07 04:32:28 elca
Exp $ */
/* $Id: nsp_debug.c,v 1.
2 2002/09/20 04:06:58 gotom
Exp $ */
/*
* Show the command data of a command
...
...
@@ -87,14 +87,21 @@ static void print_opcodek(unsigned char opcode)
static
void
print_commandk
(
unsigned
char
*
command
)
{
int
i
,
s
;
int
i
,
s
;
printk
(
KERN_DEBUG
);
print_opcodek
(
command
[
0
]);
/*printk(KERN_DEBUG __FUNCTION__ " ");*/
for
(
i
=
1
,
s
=
COMMAND_SIZE
(
command
[
0
]);
i
<
s
;
++
i
)
{
if
((
command
[
0
]
>>
5
)
==
6
||
(
command
[
0
]
>>
5
)
==
7
)
{
s
=
12
;
/* vender specific */
}
else
{
s
=
COMMAND_SIZE
(
command
[
0
]);
}
for
(
i
=
1
;
i
<
s
;
++
i
)
{
printk
(
"%02x "
,
command
[
i
]);
}
switch
(
COMMAND_SIZE
(
command
[
0
]))
{
switch
(
s
)
{
case
6
:
printk
(
"LBA=%d len=%d"
,
(((
unsigned
int
)
command
[
1
]
&
0x0f
)
<<
16
)
|
...
...
drivers/scsi/pcmcia/nsp_io.h
View file @
57e34bbb
...
...
@@ -7,7 +7,7 @@
*/
/* $Id: nsp_io.h,v 1.
9 2001/09/07 04:32:42 elca
Exp $ */
/* $Id: nsp_io.h,v 1.
2 2002/09/20 04:06:58 gotom
Exp $ */
#ifndef __NSP_IO_H__
#define __NSP_IO_H__
...
...
@@ -76,7 +76,7 @@ static inline void nsp_fifo8_read(unsigned int base,
void
*
buf
,
unsigned
long
count
)
{
/
/DEBUG(0, __FUNCTION__ "() buf=0x%p, count=0x%lx\n", buf, count);
/
*DEBUG(0, __FUNCTION__ "() buf=0x%p, count=0x%lx\n", buf, count);*/
nsp_multi_read_1
(
base
,
FIFODATA
,
buf
,
count
);
}
...
...
@@ -172,5 +172,103 @@ static inline void nsp_fifo32_write(unsigned int base,
nsp_multi_write_4
(
base
,
FIFODATA
,
buf
,
count
);
}
/*====================================================================*/
static
inline
void
nsp_mmio_write
(
unsigned
long
base
,
unsigned
int
index
,
unsigned
char
val
)
{
unsigned
char
*
ptr
=
(
unsigned
char
*
)(
base
+
NSP_MMIO_OFFSET
+
index
);
writeb
(
val
,
ptr
);
}
static
inline
unsigned
char
nsp_mmio_read
(
unsigned
long
base
,
unsigned
int
index
)
{
unsigned
char
*
ptr
=
(
unsigned
char
*
)(
base
+
NSP_MMIO_OFFSET
+
index
);
return
readb
(
ptr
);
}
/*-----------*/
static
inline
unsigned
char
nsp_mmio_index_read
(
unsigned
long
base
,
unsigned
int
reg
)
{
unsigned
char
*
index_ptr
=
(
unsigned
char
*
)(
base
+
NSP_MMIO_OFFSET
+
INDEXREG
);
unsigned
char
*
data_ptr
=
(
unsigned
char
*
)(
base
+
NSP_MMIO_OFFSET
+
DATAREG
);
writeb
((
unsigned
char
)
reg
,
index_ptr
);
return
readb
(
data_ptr
);
}
static
inline
void
nsp_mmio_index_write
(
unsigned
long
base
,
unsigned
int
reg
,
unsigned
char
val
)
{
unsigned
char
*
index_ptr
=
(
unsigned
char
*
)(
base
+
NSP_MMIO_OFFSET
+
INDEXREG
);
unsigned
char
*
data_ptr
=
(
unsigned
char
*
)(
base
+
NSP_MMIO_OFFSET
+
DATAREG
);
writeb
((
unsigned
char
)
reg
,
index_ptr
);
writeb
(
val
,
data_ptr
);
}
/* read 32bit FIFO */
static
inline
void
nsp_mmio_multi_read_4
(
unsigned
long
base
,
unsigned
int
Register
,
void
*
buf
,
unsigned
long
count
)
{
unsigned
long
*
ptr
=
(
unsigned
long
*
)(
base
+
Register
);
unsigned
long
*
tmp
=
(
unsigned
long
*
)
buf
;
int
i
;
//printk("base 0x%0lx ptr 0x%p\n",base,ptr);
for
(
i
=
0
;
i
<
count
;
i
++
)
{
*
tmp
=
readl
(
ptr
);
//printk("<%d,%p,%p,%lx>", i, ptr, tmp, *tmp);
tmp
++
;
}
}
static
inline
void
nsp_mmio_fifo32_read
(
unsigned
int
base
,
void
*
buf
,
unsigned
long
count
)
{
//DEBUG(0, __FUNCTION__ "() buf=0x%p, count=0x%lx*4\n", buf, count);
nsp_mmio_multi_read_4
(
base
,
FIFODATA
,
buf
,
count
);
}
static
inline
void
nsp_mmio_multi_write_4
(
unsigned
long
base
,
unsigned
int
Register
,
void
*
buf
,
unsigned
long
count
)
{
unsigned
long
*
ptr
=
(
unsigned
long
*
)(
base
+
Register
);
unsigned
long
*
tmp
=
(
unsigned
long
*
)
buf
;
int
i
;
//printk("base 0x%0lx ptr 0x%p\n",base,ptr);
for
(
i
=
0
;
i
<
count
;
i
++
)
{
writel
(
*
tmp
,
ptr
);
//printk("<%d,%p,%p,%lx>", i, ptr, tmp, *tmp);
tmp
++
;
}
}
static
inline
void
nsp_mmio_fifo32_write
(
unsigned
int
base
,
void
*
buf
,
unsigned
long
count
)
{
//DEBUG(0, __FUNCTION__ "() buf=0x%p, count=0x%lx*4\n", buf, count);
nsp_mmio_multi_write_4
(
base
,
FIFODATA
,
buf
,
count
);
}
#endif
/* end */
drivers/scsi/pcmcia/nsp_message.c
View file @
57e34bbb
...
...
@@ -6,7 +6,7 @@
the GNU General Public License.
*/
/* $Id: nsp_message.c,v 1.
7 2001/09/07 04:33:01 elca
Exp $ */
/* $Id: nsp_message.c,v 1.
2 2002/09/20 04:06:58 gotom
Exp $ */
static
void
nsp_message_in
(
Scsi_Cmnd
*
SCpnt
,
nsp_hw_data
*
data
)
{
...
...
@@ -64,7 +64,7 @@ static void nsp_message_out(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
DEBUG
(
0
,
" msgout loop
\n
"
);
do
{
if
(
nsp_xfer
(
SCpnt
,
data
,
BUSPHASE_MESSAGE_OUT
))
{
printk
(
KERN_DEBUG
"
"
__FUNCTION__
" msgout: xfer short
\n
"
);
printk
(
KERN_DEBUG
"
%s msgout: xfer short
\n
"
,
__FUNCTION__
);
}
/* catch a next signal */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment