Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
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