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
5463a13c
Commit
5463a13c
authored
Jul 02, 2002
by
James Bottomley
Browse files
Options
Browse Files
Download
Plain Diff
Merge
parents
a8c759e0
c9761c4d
Changes
32
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
32 changed files
with
1167 additions
and
349 deletions
+1167
-349
drivers/cdrom/cdrom.c
drivers/cdrom/cdrom.c
+5
-0
drivers/scsi/53c700.c
drivers/scsi/53c700.c
+65
-177
drivers/scsi/53c700.h
drivers/scsi/53c700.h
+2
-3
drivers/scsi/aha1542.c
drivers/scsi/aha1542.c
+2
-2
drivers/scsi/constants.c
drivers/scsi/constants.c
+2
-2
drivers/scsi/eata.c
drivers/scsi/eata.c
+8
-8
drivers/scsi/hosts.c
drivers/scsi/hosts.c
+1
-0
drivers/scsi/hosts.h
drivers/scsi/hosts.h
+34
-0
drivers/scsi/ide-scsi.c
drivers/scsi/ide-scsi.c
+1
-1
drivers/scsi/osst.c
drivers/scsi/osst.c
+10
-10
drivers/scsi/qla1280.c
drivers/scsi/qla1280.c
+2
-2
drivers/scsi/scsi.c
drivers/scsi/scsi.c
+78
-28
drivers/scsi/scsi.h
drivers/scsi/scsi.h
+90
-3
drivers/scsi/scsi_debug.c
drivers/scsi/scsi_debug.c
+1
-1
drivers/scsi/scsi_error.c
drivers/scsi/scsi_error.c
+4
-4
drivers/scsi/scsi_lib.c
drivers/scsi/scsi_lib.c
+44
-36
drivers/scsi/scsi_merge.c
drivers/scsi/scsi_merge.c
+1
-1
drivers/scsi/scsi_scan.c
drivers/scsi/scsi_scan.c
+413
-0
drivers/scsi/scsi_syms.c
drivers/scsi/scsi_syms.c
+5
-0
drivers/scsi/sd.c
drivers/scsi/sd.c
+38
-22
drivers/scsi/sg.c
drivers/scsi/sg.c
+51
-3
drivers/scsi/sr.c
drivers/scsi/sr.c
+67
-19
drivers/scsi/sr_ioctl.c
drivers/scsi/sr_ioctl.c
+2
-2
drivers/scsi/st.c
drivers/scsi/st.c
+81
-12
drivers/scsi/st.h
drivers/scsi/st.h
+2
-0
drivers/scsi/sun3_NCR5380.c
drivers/scsi/sun3_NCR5380.c
+4
-4
drivers/scsi/sun3_scsi.c
drivers/scsi/sun3_scsi.c
+1
-1
drivers/scsi/u14-34f.c
drivers/scsi/u14-34f.c
+8
-8
fs/partitions/check.c
fs/partitions/check.c
+138
-0
include/linux/cdrom.h
include/linux/cdrom.h
+2
-0
include/linux/genhd.h
include/linux/genhd.h
+4
-0
kernel/ksyms.c
kernel/ksyms.c
+1
-0
No files found.
drivers/cdrom/cdrom.c
View file @
5463a13c
...
...
@@ -431,6 +431,11 @@ int unregister_cdrom(struct cdrom_device_info *unreg)
topCdromPtr
=
cdi
->
next
;
cdi
->
ops
->
n_minors
--
;
devfs_unregister
(
cdi
->
de
);
if
(
atomic_read
(
&
cdi
->
cdrom_driverfs_dev
.
refcount
))
{
device_remove_file
(
&
cdi
->
cdrom_driverfs_dev
,
"name"
);
device_remove_file
(
&
cdi
->
cdrom_driverfs_dev
,
"kdev"
);
put_device
(
&
cdi
->
cdrom_driverfs_dev
);
}
devfs_dealloc_unique_number
(
&
cdrom_numspace
,
cdi
->
number
);
cdinfo
(
CD_REG_UNREG
,
"drive
\"
/dev/%s
\"
unregistered
\n
"
,
cdi
->
name
);
return
0
;
...
...
drivers/scsi/53c700.c
View file @
5463a13c
This diff is collapsed.
Click to expand it.
drivers/scsi/53c700.h
View file @
5463a13c
...
...
@@ -9,7 +9,7 @@
#define _53C700_H
/* Turn on for general debugging---too verbose for normal use */
#undef
NCR_700_DEBUG
#undef
NCR_700_DEBUG
/* Debug the tag queues, checking hash queue allocation and deallocation
* and search for duplicate tags */
#undef NCR_700_TAG_DEBUG
...
...
@@ -189,8 +189,7 @@ struct NCR_700_command_slot {
#define NCR_700_SLOT_BUSY (1|NCR_700_SLOT_MAGIC)
/* slot has command active on HA */
#define NCR_700_SLOT_QUEUED (2|NCR_700_SLOT_MAGIC)
/* slot has command to be made active on HA */
__u8
state
;
#define NCR_700_NO_TAG 0xdead
__u16
tag
;
int
tag
;
__u32
resume_offset
;
Scsi_Cmnd
*
cmnd
;
/* The pci_mapped address of the actual command in cmnd */
...
...
drivers/scsi/aha1542.c
View file @
5463a13c
...
...
@@ -1635,14 +1635,14 @@ static int aha1542_old_abort(Scsi_Cmnd * SCpnt)
if (HOSTDATA(SCpnt->host)->SCint[i]) {
if (HOSTDATA(SCpnt->host)->SCint[i] == SCpnt) {
printk(KERN_ERR "Timed out command pending for %s\n",
kdevname(SCpnt->request
.
rq_dev));
kdevname(SCpnt->request
->
rq_dev));
if (HOSTDATA(SCpnt->host)->mb[i].status) {
printk(KERN_ERR "OGMB still full - restarting\n");
aha1542_out(SCpnt->host->io_port, &ahacmd, 1);
};
} else
printk(KERN_ERR "Other pending command %s\n",
kdevname(SCpnt->request
.
rq_dev));
kdevname(SCpnt->request
->
rq_dev));
}
#endif
...
...
drivers/scsi/constants.c
View file @
5463a13c
...
...
@@ -1006,13 +1006,13 @@ print_sense_internal(const char * devclass,
void
print_sense
(
const
char
*
devclass
,
Scsi_Cmnd
*
SCpnt
)
{
print_sense_internal
(
devclass
,
SCpnt
->
sense_buffer
,
SCpnt
->
request
.
rq_dev
);
SCpnt
->
request
->
rq_dev
);
}
void
print_req_sense
(
const
char
*
devclass
,
Scsi_Request
*
SRpnt
)
{
print_sense_internal
(
devclass
,
SRpnt
->
sr_sense_buffer
,
SRpnt
->
sr_request
.
rq_dev
);
SRpnt
->
sr_request
->
rq_dev
);
}
#if (CONSTANTS & CONST_MSG)
...
...
drivers/scsi/eata.c
View file @
5463a13c
...
...
@@ -1563,7 +1563,7 @@ static inline int do_qcomm(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
if
(
linked_comm
&&
SCpnt
->
device
->
queue_depth
>
2
&&
TLDEV
(
SCpnt
->
device
->
type
))
{
HD
(
j
)
->
cp_stat
[
i
]
=
READY
;
flush_dev
(
SCpnt
->
device
,
SCpnt
->
request
.
sector
,
j
,
FALSE
);
flush_dev
(
SCpnt
->
device
,
SCpnt
->
request
->
sector
,
j
,
FALSE
);
return
0
;
}
...
...
@@ -1875,11 +1875,11 @@ static inline int reorder(unsigned int j, unsigned long cursec,
if
(
!
cpp
->
din
)
input_only
=
FALSE
;
if
(
SCpnt
->
request
.
sector
<
minsec
)
minsec
=
SCpnt
->
request
.
sector
;
if
(
SCpnt
->
request
.
sector
>
maxsec
)
maxsec
=
SCpnt
->
request
.
sector
;
if
(
SCpnt
->
request
->
sector
<
minsec
)
minsec
=
SCpnt
->
request
->
sector
;
if
(
SCpnt
->
request
->
sector
>
maxsec
)
maxsec
=
SCpnt
->
request
->
sector
;
sl
[
n
]
=
SCpnt
->
request
.
sector
;
ioseek
+=
SCpnt
->
request
.
nr_sectors
;
sl
[
n
]
=
SCpnt
->
request
->
sector
;
ioseek
+=
SCpnt
->
request
->
nr_sectors
;
if
(
!
n
)
continue
;
...
...
@@ -1907,7 +1907,7 @@ static inline int reorder(unsigned int j, unsigned long cursec,
if
(
!
input_only
)
for
(
n
=
0
;
n
<
n_ready
;
n
++
)
{
k
=
il
[
n
];
cpp
=
&
HD
(
j
)
->
cp
[
k
];
SCpnt
=
cpp
->
SCpnt
;
ll
[
n
]
=
SCpnt
->
request
.
nr_sectors
;
pl
[
n
]
=
SCpnt
->
pid
;
ll
[
n
]
=
SCpnt
->
request
->
nr_sectors
;
pl
[
n
]
=
SCpnt
->
pid
;
if
(
!
n
)
continue
;
...
...
@@ -1935,7 +1935,7 @@ static inline int reorder(unsigned int j, unsigned long cursec,
" cur %ld s:%c r:%c rev:%c in:%c ov:%c xd %d.
\n
"
,
(
ihdlr
?
"ihdlr"
:
"qcomm"
),
SCpnt
->
channel
,
SCpnt
->
target
,
SCpnt
->
lun
,
SCpnt
->
pid
,
k
,
flushcount
,
n_ready
,
SCpnt
->
request
.
sector
,
SCpnt
->
request
.
nr_sectors
,
cursec
,
SCpnt
->
request
->
sector
,
SCpnt
->
request
->
nr_sectors
,
cursec
,
YESNO
(
s
),
YESNO
(
r
),
YESNO
(
rev
),
YESNO
(
input_only
),
YESNO
(
overlap
),
cpp
->
din
);
}
...
...
@@ -2073,7 +2073,7 @@ static inline void ihdlr(int irq, unsigned int j) {
if
(
linked_comm
&&
SCpnt
->
device
->
queue_depth
>
2
&&
TLDEV
(
SCpnt
->
device
->
type
))
flush_dev
(
SCpnt
->
device
,
SCpnt
->
request
.
sector
,
j
,
TRUE
);
flush_dev
(
SCpnt
->
device
,
SCpnt
->
request
->
sector
,
j
,
TRUE
);
tstatus
=
status_byte
(
spp
->
target_status
);
...
...
drivers/scsi/hosts.c
View file @
5463a13c
...
...
@@ -230,6 +230,7 @@ struct Scsi_Host * scsi_register(Scsi_Host_Template * tpnt, int j)
retval
->
select_queue_depths
=
tpnt
->
select_queue_depths
;
retval
->
max_sectors
=
tpnt
->
max_sectors
;
retval
->
use_blk_tcq
=
tpnt
->
use_blk_tcq
;
if
(
!
scsi_hostlist
)
scsi_hostlist
=
retval
;
...
...
drivers/scsi/hosts.h
View file @
5463a13c
...
...
@@ -286,6 +286,12 @@ typedef struct SHT
unsigned
highmem_io
:
1
;
/*
* True if the driver wishes to use the generic block layer
* tag queueing functions
*/
unsigned
use_blk_tcq
:
1
;
/*
* Name of proc directory
*/
...
...
@@ -386,6 +392,7 @@ struct Scsi_Host
unsigned
unchecked_isa_dma
:
1
;
unsigned
use_clustering
:
1
;
unsigned
highmem_io
:
1
;
unsigned
use_blk_tcq
:
1
;
/*
* Host has rejected a command because it was busy.
...
...
@@ -418,6 +425,11 @@ struct Scsi_Host
*/
struct
pci_dev
*
pci_dev
;
/*
* Support for driverfs filesystem
*/
struct
device
host_driverfs_dev
;
/*
* We should ensure that this is aligned, both for better performance
* and also because some compilers (m68k) don't automatically force
...
...
@@ -478,6 +490,7 @@ static inline void scsi_set_pci_device(struct Scsi_Host *SHpnt,
struct
pci_dev
*
pdev
)
{
SHpnt
->
pci_dev
=
pdev
;
SHpnt
->
host_driverfs_dev
.
parent
=&
pdev
->
dev
;
}
...
...
@@ -516,6 +529,7 @@ struct Scsi_Device_Template
void
(
*
detach
)(
Scsi_Device
*
);
int
(
*
init_command
)(
Scsi_Cmnd
*
);
/* Used by new queueing code.
Selects command for blkdevs */
struct
device_driver
scsi_driverfs_driver
;
};
void
scsi_initialize_queue
(
Scsi_Device
*
SDpnt
,
struct
Scsi_Host
*
SHpnt
);
...
...
@@ -555,6 +569,26 @@ extern int scsi_unregister_host(Scsi_Host_Template *);
#define SD_EXTRA_DEVS CONFIG_SD_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
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
...
...
drivers/scsi/ide-scsi.c
View file @
5463a13c
...
...
@@ -668,7 +668,7 @@ static inline int should_transform(struct ata_device *drive, Scsi_Cmnd *cmd)
struct
Scsi_Host
*
host
=
drive
->
driver_data
;
idescsi_scsi_t
*
scsi
=
idescsi_private
(
host
);
if
(
major
(
cmd
->
request
.
rq_dev
)
==
SCSI_GENERIC_MAJOR
)
if
(
major
(
cmd
->
request
->
rq_dev
)
==
SCSI_GENERIC_MAJOR
)
return
test_bit
(
IDESCSI_SG_TRANSFORM
,
&
scsi
->
transform
);
return
test_bit
(
IDESCSI_TRANSFORM
,
&
scsi
->
transform
);
}
...
...
drivers/scsi/osst.c
View file @
5463a13c
...
...
@@ -270,7 +270,7 @@ static int osst_chk_result(OS_Scsi_Tape * STp, Scsi_Request * SRpnt)
/* Wakeup from interrupt */
static
void
osst_sleep_done
(
Scsi_Cmnd
*
SCpnt
)
{
unsigned
int
dev
=
TAPE_NR
(
SCpnt
->
request
.
rq_dev
);
unsigned
int
dev
=
TAPE_NR
(
SCpnt
->
request
->
rq_dev
);
OS_Scsi_Tape
*
STp
;
if
(
os_scsi_tapes
&&
(
STp
=
os_scsi_tapes
[
dev
]))
{
...
...
@@ -285,13 +285,13 @@ static void osst_sleep_done (Scsi_Cmnd * SCpnt)
}
else
(
STp
->
buffer
)
->
midlevel_result
=
SCpnt
->
result
;
SCpnt
->
request
.
rq_status
=
RQ_SCSI_DONE
;
SCpnt
->
request
->
rq_status
=
RQ_SCSI_DONE
;
(
STp
->
buffer
)
->
last_SRpnt
=
SCpnt
->
sc_request
;
#if DEBUG
STp
->
write_pending
=
0
;
#endif
complete
(
SCpnt
->
request
.
waiting
);
complete
(
SCpnt
->
request
->
waiting
);
}
#if DEBUG
else
if
(
debugging
)
...
...
@@ -313,7 +313,7 @@ static Scsi_Request * osst_do_scsi(Scsi_Request *SRpnt, OS_Scsi_Tape *STp,
#endif
if
(
SRpnt
==
NULL
)
{
if
((
SRpnt
=
scsi_allocate_request
(
STp
->
device
))
==
NULL
)
{
printk
(
KERN_ERR
"osst%d:E: Can't get SCSI request
.
\n
"
,
TAPE_NR
(
STp
->
devt
));
printk
(
KERN_ERR
"osst%d:E: Can't get SCSI request
->
\n
"
,
TAPE_NR
(
STp
->
devt
));
if
(
signal_pending
(
current
))
(
STp
->
buffer
)
->
syscall_result
=
(
-
EINTR
);
else
...
...
@@ -336,15 +336,15 @@ static Scsi_Request * osst_do_scsi(Scsi_Request *SRpnt, OS_Scsi_Tape *STp,
bp
=
(
STp
->
buffer
)
->
b_data
;
SRpnt
->
sr_data_direction
=
direction
;
SRpnt
->
sr_cmd_len
=
0
;
SRpnt
->
sr_request
.
waiting
=
&
(
STp
->
wait
);
SRpnt
->
sr_request
.
rq_status
=
RQ_SCSI_BUSY
;
SRpnt
->
sr_request
.
rq_dev
=
STp
->
devt
;
SRpnt
->
sr_request
->
waiting
=
&
(
STp
->
wait
);
SRpnt
->
sr_request
->
rq_status
=
RQ_SCSI_BUSY
;
SRpnt
->
sr_request
->
rq_dev
=
STp
->
devt
;
scsi_do_req
(
SRpnt
,
(
void
*
)
cmd
,
bp
,
bytes
,
osst_sleep_done
,
timeout
,
retries
);
if
(
do_wait
)
{
wait_for_completion
(
SRpnt
->
sr_request
.
waiting
);
SRpnt
->
sr_request
.
waiting
=
NULL
;
wait_for_completion
(
SRpnt
->
sr_request
->
waiting
);
SRpnt
->
sr_request
->
waiting
=
NULL
;
STp
->
buffer
->
syscall_result
=
osst_chk_result
(
STp
,
SRpnt
);
#ifdef OSST_INJECT_ERRORS
if
(
STp
->
buffer
->
syscall_result
==
0
&&
...
...
@@ -377,7 +377,7 @@ static void osst_write_behind_check(OS_Scsi_Tape *STp)
STp
->
nbr_finished
++
;
#endif
wait_for_completion
(
&
(
STp
->
wait
));
(
STp
->
buffer
)
->
last_SRpnt
->
sr_request
.
waiting
=
NULL
;
(
STp
->
buffer
)
->
last_SRpnt
->
sr_request
->
waiting
=
NULL
;
STp
->
buffer
->
syscall_result
=
osst_chk_result
(
STp
,
STp
->
buffer
->
last_SRpnt
);
...
...
drivers/scsi/qla1280.c
View file @
5463a13c
...
...
@@ -4236,7 +4236,7 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, srb_t * sp)
/* Set transfer direction (READ and WRITE) */
/* Linux doesn't tell us */
/*
* For block devices, cmd->request
.
cmd has the operation
* For block devices, cmd->request
->
cmd has the operation
* For character devices, this isn't always set properly, so
* we need to check data_cmnd[0]. This catches the conditions
* for st.c, but not sg. Generic commands are pass down to us.
...
...
@@ -6241,7 +6241,7 @@ qla1280_print_scsi_cmd(Scsi_Cmnd * cmd)
cmd
->
tag
,
cmd
->
flags
,
cmd
->
transfersize
);
printk
(
" Pid=%li, SP=0x%p
\n
"
,
cmd
->
pid
,
CMD_SP
(
cmd
));
printk
(
" underflow size = 0x%x, direction=0x%x, req.cmd=0x%x
\n
"
,
cmd
->
underflow
,
sp
->
dir
,
cmd
->
request
.
cmd
);
cmd
->
underflow
,
sp
->
dir
,
cmd
->
request
->
cmd
);
}
/**************************************************************************
...
...
drivers/scsi/scsi.c
View file @
5463a13c
...
...
@@ -258,11 +258,20 @@ __setup("scsi_logging=", scsi_logging_setup);
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 */
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
)
complete
(
req
->
waiting
);
}
...
...
@@ -295,17 +304,19 @@ static spinlock_t device_request_lock = SPIN_LOCK_UNLOCKED;
Scsi_Request
*
scsi_allocate_request
(
Scsi_Device
*
device
)
{
Scsi_Request
*
SRpnt
=
NULL
;
const
int
offset
=
ALIGN
(
sizeof
(
Scsi_Request
),
4
);
const
int
size
=
offset
+
sizeof
(
struct
request
);
if
(
!
device
)
panic
(
"No device passed to scsi_allocate_request().
\n
"
);
SRpnt
=
(
Scsi_Request
*
)
kmalloc
(
sizeof
(
Scsi_Request
)
,
GFP_ATOMIC
);
SRpnt
=
(
Scsi_Request
*
)
kmalloc
(
size
,
GFP_ATOMIC
);
if
(
SRpnt
==
NULL
)
{
return
NULL
;
}
memset
(
SRpnt
,
0
,
sizeof
(
Scsi_Request
)
);
memset
(
SRpnt
,
0
,
size
);
SRpnt
->
sr_request
=
(
struct
request
*
)(((
char
*
)
SRpnt
)
+
offset
);
SRpnt
->
sr_device
=
device
;
SRpnt
->
sr_host
=
device
->
host
;
SRpnt
->
sr_magic
=
SCSI_REQ_MAGIC
;
...
...
@@ -433,7 +444,7 @@ Scsi_Cmnd *scsi_allocate_device(Scsi_Device * device, int wait,
* Now we can check for a free command block for this device.
*/
for
(
SCpnt
=
device
->
device_queue
;
SCpnt
;
SCpnt
=
SCpnt
->
next
)
{
if
(
SCpnt
->
request
.
rq_status
==
RQ_INACTIVE
)
if
(
SCpnt
->
request
==
NULL
)
break
;
}
}
...
...
@@ -502,9 +513,7 @@ Scsi_Cmnd *scsi_allocate_device(Scsi_Device * device, int wait,
}
}
SCpnt
->
request
.
rq_status
=
RQ_SCSI_BUSY
;
SCpnt
->
request
.
waiting
=
NULL
;
/* And no one is waiting for this
* to complete */
SCpnt
->
request
=
NULL
;
atomic_inc
(
&
SCpnt
->
host
->
host_active
);
atomic_inc
(
&
SCpnt
->
device
->
device_active
);
...
...
@@ -547,7 +556,7 @@ inline void __scsi_release_command(Scsi_Cmnd * SCpnt)
SDpnt
=
SCpnt
->
device
;
SCpnt
->
request
.
rq_status
=
RQ_INACTIVE
;
SCpnt
->
request
=
NULL
;
SCpnt
->
state
=
SCSI_STATE_UNUSED
;
SCpnt
->
owner
=
SCSI_OWNER_NOBODY
;
atomic_dec
(
&
SCpnt
->
host
->
host_active
);
...
...
@@ -770,13 +779,13 @@ void scsi_wait_req (Scsi_Request * SRpnt, const void *cmnd ,
DECLARE_COMPLETION
(
wait
);
request_queue_t
*
q
=
&
SRpnt
->
sr_device
->
request_queue
;
SRpnt
->
sr_request
.
waiting
=
&
wait
;
SRpnt
->
sr_request
.
rq_status
=
RQ_SCSI_BUSY
;
SRpnt
->
sr_request
->
waiting
=
&
wait
;
SRpnt
->
sr_request
->
rq_status
=
RQ_SCSI_BUSY
;
scsi_do_req
(
SRpnt
,
(
void
*
)
cmnd
,
buffer
,
bufflen
,
scsi_wait_done
,
timeout
,
retries
);
generic_unplug_device
(
q
);
wait_for_completion
(
&
wait
);
SRpnt
->
sr_request
.
waiting
=
NULL
;
SRpnt
->
sr_request
->
waiting
=
NULL
;
if
(
SRpnt
->
sr_command
!=
NULL
)
{
scsi_release_command
(
SRpnt
->
sr_command
);
...
...
@@ -927,8 +936,7 @@ void scsi_init_cmd_from_req(Scsi_Cmnd * SCpnt, Scsi_Request * SRpnt)
SCpnt
->
cmd_len
=
SRpnt
->
sr_cmd_len
;
SCpnt
->
use_sg
=
SRpnt
->
sr_use_sg
;
memcpy
((
void
*
)
&
SCpnt
->
request
,
(
const
void
*
)
&
SRpnt
->
sr_request
,
sizeof
(
SRpnt
->
sr_request
));
SCpnt
->
request
=
SRpnt
->
sr_request
;
memcpy
((
void
*
)
SCpnt
->
data_cmnd
,
(
const
void
*
)
SRpnt
->
sr_cmnd
,
sizeof
(
SCpnt
->
data_cmnd
));
SCpnt
->
reset_chain
=
NULL
;
...
...
@@ -1458,7 +1466,7 @@ void scsi_build_commandblocks(Scsi_Device * SDpnt)
SCpnt
->
target
=
SDpnt
->
id
;
SCpnt
->
lun
=
SDpnt
->
lun
;
SCpnt
->
channel
=
SDpnt
->
channel
;
SCpnt
->
request
.
rq_status
=
RQ_INACTIVE
;
SCpnt
->
request
=
NULL
;
SCpnt
->
use_sg
=
0
;
SCpnt
->
old_use_sg
=
0
;
SCpnt
->
old_cmd_len
=
0
;
...
...
@@ -1910,6 +1918,11 @@ int scsi_register_host(Scsi_Host_Template * tpnt)
}
printk
(
KERN_INFO
"scsi%d : %s
\n
"
,
/* And print a little message */
shpnt
->
host_no
,
name
);
strncpy
(
shpnt
->
host_driverfs_dev
.
name
,
name
,
DEVICE_NAME_SIZE
-
1
);
sprintf
(
shpnt
->
host_driverfs_dev
.
bus_id
,
"scsi%d"
,
shpnt
->
host_no
);
}
}
...
...
@@ -1918,6 +1931,8 @@ int scsi_register_host(Scsi_Host_Template * tpnt)
*/
for
(
shpnt
=
scsi_hostlist
;
shpnt
;
shpnt
=
shpnt
->
next
)
{
if
(
shpnt
->
hostt
==
tpnt
)
{
/* first register parent with driverfs */
device_register
(
&
shpnt
->
host_driverfs_dev
);
scan_scsis
(
shpnt
,
0
,
0
,
0
,
0
);
if
(
shpnt
->
select_queue_depths
!=
NULL
)
{
(
shpnt
->
select_queue_depths
)
(
shpnt
,
shpnt
->
host_queue
);
...
...
@@ -2030,16 +2045,16 @@ int scsi_unregister_host(Scsi_Host_Template * tpnt)
SCpnt
=
SCpnt
->
next
)
{
online_status
=
SDpnt
->
online
;
SDpnt
->
online
=
FALSE
;
if
(
SCpnt
->
request
.
rq_status
!=
RQ_INACTIVE
)
{
if
(
SCpnt
->
request
&&
SCpnt
->
request
->
rq_status
!=
RQ_INACTIVE
)
{
printk
(
KERN_ERR
"SCSI device not inactive - rq_status=%d, target=%d, pid=%ld, state=%d, owner=%d.
\n
"
,
SCpnt
->
request
.
rq_status
,
SCpnt
->
target
,
SCpnt
->
pid
,
SCpnt
->
request
->
rq_status
,
SCpnt
->
target
,
SCpnt
->
pid
,
SCpnt
->
state
,
SCpnt
->
owner
);
for
(
SDpnt1
=
shpnt
->
host_queue
;
SDpnt1
;
SDpnt1
=
SDpnt1
->
next
)
{
for
(
SCpnt
=
SDpnt1
->
device_queue
;
SCpnt
;
SCpnt
=
SCpnt
->
next
)
if
(
SCpnt
->
request
.
rq_status
==
RQ_SCSI_DISCONNECTING
)
SCpnt
->
request
.
rq_status
=
RQ_INACTIVE
;
if
(
SCpnt
->
request
->
rq_status
==
RQ_SCSI_DISCONNECTING
)
SCpnt
->
request
->
rq_status
=
RQ_INACTIVE
;
}
SDpnt
->
online
=
online_status
;
printk
(
KERN_ERR
"Device busy???
\n
"
);
...
...
@@ -2050,7 +2065,8 @@ int scsi_unregister_host(Scsi_Host_Template * tpnt)
* continue on.
*/
SCpnt
->
state
=
SCSI_STATE_DISCONNECTING
;
SCpnt
->
request
.
rq_status
=
RQ_SCSI_DISCONNECTING
;
/* Mark as busy */
if
(
SCpnt
->
request
)
SCpnt
->
request
->
rq_status
=
RQ_SCSI_DISCONNECTING
;
/* Mark as busy */
}
}
}
...
...
@@ -2072,6 +2088,7 @@ int scsi_unregister_host(Scsi_Host_Template * tpnt)
goto
err_out
;
}
devfs_unregister
(
SDpnt
->
de
);
put_device
(
&
SDpnt
->
sdev_driverfs_dev
);
}
}
...
...
@@ -2122,6 +2139,7 @@ int scsi_unregister_host(Scsi_Host_Template * tpnt)
/* Remove the /proc/scsi directory entry */
sprintf
(
name
,
"%d"
,
shpnt
->
host_no
);
remove_proc_entry
(
name
,
tpnt
->
proc_dir
);
put_device
(
&
shpnt
->
host_driverfs_dev
);
if
(
tpnt
->
release
)
(
*
tpnt
->
release
)
(
shpnt
);
else
{
...
...
@@ -2360,11 +2378,11 @@ static void scsi_dump_status(int level)
SCpnt
->
target
,
SCpnt
->
lun
,
kdevname
(
SCpnt
->
request
.
rq_dev
),
SCpnt
->
request
.
sector
,
SCpnt
->
request
.
nr_sectors
,
(
long
)
SCpnt
->
request
.
current_nr_sectors
,
SCpnt
->
request
.
rq_status
,
kdevname
(
SCpnt
->
request
->
rq_dev
),
SCpnt
->
request
->
sector
,
SCpnt
->
request
->
nr_sectors
,
(
long
)
SCpnt
->
request
->
current_nr_sectors
,
SCpnt
->
request
->
rq_status
,
SCpnt
->
use_sg
,
SCpnt
->
retries
,
...
...
@@ -2470,6 +2488,34 @@ void scsi_free_sgtable(struct scatterlist *sgl, int index)
mempool_free
(
sgl
,
sgp
->
pool
);
}
static
int
scsi_bus_match
(
struct
device
*
scsi_driverfs_dev
,
struct
device_driver
*
scsi_driverfs_drv
)
{
char
*
p
=
0
;
if
(
!
strcmp
(
"sd"
,
scsi_driverfs_drv
->
name
))
{
if
((
p
=
strstr
(
scsi_driverfs_dev
->
bus_id
,
":disc"
))
||
(
p
=
strstr
(
scsi_driverfs_dev
->
bus_id
,
":p"
)))
{
return
1
;
}
}
else
if
(
!
strcmp
(
"sg"
,
scsi_driverfs_drv
->
name
))
{
if
(
strstr
(
scsi_driverfs_dev
->
bus_id
,
":gen"
))
return
1
;
}
else
if
(
!
strcmp
(
"sr"
,
scsi_driverfs_drv
->
name
))
{
if
(
strstr
(
scsi_driverfs_dev
->
bus_id
,
":cd"
))
return
1
;
}
else
if
(
!
strcmp
(
"st"
,
scsi_driverfs_drv
->
name
))
{
if
(
strstr
(
scsi_driverfs_dev
->
bus_id
,
":mt"
))
return
1
;
}
return
0
;
}
struct
bus_type
scsi_driverfs_bus_type
=
{
name:
"scsi"
,
match:
scsi_bus_match
,
};
static
int
__init
init_scsi
(
void
)
{
struct
proc_dir_entry
*
generic
;
...
...
@@ -2516,6 +2562,8 @@ static int __init init_scsi(void)
printk
(
KERN_INFO
"scsi: host order: %s
\n
"
,
scsihosts
);
scsi_host_no_init
(
scsihosts
);
bus_register
(
&
scsi_driverfs_bus_type
);
/* Where we handle work queued by scsi_done */
open_softirq
(
SCSI_SOFTIRQ
,
scsi_softirq
,
NULL
);
...
...
@@ -2677,16 +2725,18 @@ int
scsi_reset_provider
(
Scsi_Device
*
dev
,
int
flag
)
{
Scsi_Cmnd
SC
,
*
SCpnt
=
&
SC
;
struct
request
req
;
int
rtn
;
SCpnt
->
request
=
&
req
;
memset
(
&
SCpnt
->
eh_timeout
,
0
,
sizeof
(
SCpnt
->
eh_timeout
));
SCpnt
->
host
=
dev
->
host
;
SCpnt
->
device
=
dev
;
SCpnt
->
target
=
dev
->
id
;
SCpnt
->
lun
=
dev
->
lun
;
SCpnt
->
channel
=
dev
->
channel
;
SCpnt
->
request
.
rq_status
=
RQ_SCSI_BUSY
;
SCpnt
->
request
.
waiting
=
NULL
;
SCpnt
->
request
->
rq_status
=
RQ_SCSI_BUSY
;
SCpnt
->
request
->
waiting
=
NULL
;
SCpnt
->
use_sg
=
0
;
SCpnt
->
old_use_sg
=
0
;
SCpnt
->
old_cmd_len
=
0
;
...
...
drivers/scsi/scsi.h
View file @
5463a13c
...
...
@@ -417,6 +417,8 @@ extern unsigned int scsi_need_isa_buffer; /* True if some devices need indirecti
extern
volatile
int
in_scan_scsis
;
extern
const
unsigned
char
scsi_command_size
[
8
];
extern
struct
bus_type
scsi_driverfs_bus_type
;
/*
* These are the error handling functions defined in scsi_error.c
...
...
@@ -566,6 +568,7 @@ struct scsi_device {
atomic_t
device_active
;
/* commands checked out for device */
volatile
unsigned
short
device_busy
;
/* commands actually active on low-level */
Scsi_Cmnd
*
device_queue
;
/* queue of SCSI Command structures */
Scsi_Cmnd
*
current_cmnd
;
/* currently active command */
unsigned
int
id
,
lun
,
channel
;
...
...
@@ -622,6 +625,7 @@ struct scsi_device {
// Flag to allow revalidate to succeed in sd_open
int
allow_revalidate
;
struct
device
sdev_driverfs_dev
;
};
...
...
@@ -662,7 +666,7 @@ struct scsi_request {
struct
Scsi_Host
*
sr_host
;
Scsi_Device
*
sr_device
;
Scsi_Cmnd
*
sr_command
;
struct
request
sr_request
;
/* A copy of the command we are
struct
request
*
sr_request
;
/* A copy of the command we are
working on */
unsigned
sr_bufflen
;
/* Size of data buffer */
void
*
sr_buffer
;
/* Data buffer */
...
...
@@ -773,8 +777,8 @@ struct scsi_cmnd {
transferred less actual number
transferred (0 if not supported) */
struct
request
request
;
/* A copy of t
he command we are
working on */
struct
request
*
request
;
/* T
he command we are
working on */
unsigned
char
sense_buffer
[
SCSI_SENSE_BUFFERSIZE
];
/* obtained by REQUEST SENSE
* when CHECK CONDITION is
...
...
@@ -856,4 +860,87 @@ struct scsi_cmnd {
extern
int
scsi_reset_provider
(
Scsi_Device
*
,
int
);
/**
* scsi_activate_tcq - turn on tag command queueing
* @SDpnt: device to turn on TCQ for
* @depth: queue depth
*
* Notes:
* Eventually, I hope depth would be the maximum depth
* the device could cope with and the real queue depth
* would be adjustable from 0 to depth.
**/
static
inline
void
scsi_activate_tcq
(
Scsi_Device
*
SDpnt
,
int
depth
)
{
request_queue_t
*
q
=
&
SDpnt
->
request_queue
;
if
(
SDpnt
->
tagged_supported
&&
!
blk_queue_tagged
(
q
))
{
blk_queue_init_tags
(
q
,
depth
);
SDpnt
->
tagged_queue
=
1
;
}
}
/**
* scsi_deactivate_tcq - turn off tag command queueing
* @SDpnt: device to turn off TCQ for
**/
static
inline
void
scsi_deactivate_tcq
(
Scsi_Device
*
SDpnt
)
{
blk_queue_free_tags
(
&
SDpnt
->
request_queue
);
SDpnt
->
tagged_queue
=
0
;
}
#define MSG_SIMPLE_TAG 0x20
#define MSG_HEAD_TAG 0x21
#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
* @SCpnt: pointer to the Scsi_Cmnd for the tag
* @msg: pointer to the area to place the tag
*
* Notes:
* designed to create the correct type of tag message for the
* particular request. Returns the size of the tag message.
* May return 0 if TCQ is disabled for this device.
**/
static
inline
int
scsi_populate_tag_msg
(
Scsi_Cmnd
*
SCpnt
,
char
*
msg
)
{
struct
request
*
req
=
SCpnt
->
request
;
if
(
!
blk_rq_tagged
(
req
))
return
0
;
if
(
req
->
flags
&
REQ_BARRIER
)
*
msg
++
=
MSG_ORDERED_TAG
;
else
*
msg
++
=
MSG_SIMPLE_TAG
;
*
msg
++
=
SCpnt
->
request
->
tag
;
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
drivers/scsi/scsi_debug.c
View file @
5463a13c
...
...
@@ -694,7 +694,7 @@ static int scsi_debug_read(Scsi_Cmnd * SCpnt, int upper_blk, int block,
{
int
delay
=
SCSI_SETUP_LATENCY
;
delay
+=
SCpnt
->
request
.
nr_sectors
*
SCSI_DATARATE
;
delay
+=
SCpnt
->
request
->
nr_sectors
*
SCSI_DATARATE
;
if
(
delay
)
usleep
(
delay
);
}
...
...
drivers/scsi/scsi_error.c
View file @
5463a13c
...
...
@@ -319,7 +319,7 @@ void scsi_eh_done(Scsi_Cmnd * SCpnt)
return
;
}
SCpnt
->
request
.
rq_status
=
RQ_SCSI_DONE
;
SCpnt
->
request
->
rq_status
=
RQ_SCSI_DONE
;
SCpnt
->
owner
=
SCSI_OWNER_ERROR_HANDLER
;
SCpnt
->
eh_state
=
SUCCESS
;
...
...
@@ -346,7 +346,7 @@ void scsi_eh_done(Scsi_Cmnd * SCpnt)
STATIC
void
scsi_eh_action_done
(
Scsi_Cmnd
*
SCpnt
,
int
answer
)
{
SCpnt
->
request
.
rq_status
=
RQ_SCSI_DONE
;
SCpnt
->
request
->
rq_status
=
RQ_SCSI_DONE
;
SCpnt
->
owner
=
SCSI_OWNER_ERROR_HANDLER
;
SCpnt
->
eh_state
=
(
answer
?
SUCCESS
:
FAILED
);
...
...
@@ -601,7 +601,7 @@ STATIC void scsi_send_eh_cmnd(Scsi_Cmnd * SCpnt, int timeout)
* Set up the semaphore so we wait for the command to complete.
*/
SCpnt
->
host
->
eh_action
=
&
sem
;
SCpnt
->
request
.
rq_status
=
RQ_SCSI_BUSY
;
SCpnt
->
request
->
rq_status
=
RQ_SCSI_BUSY
;
spin_lock_irqsave
(
SCpnt
->
host
->
host_lock
,
flags
);
host
->
hostt
->
queuecommand
(
SCpnt
,
scsi_eh_done
);
...
...
@@ -633,7 +633,7 @@ STATIC void scsi_send_eh_cmnd(Scsi_Cmnd * SCpnt, int timeout)
SCpnt
->
host
->
hostt
->
eh_abort_handler
(
SCpnt
);
spin_unlock_irqrestore
(
SCpnt
->
host
->
host_lock
,
flags
);
SCpnt
->
request
.
rq_status
=
RQ_SCSI_DONE
;
SCpnt
->
request
->
rq_status
=
RQ_SCSI_DONE
;
SCpnt
->
owner
=
SCSI_OWNER_ERROR_HANDLER
;
SCpnt
->
eh_state
=
FAILED
;
...
...
drivers/scsi/scsi_lib.c
View file @
5463a13c
...
...
@@ -76,12 +76,10 @@ 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
* barrier
*/
rq
->
flags
=
REQ_SPECIAL
|
REQ_BARRIER
;
rq
->
flags
&=
REQ_QUEUED
;
rq
->
flags
|=
REQ_SPECIAL
|
REQ_BARRIER
;
rq
->
special
=
data
;
rq
->
q
=
NULL
;
rq
->
bio
=
rq
->
biotail
=
NULL
;
rq
->
nr_phys_segments
=
0
;
/*
* We have the option of inserting the head or the tail of the queue.
...
...
@@ -90,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.
*/
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
);
q
->
request_fn
(
q
);
spin_unlock_irqrestore
(
q
->
queue_lock
,
flags
);
...
...
@@ -120,7 +121,7 @@ int scsi_insert_special_cmd(Scsi_Cmnd * SCpnt, int at_head)
{
request_queue_t
*
q
=
&
SCpnt
->
device
->
request_queue
;
__scsi_insert_special
(
q
,
&
SCpnt
->
request
,
SCpnt
,
at_head
);
__scsi_insert_special
(
q
,
SCpnt
->
request
,
SCpnt
,
at_head
);
return
0
;
}
...
...
@@ -148,7 +149,7 @@ int scsi_insert_special_req(Scsi_Request * SRpnt, int at_head)
{
request_queue_t
*
q
=
&
SRpnt
->
sr_device
->
request_queue
;
__scsi_insert_special
(
q
,
&
SRpnt
->
sr_request
,
SRpnt
,
at_head
);
__scsi_insert_special
(
q
,
SRpnt
->
sr_request
,
SRpnt
,
at_head
);
return
0
;
}
...
...
@@ -259,8 +260,10 @@ void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt)
* in which case we need to request the blocks that come after
* the bad sector.
*/
SCpnt
->
request
.
special
=
(
void
*
)
SCpnt
;
_elv_add_request
(
q
,
&
SCpnt
->
request
,
0
,
0
);
SCpnt
->
request
->
special
=
(
void
*
)
SCpnt
;
if
(
blk_rq_tagged
(
SCpnt
->
request
))
blk_queue_end_tag
(
q
,
SCpnt
->
request
);
_elv_add_request
(
q
,
SCpnt
->
request
,
0
,
0
);
}
/*
...
...
@@ -356,15 +359,18 @@ static Scsi_Cmnd *__scsi_end_request(Scsi_Cmnd * SCpnt,
int
frequeue
)
{
request_queue_t
*
q
=
&
SCpnt
->
device
->
request_queue
;
struct
request
*
req
=
&
SCpnt
->
request
;
struct
request
*
req
=
SCpnt
->
request
;
int
flags
;
ASSERT_LOCK
(
q
->
queue_lock
,
0
);
spin_lock_irqsave
(
q
->
queue_lock
,
flags
);
/*
* If there are blocks left over at the end, set up the command
* to queue the remainder of them.
*/
if
(
end_that_request_first
(
req
,
uptodate
,
sectors
))
{
spin_unlock_irqrestore
(
q
->
queue_lock
,
flags
);
if
(
!
requeue
)
return
SCpnt
;
...
...
@@ -376,15 +382,15 @@ static Scsi_Cmnd *__scsi_end_request(Scsi_Cmnd * SCpnt,
return
SCpnt
;
}
/*
* This request is done. If there is someone blocked waiting for this
* request, wake them up.
*/
if
(
req
->
waiting
)
complete
(
req
->
waiting
);
add_blkdev_randomness
(
major
(
req
->
rq_dev
));
if
(
blk_rq_tagged
(
req
))
blk_queue_end_tag
(
q
,
req
);
end_that_request_last
(
req
);
spin_unlock_irqrestore
(
q
->
queue_lock
,
flags
);
/*
* This will goose the queue request function at the end, so we don't
* need to worry about launching another command.
...
...
@@ -441,7 +447,7 @@ Scsi_Cmnd *scsi_end_request(Scsi_Cmnd * SCpnt, int uptodate, int sectors)
*/
static
void
scsi_release_buffers
(
Scsi_Cmnd
*
SCpnt
)
{
struct
request
*
req
=
&
SCpnt
->
request
;
struct
request
*
req
=
SCpnt
->
request
;
ASSERT_LOCK
(
SCpnt
->
host
->
host_lock
,
0
);
...
...
@@ -491,7 +497,7 @@ void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors,
int
result
=
SCpnt
->
result
;
int
this_count
=
SCpnt
->
bufflen
>>
9
;
request_queue_t
*
q
=
&
SCpnt
->
device
->
request_queue
;
struct
request
*
req
=
&
SCpnt
->
request
;
struct
request
*
req
=
SCpnt
->
request
;
/*
* We must do one of several things here:
...
...
@@ -675,7 +681,7 @@ void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors,
if
(
result
)
{
struct
Scsi_Device_Template
*
STpnt
;
STpnt
=
scsi_get_request_dev
(
&
SCpnt
->
request
);
STpnt
=
scsi_get_request_dev
(
SCpnt
->
request
);
printk
(
"SCSI %s error : host %d channel %d id %d lun %d return code = %x
\n
"
,
(
STpnt
?
STpnt
->
name
:
"device"
),
SCpnt
->
device
->
host
->
host_no
,
...
...
@@ -868,7 +874,7 @@ void scsi_request_fn(request_queue_t * q)
* the remainder of a partially fulfilled request that can
* come up when there is a medium error. We have to treat
* these two cases differently. We differentiate by looking
* at request
.
cmd, as this tells us the real story.
* at request
->
cmd, as this tells us the real story.
*/
if
(
req
->
flags
&
REQ_SPECIAL
)
{
STpnt
=
NULL
;
...
...
@@ -904,6 +910,9 @@ void scsi_request_fn(request_queue_t * q)
*/
if
(
!
SCpnt
)
break
;
/* pull a tag out of the request if we have one */
SCpnt
->
tag
=
req
->
tag
;
}
else
{
blk_dump_rq_flags
(
req
,
"SCSI bad req"
);
break
;
...
...
@@ -924,18 +933,15 @@ void scsi_request_fn(request_queue_t * q)
* reason to search the list, because all of the commands
* in this queue are for the same device.
*/
blkdev_dequeue_request
(
req
);
if
(
!
(
blk_queue_tagged
(
q
)
&&
(
blk_queue_start_tag
(
q
,
req
)
==
0
)))
blkdev_dequeue_request
(
req
);
if
(
req
!=
&
SCpnt
->
request
&&
req
!=
&
SRpnt
->
sr_request
)
{
memcpy
(
&
SCpnt
->
request
,
req
,
sizeof
(
struct
request
));
/* 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
;
/*
* We have copied the data out of the request block -
* it is now in a field in SCpnt. Release the request
* block.
*/
blkdev_release_request
(
req
);
}
/*
* Now it is finally safe to release the lock. We are
* not going to noodle the request list until this
...
...
@@ -945,7 +951,7 @@ void scsi_request_fn(request_queue_t * q)
req
=
NULL
;
spin_unlock_irq
(
q
->
queue_lock
);
if
(
SCpnt
->
request
.
flags
&
REQ_CMD
)
{
if
(
SCpnt
->
request
->
flags
&
REQ_CMD
)
{
/*
* This will do a couple of things:
* 1) Fill in the actual SCSI command.
...
...
@@ -959,7 +965,7 @@ void scsi_request_fn(request_queue_t * q)
* request to be rejected immediately.
*/
if
(
STpnt
==
NULL
)
STpnt
=
scsi_get_request_dev
(
&
SCpnt
->
request
);
STpnt
=
scsi_get_request_dev
(
SCpnt
->
request
);
/*
* This sets up the scatter-gather table (allocating if
...
...
@@ -973,9 +979,11 @@ void scsi_request_fn(request_queue_t * q)
SDpnt
->
starved
=
1
;
SHpnt
->
some_device_starved
=
1
;
}
SCpnt
->
request
.
special
=
SCpnt
;
SCpnt
->
request
.
flags
|=
REQ_SPECIAL
;
_elv_add_request
(
q
,
&
SCpnt
->
request
,
0
,
0
);
SCpnt
->
request
->
special
=
SCpnt
;
SCpnt
->
request
->
flags
|=
REQ_SPECIAL
;
if
(
blk_rq_tagged
(
SCpnt
->
request
))
blk_queue_end_tag
(
q
,
SCpnt
->
request
);
_elv_add_request
(
q
,
SCpnt
->
request
,
0
,
0
);
break
;
}
...
...
@@ -985,7 +993,7 @@ void scsi_request_fn(request_queue_t * q)
if
(
!
STpnt
->
init_command
(
SCpnt
))
{
scsi_release_buffers
(
SCpnt
);
SCpnt
=
__scsi_end_request
(
SCpnt
,
0
,
SCpnt
->
request
.
nr_sectors
,
0
,
0
);
SCpnt
->
request
->
nr_sectors
,
0
,
0
);
if
(
SCpnt
!=
NULL
)
{
panic
(
"Should not have leftover blocks
\n
"
);
...
...
drivers/scsi/scsi_merge.c
View file @
5463a13c
...
...
@@ -57,7 +57,7 @@
*/
int
scsi_init_io
(
Scsi_Cmnd
*
SCpnt
)
{
struct
request
*
req
=
&
SCpnt
->
request
;
struct
request
*
req
=
SCpnt
->
request
;
struct
scatterlist
*
sgpnt
;
int
count
,
gfp_mask
;
...
...
drivers/scsi/scsi_scan.c
View file @
5463a13c
This diff is collapsed.
Click to expand it.
drivers/scsi/scsi_syms.c
View file @
5463a13c
...
...
@@ -101,3 +101,8 @@ extern void scsi_add_timer(Scsi_Cmnd *, int, void ((*) (Scsi_Cmnd *)));
extern
int
scsi_delete_timer
(
Scsi_Cmnd
*
);
EXPORT_SYMBOL
(
scsi_add_timer
);
EXPORT_SYMBOL
(
scsi_delete_timer
);
/*
* driverfs support for determining driver types
*/
EXPORT_SYMBOL
(
scsi_driverfs_bus_type
);
drivers/scsi/sd.c
View file @
5463a13c
...
...
@@ -129,6 +129,7 @@ static void sd_rw_intr(Scsi_Cmnd * SCpnt);
static
Scsi_Disk
*
sd_get_sdisk
(
int
index
);
extern
void
driverfs_remove_partitions
(
struct
gendisk
*
hd
,
int
minor
);
#if defined(CONFIG_PPC32)
/**
...
...
@@ -327,13 +328,13 @@ static int sd_init_command(Scsi_Cmnd * SCpnt)
/*
* don't support specials for nwo
*/
if
(
!
(
SCpnt
->
request
.
flags
&
REQ_CMD
))
if
(
!
(
SCpnt
->
request
->
flags
&
REQ_CMD
))
return
0
;
part_nr
=
SD_PARTITION
(
SCpnt
->
request
.
rq_dev
);
dsk_nr
=
DEVICE_NR
(
SCpnt
->
request
.
rq_dev
);
part_nr
=
SD_PARTITION
(
SCpnt
->
request
->
rq_dev
);
dsk_nr
=
DEVICE_NR
(
SCpnt
->
request
->
rq_dev
);
block
=
SCpnt
->
request
.
sector
;
block
=
SCpnt
->
request
->
sector
;
this_count
=
SCpnt
->
request_bufflen
>>
9
;
SCSI_LOG_HLQUEUE
(
1
,
printk
(
"sd_command_init: dsk_nr=%d, block=%d, "
...
...
@@ -344,9 +345,9 @@ static int sd_init_command(Scsi_Cmnd * SCpnt)
/* >>>>> this change is not in the lk 2.5 series */
if
(
part_nr
>=
(
sd_template
.
dev_max
<<
4
)
||
(
part_nr
&
0xf
)
||
!
sdp
||
!
sdp
->
online
||
block
+
SCpnt
->
request
.
nr_sectors
>
sd
[
part_nr
].
nr_sects
)
{
block
+
SCpnt
->
request
->
nr_sectors
>
sd
[
part_nr
].
nr_sects
)
{
SCSI_LOG_HLQUEUE
(
2
,
printk
(
"Finishing %ld sectors
\n
"
,
SCpnt
->
request
.
nr_sectors
));
SCpnt
->
request
->
nr_sectors
));
SCSI_LOG_HLQUEUE
(
2
,
printk
(
"Retry with 0x%p
\n
"
,
SCpnt
));
return
0
;
}
...
...
@@ -375,7 +376,7 @@ static int sd_init_command(Scsi_Cmnd * SCpnt)
* for this.
*/
if
(
sdp
->
sector_size
==
1024
)
{
if
((
block
&
1
)
||
(
SCpnt
->
request
.
nr_sectors
&
1
))
{
if
((
block
&
1
)
||
(
SCpnt
->
request
->
nr_sectors
&
1
))
{
printk
(
KERN_ERR
"sd: Bad block number requested"
);
return
0
;
}
else
{
...
...
@@ -384,7 +385,7 @@ static int sd_init_command(Scsi_Cmnd * SCpnt)
}
}
if
(
sdp
->
sector_size
==
2048
)
{
if
((
block
&
3
)
||
(
SCpnt
->
request
.
nr_sectors
&
3
))
{
if
((
block
&
3
)
||
(
SCpnt
->
request
->
nr_sectors
&
3
))
{
printk
(
KERN_ERR
"sd: Bad block number requested"
);
return
0
;
}
else
{
...
...
@@ -393,7 +394,7 @@ static int sd_init_command(Scsi_Cmnd * SCpnt)
}
}
if
(
sdp
->
sector_size
==
4096
)
{
if
((
block
&
7
)
||
(
SCpnt
->
request
.
nr_sectors
&
7
))
{
if
((
block
&
7
)
||
(
SCpnt
->
request
->
nr_sectors
&
7
))
{
printk
(
KERN_ERR
"sd: Bad block number requested"
);
return
0
;
}
else
{
...
...
@@ -401,25 +402,25 @@ static int sd_init_command(Scsi_Cmnd * SCpnt)
this_count
=
this_count
>>
3
;
}
}
if
(
rq_data_dir
(
&
SCpnt
->
request
)
==
WRITE
)
{
if
(
rq_data_dir
(
SCpnt
->
request
)
==
WRITE
)
{
if
(
!
sdp
->
writeable
)
{
return
0
;
}
SCpnt
->
cmnd
[
0
]
=
WRITE_6
;
SCpnt
->
sc_data_direction
=
SCSI_DATA_WRITE
;
}
else
if
(
rq_data_dir
(
&
SCpnt
->
request
)
==
READ
)
{
}
else
if
(
rq_data_dir
(
SCpnt
->
request
)
==
READ
)
{
SCpnt
->
cmnd
[
0
]
=
READ_6
;
SCpnt
->
sc_data_direction
=
SCSI_DATA_READ
;
}
else
{
printk
(
KERN_ERR
"sd: Unknown command %lx
\n
"
,
SCpnt
->
request
.
flags
);
/* overkill panic("Unknown sd command %lx\n", SCpnt->request
.
flags); */
SCpnt
->
request
->
flags
);
/* overkill panic("Unknown sd command %lx\n", SCpnt->request
->
flags); */
return
0
;
}
SCSI_LOG_HLQUEUE
(
2
,
printk
(
"%s : %s %d/%ld 512 byte blocks.
\n
"
,
nbuff
,
(
rq_data_dir
(
&
SCpnt
->
request
)
==
WRITE
)
?
"writing"
:
"reading"
,
this_count
,
SCpnt
->
request
.
nr_sectors
));
nbuff
,
(
rq_data_dir
(
SCpnt
->
request
)
==
WRITE
)
?
"writing"
:
"reading"
,
this_count
,
SCpnt
->
request
->
nr_sectors
));
SCpnt
->
cmnd
[
1
]
=
(
SCpnt
->
device
->
scsi_level
<=
SCSI_2
)
?
((
SCpnt
->
lun
<<
5
)
&
0xe0
)
:
0
;
...
...
@@ -664,7 +665,7 @@ static void sd_rw_intr(Scsi_Cmnd * SCpnt)
#if CONFIG_SCSI_LOGGING
char
nbuff
[
6
];
SCSI_LOG_HLCOMPLETE
(
1
,
sd_dskname
(
DEVICE_NR
(
SCpnt
->
request
.
rq_dev
),
SCSI_LOG_HLCOMPLETE
(
1
,
sd_dskname
(
DEVICE_NR
(
SCpnt
->
request
->
rq_dev
),
nbuff
));
SCSI_LOG_HLCOMPLETE
(
1
,
printk
(
"sd_rw_intr: %s: res=0x%x
\n
"
,
nbuff
,
result
));
...
...
@@ -690,8 +691,8 @@ static void sd_rw_intr(Scsi_Cmnd * SCpnt)
(
SCpnt
->
sense_buffer
[
4
]
<<
16
)
|
(
SCpnt
->
sense_buffer
[
5
]
<<
8
)
|
SCpnt
->
sense_buffer
[
6
];
if
(
SCpnt
->
request
.
bio
!=
NULL
)
block_sectors
=
bio_sectors
(
SCpnt
->
request
.
bio
);
if
(
SCpnt
->
request
->
bio
!=
NULL
)
block_sectors
=
bio_sectors
(
SCpnt
->
request
->
bio
);
switch
(
SCpnt
->
device
->
sector_size
)
{
case
1024
:
error_sector
<<=
1
;
...
...
@@ -716,7 +717,7 @@ static void sd_rw_intr(Scsi_Cmnd * SCpnt)
}
error_sector
&=
~
(
block_sectors
-
1
);
good_sectors
=
error_sector
-
SCpnt
->
request
.
sector
;
good_sectors
=
error_sector
-
SCpnt
->
request
->
sector
;
if
(
good_sectors
<
0
||
good_sectors
>=
this_count
)
good_sectors
=
0
;
break
;
...
...
@@ -1277,12 +1278,15 @@ static int sd_init()
init_mem_lth
(
sd_gendisks
[
k
].
de_arr
,
N
);
init_mem_lth
(
sd_gendisks
[
k
].
flags
,
N
);
init_mem_lth
(
sd_gendisks
[
k
].
driverfs_dev_arr
,
N
);
if
(
!
sd_gendisks
[
k
].
de_arr
||
!
sd_gendisks
[
k
].
flags
)
if
(
!
sd_gendisks
[
k
].
de_arr
||
!
sd_gendisks
[
k
].
flags
||
!
sd_gendisks
[
k
].
driverfs_dev_arr
)
goto
cleanup_gendisks
;
zero_mem_lth
(
sd_gendisks
[
k
].
de_arr
,
N
);
zero_mem_lth
(
sd_gendisks
[
k
].
flags
,
N
);
zero_mem_lth
(
sd_gendisks
[
k
].
driverfs_dev_arr
,
N
);
sd_gendisks
[
k
].
major
=
SD_MAJOR
(
k
);
sd_gendisks
[
k
].
major_name
=
"sd"
;
...
...
@@ -1291,7 +1295,6 @@ static int sd_init()
sd_gendisks
[
k
].
sizes
=
sd_sizes
+
k
*
(
N
<<
4
);
sd_gendisks
[
k
].
nr_real
=
0
;
}
return
0
;
#undef init_mem_lth
...
...
@@ -1302,6 +1305,7 @@ static int sd_init()
for
(
k
=
0
;
k
<
N_USED_SD_MAJORS
;
k
++
)
{
vfree
(
sd_gendisks
[
k
].
de_arr
);
vfree
(
sd_gendisks
[
k
].
flags
);
vfree
(
sd_gendisks
[
k
].
driverfs_dev_arr
);
}
cleanup_mem:
vfree
(
sd_gendisks
);
...
...
@@ -1436,6 +1440,8 @@ static int sd_attach(Scsi_Device * sdp)
SD_GENDISK
(
dsk_nr
).
nr_real
++
;
devnum
=
dsk_nr
%
SCSI_DISKS_PER_MAJOR
;
SD_GENDISK
(
dsk_nr
).
de_arr
[
devnum
]
=
sdp
->
de
;
SD_GENDISK
(
dsk_nr
).
driverfs_dev_arr
[
devnum
]
=
&
sdp
->
sdev_driverfs_dev
;
if
(
sdp
->
removable
)
SD_GENDISK
(
dsk_nr
).
flags
[
devnum
]
|=
GENHD_FL_REMOVABLE
;
sd_dskname
(
dsk_nr
,
diskname
);
...
...
@@ -1535,6 +1541,8 @@ static void sd_detach(Scsi_Device * sdp)
max_p
=
1
<<
sd_gendisk
.
minor_shift
;
start
=
dsk_nr
<<
sd_gendisk
.
minor_shift
;
dev
=
MKDEV_SD_PARTITION
(
start
);
driverfs_remove_partitions
(
&
SD_GENDISK
(
dsk_nr
),
SD_MINOR_NUMBER
(
start
));
wipe_partitions
(
dev
);
for
(
j
=
max_p
-
1
;
j
>=
0
;
j
--
)
sd_sizes
[
start
+
j
]
=
0
;
...
...
@@ -1556,9 +1564,16 @@ static void sd_detach(Scsi_Device * sdp)
**/
static
int
__init
init_sd
(
void
)
{
int
rc
;
SCSI_LOG_HLQUEUE
(
3
,
printk
(
"init_sd: sd driver entry point
\n
"
));
sd_template
.
module
=
THIS_MODULE
;
return
scsi_register_device
(
&
sd_template
);
rc
=
scsi_register_device
(
&
sd_template
);
if
(
!
rc
)
{
sd_template
.
scsi_driverfs_driver
.
name
=
(
char
*
)
sd_template
.
tag
;
sd_template
.
scsi_driverfs_driver
.
bus
=
&
scsi_driverfs_bus_type
;
driver_register
(
&
sd_template
.
scsi_driverfs_driver
);
}
return
rc
;
}
/**
...
...
@@ -1591,6 +1606,7 @@ static void __exit exit_sd(void)
sd_template
.
dev_max
=
0
;
if
(
sd_gendisks
!=
&
sd_gendisk
)
vfree
(
sd_gendisks
);
remove_driver
(
&
sd_template
.
scsi_driverfs_driver
);
}
static
Scsi_Disk
*
sd_get_sdisk
(
int
index
)
...
...
drivers/scsi/sg.c
View file @
5463a13c
...
...
@@ -194,6 +194,7 @@ typedef struct sg_device /* holds the state of each scsi generic device */
volatile
char
detached
;
/* 0->attached, 1->detached pending removal */
volatile
char
exclude
;
/* opened for exclusive access */
char
sgdebug
;
/* 0->off, 1->sense, 9->dump dev, 10-> all devs */
struct
device
sg_driverfs_dev
;
}
Sg_device
;
/* 36 bytes long on i386 */
...
...
@@ -695,7 +696,7 @@ static int sg_common_write(Sg_fd * sfp, Sg_request * srp,
srp
->
my_cmdp
=
SRpnt
;
q
=
&
SRpnt
->
sr_device
->
request_queue
;
SRpnt
->
sr_request
.
rq_dev
=
sdp
->
i_rdev
;
SRpnt
->
sr_request
->
rq_dev
=
sdp
->
i_rdev
;
SRpnt
->
sr_sense_buffer
[
0
]
=
0
;
SRpnt
->
sr_cmd_len
=
hp
->
cmd_len
;
if
(
!
(
hp
->
flags
&
SG_FLAG_LUN_INHIBIT
))
{
...
...
@@ -1222,7 +1223,7 @@ static void sg_cmd_done_bh(Scsi_Cmnd * SCpnt)
SRpnt
->
sr_bufflen
=
0
;
SRpnt
->
sr_buffer
=
NULL
;
SRpnt
->
sr_underflow
=
0
;
SRpnt
->
sr_request
.
rq_dev
=
mk_kdev
(
0
,
0
);
/* "sg" _disowns_ request blk */
SRpnt
->
sr_request
->
rq_dev
=
mk_kdev
(
0
,
0
);
/* "sg" _disowns_ request blk */
srp
->
my_cmdp
=
NULL
;
srp
->
done
=
1
;
...
...
@@ -1370,6 +1371,29 @@ static int __init sg_def_reserved_size_setup(char *str)
__setup
(
"sg_def_reserved_size="
,
sg_def_reserved_size_setup
);
#endif
/* Driverfs file support */
static
ssize_t
sg_device_kdev_read
(
struct
device
*
driverfs_dev
,
char
*
page
,
size_t
count
,
loff_t
off
)
{
Sg_device
*
sdp
=
list_entry
(
driverfs_dev
,
Sg_device
,
sg_driverfs_dev
);
return
off
?
0
:
sprintf
(
page
,
"%x
\n
"
,
sdp
->
i_rdev
.
value
);
}
static
struct
driver_file_entry
sg_device_kdev_file
=
{
name:
"kdev"
,
mode:
S_IRUGO
,
show:
sg_device_kdev_read
,
};
static
ssize_t
sg_device_type_read
(
struct
device
*
driverfs_dev
,
char
*
page
,
size_t
count
,
loff_t
off
)
{
return
off
?
0
:
sprintf
(
page
,
"CHR
\n
"
);
}
static
struct
driver_file_entry
sg_device_type_file
=
{
name:
"type"
,
mode:
S_IRUGO
,
show:
sg_device_type_read
,
};
static
int
sg_attach
(
Scsi_Device
*
scsidp
)
{
...
...
@@ -1428,6 +1452,18 @@ static int sg_attach(Scsi_Device * scsidp)
sdp
->
detached
=
0
;
sdp
->
sg_tablesize
=
scsidp
->
host
?
scsidp
->
host
->
sg_tablesize
:
0
;
sdp
->
i_rdev
=
mk_kdev
(
SCSI_GENERIC_MAJOR
,
k
);
memset
(
&
sdp
->
sg_driverfs_dev
,
0
,
sizeof
(
struct
device
));
sprintf
(
sdp
->
sg_driverfs_dev
.
bus_id
,
"%s:gen"
,
scsidp
->
sdev_driverfs_dev
.
bus_id
);
sprintf
(
sdp
->
sg_driverfs_dev
.
name
,
"%sgeneric"
,
scsidp
->
sdev_driverfs_dev
.
name
);
sdp
->
sg_driverfs_dev
.
parent
=
&
scsidp
->
sdev_driverfs_dev
;
sdp
->
sg_driverfs_dev
.
bus
=
&
scsi_driverfs_bus_type
;
device_register
(
&
sdp
->
sg_driverfs_dev
);
device_create_file
(
&
sdp
->
sg_driverfs_dev
,
&
sg_device_type_file
);
device_create_file
(
&
sdp
->
sg_driverfs_dev
,
&
sg_device_kdev_file
);
sdp
->
de
=
devfs_register
(
scsidp
->
de
,
"generic"
,
DEVFS_FL_DEFAULT
,
SCSI_GENERIC_MAJOR
,
k
,
S_IFCHR
|
S_IRUSR
|
S_IWUSR
|
S_IRGRP
,
...
...
@@ -1496,6 +1532,9 @@ static void sg_detach(Scsi_Device * scsidp)
}
SCSI_LOG_TIMEOUT
(
3
,
printk
(
"sg_detach: dev=%d, dirty
\n
"
,
k
));
devfs_unregister
(
sdp
->
de
);
device_remove_file
(
&
sdp
->
sg_driverfs_dev
,
sg_device_type_file
.
name
);
device_remove_file
(
&
sdp
->
sg_driverfs_dev
,
sg_device_kdev_file
.
name
);
put_device
(
&
sdp
->
sg_driverfs_dev
);
sdp
->
de
=
NULL
;
if
(
NULL
==
sdp
->
headfp
)
{
kfree
((
char
*
)
sdp
);
...
...
@@ -1505,6 +1544,7 @@ static void sg_detach(Scsi_Device * scsidp)
else
{
/* nothing active, simple case */
SCSI_LOG_TIMEOUT
(
3
,
printk
(
"sg_detach: dev=%d
\n
"
,
k
));
devfs_unregister
(
sdp
->
de
);
put_device
(
&
sdp
->
sg_driverfs_dev
);
kfree
((
char
*
)
sdp
);
sg_dev_arr
[
k
]
=
NULL
;
}
...
...
@@ -1529,9 +1569,16 @@ MODULE_PARM(def_reserved_size, "i");
MODULE_PARM_DESC
(
def_reserved_size
,
"size of buffer reserved for each fd"
);
static
int
__init
init_sg
(
void
)
{
int
rc
;
if
(
def_reserved_size
>=
0
)
sg_big_buff
=
def_reserved_size
;
return
scsi_register_device
(
&
sg_template
);
rc
=
scsi_register_device
(
&
sg_template
);
if
(
!
rc
)
{
sg_template
.
scsi_driverfs_driver
.
name
=
(
char
*
)
sg_template
.
tag
;
sg_template
.
scsi_driverfs_driver
.
bus
=
&
scsi_driverfs_bus_type
;
driver_register
(
&
sg_template
.
scsi_driverfs_driver
);
}
return
rc
;
}
static
void
__exit
exit_sg
(
void
)
...
...
@@ -1546,6 +1593,7 @@ static void __exit exit_sg( void)
sg_dev_arr
=
NULL
;
}
sg_template
.
dev_max
=
0
;
remove_driver
(
&
sg_template
.
scsi_driverfs_driver
);
}
...
...
drivers/scsi/sr.c
View file @
5463a13c
...
...
@@ -197,11 +197,11 @@ static void rw_intr(Scsi_Cmnd * SCpnt)
int
this_count
=
SCpnt
->
bufflen
>>
9
;
int
good_sectors
=
(
result
==
0
?
this_count
:
0
);
int
block_sectors
=
0
;
int
device_nr
=
DEVICE_NR
(
SCpnt
->
request
.
rq_dev
);
int
device_nr
=
DEVICE_NR
(
SCpnt
->
request
->
rq_dev
);
Scsi_CD
*
SCp
=
&
scsi_CDs
[
device_nr
];
#ifdef DEBUG
printk
(
"sr.c done: %x %p
\n
"
,
result
,
SCpnt
->
request
.
bh
->
b_data
);
printk
(
"sr.c done: %x %p
\n
"
,
result
,
SCpnt
->
request
->
bh
->
b_data
);
#endif
/*
Handle MEDIUM ERRORs or VOLUME OVERFLOWs that indicate partial success.
...
...
@@ -219,14 +219,14 @@ static void rw_intr(Scsi_Cmnd * SCpnt)
(
SCpnt
->
sense_buffer
[
4
]
<<
16
)
|
(
SCpnt
->
sense_buffer
[
5
]
<<
8
)
|
SCpnt
->
sense_buffer
[
6
];
if
(
SCpnt
->
request
.
bio
!=
NULL
)
block_sectors
=
bio_sectors
(
SCpnt
->
request
.
bio
);
if
(
SCpnt
->
request
->
bio
!=
NULL
)
block_sectors
=
bio_sectors
(
SCpnt
->
request
->
bio
);
if
(
block_sectors
<
4
)
block_sectors
=
4
;
if
(
SCp
->
device
->
sector_size
==
2048
)
error_sector
<<=
2
;
error_sector
&=
~
(
block_sectors
-
1
);
good_sectors
=
error_sector
-
SCpnt
->
request
.
sector
;
good_sectors
=
error_sector
-
SCpnt
->
request
->
sector
;
if
(
good_sectors
<
0
||
good_sectors
>=
this_count
)
good_sectors
=
0
;
/*
...
...
@@ -266,14 +266,14 @@ static int sr_init_command(Scsi_Cmnd * SCpnt)
int
dev
,
devm
,
block
=
0
,
this_count
,
s_size
;
Scsi_CD
*
SCp
;
devm
=
minor
(
SCpnt
->
request
.
rq_dev
);
dev
=
DEVICE_NR
(
SCpnt
->
request
.
rq_dev
);
devm
=
minor
(
SCpnt
->
request
->
rq_dev
);
dev
=
DEVICE_NR
(
SCpnt
->
request
->
rq_dev
);
SCp
=
&
scsi_CDs
[
dev
];
SCSI_LOG_HLQUEUE
(
1
,
printk
(
"Doing sr request, dev = %d, block = %d
\n
"
,
devm
,
block
));
if
(
dev
>=
sr_template
.
nr_dev
||
!
SCp
->
device
||
!
SCp
->
device
->
online
)
{
SCSI_LOG_HLQUEUE
(
2
,
printk
(
"Finishing %ld sectors
\n
"
,
SCpnt
->
request
.
nr_sectors
));
SCSI_LOG_HLQUEUE
(
2
,
printk
(
"Finishing %ld sectors
\n
"
,
SCpnt
->
request
->
nr_sectors
));
SCSI_LOG_HLQUEUE
(
2
,
printk
(
"Retry with 0x%p
\n
"
,
SCpnt
));
return
0
;
}
...
...
@@ -286,8 +286,8 @@ static int sr_init_command(Scsi_Cmnd * SCpnt)
return
0
;
}
if
(
!
(
SCpnt
->
request
.
flags
&
REQ_CMD
))
{
blk_dump_rq_flags
(
&
SCpnt
->
request
,
"sr unsup command"
);
if
(
!
(
SCpnt
->
request
->
flags
&
REQ_CMD
))
{
blk_dump_rq_flags
(
SCpnt
->
request
,
"sr unsup command"
);
return
0
;
}
...
...
@@ -308,23 +308,23 @@ static int sr_init_command(Scsi_Cmnd * SCpnt)
return
0
;
}
if
(
rq_data_dir
(
&
SCpnt
->
request
)
==
WRITE
)
{
if
(
rq_data_dir
(
SCpnt
->
request
)
==
WRITE
)
{
if
(
!
SCp
->
device
->
writeable
)
return
0
;
SCpnt
->
cmnd
[
0
]
=
WRITE_10
;
SCpnt
->
sc_data_direction
=
SCSI_DATA_WRITE
;
}
else
if
(
rq_data_dir
(
&
SCpnt
->
request
)
==
READ
)
{
}
else
if
(
rq_data_dir
(
SCpnt
->
request
)
==
READ
)
{
SCpnt
->
cmnd
[
0
]
=
READ_10
;
SCpnt
->
sc_data_direction
=
SCSI_DATA_READ
;
}
else
{
blk_dump_rq_flags
(
&
SCpnt
->
request
,
"Unknown sr command"
);
blk_dump_rq_flags
(
SCpnt
->
request
,
"Unknown sr command"
);
return
0
;
}
/*
* request doesn't start on hw block boundary, add scatter pads
*/
if
((
SCpnt
->
request
.
sector
%
(
s_size
>>
9
))
||
(
SCpnt
->
request_bufflen
%
s_size
))
{
if
((
SCpnt
->
request
->
sector
%
(
s_size
>>
9
))
||
(
SCpnt
->
request_bufflen
%
s_size
))
{
printk
(
"sr: unaligned transfer
\n
"
);
return
0
;
}
...
...
@@ -334,13 +334,13 @@ static int sr_init_command(Scsi_Cmnd * SCpnt)
SCSI_LOG_HLQUEUE
(
2
,
printk
(
"sr%d : %s %d/%ld 512 byte blocks.
\n
"
,
devm
,
(
rq_data_dir
(
&
SCpnt
->
request
)
==
WRITE
)
?
"writing"
:
"reading"
,
this_count
,
SCpnt
->
request
.
nr_sectors
));
(
rq_data_dir
(
SCpnt
->
request
)
==
WRITE
)
?
"writing"
:
"reading"
,
this_count
,
SCpnt
->
request
->
nr_sectors
));
SCpnt
->
cmnd
[
1
]
=
(
SCpnt
->
device
->
scsi_level
<=
SCSI_2
)
?
((
SCpnt
->
lun
<<
5
)
&
0xe0
)
:
0
;
block
=
SCpnt
->
request
.
sector
/
(
s_size
>>
9
);
block
=
SCpnt
->
request
->
sector
/
(
s_size
>>
9
);
if
(
this_count
>
0xffff
)
this_count
=
0xffff
;
...
...
@@ -496,7 +496,7 @@ void get_sectorsize(int i)
cmd
[
1
]
=
(
SCp
->
device
->
scsi_level
<=
SCSI_2
)
?
((
SCp
->
device
->
lun
<<
5
)
&
0xe0
)
:
0
;
memset
((
void
*
)
&
cmd
[
2
],
0
,
8
);
SRpnt
->
sr_request
.
rq_status
=
RQ_SCSI_BUSY
;
/* Mark as really busy */
SRpnt
->
sr_request
->
rq_status
=
RQ_SCSI_BUSY
;
/* Mark as really busy */
SRpnt
->
sr_cmd_len
=
0
;
memset
(
buffer
,
0
,
8
);
...
...
@@ -731,6 +731,32 @@ static int sr_init()
return
1
;
}
/* Driverfs file support */
static
ssize_t
sr_device_kdev_read
(
struct
device
*
driverfs_dev
,
char
*
page
,
size_t
count
,
loff_t
off
)
{
kdev_t
kdev
;
kdev
.
value
=
(
int
)
driverfs_dev
->
driver_data
;
return
off
?
0
:
sprintf
(
page
,
"%x
\n
"
,
kdev
.
value
);
}
static
struct
driver_file_entry
sr_device_kdev_file
=
{
name:
"kdev"
,
mode:
S_IRUGO
,
show:
sr_device_kdev_read
,
};
static
ssize_t
sr_device_type_read
(
struct
device
*
driverfs_dev
,
char
*
page
,
size_t
count
,
loff_t
off
)
{
return
off
?
0
:
sprintf
(
page
,
"CHR
\n
"
);
}
static
struct
driver_file_entry
sr_device_type_file
=
{
name:
"type"
,
mode:
S_IRUGO
,
show:
sr_device_type_read
,
};
void
sr_finish
()
{
int
i
;
...
...
@@ -776,6 +802,20 @@ void sr_finish()
sprintf
(
name
,
"sr%d"
,
i
);
strcpy
(
SCp
->
cdi
.
name
,
name
);
sprintf
(
SCp
->
cdi
.
cdrom_driverfs_dev
.
bus_id
,
"%s:cd"
,
SCp
->
device
->
sdev_driverfs_dev
.
bus_id
);
sprintf
(
SCp
->
cdi
.
cdrom_driverfs_dev
.
name
,
"%scdrom"
,
SCp
->
device
->
sdev_driverfs_dev
.
name
);
SCp
->
cdi
.
cdrom_driverfs_dev
.
parent
=
&
SCp
->
device
->
sdev_driverfs_dev
;
SCp
->
cdi
.
cdrom_driverfs_dev
.
bus
=
&
scsi_driverfs_bus_type
;
SCp
->
cdi
.
cdrom_driverfs_dev
.
driver_data
=
(
void
*
)
__mkdev
(
MAJOR_NR
,
i
);
device_register
(
&
SCp
->
cdi
.
cdrom_driverfs_dev
);
device_create_file
(
&
SCp
->
cdi
.
cdrom_driverfs_dev
,
&
sr_device_type_file
);
device_create_file
(
&
SCp
->
cdi
.
cdrom_driverfs_dev
,
&
sr_device_kdev_file
);
SCp
->
cdi
.
de
=
devfs_register
(
SCp
->
device
->
de
,
"cd"
,
DEVFS_FL_DEFAULT
,
MAJOR_NR
,
i
,
S_IFBLK
|
S_IRUGO
|
S_IWUGO
,
...
...
@@ -816,7 +856,14 @@ static void sr_detach(Scsi_Device * SDp)
static
int
__init
init_sr
(
void
)
{
return
scsi_register_device
(
&
sr_template
);
int
rc
;
rc
=
scsi_register_device
(
&
sr_template
);
if
(
!
rc
)
{
sr_template
.
scsi_driverfs_driver
.
name
=
(
char
*
)
sr_template
.
tag
;
sr_template
.
scsi_driverfs_driver
.
bus
=
&
scsi_driverfs_bus_type
;
driver_register
(
&
sr_template
.
scsi_driverfs_driver
);
}
return
rc
;
}
static
void
__exit
exit_sr
(
void
)
...
...
@@ -833,6 +880,7 @@ static void __exit exit_sr(void)
blk_clear
(
MAJOR_NR
);
sr_template
.
dev_max
=
0
;
remove_driver
(
&
sr_template
.
scsi_driverfs_driver
);
}
module_init
(
init_sr
);
...
...
drivers/scsi/sr_ioctl.c
View file @
5463a13c
...
...
@@ -93,7 +93,7 @@ int sr_do_ioctl(int target, unsigned char *sr_cmd, void *buffer, unsigned buflen
SRpnt
->
sr_data_direction
=
readwrite
;
/* use ISA DMA buffer if necessary */
SRpnt
->
sr_request
.
buffer
=
buffer
;
SRpnt
->
sr_request
->
buffer
=
buffer
;
if
(
buffer
&&
SRpnt
->
sr_host
->
unchecked_isa_dma
&&
(
virt_to_phys
(
buffer
)
+
buflength
-
1
>
ISA_DMA_THRESHOLD
))
{
bounce_buffer
=
(
char
*
)
kmalloc
(
buflength
,
GFP_DMA
);
...
...
@@ -112,7 +112,7 @@ int sr_do_ioctl(int target, unsigned char *sr_cmd, void *buffer, unsigned buflen
scsi_wait_req
(
SRpnt
,
(
void
*
)
sr_cmd
,
(
void
*
)
buffer
,
buflength
,
IOCTL_TIMEOUT
,
IOCTL_RETRIES
);
req
=
&
SRpnt
->
sr_request
;
req
=
SRpnt
->
sr_request
;
if
(
SRpnt
->
sr_buffer
&&
req
->
buffer
&&
SRpnt
->
sr_buffer
!=
req
->
buffer
)
{
memcpy
(
req
->
buffer
,
SRpnt
->
sr_buffer
,
SRpnt
->
sr_bufflen
);
kfree
(
SRpnt
->
sr_buffer
);
...
...
drivers/scsi/st.c
View file @
5463a13c
...
...
@@ -229,7 +229,7 @@ static int st_chk_result(Scsi_Tape *STp, Scsi_Request * SRpnt)
scode
=
0
;
}
dev
=
TAPE_NR
(
SRpnt
->
sr_request
.
rq_dev
);
dev
=
TAPE_NR
(
SRpnt
->
sr_request
->
rq_dev
);
DEB
(
if
(
debugging
)
{
printk
(
ST_DEB_MSG
"st%d: Error: %x, cmd: %x %x %x %x %x %x Len: %d
\n
"
,
...
...
@@ -306,7 +306,7 @@ static void st_sleep_done(Scsi_Cmnd * SCpnt)
int
remainder
;
Scsi_Tape
*
STp
;
st_nbr
=
TAPE_NR
(
SCpnt
->
request
.
rq_dev
);
st_nbr
=
TAPE_NR
(
SCpnt
->
request
->
rq_dev
);
read_lock
(
&
st_dev_arr_lock
);
STp
=
scsi_tapes
[
st_nbr
];
read_unlock
(
&
st_dev_arr_lock
);
...
...
@@ -328,11 +328,11 @@ static void st_sleep_done(Scsi_Cmnd * SCpnt)
(
STp
->
buffer
)
->
midlevel_result
=
INT_MAX
;
/* OK */
}
else
(
STp
->
buffer
)
->
midlevel_result
=
SCpnt
->
result
;
SCpnt
->
request
.
rq_status
=
RQ_SCSI_DONE
;
SCpnt
->
request
->
rq_status
=
RQ_SCSI_DONE
;
(
STp
->
buffer
)
->
last_SRpnt
=
SCpnt
->
sc_request
;
DEB
(
STp
->
write_pending
=
0
;
)
complete
(
SCpnt
->
request
.
waiting
);
complete
(
SCpnt
->
request
->
waiting
);
}
...
...
@@ -371,16 +371,16 @@ static Scsi_Request *
bp
=
(
STp
->
buffer
)
->
b_data
;
SRpnt
->
sr_data_direction
=
direction
;
SRpnt
->
sr_cmd_len
=
0
;
SRpnt
->
sr_request
.
waiting
=
&
(
STp
->
wait
);
SRpnt
->
sr_request
.
rq_status
=
RQ_SCSI_BUSY
;
SRpnt
->
sr_request
.
rq_dev
=
STp
->
devt
;
SRpnt
->
sr_request
->
waiting
=
&
(
STp
->
wait
);
SRpnt
->
sr_request
->
rq_status
=
RQ_SCSI_BUSY
;
SRpnt
->
sr_request
->
rq_dev
=
STp
->
devt
;
scsi_do_req
(
SRpnt
,
(
void
*
)
cmd
,
bp
,
bytes
,
st_sleep_done
,
timeout
,
retries
);
if
(
do_wait
)
{
wait_for_completion
(
SRpnt
->
sr_request
.
waiting
);
SRpnt
->
sr_request
.
waiting
=
NULL
;
wait_for_completion
(
SRpnt
->
sr_request
->
waiting
);
SRpnt
->
sr_request
->
waiting
=
NULL
;
(
STp
->
buffer
)
->
syscall_result
=
st_chk_result
(
STp
,
SRpnt
);
}
return
SRpnt
;
...
...
@@ -403,7 +403,7 @@ static void write_behind_check(Scsi_Tape * STp)
)
/* end DEB */
wait_for_completion
(
&
(
STp
->
wait
));
(
STp
->
buffer
)
->
last_SRpnt
->
sr_request
.
waiting
=
NULL
;
(
STp
->
buffer
)
->
last_SRpnt
->
sr_request
->
waiting
=
NULL
;
(
STp
->
buffer
)
->
syscall_result
=
st_chk_result
(
STp
,
(
STp
->
buffer
)
->
last_SRpnt
);
scsi_release_request
((
STp
->
buffer
)
->
last_SRpnt
);
...
...
@@ -3531,6 +3531,31 @@ __setup("st=", st_setup);
#endif
/* Driverfs file support */
static
ssize_t
st_device_kdev_read
(
struct
device
*
driverfs_dev
,
char
*
page
,
size_t
count
,
loff_t
off
)
{
kdev_t
kdev
;
kdev
.
value
=
(
int
)
driverfs_dev
->
driver_data
;
return
off
?
0
:
sprintf
(
page
,
"%x
\n
"
,
kdev
.
value
);
}
static
struct
driver_file_entry
st_device_kdev_file
=
{
name:
"kdev"
,
mode:
S_IRUGO
,
show:
st_device_kdev_read
,
};
static
ssize_t
st_device_type_read
(
struct
device
*
driverfs_dev
,
char
*
page
,
size_t
count
,
loff_t
off
)
{
return
off
?
0
:
sprintf
(
page
,
"CHR
\n
"
);
}
static
struct
driver_file_entry
st_device_type_file
=
{
name:
"type"
,
mode:
S_IRUGO
,
show:
st_device_type_read
,
};
static
struct
file_operations
st_fops
=
{
...
...
@@ -3632,6 +3657,18 @@ static int st_attach(Scsi_Device * SDp)
/* Rewind entry */
sprintf
(
name
,
"mt%s"
,
formats
[
mode
]);
sprintf
(
tpnt
->
driverfs_dev_r
[
mode
].
bus_id
,
"%s:%s"
,
SDp
->
sdev_driverfs_dev
.
name
,
name
);
sprintf
(
tpnt
->
driverfs_dev_r
[
mode
].
name
,
"%s%s"
,
SDp
->
sdev_driverfs_dev
.
name
,
name
);
tpnt
->
driverfs_dev_r
[
mode
].
parent
=
&
SDp
->
sdev_driverfs_dev
;
tpnt
->
driverfs_dev_r
[
mode
].
bus
=
&
scsi_driverfs_bus_type
;
tpnt
->
driverfs_dev_r
[
mode
].
driver_data
=
(
void
*
)
__mkdev
(
MAJOR_NR
,
i
+
(
mode
<<
5
));
device_register
(
&
tpnt
->
driverfs_dev_r
[
mode
]);
device_create_file
(
&
tpnt
->
driverfs_dev_r
[
mode
],
&
st_device_type_file
);
device_create_file
(
&
tpnt
->
driverfs_dev_r
[
mode
],
&
st_device_kdev_file
);
tpnt
->
de_r
[
mode
]
=
devfs_register
(
SDp
->
de
,
name
,
DEVFS_FL_DEFAULT
,
MAJOR_NR
,
i
+
(
mode
<<
5
),
...
...
@@ -3639,6 +3676,19 @@ static int st_attach(Scsi_Device * SDp)
&
st_fops
,
NULL
);
/* No-rewind entry */
sprintf
(
name
,
"mt%sn"
,
formats
[
mode
]);
sprintf
(
tpnt
->
driverfs_dev_n
[
mode
].
bus_id
,
"%s:%s"
,
SDp
->
sdev_driverfs_dev
.
name
,
name
);
sprintf
(
tpnt
->
driverfs_dev_n
[
mode
].
name
,
"%s%s"
,
SDp
->
sdev_driverfs_dev
.
name
,
name
);
tpnt
->
driverfs_dev_n
[
mode
].
parent
=
&
SDp
->
sdev_driverfs_dev
;
tpnt
->
driverfs_dev_n
[
mode
].
bus
=
&
scsi_driverfs_bus_type
;
tpnt
->
driverfs_dev_n
[
mode
].
driver_data
=
(
void
*
)
__mkdev
(
MAJOR_NR
,
i
+
(
mode
<<
5
)
+
128
);
device_register
(
&
tpnt
->
driverfs_dev_n
[
mode
]);
device_create_file
(
&
tpnt
->
driverfs_dev_n
[
mode
],
&
st_device_type_file
);
device_create_file
(
&
tpnt
->
driverfs_dev_n
[
mode
],
&
st_device_kdev_file
);
tpnt
->
de_n
[
mode
]
=
devfs_register
(
SDp
->
de
,
name
,
DEVFS_FL_DEFAULT
,
MAJOR_NR
,
i
+
(
mode
<<
5
)
+
128
,
...
...
@@ -3738,8 +3788,18 @@ static void st_detach(Scsi_Device * SDp)
for
(
mode
=
0
;
mode
<
ST_NBR_MODES
;
++
mode
)
{
devfs_unregister
(
tpnt
->
de_r
[
mode
]);
tpnt
->
de_r
[
mode
]
=
NULL
;
device_remove_file
(
&
tpnt
->
driverfs_dev_r
[
mode
],
st_device_type_file
.
name
);
device_remove_file
(
&
tpnt
->
driverfs_dev_r
[
mode
],
st_device_kdev_file
.
name
);
put_device
(
&
tpnt
->
driverfs_dev_r
[
mode
]);
devfs_unregister
(
tpnt
->
de_n
[
mode
]);
tpnt
->
de_n
[
mode
]
=
NULL
;
device_remove_file
(
&
tpnt
->
driverfs_dev_n
[
mode
],
st_device_type_file
.
name
);
device_remove_file
(
&
tpnt
->
driverfs_dev_n
[
mode
],
st_device_kdev_file
.
name
);
put_device
(
&
tpnt
->
driverfs_dev_n
[
mode
]);
}
if
(
tpnt
->
buffer
)
{
tpnt
->
buffer
->
orig_sg_segs
=
0
;
...
...
@@ -3770,8 +3830,16 @@ static int __init init_st(void)
verstr
,
st_fixed_buffer_size
,
st_write_threshold
,
st_max_sg_segs
);
if
(
devfs_register_chrdev
(
SCSI_TAPE_MAJOR
,
"st"
,
&
st_fops
)
>=
0
)
return
scsi_register_device
(
&
st_template
);
if
(
devfs_register_chrdev
(
SCSI_TAPE_MAJOR
,
"st"
,
&
st_fops
)
>=
0
)
{
if
(
scsi_register_device
(
&
st_template
)
==
0
)
{
st_template
.
scsi_driverfs_driver
.
name
=
(
char
*
)
st_template
.
tag
;
st_template
.
scsi_driverfs_driver
.
bus
=
&
scsi_driverfs_bus_type
;
driver_register
(
&
st_template
.
scsi_driverfs_driver
);
return
0
;
}
}
printk
(
KERN_ERR
"Unable to get major %d for SCSI tapes
\n
"
,
MAJOR_NR
);
return
1
;
...
...
@@ -3790,6 +3858,7 @@ static void __exit exit_st(void)
kfree
(
scsi_tapes
);
}
st_template
.
dev_max
=
0
;
remove_driver
(
&
st_template
.
scsi_driverfs_driver
);
printk
(
KERN_INFO
"st: Unloaded.
\n
"
);
}
...
...
drivers/scsi/st.h
View file @
5463a13c
...
...
@@ -94,6 +94,8 @@ typedef struct {
int
current_mode
;
devfs_handle_t
de_r
[
ST_NBR_MODES
];
/* Rewind entries */
devfs_handle_t
de_n
[
ST_NBR_MODES
];
/* No-rewind entries */
struct
device
driverfs_dev_r
[
ST_NBR_MODES
];
struct
device
driverfs_dev_n
[
ST_NBR_MODES
];
/* Status variables */
int
partition
;
...
...
drivers/scsi/sun3_NCR5380.c
View file @
5463a13c
...
...
@@ -1217,7 +1217,7 @@ static void NCR5380_dma_complete( struct Scsi_Host *instance )
HOSTNO
,
NCR5380_read
(
BUS_AND_STATUS_REG
),
NCR5380_read
(
STATUS_REG
));
if
((
sun3scsi_dma_finish
(
hostdata
->
connected
->
request
.
cmd
)))
{
if
((
sun3scsi_dma_finish
(
hostdata
->
connected
->
request
->
cmd
)))
{
printk
(
"scsi%d: overrun in UDC counter -- not prepared to deal with this!
\n
"
,
HOSTNO
);
printk
(
"please e-mail sammy@oh.verio.com with a description of how this
\n
"
);
printk
(
"error was produced.
\n
"
);
...
...
@@ -2016,9 +2016,9 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance)
if
((
count
>
SUN3_DMA_MINSIZE
)
&&
(
sun3_dma_setup_done
!=
cmd
))
{
if
((
cmd
->
request
.
cmd
==
0
)
||
(
cmd
->
request
.
cmd
==
1
))
{
if
((
cmd
->
request
->
cmd
==
0
)
||
(
cmd
->
request
->
cmd
==
1
))
{
sun3scsi_dma_setup
(
d
,
count
,
cmd
->
request
.
cmd
);
cmd
->
request
->
cmd
);
sun3_dma_setup_done
=
cmd
;
}
}
...
...
@@ -2628,7 +2628,7 @@ static void NCR5380_reselect (struct Scsi_Host *instance)
!=
tmp
))
{
sun3scsi_dma_setup
(
d
,
count
,
tmp
->
request
.
cmd
);
tmp
->
request
->
cmd
);
sun3_dma_setup_done
=
tmp
;
}
#endif
...
...
drivers/scsi/sun3_scsi.c
View file @
5463a13c
...
...
@@ -518,7 +518,7 @@ static inline unsigned long sun3scsi_dma_residual(struct Scsi_Host *instance)
static
inline
unsigned
long
sun3scsi_dma_xfer_len
(
unsigned
long
wanted
,
Scsi_Cmnd
*
cmd
,
int
write_flag
)
{
if
((
cmd
->
request
.
cmd
==
0
)
||
(
cmd
->
request
.
cmd
==
1
))
if
((
cmd
->
request
->
cmd
==
0
)
||
(
cmd
->
request
->
cmd
==
1
))
return
wanted
;
else
return
0
;
...
...
drivers/scsi/u14-34f.c
View file @
5463a13c
...
...
@@ -1206,7 +1206,7 @@ static inline int do_qcomm(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
if
(
linked_comm
&&
SCpnt
->
device
->
queue_depth
>
2
&&
TLDEV
(
SCpnt
->
device
->
type
))
{
HD
(
j
)
->
cp_stat
[
i
]
=
READY
;
flush_dev
(
SCpnt
->
device
,
SCpnt
->
request
.
sector
,
j
,
FALSE
);
flush_dev
(
SCpnt
->
device
,
SCpnt
->
request
->
sector
,
j
,
FALSE
);
return
0
;
}
...
...
@@ -1529,11 +1529,11 @@ static inline int reorder(unsigned int j, unsigned long cursec,
if
(
!
(
cpp
->
xdir
==
DTD_IN
))
input_only
=
FALSE
;
if
(
SCpnt
->
request
.
sector
<
minsec
)
minsec
=
SCpnt
->
request
.
sector
;
if
(
SCpnt
->
request
.
sector
>
maxsec
)
maxsec
=
SCpnt
->
request
.
sector
;
if
(
SCpnt
->
request
->
sector
<
minsec
)
minsec
=
SCpnt
->
request
->
sector
;
if
(
SCpnt
->
request
->
sector
>
maxsec
)
maxsec
=
SCpnt
->
request
->
sector
;
sl
[
n
]
=
SCpnt
->
request
.
sector
;
ioseek
+=
SCpnt
->
request
.
nr_sectors
;
sl
[
n
]
=
SCpnt
->
request
->
sector
;
ioseek
+=
SCpnt
->
request
->
nr_sectors
;
if
(
!
n
)
continue
;
...
...
@@ -1561,7 +1561,7 @@ static inline int reorder(unsigned int j, unsigned long cursec,
if
(
!
input_only
)
for
(
n
=
0
;
n
<
n_ready
;
n
++
)
{
k
=
il
[
n
];
cpp
=
&
HD
(
j
)
->
cp
[
k
];
SCpnt
=
cpp
->
SCpnt
;
ll
[
n
]
=
SCpnt
->
request
.
nr_sectors
;
pl
[
n
]
=
SCpnt
->
pid
;
ll
[
n
]
=
SCpnt
->
request
->
nr_sectors
;
pl
[
n
]
=
SCpnt
->
pid
;
if
(
!
n
)
continue
;
...
...
@@ -1589,7 +1589,7 @@ static inline int reorder(unsigned int j, unsigned long cursec,
" cur %ld s:%c r:%c rev:%c in:%c ov:%c xd %d.
\n
"
,
(
ihdlr
?
"ihdlr"
:
"qcomm"
),
SCpnt
->
channel
,
SCpnt
->
target
,
SCpnt
->
lun
,
SCpnt
->
pid
,
k
,
flushcount
,
n_ready
,
SCpnt
->
request
.
sector
,
SCpnt
->
request
.
nr_sectors
,
cursec
,
SCpnt
->
request
->
sector
,
SCpnt
->
request
->
nr_sectors
,
cursec
,
YESNO
(
s
),
YESNO
(
r
),
YESNO
(
rev
),
YESNO
(
input_only
),
YESNO
(
overlap
),
cpp
->
xdir
);
}
...
...
@@ -1718,7 +1718,7 @@ static inline void ihdlr(int irq, unsigned int j) {
if
(
linked_comm
&&
SCpnt
->
device
->
queue_depth
>
2
&&
TLDEV
(
SCpnt
->
device
->
type
))
flush_dev
(
SCpnt
->
device
,
SCpnt
->
request
.
sector
,
j
,
TRUE
);
flush_dev
(
SCpnt
->
device
,
SCpnt
->
request
->
sector
,
j
,
TRUE
);
tstatus
=
status_byte
(
spp
->
target_status
);
...
...
fs/partitions/check.c
View file @
5463a13c
...
...
@@ -22,6 +22,7 @@
#include <linux/init.h>
#include <linux/raid/md.h>
#include <linux/buffer_head.h>
/* for invalidate_bdev() */
#include <linux/kmod.h>
#include "check.h"
...
...
@@ -225,6 +226,136 @@ void add_gd_partition(struct gendisk *hd, int minor, int start, int size)
#endif
}
/* Driverfs file support */
static
ssize_t
partition_device_kdev_read
(
struct
device
*
driverfs_dev
,
char
*
page
,
size_t
count
,
loff_t
off
)
{
kdev_t
kdev
;
kdev
.
value
=
(
int
)
driverfs_dev
->
driver_data
;
return
off
?
0
:
sprintf
(
page
,
"%x
\n
"
,
kdev
.
value
);
}
static
struct
driver_file_entry
partition_device_kdev_file
=
{
name:
"kdev"
,
mode:
S_IRUGO
,
show:
partition_device_kdev_read
,
};
static
ssize_t
partition_device_type_read
(
struct
device
*
driverfs_dev
,
char
*
page
,
size_t
count
,
loff_t
off
)
{
return
off
?
0
:
sprintf
(
page
,
"BLK
\n
"
);
}
static
struct
driver_file_entry
partition_device_type_file
=
{
name:
"type"
,
mode:
S_IRUGO
,
show:
partition_device_type_read
,
};
void
driverfs_create_partitions
(
struct
gendisk
*
hd
,
int
minor
)
{
int
pos
=
-
1
;
int
devnum
=
minor
>>
hd
->
minor_shift
;
char
dirname
[
256
];
struct
device
*
parent
=
0
;
int
max_p
;
int
part
;
devfs_handle_t
dir
=
0
;
/* get parent driverfs device structure */
if
(
hd
->
driverfs_dev_arr
)
parent
=
hd
->
driverfs_dev_arr
[
devnum
];
else
/* if driverfs not supported by subsystem, skip partitions */
return
;
/* get parent device node directory name */
if
(
hd
->
de_arr
)
{
dir
=
hd
->
de_arr
[
devnum
];
if
(
dir
)
pos
=
devfs_generate_path
(
dir
,
dirname
,
sizeof
dirname
);
}
if
(
pos
<
0
)
{
disk_name
(
hd
,
minor
,
dirname
);
pos
=
0
;
}
max_p
=
(
1
<<
hd
->
minor_shift
);
/* for all partitions setup parents and device node names */
for
(
part
=
0
;
part
<
max_p
;
part
++
)
{
if
((
part
==
0
)
||
(
hd
->
part
[
minor
+
part
].
nr_sects
>=
1
))
{
struct
device
*
current_driverfs_dev
=
&
hd
->
part
[
minor
+
part
].
hd_driverfs_dev
;
current_driverfs_dev
->
parent
=
parent
;
/* handle disc case */
current_driverfs_dev
->
driver_data
=
(
void
*
)
__mkdev
(
hd
->
major
,
minor
+
part
);
if
(
part
==
0
)
{
if
(
parent
)
{
sprintf
(
current_driverfs_dev
->
name
,
"%sdisc"
,
parent
->
name
);
sprintf
(
current_driverfs_dev
->
bus_id
,
"%s:disc"
,
parent
->
bus_id
);
}
else
{
sprintf
(
current_driverfs_dev
->
name
,
"disc"
);
sprintf
(
current_driverfs_dev
->
bus_id
,
"disc"
);
}
}
else
{
/* this is a partition */
if
(
parent
)
{
sprintf
(
current_driverfs_dev
->
name
,
"%spart%d"
,
parent
->
name
,
part
);
sprintf
(
current_driverfs_dev
->
bus_id
,
"%s:p%d"
,
parent
->
bus_id
,
part
);
}
else
{
sprintf
(
current_driverfs_dev
->
name
,
"part%d"
,
part
);
sprintf
(
current_driverfs_dev
->
bus_id
,
"p%d"
,
part
);
}
}
if
(
parent
)
current_driverfs_dev
->
bus
=
parent
->
bus
;
device_register
(
current_driverfs_dev
);
device_create_file
(
current_driverfs_dev
,
&
partition_device_type_file
);
device_create_file
(
current_driverfs_dev
,
&
partition_device_kdev_file
);
}
}
return
;
}
void
driverfs_remove_partitions
(
struct
gendisk
*
hd
,
int
minor
)
{
int
max_p
;
int
part
;
struct
device
*
current_driverfs_dev
;
max_p
=
(
1
<<
hd
->
minor_shift
);
/* for all parts setup parent relationships and device node names */
for
(
part
=
1
;
part
<
max_p
;
part
++
)
{
if
((
hd
->
part
[
minor
+
part
].
nr_sects
>=
1
))
{
current_driverfs_dev
=
&
hd
->
part
[
minor
+
part
].
hd_driverfs_dev
;
device_remove_file
(
current_driverfs_dev
,
partition_device_type_file
.
name
);
device_remove_file
(
current_driverfs_dev
,
partition_device_kdev_file
.
name
);
put_device
(
current_driverfs_dev
);
}
}
current_driverfs_dev
=
&
hd
->
part
[
minor
].
hd_driverfs_dev
;
device_remove_file
(
current_driverfs_dev
,
partition_device_type_file
.
name
);
device_remove_file
(
current_driverfs_dev
,
partition_device_kdev_file
.
name
);
put_device
(
current_driverfs_dev
);
return
;
}
static
void
check_partition
(
struct
gendisk
*
hd
,
kdev_t
dev
,
int
first_part_minor
)
{
devfs_handle_t
de
=
NULL
;
...
...
@@ -285,6 +416,13 @@ static void check_partition(struct gendisk *hd, kdev_t dev, int first_part_minor
truncate_inode_pages
(
bdev
->
bd_inode
->
i_mapping
,
0
);
bdput
(
bdev
);
i
=
first_part_minor
-
1
;
/* Setup driverfs tree */
if
(
hd
->
sizes
)
driverfs_create_partitions
(
hd
,
i
);
else
driverfs_remove_partitions
(
hd
,
i
);
devfs_register_partitions
(
hd
,
i
,
hd
->
sizes
?
0
:
1
);
}
...
...
include/linux/cdrom.h
View file @
5463a13c
...
...
@@ -716,6 +716,7 @@ struct request_sense {
#ifdef __KERNEL__
#include <linux/devfs_fs_kernel.h>
#include <linux/device.h>
struct
cdrom_write_settings
{
unsigned
char
fpacket
;
/* fixed/variable packets */
...
...
@@ -730,6 +731,7 @@ struct cdrom_device_info {
struct
cdrom_device_info
*
next
;
/* next device_info for this major */
void
*
handle
;
/* driver-dependent data */
devfs_handle_t
de
;
/* real driver should create this */
struct
device
cdrom_driverfs_dev
;
/* driverfs implementation */
int
number
;
/* generic driver updates this */
/* specifications */
kdev_t
dev
;
/* device number */
...
...
include/linux/genhd.h
View file @
5463a13c
...
...
@@ -12,6 +12,7 @@
#include <linux/config.h>
#include <linux/types.h>
#include <linux/major.h>
#include <linux/device.h>
enum
{
/* These three have identical behaviour; use the second one if DOS fdisk gets
...
...
@@ -62,6 +63,7 @@ struct hd_struct {
unsigned
long
nr_sects
;
devfs_handle_t
de
;
/* primary (master) devfs entry */
int
number
;
/* stupid old code wastes space */
struct
device
hd_driverfs_dev
;
/* support driverfs hiearchy */
};
#define GENHD_FL_REMOVABLE 1
...
...
@@ -80,6 +82,7 @@ struct gendisk {
struct
block_device_operations
*
fops
;
devfs_handle_t
*
de_arr
;
/* one per physical disc */
struct
device
**
driverfs_dev_arr
;
/* support driverfs hierarchy */
char
*
flags
;
/* one per physical disc */
};
...
...
@@ -241,6 +244,7 @@ char *disk_name (struct gendisk *hd, int minor, char *buf);
extern
void
devfs_register_partitions
(
struct
gendisk
*
dev
,
int
minor
,
int
unregister
);
extern
void
driverfs_remove_partitions
(
struct
gendisk
*
hd
,
int
minor
);
static
inline
unsigned
int
disk_index
(
kdev_t
dev
)
{
...
...
kernel/ksyms.c
View file @
5463a13c
...
...
@@ -334,6 +334,7 @@ EXPORT_SYMBOL(bdev_read_only);
EXPORT_SYMBOL
(
set_device_ro
);
EXPORT_SYMBOL
(
bmap
);
EXPORT_SYMBOL
(
devfs_register_partitions
);
EXPORT_SYMBOL
(
driverfs_remove_partitions
);
EXPORT_SYMBOL
(
blkdev_open
);
EXPORT_SYMBOL
(
blkdev_get
);
EXPORT_SYMBOL
(
blkdev_put
);
...
...
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