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
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