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
8c0b740d
Commit
8c0b740d
authored
Jun 11, 2002
by
James Bottomley
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[SCSI mid-layer]
Add support for generic blk layer TCQ (needs blk_queue_find_tag function)
parent
838ede57
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
84 additions
and
23 deletions
+84
-23
drivers/scsi/hosts.h
drivers/scsi/hosts.h
+20
-0
drivers/scsi/scsi.c
drivers/scsi/scsi.c
+11
-2
drivers/scsi/scsi.h
drivers/scsi/scsi.h
+43
-17
drivers/scsi/scsi_lib.c
drivers/scsi/scsi_lib.c
+10
-4
No files found.
drivers/scsi/hosts.h
View file @
8c0b740d
...
@@ -562,6 +562,26 @@ extern int scsi_unregister_host(Scsi_Host_Template *);
...
@@ -562,6 +562,26 @@ extern int scsi_unregister_host(Scsi_Host_Template *);
#define SD_EXTRA_DEVS CONFIG_SD_EXTRA_DEVS
#define SD_EXTRA_DEVS CONFIG_SD_EXTRA_DEVS
#define SR_EXTRA_DEVS CONFIG_SR_EXTRA_DEVS
#define SR_EXTRA_DEVS CONFIG_SR_EXTRA_DEVS
/**
* scsi_find_device - find a device given the host
* @channel: SCSI channel (zero if only one channel)
* @pun: SCSI target number (physical unit number)
* @lun: SCSI Logical Unit Number
**/
static
inline
Scsi_Device
*
scsi_find_device
(
struct
Scsi_Host
*
host
,
int
channel
,
int
pun
,
int
lun
)
{
Scsi_Device
*
SDpnt
;
for
(
SDpnt
=
host
->
host_queue
;
SDpnt
!=
NULL
;
SDpnt
=
SDpnt
->
next
)
if
(
SDpnt
->
channel
==
channel
&&
SDpnt
->
id
==
pun
&&
SDpnt
->
lun
==
lun
)
break
;
return
SDpnt
;
}
#endif
#endif
/*
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Overrides for Emacs so that we follow Linus's tabbing style.
...
...
drivers/scsi/scsi.c
View file @
8c0b740d
...
@@ -254,11 +254,20 @@ __setup("scsi_logging=", scsi_logging_setup);
...
@@ -254,11 +254,20 @@ __setup("scsi_logging=", scsi_logging_setup);
static
void
scsi_wait_done
(
Scsi_Cmnd
*
SCpnt
)
static
void
scsi_wait_done
(
Scsi_Cmnd
*
SCpnt
)
{
{
struct
request
*
req
;
struct
request
*
req
=
SCpnt
->
request
;
struct
request_queue
*
q
=
&
SCpnt
->
device
->
request_queue
;
unsigned
long
flags
;
req
=
SCpnt
->
request
;
ASSERT_LOCK
(
q
->
queue_lock
,
0
)
;
req
->
rq_status
=
RQ_SCSI_DONE
;
/* Busy, but indicate request done */
req
->
rq_status
=
RQ_SCSI_DONE
;
/* Busy, but indicate request done */
spin_lock_irqsave
(
q
->
queue_lock
,
flags
);
if
(
blk_rq_tagged
(
req
))
blk_queue_end_tag
(
q
,
req
);
spin_unlock_irqrestore
(
q
->
queue_lock
,
flags
);
if
(
req
->
waiting
)
if
(
req
->
waiting
)
complete
(
req
->
waiting
);
complete
(
req
->
waiting
);
}
}
...
...
drivers/scsi/scsi.h
View file @
8c0b740d
...
@@ -560,6 +560,7 @@ struct scsi_device {
...
@@ -560,6 +560,7 @@ struct scsi_device {
atomic_t
device_active
;
/* commands checked out for device */
atomic_t
device_active
;
/* commands checked out for device */
volatile
unsigned
short
device_busy
;
/* commands actually active on low-level */
volatile
unsigned
short
device_busy
;
/* commands actually active on low-level */
Scsi_Cmnd
*
device_queue
;
/* queue of SCSI Command structures */
Scsi_Cmnd
*
device_queue
;
/* queue of SCSI Command structures */
Scsi_Cmnd
*
current_cmnd
;
/* currently active command */
unsigned
int
id
,
lun
,
channel
;
unsigned
int
id
,
lun
,
channel
;
...
@@ -881,6 +882,8 @@ static inline void scsi_deactivate_tcq(Scsi_Device *SDpnt) {
...
@@ -881,6 +882,8 @@ static inline void scsi_deactivate_tcq(Scsi_Device *SDpnt) {
#define MSG_HEAD_TAG 0x21
#define MSG_HEAD_TAG 0x21
#define MSG_ORDERED_TAG 0x22
#define MSG_ORDERED_TAG 0x22
#define SCSI_NO_TAG (-1)
/* identify no tag in use */
/**
/**
* scsi_populate_tag_msg - place a tag message in a buffer
* scsi_populate_tag_msg - place a tag message in a buffer
* @SCpnt: pointer to the Scsi_Cmnd for the tag
* @SCpnt: pointer to the Scsi_Cmnd for the tag
...
@@ -907,6 +910,29 @@ static inline int scsi_populate_tag_msg(Scsi_Cmnd *SCpnt, char *msg) {
...
@@ -907,6 +910,29 @@ static inline int scsi_populate_tag_msg(Scsi_Cmnd *SCpnt, char *msg) {
return
2
;
return
2
;
}
}
/**
* scsi_find_tag - find a tagged command by device
* @SDpnt: pointer to the ScSI device
* @tag: the tag number
*
* Notes:
* Only works with tags allocated by the generic blk layer.
**/
static
inline
Scsi_Cmnd
*
scsi_find_tag
(
Scsi_Device
*
SDpnt
,
int
tag
)
{
struct
request
*
req
;
if
(
tag
==
SCSI_NO_TAG
)
/* single command, look in space */
return
SDpnt
->
current_cmnd
;
req
=
blk_queue_find_tag
(
&
SDpnt
->
request_queue
,
tag
);
if
(
req
==
NULL
)
return
NULL
;
return
(
Scsi_Cmnd
*
)
req
->
special
;
}
#endif
#endif
...
...
drivers/scsi/scsi_lib.c
View file @
8c0b740d
...
@@ -76,7 +76,8 @@ static void __scsi_insert_special(request_queue_t *q, struct request *rq,
...
@@ -76,7 +76,8 @@ static void __scsi_insert_special(request_queue_t *q, struct request *rq,
* must not attempt merges on this) and that it acts as a soft
* must not attempt merges on this) and that it acts as a soft
* barrier
* barrier
*/
*/
rq
->
flags
=
REQ_SPECIAL
|
REQ_BARRIER
;
rq
->
flags
&=
REQ_QUEUED
;
rq
->
flags
|=
REQ_SPECIAL
|
REQ_BARRIER
;
rq
->
special
=
data
;
rq
->
special
=
data
;
...
@@ -87,6 +88,9 @@ static void __scsi_insert_special(request_queue_t *q, struct request *rq,
...
@@ -87,6 +88,9 @@ static void __scsi_insert_special(request_queue_t *q, struct request *rq,
* device, or a host that is unable to accept a particular command.
* device, or a host that is unable to accept a particular command.
*/
*/
spin_lock_irqsave
(
q
->
queue_lock
,
flags
);
spin_lock_irqsave
(
q
->
queue_lock
,
flags
);
/* If command is tagged, release the tag */
if
(
blk_rq_tagged
(
rq
))
blk_queue_end_tag
(
q
,
rq
);
_elv_add_request
(
q
,
rq
,
!
at_head
,
0
);
_elv_add_request
(
q
,
rq
,
!
at_head
,
0
);
q
->
request_fn
(
q
);
q
->
request_fn
(
q
);
spin_unlock_irqrestore
(
q
->
queue_lock
,
flags
);
spin_unlock_irqrestore
(
q
->
queue_lock
,
flags
);
...
@@ -927,11 +931,13 @@ void scsi_request_fn(request_queue_t * q)
...
@@ -927,11 +931,13 @@ void scsi_request_fn(request_queue_t * q)
* reason to search the list, because all of the commands
* reason to search the list, because all of the commands
* in this queue are for the same device.
* in this queue are for the same device.
*/
*/
if
(
blk_queue_tagged
(
q
))
if
(
!
(
blk_queue_tagged
(
q
)
&&
(
blk_queue_start_tag
(
q
,
req
)
==
0
)))
blk_queue_start_tag
(
q
,
req
);
else
blkdev_dequeue_request
(
req
);
blkdev_dequeue_request
(
req
);
/* note the overloading of req->special. When the tag
* is active it always means SCpnt. If the tag goes
* back for re-queueing, it may be reset */
req
->
special
=
SCpnt
;
SCpnt
->
request
=
req
;
SCpnt
->
request
=
req
;
/*
/*
...
...
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