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
9da07cd3
Commit
9da07cd3
authored
Nov 04, 2002
by
Alan Cox
Committed by
Dave Jones
Nov 04, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] first pass over ultrastor.c (still used for u24f)
parent
4847fb27
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
80 additions
and
88 deletions
+80
-88
drivers/scsi/ultrastor.c
drivers/scsi/ultrastor.c
+72
-79
drivers/scsi/ultrastor.h
drivers/scsi/ultrastor.h
+8
-9
No files found.
drivers/scsi/ultrastor.c
View file @
9da07cd3
...
...
@@ -8,6 +8,9 @@
* John's work modified by Caleb Epstein (cae@jpmorgan.com) and
* Eric Youngdale (ericy@cais.com).
* Thanks to UltraStor for providing the necessary documentation
*
* This is an old driver, for the 14F and 34F you should be using the
* u14-34f driver instead.
*/
/*
...
...
@@ -164,8 +167,8 @@
packed structure. */
typedef
struct
{
u
nsigned
int
address
;
u
nsigned
int
num_bytes
;
u
32
address
;
u
32
num_bytes
;
}
ultrastor_sg_list
;
...
...
@@ -190,7 +193,7 @@ struct mscp {
unsigned
char
scsi_cdbs
[
12
];
/* SCSI commands */
unsigned
char
adapter_status
;
/* non-zero indicates HA error */
unsigned
char
target_status
;
/* non-zero indicates target error */
u
nsigned
int
sense_data
PACKED
;
u
32
sense_data
PACKED
;
/* The following fields are for software only. They are included in
the MSCP structure because they are associated with SCSI requests. */
void
(
*
done
)(
Scsi_Cmnd
*
);
...
...
@@ -289,17 +292,15 @@ static void do_ultrastor_interrupt(int, void *, struct pt_regs *);
static
inline
void
build_sg_list
(
struct
mscp
*
,
Scsi_Cmnd
*
SCpnt
);
/* Always called with host lock held */
static
inline
int
find_and_clear_bit_16
(
unsigned
short
*
field
)
{
int
rv
;
unsigned
long
flags
;
save_flags
(
flags
);
cli
();
if
(
*
field
==
0
)
panic
(
"No free mscp"
);
asm
(
"xorl %0,%0
\n
0:
\t
bsfw %1,%w0
\n\t
btr %0,%1
\n\t
jnc 0b"
:
"=&r"
(
rv
),
"=m"
(
*
field
)
:
"1"
(
*
field
));
restore_flags
(
flags
);
return
rv
;
}
...
...
@@ -320,14 +321,12 @@ static inline unsigned char xchgb(unsigned char reg,
#if ULTRASTOR_DEBUG & (UD_COMMAND | UD_ABORT)
static
void
log_ultrastor_abort
(
register
struct
ultrastor_config
*
config
,
/* Always called with the host lock held */
static
void
log_ultrastor_abort
(
struct
ultrastor_config
*
config
,
int
command
)
{
static
char
fmt
[
80
]
=
"abort %d (%x); MSCP free pool: %x;"
;
register
int
i
;
unsigned
long
flags
;
save_flags
(
flags
);
cli
();
int
i
;
for
(
i
=
0
;
i
<
ULTRASTOR_MAX_CMDS
;
i
++
)
{
...
...
@@ -340,7 +339,7 @@ static void log_ultrastor_abort(register struct ultrastor_config *config,
fmt
[
20
+
ULTRASTOR_MAX_CMDS
*
2
]
=
'\n'
;
fmt
[
21
+
ULTRASTOR_MAX_CMDS
*
2
]
=
0
;
printk
(
fmt
,
command
,
&
config
->
mscp
[
command
],
config
->
mscp_free
);
restore_flags
(
flags
);
}
#endif
...
...
@@ -528,7 +527,7 @@ static int ultrastor_14f_detect(Scsi_Host_Template * tpnt)
static
int
ultrastor_24f_detect
(
Scsi_Host_Template
*
tpnt
)
{
register
int
i
;
int
i
;
struct
Scsi_Host
*
shpnt
=
NULL
;
#if (ULTRASTOR_DEBUG & UD_DETECT)
...
...
@@ -638,13 +637,13 @@ static int ultrastor_24f_detect(Scsi_Host_Template * tpnt)
return
FALSE
;
}
int
ultrastor_detect
(
Scsi_Host_Template
*
tpnt
)
static
int
ultrastor_detect
(
Scsi_Host_Template
*
tpnt
)
{
tpnt
->
proc_name
=
"ultrastor"
;
return
ultrastor_14f_detect
(
tpnt
)
||
ultrastor_24f_detect
(
tpnt
);
}
const
char
*
ultrastor_info
(
struct
Scsi_Host
*
shpnt
)
static
const
char
*
ultrastor_info
(
struct
Scsi_Host
*
shpnt
)
{
static
char
buf
[
64
];
...
...
@@ -662,7 +661,7 @@ const char *ultrastor_info(struct Scsi_Host * shpnt)
return
buf
;
}
static
inline
void
build_sg_list
(
register
struct
mscp
*
mscp
,
Scsi_Cmnd
*
SCpnt
)
static
inline
void
build_sg_list
(
struct
mscp
*
mscp
,
Scsi_Cmnd
*
SCpnt
)
{
struct
scatterlist
*
sl
;
long
transfer_length
=
0
;
...
...
@@ -683,14 +682,13 @@ static inline void build_sg_list(register struct mscp *mscp, Scsi_Cmnd *SCpnt)
mscp
->
transfer_data_length
=
transfer_length
;
}
int
ultrastor_queuecommand
(
Scsi_Cmnd
*
SCpnt
,
void
(
*
done
)(
Scsi_Cmnd
*
))
static
int
ultrastor_queuecommand
(
Scsi_Cmnd
*
SCpnt
,
void
(
*
done
)(
Scsi_Cmnd
*
))
{
register
struct
mscp
*
my_mscp
;
struct
mscp
*
my_mscp
;
#if ULTRASTOR_MAX_CMDS > 1
int
mscp_index
;
#endif
unsigned
int
status
;
unsigned
long
flags
;
/* Next test is for debugging; "can't happen" */
if
((
config
.
mscp_free
&
((
1U
<<
ULTRASTOR_MAX_CMDS
)
-
1
))
==
0
)
...
...
@@ -706,14 +704,8 @@ int ultrastor_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
my_mscp
=
&
config
.
mscp
[
mscp_index
];
#if 1
/* This way is faster. */
*
(
unsigned
char
*
)
my_mscp
=
OP_SCSI
|
(
DTD_SCSI
<<
3
);
#else
my_mscp
->
opcode
=
OP_SCSI
;
my_mscp
->
xdir
=
DTD_SCSI
;
my_mscp
->
dcn
=
FALSE
;
#endif
/* Tape drives don't work properly if the cache is used. The SCSI
READ command for a tape doesn't have a block offset, and the adapter
incorrectly assumes that all reads from the tape read the same
...
...
@@ -748,35 +740,31 @@ int ultrastor_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
SCpnt
->
host_scribble
=
(
unsigned
char
*
)
my_mscp
;
/* Find free OGM slot. On 24F, look for OGM status byte == 0.
On 14F and 34F, wait for local interrupt pending flag to clear.
*/
On 14F and 34F, wait for local interrupt pending flag to clear.
retry:
FIXME: now we are using new_eh we should punt here and let the
midlayer sort it out */
retry:
if
(
config
.
slot
)
while
(
inb
(
config
.
ogm_address
-
1
)
!=
0
&&
config
.
aborted
[
mscp_index
]
==
0xff
)
barrier
();
while
(
inb
(
config
.
ogm_address
-
1
)
!=
0
&&
config
.
aborted
[
mscp_index
]
==
0xff
)
barrier
();
/* else??? */
while
((
inb
(
LCL_DOORBELL_INTR
(
config
.
doorbell_address
))
&
(
config
.
slot
?
2
:
1
))
&&
config
.
aborted
[
mscp_index
]
==
0xff
)
barrier
();
/* To avoid race conditions, make the code to write to the adapter
atomic. This simplifies the abort code. */
while
((
inb
(
LCL_DOORBELL_INTR
(
config
.
doorbell_address
))
&
(
config
.
slot
?
2
:
1
))
&&
config
.
aborted
[
mscp_index
]
==
0xff
)
barrier
();
save_flags
(
flags
);
cli
();
/* To avoid race conditions, keep the code to write to the adapter
atomic. This simplifies the abort code. Right now the
scsi mid layer has the host_lock already held
*/
if
(
inb
(
LCL_DOORBELL_INTR
(
config
.
doorbell_address
))
&
(
config
.
slot
?
2
:
1
))
{
restore_flags
(
flags
);
if
(
inb
(
LCL_DOORBELL_INTR
(
config
.
doorbell_address
))
&
(
config
.
slot
?
2
:
1
))
goto
retry
;
}
status
=
xchgb
(
0
,
&
config
.
aborted
[
mscp_index
]);
if
(
status
!=
0xff
)
{
restore_flags
(
flags
);
#if ULTRASTOR_DEBUG & (UD_COMMAND | UD_ABORT)
printk
(
"USx4F: queuecommand: aborted
\n
"
);
...
...
@@ -811,8 +799,6 @@ int ultrastor_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
outb
(
0x1
,
LCL_DOORBELL_INTR
(
config
.
doorbell_address
));
}
restore_flags
(
flags
);
#if (ULTRASTOR_DEBUG & UD_COMMAND)
printk
(
"USx4F: queuecommand: returning
\n
"
);
#endif
...
...
@@ -835,7 +821,7 @@ int ultrastor_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
*/
int
ultrastor_abort
(
Scsi_Cmnd
*
SCpnt
)
static
int
ultrastor_abort
(
Scsi_Cmnd
*
SCpnt
)
{
#if ULTRASTOR_DEBUG & UD_ABORT
char
out
[
108
];
...
...
@@ -844,14 +830,16 @@ int ultrastor_abort(Scsi_Cmnd *SCpnt)
#endif
unsigned
int
mscp_index
;
unsigned
char
old_aborted
;
unsigned
long
flags
;
void
(
*
done
)(
Scsi_Cmnd
*
);
struct
Scsi_Host
*
host
=
SCpnt
->
host
;
if
(
config
.
slot
)
return
SCSI_ABORT_SNOOZE
;
/* Do not attempt an abort for the 24f */
return
FAILED
;
/* Do not attempt an abort for the 24f */
/* Simple consistency checking */
if
(
!
SCpnt
->
host_scribble
)
return
SCSI_ABORT_NOT_RUNNING
;
return
FAILED
;
mscp_index
=
((
struct
mscp
*
)
SCpnt
->
host_scribble
)
-
config
.
mscp
;
if
(
mscp_index
>=
ULTRASTOR_MAX_CMDS
)
...
...
@@ -863,8 +851,8 @@ int ultrastor_abort(Scsi_Cmnd *SCpnt)
int
port0
=
(
config
.
slot
<<
12
)
|
0xc80
;
int
i
;
unsigned
long
flags
;
save_flags
(
flags
);
cli
(
);
spin_lock_irqsave
(
host
->
host_lock
,
flags
);
strcpy
(
out
,
"OGM %d:%x ICM %d:%x ports: "
);
for
(
i
=
0
;
i
<
16
;
i
++
)
{
...
...
@@ -879,7 +867,7 @@ int ultrastor_abort(Scsi_Cmnd *SCpnt)
ogm_addr
=
(
unsigned
int
)
isa_bus_to_virt
(
inl
(
port0
+
23
));
icm_status
=
inb
(
port0
+
27
);
icm_addr
=
(
unsigned
int
)
isa_bus_to_virt
(
inl
(
port0
+
28
));
restore_flags
(
flags
);
spin_lock_irqsave
(
host
->
host_lock
,
flags
);
}
/* First check to see if an interrupt is pending. I suspect the SiS
...
...
@@ -888,14 +876,13 @@ int ultrastor_abort(Scsi_Cmnd *SCpnt)
if
(
config
.
slot
?
inb
(
config
.
icm_address
-
1
)
==
2
:
(
inb
(
SYS_DOORBELL_INTR
(
config
.
doorbell_address
))
&
1
))
{
unsigned
long
flags
;
save_flags
(
flags
);
printk
(
"Ux4F: abort while completed command pending
\n
"
);
restore_flags
(
flags
);
cli
();
spin_lock_irqsave
(
host
->
host_lock
,
flags
);
/* FIXME: Ewww... need to think about passing host around properly */
ultrastor_interrupt
(
0
,
NULL
,
NULL
);
restore_flags
(
flags
);
return
S
CSI_ABORT_SUCCESS
;
/* FIXME - is this correct? -ERY */
spin_unlock_irqrestore
(
host
->
host_lock
,
flags
);
return
S
UCCESS
;
}
#endif
...
...
@@ -904,7 +891,7 @@ int ultrastor_abort(Scsi_Cmnd *SCpnt)
/* aborted == 0xff is the signal that queuecommand has not yet sent
the command. It will notice the new abort flag and fail. */
if
(
old_aborted
==
0xff
)
return
S
CSI_ABORT_S
UCCESS
;
return
SUCCESS
;
/* On 24F, send an abort MSCP request. The adapter will interrupt
and the interrupt handler will call done. */
...
...
@@ -912,18 +899,18 @@ int ultrastor_abort(Scsi_Cmnd *SCpnt)
{
unsigned
long
flags
;
save_flags
(
flags
);
cli
();
spin_lock_irqsave
(
host
->
host_lock
,
flags
);
outl
(
isa_virt_to_bus
(
&
config
.
mscp
[
mscp_index
]),
config
.
ogm_address
);
inb
(
0xc80
);
/* delay */
udelay
(
8
);
outb
(
0x80
,
config
.
ogm_address
-
1
);
outb
(
0x2
,
LCL_DOORBELL_INTR
(
config
.
doorbell_address
));
#if ULTRASTOR_DEBUG & UD_ABORT
log_ultrastor_abort
(
&
config
,
mscp_index
);
printk
(
out
,
ogm_status
,
ogm_addr
,
icm_status
,
icm_addr
);
#endif
restore_flags
(
flags
);
return
SCSI_ABORT_PENDING
;
spin_unlock_irqrestore
(
host
->
host_lock
,
flags
);
/* FIXME: add a wait for the abort to complete */
return
SUCCESS
;
}
#if ULTRASTOR_DEBUG & UD_ABORT
...
...
@@ -953,27 +940,30 @@ int ultrastor_abort(Scsi_Cmnd *SCpnt)
done
=
config
.
mscp
[
mscp_index
].
done
;
config
.
mscp
[
mscp_index
].
done
=
0
;
SCpnt
->
result
=
DID_ABORT
<<
16
;
/* I worry about reentrancy in scsi.c */
/* Take the host lock to guard against scsi layer re-entry */
spin_lock_irqsave
(
host
->
host_lock
,
flags
);
done
(
SCpnt
);
spin_unlock_irqrestore
(
host
->
host_lock
,
flags
);
/* Need to set a timeout here in case command never completes. */
return
S
CSI_ABORT_S
UCCESS
;
return
SUCCESS
;
}
int
ultrastor_reset
(
Scsi_Cmnd
*
SCpnt
,
unsigned
int
reset_flags
)
static
int
ultrastor_host_reset
(
Scsi_Cmnd
*
SCpnt
)
{
unsigned
long
flags
;
register
int
i
;
int
i
;
struct
Scsi_Host
*
host
=
SCpnt
->
host
;
#if (ULTRASTOR_DEBUG & UD_RESET)
printk
(
"US14F: reset: called
\n
"
);
#endif
if
(
config
.
slot
)
return
SCSI_RESET_PUNT
;
/* Do not attempt a reset for the 24f */
save_flags
(
flags
);
cli
();
return
FAILED
;
spin_lock_irqsave
(
host
->
host_lock
,
flags
);
/* Reset the adapter and SCSI bus. The SCSI bus reset can be
inhibited by clearing ultrastor_bus_reset before probe. */
outb
(
0xc0
,
LCL_DOORBELL_INTR
(
config
.
doorbell_address
));
...
...
@@ -1005,7 +995,10 @@ int ultrastor_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags)
#endif
/* FIXME - if the device implements soft resets, then the command
will still be running. ERY */
will still be running. ERY
Even bigger deal with new_eh!
*/
memset
((
unsigned
char
*
)
config
.
aborted
,
0
,
sizeof
config
.
aborted
);
#if ULTRASTOR_MAX_CMDS == 1
...
...
@@ -1014,7 +1007,7 @@ int ultrastor_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags)
config
.
mscp_free
=
~
0
;
#endif
restore_flags
(
flags
);
spin_unlock_irqrestore
(
host
->
host_lock
,
flags
);
return
SCSI_RESET_SUCCESS
;
}
...
...
@@ -1041,7 +1034,7 @@ static void ultrastor_interrupt(int irq, void *dev_id, struct pt_regs *regs)
#if ULTRASTOR_MAX_CMDS > 1
unsigned
int
mscp_index
;
#endif
register
struct
mscp
*
mscp
;
struct
mscp
*
mscp
;
void
(
*
done
)(
Scsi_Cmnd
*
);
Scsi_Cmnd
*
SCtmp
;
...
...
drivers/scsi/ultrastor.h
View file @
9da07cd3
...
...
@@ -13,13 +13,12 @@
#ifndef _ULTRASTOR_H
#define _ULTRASTOR_H
int
ultrastor_detect
(
Scsi_Host_Template
*
);
const
char
*
ultrastor_info
(
struct
Scsi_Host
*
shpnt
);
int
ultrastor_queuecommand
(
Scsi_Cmnd
*
,
void
(
*
done
)(
Scsi_Cmnd
*
));
int
ultrastor_abort
(
Scsi_Cmnd
*
);
int
ultrastor_reset
(
Scsi_Cmnd
*
,
unsigned
int
);
int
ultrastor_biosparam
(
struct
scsi_device
*
,
struct
block_device
*
,
sector_t
,
int
*
);
static
int
ultrastor_detect
(
Scsi_Host_Template
*
);
static
const
char
*
ultrastor_info
(
struct
Scsi_Host
*
shpnt
);
static
int
ultrastor_queuecommand
(
Scsi_Cmnd
*
,
void
(
*
done
)(
Scsi_Cmnd
*
));
static
int
ultrastor_abort
(
Scsi_Cmnd
*
);
static
int
ultrastor_host_reset
(
Scsi_Cmnd
*
);
static
int
ultrastor_biosparam
(
struct
scsi_device
*
,
struct
block_device
*
,
sector_t
,
int
*
);
#define ULTRASTOR_14F_MAX_SG 16
...
...
@@ -35,8 +34,8 @@ int ultrastor_biosparam(struct scsi_device *, struct block_device *,
detect: ultrastor_detect, \
info: ultrastor_info, \
queuecommand: ultrastor_queuecommand, \
abort:
ultrastor_abort, \
reset: ultrastor_reset,
\
eh_abort_handler:
ultrastor_abort, \
eh_host_reset_handler: ultrastor_host_reset,
\
bios_param: ultrastor_biosparam, \
can_queue: ULTRASTOR_MAX_CMDS, \
this_id: 0, \
...
...
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