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
4794bf02
Commit
4794bf02
authored
Nov 20, 2002
by
Christoph Hellwig
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] turn scsi_allocate_device into readable code
parent
1b29b8d4
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
105 additions
and
156 deletions
+105
-156
drivers/scsi/cpqfcTSinit.c
drivers/scsi/cpqfcTSinit.c
+1
-1
drivers/scsi/gdth.c
drivers/scsi/gdth.c
+2
-2
drivers/scsi/gdth_proc.c
drivers/scsi/gdth_proc.c
+2
-2
drivers/scsi/scsi.c
drivers/scsi/scsi.c
+96
-146
drivers/scsi/scsi.h
drivers/scsi/scsi.h
+1
-1
drivers/scsi/scsi_lib.c
drivers/scsi/scsi_lib.c
+3
-4
No files found.
drivers/scsi/cpqfcTSinit.c
View file @
4794bf02
...
...
@@ -1601,7 +1601,7 @@ return -ENOTSUPP;
scsi_cdb
[
0
]
=
RELEASE
;
// allocate with wait = true, interruptible = false
SCpnt
=
scsi_allocate_device
(
ScsiDev
,
1
,
0
);
SCpnt
=
scsi_allocate_device
(
ScsiDev
,
1
);
{
CPQFC_DECLARE_COMPLETION
(
wait
);
...
...
drivers/scsi/gdth.c
View file @
4794bf02
...
...
@@ -4599,7 +4599,7 @@ static void gdth_flush(int hanum)
#if LINUX_VERSION_CODE >= 0x020322
sdev
=
scsi_get_host_dev
(
gdth_ctr_tab
[
hanum
]);
scp
=
scsi_allocate_device
(
sdev
,
1
,
FALSE
);
scp
=
scsi_allocate_device
(
sdev
,
1
);
scp
->
cmd_len
=
12
;
scp
->
use_sg
=
0
;
#else
...
...
@@ -4673,7 +4673,7 @@ void gdth_halt(void)
memset
(
cmnd
,
0xff
,
MAX_COMMAND_SIZE
);
#if LINUX_VERSION_CODE >= 0x020322
sdev
=
scsi_get_host_dev
(
gdth_ctr_tab
[
hanum
]);
scp
=
scsi_allocate_device
(
sdev
,
1
,
FALSE
);
scp
=
scsi_allocate_device
(
sdev
,
1
);
scp
->
cmd_len
=
12
;
scp
->
use_sg
=
0
;
#else
...
...
drivers/scsi/gdth_proc.c
View file @
4794bf02
...
...
@@ -48,7 +48,7 @@ static int gdth_set_info(char *buffer,int length,int vh,int hanum,int busnum)
#if LINUX_VERSION_CODE >= 0x020322
sdev
=
scsi_get_host_dev
(
gdth_ctr_vtab
[
vh
]);
scp
=
scsi_allocate_device
(
sdev
,
1
,
FALSE
);
scp
=
scsi_allocate_device
(
sdev
,
1
);
if
(
!
scp
)
return
-
ENOMEM
;
scp
->
cmd_len
=
12
;
...
...
@@ -712,7 +712,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,
#if LINUX_VERSION_CODE >= 0x020322
sdev
=
scsi_get_host_dev
(
gdth_ctr_vtab
[
vh
]);
scp
=
scsi_allocate_device
(
sdev
,
1
,
FALSE
);
scp
=
scsi_allocate_device
(
sdev
,
1
);
if
(
!
scp
)
return
-
ENOMEM
;
scp
->
cmd_len
=
12
;
...
...
drivers/scsi/scsi.c
View file @
4794bf02
...
...
@@ -346,6 +346,41 @@ void scsi_release_request(Scsi_Request * req)
kfree
(
req
);
}
/*
* FIXME(eric) - this is not at all optimal. Given that
* single lun devices are rare and usually slow
* (i.e. CD changers), this is good enough for now, but
* we may want to come back and optimize this later.
*
* Scan through all of the devices attached to this
* host, and see if any are active or not. If so,
* we need to defer this command.
*
* We really need a busy counter per device. This would
* allow us to more easily figure out whether we should
* do anything here or not.
*/
static
int
check_all_luns
(
struct
Scsi_Host
*
shost
,
struct
scsi_device
*
myself
)
{
struct
scsi_device
*
sdev
;
for
(
sdev
=
shost
->
host_queue
;
sdev
;
sdev
=
sdev
->
next
)
{
/*
* Only look for other devices on the same bus
* with the same target ID.
*/
if
(
sdev
->
channel
!=
myself
->
channel
||
sdev
->
id
!=
myself
->
id
)
continue
;
if
(
sdev
==
myself
)
continue
;
if
(
atomic_read
(
&
sdev
->
device_active
))
return
1
;
}
return
0
;
}
/*
* Function: scsi_allocate_device
*
...
...
@@ -372,172 +407,87 @@ void scsi_release_request(Scsi_Request * req)
* This function is deprecated, and drivers should be
* rewritten to use Scsi_Request instead of Scsi_Cmnd.
*/
Scsi_Cmnd
*
scsi_allocate_device
(
Scsi_Device
*
device
,
int
wait
,
int
interruptable
)
struct
scsi_cmnd
*
scsi_allocate_device
(
struct
scsi_device
*
sdev
,
int
wait
)
{
struct
Scsi_Host
*
host
;
Scsi_Cmnd
*
SCpnt
=
NULL
;
Scsi_Device
*
SDpnt
;
DECLARE_WAITQUEUE
(
wq
,
current
)
;
struct
Scsi_Host
*
shost
=
sdev
->
host
;
struct
scsi_cmnd
*
scmnd
;
unsigned
long
flags
;
if
(
!
device
)
panic
(
"No device passed to scsi_allocate_device().
\n
"
);
host
=
device
->
host
;
spin_lock_irqsave
(
&
device_request_lock
,
flags
);
while
(
1
==
1
)
{
SCpnt
=
NULL
;
if
(
!
device
->
device_blocked
)
{
if
(
device
->
single_lun
)
{
/*
* FIXME(eric) - this is not at all optimal. Given that
* single lun devices are rare and usually slow
* (i.e. CD changers), this is good enough for now, but
* we may want to come back and optimize this later.
*
* Scan through all of the devices attached to this
* host, and see if any are active or not. If so,
* we need to defer this command.
*
* We really need a busy counter per device. This would
* allow us to more easily figure out whether we should
* do anything here or not.
*/
for
(
SDpnt
=
host
->
host_queue
;
SDpnt
;
SDpnt
=
SDpnt
->
next
)
{
/*
* Only look for other devices on the same bus
* with the same target ID.
*/
if
(
SDpnt
->
channel
!=
device
->
channel
||
SDpnt
->
id
!=
device
->
id
||
SDpnt
==
device
)
{
continue
;
}
if
(
atomic_read
(
&
SDpnt
->
device_active
)
!=
0
)
{
break
;
}
}
if
(
SDpnt
)
{
/*
* Some other device in this cluster is busy.
* If asked to wait, we need to wait, otherwise
* return NULL.
*/
SCpnt
=
NULL
;
goto
busy
;
}
}
/*
* Now we can check for a free command block for this device.
*/
for
(
SCpnt
=
device
->
device_queue
;
SCpnt
;
SCpnt
=
SCpnt
->
next
)
{
if
(
SCpnt
->
request
==
NULL
)
break
;
}
}
while
(
1
)
{
if
(
sdev
->
device_blocked
)
goto
busy
;
if
(
sdev
->
single_lun
&&
check_all_luns
(
shost
,
sdev
))
goto
busy
;
/*
* If we couldn't find a free command block, and we have been
* asked to wait, then do so.
* Now we can check for a free command block for this device.
*/
if
(
SCpnt
)
{
break
;
}
busy:
for
(
scmnd
=
sdev
->
device_queue
;
scmnd
;
scmnd
=
scmnd
->
next
)
if
(
!
scmnd
->
request
)
goto
found
;
busy:
if
(
!
wait
)
goto
fail
;
/*
* If we have been asked to wait for a free block, then
* wait here.
* We need to wait for a free commandblock. We need to
* insert ourselves into the list before we release the
* lock. This way if a block were released the same
* microsecond that we released the lock, the call
* to schedule() wouldn't block (well, it might switch,
* but the current task will still be schedulable.
*/
if
(
wait
)
{
DECLARE_WAITQUEUE
(
wait
,
current
);
/*
* We need to wait for a free commandblock. We need to
* insert ourselves into the list before we release the
* lock. This way if a block were released the same
* microsecond that we released the lock, the call
* to schedule() wouldn't block (well, it might switch,
* but the current task will still be schedulable.
*/
add_wait_queue
(
&
device
->
scpnt_wait
,
&
wait
);
if
(
interruptable
)
{
set_current_state
(
TASK_INTERRUPTIBLE
);
}
else
{
set_current_state
(
TASK_UNINTERRUPTIBLE
);
}
spin_unlock_irqrestore
(
&
device_request_lock
,
flags
);
/*
* This should block until a device command block
* becomes available.
*/
schedule
();
add_wait_queue
(
&
sdev
->
scpnt_wait
,
&
wq
);
set_current_state
(
TASK_UNINTERRUPTIBLE
);
spin_lock_irqsave
(
&
device_request_lock
,
flags
);
spin_unlock_irqrestore
(
&
device_request_lock
,
flags
);
schedule
();
spin_lock_irqsave
(
&
device_request_lock
,
flags
);
remove_wait_queue
(
&
device
->
scpnt_wait
,
&
wait
);
/*
* FIXME - Isn't this redundant?? Someone
* else will have forced the state back to running.
*/
set_current_state
(
TASK_RUNNING
);
/*
* In the event that a signal has arrived that we need
* to consider, then simply return NULL. Everyone
* that calls us should be prepared for this
* possibility, and pass the appropriate code back
* to the user.
*/
if
(
interruptable
)
{
if
(
signal_pending
(
current
))
{
spin_unlock_irqrestore
(
&
device_request_lock
,
flags
);
return
NULL
;
}
}
}
else
{
spin_unlock_irqrestore
(
&
device_request_lock
,
flags
);
return
NULL
;
}
remove_wait_queue
(
&
sdev
->
scpnt_wait
,
&
wq
);
set_current_state
(
TASK_RUNNING
);
}
SCpnt
->
request
=
NULL
;
atomic_inc
(
&
SCpnt
->
host
->
host_active
);
atomic_inc
(
&
SCpnt
->
device
->
device_active
);
found:
scmnd
->
request
=
NULL
;
atomic_inc
(
&
scmnd
->
host
->
host_active
);
atomic_inc
(
&
scmnd
->
device
->
device_active
);
SCpnt
->
buffer
=
NULL
;
SCpnt
->
bufflen
=
0
;
SCpnt
->
request_buffer
=
NULL
;
SCpnt
->
request_bufflen
=
0
;
scmnd
->
buffer
=
NULL
;
scmnd
->
bufflen
=
0
;
scmnd
->
request_buffer
=
NULL
;
scmnd
->
request_bufflen
=
0
;
SCpnt
->
use_sg
=
0
;
/* Reset the scatter-gather flag */
SCpnt
->
old_use_sg
=
0
;
SCpnt
->
transfersize
=
0
;
/* No default transfer size */
SCpnt
->
cmd_len
=
0
;
scmnd
->
use_sg
=
0
;
/* Reset the scatter-gather flag */
scmnd
->
old_use_sg
=
0
;
scmnd
->
transfersize
=
0
;
/* No default transfer size */
scmnd
->
cmd_len
=
0
;
SCpnt
->
sc_data_direction
=
SCSI_DATA_UNKNOWN
;
SCpnt
->
sc_request
=
NULL
;
SCpnt
->
sc_magic
=
SCSI_CMND_MAGIC
;
scmnd
->
sc_data_direction
=
SCSI_DATA_UNKNOWN
;
scmnd
->
sc_request
=
NULL
;
scmnd
->
sc_magic
=
SCSI_CMND_MAGIC
;
SCpnt
->
result
=
0
;
SCpnt
->
underflow
=
0
;
/* Do not flag underflow conditions */
SCpnt
->
old_underflow
=
0
;
SCpnt
->
resid
=
0
;
SCpnt
->
state
=
SCSI_STATE_INITIALIZING
;
SCpnt
->
owner
=
SCSI_OWNER_HIGHLEVEL
;
scmnd
->
result
=
0
;
scmnd
->
underflow
=
0
;
/* Do not flag underflow conditions */
scmnd
->
old_underflow
=
0
;
scmnd
->
resid
=
0
;
scmnd
->
state
=
SCSI_STATE_INITIALIZING
;
scmnd
->
owner
=
SCSI_OWNER_HIGHLEVEL
;
spin_unlock_irqrestore
(
&
device_request_lock
,
flags
);
SCSI_LOG_MLQUEUE
(
5
,
printk
(
"Activating command for device %d (%d)
\n
"
,
SCpnt
->
target
,
atomic_read
(
&
SCpnt
->
host
->
host_active
)));
scmnd
->
target
,
atomic_read
(
&
scmnd
->
host
->
host_active
)));
return
scmnd
;
return
SCpnt
;
fail:
spin_unlock_irqrestore
(
&
device_request_lock
,
flags
);
return
NULL
;
}
inline
void
__scsi_release_command
(
Scsi_Cmnd
*
SCpnt
)
...
...
drivers/scsi/scsi.h
View file @
4794bf02
...
...
@@ -455,7 +455,7 @@ extern void scsi_slave_detach(struct scsi_device *sdev);
extern
void
scsi_done
(
Scsi_Cmnd
*
SCpnt
);
extern
void
scsi_finish_command
(
Scsi_Cmnd
*
);
extern
int
scsi_retry_command
(
Scsi_Cmnd
*
);
extern
Scsi_Cmnd
*
scsi_allocate_device
(
Scsi_Device
*
,
int
,
int
);
extern
Scsi_Cmnd
*
scsi_allocate_device
(
Scsi_Device
*
,
int
);
extern
void
__scsi_release_command
(
Scsi_Cmnd
*
);
extern
void
scsi_release_command
(
Scsi_Cmnd
*
);
extern
void
scsi_do_cmd
(
Scsi_Cmnd
*
,
const
void
*
cmnd
,
...
...
drivers/scsi/scsi_lib.c
View file @
4794bf02
...
...
@@ -762,8 +762,7 @@ int scsi_prep_fn(struct request_queue *q, struct request *req)
SRpnt
=
(
Scsi_Request
*
)
req
->
special
;
if
(
SRpnt
->
sr_magic
==
SCSI_REQ_MAGIC
)
{
SCpnt
=
scsi_allocate_device
(
SRpnt
->
sr_device
,
FALSE
,
FALSE
);
SCpnt
=
scsi_allocate_device
(
SRpnt
->
sr_device
,
0
);
if
(
!
SCpnt
)
return
BLKPREP_DEFER
;
scsi_init_cmd_from_req
(
SCpnt
,
SRpnt
);
...
...
@@ -774,9 +773,9 @@ int scsi_prep_fn(struct request_queue *q, struct request *req)
* Now try and find a command block that we can use.
*/
if
(
req
->
special
)
{
SCpnt
=
(
Scsi_Cmnd
*
)
req
->
special
;
SCpnt
=
(
Scsi_Cmnd
*
)
req
->
special
;
}
else
{
SCpnt
=
scsi_allocate_device
(
SDpnt
,
FALSE
,
FALSE
);
SCpnt
=
scsi_allocate_device
(
SDpnt
,
0
);
}
/*
* if command allocation failure, wait a bit
...
...
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