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
Kirill Smelkov
linux
Commits
98abe783
Commit
98abe783
authored
Oct 12, 2002
by
Alan Cox
Committed by
Linus Torvalds
Oct 12, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] sym53c416 updates
parent
4b3c5bb6
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
55 additions
and
59 deletions
+55
-59
drivers/scsi/sym53c416.c
drivers/scsi/sym53c416.c
+55
-59
No files found.
drivers/scsi/sym53c416.c
View file @
98abe783
...
...
@@ -9,6 +9,8 @@
* Alan Cox <alan@redhat.com> : Cleaned up code formatting
* Fixed an irq locking bug
* Added ISAPnP support
* Bjoern A. Zeeb <bzeeb@zabbadoz.net> : Initial irq locking updates
* Added another card with ISAPnP support
*
* LILO command line usage: sym53c416=<PORTBASE>[,<IRQ>]
*
...
...
@@ -27,6 +29,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/ioport.h>
#include <linux/sched.h>
...
...
@@ -194,18 +197,10 @@ static unsigned int sym53c416_base_3[2] = {0,0};
#endif
/* #define DEBUG */
/* Macro for debugging purposes */
#ifdef DEBUG
#define DEB(x) x
#else
#define DEB(x)
#endif
#define MAXHOSTS 4
#define SG_ADDRESS(buffer) ((char *) (page_address((buffer)->page)+(buffer)->offset))
enum
phases
{
idle
,
...
...
@@ -246,6 +241,8 @@ static void sym53c416_set_transfer_counter(int base, unsigned int len)
outb
((
len
&
0xFF0000
)
>>
16
,
base
+
TC_HIGH
);
}
static
spinlock_t
sym53c416_lock
=
SPIN_LOCK_UNLOCKED
;
/* Returns the number of bytes read */
static
__inline__
unsigned
int
sym53c416_read
(
int
base
,
unsigned
char
*
buffer
,
unsigned
int
len
)
{
...
...
@@ -256,8 +253,7 @@ static __inline__ unsigned int sym53c416_read(int base, unsigned char *buffer, u
int
timeout
=
READ_TIMEOUT
;
/* Do transfer */
save_flags
(
flags
);
cli
();
spin_lock_irqsave
(
&
sym53c416_lock
,
flags
);
while
(
len
&&
timeout
)
{
bytes_left
=
inb
(
base
+
PIO_FIFO_CNT
);
/* Number of bytes in the PIO FIFO */
...
...
@@ -276,17 +272,16 @@ static __inline__ unsigned int sym53c416_read(int base, unsigned char *buffer, u
else
{
i
=
jiffies
+
timeout
;
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
sym53c416_lock
,
flags
);
while
(
jiffies
<
i
&&
(
inb
(
base
+
PIO_INT_REG
)
&
EMPTY
)
&&
timeout
)
if
(
inb
(
base
+
PIO_INT_REG
)
&
SCI
)
timeout
=
0
;
save_flags
(
flags
);
cli
();
spin_lock_irqsave
(
&
sym53c416_lock
,
flags
);
if
(
inb
(
base
+
PIO_INT_REG
)
&
EMPTY
)
timeout
=
0
;
}
}
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
sym53c416_lock
,
flags
);
return
orig_len
-
len
;
}
...
...
@@ -300,8 +295,7 @@ static __inline__ unsigned int sym53c416_write(int base, unsigned char *buffer,
unsigned
int
timeout
=
WRITE_TIMEOUT
;
/* Do transfer */
save_flags
(
flags
);
cli
();
spin_lock_irqsave
(
&
sym53c416_lock
,
flags
);
while
(
len
&&
timeout
)
{
bufferfree
=
PIO_SIZE
-
inb
(
base
+
PIO_FIFO_CNT
);
...
...
@@ -322,16 +316,15 @@ static __inline__ unsigned int sym53c416_write(int base, unsigned char *buffer,
else
{
i
=
jiffies
+
timeout
;
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
sym53c416_lock
,
flags
);
while
(
jiffies
<
i
&&
(
inb
(
base
+
PIO_INT_REG
)
&
FULL
)
&&
timeout
)
;
save_flags
(
flags
);
cli
();
spin_lock_irqsave
(
&
sym53c416_lock
,
flags
);
if
(
inb
(
base
+
PIO_INT_REG
)
&
FULL
)
timeout
=
0
;
}
}
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
sym53c416_lock
,
flags
);
return
orig_len
-
len
;
}
...
...
@@ -449,7 +442,7 @@ static void sym53c416_intr_handle(int irq, void *dev_id, struct pt_regs *regs)
sglist
=
current_command
->
request_buffer
;
while
(
sgcount
--
)
{
tot_trans
+=
sym53c416_write
(
base
,
sglist
->
address
,
sglist
->
length
);
tot_trans
+=
sym53c416_write
(
base
,
SG_ADDRESS
(
sglist
)
,
sglist
->
length
);
sglist
++
;
}
}
...
...
@@ -475,7 +468,7 @@ static void sym53c416_intr_handle(int irq, void *dev_id, struct pt_regs *regs)
sglist
=
current_command
->
request_buffer
;
while
(
sgcount
--
)
{
tot_trans
+=
sym53c416_read
(
base
,
sglist
->
address
,
sglist
->
length
);
tot_trans
+=
sym53c416_read
(
base
,
SG_ADDRESS
(
sglist
)
,
sglist
->
length
);
sglist
++
;
}
}
...
...
@@ -562,7 +555,7 @@ static int sym53c416_probeirq(int base, int scsi_id)
i
=
jiffies
+
20
;
while
(
i
>
jiffies
&&
!
(
inb
(
base
+
STATUS_REG
)
&
SCI
))
barrier
();
if
(
i
<=
jiffies
)
/* timed out */
if
(
time_before_eq
(
i
,
jiffies
))
/* timed out */
return
0
;
/* Get occurred irq */
irq
=
probe_irq_off
(
irqs
);
...
...
@@ -611,10 +604,12 @@ static int sym53c416_test(int base)
}
static
struct
isapnp_device_id
id_table
[]
=
{
static
struct
isapnp_device_id
id_table
[]
__devinitdata
=
{
{
ISAPNP_ANY_ID
,
ISAPNP_ANY_ID
,
ISAPNP_VENDOR
(
'S'
,
'L'
,
'I'
),
ISAPNP_FUNCTION
(
0x4161
),
0
},
{
ISAPNP_ANY_ID
,
ISAPNP_ANY_ID
,
ISAPNP_VENDOR
(
'S'
,
'L'
,
'I'
),
ISAPNP_FUNCTION
(
0x4163
),
0
},
{
0
}
{
ISAPNP_DEVICE_SINGLE_END
}
};
MODULE_DEVICE_TABLE
(
isapnp
,
id_table
);
...
...
@@ -635,7 +630,7 @@ void sym53c416_probe(void)
}
}
int
sym53c416_detect
(
Scsi_Host_Template
*
tpnt
)
int
__init
sym53c416_detect
(
Scsi_Host_Template
*
tpnt
)
{
unsigned
long
flags
;
struct
Scsi_Host
*
shpnt
=
NULL
;
...
...
@@ -674,29 +669,32 @@ int sym53c416_detect(Scsi_Host_Template *tpnt)
#endif
printk
(
KERN_INFO
"sym53c416.c: %s
\n
"
,
VERSION_STRING
);
while
((
idev
=
isapnp_find_dev
(
NULL
,
ISAPNP_VENDOR
(
'S'
,
'L'
,
'I'
),
ISAPNP_FUNCTION
(
0x4163
),
idev
))
!=
NULL
)
{
int
i
[
3
];
if
(
idev
->
prepare
(
idev
)
<
0
)
{
printk
(
KERN_WARNING
"sym53c416: unable to prepare PnP card.
\n
"
);
continue
;
}
if
(
idev
->
activate
(
idev
)
<
0
)
for
(
i
=
0
;
id_table
[
i
].
vendor
!=
0
;
i
++
)
{
while
((
idev
=
isapnp_find_dev
(
NULL
,
id_table
[
i
].
vendor
,
id_table
[
i
].
function
,
idev
))
!=
NULL
)
{
printk
(
KERN_WARNING
"sym53c416: unable to activate PnP card.
\n
"
);
continue
;
}
i
[
0
]
=
2
;
i
[
1
]
=
idev
->
resource
[
0
].
start
;
i
[
2
]
=
idev
->
irq_resource
[
0
].
start
;
printk
(
KERN_INFO
"sym53c416: ISAPnP card found and configured at 0x%X, IRQ %d.
\n
"
,
i
[
1
],
i
[
2
]);
sym53c416_setup
(
NULL
,
i
);
int
i
[
3
];
if
(
idev
->
prepare
(
idev
)
<
0
)
{
printk
(
KERN_WARNING
"sym53c416: unable to prepare PnP card.
\n
"
);
continue
;
}
if
(
idev
->
activate
(
idev
)
<
0
)
{
printk
(
KERN_WARNING
"sym53c416: unable to activate PnP card.
\n
"
);
continue
;
}
i
[
0
]
=
2
;
i
[
1
]
=
idev
->
resource
[
0
].
start
;
i
[
2
]
=
idev
->
irq_resource
[
0
].
start
;
printk
(
KERN_INFO
"sym53c416: ISAPnP card found and configured at 0x%X, IRQ %d.
\n
"
,
i
[
1
],
i
[
2
]);
sym53c416_setup
(
NULL
,
i
);
}
}
sym53c416_probe
();
...
...
@@ -716,13 +714,12 @@ int sym53c416_detect(Scsi_Host_Template *tpnt)
shpnt
=
scsi_register
(
tpnt
,
0
);
if
(
shpnt
==
NULL
)
continue
;
save_flags
(
flags
);
cli
();
spin_lock_irqsave
(
&
sym53c416_lock
,
flags
);
/* FIXME: Request_irq with CLI is not safe */
/* Request for specified IRQ */
if
(
request_irq
(
hosts
[
i
].
irq
,
sym53c416_intr_handle
,
0
,
ID
,
shpnt
))
{
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
sym53c416_lock
,
flags
);
printk
(
KERN_ERR
"sym53c416: Unable to assign IRQ %d
\n
"
,
hosts
[
i
].
irq
);
scsi_unregister
(
shpnt
);
}
...
...
@@ -737,7 +734,7 @@ int sym53c416_detect(Scsi_Host_Template *tpnt)
shpnt
->
this_id
=
hosts
[
i
].
scsi_id
;
sym53c416_init
(
hosts
[
i
].
base
,
hosts
[
i
].
scsi_id
);
count
++
;
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
sym53c416_lock
,
flags
);
}
}
}
...
...
@@ -774,8 +771,7 @@ int sym53c416_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
current_command
->
SCp
.
Status
=
0
;
current_command
->
SCp
.
Message
=
0
;
save_flags
(
flags
);
cli
();
spin_lock_irqsave
(
&
sym53c416_lock
,
flags
);
outb
(
SCpnt
->
target
,
base
+
DEST_BUS_ID
);
/* Set scsi id target */
outb
(
FLUSH_FIFO
,
base
+
COMMAND_REG
);
/* Flush SCSI and PIO FIFO's */
/* Write SCSI command into the SCSI fifo */
...
...
@@ -784,7 +780,7 @@ int sym53c416_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
/* Start selection sequence */
outb
(
SEL_WITHOUT_ATN_SEQ
,
base
+
COMMAND_REG
);
/* Now an interrupt will be generated which we will catch in out interrupt routine */
restore_flags
(
flags
);
spin_unlock_irqrestore
(
&
sym53c416_lock
,
flags
);
return
0
;
}
...
...
@@ -804,7 +800,7 @@ static int sym53c416_command(Scsi_Cmnd *SCpnt)
static
int
sym53c416_abort
(
Scsi_Cmnd
*
SCpnt
)
{
/
/printk("sym53c416_abort\n");
/
* printk("sym53c416_abort\n"); */
/* We don't know how to abort for the moment */
return
SCSI_ABORT_SNOOZE
;
}
...
...
@@ -815,7 +811,7 @@ static int sym53c416_reset(Scsi_Cmnd *SCpnt, unsigned int reset_flags)
int
scsi_id
=
-
1
;
int
i
;
/
/printk("sym53c416_reset\n");
/
* printk("sym53c416_reset\n"); */
base
=
SCpnt
->
host
->
io_port
;
/* search scsi_id */
for
(
i
=
0
;
i
<
host_index
&&
scsi_id
!=
-
1
;
i
++
)
...
...
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