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
2983e9a6
Commit
2983e9a6
authored
Nov 20, 2002
by
James Bottomley
Browse files
Options
Browse Files
Download
Plain Diff
Merge mulgrave.(none):/home/jejb/BK/scsi-misc-2.5
into mulgrave.(none):/home/jejb/BK/scsi-for-linus-2.5
parents
37256d28
d67cf443
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
298 additions
and
254 deletions
+298
-254
drivers/block/ll_rw_blk.c
drivers/block/ll_rw_blk.c
+11
-0
drivers/scsi/hosts.c
drivers/scsi/hosts.c
+61
-0
drivers/scsi/hosts.h
drivers/scsi/hosts.h
+0
-9
drivers/scsi/scsi.c
drivers/scsi/scsi.c
+4
-94
drivers/scsi/scsi.h
drivers/scsi/scsi.h
+7
-0
drivers/scsi/scsi_debug.c
drivers/scsi/scsi_debug.c
+189
-72
drivers/scsi/scsi_debug.h
drivers/scsi/scsi_debug.h
+1
-0
drivers/scsi/scsi_error.c
drivers/scsi/scsi_error.c
+1
-3
drivers/scsi/scsi_lib.c
drivers/scsi/scsi_lib.c
+8
-43
drivers/scsi/scsi_proc.c
drivers/scsi/scsi_proc.c
+2
-18
drivers/scsi/scsi_scan.c
drivers/scsi/scsi_scan.c
+4
-4
include/linux/blkdev.h
include/linux/blkdev.h
+1
-0
include/scsi/scsi_ioctl.h
include/scsi/scsi_ioctl.h
+9
-11
No files found.
drivers/block/ll_rw_blk.c
View file @
2983e9a6
...
...
@@ -1037,6 +1037,16 @@ void blk_stop_queue(request_queue_t *q)
spin_unlock_irqrestore
(
q
->
queue_lock
,
flags
);
}
/**
* blk_run_queue - run a single device queue
* @q The queue to run
*/
void
__blk_run_queue
(
request_queue_t
*
q
)
{
blk_remove_plug
(
q
);
q
->
request_fn
(
q
);
}
/**
* blk_run_queues - fire all plugged queues
*
...
...
@@ -2198,4 +2208,5 @@ EXPORT_SYMBOL(blk_queue_invalidate_tags);
EXPORT_SYMBOL
(
blk_start_queue
);
EXPORT_SYMBOL
(
blk_stop_queue
);
EXPORT_SYMBOL
(
__blk_stop_queue
);
EXPORT_SYMBOL
(
__blk_run_queue
);
EXPORT_SYMBOL
(
blk_run_queues
);
drivers/scsi/hosts.c
View file @
2983e9a6
...
...
@@ -669,6 +669,67 @@ void __init scsi_host_init(void)
}
}
/*
* Function: scsi_get_host_dev()
*
* Purpose: Create a Scsi_Device that points to the host adapter itself.
*
* Arguments: SHpnt - Host that needs a Scsi_Device
*
* Lock status: None assumed.
*
* Returns: The Scsi_Device or NULL
*
* Notes:
* Attach a single Scsi_Device to the Scsi_Host - this should
* be made to look like a "pseudo-device" that points to the
* HA itself. For the moment, we include it at the head of
* the host_queue itself - I don't think we want to show this
* to the HA in select_queue_depths(), as this would probably confuse
* matters.
*
* Note - this device is not accessible from any high-level
* drivers (including generics), which is probably not
* optimal. We can add hooks later to attach
*/
struct
scsi_device
*
scsi_get_host_dev
(
struct
Scsi_Host
*
shost
)
{
struct
scsi_device
*
sdev
;
sdev
=
scsi_alloc_sdev
(
shost
,
0
,
shost
->
this_id
,
0
);
if
(
sdev
)
{
scsi_build_commandblocks
(
sdev
);
if
(
sdev
->
current_queue_depth
==
0
)
goto
fail
;
sdev
->
borken
=
0
;
}
return
sdev
;
fail:
kfree
(
sdev
);
return
NULL
;
}
/*
* Function: scsi_free_host_dev()
*
* Purpose: Free a scsi_device that points to the host adapter itself.
*
* Arguments: SHpnt - Host that needs a Scsi_Device
*
* Lock status: None assumed.
*
* Returns: Nothing
*
* Notes:
*/
void
scsi_free_host_dev
(
struct
scsi_device
*
sdev
)
{
BUG_ON
(
sdev
->
id
!=
sdev
->
host
->
this_id
);
scsi_free_sdev
(
sdev
);
}
void
scsi_host_busy_inc
(
struct
Scsi_Host
*
shost
,
Scsi_Device
*
sdev
)
{
unsigned
long
flags
;
...
...
drivers/scsi/hosts.h
View file @
2983e9a6
...
...
@@ -500,15 +500,6 @@ extern Scsi_Device * scsi_get_host_dev(struct Scsi_Host *);
extern
void
scsi_unblock_requests
(
struct
Scsi_Host
*
);
extern
void
scsi_block_requests
(
struct
Scsi_Host
*
);
extern
void
scsi_report_bus_reset
(
struct
Scsi_Host
*
,
int
);
typedef
struct
SHN
{
struct
list_head
shn_list
;
char
*
name
;
unsigned
short
host_no
;
unsigned
short
host_registered
;
}
Scsi_Host_Name
;
extern
void
scsi_register_blocked_host
(
struct
Scsi_Host
*
);
extern
void
scsi_deregister_blocked_host
(
struct
Scsi_Host
*
);
...
...
drivers/scsi/scsi.c
View file @
2983e9a6
...
...
@@ -155,7 +155,6 @@ const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE] =
"Enclosure "
,
};
static
char
*
scsi_null_device_strs
=
"nullnullnullnull"
;
static
const
char
*
const
spaces
=
" "
;
/* 16 of them */
static
unsigned
scsi_default_dev_flags
;
...
...
@@ -2225,6 +2224,8 @@ static int __init init_scsi(void)
printk
(
KERN_ERR
"SCSI: can't init sg mempool %s
\n
"
,
sgp
->
name
);
}
scsi_init_procfs
();
scsi_devfs_handle
=
devfs_mk_dir
(
NULL
,
"scsi"
,
NULL
);
scsi_host_init
();
scsi_dev_info_list_init
(
scsi_dev_flags
);
bus_register
(
&
scsi_driverfs_bus_type
);
...
...
@@ -2236,9 +2237,10 @@ static void __exit exit_scsi(void)
{
int
i
;
bus_unregister
(
&
scsi_driverfs_bus_type
);
scsi_dev_info_list_delete
();
devfs_unregister
(
scsi_devfs_handle
);
scsi_exit_procfs
();
scsi_dev_info_list_delete
();
for
(
i
=
0
;
i
<
SG_MEMPOOL_NR
;
i
++
)
{
struct
scsi_host_sg_pool
*
sgp
=
scsi_sg_pools
+
i
;
...
...
@@ -2251,95 +2253,3 @@ static void __exit exit_scsi(void)
module_init
(
init_scsi
);
module_exit
(
exit_scsi
);
/*
* Function: scsi_get_host_dev()
*
* Purpose: Create a Scsi_Device that points to the host adapter itself.
*
* Arguments: SHpnt - Host that needs a Scsi_Device
*
* Lock status: None assumed.
*
* Returns: The Scsi_Device or NULL
*
* Notes:
*/
Scsi_Device
*
scsi_get_host_dev
(
struct
Scsi_Host
*
SHpnt
)
{
Scsi_Device
*
SDpnt
;
/*
* Attach a single Scsi_Device to the Scsi_Host - this should
* be made to look like a "pseudo-device" that points to the
* HA itself. For the moment, we include it at the head of
* the host_queue itself - I don't think we want to show this
* to the HA in select_queue_depths(), as this would probably confuse
* matters.
* Note - this device is not accessible from any high-level
* drivers (including generics), which is probably not
* optimal. We can add hooks later to attach
*/
SDpnt
=
(
Scsi_Device
*
)
kmalloc
(
sizeof
(
Scsi_Device
),
GFP_ATOMIC
);
if
(
SDpnt
==
NULL
)
return
NULL
;
memset
(
SDpnt
,
0
,
sizeof
(
Scsi_Device
));
SDpnt
->
vendor
=
scsi_null_device_strs
;
SDpnt
->
model
=
scsi_null_device_strs
;
SDpnt
->
rev
=
scsi_null_device_strs
;
SDpnt
->
host
=
SHpnt
;
SDpnt
->
id
=
SHpnt
->
this_id
;
SDpnt
->
type
=
-
1
;
SDpnt
->
new_queue_depth
=
1
;
scsi_build_commandblocks
(
SDpnt
);
if
(
SDpnt
->
current_queue_depth
==
0
)
{
kfree
(
SDpnt
);
return
NULL
;
}
scsi_initialize_queue
(
SDpnt
,
SHpnt
);
SDpnt
->
online
=
TRUE
;
/*
* Initialize the object that we will use to wait for command blocks.
*/
init_waitqueue_head
(
&
SDpnt
->
scpnt_wait
);
return
SDpnt
;
}
/*
* Function: scsi_free_host_dev()
*
* Purpose: Create a Scsi_Device that points to the host adapter itself.
*
* Arguments: SHpnt - Host that needs a Scsi_Device
*
* Lock status: None assumed.
*
* Returns: Nothing
*
* Notes:
*/
void
scsi_free_host_dev
(
Scsi_Device
*
SDpnt
)
{
if
(
(
unsigned
char
)
SDpnt
->
id
!=
(
unsigned
char
)
SDpnt
->
host
->
this_id
)
{
panic
(
"Attempt to delete wrong device
\n
"
);
}
blk_cleanup_queue
(
&
SDpnt
->
request_queue
);
/*
* We only have a single SCpnt attached to this device. Free
* it now.
*/
scsi_release_commandblocks
(
SDpnt
);
if
(
SDpnt
->
inquiry
)
kfree
(
SDpnt
->
inquiry
);
kfree
(
SDpnt
);
}
drivers/scsi/scsi.h
View file @
2983e9a6
...
...
@@ -519,6 +519,13 @@ static inline void scsi_proc_host_add(struct Scsi_Host *);
static
inline
void
scsi_proc_host_rm
(
struct
Scsi_Host
*
);
#endif
/* CONFIG_PROC_FS */
/*
* Prototypes for functions in scsi_scan.c
*/
extern
struct
scsi_device
*
scsi_alloc_sdev
(
struct
Scsi_Host
*
,
uint
,
uint
,
uint
);
extern
void
scsi_free_sdev
(
struct
scsi_device
*
);
/*
* Prototypes for functions in constants.c
* Some of these used to live in constants.h
...
...
drivers/scsi/scsi_debug.c
View file @
2983e9a6
...
...
@@ -19,6 +19,7 @@
* use vmalloc() more inquiry+mode_sense [20020302]
* add timers for delayed responses [20020721]
* Patrick Mansfield <patmans@us.ibm.com> max_luns+scsi_level [20021031]
* Mike Anderson <andmike@us.ibm.com> sysfs work [20021118]
*/
#include <linux/config.h>
...
...
@@ -40,6 +41,7 @@
#include <linux/blk.h>
#include "scsi.h"
#include "hosts.h"
#include <scsi/scsicam.h>
#include <linux/stat.h>
...
...
@@ -49,7 +51,7 @@
#include "scsi_debug.h"
static
const
char
*
scsi_debug_version_str
=
"Version: 1.6
4 (20021111 2
)"
;
static
const
char
*
scsi_debug_version_str
=
"Version: 1.6
5 (20021119
)"
;
#ifndef SCSI_CMD_READ_16
#define SCSI_CMD_READ_16 0x88
...
...
@@ -60,24 +62,26 @@ static const char * scsi_debug_version_str = "Version: 1.64 (20021111 2)";
#define SDEBUG_TAGGED_QUEUING 0
/* 0 | MSG_SIMPLE_TAG | MSG_ORDERED_TAG */
/*
A few options that we want selected
*/
/*
Default values for driver parameters
*/
#define DEF_NR_FAKE_DEVS 1
#define DEF_DEV_SIZE_MB 8
#define DEF_FAKE_BLK0 0
#define DEF_EVERY_NTH 100
#define DEF_DELAY 1
#define DEF_MAX_LUNS 2
#define DEF_SCSI_LEVEL 3
#define DEF_NUM_HOST 1
#define DEF_OPTS 0
#define MAX_NUM_HOSTS 128
#define DEF_OPTS 0
/* bit mask values for scsi_debug_opts */
#define SCSI_DEBUG_OPT_NOISE 1
#define SCSI_DEBUG_OPT_MEDIUM_ERR 2
#define SCSI_DEBUG_OPT_EVERY_NTH 4
#define OPT_MEDIUM_ERR_ADDR 0x1234
static
int
scsi_debug_dev_size_mb
=
DEF_DEV_SIZE_MB
;
static
int
scsi_debug_num_devs
=
DEF_NR_FAKE_DEVS
;
static
int
scsi_debug_opts
=
DEF_OPTS
;
static
int
scsi_debug_every_nth
=
DEF_EVERY_NTH
;
...
...
@@ -87,27 +91,30 @@ static int scsi_debug_max_luns = DEF_MAX_LUNS;
static
int
scsi_debug_scsi_level
=
DEF_SCSI_LEVEL
;
static
int
scsi_debug_add_host
=
DEF_NUM_HOST
;
/* This assumes one lun used per allocated target id */
#define N_HEAD 8
#define N_SECTOR 32
#define DEV_READONLY(TGT) (0)
#define DEV_REMOVEABLE(TGT) (0)
#define PERIPH_DEVICE_TYPE(TGT) (TYPE_DISK);
static
int
scsi_debug_dev_size_mb
=
DEF_DEV_SIZE_MB
;
#define STORE_SIZE (scsi_debug_dev_size_mb * 1024 * 1024)
static
unsigned
long
sdebug_store_size
;
/* in bytes */
static
sector_t
sdebug_capacity
;
/* in sectors */
/* old BIOS stuff, kernel may get rid of them but some mode sense pages
may still need them */
static
int
sdebug_heads
;
/* heads per disk */
static
int
sdebug_cylinders_per
;
/* cylinders per surface */
static
int
sdebug_sectors_per
;
/* sectors per cylinder */
/* default sector size is 512 bytes, 2**9 bytes */
#define POW2_SECT_SIZE 9
#define SECT_SIZE (1 << POW2_SECT_SIZE)
#define N_CYLINDER (STORE_SIZE / (SECT_SIZE * N_SECTOR * N_HEAD))
/* Time to wait before completing a command */
#define CAPACITY (N_HEAD * N_SECTOR * N_CYLINDER)
#define SECT_SIZE_PER(TGT) SECT_SIZE
struct
Scsi_Host
*
scsi_debug_hosts
[
MAX_NUM_HOSTS
];
struct
sdebug_host_info
{
struct
Scsi_Host
*
shost
;
struct
device
*
dev
;
};
struct
sdebug_host_info
*
scsi_debug_hosts
;
#define SDEBUG_SENSE_LEN 32
...
...
@@ -145,7 +152,10 @@ static int num_host_resets = 0;
static
spinlock_t
queued_arr_lock
=
SPIN_LOCK_UNLOCKED
;
static
rwlock_t
atomic_rw
=
RW_LOCK_UNLOCKED
;
static
struct
device_driver
sdebug_driverfs_driver
;
static
char
sdebug_proc_name
[]
=
"scsi_debug"
;
static
struct
device_driver
sdebug_driverfs_driver
=
{
.
name
=
sdebug_proc_name
,
};
/* function declarations */
static
int
resp_inquiry
(
unsigned
char
*
cmd
,
int
target
,
unsigned
char
*
buff
,
...
...
@@ -175,8 +185,15 @@ static int inquiry_evpd_83(unsigned char * arr, int dev_id_num,
const
char
*
dev_id_str
,
int
dev_id_str_len
);
static
void
do_create_driverfs_files
(
void
);
static
void
do_remove_driverfs_files
(
void
);
static
struct
Scsi_Host
*
sdebug_add_shost
(
void
);
static
void
sdebug_add_shost
(
int
num
);
static
void
sdebug_remove_shost
(
int
num
);
static
int
sdebug_add_adapter
(
int
num
);
static
void
sdebug_remove_adapter
(
int
num
);
static
struct
device
pseudo_primary
;
static
struct
bus_type
pseudo_lld_bus
;
int
scsi_debug_register_driver
(
struct
device_driver
*
);
int
scsi_debug_unregister_driver
(
struct
device_driver
*
);
static
unsigned
char
*
scatg2virt
(
const
struct
scatterlist
*
sclp
)
{
...
...
@@ -193,13 +210,12 @@ static
int
scsi_debug_queuecommand
(
struct
scsi_cmnd
*
SCpnt
,
done_funct_t
done
)
{
unsigned
char
*
cmd
=
(
unsigned
char
*
)
SCpnt
->
cmnd
;
int
block
;
int
upper_blk
;
int
block
,
upper_blk
,
num
;
unsigned
char
*
buff
;
int
errsts
=
0
;
int
target
=
SCpnt
->
target
;
int
bufflen
=
SCpnt
->
request_bufflen
;
int
num
,
capac
;
unsigned
long
capac
;
struct
sdebug_dev_info
*
devip
=
NULL
;
unsigned
char
*
sbuff
;
...
...
@@ -230,11 +246,6 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
if
(
SCpnt
->
lun
>=
scsi_debug_max_luns
)
return
schedule_resp
(
SCpnt
,
NULL
,
done
,
DID_NO_CONNECT
<<
16
,
0
);
#if 0
printk(KERN_INFO "sdebug:qc: host_no=%u, id=%u, sdp=%p, cmd=0x%x\n",
(int)SCpnt->device->host->host_no, (int)SCpnt->device->id,
SCpnt->device, (int)*cmd);
#endif
devip
=
devInfoReg
(
SCpnt
);
if
(
NULL
==
devip
)
return
schedule_resp
(
SCpnt
,
NULL
,
done
,
...
...
@@ -302,7 +313,7 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
errsts
=
check_reset
(
SCpnt
,
devip
);
memset
(
buff
,
0
,
bufflen
);
if
(
bufflen
>
7
)
{
capac
=
CAPACITY
-
1
;
capac
=
(
unsigned
long
)
sdebug_capacity
-
1
;
buff
[
0
]
=
(
capac
>>
24
);
buff
[
1
]
=
(
capac
>>
16
)
&
0xff
;
buff
[
2
]
=
(
capac
>>
8
)
&
0xff
;
...
...
@@ -382,10 +393,6 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
memset
(
buff
,
0
,
bufflen
);
break
;
default:
#if 0
printk(KERN_INFO "scsi_debug: Unsupported command, "
"opcode=0x%x\n", (int)cmd[0]);
#endif
if
((
errsts
=
check_reset
(
SCpnt
,
devip
)))
break
;
mk_sense_buffer
(
devip
,
ILLEGAL_REQUEST
,
0x20
,
0
,
14
);
...
...
@@ -543,8 +550,8 @@ static int resp_format_pg(unsigned char * p, int pcontrol, int target)
0
,
0
,
0
,
0
,
0x40
,
0
,
0
,
0
};
memcpy
(
p
,
format_pg
,
sizeof
(
format_pg
));
p
[
10
]
=
(
N_SECTOR
>>
8
)
&
0xff
;
p
[
11
]
=
N_SECTOR
&
0xff
;
p
[
10
]
=
(
sdebug_sectors_per
>>
8
)
&
0xff
;
p
[
11
]
=
sdebug_sectors_per
&
0xff
;
p
[
12
]
=
(
SECT_SIZE
>>
8
)
&
0xff
;
p
[
13
]
=
SECT_SIZE
&
0xff
;
if
(
DEV_REMOVEABLE
(
target
))
...
...
@@ -673,7 +680,7 @@ static int resp_read(struct scsi_cmnd * SCpnt, int upper_blk, int block,
int
bufflen
=
SCpnt
->
request_bufflen
;
unsigned
long
iflags
;
if
(
upper_blk
||
(
block
+
num
>
CAPACITY
))
{
if
(
upper_blk
||
(
block
+
num
>
sdebug_capacity
))
{
mk_sense_buffer
(
devip
,
ILLEGAL_REQUEST
,
0x21
,
0
,
14
);
return
(
COMMAND_COMPLETE
<<
8
)
|
(
CHECK_CONDITION
<<
1
);
}
...
...
@@ -722,7 +729,7 @@ static int resp_write(struct scsi_cmnd * SCpnt, int upper_blk, int block,
int
bufflen
=
SCpnt
->
request_bufflen
;
unsigned
long
iflags
;
if
(
upper_blk
||
(
block
+
num
>
CAPACITY
))
{
if
(
upper_blk
||
(
block
+
num
>
sdebug_capacity
))
{
mk_sense_buffer
(
devip
,
ILLEGAL_REQUEST
,
0x21
,
0
,
14
);
return
(
COMMAND_COMPLETE
<<
8
)
|
(
CHECK_CONDITION
<<
1
);
}
...
...
@@ -805,8 +812,6 @@ static void timer_intr_handler(unsigned long indx)
spin_unlock_irqrestore
(
&
queued_arr_lock
,
iflags
);
}
static
const
char
*
sdebug_proc_name
=
"scsi_debug"
;
static
int
scsi_debug_slave_attach
(
struct
scsi_device
*
sdp
)
{
int
k
;
...
...
@@ -910,14 +915,22 @@ static int scsi_debug_abort(struct scsi_cmnd * SCpnt)
static
int
scsi_debug_biosparam
(
struct
scsi_device
*
sdev
,
struct
block_device
*
bdev
,
sector_t
capacity
,
int
*
info
)
{
int
res
;
unsigned
char
*
buf
;
if
(
SCSI_DEBUG_OPT_NOISE
&
scsi_debug_opts
)
printk
(
KERN_INFO
"scsi_debug: biosparam
\n
"
);
/* int size = capacity; */
info
[
0
]
=
N_HEAD
;
info
[
1
]
=
N_SECTOR
;
info
[
2
]
=
N_CYLINDER
;
if
(
info
[
2
]
>=
1024
)
info
[
2
]
=
1024
;
buf
=
scsi_bios_ptable
(
bdev
);
if
(
buf
)
{
res
=
scsi_partsize
(
buf
,
capacity
,
&
info
[
2
],
&
info
[
0
],
&
info
[
1
]);
kfree
(
buf
);
if
(
!
res
)
return
res
;
}
info
[
0
]
=
sdebug_heads
;
info
[
1
]
=
sdebug_sectors_per
;
info
[
2
]
=
sdebug_cylinders_per
;
return
0
;
}
...
...
@@ -1289,7 +1302,7 @@ static int scsi_debug_proc_info(char *buffer, char **start, off_t offset,
scsi_debug_dev_size_mb
,
scsi_debug_opts
,
scsi_debug_every_nth
,
scsi_debug_cmnd_count
,
scsi_debug_delay
,
scsi_debug_max_luns
,
scsi_debug_scsi_level
,
SECT_SIZE
,
N_CYLINDER
,
N_HEAD
,
N_SECTOR
,
SECT_SIZE
,
sdebug_cylinders_per
,
sdebug_heads
,
sdebug_sectors_per
,
num_aborts
,
num_dev_resets
,
num_bus_resets
,
num_host_resets
);
if
(
pos
<
offset
)
{
len
=
0
;
...
...
@@ -1402,7 +1415,6 @@ static ssize_t sdebug_add_host_read(struct device_driver * ddp, char * buf,
static
ssize_t
sdebug_add_host_write
(
struct
device_driver
*
ddp
,
const
char
*
buf
,
size_t
count
,
loff_t
off
)
{
struct
Scsi_Host
*
hpnt
;
int
delta_hosts
,
k
;
char
work
[
20
];
...
...
@@ -1410,14 +1422,21 @@ static ssize_t sdebug_add_host_write(struct device_driver * ddp,
return
0
;
if
(
1
!=
sscanf
(
buf
,
"%10s"
,
work
))
return
-
EINVAL
;
if
(
1
!=
sscanf
(
work
,
"%d"
,
&
delta_hosts
))
return
-
EINVAL
;
{
/* temporary hack around sscanf() problem with -ve nums */
int
neg
=
0
;
if
(
'-'
==
*
work
)
neg
=
1
;
if
(
1
!=
sscanf
(
work
+
neg
,
"%d"
,
&
delta_hosts
))
return
-
EINVAL
;
if
(
neg
)
delta_hosts
=
-
delta_hosts
;
}
if
(
delta_hosts
>
0
)
{
do
{
for
(
k
=
0
;
k
<
MAX_NUM_HOSTS
;
++
k
)
{
if
(
NULL
==
scsi_debug_hosts
[
k
])
{
hpnt
=
sdebug_add_shost
();
scsi_debug_hosts
[
k
]
=
hpnt
;
if
(
NULL
==
scsi_debug_hosts
[
k
].
shost
)
{
sdebug_add_shost
(
k
);
break
;
}
}
...
...
@@ -1428,10 +1447,8 @@ static ssize_t sdebug_add_host_write(struct device_driver * ddp,
}
else
if
(
delta_hosts
<
0
)
{
do
{
for
(
k
=
MAX_NUM_HOSTS
-
1
;
k
>=
0
;
--
k
)
{
if
(
scsi_debug_hosts
[
k
])
{
scsi_remove_host
(
scsi_debug_hosts
[
k
]);
scsi_unregister
(
scsi_debug_hosts
[
k
]);
scsi_debug_hosts
[
k
]
=
NULL
;
if
(
scsi_debug_hosts
[
k
].
shost
)
{
sdebug_remove_shost
(
k
);
break
;
}
}
...
...
@@ -1469,30 +1486,65 @@ static void do_remove_driverfs_files()
driver_remove_file
(
&
sdebug_driverfs_driver
,
&
driver_attr_delay
);
}
static
struct
Scsi_Host
*
sdebug_add_shost
(
void
)
static
void
sdebug_add_shost
(
int
num
)
{
struct
Scsi_Host
*
hpnt
;
int
err
;
if
(
sdebug_add_adapter
(
num
)){
printk
(
KERN_ERR
"sdebug_add_shost: sdebug_add_adapter failed
\n
"
);
return
;
}
hpnt
=
scsi_register
(
&
sdebug_driver_template
,
0
);
if
(
NULL
==
hpnt
)
{
sdebug_remove_adapter
(
num
);
printk
(
KERN_ERR
"sdebug_add_shost: scsi_register failed
\n
"
);
return
NULL
;
return
;
}
err
=
scsi_add_host
(
hpnt
);
if
(
err
)
{
printk
(
KERN_ERR
"sdebug_add_shost: scsi_add_host failed
\n
"
);
scsi_unregister
(
hpnt
);
return
NULL
;
sdebug_remove_adapter
(
num
);
return
;
}
hpnt
->
max_lun
=
scsi_debug_max_luns
;
return
hpnt
;
scsi_debug_hosts
[
num
].
shost
=
hpnt
;
}
static
void
sdebug_remove_shost
(
int
num
)
{
scsi_remove_host
(
scsi_debug_hosts
[
num
].
shost
);
scsi_unregister
(
scsi_debug_hosts
[
num
].
shost
);
sdebug_remove_adapter
(
num
);
scsi_debug_hosts
[
num
].
shost
=
NULL
;
}
static
int
__init
scsi_debug_init
(
void
)
{
int
sz
,
k
;
unsigned
long
sz
;
int
k
;
sdebug_store_size
=
(
unsigned
long
)
scsi_debug_dev_size_mb
*
1048576
;
sdebug_capacity
=
sdebug_store_size
/
SECT_SIZE
;
/* play around with geometry, don't waste too much on track 0 */
sdebug_heads
=
8
;
sdebug_sectors_per
=
32
;
if
(
scsi_debug_dev_size_mb
>=
16
)
sdebug_heads
=
32
;
else
if
(
scsi_debug_dev_size_mb
>=
256
)
sdebug_heads
=
64
;
sdebug_cylinders_per
=
(
unsigned
long
)
sdebug_capacity
/
(
sdebug_sectors_per
*
sdebug_heads
);
if
(
sdebug_cylinders_per
>=
1024
)
{
/* other LLDs do this; implies >= 1GB ram disk ... */
sdebug_heads
=
255
;
sdebug_sectors_per
=
63
;
sdebug_cylinders_per
=
(
unsigned
long
)
sdebug_capacity
/
(
sdebug_sectors_per
*
sdebug_heads
);
}
if
(
scsi_debug_num_devs
>
0
)
{
sz
=
sizeof
(
struct
sdebug_dev_info
)
*
scsi_debug_num_devs
;
...
...
@@ -1504,7 +1556,15 @@ static int __init scsi_debug_init(void)
memset
(
devInfop
,
0
,
sz
);
}
sz
=
STORE_SIZE
;
sz
=
sizeof
(
struct
sdebug_host_info
)
*
MAX_NUM_HOSTS
;
scsi_debug_hosts
=
vmalloc
(
sz
);
if
(
NULL
==
scsi_debug_hosts
)
{
printk
(
KERN_ERR
"scsi_debug_init: out of memory 1
\n
"
);
return
-
ENOMEM
;
}
memset
(
scsi_debug_hosts
,
0
,
sz
);
sz
=
sdebug_store_size
;
fake_storep
=
vmalloc
(
sz
);
if
(
NULL
==
fake_storep
)
{
printk
(
KERN_ERR
"scsi_debug_init: out of memory, 1
\n
"
);
...
...
@@ -1516,23 +1576,22 @@ static int __init scsi_debug_init(void)
init_all_queued
();
sdebug_driverfs_driver
.
name
=
(
char
*
)
sdebug_proc_name
;
sdebug_driverfs_driver
.
bus
=
&
scsi_driverfs_bus_type
;
driver_regist
er
(
&
sdebug_driverfs_driver
);
device_register
(
&
pseudo_primary
)
;
bus_register
(
&
pseudo_lld_bus
)
;
scsi_debug_register_driv
er
(
&
sdebug_driverfs_driver
);
do_create_driverfs_files
();
sdebug_driver_template
.
proc_name
=
(
char
*
)
sdebug_proc_name
;
memset
(
scsi_debug_hosts
,
0
,
sizeof
(
struct
Scsi_Host
*
)
*
MAX_NUM_HOSTS
);
for
(
k
=
0
;
(
k
<
scsi_debug_add_host
)
&&
(
k
<
MAX_NUM_HOSTS
);
k
++
)
{
s
csi_debug_hosts
[
k
]
=
sdebug_add_shost
(
);
if
(
NULL
==
scsi_debug_hosts
[
k
])
{
s
debug_add_shost
(
k
);
if
(
NULL
==
scsi_debug_hosts
[
k
]
.
shost
)
{
printk
(
KERN_ERR
"scsi_debug_init: "
"sdebug_add_shost failed k=%d
\n
"
,
k
);
break
;
}
}
scsi_debug_add_host
=
k
;
// number of hosts actually present
scsi_debug_add_host
=
k
;
// number of hosts actually present
if
(
SCSI_DEBUG_OPT_NOISE
&
scsi_debug_opts
)
{
printk
(
KERN_INFO
"scsi_debug: ... built %d host(s)
\n
"
,
...
...
@@ -1546,20 +1605,78 @@ static void __exit scsi_debug_exit(void)
int
k
;
for
(
k
=
MAX_NUM_HOSTS
-
1
;
k
>=
0
;
--
k
)
{
if
(
scsi_debug_hosts
[
k
])
{
scsi_remove_host
(
scsi_debug_hosts
[
k
]);
scsi_unregister
(
scsi_debug_hosts
[
k
]);
scsi_debug_hosts
[
k
]
=
NULL
;
if
(
scsi_debug_hosts
[
k
].
shost
)
{
sdebug_remove_shost
(
k
);
}
}
stop_all_queued
();
do_remove_driverfs_files
();
driver_unregister
(
&
sdebug_driverfs_driver
);
scsi_debug_unregister_driver
(
&
sdebug_driverfs_driver
);
bus_unregister
(
&
pseudo_lld_bus
);
device_unregister
(
&
pseudo_primary
);
vfree
(
fake_storep
);
if
(
devInfop
)
vfree
(
devInfop
);
}
module_init
(
scsi_debug_init
);
device_initcall
(
scsi_debug_init
);
module_exit
(
scsi_debug_exit
);
static
struct
device
pseudo_primary
=
{
.
name
=
"Host/Pseudo Bridge"
,
.
bus_id
=
"pseudo_0"
,
};
static
int
pseudo_lld_bus_match
(
struct
device
*
dev
,
struct
device_driver
*
dev_driver
)
{
return
1
;
}
static
struct
bus_type
pseudo_lld_bus
=
{
name:
"pseudo"
,
match:
pseudo_lld_bus_match
,
};
int
scsi_debug_register_driver
(
struct
device_driver
*
dev_driver
)
{
dev_driver
->
bus
=
&
pseudo_lld_bus
;
driver_register
(
dev_driver
);
return
0
;
}
int
scsi_debug_unregister_driver
(
struct
device_driver
*
dev_driver
)
{
driver_unregister
(
dev_driver
);
return
0
;
}
static
int
sdebug_add_adapter
(
int
num
)
{
struct
device
*
dev
;
dev
=
kmalloc
(
sizeof
(
*
dev
),
GFP_KERNEL
);
if
(
NULL
==
dev
)
{
printk
(
KERN_ERR
"%s: out of memory
\n
"
,
__FUNCTION__
);
return
1
;
}
memset
(
dev
,
0
,
sizeof
(
*
dev
));
dev
->
bus
=
&
pseudo_lld_bus
;
dev
->
parent
=
&
pseudo_primary
;
sprintf
(
dev
->
name
,
"scsi debug adapter"
);
sprintf
(
dev
->
bus_id
,
"adapter%d"
,
num
);
device_register
(
dev
);
scsi_debug_hosts
[
num
].
dev
=
dev
;
return
0
;
}
static
void
sdebug_remove_adapter
(
int
num
)
{
device_unregister
(
scsi_debug_hosts
[
num
].
dev
);
}
drivers/scsi/scsi_debug.h
View file @
2983e9a6
...
...
@@ -43,6 +43,7 @@ static Scsi_Host_Template sdebug_driver_template = {
.
max_sectors
=
4096
,
.
unchecked_isa_dma
=
0
,
.
use_clustering
=
ENABLE_CLUSTERING
,
.
module
=
THIS_MODULE
,
};
#endif
drivers/scsi/scsi_error.c
View file @
2983e9a6
...
...
@@ -1479,8 +1479,6 @@ static void scsi_restart_operations(struct Scsi_Host *shost)
*/
spin_lock_irqsave
(
shost
->
host_lock
,
flags
);
for
(
sdev
=
shost
->
host_queue
;
sdev
;
sdev
=
sdev
->
next
)
{
request_queue_t
*
q
=
&
sdev
->
request_queue
;
if
((
shost
->
can_queue
>
0
&&
(
shost
->
host_busy
>=
shost
->
can_queue
))
||
(
shost
->
host_blocked
)
...
...
@@ -1488,7 +1486,7 @@ static void scsi_restart_operations(struct Scsi_Host *shost)
break
;
}
q
->
request_fn
(
q
);
__blk_run_queue
(
&
sdev
->
request_queue
);
}
spin_unlock_irqrestore
(
shost
->
host_lock
,
flags
);
}
...
...
drivers/scsi/scsi_lib.c
View file @
2983e9a6
...
...
@@ -7,49 +7,18 @@
* of people at Linux Expo.
*/
/*
* The fundamental purpose of this file is to contain a library of utility
* routines that can be used by low-level drivers. Ultimately the idea
* is that there should be a sufficiently rich number of functions that it
* would be possible for a driver author to fashion a queueing function for
* a low-level driver if they wished. Note however that this file also
* contains the "default" versions of these functions, as we don't want to
* go through and retrofit queueing functions into all 30 some-odd drivers.
*/
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/bio.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/stat.h>
#include <linux/blk.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/smp_lock.h>
#include <linux/completion.h>
#define __KERNEL_SYSCALLS__
#include <linux/unistd.h>
#include <asm/system.h>
#include <asm/irq.h>
#include <asm/dma.h>
#include "scsi.h"
#include "hosts.h"
#include <scsi/scsi_ioctl.h>
/*
* This entire source file deals with the new queueing code.
*/
/*
* Function: scsi_insert_special_cmd()
*
...
...
@@ -259,7 +228,7 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt)
/*
* Just hit the requeue function for the queue.
*/
q
->
request_fn
(
q
);
__blk_run_queue
(
q
);
SDpnt
=
(
Scsi_Device
*
)
q
->
queuedata
;
SHpnt
=
SDpnt
->
host
;
...
...
@@ -272,8 +241,6 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt)
* use function pointers to pick the right one.
*/
if
(
SDpnt
->
single_lun
&&
blk_queue_empty
(
q
)
&&
SDpnt
->
device_busy
==
0
)
{
request_queue_t
*
q
;
for
(
SDpnt
=
SHpnt
->
host_queue
;
SDpnt
;
SDpnt
=
SDpnt
->
next
)
{
if
(((
SHpnt
->
can_queue
>
0
)
&&
(
SHpnt
->
host_busy
>=
SHpnt
->
can_queue
))
...
...
@@ -283,8 +250,7 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt)
break
;
}
q
=
&
SDpnt
->
request_queue
;
q
->
request_fn
(
q
);
__blk_run_queue
(
&
SDpnt
->
request_queue
);
}
}
...
...
@@ -299,7 +265,6 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt)
all_clear
=
1
;
if
(
SHpnt
->
some_device_starved
)
{
for
(
SDpnt
=
SHpnt
->
host_queue
;
SDpnt
;
SDpnt
=
SDpnt
->
next
)
{
request_queue_t
*
q
;
if
((
SHpnt
->
can_queue
>
0
&&
(
SHpnt
->
host_busy
>=
SHpnt
->
can_queue
))
||
(
SHpnt
->
host_blocked
)
||
(
SHpnt
->
host_self_blocked
))
{
...
...
@@ -308,8 +273,7 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt)
if
(
SDpnt
->
device_blocked
||
!
SDpnt
->
starved
)
{
continue
;
}
q
=
&
SDpnt
->
request_queue
;
q
->
request_fn
(
q
);
__blk_run_queue
(
&
SDpnt
->
request_queue
);
all_clear
=
0
;
}
if
(
SDpnt
==
NULL
&&
all_clear
)
{
...
...
@@ -1021,10 +985,11 @@ void scsi_request_fn(request_queue_t * q)
break
;
if
(
!
req
)
{
/* can happen if the prep fails
* FIXME: elv_next_request() should be plugging the
* queue */
blk_plug_device
(
q
);
/* If the device is busy, a returning I/O
* will restart the queue. Otherwise, we have
* to plug the queue */
if
(
SDpnt
->
device_busy
==
0
)
blk_plug_device
(
q
);
break
;
}
...
...
drivers/scsi/scsi_proc.c
View file @
2983e9a6
...
...
@@ -607,25 +607,9 @@ static int proc_scsi_gen_write(struct file * file, const char * buf,
if
(
sdev
->
attached
==
0
)
{
devfs_unregister
(
sdev
->
de
);
/* Now we can remove the device structure */
if
(
sdev
->
next
!=
NULL
)
sdev
->
next
->
prev
=
sdev
->
prev
;
if
(
sdev
->
prev
!=
NULL
)
sdev
->
prev
->
next
=
sdev
->
next
;
if
(
shost
->
host_queue
==
sdev
)
{
shost
->
host_queue
=
sdev
->
next
;
}
blk_cleanup_queue
(
&
sdev
->
request_queue
);
if
(
sdev
->
inquiry
)
kfree
(
sdev
->
inquiry
);
kfree
((
char
*
)
sdev
);
}
else
{
goto
out
;
scsi_free_sdev
(
sdev
);
err
=
0
;
}
err
=
0
;
}
out:
...
...
drivers/scsi/scsi_scan.c
View file @
2983e9a6
...
...
@@ -465,12 +465,12 @@ static void scsi_initialize_merge_fn(struct scsi_device *sd)
* Return value:
* Scsi_Device pointer, or NULL on failure.
**/
st
atic
Scsi_D
evice
*
scsi_alloc_sdev
(
struct
Scsi_Host
*
shost
,
uint
channel
,
st
ruct
scsi_d
evice
*
scsi_alloc_sdev
(
struct
Scsi_Host
*
shost
,
uint
channel
,
uint
id
,
uint
lun
)
{
Scsi_D
evice
*
sdev
;
struct
scsi_d
evice
*
sdev
;
sdev
=
(
Scsi_Device
*
)
kmalloc
(
sizeof
(
Scsi_Device
),
GFP_ATOMIC
);
sdev
=
kmalloc
(
sizeof
(
*
sdev
),
GFP_ATOMIC
);
if
(
sdev
==
NULL
)
printk
(
ALLOC_FAILURE_MSG
,
__FUNCTION__
);
else
{
...
...
@@ -522,7 +522,7 @@ static Scsi_Device *scsi_alloc_sdev(struct Scsi_Host *shost, uint channel,
* Undo the actions in scsi_alloc_sdev, including removing @sdev from
* the list, and freeing @sdev.
**/
static
void
scsi_free_sdev
(
Scsi_D
evice
*
sdev
)
void
scsi_free_sdev
(
struct
scsi_d
evice
*
sdev
)
{
if
(
sdev
->
prev
!=
NULL
)
sdev
->
prev
->
next
=
sdev
->
next
;
...
...
include/linux/blkdev.h
View file @
2983e9a6
...
...
@@ -321,6 +321,7 @@ extern int scsi_cmd_ioctl(struct block_device *, unsigned int, unsigned long);
extern
void
blk_start_queue
(
request_queue_t
*
q
);
extern
void
blk_stop_queue
(
request_queue_t
*
q
);
extern
void
__blk_stop_queue
(
request_queue_t
*
q
);
extern
void
__blk_run_queue
(
request_queue_t
*
q
);
static
inline
request_queue_t
*
bdev_get_queue
(
struct
block_device
*
bdev
)
{
...
...
include/scsi/scsi_ioctl.h
View file @
2983e9a6
...
...
@@ -17,6 +17,8 @@
#ifdef __KERNEL__
struct
scsi_device
;
/*
* Structures used for scsi_ioctl et al.
*/
...
...
@@ -33,19 +35,15 @@ typedef struct scsi_idlun {
}
Scsi_Idlun
;
/* Fibre Channel WWN, port_id struct */
typedef
struct
scsi_fctargaddress
{
typedef
struct
scsi_fctargaddress
{
__u32
host_port_id
;
unsigned
char
host_wwn
[
8
];
// include NULL term.
}
Scsi_FCTargAddress
;
extern
int
scsi_ioctl
(
Scsi_Device
*
dev
,
int
cmd
,
void
*
arg
);
extern
int
kernel_scsi_ioctl
(
Scsi_Device
*
dev
,
int
cmd
,
void
*
arg
);
extern
int
scsi_ioctl_send_command
(
Scsi_Device
*
dev
,
Scsi_Ioctl_Command
*
arg
);
#endif
#endif
extern
int
scsi_ioctl
(
struct
scsi_device
*
,
int
,
void
*
);
extern
int
kernel_scsi_ioctl
(
struct
scsi_device
*
,
int
,
void
*
);
extern
int
scsi_ioctl_send_command
(
struct
scsi_device
*
,
struct
scsi_ioctl_command
*
);
#endif
/* __KERNEL__ */
#endif
/* _SCSI_IOCTL_H */
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