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
c83b4e61
Commit
c83b4e61
authored
Mar 21, 2003
by
Alan Cox
Committed by
Linus Torvalds
Mar 21, 2003
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] gdth update from Intel
parent
8c8373b4
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
1857 additions
and
435 deletions
+1857
-435
drivers/scsi/gdth.c
drivers/scsi/gdth.c
+1133
-167
drivers/scsi/gdth.h
drivers/scsi/gdth.h
+205
-150
drivers/scsi/gdth_ioctl.h
drivers/scsi/gdth_ioctl.h
+205
-2
drivers/scsi/gdth_proc.c
drivers/scsi/gdth_proc.c
+292
-110
drivers/scsi/gdth_proc.h
drivers/scsi/gdth_proc.h
+22
-6
No files found.
drivers/scsi/gdth.c
View file @
c83b4e61
...
...
@@ -4,7 +4,7 @@
* Intel Corporation: Storage RAID Controllers *
* *
* gdth.c *
* Copyright (C) 1995-0
2
ICP vortex, an Intel company, Achim Leubner *
* Copyright (C) 1995-0
3
ICP vortex, an Intel company, Achim Leubner *
* <achim.leubner@intel.com> *
* *
* Additions/Fixes: Boji Tony Kannanthanam *
...
...
@@ -24,11 +24,17 @@
* along with this kernel; if not, write to the Free Software *
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
* *
* Tested with Linux 1.2.13, ..., 2.2.20, ..., 2.4.
18
*
* Tested with Linux 1.2.13, ..., 2.2.20, ..., 2.4.
20
*
* *
* $Log: gdth.c,v $
* Revision 1.61 2002/10/03 09:35:22 boji
* Fixed SCREENSERVICE initialisation in SMP cases.
* Revision 1.62 2003/02/27 15:01:59 achim
* Dynamic DMA mapping implemented
* New (character device) IOCTL interface added
* Other controller related changes made
*
* Revision 1.61 2002/11/08 13:09:52 boji
* Added support for XSCALE based RAID Controllers
* Fixed SCREENSERVICE initialization in SMP cases
* Added checks for gdth_polling before GDTH_HA_LOCK
*
* Revision 1.60 2002/02/05 09:35:22 achim
...
...
@@ -216,7 +222,7 @@
*
* Revision 1.9 1997/09/04 10:07:25 achim
* IO-mapping with virt_to_bus(), gdth_readb(), gdth_writeb(), ...
* register_reboot_notifier() to get a notify on shut
d
own used
* register_reboot_notifier() to get a notify on shutown used
*
* Revision 1.8 1997/04/02 12:14:30 achim
* Version 1.00 (see gdth.h), tested with kernel 2.0.29
...
...
@@ -248,7 +254,7 @@
* Initial revision
*
************************************************************************/
#ident "$Id: gdth.c,v 1.6
0 2002/02/05 09:35:22
achim Exp $"
#ident "$Id: gdth.c,v 1.6
2 2003/02/27 15:01:59
achim Exp $"
/* All GDT Disk Array Controllers are fully supported by this driver.
* This includes the PCI/EISA/ISA SCSI Disk Array Controllers and the
...
...
@@ -300,18 +306,21 @@
*/
/* The meaning of the Scsi_Pointer members in this driver is as follows:
* ptr: Chaining
* this_residual: Command priority
* buffer: Unused
* buffers_residual: Timeout value
* Status: Command status (gdth_do_cmd())
* Message: Additional info (gdth_do_cmd())
* have_data_in: Flag for gdth_wait_completion()
* sent_command: Opcode special command
* phase: Service/parameter/return code special command
* ptr: Chaining
* this_residual: Command priority
* buffer: phys. DMA sense buffer
* dma_handle: phys. DMA buffer (kernel >= 2.4.0)
* buffers_residual: Timeout value
* Status: Command status (gdth_do_cmd()), DMA mem. mappings
* Message: Additional info (gdth_do_cmd()), DMA direction
* have_data_in: Flag for gdth_wait_completion()
* sent_command: Opcode special command
* phase: Service/parameter/return code special command
*/
#error Please convert me to Documentation/DMA-mapping.txt
/* default: activate /proc and character device IOCTL interface */
#define GDTH_IOCTL_PROC
#define GDTH_IOCTL_CHRDEV
#include <linux/module.h>
...
...
@@ -324,6 +333,7 @@
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/in.h>
#include <linux/proc_fs.h>
#include <linux/time.h>
...
...
@@ -340,6 +350,7 @@
#include <asm/dma.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#if LINUX_VERSION_CODE >= 0x020322
#include <linux/spinlock.h>
#elif LINUX_VERSION_CODE >= 0x02015F
...
...
@@ -353,6 +364,9 @@
#endif
#include "scsi.h"
#include "hosts.h"
#if LINUX_VERSION_CODE < 0x020503
#include "sd.h"
#endif
#include "gdth.h"
...
...
@@ -378,7 +392,8 @@ static void gdth_readapp_event(gdth_ha_str *ha, unchar application,
gdth_evt_str
*
estr
);
static
void
gdth_clear_events
(
void
);
static
void
gdth_copy_internal_data
(
Scsi_Cmnd
*
scp
,
char
*
buffer
,
ushort
count
);
static
void
gdth_copy_internal_data
(
int
hanum
,
Scsi_Cmnd
*
scp
,
char
*
buffer
,
ushort
count
);
static
int
gdth_internal_cache_cmd
(
int
hanum
,
Scsi_Cmnd
*
scp
);
static
int
gdth_fill_cache_cmd
(
int
hanum
,
Scsi_Cmnd
*
scp
,
ushort
hdrive
);
...
...
@@ -408,6 +423,13 @@ static void gdth_munmap(void *addr);
static
const
char
*
gdth_ctr_name
(
int
hanum
);
#ifdef GDTH_IOCTL_CHRDEV
static
int
gdth_open
(
struct
inode
*
inode
,
struct
file
*
filep
);
static
int
gdth_close
(
struct
inode
*
inode
,
struct
file
*
filep
);
static
int
gdth_ioctl
(
struct
inode
*
inode
,
struct
file
*
filep
,
unsigned
int
cmd
,
unsigned
long
arg
);
#endif
#if LINUX_VERSION_CODE >= 0x010300
static
void
gdth_flush
(
int
hanum
);
#if LINUX_VERSION_CODE >= 0x020100
...
...
@@ -604,6 +626,9 @@ static unchar gdth_write_through = FALSE; /* write through */
static
gdth_evt_str
ebuffer
[
MAX_EVENTS
];
/* event buffer */
static
int
elastidx
;
static
int
eoldidx
;
#ifdef GDTH_IOCTL_CHRDEV
static
int
major
;
#endif
#define DIN 1
/* IN data direction */
#define DOU 2
/* OUT data direction */
...
...
@@ -641,24 +666,35 @@ static unchar gdth_direction_tab[0x100] = {
#define __init
#endif
#if LINUX_VERSION_CODE >= 0x02015F
#if LINUX_VERSION_CODE >= 0x020503
#define GDTH_INIT_LOCK_HA(ha) spin_lock_init(&(ha)->smp_lock)
#define GDTH_LOCK_HA(ha,flags) spin_lock_irqsave(&(ha)->smp_lock,flags)
#define GDTH_UNLOCK_HA(ha,flags) spin_unlock_irqrestore(&(ha)->smp_lock,flags)
#define GDTH_LOCK_SCSI_DONE(dev, flags) spin_lock_irqsave(dev->host_lock,flags)
#define GDTH_UNLOCK_SCSI_DONE(dev, flags) spin_unlock_irqrestore(dev->host_lock,flags)
#define GDTH_LOCK_SCSI_DOCMD(dev) spin_lock_irq(dev->host_lock)
#define GDTH_UNLOCK_SCSI_DOCMD(dev) spin_unlock_irq(dev->host_lock)
#elif LINUX_VERSION_CODE >= 0x02015F
#define GDTH_INIT_LOCK_HA(ha) spin_lock_init(&(ha)->smp_lock)
#define GDTH_LOCK_HA(ha,flags) spin_lock_irqsave(&(ha)->smp_lock,flags)
#define GDTH_UNLOCK_HA(ha,flags) spin_unlock_irqrestore(&(ha)->smp_lock,flags)
#define GDTH_LOCK_SCSI_DONE(dev, flags) spin_lock_irqsave(dev->host_lock,flags)
#define GDTH_UNLOCK_SCSI_DONE(flags) spin_unlock_irqrestore(dev->host_lock,flags)
#define GDTH_LOCK_SCSI_DOCMD(dev) spin_lock_irq(dev->host_lock)
#define GDTH_UNLOCK_SCSI_DOCMD(dev) spin_unlock_irq(dev->host_lock)
#define GDTH_LOCK_SCSI_DONE(flags) spin_lock_irqsave(&io_request_lock,flags)
#define GDTH_UNLOCK_SCSI_DONE(flags) spin_unlock_irqrestore(&io_request_lock,flags)
#define GDTH_LOCK_SCSI_DOCMD() spin_lock_irq(&io_request_lock)
#define GDTH_UNLOCK_SCSI_DOCMD() spin_unlock_irq(&io_request_lock)
#else
#define GDTH_INIT_LOCK_HA(ha) do {} while (0)
#define GDTH_LOCK_HA(ha,flags) do {save_flags(flags); cli();} while (0)
#define GDTH_UNLOCK_HA(ha,flags) do {restore_flags(flags);} while (0)
#define GDTH_LOCK_SCSI_DONE(
dev,
flags) do {} while (0)
#define GDTH_UNLOCK_SCSI_DONE(
dev,
flags) do {} while (0)
#define GDTH_LOCK_SCSI_DOCMD(
dev
) do {} while (0)
#define GDTH_UNLOCK_SCSI_DOCMD(
dev
) do {} while (0)
#define GDTH_LOCK_SCSI_DONE(flags) do {} while (0)
#define GDTH_UNLOCK_SCSI_DONE(flags) do {} while (0)
#define GDTH_LOCK_SCSI_DOCMD() do {} while (0)
#define GDTH_UNLOCK_SCSI_DOCMD() do {} while (0)
#endif
/* LILO and modprobe/insmod parameters */
...
...
@@ -702,10 +738,21 @@ MODULE_PARM(rescan, "i");
MODULE_PARM
(
virt_ctr
,
"i"
);
MODULE_PARM
(
shared_access
,
"i"
);
MODULE_AUTHOR
(
"Achim Leubner"
);
#endif
#if LINUX_VERSION_CODE >= 0x02040B
MODULE_LICENSE
(
"GPL"
);
#endif
#endif
#ifdef GDTH_IOCTL_CHRDEV
/* ioctl interface */
static
struct
file_operations
gdth_fops
=
{
ioctl:
gdth_ioctl
,
open:
gdth_open
,
release:
gdth_close
,
};
#endif
/* /proc support */
#if LINUX_VERSION_CODE >= 0x010300
#include <linux/stat.h>
...
...
@@ -813,6 +860,8 @@ GDTH_INITFUNC(static int, gdth_search_pci(gdth_pci_str *pcistr))
PCI_DEVICE_ID_VORTEX_GDTNEWRX
);
gdth_search_dev
(
pcistr
,
&
cnt
,
PCI_VENDOR_ID_INTEL
,
PCI_DEVICE_ID_INTEL_SRC
);
gdth_search_dev
(
pcistr
,
&
cnt
,
PCI_VENDOR_ID_INTEL
,
PCI_DEVICE_ID_INTEL_SRC_XSCALE
);
return
cnt
;
}
...
...
@@ -820,10 +869,11 @@ GDTH_INITFUNC(static int, gdth_search_pci(gdth_pci_str *pcistr))
/* Vortex only makes RAID controllers.
* We do not really want to specify all 550 ids here, so wildcard match.
*/
static
struct
pci_device_id
gdthtable
[]
=
{
{
PCI_VENDOR_ID_VORTEX
,
PCI_ANY_ID
,
PCI_ANY_ID
,
PCI_ANY_ID
},
{
PCI_VENDOR_ID_INTEL
,
PCI_DEVICE_ID_INTEL_SRC
,
PCI_ANY_ID
,
PCI_ANY_ID
},
{
0
}
static
struct
pci_device_id
gdthtable
[]
__devinitdata
=
{
{
PCI_VENDOR_ID_VORTEX
,
PCI_ANY_ID
,
PCI_ANY_ID
,
PCI_ANY_ID
},
{
PCI_VENDOR_ID_INTEL
,
PCI_DEVICE_ID_INTEL_SRC
,
PCI_ANY_ID
,
PCI_ANY_ID
},
{
PCI_VENDOR_ID_INTEL
,
PCI_DEVICE_ID_INTEL_SRC_XSCALE
,
PCI_ANY_ID
,
PCI_ANY_ID
},
{
0
}
};
MODULE_DEVICE_TABLE
(
pci
,
gdthtable
);
#endif
...
...
@@ -1235,6 +1285,9 @@ GDTH_INITFUNC(static int, gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha))
ha
->
stype
=
(
ulong32
)
pcistr
->
device_id
;
ha
->
subdevice_id
=
pcistr
->
subdevice_id
;
ha
->
irq
=
pcistr
->
irq
;
#if LINUX_VERSION_CODE >= 0x20400
ha
->
pdev
=
pcistr
->
pdev
;
#endif
if
(
ha
->
stype
<=
PCI_DEVICE_ID_VORTEX_GDT6000B
)
{
/* GDT6000/B */
TRACE2
((
"init_pci() dpmem %lx irq %d
\n
"
,
pcistr
->
dpmem
,
ha
->
irq
));
...
...
@@ -1511,6 +1564,11 @@ GDTH_INITFUNC(static int, gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha))
PCI_ROM_ADDRESS
,
rom_addr
);
#endif
/* Ensure that it is safe to access the non HW portions of DPMEM.
* Aditional check needed for Xscale based RAID controllers */
while
(
((
int
)
gdth_readb
(
&
((
gdt6m_dpram_str
*
)
ha
->
brd
)
->
i960r
.
sema0_reg
)
)
&
3
)
gdth_delay
(
1
);
/* check and reset interface area */
dp6m_ptr
=
(
gdt6m_dpram_str
*
)
ha
->
brd
;
gdth_writel
(
DPMEM_MAGIC
,
&
dp6m_ptr
->
u
);
...
...
@@ -1840,7 +1898,7 @@ static void gdth_release_event(int hanum)
if
(
ha
->
type
==
GDT_EISA
)
{
if
(
ha
->
pccb
->
OpCode
==
GDT_INIT
)
/* store DMA buffer */
outl
(
virt_to_bus
(
ha
->
pccb
)
,
ha
->
bmic
+
MAILBOXREG
);
outl
(
ha
->
ccb_phys
,
ha
->
bmic
+
MAILBOXREG
);
outb
(
ha
->
pccb
->
Service
,
ha
->
bmic
+
LDOORREG
);
}
else
if
(
ha
->
type
==
GDT_ISA
)
{
gdth_writeb
(
0
,
&
((
gdt2_dpram_str
*
)
ha
->
brd
)
->
io
.
event
);
...
...
@@ -1916,7 +1974,7 @@ static int gdth_internal_cmd(int hanum,unchar service,ushort opcode,ulong32 p1,
cmd_ptr
->
u
.
ioctl
.
subfunc
=
p1
;
cmd_ptr
->
u
.
ioctl
.
channel
=
p2
;
cmd_ptr
->
u
.
ioctl
.
param_size
=
(
ushort
)
p3
;
cmd_ptr
->
u
.
ioctl
.
p_param
=
virt_to_bus
(
ha
->
pscratch
)
;
cmd_ptr
->
u
.
ioctl
.
p_param
=
ha
->
scratch_phys
;
}
else
{
cmd_ptr
->
u
.
cache
.
DeviceNo
=
(
ushort
)
p1
;
cmd_ptr
->
u
.
cache
.
BlockNo
=
p2
;
...
...
@@ -1965,6 +2023,8 @@ GDTH_INITFUNC(static int, gdth_search_drives(int hanum))
gdth_raw_iochan_str
*
iocr
;
gdth_arcdl_str
*
alst
;
gdth_alist_str
*
alst2
;
gdth_oem_str_ioctl
*
oemstr
;
#ifdef GDTH_RTC
unchar
rtc
[
12
];
ulong
flags
;
...
...
@@ -2233,6 +2293,27 @@ GDTH_INITFUNC(static int, gdth_search_drives(int hanum))
}
}
/* Determine OEM string using IOCTL */
oemstr
=
(
gdth_oem_str_ioctl
*
)
ha
->
pscratch
;
oemstr
->
params
.
ctl_version
=
0x01
;
oemstr
->
params
.
buffer_size
=
sizeof
(
oemstr
->
text
);
if
(
gdth_internal_cmd
(
hanum
,
CACHESERVICE
,
GDT_IOCTL
,
CACHE_READ_OEM_STRING_RECORD
,
INVALID_CHANNEL
,
sizeof
(
gdth_oem_str_ioctl
)))
{
TRACE2
((
"gdth_search_drives(): CACHE_READ_OEM_STRING_RECORD OK
\n
"
));
printk
(
"GDT CTR%d Vendor: %s
\n
"
,
hanum
,
oemstr
->
text
.
oem_company_name
);
/* Save the Host Drive inquiry data */
strncpy
(
ha
->
oem_name
,
oemstr
->
text
.
scsi_host_drive_inquiry_vendor_id
,
7
);
ha
->
oem_name
[
7
]
=
'\0'
;
}
else
{
/* Old method, based on PCI ID */
TRACE2
((
"gdth_search_drives(): CACHE_READ_OEM_STRING_RECORD failed
\n
"
));
if
(
ha
->
oem_id
==
OEM_ID_INTEL
)
strcpy
(
ha
->
oem_name
,
"Intel "
);
else
strcpy
(
ha
->
oem_name
,
"ICP "
);
}
/* scanning for host drives */
for
(
i
=
0
;
i
<
cdev_cnt
;
++
i
)
gdth_analyse_hdrive
(
hanum
,
i
);
...
...
@@ -2313,8 +2394,13 @@ static void gdth_putq(int hanum,Scsi_Cmnd *scp,unchar priority)
GDTH_LOCK_HA
(
ha
,
flags
);
scp
->
SCp
.
this_residual
=
(
int
)
priority
;
#if LINUX_VERSION_CODE >= 0x02053C
b
=
virt_ctr
?
NUMDATA
(
scp
->
device
->
host
)
->
busnum
:
scp
->
device
->
channel
;
t
=
scp
->
device
->
id
;
#else
b
=
virt_ctr
?
NUMDATA
(
scp
->
host
)
->
busnum
:
scp
->
channel
;
t
=
scp
->
target
;
#endif
#if LINUX_VERSION_CODE >= 0x010300
if
(
priority
>=
DEFAULT_PRI
)
{
if
((
b
!=
ha
->
virt_bus
&&
ha
->
raw
[
BUS_L2P
(
ha
,
b
)].
lock
)
||
...
...
@@ -2357,7 +2443,7 @@ static void gdth_next(int hanum)
register
gdth_ha_str
*
ha
;
register
Scsi_Cmnd
*
pscp
;
register
Scsi_Cmnd
*
nscp
;
unchar
b
,
t
,
firsttime
;
unchar
b
,
t
,
l
,
firsttime
;
unchar
this_cmd
,
next_cmd
;
ulong
flags
=
0
;
int
cmd_index
;
...
...
@@ -2365,7 +2451,7 @@ static void gdth_next(int hanum)
TRACE
((
"gdth_next() hanum %d
\n
"
,
hanum
));
ha
=
HADATA
(
gdth_ctr_tab
[
hanum
]);
if
(
!
gdth_polling
)
GDTH_LOCK_HA
(
ha
,
flags
);
GDTH_LOCK_HA
(
ha
,
flags
);
ha
->
cmd_cnt
=
ha
->
cmd_offs_dpmem
=
0
;
this_cmd
=
firsttime
=
TRUE
;
...
...
@@ -2375,8 +2461,15 @@ static void gdth_next(int hanum)
for
(
nscp
=
pscp
=
ha
->
req_first
;
nscp
;
nscp
=
(
Scsi_Cmnd
*
)
nscp
->
SCp
.
ptr
)
{
if
(
nscp
!=
pscp
&&
nscp
!=
(
Scsi_Cmnd
*
)
pscp
->
SCp
.
ptr
)
pscp
=
(
Scsi_Cmnd
*
)
pscp
->
SCp
.
ptr
;
#if LINUX_VERSION_CODE >= 0x02053C
b
=
virt_ctr
?
NUMDATA
(
nscp
->
device
->
host
)
->
busnum
:
nscp
->
device
->
channel
;
t
=
nscp
->
device
->
id
;
l
=
nscp
->
device
->
lun
;
#else
b
=
virt_ctr
?
NUMDATA
(
nscp
->
host
)
->
busnum
:
nscp
->
channel
;
t
=
nscp
->
target
;
l
=
nscp
->
lun
;
#endif
if
(
nscp
->
SCp
.
this_residual
>=
DEFAULT_PRI
)
{
if
((
b
!=
ha
->
virt_bus
&&
ha
->
raw
[
BUS_L2P
(
ha
,
b
)].
lock
)
||
(
b
==
ha
->
virt_bus
&&
t
<
MAX_HDRIVES
&&
ha
->
hdr
[
t
].
lock
))
...
...
@@ -2404,16 +2497,16 @@ static void gdth_next(int hanum)
nscp
->
SCp
.
phase
=
CACHESERVICE
;
/* default: cache svc. */
if
(
nscp
->
cmnd
[
0
]
==
TEST_UNIT_READY
)
{
TRACE2
((
"TEST_UNIT_READY Bus %d Id %d LUN %d
\n
"
,
b
,
t
,
nscp
->
lun
));
b
,
t
,
l
));
/* TEST_UNIT_READY -> set scan mode */
if
((
ha
->
scan_mode
&
0x0f
)
==
0
)
{
if
(
b
==
0
&&
t
==
0
&&
nscp
->
device
->
lun
==
0
)
{
if
(
b
==
0
&&
t
==
0
&&
l
==
0
)
{
ha
->
scan_mode
|=
1
;
TRACE2
((
"Scan mode: 0x%x
\n
"
,
ha
->
scan_mode
));
}
}
else
if
((
ha
->
scan_mode
&
0x0f
)
==
1
)
{
if
(
b
==
0
&&
((
t
==
0
&&
nscp
->
device
->
lun
==
1
)
||
(
t
==
1
&&
nscp
->
device
->
lun
==
0
)))
{
if
(
b
==
0
&&
((
t
==
0
&&
l
==
1
)
||
(
t
==
1
&&
l
==
0
)))
{
nscp
->
SCp
.
sent_command
=
GDT_SCAN_START
;
nscp
->
SCp
.
phase
=
((
ha
->
scan_mode
&
0x10
?
1
:
0
)
<<
8
)
|
SCSIRAWSERVICE
;
...
...
@@ -2465,7 +2558,7 @@ static void gdth_next(int hanum)
/* io_request_lock already active ! */
nscp
->
scsi_done
(
nscp
);
if
(
!
gdth_polling
)
GDTH_LOCK_HA
(
ha
,
flags
);
GDTH_LOCK_HA
(
ha
,
flags
);
}
}
}
else
...
...
@@ -2483,19 +2576,19 @@ static void gdth_next(int hanum)
this_cmd
=
FALSE
;
else
ha
->
raw
[
BUS_L2P
(
ha
,
b
)].
io_cnt
[
t
]
++
;
}
else
if
(
t
>=
MAX_HDRIVES
||
!
ha
->
hdr
[
t
].
present
||
nscp
->
device
->
lun
!=
0
)
{
}
else
if
(
t
>=
MAX_HDRIVES
||
!
ha
->
hdr
[
t
].
present
||
l
!=
0
)
{
TRACE2
((
"Command 0x%x to bus %d id %d lun %d -> IGNORE
\n
"
,
nscp
->
cmnd
[
0
],
b
,
t
,
nscp
->
lun
));
nscp
->
cmnd
[
0
],
b
,
t
,
l
));
nscp
->
result
=
DID_BAD_TARGET
<<
16
;
if
(
!
nscp
->
SCp
.
have_data_in
)
nscp
->
SCp
.
have_data_in
++
;
else
{
if
(
!
gdth_polling
)
GDTH_UNLOCK_HA
(
ha
,
flags
);
GDTH_UNLOCK_HA
(
ha
,
flags
);
/* io_request_lock already active ! */
nscp
->
scsi_done
(
nscp
);
if
(
!
gdth_polling
)
GDTH_LOCK_HA
(
ha
,
flags
);
GDTH_LOCK_HA
(
ha
,
flags
);
}
}
else
{
switch
(
nscp
->
cmnd
[
0
])
{
...
...
@@ -2521,20 +2614,20 @@ static void gdth_next(int hanum)
if
(
!
nscp
->
SCp
.
have_data_in
)
nscp
->
SCp
.
have_data_in
++
;
else
{
if
(
!
gdth_polling
)
GDTH_UNLOCK_HA
(
ha
,
flags
);
if
(
!
gdth_polling
)
GDTH_UNLOCK_HA
(
ha
,
flags
);
/* io_request_lock already active ! */
nscp
->
scsi_done
(
nscp
);
if
(
!
gdth_polling
)
GDTH_LOCK_HA
(
ha
,
flags
);
if
(
!
gdth_polling
)
GDTH_LOCK_HA
(
ha
,
flags
);
}
}
else
if
(
gdth_internal_cache_cmd
(
hanum
,
nscp
))
{
if
(
!
gdth_polling
)
GDTH_UNLOCK_HA
(
ha
,
flags
);
GDTH_UNLOCK_HA
(
ha
,
flags
);
/* io_request_lock already active ! */
nscp
->
scsi_done
(
nscp
);
if
(
!
gdth_polling
)
GDTH_LOCK_HA
(
ha
,
flags
);
GDTH_LOCK_HA
(
ha
,
flags
);
}
break
;
...
...
@@ -2549,12 +2642,12 @@ static void gdth_next(int hanum)
if
(
!
nscp
->
SCp
.
have_data_in
)
nscp
->
SCp
.
have_data_in
++
;
else
{
if
(
!
gdth_polling
)
GDTH_UNLOCK_HA
(
ha
,
flags
);
if
(
!
gdth_polling
)
GDTH_UNLOCK_HA
(
ha
,
flags
);
/* io_request_lock already active ! */
nscp
->
scsi_done
(
nscp
);
if
(
!
gdth_polling
)
GDTH_LOCK_HA
(
ha
,
flags
);
if
(
!
gdth_polling
)
GDTH_LOCK_HA
(
ha
,
flags
);
}
}
else
{
nscp
->
cmnd
[
3
]
=
(
ha
->
hdr
[
t
].
devtype
&
1
)
?
1
:
0
;
...
...
@@ -2589,12 +2682,12 @@ static void gdth_next(int hanum)
if
(
!
nscp
->
SCp
.
have_data_in
)
nscp
->
SCp
.
have_data_in
++
;
else
{
if
(
!
gdth_polling
)
GDTH_UNLOCK_HA
(
ha
,
flags
);
if
(
!
gdth_polling
)
GDTH_UNLOCK_HA
(
ha
,
flags
);
/* io_request_lock already active ! */
nscp
->
scsi_done
(
nscp
);
if
(
!
gdth_polling
)
GDTH_LOCK_HA
(
ha
,
flags
);
if
(
!
gdth_polling
)
GDTH_LOCK_HA
(
ha
,
flags
);
}
}
else
if
(
!
(
cmd_index
=
gdth_fill_cache_cmd
(
hanum
,
nscp
,
t
)))
this_cmd
=
FALSE
;
...
...
@@ -2611,11 +2704,11 @@ static void gdth_next(int hanum)
nscp
->
SCp
.
have_data_in
++
;
else
{
if
(
!
gdth_polling
)
GDTH_UNLOCK_HA
(
ha
,
flags
);
GDTH_UNLOCK_HA
(
ha
,
flags
);
/* io_request_lock already active ! */
nscp
->
scsi_done
(
nscp
);
if
(
!
gdth_polling
)
GDTH_LOCK_HA
(
ha
,
flags
);
GDTH_LOCK_HA
(
ha
,
flags
);
}
break
;
}
...
...
@@ -2636,7 +2729,7 @@ static void gdth_next(int hanum)
}
if
(
!
gdth_polling
)
GDTH_UNLOCK_HA
(
ha
,
flags
);
GDTH_UNLOCK_HA
(
ha
,
flags
);
if
(
gdth_polling
&&
ha
->
cmd_cnt
>
0
)
{
if
(
!
gdth_wait
(
hanum
,
cmd_index
,
POLL_TIMEOUT
))
...
...
@@ -2645,27 +2738,54 @@ static void gdth_next(int hanum)
}
}
static
void
gdth_copy_internal_data
(
Scsi_Cmnd
*
scp
,
char
*
buffer
,
ushort
count
)
static
void
gdth_copy_internal_data
(
int
hanum
,
Scsi_Cmnd
*
scp
,
char
*
buffer
,
ushort
count
)
{
ushort
cpcount
,
i
;
ushort
cpsum
,
cpnow
;
struct
scatterlist
*
sl
;
gdth_ha_str
*
ha
;
int
sgcnt
;
char
*
address
;
cpcount
=
count
<=
(
ushort
)
scp
->
bufflen
?
count
:
(
ushort
)
scp
->
bufflen
;
ha
=
HADATA
(
gdth_ctr_tab
[
hanum
]);
if
(
scp
->
use_sg
)
{
sl
=
(
struct
scatterlist
*
)
scp
->
request_buffer
;
for
(
i
=
0
,
cpsum
=
0
;
i
<
scp
->
use_sg
;
++
i
,
++
sl
)
{
cpnow
=
(
ushort
)
sl
->
length
;
#if LINUX_VERSION_CODE >= 0x020400
sgcnt
=
pci_map_sg
(
ha
->
pdev
,
sl
,
scp
->
use_sg
,
PCI_DMA_FROMDEVICE
);
for
(
i
=
0
,
cpsum
=
0
;
i
<
sgcnt
;
++
i
,
++
sl
)
{
cpnow
=
(
ushort
)
sg_dma_len
(
sl
);
TRACE
((
"copy_internal() now %d sum %d count %d %d
\n
"
,
cpnow
,
cpsum
,
cpcount
,(
ushort
)
scp
->
bufflen
));
if
(
cpsum
+
cpnow
>
cpcount
)
cpnow
=
cpcount
-
cpsum
;
cpsum
+=
cpnow
;
memcpy
((
char
*
)
sl
->
address
,
buffer
,
cpnow
);
address
=
(
char
*
)
phys_to_virt
(
sg_dma_address
(
sl
));
memcpy
(
address
,
buffer
,
cpnow
);
if
(
cpsum
==
cpcount
)
break
;
buffer
+=
cpnow
;
}
pci_unmap_sg
(
ha
->
pdev
,
scp
->
request_buffer
,
scp
->
use_sg
,
PCI_DMA_FROMDEVICE
);
#else
sgcnt
=
scp
->
use_sg
;
for
(
i
=
0
,
cpsum
=
0
;
i
<
sgcnt
;
++
i
,
++
sl
)
{
cpnow
=
(
ushort
)
sl
->
length
;
TRACE
((
"copy_internal() now %d sum %d count %d %d
\n
"
,
cpnow
,
cpsum
,
cpcount
,(
ushort
)
scp
->
bufflen
));
if
(
cpsum
+
cpnow
>
cpcount
)
cpnow
=
cpcount
-
cpsum
;
cpsum
+=
cpnow
;
address
=
(
char
*
)
sl
->
address
;
memcpy
(
address
,
buffer
,
cpnow
);
if
(
cpsum
==
cpcount
)
break
;
buffer
+=
cpnow
;
}
#endif
}
else
{
TRACE
((
"copy_internal() count %d
\n
"
,
cpcount
));
memcpy
((
char
*
)
scp
->
request_buffer
,
buffer
,
cpcount
);
...
...
@@ -2682,7 +2802,11 @@ static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp)
gdth_modep_data
mpd
;
ha
=
HADATA
(
gdth_ctr_tab
[
hanum
]);
#if LINUX_VERSION_CODE >= 0x02053C
t
=
scp
->
device
->
id
;
#else
t
=
scp
->
target
;
#endif
TRACE
((
"gdth_internal_cache_cmd() cmd 0x%x hdrive %d
\n
"
,
scp
->
cmnd
[
0
],
t
));
...
...
@@ -2706,13 +2830,10 @@ static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp)
inq
.
version
=
2
;
inq
.
resp_aenc
=
2
;
inq
.
add_length
=
32
;
if
(
ha
->
oem_id
==
OEM_ID_INTEL
)
strcpy
(
inq
.
vendor
,
"Intel "
);
else
strcpy
(
inq
.
vendor
,
"ICP "
);
strcpy
(
inq
.
vendor
,
ha
->
oem_name
);
sprintf
(
inq
.
product
,
"Host Drive #%02d"
,
t
);
strcpy
(
inq
.
revision
,
" "
);
gdth_copy_internal_data
(
scp
,(
char
*
)
&
inq
,
sizeof
(
gdth_inq_data
));
gdth_copy_internal_data
(
hanum
,
scp
,(
char
*
)
&
inq
,
sizeof
(
gdth_inq_data
));
break
;
case
REQUEST_SENSE
:
...
...
@@ -2722,7 +2843,7 @@ static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp)
sd
.
key
=
NO_SENSE
;
sd
.
info
=
0
;
sd
.
add_length
=
0
;
gdth_copy_internal_data
(
scp
,(
char
*
)
&
sd
,
sizeof
(
gdth_sense_data
));
gdth_copy_internal_data
(
hanum
,
scp
,(
char
*
)
&
sd
,
sizeof
(
gdth_sense_data
));
break
;
case
MODE_SENSE
:
...
...
@@ -2734,14 +2855,14 @@ static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp)
mpd
.
bd
.
block_length
[
0
]
=
(
SECTOR_SIZE
&
0x00ff0000
)
>>
16
;
mpd
.
bd
.
block_length
[
1
]
=
(
SECTOR_SIZE
&
0x0000ff00
)
>>
8
;
mpd
.
bd
.
block_length
[
2
]
=
(
SECTOR_SIZE
&
0x000000ff
);
gdth_copy_internal_data
(
scp
,(
char
*
)
&
mpd
,
sizeof
(
gdth_modep_data
));
gdth_copy_internal_data
(
hanum
,
scp
,(
char
*
)
&
mpd
,
sizeof
(
gdth_modep_data
));
break
;
case
READ_CAPACITY
:
TRACE2
((
"Read capacity hdrive %d
\n
"
,
t
));
rdc
.
last_block_no
=
ntohl
(
ha
->
hdr
[
t
].
size
-
1
);
rdc
.
block_length
=
ntohl
(
SECTOR_SIZE
);
gdth_copy_internal_data
(
scp
,(
char
*
)
&
rdc
,
sizeof
(
gdth_rdcap_data
));
gdth_copy_internal_data
(
hanum
,
scp
,(
char
*
)
&
rdc
,
sizeof
(
gdth_rdcap_data
));
break
;
default:
...
...
@@ -2766,8 +2887,8 @@ static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive)
register
gdth_cmd_str
*
cmdp
;
struct
scatterlist
*
sl
;
ushort
i
,
cnt
;
ulong32
no
;
int
cmd_index
,
read_write
;
ulong32
no
,
phys_addr
;
int
cmd_index
,
read_write
,
sgcnt
;
ha
=
HADATA
(
gdth_ctr_tab
[
hanum
]);
cmdp
=
ha
->
pccb
;
...
...
@@ -2789,7 +2910,7 @@ static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive)
gdth_set_sema0
(
hanum
);
/* fill command */
read_write
=
FALSE
;
read_write
=
0
;
if
(
scp
->
SCp
.
sent_command
!=
-
1
)
cmdp
->
OpCode
=
scp
->
SCp
.
sent_command
;
/* special cache cmd. */
else
if
(
scp
->
cmnd
[
0
]
==
RESERVE
)
...
...
@@ -2803,15 +2924,16 @@ static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive)
cmdp
->
OpCode
=
GDT_UNMOUNT
;
else
cmdp
->
OpCode
=
GDT_FLUSH
;
}
else
if
(
scp
->
cmnd
[
0
]
==
WRITE_6
||
scp
->
cmnd
[
0
]
==
WRITE_10
)
{
read_write
=
TRUE
;
}
else
if
(
scp
->
cmnd
[
0
]
==
WRITE_6
||
scp
->
cmnd
[
0
]
==
WRITE_10
||
scp
->
cmnd
[
0
]
==
WRITE_12
)
{
read_write
=
1
;
if
(
gdth_write_through
||
((
ha
->
hdr
[
hdrive
].
rw_attribs
&
1
)
&&
(
ha
->
cache_feat
&
GDT_WR_THROUGH
)))
cmdp
->
OpCode
=
GDT_WRITE_THR
;
else
cmdp
->
OpCode
=
GDT_WRITE
;
}
else
{
read_write
=
TRUE
;
read_write
=
2
;
cmdp
->
OpCode
=
GDT_READ
;
}
...
...
@@ -2835,10 +2957,22 @@ static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive)
if
(
scp
->
use_sg
)
{
cmdp
->
u
.
cache
.
DestAddr
=
0xffffffff
;
sl
=
(
struct
scatterlist
*
)
scp
->
request_buffer
;
for
(
i
=
0
;
i
<
scp
->
use_sg
;
++
i
,
++
sl
)
{
sgcnt
=
scp
->
use_sg
;
#if LINUX_VERSION_CODE >= 0x020400
scp
->
SCp
.
Status
=
GDTH_MAP_SG
;
scp
->
SCp
.
Message
=
(
read_write
==
1
?
PCI_DMA_TODEVICE
:
PCI_DMA_FROMDEVICE
);
sgcnt
=
pci_map_sg
(
ha
->
pdev
,
sl
,
scp
->
use_sg
,
scp
->
SCp
.
Message
);
for
(
i
=
0
;
i
<
sgcnt
;
++
i
,
++
sl
)
{
cmdp
->
u
.
cache
.
sg_lst
[
i
].
sg_ptr
=
sg_dma_address
(
sl
);
cmdp
->
u
.
cache
.
sg_lst
[
i
].
sg_len
=
sg_dma_len
(
sl
);
}
#else
for
(
i
=
0
;
i
<
sgcnt
;
++
i
,
++
sl
)
{
cmdp
->
u
.
cache
.
sg_lst
[
i
].
sg_ptr
=
virt_to_bus
(
sl
->
address
);
cmdp
->
u
.
cache
.
sg_lst
[
i
].
sg_len
=
(
ulong32
)
sl
->
length
;
}
#endif
cmdp
->
u
.
cache
.
sg_canz
=
(
ulong32
)
i
;
#ifdef GDTH_STATISTICS
...
...
@@ -2850,15 +2984,24 @@ static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive)
if
(
i
<
GDTH_MAXSG
)
cmdp
->
u
.
cache
.
sg_lst
[
i
].
sg_len
=
0
;
}
else
{
#if LINUX_VERSION_CODE >= 0x020400
scp
->
SCp
.
Status
=
GDTH_MAP_SINGLE
;
scp
->
SCp
.
Message
=
(
read_write
==
1
?
PCI_DMA_TODEVICE
:
PCI_DMA_FROMDEVICE
);
phys_addr
=
pci_map_single
(
ha
->
pdev
,
scp
->
request_buffer
,
scp
->
request_bufflen
,
scp
->
SCp
.
Message
);
scp
->
SCp
.
dma_handle
=
phys_addr
;
#else
phys_addr
=
virt_to_bus
(
scp
->
request_buffer
);
#endif
if
(
ha
->
cache_feat
&
SCATTER_GATHER
)
{
cmdp
->
u
.
cache
.
DestAddr
=
0xffffffff
;
cmdp
->
u
.
cache
.
sg_canz
=
1
;
cmdp
->
u
.
cache
.
sg_lst
[
0
].
sg_ptr
=
virt_to_bus
(
scp
->
request_buffer
);
cmdp
->
u
.
cache
.
sg_lst
[
0
].
sg_ptr
=
phys_addr
;
cmdp
->
u
.
cache
.
sg_lst
[
0
].
sg_len
=
scp
->
request_bufflen
;
cmdp
->
u
.
cache
.
sg_lst
[
1
].
sg_len
=
0
;
}
else
{
cmdp
->
u
.
cache
.
DestAddr
=
virt_to_bus
(
scp
->
request_buffer
)
;
cmdp
->
u
.
cache
.
DestAddr
=
phys_addr
;
cmdp
->
u
.
cache
.
sg_canz
=
0
;
}
}
...
...
@@ -2896,12 +3039,18 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b)
register
gdth_cmd_str
*
cmdp
;
struct
scatterlist
*
sl
;
ushort
i
;
int
cmd_index
;
ulong32
phys_addr
,
sense_paddr
;
int
cmd_index
,
sgcnt
;
unchar
t
,
l
;
ha
=
HADATA
(
gdth_ctr_tab
[
hanum
]);
#if LINUX_VERSION_CODE >= 0x02053C
t
=
scp
->
device
->
id
;
l
=
scp
->
device
->
lun
;
#else
t
=
scp
->
target
;
l
=
scp
->
lun
;
#endif
cmdp
=
ha
->
pccb
;
TRACE
((
"gdth_fill_raw_cmd() cmd 0x%x bus %d ID %d LUN %d
\n
"
,
scp
->
cmnd
[
0
],
b
,
t
,
l
));
...
...
@@ -2931,6 +3080,13 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b)
/* evaluate command size */
ha
->
cmd_len
=
GDTOFFSOF
(
gdth_cmd_str
,
u
.
raw
.
sg_lst
);
}
else
{
#if LINUX_VERSION_CODE >= 0x020400
sense_paddr
=
pci_map_single
(
ha
->
pdev
,
scp
->
sense_buffer
,
16
,
PCI_DMA_FROMDEVICE
);
scp
->
SCp
.
buffer
=
(
struct
scatterlist
*
)
sense_paddr
;
#else
sense_paddr
=
virt_to_bus
(
scp
->
sense_buffer
);
#endif
cmdp
->
OpCode
=
GDT_WRITE
;
/* always */
cmdp
->
BoardNode
=
LOCALBOARD
;
cmdp
->
u
.
raw
.
reserved
=
0
;
...
...
@@ -2944,7 +3100,7 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b)
cmdp
->
u
.
raw
.
link_p
=
0
;
cmdp
->
u
.
raw
.
sdlen
=
scp
->
request_bufflen
;
cmdp
->
u
.
raw
.
sense_len
=
16
;
cmdp
->
u
.
raw
.
sense_data
=
virt_to_bus
(
scp
->
sense_buffer
)
;
cmdp
->
u
.
raw
.
sense_data
=
sense_paddr
;
cmdp
->
u
.
raw
.
direction
=
gdth_direction_tab
[
scp
->
cmnd
[
0
]]
==
DOU
?
GDTH_DATA_OUT
:
GDTH_DATA_IN
;
memcpy
(
cmdp
->
u
.
raw
.
cmd
,
scp
->
cmnd
,
12
);
...
...
@@ -2952,10 +3108,21 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b)
if
(
scp
->
use_sg
)
{
cmdp
->
u
.
raw
.
sdata
=
0xffffffff
;
sl
=
(
struct
scatterlist
*
)
scp
->
request_buffer
;
for
(
i
=
0
;
i
<
scp
->
use_sg
;
++
i
,
++
sl
)
{
sgcnt
=
scp
->
use_sg
;
#if LINUX_VERSION_CODE >= 0x020400
scp
->
SCp
.
Status
=
GDTH_MAP_SG
;
scp
->
SCp
.
Message
=
PCI_DMA_BIDIRECTIONAL
;
sgcnt
=
pci_map_sg
(
ha
->
pdev
,
sl
,
scp
->
use_sg
,
scp
->
SCp
.
Message
);
for
(
i
=
0
;
i
<
sgcnt
;
++
i
,
++
sl
)
{
cmdp
->
u
.
raw
.
sg_lst
[
i
].
sg_ptr
=
sg_dma_address
(
sl
);
cmdp
->
u
.
raw
.
sg_lst
[
i
].
sg_len
=
sg_dma_len
(
sl
);
}
#else
for
(
i
=
0
;
i
<
sgcnt
;
++
i
,
++
sl
)
{
cmdp
->
u
.
raw
.
sg_lst
[
i
].
sg_ptr
=
virt_to_bus
(
sl
->
address
);
cmdp
->
u
.
raw
.
sg_lst
[
i
].
sg_len
=
(
ulong32
)
sl
->
length
;
}
#endif
cmdp
->
u
.
raw
.
sg_ranz
=
(
ulong32
)
i
;
#ifdef GDTH_STATISTICS
...
...
@@ -2967,14 +3134,23 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b)
if
(
i
<
GDTH_MAXSG
)
cmdp
->
u
.
raw
.
sg_lst
[
i
].
sg_len
=
0
;
}
else
{
#if LINUX_VERSION_CODE >= 0x020400
scp
->
SCp
.
Status
=
GDTH_MAP_SINGLE
;
scp
->
SCp
.
Message
=
PCI_DMA_BIDIRECTIONAL
;
phys_addr
=
pci_map_single
(
ha
->
pdev
,
scp
->
request_buffer
,
scp
->
request_bufflen
,
scp
->
SCp
.
Message
);
scp
->
SCp
.
dma_handle
=
phys_addr
;
#else
phys_addr
=
virt_to_bus
(
scp
->
request_buffer
);
#endif
if
(
ha
->
raw_feat
&
SCATTER_GATHER
)
{
cmdp
->
u
.
raw
.
sdata
=
0xffffffff
;
cmdp
->
u
.
raw
.
sg_ranz
=
1
;
cmdp
->
u
.
raw
.
sg_lst
[
0
].
sg_ptr
=
virt_to_bus
(
scp
->
request_buffer
)
;
cmdp
->
u
.
raw
.
sg_lst
[
0
].
sg_ptr
=
phys_addr
;
cmdp
->
u
.
raw
.
sg_lst
[
0
].
sg_len
=
scp
->
request_bufflen
;
cmdp
->
u
.
raw
.
sg_lst
[
1
].
sg_len
=
0
;
}
else
{
cmdp
->
u
.
raw
.
sdata
=
virt_to_bus
(
scp
->
request_buffer
)
;
cmdp
->
u
.
raw
.
sdata
=
phys_addr
;
cmdp
->
u
.
raw
.
sg_ranz
=
0
;
}
}
...
...
@@ -3372,9 +3548,19 @@ static void gdth_interrupt(int irq,struct pt_regs *regs)
if
(
rval
==
2
)
{
gdth_putq
(
hanum
,
scp
,
scp
->
SCp
.
this_residual
);
}
else
if
(
rval
==
1
)
{
#if LINUX_VERSION_CODE >= 0x02053C
GDTH_LOCK_SCSI_DONE
(
scp
->
device
->
host
,
flags
);
scp
->
scsi_done
(
scp
);
GDTH_UNLOCK_SCSI_DONE
(
scp
->
host
,
flags
);
GDTH_UNLOCK_SCSI_DONE
(
scp
->
device
->
host
,
flags
);
#elif LINUX_VERSION_CODE >= 0x020503
GDTH_LOCK_SCSI_DONE
(
scp
->
host
,
flags
);
scp
->
scsi_done
(
scp
);
GDTH_UNLOCK_SCSI_DONE
(
scp
->
host
,
flags
);
#else
GDTH_LOCK_SCSI_DONE
(
flags
);
scp
->
scsi_done
(
scp
);
GDTH_UNLOCK_SCSI_DONE
(
flags
);
#endif
}
gdth_next
(
hanum
);
}
...
...
@@ -3384,7 +3570,7 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp)
register
gdth_ha_str
*
ha
;
gdth_msg_str
*
msg
;
gdth_cmd_str
*
cmdp
;
unchar
b
;
unchar
b
,
t
;
ha
=
HADATA
(
gdth_ctr_tab
[
hanum
]);
cmdp
=
ha
->
pccb
;
...
...
@@ -3413,7 +3599,7 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp)
cmdp
->
BoardNode
=
LOCALBOARD
;
cmdp
->
u
.
screen
.
reserved
=
0
;
cmdp
->
u
.
screen
.
su
.
msg
.
msg_handle
=
msg
->
msg_handle
;
cmdp
->
u
.
screen
.
su
.
msg
.
msg_addr
=
virt_to_bus
(
msg
)
;
cmdp
->
u
.
screen
.
su
.
msg
.
msg_addr
=
ha
->
scratch_phys
;
ha
->
scratch_busy
=
TRUE
;
ha
->
cmd_offs_dpmem
=
0
;
ha
->
cmd_len
=
GDTOFFSOF
(
gdth_cmd_str
,
u
.
screen
.
su
.
msg
.
msg_addr
)
...
...
@@ -3448,7 +3634,7 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp)
cmdp
->
BoardNode
=
LOCALBOARD
;
cmdp
->
u
.
screen
.
reserved
=
0
;
cmdp
->
u
.
screen
.
su
.
msg
.
msg_handle
=
msg
->
msg_handle
;
cmdp
->
u
.
screen
.
su
.
msg
.
msg_addr
=
virt_to_bus
(
msg
)
;
cmdp
->
u
.
screen
.
su
.
msg
.
msg_addr
=
ha
->
scratch_phys
;
ha
->
scratch_busy
=
TRUE
;
ha
->
cmd_offs_dpmem
=
0
;
ha
->
cmd_len
=
GDTOFFSOF
(
gdth_cmd_str
,
u
.
screen
.
su
.
msg
.
msg_addr
)
...
...
@@ -3461,11 +3647,35 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp)
printk
(
"
\n
"
);
}
else
{
#if LINUX_VERSION_CODE >= 0x02053C
b
=
virt_ctr
?
NUMDATA
(
scp
->
device
->
host
)
->
busnum
:
scp
->
device
->
channel
;
t
=
scp
->
device
->
id
;
#else
b
=
virt_ctr
?
NUMDATA
(
scp
->
host
)
->
busnum
:
scp
->
channel
;
t
=
scp
->
target
;
#endif
if
(
scp
->
SCp
.
sent_command
==
-
1
&&
b
!=
ha
->
virt_bus
)
{
ha
->
raw
[
BUS_L2P
(
ha
,
b
)].
io_cnt
[
scp
->
device
->
id
]
--
;
ha
->
raw
[
BUS_L2P
(
ha
,
b
)].
io_cnt
[
t
]
--
;
}
/* cache or raw service */
if
(
ha
->
status
==
S_BSY
)
{
TRACE2
((
"Controller busy -> retry !
\n
"
));
if
(
scp
->
SCp
.
sent_command
==
GDT_MOUNT
)
scp
->
SCp
.
sent_command
=
GDT_CLUST_INFO
;
/* retry */
return
2
;
}
#if LINUX_VERSION_CODE >= 0x020400
if
(
scp
->
SCp
.
Status
==
GDTH_MAP_SG
)
pci_unmap_sg
(
ha
->
pdev
,
scp
->
request_buffer
,
scp
->
use_sg
,
scp
->
SCp
.
Message
);
else
if
(
scp
->
SCp
.
Status
==
GDTH_MAP_SINGLE
)
pci_unmap_single
(
ha
->
pdev
,
scp
->
SCp
.
dma_handle
,
scp
->
request_bufflen
,
scp
->
SCp
.
Message
);
if
(
scp
->
SCp
.
buffer
)
pci_unmap_single
(
ha
->
pdev
,(
dma_addr_t
)
scp
->
SCp
.
buffer
,
16
,
PCI_DMA_FROMDEVICE
);
#endif
if
(
ha
->
status
==
S_OK
)
{
scp
->
SCp
.
Status
=
S_OK
;
scp
->
SCp
.
Message
=
ha
->
info
;
...
...
@@ -3474,12 +3684,12 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp)
scp
->
SCp
.
sent_command
));
/* special commands GDT_CLUST_INFO/GDT_MOUNT ? */
if
(
scp
->
SCp
.
sent_command
==
GDT_CLUST_INFO
)
{
ha
->
hdr
[
scp
->
device
->
id
].
cluster_type
=
(
unchar
)
ha
->
info
;
if
(
!
(
ha
->
hdr
[
scp
->
device
->
id
].
cluster_type
&
ha
->
hdr
[
t
].
cluster_type
=
(
unchar
)
ha
->
info
;
if
(
!
(
ha
->
hdr
[
t
].
cluster_type
&
CLUSTER_MOUNTED
))
{
/* NOT MOUNTED -> MOUNT */
scp
->
SCp
.
sent_command
=
GDT_MOUNT
;
if
(
ha
->
hdr
[
scp
->
device
->
id
].
cluster_type
&
if
(
ha
->
hdr
[
t
].
cluster_type
&
CLUSTER_RESERVED
)
{
/* cluster drive RESERVED (on the other node) */
scp
->
SCp
.
phase
=
-
2
;
/* reservation conflict */
...
...
@@ -3489,11 +3699,11 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp)
}
}
else
{
if
(
scp
->
SCp
.
sent_command
==
GDT_MOUNT
)
{
ha
->
hdr
[
scp
->
device
->
id
].
cluster_type
|=
CLUSTER_MOUNTED
;
ha
->
hdr
[
scp
->
device
->
id
].
media_changed
=
TRUE
;
ha
->
hdr
[
t
].
cluster_type
|=
CLUSTER_MOUNTED
;
ha
->
hdr
[
t
].
media_changed
=
TRUE
;
}
else
if
(
scp
->
SCp
.
sent_command
==
GDT_UNMOUNT
)
{
ha
->
hdr
[
scp
->
device
->
id
].
cluster_type
&=
~
CLUSTER_MOUNTED
;
ha
->
hdr
[
scp
->
device
->
id
].
media_changed
=
TRUE
;
ha
->
hdr
[
t
].
cluster_type
&=
~
CLUSTER_MOUNTED
;
ha
->
hdr
[
t
].
media_changed
=
TRUE
;
}
scp
->
SCp
.
sent_command
=
-
1
;
}
...
...
@@ -3503,21 +3713,13 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp)
}
else
{
/* RESERVE/RELEASE ? */
if
(
scp
->
cmnd
[
0
]
==
RESERVE
)
{
ha
->
hdr
[
scp
->
device
->
id
].
cluster_type
|=
CLUSTER_RESERVED
;
ha
->
hdr
[
t
].
cluster_type
|=
CLUSTER_RESERVED
;
}
else
if
(
scp
->
cmnd
[
0
]
==
RELEASE
)
{
ha
->
hdr
[
scp
->
device
->
id
].
cluster_type
&=
~
CLUSTER_RESERVED
;
ha
->
hdr
[
t
].
cluster_type
&=
~
CLUSTER_RESERVED
;
}
scp
->
result
=
DID_OK
<<
16
;
scp
->
sense_buffer
[
0
]
=
0
;
}
}
else
if
(
ha
->
status
==
S_BSY
)
{
TRACE2
((
"Controller busy -> retry !
\n
"
));
scp
->
SCp
.
Status
=
S_BSY
;
scp
->
SCp
.
Message
=
ha
->
info
;
if
(
scp
->
SCp
.
sent_command
==
GDT_MOUNT
)
scp
->
SCp
.
sent_command
=
GDT_CLUST_INFO
;
/* retry */
return
2
;
}
else
{
scp
->
SCp
.
Status
=
ha
->
status
;
scp
->
SCp
.
Message
=
ha
->
info
;
...
...
@@ -3538,10 +3740,10 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp)
scp
->
result
=
(
DID_OK
<<
16
)
|
(
CHECK_CONDITION
<<
1
);
}
else
if
(
service
==
CACHESERVICE
)
{
if
(
ha
->
status
==
S_CACHE_UNKNOWN
&&
(
ha
->
hdr
[
scp
->
device
->
id
].
cluster_type
&
(
ha
->
hdr
[
t
].
cluster_type
&
CLUSTER_RESERVE_STATE
)
==
CLUSTER_RESERVE_STATE
)
{
/* bus reset -> force GDT_CLUST_INFO */
ha
->
hdr
[
scp
->
device
->
id
].
cluster_type
&=
~
CLUSTER_RESERVED
;
ha
->
hdr
[
t
].
cluster_type
&=
~
CLUSTER_RESERVED
;
}
memset
((
char
*
)
scp
->
sense_buffer
,
0
,
16
);
if
(
ha
->
status
==
(
ushort
)
S_CACHE_RESERV
)
{
...
...
@@ -3560,7 +3762,7 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp)
ha
->
dvr
.
eu
.
sync
.
service
=
service
;
ha
->
dvr
.
eu
.
sync
.
status
=
ha
->
status
;
ha
->
dvr
.
eu
.
sync
.
info
=
ha
->
info
;
ha
->
dvr
.
eu
.
sync
.
hostdrive
=
scp
->
device
->
id
;
ha
->
dvr
.
eu
.
sync
.
hostdrive
=
t
;
if
(
ha
->
status
>=
0x8000
)
gdth_store_event
(
ha
,
ES_SYNC
,
0
,
&
ha
->
dvr
);
else
...
...
@@ -3765,7 +3967,7 @@ static int gdth_async_event(int hanum)
cmdp
->
BoardNode
=
LOCALBOARD
;
cmdp
->
u
.
screen
.
reserved
=
0
;
cmdp
->
u
.
screen
.
su
.
msg
.
msg_handle
=
MSG_INV_HANDLE
;
cmdp
->
u
.
screen
.
su
.
msg
.
msg_addr
=
virt_to_bus
(
msg
)
;
cmdp
->
u
.
screen
.
su
.
msg
.
msg_addr
=
ha
->
scratch_phys
;
ha
->
scratch_busy
=
TRUE
;
ha
->
cmd_offs_dpmem
=
0
;
ha
->
cmd_len
=
GDTOFFSOF
(
gdth_cmd_str
,
u
.
screen
.
su
.
msg
.
msg_addr
)
...
...
@@ -4028,8 +4230,8 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp))
break
;
if
(
gdth_search_isa
(
isa_bios
))
{
/* controller found */
shp
=
scsi_register
(
shtp
,
sizeof
(
gdth_ext_str
));
if
(
shp
==
NULL
)
continue
;
if
(
shp
==
NULL
)
continue
;
ha
=
HADATA
(
shp
);
if
(
!
gdth_init_isa
(
isa_bios
,
ha
))
{
...
...
@@ -4076,11 +4278,15 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp))
NUMDATA
(
shp
)
->
busnum
=
0
;
ha
->
pccb
=
CMDDATA
(
shp
);
#if LINUX_VERSION_CODE >= 0x020322
ha
->
pscratch
=
(
void
*
)
__get_free_pages
(
GFP_ATOMIC
|
GFP_DMA
,
GDTH_SCRATCH_ORD
);
ha
->
ccb_phys
=
0L
;
#if LINUX_VERSION_CODE >= 0x020400
ha
->
pdev
=
NULL
;
ha
->
pscratch
=
pci_alloc_consistent
(
ha
->
pdev
,
GDTH_SCRATCH
,
&
ha
->
scratch_phys
);
#else
ha
->
pscratch
=
scsi_init_malloc
(
GDTH_SCRATCH
,
GFP_ATOMIC
|
GFP_DMA
);
if
(
ha
->
pscratch
)
ha
->
scratch_phys
=
virt_to_bus
(
ha
->
pscratch
);
#endif
ha
->
scratch_busy
=
FALSE
;
ha
->
req_first
=
NULL
;
...
...
@@ -4095,12 +4301,14 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp))
printk
(
"GDT-ISA: Error during device scan
\n
"
);
--
gdth_ctr_count
;
--
gdth_ctr_vcount
;
if
(
ha
->
pscratch
!=
NULL
)
#if LINUX_VERSION_CODE >= 0x020322
free_pages
((
unsigned
long
)
ha
->
pscratch
,
GDTH_SCRATCH_ORD
);
if
(
ha
->
pscratch
!=
NULL
)
{
#if LINUX_VERSION_CODE >= 0x020400
pci_free_consistent
(
ha
->
pdev
,
GDTH_SCRATCH
,
ha
->
pscratch
,
ha
->
scratch_phys
);
#else
scsi_init_free
((
void
*
)
ha
->
pscratch
,
GDTH_SCRATCH
);
#endif
}
#if LINUX_VERSION_CODE >= 0x010346
free_irq
(
ha
->
irq
,
ha
);
#else
...
...
@@ -4145,8 +4353,8 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp))
break
;
if
(
gdth_search_eisa
(
eisa_slot
))
{
/* controller found */
shp
=
scsi_register
(
shtp
,
sizeof
(
gdth_ext_str
));
if
(
shp
==
NULL
)
continue
;
if
(
shp
==
NULL
)
continue
;
ha
=
HADATA
(
shp
);
if
(
!
gdth_init_eisa
(
eisa_slot
,
ha
))
{
...
...
@@ -4180,11 +4388,19 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp))
NUMDATA
(
shp
)
->
hanum
));
ha
->
pccb
=
CMDDATA
(
shp
);
#if LINUX_VERSION_CODE >= 0x020322
ha
->
pscratch
=
(
void
*
)
__get_free_pages
(
GFP_ATOMIC
|
GFP_DMA
,
GDTH_SCRATCH_ORD
);
ha
->
ccb_phys
=
0L
;
#if LINUX_VERSION_CODE >= 0x020400
ha
->
pdev
=
NULL
;
ha
->
pscratch
=
pci_alloc_consistent
(
ha
->
pdev
,
GDTH_SCRATCH
,
&
ha
->
scratch_phys
);
ha
->
ccb_phys
=
pci_map_single
(
ha
->
pdev
,
ha
->
pccb
,
sizeof
(
gdth_cmd_str
),
PCI_DMA_BIDIRECTIONAL
);
#else
ha
->
pscratch
=
scsi_init_malloc
(
GDTH_SCRATCH
,
GFP_ATOMIC
|
GFP_DMA
);
if
(
ha
->
pscratch
)
ha
->
scratch_phys
=
virt_to_bus
(
ha
->
pscratch
);
ha
->
ccb_phys
=
virt_to_bus
(
ha
->
pccb
);
#endif
ha
->
scratch_busy
=
FALSE
;
ha
->
req_first
=
NULL
;
...
...
@@ -4199,12 +4415,16 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp))
printk
(
"GDT-EISA: Error during device scan
\n
"
);
--
gdth_ctr_count
;
--
gdth_ctr_vcount
;
if
(
ha
->
pscratch
!=
NULL
)
#if LINUX_VERSION_CODE >= 0x020322
free_pages
((
unsigned
long
)
ha
->
pscratch
,
GDTH_SCRATCH_ORD
);
if
(
ha
->
pscratch
!=
NULL
)
{
#if LINUX_VERSION_CODE >= 0x020400
pci_free_consistent
(
ha
->
pdev
,
GDTH_SCRATCH
,
ha
->
pscratch
,
ha
->
scratch_phys
);
pci_unmap_single
(
ha
->
pdev
,
ha
->
ccb_phys
,
sizeof
(
gdth_cmd_str
),
PCI_DMA_BIDIRECTIONAL
);
#else
scsi_init_free
((
void
*
)
ha
->
pscratch
,
GDTH_SCRATCH
);
#endif
}
#if LINUX_VERSION_CODE >= 0x010346
free_irq
(
ha
->
irq
,
ha
);
#else
...
...
@@ -4252,14 +4472,14 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp))
gdth_pci_str
pcistr
[
MAXHA
];
cnt
=
gdth_search_pci
(
pcistr
);
printk
(
"GDT: Found %d PCI Storage RAID Controllers
\n
"
,
cnt
);
printk
(
"GDT: Found %d PCI Storage RAID Controllers
\n
"
,
cnt
);
gdth_sort_pci
(
pcistr
,
cnt
);
for
(
ctr
=
0
;
ctr
<
cnt
;
++
ctr
)
{
if
(
gdth_ctr_count
>=
MAXHA
)
break
;
shp
=
scsi_register
(
shtp
,
sizeof
(
gdth_ext_str
));
if
(
shp
==
NULL
)
continue
;
if
(
shp
==
NULL
)
continue
;
ha
=
HADATA
(
shp
);
if
(
!
gdth_init_pci
(
&
pcistr
[
ctr
],
ha
))
{
...
...
@@ -4293,11 +4513,14 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp))
NUMDATA
(
shp
)
->
busnum
=
0
;
ha
->
pccb
=
CMDDATA
(
shp
);
#if LINUX_VERSION_CODE >= 0x020322
ha
->
pscratch
=
(
void
*
)
__get_free_pages
(
GFP_ATOMIC
|
GFP_DMA
,
GDTH_SCRATCH_ORD
);
ha
->
ccb_phys
=
0L
;
#if LINUX_VERSION_CODE >= 0x020400
ha
->
pscratch
=
pci_alloc_consistent
(
ha
->
pdev
,
GDTH_SCRATCH
,
&
ha
->
scratch_phys
);
#else
ha
->
pscratch
=
scsi_init_malloc
(
GDTH_SCRATCH
,
GFP_ATOMIC
|
GFP_DMA
);
if
(
ha
->
pscratch
)
ha
->
scratch_phys
=
virt_to_bus
(
ha
->
pscratch
);
#endif
ha
->
scratch_busy
=
FALSE
;
ha
->
req_first
=
NULL
;
...
...
@@ -4312,12 +4535,14 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp))
printk
(
"GDT-PCI: Error during device scan
\n
"
);
--
gdth_ctr_count
;
--
gdth_ctr_vcount
;
if
(
ha
->
pscratch
!=
NULL
)
#if LINUX_VERSION_CODE >= 0x020322
free_pages
((
unsigned
long
)
ha
->
pscratch
,
GDTH_SCRATCH_ORD
);
if
(
ha
->
pscratch
!=
NULL
)
{
#if LINUX_VERSION_CODE >= 0x020400
pci_free_consistent
(
ha
->
pdev
,
GDTH_SCRATCH
,
ha
->
pscratch
,
ha
->
scratch_phys
);
#else
scsi_init_free
((
void
*
)
ha
->
pscratch
,
GDTH_SCRATCH
);
#endif
}
#if LINUX_VERSION_CODE >= 0x010346
free_irq
(
ha
->
irq
,
ha
);
#else
...
...
@@ -4365,6 +4590,9 @@ GDTH_INITFUNC(int, gdth_detect(Scsi_Host_Template *shtp))
gdth_timer
.
function
=
gdth_timeout
;
add_timer
(
&
gdth_timer
);
#endif
#ifdef GDTH_IOCTL_CHRDEV
major
=
register_chrdev
(
0
,
"gdth"
,
&
gdth_fops
);
#endif
#if LINUX_VERSION_CODE >= 0x020100
register_reboot_notifier
(
&
gdth_notifier
);
#endif
...
...
@@ -4399,8 +4627,12 @@ int gdth_release(struct Scsi_Host *shp)
free_dma
(
shp
->
dma_channel
);
}
#endif
#if LINUX_VERSION_CODE >= 0x020322
free_pages
((
unsigned
long
)
ha
->
pscratch
,
GDTH_SCRATCH_ORD
);
#if LINUX_VERSION_CODE >= 0x020400
pci_free_consistent
(
ha
->
pdev
,
GDTH_SCRATCH
,
ha
->
pscratch
,
ha
->
scratch_phys
);
if
(
ha
->
ccb_phys
)
pci_unmap_single
(
ha
->
pdev
,
ha
->
ccb_phys
,
sizeof
(
gdth_cmd_str
),
PCI_DMA_BIDIRECTIONAL
);
#else
scsi_init_free
((
void
*
)
ha
->
pscratch
,
GDTH_SCRATCH
);
#endif
...
...
@@ -4412,6 +4644,9 @@ int gdth_release(struct Scsi_Host *shp)
#ifdef GDTH_STATISTICS
del_timer
(
&
gdth_timer
);
#endif
#ifdef GDTH_IOCTL_CHRDEV
unregister_chrdev
(
major
,
"gdth"
);
#endif
#if LINUX_VERSION_CODE >= 0x020100
unregister_reboot_notifier
(
&
gdth_notifier
);
#endif
...
...
@@ -4507,15 +4742,24 @@ int gdth_eh_bus_reset(Scsi_Cmnd *scp)
unchar
b
;
TRACE2
((
"gdth_eh_bus_reset()
\n
"
));
#if LINUX_VERSION_CODE >= 0x02053C
hanum
=
NUMDATA
(
scp
->
device
->
host
)
->
hanum
;
b
=
virt_ctr
?
NUMDATA
(
scp
->
device
->
host
)
->
busnum
:
scp
->
device
->
channel
;
#else
hanum
=
NUMDATA
(
scp
->
host
)
->
hanum
;
b
=
virt_ctr
?
NUMDATA
(
scp
->
host
)
->
busnum
:
scp
->
channel
;
#endif
ha
=
HADATA
(
gdth_ctr_tab
[
hanum
]);
/* clear command tab */
GDTH_LOCK_HA
(
ha
,
flags
);
for
(
i
=
0
;
i
<
GDTH_MAXCMDS
;
++
i
)
{
cmnd
=
ha
->
cmd_tab
[
i
].
cmnd
;
#if LINUX_VERSION_CODE >= 0x02053C
if
(
!
SPECIAL_SCP
(
cmnd
)
&&
cmnd
->
device
->
channel
==
b
)
#else
if
(
!
SPECIAL_SCP
(
cmnd
)
&&
cmnd
->
channel
==
b
)
#endif
ha
->
cmd_tab
[
i
].
cmnd
=
UNUSED_CMND
;
}
GDTH_UNLOCK_HA
(
ha
,
flags
);
...
...
@@ -4558,16 +4802,31 @@ int gdth_eh_host_reset(Scsi_Cmnd *scp)
}
#endif
int
gdth_bios_param
(
struct
scsi_device
*
sdev
,
struct
block_device
*
bdev
,
sector_t
capacity
,
int
*
ip
)
#if LINUX_VERSION_CODE >= 0x020503
int
gdth_bios_param
(
struct
scsi_device
*
sdev
,
struct
block_device
*
bdev
,
sector_t
cap
,
int
*
ip
)
#elif LINUX_VERSION_CODE >= 0x010300
int
gdth_bios_param
(
Disk
*
disk
,
kdev_t
dev
,
int
*
ip
)
#else
int
gdth_bios_param
(
Disk
*
disk
,
int
dev
,
int
*
ip
)
#endif
{
unchar
b
,
t
;
int
hanum
;
gdth_ha_str
*
ha
;
struct
scsi_device
*
sd
;
unsigned
capacity
;
hanum
=
NUMDATA
(
sdev
->
host
)
->
hanum
;
b
=
virt_ctr
?
NUMDATA
(
sdev
->
host
)
->
busnum
:
sdev
->
channel
;
t
=
sdev
->
id
;
#if LINUX_VERSION_CODE >= 0x020503
sd
=
sdev
;
capacity
=
cap
;
#else
sd
=
disk
->
device
;
capacity
=
disk
->
capacity
;
#endif
hanum
=
NUMDATA
(
sd
->
host
)
->
hanum
;
b
=
virt_ctr
?
NUMDATA
(
sd
->
host
)
->
busnum
:
sd
->
channel
;
t
=
sd
->
id
;
TRACE2
((
"gdth_bios_param() ha %d bus %d target %d
\n
"
,
hanum
,
b
,
t
));
ha
=
HADATA
(
gdth_ctr_tab
[
hanum
]);
...
...
@@ -4592,14 +4851,19 @@ int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *))
int
hanum
;
int
priority
;
TRACE
((
"gdth_queuecommand() cmd 0x%x id %d lun %d
\n
"
,
scp
->
cmnd
[
0
],
scp
->
device
->
id
,
scp
->
lun
));
TRACE
((
"gdth_queuecommand() cmd 0x%x
\n
"
,
scp
->
cmnd
[
0
]));
scp
->
scsi_done
=
(
void
*
)
done
;
scp
->
SCp
.
have_data_in
=
1
;
scp
->
SCp
.
phase
=
-
1
;
scp
->
SCp
.
sent_command
=
-
1
;
scp
->
SCp
.
Status
=
GDTH_MAP_NONE
;
scp
->
SCp
.
buffer
=
(
struct
scatterlist
*
)
NULL
;
#if LINUX_VERSION_CODE >= 0x02053C
hanum
=
NUMDATA
(
scp
->
device
->
host
)
->
hanum
;
#else
hanum
=
NUMDATA
(
scp
->
host
)
->
hanum
;
#endif
#ifdef GDTH_STATISTICS
++
act_ios
;
#endif
...
...
@@ -4615,6 +4879,667 @@ int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *))
return
0
;
}
#ifdef GDTH_IOCTL_CHRDEV
static
int
gdth_open
(
struct
inode
*
inode
,
struct
file
*
filep
)
{
TRACE
((
"gdth_open()
\n
"
));
return
0
;
}
static
int
gdth_close
(
struct
inode
*
inode
,
struct
file
*
filep
)
{
TRACE
((
"gdth_close()
\n
"
));
return
0
;
}
static
int
gdth_ioctl
(
struct
inode
*
inode
,
struct
file
*
filep
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
gdth_ha_str
*
ha
;
#if LINUX_VERSION_CODE >= 0x020503
Scsi_Request
*
srp
;
Scsi_Cmnd
*
scp
;
Scsi_Device
*
sdev
;
#elif LINUX_VERSION_CODE >= 0x020322
Scsi_Cmnd
*
scp
;
Scsi_Device
*
sdev
;
#else
Scsi_Cmnd
scp
;
Scsi_Device
sdev
;
#endif
ulong
flags
;
char
cmnd
[
MAX_COMMAND_SIZE
];
memset
(
cmnd
,
0xff
,
12
);
TRACE
((
"gdth_ioctl() cmd 0x%x
\n
"
,
cmd
));
switch
(
cmd
)
{
case
GDTIOCTL_CTRCNT
:
{
int
cnt
=
gdth_ctr_count
;
put_user
(
cnt
,
(
int
*
)
arg
);
break
;
}
case
GDTIOCTL_DRVERS
:
{
int
ver
=
(
GDTH_VERSION
<<
8
)
|
GDTH_SUBVERSION
;
put_user
(
ver
,
(
int
*
)
arg
);
break
;
}
case
GDTIOCTL_OSVERS
:
{
gdth_ioctl_osvers
osv
;
osv
.
version
=
(
unchar
)(
LINUX_VERSION_CODE
>>
16
);
osv
.
subversion
=
(
unchar
)(
LINUX_VERSION_CODE
>>
8
);
osv
.
revision
=
(
ushort
)(
LINUX_VERSION_CODE
&
0xff
);
copy_to_user
((
char
*
)
arg
,
&
osv
,
sizeof
(
gdth_ioctl_osvers
));
break
;
}
case
GDTIOCTL_CTRTYPE
:
{
gdth_ioctl_ctrtype
ctrt
;
if
(
copy_from_user
(
&
ctrt
,
(
char
*
)
arg
,
sizeof
(
gdth_ioctl_ctrtype
))
||
ctrt
.
ionode
>=
gdth_ctr_count
)
return
-
EFAULT
;
ha
=
HADATA
(
gdth_ctr_tab
[
ctrt
.
ionode
]);
if
(
ha
->
type
==
GDT_ISA
||
ha
->
type
==
GDT_EISA
)
{
ctrt
.
type
=
(
unchar
)((
ha
->
stype
>>
20
)
-
0x10
);
}
else
{
if
(
ha
->
type
!=
GDT_PCIMPR
)
{
ctrt
.
type
=
(
unchar
)((
ha
->
stype
<<
4
)
+
6
);
}
else
{
ctrt
.
type
=
(
ha
->
oem_id
==
OEM_ID_INTEL
?
0xfd
:
0xfe
);
if
(
ha
->
stype
>=
0x300
)
ctrt
.
ext_type
=
0x6000
|
ha
->
subdevice_id
;
else
ctrt
.
ext_type
=
0x6000
|
ha
->
stype
;
}
ctrt
.
device_id
=
ha
->
stype
;
ctrt
.
sub_device_id
=
ha
->
subdevice_id
;
}
ctrt
.
info
=
ha
->
brd_phys
;
ctrt
.
oem_id
=
ha
->
oem_id
;
if
(
copy_to_user
((
char
*
)
arg
,
&
ctrt
,
sizeof
(
gdth_ioctl_ctrtype
)))
return
-
EFAULT
;
break
;
}
case
GDTIOCTL_GENERAL
:
{
gdth_ioctl_general
gen
;
char
*
buf
=
NULL
;
ulong32
paddr
;
int
hanum
;
if
(
copy_from_user
(
&
gen
,
(
char
*
)
arg
,
sizeof
(
gdth_ioctl_general
))
||
gen
.
ionode
>=
gdth_ctr_count
)
return
-
EFAULT
;
hanum
=
gen
.
ionode
;
ha
=
HADATA
(
gdth_ctr_tab
[
hanum
]);
if
(
gen
.
data_len
+
gen
.
sense_len
!=
0
)
{
if
(
!
(
buf
=
gdth_ioctl_alloc
(
hanum
,
gen
.
data_len
+
gen
.
sense_len
,
FALSE
,
&
paddr
)))
return
-
EFAULT
;
if
(
copy_from_user
(
buf
,
(
char
*
)
arg
+
sizeof
(
gdth_ioctl_general
),
gen
.
data_len
+
gen
.
sense_len
))
{
gdth_ioctl_free
(
hanum
,
gen
.
data_len
+
gen
.
sense_len
,
buf
,
paddr
);
return
-
EFAULT
;
}
if
(
gen
.
command
.
OpCode
==
GDT_IOCTL
)
{
gen
.
command
.
u
.
ioctl
.
p_param
=
paddr
;
}
else
if
(
gen
.
command
.
Service
==
CACHESERVICE
)
{
if
(
ha
->
cache_feat
&
SCATTER_GATHER
)
{
gen
.
command
.
u
.
cache
.
DestAddr
=
0xffffffff
;
gen
.
command
.
u
.
cache
.
sg_canz
=
1
;
gen
.
command
.
u
.
cache
.
sg_lst
[
0
].
sg_ptr
=
paddr
;
gen
.
command
.
u
.
cache
.
sg_lst
[
0
].
sg_len
=
gen
.
data_len
;
gen
.
command
.
u
.
cache
.
sg_lst
[
1
].
sg_len
=
0
;
}
else
{
gen
.
command
.
u
.
cache
.
DestAddr
=
paddr
;
gen
.
command
.
u
.
cache
.
sg_canz
=
0
;
}
}
else
if
(
gen
.
command
.
Service
==
SCSIRAWSERVICE
)
{
if
(
ha
->
raw_feat
&
SCATTER_GATHER
)
{
gen
.
command
.
u
.
raw
.
sdata
=
0xffffffff
;
gen
.
command
.
u
.
raw
.
sg_ranz
=
1
;
gen
.
command
.
u
.
raw
.
sg_lst
[
0
].
sg_ptr
=
paddr
;
gen
.
command
.
u
.
raw
.
sg_lst
[
0
].
sg_len
=
gen
.
data_len
;
gen
.
command
.
u
.
raw
.
sg_lst
[
1
].
sg_len
=
0
;
}
else
{
gen
.
command
.
u
.
raw
.
sdata
=
paddr
;
gen
.
command
.
u
.
raw
.
sg_ranz
=
0
;
}
gen
.
command
.
u
.
raw
.
sense_data
=
paddr
+
gen
.
data_len
;
}
else
{
gdth_ioctl_free
(
hanum
,
gen
.
data_len
+
gen
.
sense_len
,
buf
,
paddr
);
return
-
EFAULT
;
}
}
#if LINUX_VERSION_CODE >= 0x020503
sdev
=
scsi_get_host_dev
(
gdth_ctr_tab
[
hanum
]);
srp
=
scsi_allocate_request
(
sdev
);
if
(
!
srp
)
return
-
ENOMEM
;
srp
->
sr_cmd_len
=
12
;
srp
->
sr_use_sg
=
0
;
gdth_do_req
(
srp
,
&
gen
.
command
,
cmnd
,
gen
.
timeout
);
gen
.
status
=
srp
->
sr_command
->
SCp
.
Status
;
gen
.
info
=
srp
->
sr_command
->
SCp
.
Message
;
scsi_release_request
(
srp
);
scsi_free_host_dev
(
sdev
);
#elif LINUX_VERSION_CODE >= 0x020322
sdev
=
scsi_get_host_dev
(
gdth_ctr_tab
[
hanum
]);
scp
=
scsi_allocate_device
(
sdev
,
1
,
FALSE
);
if
(
!
scp
)
return
-
ENOMEM
;
scp
->
cmd_len
=
12
;
scp
->
use_sg
=
0
;
gdth_do_cmd
(
scp
,
&
gen
.
command
,
cmnd
,
gen
.
timeout
);
gen
.
status
=
scp
->
SCp
.
Status
;
gen
.
info
=
scp
->
SCp
.
Message
;
scsi_release_command
(
scp
);
scsi_free_host_dev
(
sdev
);
#else
memset
(
&
sdev
,
0
,
sizeof
(
Scsi_Device
));
memset
(
&
scp
,
0
,
sizeof
(
Scsi_Cmnd
));
sdev
.
host
=
scp
.
host
=
gdth_ctr_tab
[
hanum
];
sdev
.
id
=
scp
.
target
=
sdev
.
host
->
this_id
;
scp
.
device
=
&
sdev
;
gdth_do_cmd
(
&
scp
,
&
gen
.
command
,
cmnd
,
gen
.
timeout
);
gen
.
status
=
scp
.
SCp
.
Status
;
gen
.
info
=
scp
.
SCp
.
Message
;
#endif
if
(
copy_to_user
((
char
*
)
arg
+
sizeof
(
gdth_ioctl_general
),
buf
,
gen
.
data_len
+
gen
.
sense_len
))
{
gdth_ioctl_free
(
hanum
,
gen
.
data_len
+
gen
.
sense_len
,
buf
,
paddr
);
return
-
EFAULT
;
}
if
(
copy_to_user
((
char
*
)
arg
,
&
gen
,
sizeof
(
gdth_ioctl_general
)
-
sizeof
(
gdth_cmd_str
)))
{
gdth_ioctl_free
(
hanum
,
gen
.
data_len
+
gen
.
sense_len
,
buf
,
paddr
);
return
-
EFAULT
;
}
gdth_ioctl_free
(
hanum
,
gen
.
data_len
+
gen
.
sense_len
,
buf
,
paddr
);
break
;
}
case
GDTIOCTL_EVENT
:
{
gdth_ioctl_event
evt
;
gdth_ha_str
*
ha
;
ulong
flags
;
if
(
copy_from_user
(
&
evt
,
(
char
*
)
arg
,
sizeof
(
gdth_ioctl_event
))
||
evt
.
ionode
>=
gdth_ctr_count
)
return
-
EFAULT
;
ha
=
HADATA
(
gdth_ctr_tab
[
evt
.
ionode
]);
if
(
evt
.
erase
==
0xff
)
{
if
(
evt
.
event
.
event_source
==
ES_TEST
)
evt
.
event
.
event_data
.
size
=
sizeof
(
evt
.
event
.
event_data
.
eu
.
test
);
else
if
(
evt
.
event
.
event_source
==
ES_DRIVER
)
evt
.
event
.
event_data
.
size
=
sizeof
(
evt
.
event
.
event_data
.
eu
.
driver
);
else
if
(
evt
.
event
.
event_source
==
ES_SYNC
)
evt
.
event
.
event_data
.
size
=
sizeof
(
evt
.
event
.
event_data
.
eu
.
sync
);
else
evt
.
event
.
event_data
.
size
=
sizeof
(
evt
.
event
.
event_data
.
eu
.
async
);
GDTH_LOCK_HA
(
ha
,
flags
);
gdth_store_event
(
ha
,
evt
.
event
.
event_source
,
evt
.
event
.
event_idx
,
&
evt
.
event
.
event_data
);
GDTH_UNLOCK_HA
(
ha
,
flags
);
}
else
if
(
evt
.
erase
==
0xfe
)
{
gdth_clear_events
();
}
else
if
(
evt
.
erase
==
0
)
{
evt
.
handle
=
gdth_read_event
(
ha
,
evt
.
handle
,
&
evt
.
event
);
}
else
{
gdth_readapp_event
(
ha
,
evt
.
erase
,
&
evt
.
event
);
}
if
(
copy_to_user
((
char
*
)
arg
,
&
evt
,
sizeof
(
gdth_ioctl_event
)))
return
-
EFAULT
;
break
;
}
case
GDTIOCTL_LOCKDRV
:
{
gdth_ioctl_lockdrv
ldrv
;
unchar
i
,
j
;
if
(
copy_from_user
(
&
ldrv
,
(
char
*
)
arg
,
sizeof
(
gdth_ioctl_lockdrv
))
||
ldrv
.
ionode
>=
gdth_ctr_count
)
return
-
EFAULT
;
ha
=
HADATA
(
gdth_ctr_tab
[
ldrv
.
ionode
]);
for
(
i
=
0
;
i
<
ldrv
.
drive_cnt
&&
i
<
MAX_HDRIVES
;
++
i
)
{
j
=
ldrv
.
drives
[
i
];
if
(
j
>=
MAX_HDRIVES
||
!
ha
->
hdr
[
j
].
present
)
continue
;
if
(
ldrv
.
lock
)
{
GDTH_LOCK_HA
(
ha
,
flags
);
ha
->
hdr
[
j
].
lock
=
1
;
GDTH_UNLOCK_HA
(
ha
,
flags
);
gdth_wait_completion
(
ldrv
.
ionode
,
ha
->
bus_cnt
,
j
);
gdth_stop_timeout
(
ldrv
.
ionode
,
ha
->
bus_cnt
,
j
);
}
else
{
GDTH_LOCK_HA
(
ha
,
flags
);
ha
->
hdr
[
j
].
lock
=
0
;
GDTH_UNLOCK_HA
(
ha
,
flags
);
gdth_start_timeout
(
ldrv
.
ionode
,
ha
->
bus_cnt
,
j
);
gdth_next
(
ldrv
.
ionode
);
}
}
break
;
}
case
GDTIOCTL_LOCKCHN
:
{
gdth_ioctl_lockchn
lchn
;
unchar
i
,
j
;
if
(
copy_from_user
(
&
lchn
,
(
char
*
)
arg
,
sizeof
(
gdth_ioctl_lockchn
))
||
lchn
.
ionode
>=
gdth_ctr_count
)
return
-
EFAULT
;
ha
=
HADATA
(
gdth_ctr_tab
[
lchn
.
ionode
]);
i
=
lchn
.
channel
;
if
(
i
<
ha
->
bus_cnt
)
{
if
(
lchn
.
lock
)
{
GDTH_LOCK_HA
(
ha
,
flags
);
ha
->
raw
[
i
].
lock
=
1
;
GDTH_UNLOCK_HA
(
ha
,
flags
);
for
(
j
=
0
;
j
<
ha
->
tid_cnt
;
++
j
)
{
gdth_wait_completion
(
lchn
.
ionode
,
i
,
j
);
gdth_stop_timeout
(
lchn
.
ionode
,
i
,
j
);
}
}
else
{
GDTH_LOCK_HA
(
ha
,
flags
);
ha
->
raw
[
i
].
lock
=
0
;
GDTH_UNLOCK_HA
(
ha
,
flags
);
for
(
j
=
0
;
j
<
ha
->
tid_cnt
;
++
j
)
{
gdth_start_timeout
(
lchn
.
ionode
,
i
,
j
);
gdth_next
(
lchn
.
ionode
);
}
}
}
break
;
}
case
GDTIOCTL_RESCAN
:
{
gdth_ioctl_rescan
rsc
;
gdth_cmd_str
cmd
;
ushort
i
,
status
,
hdr_cnt
;
ulong32
info
;
int
hanum
,
cyls
,
hds
,
secs
;
if
(
copy_from_user
(
&
rsc
,
(
char
*
)
arg
,
sizeof
(
gdth_ioctl_rescan
))
||
rsc
.
ionode
>=
gdth_ctr_count
)
return
-
EFAULT
;
hanum
=
rsc
.
ionode
;
ha
=
HADATA
(
gdth_ctr_tab
[
hanum
]);
#if LINUX_VERSION_CODE >= 0x020503
sdev
=
scsi_get_host_dev
(
gdth_ctr_tab
[
hanum
]);
srp
=
scsi_allocate_request
(
sdev
);
if
(
!
srp
)
return
-
ENOMEM
;
srp
->
sr_cmd_len
=
12
;
srp
->
sr_use_sg
=
0
;
#elif LINUX_VERSION_CODE >= 0x020322
sdev
=
scsi_get_host_dev
(
gdth_ctr_tab
[
hanum
]);
scp
=
scsi_allocate_device
(
sdev
,
1
,
FALSE
);
if
(
!
scp
)
return
-
ENOMEM
;
scp
->
cmd_len
=
12
;
scp
->
use_sg
=
0
;
#else
memset
(
&
sdev
,
0
,
sizeof
(
Scsi_Device
));
memset
(
&
scp
,
0
,
sizeof
(
Scsi_Cmnd
));
sdev
.
host
=
scp
.
host
=
gdth_ctr_tab
[
hanum
];
sdev
.
id
=
scp
.
target
=
sdev
.
host
->
this_id
;
scp
.
device
=
&
sdev
;
#endif
if
(
rsc
.
flag
==
0
)
{
/* old method: re-init. cache service */
cmd
.
Service
=
CACHESERVICE
;
cmd
.
OpCode
=
GDT_INIT
;
cmd
.
u
.
cache
.
DeviceNo
=
LINUX_OS
;
#if LINUX_VERSION_CODE >= 0x020503
gdth_do_req
(
srp
,
&
cmd
,
cmnd
,
30
);
status
=
(
ushort
)
srp
->
sr_command
->
SCp
.
Status
;
info
=
(
ulong32
)
srp
->
sr_command
->
SCp
.
Message
;
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd
(
scp
,
&
cmd
,
cmnd
,
30
);
status
=
(
ushort
)
scp
->
SCp
.
Status
;
info
=
(
ulong32
)
scp
->
SCp
.
Message
;
#else
gdth_do_cmd
(
&
scp
,
&
cmd
,
cmnd
,
30
);
status
=
(
ushort
)
scp
.
SCp
.
Status
;
info
=
(
ulong32
)
scp
.
SCp
.
Message
;
#endif
i
=
0
;
hdr_cnt
=
(
status
==
S_OK
?
(
ushort
)
info
:
0
);
}
else
{
i
=
rsc
.
hdr_no
;
hdr_cnt
=
i
+
1
;
}
for
(;
i
<
hdr_cnt
&&
i
<
MAX_HDRIVES
;
++
i
)
{
cmd
.
Service
=
CACHESERVICE
;
cmd
.
OpCode
=
GDT_INFO
;
cmd
.
u
.
cache
.
DeviceNo
=
i
;
#if LINUX_VERSION_CODE >= 0x020503
gdth_do_req
(
srp
,
&
cmd
,
cmnd
,
30
);
status
=
(
ushort
)
srp
->
sr_command
->
SCp
.
Status
;
info
=
(
ulong32
)
srp
->
sr_command
->
SCp
.
Message
;
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd
(
scp
,
&
cmd
,
cmnd
,
30
);
status
=
(
ushort
)
scp
->
SCp
.
Status
;
info
=
(
ulong32
)
scp
->
SCp
.
Message
;
#else
gdth_do_cmd
(
&
scp
,
&
cmd
,
cmnd
,
30
);
status
=
(
ushort
)
scp
.
SCp
.
Status
;
info
=
(
ulong32
)
scp
.
SCp
.
Message
;
#endif
GDTH_LOCK_HA
(
ha
,
flags
);
rsc
.
hdr_list
[
i
].
bus
=
ha
->
virt_bus
;
rsc
.
hdr_list
[
i
].
target
=
i
;
rsc
.
hdr_list
[
i
].
lun
=
0
;
if
(
status
!=
S_OK
)
{
ha
->
hdr
[
i
].
present
=
FALSE
;
}
else
{
ha
->
hdr
[
i
].
present
=
TRUE
;
ha
->
hdr
[
i
].
size
=
info
;
/* evaluate mapping */
ha
->
hdr
[
i
].
size
&=
~
SECS32
;
gdth_eval_mapping
(
ha
->
hdr
[
i
].
size
,
&
cyls
,
&
hds
,
&
secs
);
ha
->
hdr
[
i
].
heads
=
hds
;
ha
->
hdr
[
i
].
secs
=
secs
;
/* round size */
ha
->
hdr
[
i
].
size
=
cyls
*
hds
*
secs
;
}
GDTH_UNLOCK_HA
(
ha
,
flags
);
if
(
status
!=
S_OK
)
continue
;
/* devtype, cluster info, R/W attribs */
cmd
.
Service
=
CACHESERVICE
;
cmd
.
OpCode
=
GDT_DEVTYPE
;
cmd
.
u
.
cache
.
DeviceNo
=
i
;
#if LINUX_VERSION_CODE >= 0x020503
gdth_do_req
(
srp
,
&
cmd
,
cmnd
,
30
);
status
=
(
ushort
)
srp
->
sr_command
->
SCp
.
Status
;
info
=
(
ulong32
)
srp
->
sr_command
->
SCp
.
Message
;
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd
(
scp
,
&
cmd
,
cmnd
,
30
);
status
=
(
ushort
)
scp
->
SCp
.
Status
;
info
=
(
ulong32
)
scp
->
SCp
.
Message
;
#else
gdth_do_cmd
(
&
scp
,
&
cmd
,
cmnd
,
30
);
status
=
(
ushort
)
scp
.
SCp
.
Status
;
info
=
(
ulong32
)
scp
.
SCp
.
Message
;
#endif
GDTH_LOCK_HA
(
ha
,
flags
);
ha
->
hdr
[
i
].
devtype
=
(
status
==
S_OK
?
(
ushort
)
info
:
0
);
GDTH_UNLOCK_HA
(
ha
,
flags
);
cmd
.
Service
=
CACHESERVICE
;
cmd
.
OpCode
=
GDT_CLUST_INFO
;
cmd
.
u
.
cache
.
DeviceNo
=
i
;
#if LINUX_VERSION_CODE >= 0x020503
gdth_do_req
(
srp
,
&
cmd
,
cmnd
,
30
);
status
=
(
ushort
)
srp
->
sr_command
->
SCp
.
Status
;
info
=
(
ulong32
)
srp
->
sr_command
->
SCp
.
Message
;
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd
(
scp
,
&
cmd
,
cmnd
,
30
);
status
=
(
ushort
)
scp
->
SCp
.
Status
;
info
=
(
ulong32
)
scp
->
SCp
.
Message
;
#else
gdth_do_cmd
(
&
scp
,
&
cmd
,
cmnd
,
30
);
status
=
(
ushort
)
scp
.
SCp
.
Status
;
info
=
(
ulong32
)
scp
.
SCp
.
Message
;
#endif
GDTH_LOCK_HA
(
ha
,
flags
);
ha
->
hdr
[
i
].
cluster_type
=
((
status
==
S_OK
&&
!
shared_access
)
?
(
ushort
)
info
:
0
);
GDTH_UNLOCK_HA
(
ha
,
flags
);
rsc
.
hdr_list
[
i
].
cluster_type
=
ha
->
hdr
[
i
].
cluster_type
;
cmd
.
Service
=
CACHESERVICE
;
cmd
.
OpCode
=
GDT_RW_ATTRIBS
;
cmd
.
u
.
cache
.
DeviceNo
=
i
;
#if LINUX_VERSION_CODE >= 0x020503
gdth_do_req
(
srp
,
&
cmd
,
cmnd
,
30
);
status
=
(
ushort
)
srp
->
sr_command
->
SCp
.
Status
;
info
=
(
ulong32
)
srp
->
sr_command
->
SCp
.
Message
;
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd
(
scp
,
&
cmd
,
cmnd
,
30
);
status
=
(
ushort
)
scp
->
SCp
.
Status
;
info
=
(
ulong32
)
scp
->
SCp
.
Message
;
#else
gdth_do_cmd
(
&
scp
,
&
cmd
,
cmnd
,
30
);
status
=
(
ushort
)
scp
.
SCp
.
Status
;
info
=
(
ulong32
)
scp
.
SCp
.
Message
;
#endif
GDTH_LOCK_HA
(
ha
,
flags
);
ha
->
hdr
[
i
].
rw_attribs
=
(
status
==
S_OK
?
(
ushort
)
info
:
0
);
GDTH_UNLOCK_HA
(
ha
,
flags
);
}
#if LINUX_VERSION_CODE >= 0x020503
scsi_release_request
(
srp
);
scsi_free_host_dev
(
sdev
);
#elif LINUX_VERSION_CODE >= 0x020322
scsi_release_command
(
scp
);
scsi_free_host_dev
(
sdev
);
#endif
if
(
copy_to_user
((
char
*
)
arg
,
&
rsc
,
sizeof
(
gdth_ioctl_rescan
)))
return
-
EFAULT
;
break
;
}
case
GDTIOCTL_HDRLIST
:
{
gdth_ioctl_rescan
rsc
;
gdth_cmd_str
cmd
;
gdth_ha_str
*
ha
;
unchar
i
;
int
hanum
;
if
(
copy_from_user
(
&
rsc
,
(
char
*
)
arg
,
sizeof
(
gdth_ioctl_rescan
))
||
rsc
.
ionode
>=
gdth_ctr_count
)
return
-
EFAULT
;
hanum
=
rsc
.
ionode
;
ha
=
HADATA
(
gdth_ctr_tab
[
hanum
]);
#if LINUX_VERSION_CODE >= 0x020503
sdev
=
scsi_get_host_dev
(
gdth_ctr_tab
[
hanum
]);
srp
=
scsi_allocate_request
(
sdev
);
if
(
!
srp
)
return
-
ENOMEM
;
srp
->
sr_cmd_len
=
12
;
srp
->
sr_use_sg
=
0
;
#elif LINUX_VERSION_CODE >= 0x020322
sdev
=
scsi_get_host_dev
(
gdth_ctr_tab
[
hanum
]);
scp
=
scsi_allocate_device
(
sdev
,
1
,
FALSE
);
if
(
!
scp
)
return
-
ENOMEM
;
scp
->
cmd_len
=
12
;
scp
->
use_sg
=
0
;
#else
memset
(
&
sdev
,
0
,
sizeof
(
Scsi_Device
));
memset
(
&
scp
,
0
,
sizeof
(
Scsi_Cmnd
));
sdev
.
host
=
scp
.
host
=
gdth_ctr_tab
[
hanum
];
sdev
.
id
=
scp
.
target
=
sdev
.
host
->
this_id
;
scp
.
device
=
&
sdev
;
#endif
for
(
i
=
0
;
i
<
MAX_HDRIVES
;
++
i
)
{
if
(
!
ha
->
hdr
[
i
].
present
)
{
rsc
.
hdr_list
[
i
].
bus
=
0xff
;
continue
;
}
rsc
.
hdr_list
[
i
].
bus
=
ha
->
virt_bus
;
rsc
.
hdr_list
[
i
].
target
=
i
;
rsc
.
hdr_list
[
i
].
lun
=
0
;
rsc
.
hdr_list
[
i
].
cluster_type
=
ha
->
hdr
[
i
].
cluster_type
;
if
(
ha
->
hdr
[
i
].
cluster_type
&
CLUSTER_DRIVE
)
{
cmd
.
Service
=
CACHESERVICE
;
cmd
.
OpCode
=
GDT_CLUST_INFO
;
cmd
.
u
.
cache
.
DeviceNo
=
i
;
#if LINUX_VERSION_CODE >= 0x020503
gdth_do_req
(
srp
,
&
cmd
,
cmnd
,
30
);
if
(
srp
->
sr_command
->
SCp
.
Status
==
S_OK
)
rsc
.
hdr_list
[
i
].
cluster_type
=
srp
->
sr_command
->
SCp
.
Message
;
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd
(
scp
,
&
cmd
,
cmnd
,
30
);
if
(
scp
->
SCp
.
Status
==
S_OK
)
rsc
.
hdr_list
[
i
].
cluster_type
=
scp
->
SCp
.
Message
;
#else
gdth_do_cmd
(
&
scp
,
&
cmd
,
cmnd
,
30
);
if
(
scp
.
SCp
.
Status
==
S_OK
)
rsc
.
hdr_list
[
i
].
cluster_type
=
scp
.
SCp
.
Message
;
#endif
}
}
#if LINUX_VERSION_CODE >= 0x020503
scsi_release_request
(
srp
);
scsi_free_host_dev
(
sdev
);
#elif LINUX_VERSION_CODE >= 0x020322
scsi_release_command
(
scp
);
scsi_free_host_dev
(
sdev
);
#endif
if
(
copy_to_user
((
char
*
)
arg
,
&
rsc
,
sizeof
(
gdth_ioctl_rescan
)))
return
-
EFAULT
;
break
;
}
case
GDTIOCTL_RESET_BUS
:
{
gdth_ioctl_reset
res
;
int
hanum
,
rval
;
if
(
copy_from_user
(
&
res
,
(
char
*
)
arg
,
sizeof
(
gdth_ioctl_reset
))
||
res
.
ionode
>=
gdth_ctr_count
)
return
-
EFAULT
;
hanum
=
res
.
ionode
;
/* Because we need a Scsi_Cmnd struct., we make a scsi_allocate device also for kernels >=2.5.x */
#if LINUX_VERSION_CODE >= 0x02053C
sdev
=
scsi_get_host_dev
(
gdth_ctr_tab
[
hanum
]);
scp
=
scsi_get_command
(
sdev
,
GFP_KERNEL
);
if
(
!
scp
)
return
-
ENOMEM
;
scp
->
cmd_len
=
12
;
scp
->
use_sg
=
0
;
scp
->
device
->
channel
=
virt_ctr
?
0
:
res
.
number
;
rval
=
gdth_eh_bus_reset
(
scp
);
res
.
status
=
(
rval
==
SUCCESS
?
S_OK
:
S_GENERR
);
scsi_put_command
(
scp
);
scsi_free_host_dev
(
sdev
);
#elif LINUX_VERSION_CODE >= 0x020322
sdev
=
scsi_get_host_dev
(
gdth_ctr_tab
[
hanum
]);
#if LINUX_VERSION_CODE >= 0x020503
scp
=
scsi_allocate_device
(
sdev
,
1
);
#else
scp
=
scsi_allocate_device
(
sdev
,
1
,
FALSE
);
#endif
if
(
!
scp
)
return
-
ENOMEM
;
scp
->
cmd_len
=
12
;
scp
->
use_sg
=
0
;
scp
->
channel
=
virt_ctr
?
0
:
res
.
number
;
rval
=
gdth_eh_bus_reset
(
scp
);
res
.
status
=
(
rval
==
SUCCESS
?
S_OK
:
S_GENERR
);
scsi_release_command
(
scp
);
scsi_free_host_dev
(
sdev
);
#elif LINUX_VERSION_CODE >= 0x02015F
memset
(
&
sdev
,
0
,
sizeof
(
Scsi_Device
));
memset
(
&
scp
,
0
,
sizeof
(
Scsi_Cmnd
));
sdev
.
host
=
scp
.
host
=
gdth_ctr_tab
[
hanum
];
sdev
.
id
=
scp
.
target
=
sdev
.
host
->
this_id
;
scp
.
device
=
&
sdev
;
scp
.
channel
=
virt_ctr
?
0
:
res
.
number
;
rval
=
gdth_eh_bus_reset
(
&
scp
);
res
.
status
=
(
rval
==
SUCCESS
?
S_OK
:
S_GENERR
);
#else
res
.
status
=
S_OK
;
#endif
if
(
copy_to_user
((
char
*
)
arg
,
&
res
,
sizeof
(
gdth_ioctl_reset
)))
return
-
EFAULT
;
break
;
}
case
GDTIOCTL_RESET_DRV
:
{
gdth_ioctl_reset
res
;
gdth_cmd_str
cmd
;
int
hanum
;
if
(
copy_from_user
(
&
res
,
(
char
*
)
arg
,
sizeof
(
gdth_ioctl_reset
))
||
res
.
ionode
>=
gdth_ctr_count
||
res
.
number
>=
MAX_HDRIVES
)
return
-
EFAULT
;
hanum
=
res
.
ionode
;
ha
=
HADATA
(
gdth_ctr_tab
[
hanum
]);
if
(
!
ha
->
hdr
[
res
.
number
].
present
)
return
0
;
cmd
.
Service
=
CACHESERVICE
;
cmd
.
OpCode
=
GDT_CLUST_RESET
;
cmd
.
u
.
cache
.
DeviceNo
=
res
.
number
;
#if LINUX_VERSION_CODE >= 0x020503
sdev
=
scsi_get_host_dev
(
gdth_ctr_tab
[
hanum
]);
srp
=
scsi_allocate_request
(
sdev
);
if
(
!
srp
)
return
-
ENOMEM
;
srp
->
sr_cmd_len
=
12
;
srp
->
sr_use_sg
=
0
;
gdth_do_req
(
srp
,
&
cmd
,
cmnd
,
30
);
res
.
status
=
(
ushort
)
srp
->
sr_command
->
SCp
.
Status
;
scsi_release_request
(
srp
);
scsi_free_host_dev
(
sdev
);
#elif LINUX_VERSION_CODE >= 0x020322
sdev
=
scsi_get_host_dev
(
gdth_ctr_tab
[
hanum
]);
scp
=
scsi_allocate_device
(
sdev
,
1
,
FALSE
);
if
(
!
scp
)
return
-
ENOMEM
;
scp
->
cmd_len
=
12
;
scp
->
use_sg
=
0
;
gdth_do_cmd
(
scp
,
&
cmd
,
cmnd
,
30
);
res
.
status
=
(
ushort
)
scp
->
SCp
.
Status
;
scsi_release_command
(
scp
);
scsi_free_host_dev
(
sdev
);
#else
memset
(
&
sdev
,
0
,
sizeof
(
Scsi_Device
));
memset
(
&
scp
,
0
,
sizeof
(
Scsi_Cmnd
));
sdev
.
host
=
scp
.
host
=
gdth_ctr_tab
[
hanum
];
sdev
.
id
=
scp
.
target
=
sdev
.
host
->
this_id
;
scp
.
device
=
&
sdev
;
gdth_do_cmd
(
&
scp
,
&
cmd
,
cmnd
,
30
);
res
.
status
=
(
ushort
)
scp
.
SCp
.
Status
;
#endif
if
(
copy_to_user
((
char
*
)
arg
,
&
res
,
sizeof
(
gdth_ioctl_reset
)))
return
-
EFAULT
;
break
;
}
default:
break
;
}
return
0
;
}
#endif
#if LINUX_VERSION_CODE >= 0x010300
/* flush routine */
static
void
gdth_flush
(
int
hanum
)
...
...
@@ -4622,7 +5547,10 @@ static void gdth_flush(int hanum)
int
i
;
gdth_ha_str
*
ha
;
gdth_cmd_str
gdtcmd
;
#if LINUX_VERSION_CODE >= 0x020322
#if LINUX_VERSION_CODE >= 0x020503
Scsi_Request
*
srp
;
Scsi_Device
*
sdev
;
#elif LINUX_VERSION_CODE >= 0x020322
Scsi_Cmnd
*
scp
;
Scsi_Device
*
sdev
;
#else
...
...
@@ -4635,9 +5563,18 @@ static void gdth_flush(int hanum)
TRACE2
((
"gdth_flush() hanum %d
\n
"
,
hanum
));
ha
=
HADATA
(
gdth_ctr_tab
[
hanum
]);
#if LINUX_VERSION_CODE >= 0x020
322
#if LINUX_VERSION_CODE >= 0x020
503
sdev
=
scsi_get_host_dev
(
gdth_ctr_tab
[
hanum
]);
scp
=
scsi_get_command
(
sdev
,
GFP_KERNEL
);
srp
=
scsi_allocate_request
(
sdev
);
if
(
!
srp
)
return
;
srp
->
sr_cmd_len
=
12
;
srp
->
sr_use_sg
=
0
;
#elif LINUX_VERSION_CODE >= 0x020322
sdev
=
scsi_get_host_dev
(
gdth_ctr_tab
[
hanum
]);
scp
=
scsi_allocate_device
(
sdev
,
1
,
FALSE
);
if
(
!
scp
)
return
;
scp
->
cmd_len
=
12
;
scp
->
use_sg
=
0
;
#else
...
...
@@ -4657,15 +5594,20 @@ static void gdth_flush(int hanum)
gdtcmd
.
u
.
cache
.
BlockNo
=
1
;
gdtcmd
.
u
.
cache
.
sg_canz
=
0
;
TRACE2
((
"gdth_flush(): flush ha %d drive %d
\n
"
,
hanum
,
i
));
#if LINUX_VERSION_CODE >= 0x020322
#if LINUX_VERSION_CODE >= 0x020503
gdth_do_req
(
srp
,
&
gdtcmd
,
cmnd
,
30
);
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd
(
scp
,
&
gdtcmd
,
cmnd
,
30
);
#else
gdth_do_cmd
(
&
scp
,
&
gdtcmd
,
cmnd
,
30
);
#endif
}
}
#if LINUX_VERSION_CODE >= 0x020322
scsi_put_command
(
scp
);
#if LINUX_VERSION_CODE >= 0x020503
scsi_release_request
(
srp
);
scsi_free_host_dev
(
sdev
);
#elif LINUX_VERSION_CODE >= 0x020322
scsi_release_command
(
scp
);
scsi_free_host_dev
(
sdev
);
#endif
}
...
...
@@ -4680,7 +5622,10 @@ void gdth_halt(void)
int
hanum
;
#ifndef __alpha__
gdth_cmd_str
gdtcmd
;
#if LINUX_VERSION_CODE >= 0x020322
#if LINUX_VERSION_CODE >= 0x020503
Scsi_Request
*
srp
;
Scsi_Device
*
sdev
;
#elif LINUX_VERSION_CODE >= 0x020322
Scsi_Cmnd
*
scp
;
Scsi_Device
*
sdev
;
#else
...
...
@@ -4702,6 +5647,7 @@ void gdth_halt(void)
}
halt_called
=
TRUE
;
#endif
printk
(
"GDT: Flushing all host drives .. "
);
for
(
hanum
=
0
;
hanum
<
gdth_ctr_count
;
++
hanum
)
{
gdth_flush
(
hanum
);
...
...
@@ -4709,28 +5655,48 @@ void gdth_halt(void)
#ifndef __alpha__
/* controller reset */
memset
(
cmnd
,
0xff
,
MAX_COMMAND_SIZE
);
#if LINUX_VERSION_CODE >= 0x020322
gdtcmd
.
BoardNode
=
LOCALBOARD
;
gdtcmd
.
Service
=
CACHESERVICE
;
gdtcmd
.
OpCode
=
GDT_RESET
;
TRACE2
((
"gdth_halt(): reset controller %d
\n
"
,
hanum
));
#if LINUX_VERSION_CODE >= 0x020503
sdev
=
scsi_get_host_dev
(
gdth_ctr_tab
[
hanum
]);
scp
=
scsi_get_command
(
sdev
,
GFP_KERNEL
);
srp
=
scsi_allocate_request
(
sdev
);
if
(
!
srp
)
{
#if LINUX_VERSION_CODE >= 0x020100
unregister_reboot_notifier
(
&
gdth_notifier
);
return
NOTIFY_OK
;
#else
return
;
#endif
}
srp
->
sr_cmd_len
=
12
;
srp
->
sr_use_sg
=
0
;
gdth_do_req
(
srp
,
&
gdtcmd
,
cmnd
,
10
);
scsi_release_request
(
srp
);
scsi_free_host_dev
(
sdev
);
#elif LINUX_VERSION_CODE >= 0x020322
sdev
=
scsi_get_host_dev
(
gdth_ctr_tab
[
hanum
]);
scp
=
scsi_allocate_device
(
sdev
,
1
,
FALSE
);
if
(
!
scp
)
{
#if LINUX_VERSION_CODE >= 0x020100
unregister_reboot_notifier
(
&
gdth_notifier
);
return
NOTIFY_OK
;
#else
return
;
#endif
}
scp
->
cmd_len
=
12
;
scp
->
use_sg
=
0
;
gdth_do_cmd
(
scp
,
&
gdtcmd
,
cmnd
,
10
);
scsi_release_command
(
scp
);
scsi_free_host_dev
(
sdev
);
#else
memset
(
&
sdev
,
0
,
sizeof
(
Scsi_Device
));
memset
(
&
scp
,
0
,
sizeof
(
Scsi_Cmnd
));
sdev
.
host
=
scp
.
host
=
gdth_ctr_tab
[
hanum
];
sdev
.
id
=
scp
.
target
=
sdev
.
host
->
this_id
;
scp
.
device
=
&
sdev
;
#endif
gdtcmd
.
BoardNode
=
LOCALBOARD
;
gdtcmd
.
Service
=
CACHESERVICE
;
gdtcmd
.
OpCode
=
GDT_RESET
;
TRACE2
((
"gdth_halt(): reset controller %d
\n
"
,
hanum
));
#if LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd
(
scp
,
&
gdtcmd
,
cmnd
,
10
);
scsi_put_command
(
scp
);
scsi_free_host_dev
(
sdev
);
#else
gdth_do_cmd
(
&
scp
,
&
gdtcmd
,
cmnd
,
10
);
#endif
#endif
...
...
drivers/scsi/gdth.h
View file @
c83b4e61
...
...
@@ -10,7 +10,7 @@
*
* <achim.leubner@intel.com>
*
* $Id: gdth.h,v 1.4
6 2002/02/05 09:39:53
achim Exp $
* $Id: gdth.h,v 1.4
8 2003/02/27 14:58:22
achim Exp $
*/
#include <linux/version.h>
...
...
@@ -29,16 +29,16 @@
/* defines, macros */
/* driver version */
#define GDTH_VERSION_STR "2.0
5
"
#define GDTH_VERSION_STR "2.0
7
"
#define GDTH_VERSION 2
#define GDTH_SUBVERSION
5
#define GDTH_SUBVERSION
7
/* protocol version */
#define PROTOCOL_VERSION 1
/* OEM IDs */
#define OEM_ID_ICP
0x941c
#define OEM_ID_INTEL
0x8000
#define OEM_ID_ICP
0x941c
#define OEM_ID_INTEL
0x8000
/* controller classes */
#define GDT_ISA 0x01
/* ISA controller */
...
...
@@ -134,12 +134,17 @@
#ifndef PCI_DEVICE_ID_VORTEX_GDTNEWRX
/* new GDT Rx Controller */
#define PCI_DEVICE_ID_VORTEX_GDTNEWRX
0x300
#define PCI_DEVICE_ID_VORTEX_GDTNEWRX
0x300
#endif
#ifndef PCI_DEVICE_ID_INTEL_SRC
/* Intel Storage RAID Controller */
#define PCI_DEVICE_ID_INTEL_SRC 0x600
#define PCI_DEVICE_ID_INTEL_SRC 0x600
#endif
#ifndef PCI_DEVICE_ID_INTEL_SRC_XSCALE
/* Intel Storage RAID Controller */
#define PCI_DEVICE_ID_INTEL_SRC_XSCALE 0x601
#endif
/* limits */
...
...
@@ -153,8 +158,6 @@
#define MAXID 127
#define MAXLUN 8
#define MAXBUS 6
#define MAX_HDRIVES 100
/* max. host drive count */
#define MAX_LDRIVES 255
/* max. log. drive count */
#define MAX_EVENTS 100
/* event buffer count */
#define MAX_RES_ARGS 40
/* device reservation,
must be a multiple of 4 */
...
...
@@ -254,6 +257,7 @@
#define CACHE_DRV_INFO 0x07
/* cache drive info */
#define BOARD_FEATURES 0x15
/* controller features */
#define BOARD_INFO 0x28
/* controller info */
#define CACHE_READ_OEM_STRING_RECORD 0x84
/* read OEM string record */
#define HOST_GET 0x10001L
/* get host drive list */
#define IO_CHANNEL 0x00020000L
/* default IO channel */
#define INVALID_CHANNEL 0x0000ffffL
/* invalid channel */
...
...
@@ -265,7 +269,7 @@
#define S_CACHE_UNKNOWN 12
/* cache serv.: drive unknown */
#define S_RAW_SCSI 12
/* raw serv.: target error */
#define S_RAW_ILL 0xff
/* raw serv.: illegal */
#define S_CACHE_RESERV
-24
/* cache: reserv. conflict */
#define S_CACHE_RESERV
-24
/* cache: reserv. conflict */
/* timeout values */
#define INIT_RETRIES 100000
/* 100000 * 1ms = 100s */
...
...
@@ -292,10 +296,15 @@
#define MAILBOXREG 0x0c90
/* mailbox reg. (16 bytes) */
#define EISAREG 0x0cc0
/* EISA configuration */
/* DMA memory mappings */
#define GDTH_MAP_NONE 0
#define GDTH_MAP_SINGLE 1
#define GDTH_MAP_SG 2
#define GDTH_MAP_IOCTL 3
/* other defines */
#define LINUX_OS 8
/* used for cache optim. */
#define SCATTER_GATHER 1
/* s/g feature */
#define GDTH_MAXSG 32
/* max. s/g elements */
#define SECS32 0x1f
/* round capacity */
#define BIOS_ID_OFFS 0x10
/* offset contr-ID in ISABIOS */
#define LOCALBOARD 0
/* board node always 0 */
...
...
@@ -303,10 +312,7 @@
#define SPEZINDEX 1
/* cmd index unknown service */
#define GDT_WR_THROUGH 0x100
/* WRITE_THROUGH supported */
/* typedefs */
typedef
u32
ulong32
;
#define PACKED __attribute__((packed))
#include "gdth_ioctl.h"
/* screenservice message */
typedef
struct
{
...
...
@@ -535,6 +541,50 @@ typedef struct {
unchar
ld_error
;
/* error */
}
PACKED
gdth_cdrinfo_str
;
/* OEM string */
typedef
struct
{
ulong32
ctl_version
;
ulong32
file_major_version
;
ulong32
file_minor_version
;
ulong32
buffer_size
;
ulong32
cpy_count
;
ulong32
ext_error
;
ulong32
oem_id
;
ulong32
board_id
;
}
PACKED
gdth_oem_str_params
;
typedef
struct
{
unchar
product_0_1_name
[
16
];
unchar
product_4_5_name
[
16
];
unchar
product_cluster_name
[
16
];
unchar
product_reserved
[
16
];
unchar
scsi_cluster_target_vendor_id
[
16
];
unchar
cluster_raid_fw_name
[
16
];
unchar
oem_brand_name
[
16
];
unchar
oem_raid_type
[
16
];
unchar
bios_type
[
13
];
unchar
bios_title
[
50
];
unchar
oem_company_name
[
37
];
ulong32
pci_id_1
;
ulong32
pci_id_2
;
unchar
validation_status
[
80
];
unchar
reserved_1
[
4
];
unchar
scsi_host_drive_inquiry_vendor_id
[
16
];
unchar
library_file_template
[
16
];
unchar
reserved_2
[
16
];
unchar
tool_name_1
[
32
];
unchar
tool_name_2
[
32
];
unchar
tool_name_3
[
32
];
unchar
oem_contact_1
[
84
];
unchar
oem_contact_2
[
84
];
unchar
oem_contact_3
[
84
];
}
PACKED
gdth_oem_str
;
typedef
struct
{
gdth_oem_str_params
params
;
gdth_oem_str
text
;
}
PACKED
gdth_oem_str_ioctl
;
/* board features */
typedef
struct
{
unchar
chaining
;
/* Chaining supported */
...
...
@@ -594,118 +644,6 @@ typedef struct {
gdth_hentry_str
entry
[
MAX_HDRIVES
];
/* entries */
}
PACKED
gdth_hget_str
;
/* scatter/gather element */
typedef
struct
{
ulong32
sg_ptr
;
/* address */
ulong32
sg_len
;
/* length */
}
PACKED
gdth_sg_str
;
/* command structure */
typedef
struct
{
ulong32
BoardNode
;
/* board node (always 0) */
ulong32
CommandIndex
;
/* command number */
ushort
OpCode
;
/* the command (READ,..) */
union
{
struct
{
ushort
DeviceNo
;
/* number of cache drive */
ulong32
BlockNo
;
/* block number */
ulong32
BlockCnt
;
/* block count */
ulong32
DestAddr
;
/* dest. addr. (if s/g: -1) */
ulong32
sg_canz
;
/* s/g element count */
gdth_sg_str
sg_lst
[
GDTH_MAXSG
];
/* s/g list */
}
PACKED
cache
;
/* cache service cmd. str. */
struct
{
ushort
param_size
;
/* size of p_param buffer */
ulong32
subfunc
;
/* IOCTL function */
ulong32
channel
;
/* device */
ulong32
p_param
;
/* buffer */
}
PACKED
ioctl
;
/* IOCTL command structure */
struct
{
ushort
reserved
;
union
{
struct
{
ulong32
msg_handle
;
/* message handle */
ulong32
msg_addr
;
/* message buffer address */
}
PACKED
msg
;
unchar
data
[
12
];
/* buffer for rtc data, ... */
}
su
;
}
PACKED
screen
;
/* screen service cmd. str. */
struct
{
ushort
reserved
;
ulong32
direction
;
/* data direction */
ulong32
mdisc_time
;
/* disc. time (0: no timeout)*/
ulong32
mcon_time
;
/* connect time(0: no to.) */
ulong32
sdata
;
/* dest. addr. (if s/g: -1) */
ulong32
sdlen
;
/* data length (bytes) */
ulong32
clen
;
/* SCSI cmd. length(6,10,12) */
unchar
cmd
[
12
];
/* SCSI command */
unchar
target
;
/* target ID */
unchar
lun
;
/* LUN */
unchar
bus
;
/* SCSI bus number */
unchar
priority
;
/* only 0 used */
ulong32
sense_len
;
/* sense data length */
ulong32
sense_data
;
/* sense data addr. */
ulong32
link_p
;
/* linked cmds (not supp.) */
ulong32
sg_ranz
;
/* s/g element count */
gdth_sg_str
sg_lst
[
GDTH_MAXSG
];
/* s/g list */
}
PACKED
raw
;
/* raw service cmd. struct. */
}
u
;
/* additional variables */
unchar
Service
;
/* controller service */
ushort
Status
;
/* command result */
ulong32
Info
;
/* additional information */
Scsi_Cmnd
*
RequestBuffer
;
/* request buffer */
}
PACKED
gdth_cmd_str
;
/* controller event structure */
#define ES_ASYNC 1
#define ES_DRIVER 2
#define ES_TEST 3
#define ES_SYNC 4
typedef
struct
{
ushort
size
;
/* size of structure */
union
{
char
stream
[
16
];
struct
{
ushort
ionode
;
ushort
service
;
ulong32
index
;
}
PACKED
driver
;
struct
{
ushort
ionode
;
ushort
service
;
ushort
status
;
ulong32
info
;
unchar
scsi_coord
[
3
];
}
PACKED
async
;
struct
{
ushort
ionode
;
ushort
service
;
ushort
status
;
ulong32
info
;
ushort
hostdrive
;
unchar
scsi_coord
[
3
];
unchar
sense_key
;
}
PACKED
sync
;
struct
{
ulong32
l1
,
l2
,
l3
,
l4
;
}
PACKED
test
;
}
eu
;
ulong32
severity
;
unchar
event_string
[
256
];
}
PACKED
gdth_evt_data
;
typedef
struct
{
ulong32
first_stamp
;
ulong32
last_stamp
;
ushort
same_count
;
ushort
event_source
;
ushort
event_idx
;
unchar
application
;
unchar
reserved
;
gdth_evt_data
event_data
;
}
PACKED
gdth_evt_str
;
/* DPRAM structures */
...
...
@@ -889,7 +827,9 @@ typedef struct {
ulong32
brd_phys
;
/* slot number/BIOS address */
gdt6c_plx_regs
*
plx
;
/* PLX regs (new PCI contr.) */
gdth_cmd_str
*
pccb
;
/* address command structure */
ulong32
ccb_phys
;
/* phys. address */
char
*
pscratch
;
/* scratch (DMA) buffer */
ulong32
scratch_phys
;
/* phys. address */
unchar
scratch_busy
;
/* in use? */
unchar
scan_mode
;
/* current scan mode */
unchar
irq
;
/* IRQ */
...
...
@@ -946,6 +886,10 @@ typedef struct {
#if LINUX_VERSION_CODE >= 0x02015F
spinlock_t
smp_lock
;
#endif
#if LINUX_VERSION_CODE >= 0x020400
struct
pci_dev
*
pdev
;
#endif
char
oem_name
[
8
];
}
gdth_ha_str
;
/* structure for scsi_register(), SCSI bus != 0 */
...
...
@@ -1032,34 +976,145 @@ int gdth_reset(Scsi_Cmnd *);
#endif
const
char
*
gdth_info
(
struct
Scsi_Host
*
);
#if LINUX_VERSION_CODE >= 0x020501
int
gdth_bios_param
(
struct
scsi_device
*
,
struct
block_device
*
,
sector_t
,
int
*
);
int
gdth_proc_info
(
char
*
,
char
**
,
off_t
,
int
,
int
,
int
);
int
gdth_eh_abort
(
Scsi_Cmnd
*
scp
);
int
gdth_eh_device_reset
(
Scsi_Cmnd
*
scp
);
int
gdth_eh_bus_reset
(
Scsi_Cmnd
*
scp
);
int
gdth_eh_host_reset
(
Scsi_Cmnd
*
scp
);
#define GDTH { .proc_name = "gdth", \
.proc_info = gdth_proc_info, \
.name = "GDT SCSI Disk Array Controller",\
.detect = gdth_detect, \
.release = gdth_release, \
.info = gdth_info, \
.command = NULL, \
.queuecommand = gdth_queuecommand, \
.eh_abort_handler = gdth_eh_abort, \
.eh_device_reset_handler = gdth_eh_device_reset, \
.eh_bus_reset_handler = gdth_eh_bus_reset, \
.eh_host_reset_handler = gdth_eh_host_reset, \
.abort = gdth_abort, \
.reset = gdth_reset, \
.bios_param = gdth_bios_param, \
.can_queue = GDTH_MAXCMDS, \
.this_id = -1, \
.sg_tablesize = GDTH_MAXSG, \
.cmd_per_lun = GDTH_MAXC_P_L, \
.present = 0, \
.unchecked_isa_dma = 1, \
.use_clustering = ENABLE_CLUSTERING }
#define GDTH { .proc_name = "gdth", \
.proc_info = gdth_proc_info, \
.name = "GDT SCSI Disk Array Controller",\
.detect = gdth_detect, \
.release = gdth_release, \
.info = gdth_info, \
.command = NULL, \
.queuecommand = gdth_queuecommand, \
.eh_abort_handler = gdth_eh_abort, \
.eh_device_reset_handler = gdth_eh_device_reset, \
.eh_bus_reset_handler = gdth_eh_bus_reset, \
.eh_host_reset_handler = gdth_eh_host_reset, \
.abort = NULL, \
.reset = NULL, \
.bios_param = gdth_bios_param, \
.can_queue = GDTH_MAXCMDS, \
.this_id = -1, \
.sg_tablesize = GDTH_MAXSG, \
.cmd_per_lun = GDTH_MAXC_P_L, \
.present = 0, \
.unchecked_isa_dma = 1, \
.use_clustering = ENABLE_CLUSTERING}
#elif LINUX_VERSION_CODE >= 0x020322
int
gdth_bios_param
(
Disk
*
,
kdev_t
,
int
*
);
int
gdth_proc_info
(
char
*
,
char
**
,
off_t
,
int
,
int
,
int
);
int
gdth_eh_abort
(
Scsi_Cmnd
*
scp
);
int
gdth_eh_device_reset
(
Scsi_Cmnd
*
scp
);
int
gdth_eh_bus_reset
(
Scsi_Cmnd
*
scp
);
int
gdth_eh_host_reset
(
Scsi_Cmnd
*
scp
);
#define GDTH { proc_name: "gdth", \
proc_info: gdth_proc_info, \
name: "GDT SCSI Disk Array Controller",\
detect: gdth_detect, \
release: gdth_release, \
info: gdth_info, \
command: NULL, \
queuecommand: gdth_queuecommand, \
eh_abort_handler: gdth_eh_abort, \
eh_device_reset_handler: gdth_eh_device_reset, \
eh_bus_reset_handler: gdth_eh_bus_reset, \
eh_host_reset_handler: gdth_eh_host_reset, \
abort: gdth_abort, \
reset: gdth_reset, \
bios_param: gdth_bios_param, \
can_queue: GDTH_MAXCMDS, \
this_id: -1, \
sg_tablesize: GDTH_MAXSG, \
cmd_per_lun: GDTH_MAXC_P_L, \
present: 0, \
unchecked_isa_dma: 1, \
use_clustering: ENABLE_CLUSTERING, \
use_new_eh_code: 1
/* use new error code */
}
#elif LINUX_VERSION_CODE >= 0x02015F
int
gdth_bios_param
(
Disk
*
,
kdev_t
,
int
*
);
extern
struct
proc_dir_entry
proc_scsi_gdth
;
int
gdth_proc_info
(
char
*
,
char
**
,
off_t
,
int
,
int
,
int
);
int
gdth_eh_abort
(
Scsi_Cmnd
*
scp
);
int
gdth_eh_device_reset
(
Scsi_Cmnd
*
scp
);
int
gdth_eh_bus_reset
(
Scsi_Cmnd
*
scp
);
int
gdth_eh_host_reset
(
Scsi_Cmnd
*
scp
);
#define GDTH { proc_dir: &proc_scsi_gdth, \
proc_info: gdth_proc_info, \
name: "GDT SCSI Disk Array Controller",\
detect: gdth_detect, \
release: gdth_release, \
info: gdth_info, \
command: NULL, \
queuecommand: gdth_queuecommand, \
eh_abort_handler: gdth_eh_abort, \
eh_device_reset_handler: gdth_eh_device_reset, \
eh_bus_reset_handler: gdth_eh_bus_reset, \
eh_host_reset_handler: gdth_eh_host_reset, \
abort: gdth_abort, \
reset: gdth_reset, \
bios_param: gdth_bios_param, \
can_queue: GDTH_MAXCMDS, \
this_id: -1, \
sg_tablesize: GDTH_MAXSG, \
cmd_per_lun: GDTH_MAXC_P_L, \
present: 0, \
unchecked_isa_dma: 1, \
use_clustering: ENABLE_CLUSTERING, \
use_new_eh_code: 1
/* use new error code */
}
#elif LINUX_VERSION_CODE >= 0x010300
int
gdth_bios_param
(
Disk
*
,
kdev_t
,
int
*
);
extern
struct
proc_dir_entry
proc_scsi_gdth
;
int
gdth_proc_info
(
char
*
,
char
**
,
off_t
,
int
,
int
,
int
);
#define GDTH { NULL, NULL, \
&proc_scsi_gdth, \
gdth_proc_info, \
"GDT SCSI Disk Array Controller", \
gdth_detect, \
gdth_release, \
gdth_info, \
NULL, \
gdth_queuecommand, \
gdth_abort, \
gdth_reset, \
NULL, \
gdth_bios_param, \
GDTH_MAXCMDS, \
-1, \
GDTH_MAXSG, \
GDTH_MAXC_P_L, \
0, \
1, \
ENABLE_CLUSTERING}
#else
int
gdth_bios_param
(
Disk
*
,
int
,
int
*
);
#define GDTH { NULL, NULL, \
"GDT SCSI Disk Array Controller", \
gdth_detect, \
gdth_release, \
gdth_info, \
NULL, \
gdth_queuecommand, \
gdth_abort, \
gdth_reset, \
NULL, \
gdth_bios_param, \
GDTH_MAXCMDS, \
-1, \
GDTH_MAXSG, \
GDTH_MAXC_P_L, \
0, \
1, \
ENABLE_CLUSTERING}
#endif
#endif
drivers/scsi/gdth_ioctl.h
View file @
c83b4e61
...
...
@@ -2,7 +2,7 @@
#define _GDTH_IOCTL_H
/* gdth_ioctl.h
* $Id: gdth_ioctl.h,v 1.1
0 2001/05/22 06:28:59
achim Exp $
* $Id: gdth_ioctl.h,v 1.1
1 2003/02/27 14:59:03
achim Exp $
*/
/* IOCTLs */
...
...
@@ -23,8 +23,136 @@
#define GDTIOCTL_MAGIC 0xaffe0004
#define EVENT_SIZE 294
#define
MAX_HDRIVES 100
#define
GDTH_MAXSG 32
/* max. s/g elements */
#define MAX_LDRIVES 255
/* max. log. drive count */
#ifdef GDTH_IOCTL_PROC
#define MAX_HDRIVES 100
/* max. host drive count */
#else
#define MAX_HDRIVES MAX_LDRIVES
/* max. host drive count */
#endif
/* typedefs */
#ifdef __KERNEL__
typedef
u32
ulong32
;
#endif
#define PACKED __attribute__((packed))
/* scatter/gather element */
typedef
struct
{
ulong32
sg_ptr
;
/* address */
ulong32
sg_len
;
/* length */
}
PACKED
gdth_sg_str
;
/* command structure */
typedef
struct
{
ulong32
BoardNode
;
/* board node (always 0) */
ulong32
CommandIndex
;
/* command number */
ushort
OpCode
;
/* the command (READ,..) */
union
{
struct
{
ushort
DeviceNo
;
/* number of cache drive */
ulong32
BlockNo
;
/* block number */
ulong32
BlockCnt
;
/* block count */
ulong32
DestAddr
;
/* dest. addr. (if s/g: -1) */
ulong32
sg_canz
;
/* s/g element count */
gdth_sg_str
sg_lst
[
GDTH_MAXSG
];
/* s/g list */
}
PACKED
cache
;
/* cache service cmd. str. */
struct
{
ushort
param_size
;
/* size of p_param buffer */
ulong32
subfunc
;
/* IOCTL function */
ulong32
channel
;
/* device */
ulong32
p_param
;
/* buffer */
}
PACKED
ioctl
;
/* IOCTL command structure */
struct
{
ushort
reserved
;
union
{
struct
{
ulong32
msg_handle
;
/* message handle */
ulong32
msg_addr
;
/* message buffer address */
}
PACKED
msg
;
unchar
data
[
12
];
/* buffer for rtc data, ... */
}
su
;
}
PACKED
screen
;
/* screen service cmd. str. */
struct
{
ushort
reserved
;
ulong32
direction
;
/* data direction */
ulong32
mdisc_time
;
/* disc. time (0: no timeout)*/
ulong32
mcon_time
;
/* connect time(0: no to.) */
ulong32
sdata
;
/* dest. addr. (if s/g: -1) */
ulong32
sdlen
;
/* data length (bytes) */
ulong32
clen
;
/* SCSI cmd. length(6,10,12) */
unchar
cmd
[
12
];
/* SCSI command */
unchar
target
;
/* target ID */
unchar
lun
;
/* LUN */
unchar
bus
;
/* SCSI bus number */
unchar
priority
;
/* only 0 used */
ulong32
sense_len
;
/* sense data length */
ulong32
sense_data
;
/* sense data addr. */
ulong32
link_p
;
/* linked cmds (not supp.) */
ulong32
sg_ranz
;
/* s/g element count */
gdth_sg_str
sg_lst
[
GDTH_MAXSG
];
/* s/g list */
}
PACKED
raw
;
/* raw service cmd. struct. */
}
u
;
/* additional variables */
unchar
Service
;
/* controller service */
unchar
reserved
;
ushort
Status
;
/* command result */
ulong32
Info
;
/* additional information */
void
*
RequestBuffer
;
/* request buffer */
}
PACKED
gdth_cmd_str
;
/* controller event structure */
#define ES_ASYNC 1
#define ES_DRIVER 2
#define ES_TEST 3
#define ES_SYNC 4
typedef
struct
{
ushort
size
;
/* size of structure */
union
{
char
stream
[
16
];
struct
{
ushort
ionode
;
ushort
service
;
ulong32
index
;
}
PACKED
driver
;
struct
{
ushort
ionode
;
ushort
service
;
ushort
status
;
ulong32
info
;
unchar
scsi_coord
[
3
];
}
PACKED
async
;
struct
{
ushort
ionode
;
ushort
service
;
ushort
status
;
ulong32
info
;
ushort
hostdrive
;
unchar
scsi_coord
[
3
];
unchar
sense_key
;
}
PACKED
sync
;
struct
{
ulong32
l1
,
l2
,
l3
,
l4
;
}
PACKED
test
;
}
eu
;
ulong32
severity
;
unchar
event_string
[
256
];
}
PACKED
gdth_evt_data
;
typedef
struct
{
ulong32
first_stamp
;
ulong32
last_stamp
;
ushort
same_count
;
ushort
event_source
;
ushort
event_idx
;
unchar
application
;
unchar
reserved
;
gdth_evt_data
event_data
;
}
PACKED
gdth_evt_str
;
#ifdef GDTH_IOCTL_PROC
/* IOCTL structure (write) */
typedef
struct
{
ulong32
magic
;
/* IOCTL magic */
...
...
@@ -106,7 +234,82 @@ typedef struct {
}
hdr_list
[
MAX_HDRIVES
];
/* index is host drive number */
}
iu
;
}
gdth_iord_str
;
#endif
#ifdef GDTH_IOCTL_CHRDEV
/* GDTIOCTL_GENERAL */
typedef
struct
{
ushort
ionode
;
/* controller number */
ushort
timeout
;
/* timeout */
ulong32
info
;
/* error info */
ushort
status
;
/* status */
ulong
data_len
;
/* data buffer size */
ulong
sense_len
;
/* sense buffer size */
gdth_cmd_str
command
;
/* command */
}
gdth_ioctl_general
;
/* GDTIOCTL_LOCKDRV */
typedef
struct
{
ushort
ionode
;
/* controller number */
unchar
lock
;
/* lock/unlock */
unchar
drive_cnt
;
/* drive count */
ushort
drives
[
MAX_HDRIVES
];
/* drives */
}
gdth_ioctl_lockdrv
;
/* GDTIOCTL_LOCKCHN */
typedef
struct
{
ushort
ionode
;
/* controller number */
unchar
lock
;
/* lock/unlock */
unchar
channel
;
/* channel */
}
gdth_ioctl_lockchn
;
/* GDTIOCTL_OSVERS */
typedef
struct
{
unchar
version
;
/* OS version */
unchar
subversion
;
/* OS subversion */
ushort
revision
;
/* revision */
}
gdth_ioctl_osvers
;
/* GDTIOCTL_CTRTYPE */
typedef
struct
{
ushort
ionode
;
/* controller number */
unchar
type
;
/* controller type */
ushort
info
;
/* slot etc. */
ushort
oem_id
;
/* OEM ID */
ushort
bios_ver
;
/* not used */
ushort
access
;
/* not used */
ushort
ext_type
;
/* extended type */
ushort
device_id
;
/* device ID */
ushort
sub_device_id
;
/* sub device ID */
}
gdth_ioctl_ctrtype
;
/* GDTIOCTL_EVENT */
typedef
struct
{
ushort
ionode
;
int
erase
;
/* erase event? */
int
handle
;
/* event handle */
gdth_evt_str
event
;
}
gdth_ioctl_event
;
/* GDTIOCTL_RESCAN/GDTIOCTL_HDRLIST */
typedef
struct
{
ushort
ionode
;
/* controller number */
unchar
flag
;
/* add/remove */
ushort
hdr_no
;
/* drive no. */
struct
{
unchar
bus
;
/* SCSI bus */
unchar
target
;
/* target ID */
unchar
lun
;
/* LUN */
unchar
cluster_type
;
/* cluster properties */
}
hdr_list
[
MAX_HDRIVES
];
/* index is host drive number */
}
gdth_ioctl_rescan
;
/* GDTIOCTL_RESET_BUS/GDTIOCTL_RESET_DRV */
typedef
struct
{
ushort
ionode
;
/* controller number */
ushort
number
;
/* bus/host drive number */
ushort
status
;
/* status */
}
gdth_ioctl_reset
;
#endif
#endif
drivers/scsi/gdth_proc.c
View file @
c83b4e61
/* gdth_proc.c
* $Id: gdth_proc.c,v 1.3
3 2001/08/10 07:54:39
achim Exp $
* $Id: gdth_proc.c,v 1.3
5 2003/02/27 15:00:44
achim Exp $
*/
#include "gdth_ioctl.h"
#if LINUX_VERSION_CODE >= 0x020407
#include <linux/completion.h>
#endif
...
...
@@ -33,22 +32,33 @@ int gdth_proc_info(char *buffer,char **start,off_t offset,int length,
static
int
gdth_set_info
(
char
*
buffer
,
int
length
,
int
vh
,
int
hanum
,
int
busnum
)
{
int
ret_val
;
#if LINUX_VERSION_CODE >= 0x020322
int
ret_val
=
-
EINVAL
;
#if LINUX_VERSION_CODE >= 0x020503
Scsi_Request
*
scp
;
Scsi_Device
*
sdev
;
#elif LINUX_VERSION_CODE >= 0x020322
Scsi_Cmnd
*
scp
;
Scsi_Device
*
sdev
;
#else
Scsi_Cmnd
scp
;
Scsi_Device
sdev
;
#endif
#ifdef GDTH_IOCTL_PROC
gdth_iowr_str
*
piowr
;
TRACE2
((
"gdth_set_info() ha %d bus %d
\n
"
,
hanum
,
busnum
));
piowr
=
(
gdth_iowr_str
*
)
buffer
;
#endif
TRACE2
((
"gdth_set_info() ha %d bus %d
\n
"
,
hanum
,
busnum
));
#if LINUX_VERSION_CODE >= 0x020322
sdev
=
scsi_get_host_dev
(
gdth_ctr_vtab
[
vh
]);
scp
=
scsi_get_command
(
sdev
,
GFP_KERNEL
);
#if LINUX_VERSION_CODE >= 0x020503
sdev
=
scsi_get_host_dev
(
gdth_ctr_tab
[
hanum
]);
scp
=
scsi_allocate_request
(
sdev
);
if
(
!
scp
)
return
-
ENOMEM
;
scp
->
sr_cmd_len
=
12
;
scp
->
sr_use_sg
=
0
;
#elif LINUX_VERSION_CODE >= 0x020322
sdev
=
scsi_get_host_dev
(
gdth_ctr_tab
[
hanum
]);
scp
=
scsi_allocate_device
(
sdev
,
1
,
FALSE
);
if
(
!
scp
)
return
-
ENOMEM
;
scp
->
cmd_len
=
12
;
...
...
@@ -56,7 +66,7 @@ static int gdth_set_info(char *buffer,int length,int vh,int hanum,int busnum)
#else
memset
(
&
sdev
,
0
,
sizeof
(
Scsi_Device
));
memset
(
&
scp
,
0
,
sizeof
(
Scsi_Cmnd
));
sdev
.
host
=
scp
.
host
=
gdth_ctr_
vtab
[
vh
];
sdev
.
host
=
scp
.
host
=
gdth_ctr_
tab
[
hanum
];
sdev
.
id
=
scp
.
target
=
sdev
.
host
->
this_id
;
scp
.
device
=
&
sdev
;
#endif
...
...
@@ -66,6 +76,7 @@ static int gdth_set_info(char *buffer,int length,int vh,int hanum,int busnum)
buffer
+=
5
;
length
-=
5
;
ret_val
=
gdth_set_asc_info
(
buffer
,
length
,
hanum
,
scp
);
#ifdef GDTH_IOCTL_PROC
}
else
if
(
piowr
->
magic
==
GDTIOCTL_MAGIC
)
{
ret_val
=
gdth_set_bin_info
(
buffer
,
length
,
hanum
,
scp
);
}
else
{
...
...
@@ -75,19 +86,22 @@ static int gdth_set_info(char *buffer,int length,int vh,int hanum,int busnum)
printk
(
"GDT: Please update your driver.
\n
"
);
else
printk
(
"GDT: Please update your tool.
\n
"
);
ret_val
=
-
EINVAL
;
#endif
}
}
else
{
ret_val
=
-
EINVAL
;
}
#if LINUX_VERSION_CODE >= 0x020322
scsi_put_command
(
scp
);
#if LINUX_VERSION_CODE >= 0x020503
scsi_release_request
(
scp
);
scsi_free_host_dev
(
sdev
);
#elif LINUX_VERSION_CODE >= 0x020322
scsi_release_command
(
scp
);
scsi_free_host_dev
(
sdev
);
#endif
return
ret_val
;
}
#if LINUX_VERSION_CODE >= 0x020322
#if LINUX_VERSION_CODE >= 0x020503
static
int
gdth_set_asc_info
(
char
*
buffer
,
int
length
,
int
hanum
,
Scsi_Request
*
scp
)
#elif LINUX_VERSION_CODE >= 0x020322
static
int
gdth_set_asc_info
(
char
*
buffer
,
int
length
,
int
hanum
,
Scsi_Cmnd
*
scp
)
#else
static
int
gdth_set_asc_info
(
char
*
buffer
,
int
length
,
int
hanum
,
Scsi_Cmnd
scp
)
...
...
@@ -98,6 +112,7 @@ static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
gdth_ha_str
*
ha
;
gdth_cmd_str
gdtcmd
;
gdth_cpar_str
*
pcpar
;
ulong32
paddr
;
char
cmnd
[
MAX_COMMAND_SIZE
];
memset
(
cmnd
,
0xff
,
12
);
...
...
@@ -133,7 +148,9 @@ static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
gdtcmd
.
OpCode
=
GDT_FLUSH
;
gdtcmd
.
u
.
cache
.
DeviceNo
=
i
;
gdtcmd
.
u
.
cache
.
BlockNo
=
1
;
#if LINUX_VERSION_CODE >= 0x020322
#if LINUX_VERSION_CODE >= 0x020503
gdth_do_req
(
scp
,
&
gdtcmd
,
cmnd
,
30
);
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd
(
scp
,
&
gdtcmd
,
cmnd
,
30
);
#else
gdth_do_cmd
(
&
scp
,
&
gdtcmd
,
cmnd
,
30
);
...
...
@@ -178,23 +195,25 @@ static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
}
if
(
wb_mode
)
{
if
(
!
gdth_ioctl_alloc
(
hanum
,
sizeof
(
gdth_cpar_str
),
TRUE
))
if
(
!
gdth_ioctl_alloc
(
hanum
,
sizeof
(
gdth_cpar_str
),
TRUE
,
&
paddr
))
return
(
-
EBUSY
);
pcpar
=
(
gdth_cpar_str
*
)
ha
->
pscratch
;
memcpy
(
pcpar
,
&
ha
->
cpar
,
sizeof
(
gdth_cpar_str
)
);
gdtcmd
.
Service
=
CACHESERVICE
;
gdtcmd
.
OpCode
=
GDT_IOCTL
;
gdtcmd
.
u
.
ioctl
.
p_param
=
virt_to_bus
(
pcpar
)
;
gdtcmd
.
u
.
ioctl
.
p_param
=
paddr
;
gdtcmd
.
u
.
ioctl
.
param_size
=
sizeof
(
gdth_cpar_str
);
gdtcmd
.
u
.
ioctl
.
subfunc
=
CACHE_CONFIG
;
gdtcmd
.
u
.
ioctl
.
channel
=
INVALID_CHANNEL
;
pcpar
->
write_back
=
wb_mode
==
1
?
0
:
1
;
#if LINUX_VERSION_CODE >= 0x020322
#if LINUX_VERSION_CODE >= 0x020503
gdth_do_req
(
scp
,
&
gdtcmd
,
cmnd
,
30
);
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd
(
scp
,
&
gdtcmd
,
cmnd
,
30
);
#else
gdth_do_cmd
(
&
scp
,
&
gdtcmd
,
cmnd
,
30
);
#endif
gdth_ioctl_free
(
hanum
,
ha
->
pscratch
);
gdth_ioctl_free
(
hanum
,
GDTH_SCRATCH
,
ha
->
pscratch
,
paddr
);
printk
(
"Done.
\n
"
);
return
(
orig_length
);
}
...
...
@@ -203,7 +222,10 @@ static int gdth_set_asc_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
return
(
-
EINVAL
);
}
#if LINUX_VERSION_CODE >= 0x020322
#ifdef GDTH_IOCTL_PROC
#if LINUX_VERSION_CODE >= 0x020503
static
int
gdth_set_bin_info
(
char
*
buffer
,
int
length
,
int
hanum
,
Scsi_Request
*
scp
)
#elif LINUX_VERSION_CODE >= 0x020322
static
int
gdth_set_bin_info
(
char
*
buffer
,
int
length
,
int
hanum
,
Scsi_Cmnd
*
scp
)
#else
static
int
gdth_set_bin_info
(
char
*
buffer
,
int
length
,
int
hanum
,
Scsi_Cmnd
scp
)
...
...
@@ -216,7 +238,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
gdth_iord_str
*
piord
;
gdth_cmd_str
*
pcmd
;
gdth_evt_str
*
pevt
;
ulong32
*
ppadd
,
add_size
,
*
ppadd2
,
add_size2
,
info
;
ulong32
*
ppadd
,
add_size
,
*
ppadd2
,
add_size2
,
info
,
paddr
;
ulong
flags
;
gdth_cmd_str
gdtcmd
;
int
drv_cyls
,
drv_hds
,
drv_secs
;
...
...
@@ -273,21 +295,25 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
return
(
-
EINVAL
);
}
if
(
!
gdth_ioctl_alloc
(
hanum
,
sizeof
(
gdth_iord_str
)
+
add_size
+
add_size2
,
TRUE
))
TRUE
,
&
paddr
))
return
(
-
EBUSY
);
piord
=
(
gdth_iord_str
*
)
ha
->
pscratch
;
piord
->
size
=
sizeof
(
gdth_iord_str
)
+
add_size
+
add_size2
;
if
(
add_size
>
0
)
{
memcpy
(
piord
->
iu
.
general
.
data
,
piowr
->
iu
.
general
.
data
,
add_size
);
*
ppadd
=
virt_to_bus
(
piord
->
iu
.
general
.
data
);
*
ppadd
=
paddr
+
GDTOFFSOF
(
gdth_iord_str
,
iu
.
general
.
data
[
0
]
);
}
if
(
add_size2
>
0
)
{
memcpy
(
piord
->
iu
.
general
.
data
+
add_size
,
piowr
->
iu
.
general
.
data
,
add_size2
);
*
ppadd2
=
virt_to_bus
(
piord
->
iu
.
general
.
data
+
add_size
)
;
*
ppadd2
=
paddr
+
GDTOFFSOF
(
gdth_iord_str
,
iu
.
general
.
data
[
0
])
+
add_size2
;
}
/* do IOCTL */
#if LINUX_VERSION_CODE >= 0x020322
#if LINUX_VERSION_CODE >= 0x020503
gdth_do_req
(
scp
,
pcmd
,
cmnd
,
piowr
->
timeout
);
piord
->
status
=
(
scp
->
sr_command
->
SCp
.
Message
<<
16
)
|
scp
->
sr_command
->
SCp
.
Status
;
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd
(
scp
,
pcmd
,
cmnd
,
piowr
->
timeout
);
piord
->
status
=
(
scp
->
SCp
.
Message
<<
16
)
|
scp
->
SCp
.
Status
;
#else
...
...
@@ -297,7 +323,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
break
;
case
GDTIOCTL_DRVERS
:
if
(
!
gdth_ioctl_alloc
(
hanum
,
sizeof
(
gdth_iord_str
),
TRUE
))
if
(
!
gdth_ioctl_alloc
(
hanum
,
sizeof
(
gdth_iord_str
),
TRUE
,
&
paddr
))
return
(
-
EBUSY
);
piord
=
(
gdth_iord_str
*
)
ha
->
pscratch
;
piord
->
size
=
sizeof
(
gdth_iord_str
);
...
...
@@ -306,7 +332,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
break
;
case
GDTIOCTL_CTRTYPE
:
if
(
!
gdth_ioctl_alloc
(
hanum
,
sizeof
(
gdth_iord_str
),
TRUE
))
if
(
!
gdth_ioctl_alloc
(
hanum
,
sizeof
(
gdth_iord_str
),
TRUE
,
&
paddr
))
return
(
-
EBUSY
);
piord
=
(
gdth_iord_str
*
)
ha
->
pscratch
;
piord
->
size
=
sizeof
(
gdth_iord_str
);
...
...
@@ -332,7 +358,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
break
;
case
GDTIOCTL_CTRCNT
:
if
(
!
gdth_ioctl_alloc
(
hanum
,
sizeof
(
gdth_iord_str
),
TRUE
))
if
(
!
gdth_ioctl_alloc
(
hanum
,
sizeof
(
gdth_iord_str
),
TRUE
,
&
paddr
))
return
(
-
EBUSY
);
piord
=
(
gdth_iord_str
*
)
ha
->
pscratch
;
piord
->
size
=
sizeof
(
gdth_iord_str
);
...
...
@@ -341,7 +367,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
break
;
case
GDTIOCTL_OSVERS
:
if
(
!
gdth_ioctl_alloc
(
hanum
,
sizeof
(
gdth_iord_str
),
TRUE
))
if
(
!
gdth_ioctl_alloc
(
hanum
,
sizeof
(
gdth_iord_str
),
TRUE
,
&
paddr
))
return
(
-
EBUSY
);
piord
=
(
gdth_iord_str
*
)
ha
->
pscratch
;
piord
->
size
=
sizeof
(
gdth_iord_str
);
...
...
@@ -352,7 +378,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
break
;
case
GDTIOCTL_LOCKDRV
:
if
(
!
gdth_ioctl_alloc
(
hanum
,
sizeof
(
gdth_iord_str
),
TRUE
))
if
(
!
gdth_ioctl_alloc
(
hanum
,
sizeof
(
gdth_iord_str
),
TRUE
,
&
paddr
))
return
(
-
EBUSY
);
piord
=
(
gdth_iord_str
*
)
ha
->
pscratch
;
for
(
i
=
0
;
i
<
piowr
->
iu
.
lockdrv
.
drive_cnt
;
++
i
)
{
...
...
@@ -378,7 +404,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
break
;
case
GDTIOCTL_LOCKCHN
:
if
(
!
gdth_ioctl_alloc
(
hanum
,
sizeof
(
gdth_iord_str
),
TRUE
))
if
(
!
gdth_ioctl_alloc
(
hanum
,
sizeof
(
gdth_iord_str
),
TRUE
,
&
paddr
))
return
(
-
EBUSY
);
i
=
piowr
->
iu
.
lockchn
.
channel
;
if
(
i
<
ha
->
bus_cnt
)
{
...
...
@@ -406,7 +432,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
break
;
case
GDTIOCTL_EVENT
:
if
(
!
gdth_ioctl_alloc
(
hanum
,
sizeof
(
gdth_iord_str
),
TRUE
))
if
(
!
gdth_ioctl_alloc
(
hanum
,
sizeof
(
gdth_iord_str
),
TRUE
,
&
paddr
))
return
(
-
EBUSY
);
piord
=
(
gdth_iord_str
*
)
ha
->
pscratch
;
if
(
piowr
->
iu
.
event
.
erase
==
0xff
)
{
...
...
@@ -439,16 +465,19 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
piord
->
size
=
sizeof
(
gdth_iord_str
);
piord
->
status
=
S_OK
;
break
;
case
GDTIOCTL_SCSI
:
if
(
!
gdth_ioctl_alloc
(
hanum
,
sizeof
(
gdth_iord_str
),
TRUE
))
#if LINUX_VERSION_CODE >= 0x020503
return
(
-
EINVAL
);
#else
if
(
!
gdth_ioctl_alloc
(
hanum
,
sizeof
(
gdth_iord_str
),
TRUE
,
&
paddr
))
return
(
-
EBUSY
);
piord
=
(
gdth_iord_str
*
)
ha
->
pscratch
;
piord
->
size
=
sizeof
(
gdth_iord_str
);
memcpy
(
cmnd
,
piowr
->
iu
.
scsi
.
cmd
,
12
);
#if LINUX_VERSION_CODE >= 0x020322
scp
->
device
->
id
=
piowr
->
iu
.
scsi
.
target
;
scp
->
device
->
channel
=
virt_ctr
?
0
:
piowr
->
iu
.
scsi
.
bus
;
scp
->
target
=
piowr
->
iu
.
scsi
.
target
;
scp
->
channel
=
virt_ctr
?
0
:
piowr
->
iu
.
scsi
.
bus
;
scp
->
cmd_len
=
piowr
->
iu
.
scsi
.
cmd_len
;
gdth_do_cmd
(
scp
,
pcmd
,
cmnd
,
piowr
->
timeout
);
piord
->
status
=
(
scp
->
SCp
.
Message
<<
16
)
|
scp
->
SCp
.
Status
;
...
...
@@ -458,16 +487,48 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
scp
.
cmd_len
=
piowr
->
iu
.
scsi
.
cmd_len
;
gdth_do_cmd
(
&
scp
,
pcmd
,
cmnd
,
piowr
->
timeout
);
piord
->
status
=
(
scp
.
SCp
.
Message
<<
16
)
|
scp
.
SCp
.
Status
;
#endif
#endif
break
;
case
GDTIOCTL_RESET_BUS
:
if
(
!
gdth_ioctl_alloc
(
hanum
,
sizeof
(
gdth_iord_str
),
TRUE
))
if
(
!
gdth_ioctl_alloc
(
hanum
,
sizeof
(
gdth_iord_str
),
TRUE
,
&
paddr
))
return
(
-
EBUSY
);
piord
=
(
gdth_iord_str
*
)
ha
->
pscratch
;
piord
->
size
=
sizeof
(
gdth_iord_str
);
#if LINUX_VERSION_CODE >= 0x020322
scp
->
device
->
channel
=
virt_ctr
?
0
:
piowr
->
iu
.
scsi
.
bus
;
#if LINUX_VERSION_CODE >= 0x02053C
{
Scsi_Device
*
sdev
;
Scsi_Cmnd
*
scmnd
;
sdev
=
scsi_get_host_dev
(
gdth_ctr_tab
[
hanum
]);
scmnd
=
scsi_get_command
(
sdev
,
GFP_KERNEL
);
if
(
!
scmnd
)
return
(
-
ENOMEM
);
scmnd
->
device
->
host
=
scp
->
sr_host
;
scmnd
->
device
->
channel
=
virt_ctr
?
0
:
piowr
->
iu
.
scsi
.
bus
;
piord
->
status
=
(
ulong32
)
gdth_eh_bus_reset
(
scmnd
);
if
(
piord
->
status
==
SUCCESS
)
piord
->
status
=
S_OK
;
else
piord
->
status
=
S_GENERR
;
scsi_put_command
(
scmnd
);
scsi_free_host_dev
(
sdev
);
}
#elif LINUX_VERSION_CODE >= 0x020503
{
Scsi_Cmnd
scmnd
;
scmnd
.
host
=
scp
->
sr_host
;
scmnd
.
channel
=
virt_ctr
?
0
:
piowr
->
iu
.
scsi
.
bus
;
piord
->
status
=
(
ulong32
)
gdth_eh_bus_reset
(
&
scmnd
);
if
(
piord
->
status
==
SUCCESS
)
piord
->
status
=
S_OK
;
else
piord
->
status
=
S_GENERR
;
}
#elif LINUX_VERSION_CODE >= 0x020322
scp
->
channel
=
virt_ctr
?
0
:
piowr
->
iu
.
scsi
.
bus
;
piord
->
status
=
(
ulong32
)
gdth_eh_bus_reset
(
scp
);
if
(
piord
->
status
==
SUCCESS
)
piord
->
status
=
S_OK
;
...
...
@@ -486,7 +547,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
break
;
case
GDTIOCTL_HDRLIST
:
if
(
!
gdth_ioctl_alloc
(
hanum
,
sizeof
(
gdth_iord_str
),
TRUE
))
if
(
!
gdth_ioctl_alloc
(
hanum
,
sizeof
(
gdth_iord_str
),
TRUE
,
&
paddr
))
return
(
-
EBUSY
);
piord
=
(
gdth_iord_str
*
)
ha
->
pscratch
;
piord
->
size
=
sizeof
(
gdth_iord_str
);
...
...
@@ -501,7 +562,12 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
gdtcmd
.
Service
=
CACHESERVICE
;
gdtcmd
.
OpCode
=
GDT_CLUST_INFO
;
gdtcmd
.
u
.
cache
.
DeviceNo
=
i
;
#if LINUX_VERSION_CODE >= 0x020322
#if LINUX_VERSION_CODE >= 0x020503
gdth_do_req
(
scp
,
&
gdtcmd
,
cmnd
,
30
);
if
(
scp
->
sr_command
->
SCp
.
Status
==
S_OK
)
piord
->
iu
.
hdr_list
[
i
].
cluster_type
=
(
unchar
)
scp
->
sr_command
->
SCp
.
Message
;
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd
(
scp
,
&
gdtcmd
,
cmnd
,
30
);
if
(
scp
->
SCp
.
Status
==
S_OK
)
piord
->
iu
.
hdr_list
[
i
].
cluster_type
=
...
...
@@ -520,7 +586,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
break
;
case
GDTIOCTL_RESCAN
:
if
(
!
gdth_ioctl_alloc
(
hanum
,
sizeof
(
gdth_iord_str
),
TRUE
))
if
(
!
gdth_ioctl_alloc
(
hanum
,
sizeof
(
gdth_iord_str
),
TRUE
,
&
paddr
))
return
(
-
EBUSY
);
piord
=
(
gdth_iord_str
*
)
ha
->
pscratch
;
piord
->
size
=
sizeof
(
gdth_iord_str
);
...
...
@@ -532,7 +598,11 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
gdtcmd
.
Service
=
CACHESERVICE
;
gdtcmd
.
OpCode
=
GDT_INIT
;
gdtcmd
.
u
.
cache
.
DeviceNo
=
LINUX_OS
;
#if LINUX_VERSION_CODE >= 0x020322
#if LINUX_VERSION_CODE >= 0x020503
gdth_do_req
(
scp
,
&
gdtcmd
,
cmnd
,
30
);
status
=
(
ushort
)
scp
->
sr_command
->
SCp
.
Status
;
info
=
(
ulong32
)
scp
->
sr_command
->
SCp
.
Message
;
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd
(
scp
,
&
gdtcmd
,
cmnd
,
30
);
status
=
(
ushort
)
scp
->
SCp
.
Status
;
info
=
(
ulong32
)
scp
->
SCp
.
Message
;
...
...
@@ -557,7 +627,11 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
gdtcmd
.
Service
=
CACHESERVICE
;
gdtcmd
.
OpCode
=
GDT_INFO
;
gdtcmd
.
u
.
cache
.
DeviceNo
=
k
;
#if LINUX_VERSION_CODE >= 0x020322
#if LINUX_VERSION_CODE >= 0x020503
gdth_do_req
(
scp
,
&
gdtcmd
,
cmnd
,
30
);
status
=
(
ushort
)
scp
->
sr_command
->
SCp
.
Status
;
info
=
(
ulong32
)
scp
->
sr_command
->
SCp
.
Message
;
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd
(
scp
,
&
gdtcmd
,
cmnd
,
30
);
status
=
(
ushort
)
scp
->
SCp
.
Status
;
info
=
(
ulong32
)
scp
->
SCp
.
Message
;
...
...
@@ -591,7 +665,11 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
gdtcmd
.
Service
=
CACHESERVICE
;
gdtcmd
.
OpCode
=
GDT_DEVTYPE
;
gdtcmd
.
u
.
cache
.
DeviceNo
=
k
;
#if LINUX_VERSION_CODE >= 0x020322
#if LINUX_VERSION_CODE >= 0x020503
gdth_do_req
(
scp
,
&
gdtcmd
,
cmnd
,
30
);
status
=
(
ushort
)
scp
->
sr_command
->
SCp
.
Status
;
info
=
(
ulong32
)
scp
->
sr_command
->
SCp
.
Message
;
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd
(
scp
,
&
gdtcmd
,
cmnd
,
30
);
status
=
(
ushort
)
scp
->
SCp
.
Status
;
info
=
(
ulong32
)
scp
->
SCp
.
Message
;
...
...
@@ -609,7 +687,11 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
gdtcmd
.
Service
=
CACHESERVICE
;
gdtcmd
.
OpCode
=
GDT_CLUST_INFO
;
gdtcmd
.
u
.
cache
.
DeviceNo
=
k
;
#if LINUX_VERSION_CODE >= 0x020322
#if LINUX_VERSION_CODE >= 0x020503
gdth_do_req
(
scp
,
&
gdtcmd
,
cmnd
,
30
);
status
=
(
ushort
)
scp
->
sr_command
->
SCp
.
Status
;
info
=
(
ulong32
)
scp
->
sr_command
->
SCp
.
Message
;
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd
(
scp
,
&
gdtcmd
,
cmnd
,
30
);
status
=
(
ushort
)
scp
->
SCp
.
Status
;
info
=
(
ulong32
)
scp
->
SCp
.
Message
;
...
...
@@ -628,7 +710,11 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
gdtcmd
.
Service
=
CACHESERVICE
;
gdtcmd
.
OpCode
=
GDT_RW_ATTRIBS
;
gdtcmd
.
u
.
cache
.
DeviceNo
=
k
;
#if LINUX_VERSION_CODE >= 0x020322
#if LINUX_VERSION_CODE >= 0x020503
gdth_do_req
(
scp
,
&
gdtcmd
,
cmnd
,
30
);
status
=
(
ushort
)
scp
->
sr_command
->
SCp
.
Status
;
info
=
(
ulong32
)
scp
->
sr_command
->
SCp
.
Message
;
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd
(
scp
,
&
gdtcmd
,
cmnd
,
30
);
status
=
(
ushort
)
scp
->
SCp
.
Status
;
info
=
(
ulong32
)
scp
->
SCp
.
Message
;
...
...
@@ -646,7 +732,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
break
;
case
GDTIOCTL_RESET_DRV
:
if
(
!
gdth_ioctl_alloc
(
hanum
,
sizeof
(
gdth_iord_str
),
TRUE
))
if
(
!
gdth_ioctl_alloc
(
hanum
,
sizeof
(
gdth_iord_str
),
TRUE
,
&
paddr
))
return
(
-
EBUSY
);
piord
=
(
gdth_iord_str
*
)
ha
->
pscratch
;
piord
->
size
=
sizeof
(
gdth_iord_str
);
...
...
@@ -656,7 +742,10 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
gdtcmd
.
Service
=
CACHESERVICE
;
gdtcmd
.
OpCode
=
GDT_CLUST_RESET
;
gdtcmd
.
u
.
cache
.
DeviceNo
=
i
;
#if LINUX_VERSION_CODE >= 0x020322
#if LINUX_VERSION_CODE >= 0x020503
gdth_do_req
(
scp
,
&
gdtcmd
,
cmnd
,
30
);
piord
->
status
=
(
ushort
)
scp
->
sr_command
->
SCp
.
Status
;
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd
(
scp
,
&
gdtcmd
,
cmnd
,
30
);
piord
->
status
=
(
scp
->
SCp
.
Message
<<
16
)
|
scp
->
SCp
.
Status
;
#else
...
...
@@ -671,6 +760,7 @@ static int gdth_set_bin_info(char *buffer,int length,int hanum,Scsi_Cmnd scp)
}
return
length
;
}
#endif
static
int
gdth_get_info
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
length
,
int
vh
,
int
hanum
,
int
busnum
)
...
...
@@ -678,14 +768,16 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
int
size
=
0
,
len
=
0
;
off_t
begin
=
0
,
pos
=
0
;
gdth_ha_str
*
ha
;
gdth_iord_str
*
piord
;
int
id
,
i
,
j
,
k
,
sec
,
flag
;
int
no_mdrv
=
0
,
drv_no
,
is_mirr
;
ulong32
cnt
;
ulong32
cnt
,
paddr
;
gdth_cmd_str
gdtcmd
;
gdth_evt_str
estr
;
#if LINUX_VERSION_CODE >= 0x020322
#if LINUX_VERSION_CODE >= 0x020503
Scsi_Request
*
scp
;
Scsi_Device
*
sdev
;
#elif LINUX_VERSION_CODE >= 0x020322
Scsi_Cmnd
*
scp
;
Scsi_Device
*
sdev
;
#else
...
...
@@ -710,9 +802,16 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
TRACE2
((
"gdth_get_info() ha %d bus %d
\n
"
,
hanum
,
busnum
));
ha
=
HADATA
(
gdth_ctr_tab
[
hanum
]);
#if LINUX_VERSION_CODE >= 0x020322
sdev
=
scsi_get_host_dev
(
gdth_ctr_vtab
[
vh
]);
scp
=
scsi_get_command
(
sdev
,
GFP_KERNEL
);
#if LINUX_VERSION_CODE >= 0x020503
sdev
=
scsi_get_host_dev
(
gdth_ctr_tab
[
hanum
]);
scp
=
scsi_allocate_request
(
sdev
);
if
(
!
scp
)
return
-
ENOMEM
;
scp
->
sr_cmd_len
=
12
;
scp
->
sr_use_sg
=
0
;
#elif LINUX_VERSION_CODE >= 0x020322
sdev
=
scsi_get_host_dev
(
gdth_ctr_tab
[
hanum
]);
scp
=
scsi_allocate_device
(
sdev
,
1
,
FALSE
);
if
(
!
scp
)
return
-
ENOMEM
;
scp
->
cmd_len
=
12
;
...
...
@@ -720,13 +819,15 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
#else
memset
(
&
sdev
,
0
,
sizeof
(
Scsi_Device
));
memset
(
&
scp
,
0
,
sizeof
(
Scsi_Cmnd
));
sdev
.
host
=
scp
.
host
=
gdth_ctr_
vtab
[
vh
];
sdev
.
host
=
scp
.
host
=
gdth_ctr_
tab
[
hanum
];
sdev
.
id
=
scp
.
target
=
sdev
.
host
->
this_id
;
scp
.
device
=
&
sdev
;
#endif
#ifdef GDTH_IOCTL_PROC
/* ioctl from tool? */
if
(
!
gdth_ioctl_check_bin
(
hanum
,
(
ushort
)
length
))
{
#endif
/* request is i.e. "cat /proc/scsi/gdth/0" */
/* format: %-15s\t%-10s\t%-15s\t%s */
/* driver parameters */
...
...
@@ -798,7 +899,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
len
+=
size
;
pos
=
begin
+
len
;
flag
=
FALSE
;
buf
=
gdth_ioctl_alloc
(
hanum
,
GDTH_SCRATCH
,
FALSE
);
buf
=
gdth_ioctl_alloc
(
hanum
,
GDTH_SCRATCH
,
FALSE
,
&
paddr
);
if
(
!
buf
)
goto
stop_output
;
for
(
i
=
0
;
i
<
ha
->
bus_cnt
;
++
i
)
{
...
...
@@ -807,7 +908,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
pds
=
(
gdth_dskstat_str
*
)(
buf
+
GDTH_SCRATCH
/
4
);
gdtcmd
.
Service
=
CACHESERVICE
;
gdtcmd
.
OpCode
=
GDT_IOCTL
;
gdtcmd
.
u
.
ioctl
.
p_param
=
virt_to_bus
(
pds
)
;
gdtcmd
.
u
.
ioctl
.
p_param
=
paddr
+
GDTH_SCRATCH
/
4
;
gdtcmd
.
u
.
ioctl
.
param_size
=
3
*
GDTH_SCRATCH
/
4
;
gdtcmd
.
u
.
ioctl
.
subfunc
=
DSK_STATISTICS
|
L_CTRL_PATTERN
;
gdtcmd
.
u
.
ioctl
.
channel
=
ha
->
raw
[
i
].
address
|
INVALID_CHANNEL
;
...
...
@@ -818,7 +919,10 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
sizeof
(
pds
->
list
[
0
]);
if
(
pds
->
entries
>
cnt
)
pds
->
entries
=
cnt
;
#if LINUX_VERSION_CODE >= 0x020322
#if LINUX_VERSION_CODE >= 0x020503
gdth_do_req
(
scp
,
&
gdtcmd
,
cmnd
,
30
);
if
(
scp
->
sr_command
->
SCp
.
Status
!=
S_OK
)
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd
(
scp
,
&
gdtcmd
,
cmnd
,
30
);
if
(
scp
->
SCp
.
Status
!=
S_OK
)
#else
...
...
@@ -837,12 +941,15 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
pdi
=
(
gdth_diskinfo_str
*
)
buf
;
gdtcmd
.
Service
=
CACHESERVICE
;
gdtcmd
.
OpCode
=
GDT_IOCTL
;
gdtcmd
.
u
.
ioctl
.
p_param
=
virt_to_bus
(
pdi
)
;
gdtcmd
.
u
.
ioctl
.
p_param
=
paddr
;
gdtcmd
.
u
.
ioctl
.
param_size
=
sizeof
(
gdth_diskinfo_str
);
gdtcmd
.
u
.
ioctl
.
subfunc
=
SCSI_DR_INFO
|
L_CTRL_PATTERN
;
gdtcmd
.
u
.
ioctl
.
channel
=
ha
->
raw
[
i
].
address
|
ha
->
raw
[
i
].
id_list
[
j
];
#if LINUX_VERSION_CODE >= 0x020322
#if LINUX_VERSION_CODE >= 0x020503
gdth_do_req
(
scp
,
&
gdtcmd
,
cmnd
,
30
);
if
(
scp
->
sr_command
->
SCp
.
Status
==
S_OK
)
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd
(
scp
,
&
gdtcmd
,
cmnd
,
30
);
if
(
scp
->
SCp
.
Status
==
S_OK
)
#else
...
...
@@ -892,13 +999,16 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
pdef
=
(
gdth_defcnt_str
*
)
buf
;
gdtcmd
.
Service
=
CACHESERVICE
;
gdtcmd
.
OpCode
=
GDT_IOCTL
;
gdtcmd
.
u
.
ioctl
.
p_param
=
virt_to_bus
(
pdef
)
;
gdtcmd
.
u
.
ioctl
.
p_param
=
paddr
;
gdtcmd
.
u
.
ioctl
.
param_size
=
sizeof
(
gdth_defcnt_str
);
gdtcmd
.
u
.
ioctl
.
subfunc
=
SCSI_DEF_CNT
|
L_CTRL_PATTERN
;
gdtcmd
.
u
.
ioctl
.
channel
=
ha
->
raw
[
i
].
address
|
ha
->
raw
[
i
].
id_list
[
j
];
pdef
->
sddc_type
=
0x08
;
#if LINUX_VERSION_CODE >= 0x020322
#if LINUX_VERSION_CODE >= 0x020503
gdth_do_req
(
scp
,
&
gdtcmd
,
cmnd
,
30
);
if
(
scp
->
sr_command
->
SCp
.
Status
==
S_OK
)
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd
(
scp
,
&
gdtcmd
,
cmnd
,
30
);
if
(
scp
->
SCp
.
Status
==
S_OK
)
#else
...
...
@@ -920,7 +1030,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
goto
stop_output
;
}
}
gdth_ioctl_free
(
hanum
,
buf
);
gdth_ioctl_free
(
hanum
,
GDTH_SCRATCH
,
buf
,
paddr
);
if
(
!
flag
)
{
size
=
sprintf
(
buffer
+
len
,
"
\n
--
\n
"
);
...
...
@@ -932,7 +1042,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
len
+=
size
;
pos
=
begin
+
len
;
flag
=
FALSE
;
buf
=
gdth_ioctl_alloc
(
hanum
,
GDTH_SCRATCH
,
FALSE
);
buf
=
gdth_ioctl_alloc
(
hanum
,
GDTH_SCRATCH
,
FALSE
,
&
paddr
);
if
(
!
buf
)
goto
stop_output
;
for
(
i
=
0
;
i
<
MAX_LDRIVES
;
++
i
)
{
...
...
@@ -947,11 +1057,14 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
pcdi
=
(
gdth_cdrinfo_str
*
)
buf
;
gdtcmd
.
Service
=
CACHESERVICE
;
gdtcmd
.
OpCode
=
GDT_IOCTL
;
gdtcmd
.
u
.
ioctl
.
p_param
=
virt_to_bus
(
pcdi
)
;
gdtcmd
.
u
.
ioctl
.
p_param
=
paddr
;
gdtcmd
.
u
.
ioctl
.
param_size
=
sizeof
(
gdth_cdrinfo_str
);
gdtcmd
.
u
.
ioctl
.
subfunc
=
CACHE_DRV_INFO
;
gdtcmd
.
u
.
ioctl
.
channel
=
drv_no
;
#if LINUX_VERSION_CODE >= 0x020322
#if LINUX_VERSION_CODE >= 0x020503
gdth_do_req
(
scp
,
&
gdtcmd
,
cmnd
,
30
);
if
(
scp
->
sr_command
->
SCp
.
Status
!=
S_OK
)
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd
(
scp
,
&
gdtcmd
,
cmnd
,
30
);
if
(
scp
->
SCp
.
Status
!=
S_OK
)
#else
...
...
@@ -1034,7 +1147,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
if
(
pos
>
offset
+
length
)
goto
stop_output
;
}
gdth_ioctl_free
(
hanum
,
buf
);
gdth_ioctl_free
(
hanum
,
GDTH_SCRATCH
,
buf
,
paddr
);
if
(
!
flag
)
{
size
=
sprintf
(
buffer
+
len
,
"
\n
--
\n
"
);
...
...
@@ -1046,7 +1159,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
len
+=
size
;
pos
=
begin
+
len
;
flag
=
FALSE
;
buf
=
gdth_ioctl_alloc
(
hanum
,
GDTH_SCRATCH
,
FALSE
);
buf
=
gdth_ioctl_alloc
(
hanum
,
GDTH_SCRATCH
,
FALSE
,
&
paddr
);
if
(
!
buf
)
goto
stop_output
;
for
(
i
=
0
;
i
<
MAX_LDRIVES
;
++
i
)
{
...
...
@@ -1057,11 +1170,14 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
pai
=
(
gdth_arrayinf_str
*
)
buf
;
gdtcmd
.
Service
=
CACHESERVICE
;
gdtcmd
.
OpCode
=
GDT_IOCTL
;
gdtcmd
.
u
.
ioctl
.
p_param
=
virt_to_bus
(
pai
)
;
gdtcmd
.
u
.
ioctl
.
p_param
=
paddr
;
gdtcmd
.
u
.
ioctl
.
param_size
=
sizeof
(
gdth_arrayinf_str
);
gdtcmd
.
u
.
ioctl
.
subfunc
=
ARRAY_INFO
|
LA_CTRL_PATTERN
;
gdtcmd
.
u
.
ioctl
.
channel
=
i
;
#if LINUX_VERSION_CODE >= 0x020322
#if LINUX_VERSION_CODE >= 0x020503
gdth_do_req
(
scp
,
&
gdtcmd
,
cmnd
,
30
);
if
(
scp
->
sr_command
->
SCp
.
Status
==
S_OK
)
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd
(
scp
,
&
gdtcmd
,
cmnd
,
30
);
if
(
scp
->
SCp
.
Status
==
S_OK
)
#else
...
...
@@ -1112,7 +1228,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
goto
stop_output
;
}
}
gdth_ioctl_free
(
hanum
,
buf
);
gdth_ioctl_free
(
hanum
,
GDTH_SCRATCH
,
buf
,
paddr
);
if
(
!
flag
)
{
size
=
sprintf
(
buffer
+
len
,
"
\n
--
\n
"
);
...
...
@@ -1124,7 +1240,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
len
+=
size
;
pos
=
begin
+
len
;
flag
=
FALSE
;
buf
=
gdth_ioctl_alloc
(
hanum
,
GDTH_SCRATCH
,
FALSE
);
buf
=
gdth_ioctl_alloc
(
hanum
,
sizeof
(
gdth_hget_str
),
FALSE
,
&
paddr
);
if
(
!
buf
)
goto
stop_output
;
for
(
i
=
0
;
i
<
MAX_LDRIVES
;
++
i
)
{
...
...
@@ -1136,13 +1252,16 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
phg
=
(
gdth_hget_str
*
)
buf
;
gdtcmd
.
Service
=
CACHESERVICE
;
gdtcmd
.
OpCode
=
GDT_IOCTL
;
gdtcmd
.
u
.
ioctl
.
p_param
=
virt_to_bus
(
phg
)
;
gdtcmd
.
u
.
ioctl
.
p_param
=
paddr
;
gdtcmd
.
u
.
ioctl
.
param_size
=
sizeof
(
gdth_hget_str
);
gdtcmd
.
u
.
ioctl
.
subfunc
=
HOST_GET
|
LA_CTRL_PATTERN
;
gdtcmd
.
u
.
ioctl
.
channel
=
i
;
phg
->
entries
=
MAX_HDRIVES
;
phg
->
offset
=
GDTOFFSOF
(
gdth_hget_str
,
entry
[
0
]);
#if LINUX_VERSION_CODE >= 0x020322
#if LINUX_VERSION_CODE >= 0x020503
gdth_do_req
(
scp
,
&
gdtcmd
,
cmnd
,
30
);
if
(
scp
->
sr_command
->
SCp
.
Status
!=
S_OK
)
#elif LINUX_VERSION_CODE >= 0x020322
gdth_do_cmd
(
scp
,
&
gdtcmd
,
cmnd
,
30
);
if
(
scp
->
SCp
.
Status
!=
S_OK
)
#else
...
...
@@ -1164,7 +1283,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
}
}
}
gdth_ioctl_free
(
hanum
,
buf
);
gdth_ioctl_free
(
hanum
,
sizeof
(
gdth_hget_str
),
buf
,
paddr
);
for
(
i
=
0
;
i
<
MAX_HDRIVES
;
++
i
)
{
if
(
!
(
ha
->
hdr
[
i
].
present
))
...
...
@@ -1221,20 +1340,27 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
if
(
id
==
-
1
)
break
;
}
#ifdef GDTH_IOCTL_PROC
}
else
{
gdth_iord_str
*
piord
;
/* request from tool (GDTMON,..) */
piord
=
(
gdth_iord_str
*
)
ha
->
pscratch
;
if
(
piord
==
NULL
)
goto
stop_output
;
length
=
piord
->
size
;
memcpy
(
buffer
+
len
,
(
char
*
)
piord
,
length
);
gdth_ioctl_free
(
hanum
,
ha
->
pscratch
);
gdth_ioctl_free
(
hanum
,
GDTH_SCRATCH
,
ha
->
pscratch
,
paddr
);
len
=
length
;
}
#endif
stop_output:
#if LINUX_VERSION_CODE >= 0x020322
scsi_put_command
(
scp
);
#if LINUX_VERSION_CODE >= 0x020503
scsi_release_request
(
scp
);
scsi_free_host_dev
(
sdev
);
#elif LINUX_VERSION_CODE >= 0x020322
scsi_release_command
(
scp
);
scsi_free_host_dev
(
sdev
);
#endif
*
start
=
buffer
+
(
offset
-
begin
);
...
...
@@ -1246,6 +1372,26 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
return
(
len
);
}
#if LINUX_VERSION_CODE >= 0x020503
static
void
gdth_do_req
(
Scsi_Request
*
scp
,
gdth_cmd_str
*
gdtcmd
,
char
*
cmnd
,
int
timeout
)
{
unsigned
bufflen
;
DECLARE_COMPLETION
(
wait
);
TRACE2
((
"gdth_do_req()
\n
"
));
if
(
gdtcmd
!=
NULL
)
{
bufflen
=
sizeof
(
gdth_cmd_str
);
}
else
{
bufflen
=
0
;
}
scp
->
sr_request
->
rq_status
=
RQ_SCSI_BUSY
;
scp
->
sr_request
->
waiting
=
&
wait
;
scsi_do_req
(
scp
,
cmnd
,
gdtcmd
,
bufflen
,
gdth_scsi_done
,
timeout
*
HZ
,
1
);
wait_for_completion
(
&
wait
);
}
#else
static
void
gdth_do_cmd
(
Scsi_Cmnd
*
scp
,
gdth_cmd_str
*
gdtcmd
,
char
*
cmnd
,
int
timeout
)
{
...
...
@@ -1266,8 +1412,8 @@ static void gdth_do_cmd(Scsi_Cmnd *scp, gdth_cmd_str *gdtcmd,
scp
->
SCp
.
this_residual
=
DEFAULT_PRI
;
bufflen
=
0
;
}
scp
->
request
.
rq_status
=
RQ_SCSI_BUSY
;
#if LINUX_VERSION_CODE >= 0x020407
scp
->
request
.
rq_status
=
RQ_SCSI_BUSY
;
scp
->
request
.
waiting
=
&
wait
;
scsi_do_cmd
(
scp
,
cmnd
,
gdtcmd
,
bufflen
,
gdth_scsi_done
,
timeout
*
HZ
,
1
);
wait_for_completion
(
&
wait
);
...
...
@@ -1283,46 +1429,53 @@ static void gdth_do_cmd(Scsi_Cmnd *scp, gdth_cmd_str *gdtcmd,
down
(
&
sem
);
#endif
}
#endif
void
gdth_scsi_done
(
Scsi_Cmnd
*
scp
)
{
TRACE2
((
"gdth_scsi_done()
\n
"
));
#if LINUX_VERSION_CODE >= 0x020503
scp
->
request
->
rq_status
=
RQ_SCSI_DONE
;
if
(
scp
->
request
->
waiting
!=
NULL
)
complete
(
scp
->
request
->
waiting
);
#elif LINUX_VERSION_CODE >= 0x020407
scp
->
request
.
rq_status
=
RQ_SCSI_DONE
;
#if LINUX_VERSION_CODE >= 0x020407
if
(
scp
->
request
.
waiting
!=
NULL
)
complete
(
scp
->
request
.
waiting
);
#else
scp
->
request
.
rq_status
=
RQ_SCSI_DONE
;
if
(
scp
->
request
.
sem
!=
NULL
)
up
(
scp
->
request
.
sem
);
#endif
}
static
char
*
gdth_ioctl_alloc
(
int
hanum
,
ushort
size
,
int
scratch
)
static
char
*
gdth_ioctl_alloc
(
int
hanum
,
int
size
,
int
scratch
,
ulong32
*
paddr
)
{
gdth_ha_str
*
ha
;
ulong
flags
;
char
*
ret_val
;
if
(
size
==
0
||
size
>
GDTH_SCRATCH
)
return
FALSE
;
if
(
size
==
0
)
return
NULL
;
ha
=
HADATA
(
gdth_ctr_tab
[
hanum
]);
GDTH_LOCK_HA
(
ha
,
flags
);
if
(
scratch
)
{
if
(
!
ha
->
scratch_busy
)
{
ha
->
scratch_busy
=
TRUE
;
ret_val
=
ha
->
pscratch
;
}
else
ret_val
=
NULL
;
if
(
!
ha
->
scratch_busy
&&
size
<=
GDTH_SCRATCH
)
{
ha
->
scratch_busy
=
TRUE
;
ret_val
=
ha
->
pscratch
;
*
paddr
=
ha
->
scratch_phys
;
}
else
if
(
scratch
)
{
ret_val
=
NULL
;
}
else
{
#if LINUX_VERSION_CODE >= 0x020322
ret_val
=
(
void
*
)
__get_free_pages
(
GFP_ATOMIC
|
GFP_DMA
,
GDTH_SCRATCH_ORD
);
#if LINUX_VERSION_CODE >= 0x020400
ret_val
=
pci_alloc_consistent
(
ha
->
pdev
,
size
,
paddr
);
#else
ret_val
=
scsi_init_malloc
(
GDTH_SCRATCH
,
GFP_ATOMIC
|
GFP_DMA
);
ret_val
=
scsi_init_malloc
(
size
,
GFP_ATOMIC
|
GFP_DMA
);
if
(
ret_val
)
*
paddr
=
virt_to_bus
(
ret_val
);
#endif
}
...
...
@@ -1330,7 +1483,7 @@ static char *gdth_ioctl_alloc(int hanum, ushort size, int scratch)
return
ret_val
;
}
static
void
gdth_ioctl_free
(
int
hanum
,
char
*
buf
)
static
void
gdth_ioctl_free
(
int
hanum
,
int
size
,
char
*
buf
,
ulong32
paddr
)
{
gdth_ha_str
*
ha
;
ulong
flags
;
...
...
@@ -1341,16 +1494,17 @@ static void gdth_ioctl_free(int hanum, char *buf)
if
(
buf
==
ha
->
pscratch
)
{
ha
->
scratch_busy
=
FALSE
;
}
else
{
#if LINUX_VERSION_CODE >= 0x020
322
free_pages
((
unsigned
long
)
buf
,
GDTH_SCRATCH_ORD
);
#if LINUX_VERSION_CODE >= 0x020
400
pci_free_consistent
(
ha
->
pdev
,
size
,
buf
,
paddr
);
#else
scsi_init_free
((
void
*
)
buf
,
GDTH_SCRATCH
);
scsi_init_free
((
void
*
)
buf
,
size
);
#endif
}
GDTH_UNLOCK_HA
(
ha
,
flags
);
}
#ifdef GDTH_IOCTL_PROC
static
int
gdth_ioctl_check_bin
(
int
hanum
,
ushort
size
)
{
gdth_ha_str
*
ha
;
...
...
@@ -1368,7 +1522,7 @@ static int gdth_ioctl_check_bin(int hanum, ushort size)
GDTH_UNLOCK_HA
(
ha
,
flags
);
return
ret_val
;
}
#endif
static
void
gdth_wait_completion
(
int
hanum
,
int
busnum
,
int
id
)
{
...
...
@@ -1376,23 +1530,39 @@ static void gdth_wait_completion(int hanum, int busnum, int id)
ulong
flags
;
int
i
;
Scsi_Cmnd
*
scp
;
unchar
b
;
unchar
b
,
t
;
ha
=
HADATA
(
gdth_ctr_tab
[
hanum
]);
GDTH_LOCK_HA
(
ha
,
flags
);
for
(
i
=
0
;
i
<
GDTH_MAXCMDS
;
++
i
)
{
scp
=
ha
->
cmd_tab
[
i
].
cmnd
;
#if LINUX_VERSION_CODE >= 0x02053C
b
=
virt_ctr
?
NUMDATA
(
scp
->
device
->
host
)
->
busnum
:
scp
->
device
->
channel
;
if
(
!
SPECIAL_SCP
(
scp
)
&&
scp
->
device
->
id
==
(
unchar
)
id
&&
t
=
scp
->
device
->
id
;
#else
b
=
virt_ctr
?
NUMDATA
(
scp
->
host
)
->
busnum
:
scp
->
channel
;
t
=
scp
->
target
;
#endif
if
(
!
SPECIAL_SCP
(
scp
)
&&
t
==
(
unchar
)
id
&&
b
==
(
unchar
)
busnum
)
{
scp
->
SCp
.
have_data_in
=
0
;
GDTH_UNLOCK_HA
(
ha
,
flags
);
while
(
!
scp
->
SCp
.
have_data_in
)
barrier
();
#if LINUX_VERSION_CODE >= 0x02053C
GDTH_LOCK_SCSI_DONE
(
scp
->
device
->
host
,
flags
);
scp
->
scsi_done
(
scp
);
GDTH_UNLOCK_SCSI_DONE
(
scp
->
device
->
host
,
flags
);
#elif LINUX_VERSION_CODE >= 0x020503
GDTH_LOCK_SCSI_DONE
(
scp
->
host
,
flags
);
scp
->
scsi_done
(
scp
);
GDTH_UNLOCK_SCSI_DONE
(
scp
->
host
,
flags
);
#else
GDTH_LOCK_SCSI_DONE
(
flags
);
scp
->
scsi_done
(
scp
);
GDTH_UNLOCK_SCSI_DONE
(
flags
);
#endif
GDTH_LOCK_HA
(
ha
,
flags
);
}
}
...
...
@@ -1404,14 +1574,20 @@ static void gdth_stop_timeout(int hanum, int busnum, int id)
gdth_ha_str
*
ha
;
ulong
flags
;
Scsi_Cmnd
*
scp
;
unchar
b
;
unchar
b
,
t
;
ha
=
HADATA
(
gdth_ctr_tab
[
hanum
]);
GDTH_LOCK_HA
(
ha
,
flags
);
for
(
scp
=
ha
->
req_first
;
scp
;
scp
=
(
Scsi_Cmnd
*
)
scp
->
SCp
.
ptr
)
{
#if LINUX_VERSION_CODE >= 0x02053C
b
=
virt_ctr
?
NUMDATA
(
scp
->
device
->
host
)
->
busnum
:
scp
->
device
->
channel
;
if
(
scp
->
device
->
id
==
(
unchar
)
id
&&
b
==
(
unchar
)
busnum
)
{
t
=
scp
->
device
->
id
;
#else
b
=
virt_ctr
?
NUMDATA
(
scp
->
host
)
->
busnum
:
scp
->
channel
;
t
=
scp
->
target
;
#endif
if
(
t
==
(
unchar
)
id
&&
b
==
(
unchar
)
busnum
)
{
TRACE2
((
"gdth_stop_timeout(): update_timeout()
\n
"
));
scp
->
SCp
.
buffers_residual
=
gdth_update_timeout
(
hanum
,
scp
,
0
);
}
...
...
@@ -1424,14 +1600,20 @@ static void gdth_start_timeout(int hanum, int busnum, int id)
gdth_ha_str
*
ha
;
ulong
flags
;
Scsi_Cmnd
*
scp
;
unchar
b
;
unchar
b
,
t
;
ha
=
HADATA
(
gdth_ctr_tab
[
hanum
]);
GDTH_LOCK_HA
(
ha
,
flags
);
for
(
scp
=
ha
->
req_first
;
scp
;
scp
=
(
Scsi_Cmnd
*
)
scp
->
SCp
.
ptr
)
{
#if LINUX_VERSION_CODE >= 0x02053C
b
=
virt_ctr
?
NUMDATA
(
scp
->
device
->
host
)
->
busnum
:
scp
->
device
->
channel
;
if
(
scp
->
device
->
id
==
(
unchar
)
id
&&
b
==
(
unchar
)
busnum
)
{
t
=
scp
->
device
->
id
;
#else
b
=
virt_ctr
?
NUMDATA
(
scp
->
host
)
->
busnum
:
scp
->
channel
;
t
=
scp
->
target
;
#endif
if
(
t
==
(
unchar
)
id
&&
b
==
(
unchar
)
busnum
)
{
TRACE2
((
"gdth_start_timeout(): update_timeout()
\n
"
));
gdth_update_timeout
(
hanum
,
scp
,
scp
->
SCp
.
buffers_residual
);
}
...
...
@@ -1464,7 +1646,7 @@ static int gdth_update_timeout(int hanum, Scsi_Cmnd *scp, int timeout)
timer_table
[
SCSI_TIMER
].
expires
=
jiffies
+
timeout
;
timer_active
|=
1
<<
SCSI_TIMER
;
}
else
{
if
(
time_before
(
jiffies
+
timeout
,
timer_table
[
SCSI_TIMER
].
expires
)
)
if
(
jiffies
+
timeout
<
timer_table
[
SCSI_TIMER
].
expires
)
timer_table
[
SCSI_TIMER
].
expires
=
jiffies
+
timeout
;
}
}
...
...
drivers/scsi/gdth_proc.h
View file @
c83b4e61
...
...
@@ -2,26 +2,42 @@
#define _GDTH_PROC_H
/* gdth_proc.h
* $Id: gdth_proc.h,v 1.1
1 2001/07/25 15:37:40
achim Exp $
* $Id: gdth_proc.h,v 1.1
3 2003/02/27 14:59:25
achim Exp $
*/
static
int
gdth_set_info
(
char
*
buffer
,
int
length
,
int
vh
,
int
hanum
,
int
busnum
);
static
int
gdth_get_info
(
char
*
buffer
,
char
**
start
,
off_t
offset
,
int
length
,
int
vh
,
int
hanum
,
int
busnum
);
#if LINUX_VERSION_CODE >= 0x020322
#if LINUX_VERSION_CODE >= 0x020503
static
void
gdth_do_req
(
Scsi_Request
*
srp
,
gdth_cmd_str
*
cmd
,
char
*
cmnd
,
int
timeout
);
static
int
gdth_set_asc_info
(
char
*
buffer
,
int
length
,
int
hanum
,
Scsi_Request
*
scp
);
#ifdef GDTH_IOCTL_PROC
static
int
gdth_set_bin_info
(
char
*
buffer
,
int
length
,
int
hanum
,
Scsi_Request
*
scp
);
#endif
#elif LINUX_VERSION_CODE >= 0x020322
static
void
gdth_do_cmd
(
Scsi_Cmnd
*
scp
,
gdth_cmd_str
*
cmd
,
char
*
cmnd
,
int
timeout
);
static
int
gdth_set_asc_info
(
char
*
buffer
,
int
length
,
int
hanum
,
Scsi_Cmnd
*
scp
);
#ifdef GDTH_IOCTL_PROC
static
int
gdth_set_bin_info
(
char
*
buffer
,
int
length
,
int
hanum
,
Scsi_Cmnd
*
scp
);
#endif
#else
static
void
gdth_do_cmd
(
Scsi_Cmnd
*
scp
,
gdth_cmd_str
*
cmd
,
char
*
cmnd
,
int
timeout
);
static
int
gdth_set_asc_info
(
char
*
buffer
,
int
length
,
int
hanum
,
Scsi_Cmnd
scp
);
#ifdef GDTH_IOCTL_PROC
static
int
gdth_set_bin_info
(
char
*
buffer
,
int
length
,
int
hanum
,
Scsi_Cmnd
scp
);
#endif
static
void
gdth_do_cmd
(
Scsi_Cmnd
*
scp
,
gdth_cmd_str
*
cmd
,
char
*
cmnd
,
int
timeout
);
#endif
static
char
*
gdth_ioctl_alloc
(
int
hanum
,
ushort
size
,
int
scratch
);
static
void
gdth_ioctl_free
(
int
hanum
,
char
*
buf
);
static
char
*
gdth_ioctl_alloc
(
int
hanum
,
int
size
,
int
scratch
,
ulong32
*
paddr
);
static
void
gdth_ioctl_free
(
int
hanum
,
int
size
,
char
*
buf
,
ulong32
paddr
);
#ifdef GDTH_IOCTL_PROC
static
int
gdth_ioctl_check_bin
(
int
hanum
,
ushort
size
);
#endif
static
void
gdth_wait_completion
(
int
hanum
,
int
busnum
,
int
id
);
static
void
gdth_stop_timeout
(
int
hanum
,
int
busnum
,
int
id
);
static
void
gdth_start_timeout
(
int
hanum
,
int
busnum
,
int
id
);
...
...
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