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
c9761c4d
Commit
c9761c4d
authored
Jul 02, 2002
by
James Bottomley
Browse files
Options
Browse Files
Download
Plain Diff
Merge
parents
62420867
cc236b9a
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
807 additions
and
7 deletions
+807
-7
drivers/cdrom/cdrom.c
drivers/cdrom/cdrom.c
+5
-0
drivers/scsi/hosts.h
drivers/scsi/hosts.h
+7
-0
drivers/scsi/scsi.c
drivers/scsi/scsi.c
+39
-0
drivers/scsi/scsi.h
drivers/scsi/scsi.h
+3
-0
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
+19
-3
drivers/scsi/sg.c
drivers/scsi/sg.c
+49
-1
drivers/scsi/sr.c
drivers/scsi/sr.c
+49
-1
drivers/scsi/st.c
drivers/scsi/st.c
+71
-2
drivers/scsi/st.h
drivers/scsi/st.h
+2
-0
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 @
c9761c4d
...
@@ -431,6 +431,11 @@ int unregister_cdrom(struct cdrom_device_info *unreg)
...
@@ -431,6 +431,11 @@ int unregister_cdrom(struct cdrom_device_info *unreg)
topCdromPtr
=
cdi
->
next
;
topCdromPtr
=
cdi
->
next
;
cdi
->
ops
->
n_minors
--
;
cdi
->
ops
->
n_minors
--
;
devfs_unregister
(
cdi
->
de
);
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
);
devfs_dealloc_unique_number
(
&
cdrom_numspace
,
cdi
->
number
);
cdinfo
(
CD_REG_UNREG
,
"drive
\"
/dev/%s
\"
unregistered
\n
"
,
cdi
->
name
);
cdinfo
(
CD_REG_UNREG
,
"drive
\"
/dev/%s
\"
unregistered
\n
"
,
cdi
->
name
);
return
0
;
return
0
;
...
...
drivers/scsi/hosts.h
View file @
c9761c4d
...
@@ -425,6 +425,11 @@ struct Scsi_Host
...
@@ -425,6 +425,11 @@ struct Scsi_Host
*/
*/
struct
pci_dev
*
pci_dev
;
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
* We should ensure that this is aligned, both for better performance
* and also because some compilers (m68k) don't automatically force
* and also because some compilers (m68k) don't automatically force
...
@@ -485,6 +490,7 @@ static inline void scsi_set_pci_device(struct Scsi_Host *SHpnt,
...
@@ -485,6 +490,7 @@ static inline void scsi_set_pci_device(struct Scsi_Host *SHpnt,
struct
pci_dev
*
pdev
)
struct
pci_dev
*
pdev
)
{
{
SHpnt
->
pci_dev
=
pdev
;
SHpnt
->
pci_dev
=
pdev
;
SHpnt
->
host_driverfs_dev
.
parent
=&
pdev
->
dev
;
}
}
...
@@ -523,6 +529,7 @@ struct Scsi_Device_Template
...
@@ -523,6 +529,7 @@ struct Scsi_Device_Template
void
(
*
detach
)(
Scsi_Device
*
);
void
(
*
detach
)(
Scsi_Device
*
);
int
(
*
init_command
)(
Scsi_Cmnd
*
);
/* Used by new queueing code.
int
(
*
init_command
)(
Scsi_Cmnd
*
);
/* Used by new queueing code.
Selects command for blkdevs */
Selects command for blkdevs */
struct
device_driver
scsi_driverfs_driver
;
};
};
void
scsi_initialize_queue
(
Scsi_Device
*
SDpnt
,
struct
Scsi_Host
*
SHpnt
);
void
scsi_initialize_queue
(
Scsi_Device
*
SDpnt
,
struct
Scsi_Host
*
SHpnt
);
...
...
drivers/scsi/scsi.c
View file @
c9761c4d
...
@@ -1950,6 +1950,11 @@ int scsi_register_host(Scsi_Host_Template * tpnt)
...
@@ -1950,6 +1950,11 @@ int scsi_register_host(Scsi_Host_Template * tpnt)
}
}
printk
(
KERN_INFO
"scsi%d : %s
\n
"
,
/* And print a little message */
printk
(
KERN_INFO
"scsi%d : %s
\n
"
,
/* And print a little message */
shpnt
->
host_no
,
name
);
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
);
}
}
}
}
...
@@ -1958,6 +1963,8 @@ int scsi_register_host(Scsi_Host_Template * tpnt)
...
@@ -1958,6 +1963,8 @@ int scsi_register_host(Scsi_Host_Template * tpnt)
*/
*/
for
(
shpnt
=
scsi_hostlist
;
shpnt
;
shpnt
=
shpnt
->
next
)
{
for
(
shpnt
=
scsi_hostlist
;
shpnt
;
shpnt
=
shpnt
->
next
)
{
if
(
shpnt
->
hostt
==
tpnt
)
{
if
(
shpnt
->
hostt
==
tpnt
)
{
/* first register parent with driverfs */
device_register
(
&
shpnt
->
host_driverfs_dev
);
scan_scsis
(
shpnt
,
0
,
0
,
0
,
0
);
scan_scsis
(
shpnt
,
0
,
0
,
0
,
0
);
if
(
shpnt
->
select_queue_depths
!=
NULL
)
{
if
(
shpnt
->
select_queue_depths
!=
NULL
)
{
(
shpnt
->
select_queue_depths
)
(
shpnt
,
shpnt
->
host_queue
);
(
shpnt
->
select_queue_depths
)
(
shpnt
,
shpnt
->
host_queue
);
...
@@ -2113,6 +2120,7 @@ int scsi_unregister_host(Scsi_Host_Template * tpnt)
...
@@ -2113,6 +2120,7 @@ int scsi_unregister_host(Scsi_Host_Template * tpnt)
goto
err_out
;
goto
err_out
;
}
}
devfs_unregister
(
SDpnt
->
de
);
devfs_unregister
(
SDpnt
->
de
);
put_device
(
&
SDpnt
->
sdev_driverfs_dev
);
}
}
}
}
...
@@ -2163,6 +2171,7 @@ int scsi_unregister_host(Scsi_Host_Template * tpnt)
...
@@ -2163,6 +2171,7 @@ int scsi_unregister_host(Scsi_Host_Template * tpnt)
/* Remove the /proc/scsi directory entry */
/* Remove the /proc/scsi directory entry */
sprintf
(
name
,
"%d"
,
shpnt
->
host_no
);
sprintf
(
name
,
"%d"
,
shpnt
->
host_no
);
remove_proc_entry
(
name
,
tpnt
->
proc_dir
);
remove_proc_entry
(
name
,
tpnt
->
proc_dir
);
put_device
(
&
shpnt
->
host_driverfs_dev
);
if
(
tpnt
->
release
)
if
(
tpnt
->
release
)
(
*
tpnt
->
release
)
(
shpnt
);
(
*
tpnt
->
release
)
(
shpnt
);
else
{
else
{
...
@@ -2511,6 +2520,34 @@ void scsi_free_sgtable(struct scatterlist *sgl, int index)
...
@@ -2511,6 +2520,34 @@ void scsi_free_sgtable(struct scatterlist *sgl, int index)
mempool_free
(
sgl
,
sgp
->
pool
);
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
)
static
int
__init
init_scsi
(
void
)
{
{
struct
proc_dir_entry
*
generic
;
struct
proc_dir_entry
*
generic
;
...
@@ -2557,6 +2594,8 @@ static int __init init_scsi(void)
...
@@ -2557,6 +2594,8 @@ static int __init init_scsi(void)
printk
(
KERN_INFO
"scsi: host order: %s
\n
"
,
scsihosts
);
printk
(
KERN_INFO
"scsi: host order: %s
\n
"
,
scsihosts
);
scsi_host_no_init
(
scsihosts
);
scsi_host_no_init
(
scsihosts
);
bus_register
(
&
scsi_driverfs_bus_type
);
return
0
;
return
0
;
}
}
...
...
drivers/scsi/scsi.h
View file @
c9761c4d
...
@@ -417,6 +417,8 @@ extern unsigned int scsi_need_isa_buffer; /* True if some devices need indirecti
...
@@ -417,6 +417,8 @@ extern unsigned int scsi_need_isa_buffer; /* True if some devices need indirecti
extern
volatile
int
in_scan_scsis
;
extern
volatile
int
in_scan_scsis
;
extern
const
unsigned
char
scsi_command_size
[
8
];
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
* These are the error handling functions defined in scsi_error.c
...
@@ -623,6 +625,7 @@ struct scsi_device {
...
@@ -623,6 +625,7 @@ struct scsi_device {
// Flag to allow revalidate to succeed in sd_open
// Flag to allow revalidate to succeed in sd_open
int
allow_revalidate
;
int
allow_revalidate
;
struct
device
sdev_driverfs_dev
;
};
};
...
...
drivers/scsi/scsi_scan.c
View file @
c9761c4d
...
@@ -54,6 +54,7 @@ static void scan_scsis_target(unsigned int channel, unsigned int dev,
...
@@ -54,6 +54,7 @@ static void scan_scsis_target(unsigned int channel, unsigned int dev,
char
*
scsi_result
);
char
*
scsi_result
);
static
int
find_lun0_scsi_level
(
unsigned
int
channel
,
unsigned
int
dev
,
static
int
find_lun0_scsi_level
(
unsigned
int
channel
,
unsigned
int
dev
,
struct
Scsi_Host
*
shpnt
);
struct
Scsi_Host
*
shpnt
);
static
void
scsi_load_identifier
(
Scsi_Device
*
SDpnt
,
Scsi_Request
*
SRpnt
);
struct
dev_info
{
struct
dev_info
{
const
char
*
vendor
;
const
char
*
vendor
;
...
@@ -288,6 +289,31 @@ static int scsilun_to_int(ScsiLun *scsilun_pnt)
...
@@ -288,6 +289,31 @@ static int scsilun_to_int(ScsiLun *scsilun_pnt)
}
}
#endif
#endif
/* Driverfs file content handlers */
static
ssize_t
scsi_device_type_read
(
struct
device
*
driverfs_dev
,
char
*
page
,
size_t
count
,
loff_t
off
)
{
struct
scsi_device
*
SDpnt
=
list_entry
(
driverfs_dev
,
struct
scsi_device
,
sdev_driverfs_dev
);
if
((
SDpnt
->
type
<=
MAX_SCSI_DEVICE_CODE
)
&&
(
scsi_device_types
[(
int
)
SDpnt
->
type
]
!=
NULL
))
return
off
?
0
:
sprintf
(
page
,
"%s
\n
"
,
scsi_device_types
[(
int
)
SDpnt
->
type
]);
else
return
off
?
0
:
sprintf
(
page
,
"UNKNOWN
\n
"
);
return
0
;
}
static
struct
driver_file_entry
scsi_device_type_file
=
{
name:
"type"
,
mode:
S_IRUGO
,
show:
scsi_device_type_read
,
};
/* end content handlers */
static
void
print_inquiry
(
unsigned
char
*
data
)
static
void
print_inquiry
(
unsigned
char
*
data
)
{
{
int
i
;
int
i
;
...
@@ -786,6 +812,22 @@ static int scan_scsis_single(unsigned int channel, unsigned int dev,
...
@@ -786,6 +812,22 @@ static int scan_scsis_single(unsigned int channel, unsigned int dev,
print_inquiry
(
scsi_result
);
print_inquiry
(
scsi_result
);
/* interrogate scsi target to provide device identifier */
scsi_load_identifier
(
SDpnt
,
SRpnt
);
/* create driverfs files */
sprintf
(
SDpnt
->
sdev_driverfs_dev
.
bus_id
,
"%d:%d:%d:%d"
,
SDpnt
->
host
->
host_no
,
SDpnt
->
channel
,
SDpnt
->
id
,
SDpnt
->
lun
);
SDpnt
->
sdev_driverfs_dev
.
parent
=
&
SDpnt
->
host
->
host_driverfs_dev
;
SDpnt
->
sdev_driverfs_dev
.
bus
=
&
scsi_driverfs_bus_type
;
device_register
(
&
SDpnt
->
sdev_driverfs_dev
);
/* Create driverfs file entries */
device_create_file
(
&
SDpnt
->
sdev_driverfs_dev
,
&
scsi_device_type_file
);
sprintf
(
devname
,
"host%d/bus%d/target%d/lun%d"
,
sprintf
(
devname
,
"host%d/bus%d/target%d/lun%d"
,
SDpnt
->
host
->
host_no
,
SDpnt
->
channel
,
SDpnt
->
id
,
SDpnt
->
lun
);
SDpnt
->
host
->
host_no
,
SDpnt
->
channel
,
SDpnt
->
id
,
SDpnt
->
lun
);
if
(
SDpnt
->
de
)
printk
(
"DEBUG: dir:
\"
%s
\"
already exists
\n
"
,
devname
);
if
(
SDpnt
->
de
)
printk
(
"DEBUG: dir:
\"
%s
\"
already exists
\n
"
,
devname
);
...
@@ -1306,3 +1348,374 @@ static int find_lun0_scsi_level(unsigned int channel, unsigned int dev,
...
@@ -1306,3 +1348,374 @@ static int find_lun0_scsi_level(unsigned int channel, unsigned int dev,
/* haven't found lun0, should send INQUIRY but take easy route */
/* haven't found lun0, should send INQUIRY but take easy route */
return
res
;
return
res
;
}
}
#define SCSI_UID_DEV_ID 'U'
#define SCSI_UID_SER_NUM 'S'
#define SCSI_UID_UNKNOWN 'Z'
unsigned
char
*
scsi_get_evpd_page
(
Scsi_Device
*
SDpnt
,
Scsi_Request
*
SRpnt
)
{
unsigned
char
*
evpd_page
=
NULL
;
unsigned
char
*
scsi_cmd
=
NULL
;
int
lun
=
SDpnt
->
lun
;
int
scsi_level
=
SDpnt
->
scsi_level
;
evpd_page
=
kmalloc
(
255
,
(
SDpnt
->
host
->
unchecked_isa_dma
?
GFP_DMA
:
GFP_ATOMIC
));
if
(
!
evpd_page
)
return
NULL
;
scsi_cmd
=
kmalloc
(
MAX_COMMAND_SIZE
,
GFP_ATOMIC
);
if
(
!
scsi_cmd
)
{
kfree
(
evpd_page
);
return
NULL
;
}
/* Use vital product pages to determine serial number */
/* Try Supported vital product data pages 0x00 first */
scsi_cmd
[
0
]
=
INQUIRY
;
if
((
lun
>
0
)
&&
(
scsi_level
<=
SCSI_2
))
scsi_cmd
[
1
]
=
((
lun
<<
5
)
&
0xe0
)
|
0x01
;
else
scsi_cmd
[
1
]
=
0x01
;
/* SCSI_3 and higher, don't touch */
scsi_cmd
[
2
]
=
0x00
;
scsi_cmd
[
3
]
=
0
;
scsi_cmd
[
4
]
=
255
;
scsi_cmd
[
5
]
=
0
;
SRpnt
->
sr_cmd_len
=
0
;
SRpnt
->
sr_sense_buffer
[
0
]
=
0
;
SRpnt
->
sr_sense_buffer
[
2
]
=
0
;
SRpnt
->
sr_data_direction
=
SCSI_DATA_READ
;
scsi_wait_req
(
SRpnt
,
(
void
*
)
scsi_cmd
,
(
void
*
)
evpd_page
,
255
,
SCSI_TIMEOUT
+
4
*
HZ
,
3
);
if
(
SRpnt
->
sr_result
)
{
kfree
(
scsi_cmd
);
kfree
(
evpd_page
);
return
NULL
;
}
/* check to see if response was truncated */
if
(
evpd_page
[
3
]
>
255
)
{
int
max_lgth
=
evpd_page
[
3
]
+
4
;
kfree
(
evpd_page
);
evpd_page
=
kmalloc
(
max_lgth
,
(
SDpnt
->
host
->
unchecked_isa_dma
?
GFP_DMA
:
GFP_ATOMIC
));
if
(
!
evpd_page
)
{
kfree
(
scsi_cmd
);
return
NULL
;
}
memset
(
scsi_cmd
,
0
,
MAX_COMMAND_SIZE
);
scsi_cmd
[
0
]
=
INQUIRY
;
if
((
lun
>
0
)
&&
(
scsi_level
<=
SCSI_2
))
scsi_cmd
[
1
]
=
((
lun
<<
5
)
&
0xe0
)
|
0x01
;
else
scsi_cmd
[
1
]
=
0x01
;
/* SCSI_3 and higher, don't touch */
scsi_cmd
[
2
]
=
0x00
;
scsi_cmd
[
3
]
=
0
;
scsi_cmd
[
4
]
=
max_lgth
;
scsi_cmd
[
5
]
=
0
;
SRpnt
->
sr_cmd_len
=
0
;
SRpnt
->
sr_sense_buffer
[
0
]
=
0
;
SRpnt
->
sr_sense_buffer
[
2
]
=
0
;
SRpnt
->
sr_data_direction
=
SCSI_DATA_READ
;
scsi_wait_req
(
SRpnt
,
(
void
*
)
scsi_cmd
,
(
void
*
)
evpd_page
,
max_lgth
,
SCSI_TIMEOUT
+
4
*
HZ
,
3
);
if
(
SRpnt
->
sr_result
)
{
kfree
(
scsi_cmd
);
kfree
(
evpd_page
);
return
NULL
;
}
}
kfree
(
scsi_cmd
);
/* some ill behaved devices return the std inquiry here rather than
the evpd data. snoop the data to verify */
if
(
evpd_page
[
3
]
>
16
)
{
/* if vend id appears in the evpd page assume evpd is invalid */
if
(
!
strncmp
(
&
evpd_page
[
8
],
SDpnt
->
vendor
,
8
))
{
kfree
(
evpd_page
);
return
NULL
;
}
}
return
evpd_page
;
}
int
scsi_get_deviceid
(
Scsi_Device
*
SDpnt
,
Scsi_Request
*
SRpnt
)
{
unsigned
char
*
id_page
=
NULL
;
unsigned
char
*
scsi_cmd
=
NULL
;
int
scnt
,
i
,
j
,
idtype
;
char
*
id
=
SDpnt
->
sdev_driverfs_dev
.
name
;
int
lun
=
SDpnt
->
lun
;
int
scsi_level
=
SDpnt
->
scsi_level
;
id_page
=
kmalloc
(
255
,
(
SDpnt
->
host
->
unchecked_isa_dma
?
GFP_DMA
:
GFP_ATOMIC
));
if
(
!
id_page
)
return
0
;
scsi_cmd
=
kmalloc
(
MAX_COMMAND_SIZE
,
GFP_ATOMIC
);
if
(
!
scsi_cmd
)
goto
leave
;
/* Use vital product pages to determine serial number */
/* Try Supported vital product data pages 0x00 first */
scsi_cmd
[
0
]
=
INQUIRY
;
if
((
lun
>
0
)
&&
(
scsi_level
<=
SCSI_2
))
scsi_cmd
[
1
]
=
((
lun
<<
5
)
&
0xe0
)
|
0x01
;
else
scsi_cmd
[
1
]
=
0x01
;
/* SCSI_3 and higher, don't touch */
scsi_cmd
[
2
]
=
0x83
;
scsi_cmd
[
3
]
=
0
;
scsi_cmd
[
4
]
=
255
;
scsi_cmd
[
5
]
=
0
;
SRpnt
->
sr_cmd_len
=
0
;
SRpnt
->
sr_sense_buffer
[
0
]
=
0
;
SRpnt
->
sr_sense_buffer
[
2
]
=
0
;
SRpnt
->
sr_data_direction
=
SCSI_DATA_READ
;
scsi_wait_req
(
SRpnt
,
(
void
*
)
scsi_cmd
,
(
void
*
)
id_page
,
255
,
SCSI_TIMEOUT
+
4
*
HZ
,
3
);
if
(
SRpnt
->
sr_result
)
{
kfree
(
scsi_cmd
);
goto
leave
;
}
/* check to see if response was truncated */
if
(
id_page
[
3
]
>
255
)
{
int
max_lgth
=
id_page
[
3
]
+
4
;
kfree
(
id_page
);
id_page
=
kmalloc
(
max_lgth
,
(
SDpnt
->
host
->
unchecked_isa_dma
?
GFP_DMA
:
GFP_ATOMIC
));
if
(
!
id_page
)
{
kfree
(
scsi_cmd
);
return
0
;
}
memset
(
scsi_cmd
,
0
,
MAX_COMMAND_SIZE
);
scsi_cmd
[
0
]
=
INQUIRY
;
if
((
lun
>
0
)
&&
(
scsi_level
<=
SCSI_2
))
scsi_cmd
[
1
]
=
((
lun
<<
5
)
&
0xe0
)
|
0x01
;
else
scsi_cmd
[
1
]
=
0x01
;
/* SCSI_3 and higher, don't touch */
scsi_cmd
[
2
]
=
0x83
;
scsi_cmd
[
3
]
=
0
;
scsi_cmd
[
4
]
=
max_lgth
;
scsi_cmd
[
5
]
=
0
;
SRpnt
->
sr_cmd_len
=
0
;
SRpnt
->
sr_sense_buffer
[
0
]
=
0
;
SRpnt
->
sr_sense_buffer
[
2
]
=
0
;
SRpnt
->
sr_data_direction
=
SCSI_DATA_READ
;
scsi_wait_req
(
SRpnt
,
(
void
*
)
scsi_cmd
,
(
void
*
)
id_page
,
max_lgth
,
SCSI_TIMEOUT
+
4
*
HZ
,
3
);
if
(
SRpnt
->
sr_result
)
{
kfree
(
scsi_cmd
);
goto
leave
;
}
}
kfree
(
scsi_cmd
);
idtype
=
3
;
while
(
idtype
>
0
)
{
for
(
scnt
=
4
;
scnt
<=
id_page
[
3
]
+
3
;
scnt
+=
id_page
[
scnt
+
3
]
+
4
)
{
if
((
id_page
[
scnt
+
1
]
&
0x0f
)
!=
idtype
)
{
continue
;
}
if
((
id_page
[
scnt
]
&
0x0f
)
==
2
)
{
for
(
i
=
scnt
+
4
,
j
=
1
;
i
<
scnt
+
4
+
id_page
[
scnt
+
3
];
i
++
)
{
if
(
id_page
[
i
]
>
0x20
)
{
if
(
j
==
DEVICE_NAME_SIZE
)
{
memset
(
id
,
0
,
DEVICE_NAME_SIZE
);
break
;
}
id
[
j
++
]
=
id_page
[
i
];
}
}
}
else
if
((
id_page
[
scnt
]
&
0x0f
)
==
1
)
{
static
const
char
hex_str
[]
=
"0123456789abcdef"
;
for
(
i
=
scnt
+
4
,
j
=
1
;
i
<
scnt
+
4
+
id_page
[
scnt
+
3
];
i
++
)
{
if
((
j
+
1
)
==
DEVICE_NAME_SIZE
)
{
memset
(
id
,
0
,
DEVICE_NAME_SIZE
);
break
;
}
id
[
j
++
]
=
hex_str
[(
id_page
[
i
]
&
0xf0
)
>>
4
];
id
[
j
++
]
=
hex_str
[
id_page
[
i
]
&
0x0f
];
}
}
if
(
id
[
1
]
!=
0
)
goto
leave
;
}
idtype
--
;
}
leave:
kfree
(
id_page
);
if
(
id
[
1
]
!=
0
)
{
id
[
0
]
=
SCSI_UID_DEV_ID
;
return
1
;
}
return
0
;
}
int
scsi_get_serialnumber
(
Scsi_Device
*
SDpnt
,
Scsi_Request
*
SRpnt
)
{
unsigned
char
*
serialnumber_page
=
NULL
;
unsigned
char
*
scsi_cmd
=
NULL
;
int
lun
=
SDpnt
->
lun
;
int
scsi_level
=
SDpnt
->
scsi_level
;
int
i
,
j
;
serialnumber_page
=
kmalloc
(
255
,
(
SDpnt
->
host
->
unchecked_isa_dma
?
GFP_DMA
:
GFP_ATOMIC
));
if
(
!
serialnumber_page
)
return
0
;
scsi_cmd
=
kmalloc
(
MAX_COMMAND_SIZE
,
GFP_ATOMIC
);
if
(
!
scsi_cmd
)
goto
leave
;
/* Use vital product pages to determine serial number */
/* Try Supported vital product data pages 0x00 first */
scsi_cmd
[
0
]
=
INQUIRY
;
if
((
lun
>
0
)
&&
(
scsi_level
<=
SCSI_2
))
scsi_cmd
[
1
]
=
((
lun
<<
5
)
&
0xe0
)
|
0x01
;
else
scsi_cmd
[
1
]
=
0x01
;
/* SCSI_3 and higher, don't touch */
scsi_cmd
[
2
]
=
0x80
;
scsi_cmd
[
3
]
=
0
;
scsi_cmd
[
4
]
=
255
;
scsi_cmd
[
5
]
=
0
;
SRpnt
->
sr_cmd_len
=
0
;
SRpnt
->
sr_sense_buffer
[
0
]
=
0
;
SRpnt
->
sr_sense_buffer
[
2
]
=
0
;
SRpnt
->
sr_data_direction
=
SCSI_DATA_READ
;
scsi_wait_req
(
SRpnt
,
(
void
*
)
scsi_cmd
,
(
void
*
)
serialnumber_page
,
255
,
SCSI_TIMEOUT
+
4
*
HZ
,
3
);
if
(
SRpnt
->
sr_result
)
{
kfree
(
scsi_cmd
);
goto
leave
;
}
/* check to see if response was truncated */
if
(
serialnumber_page
[
3
]
>
255
)
{
int
max_lgth
=
serialnumber_page
[
3
]
+
4
;
kfree
(
serialnumber_page
);
serialnumber_page
=
kmalloc
(
max_lgth
,
(
SDpnt
->
host
->
unchecked_isa_dma
?
GFP_DMA
:
GFP_ATOMIC
));
if
(
!
serialnumber_page
)
{
kfree
(
scsi_cmd
);
return
0
;
}
memset
(
scsi_cmd
,
0
,
MAX_COMMAND_SIZE
);
scsi_cmd
[
0
]
=
INQUIRY
;
if
((
lun
>
0
)
&&
(
scsi_level
<=
SCSI_2
))
scsi_cmd
[
1
]
=
((
lun
<<
5
)
&
0xe0
)
|
0x01
;
else
scsi_cmd
[
1
]
=
0x01
;
/* SCSI_3 and higher, don't touch */
scsi_cmd
[
2
]
=
0x80
;
scsi_cmd
[
3
]
=
0
;
scsi_cmd
[
4
]
=
max_lgth
;
scsi_cmd
[
5
]
=
0
;
SRpnt
->
sr_cmd_len
=
0
;
SRpnt
->
sr_sense_buffer
[
0
]
=
0
;
SRpnt
->
sr_sense_buffer
[
2
]
=
0
;
SRpnt
->
sr_data_direction
=
SCSI_DATA_READ
;
scsi_wait_req
(
SRpnt
,
(
void
*
)
scsi_cmd
,
(
void
*
)
serialnumber_page
,
max_lgth
,
SCSI_TIMEOUT
+
4
*
HZ
,
3
);
if
(
SRpnt
->
sr_result
)
{
kfree
(
scsi_cmd
);
goto
leave
;
}
}
kfree
(
scsi_cmd
);
SDpnt
->
sdev_driverfs_dev
.
name
[
0
]
=
SCSI_UID_SER_NUM
;
for
(
i
=
0
,
j
=
1
;
i
<
serialnumber_page
[
3
];
i
++
)
{
if
(
serialnumber_page
[
4
+
i
]
>
0x20
)
SDpnt
->
sdev_driverfs_dev
.
name
[
j
++
]
=
serialnumber_page
[
4
+
i
];
}
for
(
i
=
0
,
j
=
strlen
(
SDpnt
->
sdev_driverfs_dev
.
name
);
i
<
8
;
i
++
)
{
if
(
SDpnt
->
vendor
[
i
]
>
0x20
)
{
SDpnt
->
sdev_driverfs_dev
.
name
[
j
++
]
=
SDpnt
->
vendor
[
i
];
}
}
kfree
(
serialnumber_page
);
return
1
;
leave:
memset
(
SDpnt
->
sdev_driverfs_dev
.
name
,
0
,
DEVICE_NAME_SIZE
);
kfree
(
serialnumber_page
);
return
0
;
}
int
scsi_get_default_name
(
Scsi_Device
*
SDpnt
)
{
int
i
,
j
;
SDpnt
->
sdev_driverfs_dev
.
name
[
0
]
=
SCSI_UID_UNKNOWN
;
for
(
i
=
0
,
j
=
1
;
i
<
8
;
i
++
)
{
if
(
SDpnt
->
vendor
[
i
]
>
0x20
)
{
SDpnt
->
sdev_driverfs_dev
.
name
[
j
++
]
=
SDpnt
->
vendor
[
i
];
}
}
for
(
i
=
0
,
j
=
strlen
(
SDpnt
->
sdev_driverfs_dev
.
name
);
i
<
16
;
i
++
)
{
if
(
SDpnt
->
model
[
i
]
>
0x20
)
{
SDpnt
->
sdev_driverfs_dev
.
name
[
j
++
]
=
SDpnt
->
model
[
i
];
}
}
for
(
i
=
0
,
j
=
strlen
(
SDpnt
->
sdev_driverfs_dev
.
name
);
i
<
4
;
i
++
)
{
if
(
SDpnt
->
rev
[
i
]
>
0x20
)
{
SDpnt
->
sdev_driverfs_dev
.
name
[
j
++
]
=
SDpnt
->
rev
[
i
];
}
}
return
1
;
}
static
void
scsi_load_identifier
(
Scsi_Device
*
SDpnt
,
Scsi_Request
*
SRpnt
)
{
unsigned
char
*
evpd_page
=
NULL
;
int
cnt
;
memset
(
SDpnt
->
sdev_driverfs_dev
.
name
,
0
,
DEVICE_NAME_SIZE
);
evpd_page
=
scsi_get_evpd_page
(
SDpnt
,
SRpnt
);
if
(
!
evpd_page
)
{
/* try to obtain serial number anyway */
if
(
!
scsi_get_serialnumber
(
SDpnt
,
SRpnt
))
goto
leave
;
goto
leave
;
}
for
(
cnt
=
4
;
cnt
<=
evpd_page
[
3
]
+
3
;
cnt
++
)
{
if
(
evpd_page
[
cnt
]
==
0x83
)
{
if
(
scsi_get_deviceid
(
SDpnt
,
SRpnt
))
goto
leave
;
}
}
for
(
cnt
=
4
;
cnt
<=
evpd_page
[
3
]
+
3
;
cnt
++
)
{
if
(
evpd_page
[
cnt
]
==
0x80
)
{
if
(
scsi_get_serialnumber
(
SDpnt
,
SRpnt
))
goto
leave
;
}
}
leave:
if
(
SDpnt
->
sdev_driverfs_dev
.
name
[
0
]
==
0
)
scsi_get_default_name
(
SDpnt
);
if
(
evpd_page
)
kfree
(
evpd_page
);
return
;
}
drivers/scsi/scsi_syms.c
View file @
c9761c4d
...
@@ -101,3 +101,8 @@ extern void scsi_add_timer(Scsi_Cmnd *, int, void ((*) (Scsi_Cmnd *)));
...
@@ -101,3 +101,8 @@ extern void scsi_add_timer(Scsi_Cmnd *, int, void ((*) (Scsi_Cmnd *)));
extern
int
scsi_delete_timer
(
Scsi_Cmnd
*
);
extern
int
scsi_delete_timer
(
Scsi_Cmnd
*
);
EXPORT_SYMBOL
(
scsi_add_timer
);
EXPORT_SYMBOL
(
scsi_add_timer
);
EXPORT_SYMBOL
(
scsi_delete_timer
);
EXPORT_SYMBOL
(
scsi_delete_timer
);
/*
* driverfs support for determining driver types
*/
EXPORT_SYMBOL
(
scsi_driverfs_bus_type
);
drivers/scsi/sd.c
View file @
c9761c4d
...
@@ -129,6 +129,7 @@ static void sd_rw_intr(Scsi_Cmnd * SCpnt);
...
@@ -129,6 +129,7 @@ static void sd_rw_intr(Scsi_Cmnd * SCpnt);
static
Scsi_Disk
*
sd_get_sdisk
(
int
index
);
static
Scsi_Disk
*
sd_get_sdisk
(
int
index
);
extern
void
driverfs_remove_partitions
(
struct
gendisk
*
hd
,
int
minor
);
#if defined(CONFIG_PPC32)
#if defined(CONFIG_PPC32)
/**
/**
...
@@ -1277,12 +1278,15 @@ static int sd_init()
...
@@ -1277,12 +1278,15 @@ static int sd_init()
init_mem_lth
(
sd_gendisks
[
k
].
de_arr
,
N
);
init_mem_lth
(
sd_gendisks
[
k
].
de_arr
,
N
);
init_mem_lth
(
sd_gendisks
[
k
].
flags
,
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
;
goto
cleanup_gendisks
;
zero_mem_lth
(
sd_gendisks
[
k
].
de_arr
,
N
);
zero_mem_lth
(
sd_gendisks
[
k
].
de_arr
,
N
);
zero_mem_lth
(
sd_gendisks
[
k
].
flags
,
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
=
SD_MAJOR
(
k
);
sd_gendisks
[
k
].
major_name
=
"sd"
;
sd_gendisks
[
k
].
major_name
=
"sd"
;
...
@@ -1291,7 +1295,6 @@ static int sd_init()
...
@@ -1291,7 +1295,6 @@ static int sd_init()
sd_gendisks
[
k
].
sizes
=
sd_sizes
+
k
*
(
N
<<
4
);
sd_gendisks
[
k
].
sizes
=
sd_sizes
+
k
*
(
N
<<
4
);
sd_gendisks
[
k
].
nr_real
=
0
;
sd_gendisks
[
k
].
nr_real
=
0
;
}
}
return
0
;
return
0
;
#undef init_mem_lth
#undef init_mem_lth
...
@@ -1302,6 +1305,7 @@ static int sd_init()
...
@@ -1302,6 +1305,7 @@ static int sd_init()
for
(
k
=
0
;
k
<
N_USED_SD_MAJORS
;
k
++
)
{
for
(
k
=
0
;
k
<
N_USED_SD_MAJORS
;
k
++
)
{
vfree
(
sd_gendisks
[
k
].
de_arr
);
vfree
(
sd_gendisks
[
k
].
de_arr
);
vfree
(
sd_gendisks
[
k
].
flags
);
vfree
(
sd_gendisks
[
k
].
flags
);
vfree
(
sd_gendisks
[
k
].
driverfs_dev_arr
);
}
}
cleanup_mem:
cleanup_mem:
vfree
(
sd_gendisks
);
vfree
(
sd_gendisks
);
...
@@ -1436,6 +1440,8 @@ static int sd_attach(Scsi_Device * sdp)
...
@@ -1436,6 +1440,8 @@ static int sd_attach(Scsi_Device * sdp)
SD_GENDISK
(
dsk_nr
).
nr_real
++
;
SD_GENDISK
(
dsk_nr
).
nr_real
++
;
devnum
=
dsk_nr
%
SCSI_DISKS_PER_MAJOR
;
devnum
=
dsk_nr
%
SCSI_DISKS_PER_MAJOR
;
SD_GENDISK
(
dsk_nr
).
de_arr
[
devnum
]
=
sdp
->
de
;
SD_GENDISK
(
dsk_nr
).
de_arr
[
devnum
]
=
sdp
->
de
;
SD_GENDISK
(
dsk_nr
).
driverfs_dev_arr
[
devnum
]
=
&
sdp
->
sdev_driverfs_dev
;
if
(
sdp
->
removable
)
if
(
sdp
->
removable
)
SD_GENDISK
(
dsk_nr
).
flags
[
devnum
]
|=
GENHD_FL_REMOVABLE
;
SD_GENDISK
(
dsk_nr
).
flags
[
devnum
]
|=
GENHD_FL_REMOVABLE
;
sd_dskname
(
dsk_nr
,
diskname
);
sd_dskname
(
dsk_nr
,
diskname
);
...
@@ -1535,6 +1541,8 @@ static void sd_detach(Scsi_Device * sdp)
...
@@ -1535,6 +1541,8 @@ static void sd_detach(Scsi_Device * sdp)
max_p
=
1
<<
sd_gendisk
.
minor_shift
;
max_p
=
1
<<
sd_gendisk
.
minor_shift
;
start
=
dsk_nr
<<
sd_gendisk
.
minor_shift
;
start
=
dsk_nr
<<
sd_gendisk
.
minor_shift
;
dev
=
MKDEV_SD_PARTITION
(
start
);
dev
=
MKDEV_SD_PARTITION
(
start
);
driverfs_remove_partitions
(
&
SD_GENDISK
(
dsk_nr
),
SD_MINOR_NUMBER
(
start
));
wipe_partitions
(
dev
);
wipe_partitions
(
dev
);
for
(
j
=
max_p
-
1
;
j
>=
0
;
j
--
)
for
(
j
=
max_p
-
1
;
j
>=
0
;
j
--
)
sd_sizes
[
start
+
j
]
=
0
;
sd_sizes
[
start
+
j
]
=
0
;
...
@@ -1556,9 +1564,16 @@ static void sd_detach(Scsi_Device * sdp)
...
@@ -1556,9 +1564,16 @@ static void sd_detach(Scsi_Device * sdp)
**/
**/
static
int
__init
init_sd
(
void
)
static
int
__init
init_sd
(
void
)
{
{
int
rc
;
SCSI_LOG_HLQUEUE
(
3
,
printk
(
"init_sd: sd driver entry point
\n
"
));
SCSI_LOG_HLQUEUE
(
3
,
printk
(
"init_sd: sd driver entry point
\n
"
));
sd_template
.
module
=
THIS_MODULE
;
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)
...
@@ -1591,6 +1606,7 @@ static void __exit exit_sd(void)
sd_template
.
dev_max
=
0
;
sd_template
.
dev_max
=
0
;
if
(
sd_gendisks
!=
&
sd_gendisk
)
if
(
sd_gendisks
!=
&
sd_gendisk
)
vfree
(
sd_gendisks
);
vfree
(
sd_gendisks
);
remove_driver
(
&
sd_template
.
scsi_driverfs_driver
);
}
}
static
Scsi_Disk
*
sd_get_sdisk
(
int
index
)
static
Scsi_Disk
*
sd_get_sdisk
(
int
index
)
...
...
drivers/scsi/sg.c
View file @
c9761c4d
...
@@ -194,6 +194,7 @@ typedef struct sg_device /* holds the state of each scsi generic device */
...
@@ -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
detached
;
/* 0->attached, 1->detached pending removal */
volatile
char
exclude
;
/* opened for exclusive access */
volatile
char
exclude
;
/* opened for exclusive access */
char
sgdebug
;
/* 0->off, 1->sense, 9->dump dev, 10-> all devs */
char
sgdebug
;
/* 0->off, 1->sense, 9->dump dev, 10-> all devs */
struct
device
sg_driverfs_dev
;
}
Sg_device
;
/* 36 bytes long on i386 */
}
Sg_device
;
/* 36 bytes long on i386 */
...
@@ -1370,6 +1371,29 @@ static int __init sg_def_reserved_size_setup(char *str)
...
@@ -1370,6 +1371,29 @@ static int __init sg_def_reserved_size_setup(char *str)
__setup
(
"sg_def_reserved_size="
,
sg_def_reserved_size_setup
);
__setup
(
"sg_def_reserved_size="
,
sg_def_reserved_size_setup
);
#endif
#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
)
static
int
sg_attach
(
Scsi_Device
*
scsidp
)
{
{
...
@@ -1428,6 +1452,18 @@ static int sg_attach(Scsi_Device * scsidp)
...
@@ -1428,6 +1452,18 @@ static int sg_attach(Scsi_Device * scsidp)
sdp
->
detached
=
0
;
sdp
->
detached
=
0
;
sdp
->
sg_tablesize
=
scsidp
->
host
?
scsidp
->
host
->
sg_tablesize
:
0
;
sdp
->
sg_tablesize
=
scsidp
->
host
?
scsidp
->
host
->
sg_tablesize
:
0
;
sdp
->
i_rdev
=
mk_kdev
(
SCSI_GENERIC_MAJOR
,
k
);
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
,
sdp
->
de
=
devfs_register
(
scsidp
->
de
,
"generic"
,
DEVFS_FL_DEFAULT
,
SCSI_GENERIC_MAJOR
,
k
,
SCSI_GENERIC_MAJOR
,
k
,
S_IFCHR
|
S_IRUSR
|
S_IWUSR
|
S_IRGRP
,
S_IFCHR
|
S_IRUSR
|
S_IWUSR
|
S_IRGRP
,
...
@@ -1496,6 +1532,9 @@ static void sg_detach(Scsi_Device * scsidp)
...
@@ -1496,6 +1532,9 @@ static void sg_detach(Scsi_Device * scsidp)
}
}
SCSI_LOG_TIMEOUT
(
3
,
printk
(
"sg_detach: dev=%d, dirty
\n
"
,
k
));
SCSI_LOG_TIMEOUT
(
3
,
printk
(
"sg_detach: dev=%d, dirty
\n
"
,
k
));
devfs_unregister
(
sdp
->
de
);
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
;
sdp
->
de
=
NULL
;
if
(
NULL
==
sdp
->
headfp
)
{
if
(
NULL
==
sdp
->
headfp
)
{
kfree
((
char
*
)
sdp
);
kfree
((
char
*
)
sdp
);
...
@@ -1505,6 +1544,7 @@ static void sg_detach(Scsi_Device * scsidp)
...
@@ -1505,6 +1544,7 @@ static void sg_detach(Scsi_Device * scsidp)
else
{
/* nothing active, simple case */
else
{
/* nothing active, simple case */
SCSI_LOG_TIMEOUT
(
3
,
printk
(
"sg_detach: dev=%d
\n
"
,
k
));
SCSI_LOG_TIMEOUT
(
3
,
printk
(
"sg_detach: dev=%d
\n
"
,
k
));
devfs_unregister
(
sdp
->
de
);
devfs_unregister
(
sdp
->
de
);
put_device
(
&
sdp
->
sg_driverfs_dev
);
kfree
((
char
*
)
sdp
);
kfree
((
char
*
)
sdp
);
sg_dev_arr
[
k
]
=
NULL
;
sg_dev_arr
[
k
]
=
NULL
;
}
}
...
@@ -1529,9 +1569,16 @@ MODULE_PARM(def_reserved_size, "i");
...
@@ -1529,9 +1569,16 @@ MODULE_PARM(def_reserved_size, "i");
MODULE_PARM_DESC
(
def_reserved_size
,
"size of buffer reserved for each fd"
);
MODULE_PARM_DESC
(
def_reserved_size
,
"size of buffer reserved for each fd"
);
static
int
__init
init_sg
(
void
)
{
static
int
__init
init_sg
(
void
)
{
int
rc
;
if
(
def_reserved_size
>=
0
)
if
(
def_reserved_size
>=
0
)
sg_big_buff
=
def_reserved_size
;
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
)
static
void
__exit
exit_sg
(
void
)
...
@@ -1546,6 +1593,7 @@ static void __exit exit_sg( void)
...
@@ -1546,6 +1593,7 @@ static void __exit exit_sg( void)
sg_dev_arr
=
NULL
;
sg_dev_arr
=
NULL
;
}
}
sg_template
.
dev_max
=
0
;
sg_template
.
dev_max
=
0
;
remove_driver
(
&
sg_template
.
scsi_driverfs_driver
);
}
}
...
...
drivers/scsi/sr.c
View file @
c9761c4d
...
@@ -731,6 +731,32 @@ static int sr_init()
...
@@ -731,6 +731,32 @@ static int sr_init()
return
1
;
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
()
void
sr_finish
()
{
{
int
i
;
int
i
;
...
@@ -776,6 +802,20 @@ void sr_finish()
...
@@ -776,6 +802,20 @@ void sr_finish()
sprintf
(
name
,
"sr%d"
,
i
);
sprintf
(
name
,
"sr%d"
,
i
);
strcpy
(
SCp
->
cdi
.
name
,
name
);
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"
,
SCp
->
cdi
.
de
=
devfs_register
(
SCp
->
device
->
de
,
"cd"
,
DEVFS_FL_DEFAULT
,
MAJOR_NR
,
i
,
DEVFS_FL_DEFAULT
,
MAJOR_NR
,
i
,
S_IFBLK
|
S_IRUGO
|
S_IWUGO
,
S_IFBLK
|
S_IRUGO
|
S_IWUGO
,
...
@@ -816,7 +856,14 @@ static void sr_detach(Scsi_Device * SDp)
...
@@ -816,7 +856,14 @@ static void sr_detach(Scsi_Device * SDp)
static
int
__init
init_sr
(
void
)
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
)
static
void
__exit
exit_sr
(
void
)
...
@@ -833,6 +880,7 @@ static void __exit exit_sr(void)
...
@@ -833,6 +880,7 @@ static void __exit exit_sr(void)
blk_clear
(
MAJOR_NR
);
blk_clear
(
MAJOR_NR
);
sr_template
.
dev_max
=
0
;
sr_template
.
dev_max
=
0
;
remove_driver
(
&
sr_template
.
scsi_driverfs_driver
);
}
}
module_init
(
init_sr
);
module_init
(
init_sr
);
...
...
drivers/scsi/st.c
View file @
c9761c4d
...
@@ -3531,6 +3531,31 @@ __setup("st=", st_setup);
...
@@ -3531,6 +3531,31 @@ __setup("st=", st_setup);
#endif
#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
=
static
struct
file_operations
st_fops
=
{
{
...
@@ -3632,6 +3657,18 @@ static int st_attach(Scsi_Device * SDp)
...
@@ -3632,6 +3657,18 @@ static int st_attach(Scsi_Device * SDp)
/* Rewind entry */
/* Rewind entry */
sprintf
(
name
,
"mt%s"
,
formats
[
mode
]);
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
]
=
tpnt
->
de_r
[
mode
]
=
devfs_register
(
SDp
->
de
,
name
,
DEVFS_FL_DEFAULT
,
devfs_register
(
SDp
->
de
,
name
,
DEVFS_FL_DEFAULT
,
MAJOR_NR
,
i
+
(
mode
<<
5
),
MAJOR_NR
,
i
+
(
mode
<<
5
),
...
@@ -3639,6 +3676,19 @@ static int st_attach(Scsi_Device * SDp)
...
@@ -3639,6 +3676,19 @@ static int st_attach(Scsi_Device * SDp)
&
st_fops
,
NULL
);
&
st_fops
,
NULL
);
/* No-rewind entry */
/* No-rewind entry */
sprintf
(
name
,
"mt%sn"
,
formats
[
mode
]);
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
]
=
tpnt
->
de_n
[
mode
]
=
devfs_register
(
SDp
->
de
,
name
,
DEVFS_FL_DEFAULT
,
devfs_register
(
SDp
->
de
,
name
,
DEVFS_FL_DEFAULT
,
MAJOR_NR
,
i
+
(
mode
<<
5
)
+
128
,
MAJOR_NR
,
i
+
(
mode
<<
5
)
+
128
,
...
@@ -3738,8 +3788,18 @@ static void st_detach(Scsi_Device * SDp)
...
@@ -3738,8 +3788,18 @@ static void st_detach(Scsi_Device * SDp)
for
(
mode
=
0
;
mode
<
ST_NBR_MODES
;
++
mode
)
{
for
(
mode
=
0
;
mode
<
ST_NBR_MODES
;
++
mode
)
{
devfs_unregister
(
tpnt
->
de_r
[
mode
]);
devfs_unregister
(
tpnt
->
de_r
[
mode
]);
tpnt
->
de_r
[
mode
]
=
NULL
;
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
]);
devfs_unregister
(
tpnt
->
de_n
[
mode
]);
tpnt
->
de_n
[
mode
]
=
NULL
;
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
)
{
if
(
tpnt
->
buffer
)
{
tpnt
->
buffer
->
orig_sg_segs
=
0
;
tpnt
->
buffer
->
orig_sg_segs
=
0
;
...
@@ -3770,8 +3830,16 @@ static int __init init_st(void)
...
@@ -3770,8 +3830,16 @@ static int __init init_st(void)
verstr
,
st_fixed_buffer_size
,
st_write_threshold
,
verstr
,
st_fixed_buffer_size
,
st_write_threshold
,
st_max_sg_segs
);
st_max_sg_segs
);
if
(
devfs_register_chrdev
(
SCSI_TAPE_MAJOR
,
"st"
,
&
st_fops
)
>=
0
)
if
(
devfs_register_chrdev
(
SCSI_TAPE_MAJOR
,
"st"
,
&
st_fops
)
>=
0
)
{
return
scsi_register_device
(
&
st_template
);
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
);
printk
(
KERN_ERR
"Unable to get major %d for SCSI tapes
\n
"
,
MAJOR_NR
);
return
1
;
return
1
;
...
@@ -3790,6 +3858,7 @@ static void __exit exit_st(void)
...
@@ -3790,6 +3858,7 @@ static void __exit exit_st(void)
kfree
(
scsi_tapes
);
kfree
(
scsi_tapes
);
}
}
st_template
.
dev_max
=
0
;
st_template
.
dev_max
=
0
;
remove_driver
(
&
st_template
.
scsi_driverfs_driver
);
printk
(
KERN_INFO
"st: Unloaded.
\n
"
);
printk
(
KERN_INFO
"st: Unloaded.
\n
"
);
}
}
...
...
drivers/scsi/st.h
View file @
c9761c4d
...
@@ -94,6 +94,8 @@ typedef struct {
...
@@ -94,6 +94,8 @@ typedef struct {
int
current_mode
;
int
current_mode
;
devfs_handle_t
de_r
[
ST_NBR_MODES
];
/* Rewind entries */
devfs_handle_t
de_r
[
ST_NBR_MODES
];
/* Rewind entries */
devfs_handle_t
de_n
[
ST_NBR_MODES
];
/* No-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 */
/* Status variables */
int
partition
;
int
partition
;
...
...
fs/partitions/check.c
View file @
c9761c4d
...
@@ -22,6 +22,7 @@
...
@@ -22,6 +22,7 @@
#include <linux/init.h>
#include <linux/init.h>
#include <linux/raid/md.h>
#include <linux/raid/md.h>
#include <linux/buffer_head.h>
/* for invalidate_bdev() */
#include <linux/buffer_head.h>
/* for invalidate_bdev() */
#include <linux/kmod.h>
#include "check.h"
#include "check.h"
...
@@ -225,6 +226,136 @@ void add_gd_partition(struct gendisk *hd, int minor, int start, int size)
...
@@ -225,6 +226,136 @@ void add_gd_partition(struct gendisk *hd, int minor, int start, int size)
#endif
#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
)
static
void
check_partition
(
struct
gendisk
*
hd
,
kdev_t
dev
,
int
first_part_minor
)
{
{
devfs_handle_t
de
=
NULL
;
devfs_handle_t
de
=
NULL
;
...
@@ -285,6 +416,13 @@ static void check_partition(struct gendisk *hd, kdev_t dev, int first_part_minor
...
@@ -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
);
truncate_inode_pages
(
bdev
->
bd_inode
->
i_mapping
,
0
);
bdput
(
bdev
);
bdput
(
bdev
);
i
=
first_part_minor
-
1
;
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
);
devfs_register_partitions
(
hd
,
i
,
hd
->
sizes
?
0
:
1
);
}
}
...
...
include/linux/cdrom.h
View file @
c9761c4d
...
@@ -716,6 +716,7 @@ struct request_sense {
...
@@ -716,6 +716,7 @@ struct request_sense {
#ifdef __KERNEL__
#ifdef __KERNEL__
#include <linux/devfs_fs_kernel.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/device.h>
struct
cdrom_write_settings
{
struct
cdrom_write_settings
{
unsigned
char
fpacket
;
/* fixed/variable packets */
unsigned
char
fpacket
;
/* fixed/variable packets */
...
@@ -730,6 +731,7 @@ struct cdrom_device_info {
...
@@ -730,6 +731,7 @@ struct cdrom_device_info {
struct
cdrom_device_info
*
next
;
/* next device_info for this major */
struct
cdrom_device_info
*
next
;
/* next device_info for this major */
void
*
handle
;
/* driver-dependent data */
void
*
handle
;
/* driver-dependent data */
devfs_handle_t
de
;
/* real driver should create this */
devfs_handle_t
de
;
/* real driver should create this */
struct
device
cdrom_driverfs_dev
;
/* driverfs implementation */
int
number
;
/* generic driver updates this */
int
number
;
/* generic driver updates this */
/* specifications */
/* specifications */
kdev_t
dev
;
/* device number */
kdev_t
dev
;
/* device number */
...
...
include/linux/genhd.h
View file @
c9761c4d
...
@@ -12,6 +12,7 @@
...
@@ -12,6 +12,7 @@
#include <linux/config.h>
#include <linux/config.h>
#include <linux/types.h>
#include <linux/types.h>
#include <linux/major.h>
#include <linux/major.h>
#include <linux/device.h>
enum
{
enum
{
/* These three have identical behaviour; use the second one if DOS fdisk gets
/* These three have identical behaviour; use the second one if DOS fdisk gets
...
@@ -62,6 +63,7 @@ struct hd_struct {
...
@@ -62,6 +63,7 @@ struct hd_struct {
unsigned
long
nr_sects
;
unsigned
long
nr_sects
;
devfs_handle_t
de
;
/* primary (master) devfs entry */
devfs_handle_t
de
;
/* primary (master) devfs entry */
int
number
;
/* stupid old code wastes space */
int
number
;
/* stupid old code wastes space */
struct
device
hd_driverfs_dev
;
/* support driverfs hiearchy */
};
};
#define GENHD_FL_REMOVABLE 1
#define GENHD_FL_REMOVABLE 1
...
@@ -80,6 +82,7 @@ struct gendisk {
...
@@ -80,6 +82,7 @@ struct gendisk {
struct
block_device_operations
*
fops
;
struct
block_device_operations
*
fops
;
devfs_handle_t
*
de_arr
;
/* one per physical disc */
devfs_handle_t
*
de_arr
;
/* one per physical disc */
struct
device
**
driverfs_dev_arr
;
/* support driverfs hierarchy */
char
*
flags
;
/* one per physical disc */
char
*
flags
;
/* one per physical disc */
};
};
...
@@ -241,6 +244,7 @@ char *disk_name (struct gendisk *hd, int minor, char *buf);
...
@@ -241,6 +244,7 @@ char *disk_name (struct gendisk *hd, int minor, char *buf);
extern
void
devfs_register_partitions
(
struct
gendisk
*
dev
,
int
minor
,
extern
void
devfs_register_partitions
(
struct
gendisk
*
dev
,
int
minor
,
int
unregister
);
int
unregister
);
extern
void
driverfs_remove_partitions
(
struct
gendisk
*
hd
,
int
minor
);
static
inline
unsigned
int
disk_index
(
kdev_t
dev
)
static
inline
unsigned
int
disk_index
(
kdev_t
dev
)
{
{
...
...
kernel/ksyms.c
View file @
c9761c4d
...
@@ -334,6 +334,7 @@ EXPORT_SYMBOL(bdev_read_only);
...
@@ -334,6 +334,7 @@ EXPORT_SYMBOL(bdev_read_only);
EXPORT_SYMBOL
(
set_device_ro
);
EXPORT_SYMBOL
(
set_device_ro
);
EXPORT_SYMBOL
(
bmap
);
EXPORT_SYMBOL
(
bmap
);
EXPORT_SYMBOL
(
devfs_register_partitions
);
EXPORT_SYMBOL
(
devfs_register_partitions
);
EXPORT_SYMBOL
(
driverfs_remove_partitions
);
EXPORT_SYMBOL
(
blkdev_open
);
EXPORT_SYMBOL
(
blkdev_open
);
EXPORT_SYMBOL
(
blkdev_get
);
EXPORT_SYMBOL
(
blkdev_get
);
EXPORT_SYMBOL
(
blkdev_put
);
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