Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
fd791128
Commit
fd791128
authored
Oct 03, 2002
by
Martin Schwidefsky
Committed by
Linus Torvalds
Oct 03, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] s390 update (7/27): dasd driver.
parent
7441ad13
Changes
11
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
325 additions
and
269 deletions
+325
-269
drivers/s390/block/dasd.c
drivers/s390/block/dasd.c
+61
-46
drivers/s390/block/dasd_devmap.c
drivers/s390/block/dasd_devmap.c
+9
-0
drivers/s390/block/dasd_diag.c
drivers/s390/block/dasd_diag.c
+8
-33
drivers/s390/block/dasd_eckd.c
drivers/s390/block/dasd_eckd.c
+18
-18
drivers/s390/block/dasd_fba.c
drivers/s390/block/dasd_fba.c
+1
-6
drivers/s390/block/dasd_genhd.c
drivers/s390/block/dasd_genhd.c
+132
-93
drivers/s390/block/dasd_int.h
drivers/s390/block/dasd_int.h
+11
-11
drivers/s390/block/dasd_ioctl.c
drivers/s390/block/dasd_ioctl.c
+72
-52
drivers/s390/block/dasd_proc.c
drivers/s390/block/dasd_proc.c
+7
-8
include/asm-s390/dasd.h
include/asm-s390/dasd.h
+3
-1
include/asm-s390x/dasd.h
include/asm-s390x/dasd.h
+3
-1
No files found.
drivers/s390/block/dasd.c
View file @
fd791128
...
...
@@ -203,20 +203,24 @@ dasd_device_t *
dasd_alloc_device
(
dasd_devmap_t
*
devmap
)
{
dasd_device_t
*
device
;
struct
gendisk
*
gdp
;
int
rc
;
/* Make sure the gendisk structure for this device exists. */
while
(
dasd_gendisk_from_devindex
(
devmap
->
devindex
)
==
NULL
)
{
rc
=
dasd_gendisk_new_major
();
if
(
rc
)
return
ERR_PTR
(
rc
);
}
device
=
kmalloc
(
sizeof
(
dasd_device_t
),
GFP_ATOMIC
);
if
(
device
==
NULL
)
return
ERR_PTR
(
-
ENOMEM
);
memset
(
device
,
0
,
sizeof
(
dasd_device_t
));
/* Get devinfo from the common io layer. */
rc
=
get_dev_info_by_devno
(
devmap
->
devno
,
&
device
->
devinfo
);
if
(
rc
)
{
kfree
(
device
);
return
ERR_PTR
(
rc
);
}
DBF_EVENT
(
DBF_NOTICE
,
"got devinfo CU-type %04x and dev-type %04x"
,
device
->
devinfo
.
sid_data
.
cu_type
,
device
->
devinfo
.
sid_data
.
dev_type
);
/* Get two pages for normal block device operations. */
device
->
ccw_mem
=
(
void
*
)
__get_free_pages
(
GFP_ATOMIC
|
GFP_DMA
,
1
);
if
(
device
->
ccw_mem
==
NULL
)
{
...
...
@@ -231,17 +235,15 @@ dasd_alloc_device(dasd_devmap_t *devmap)
return
ERR_PTR
(
-
ENOMEM
);
}
/*
Get devinfo from the common io layer
. */
rc
=
get_dev_info_by_devno
(
devmap
->
devno
,
&
device
->
devinfo
);
if
(
rc
)
{
free_page
((
unsigned
long
)
device
->
erp_mem
);
/*
Allocate gendisk structure for device
. */
gdp
=
dasd_gendisk_alloc
(
device
->
name
,
devmap
->
devindex
);
if
(
IS_ERR
(
gdp
)
)
{
free_page
((
unsigned
long
)
device
->
erp_mem
);
free_pages
((
unsigned
long
)
device
->
ccw_mem
,
1
);
kfree
(
device
);
return
ERR_PTR
(
rc
)
;
return
(
dasd_device_t
*
)
gdp
;
}
DBF_EVENT
(
DBF_NOTICE
,
"got devinfo CU-type %04x and dev-type %04x"
,
device
->
devinfo
.
sid_data
.
cu_type
,
device
->
devinfo
.
sid_data
.
dev_type
);
device
->
gdp
=
gdp
;
dasd_init_chunklist
(
&
device
->
ccw_chunks
,
device
->
ccw_mem
,
PAGE_SIZE
*
2
);
dasd_init_chunklist
(
&
device
->
erp_chunks
,
device
->
erp_mem
,
PAGE_SIZE
);
...
...
@@ -268,6 +270,7 @@ dasd_free_device(dasd_device_t *device)
kfree
(
device
->
private
);
free_page
((
unsigned
long
)
device
->
erp_mem
);
free_pages
((
unsigned
long
)
device
->
ccw_mem
,
1
);
dasd_gendisk_free
(
device
->
gdp
);
kfree
(
device
);
}
...
...
@@ -278,21 +281,22 @@ static inline int
dasd_state_new_to_known
(
dasd_device_t
*
device
)
{
char
buffer
[
5
];
struct
gendisk
*
gdp
;
dasd_devmap_t
*
devmap
;
umode_t
devfs_perm
;
devfs_handle_t
dir
;
int
minor
,
rc
;
int
m
ajor
,
m
inor
,
rc
;
devmap
=
dasd_devmap_from_devno
(
device
->
devinfo
.
devno
);
if
(
devmap
==
NULL
)
return
-
ENODEV
;
gdp
=
dasd_gendisk_from_devindex
(
devmap
->
devindex
);
if
(
gdp
==
NULL
)
major
=
dasd_gendisk_index_major
(
devmap
->
devindex
);
if
(
major
<
0
)
return
-
ENODEV
;
/* Set kdev and the device name. */
device
->
kdev
=
mk_kdev
(
gdp
->
major
,
gdp
->
first_minor
);
strcpy
(
device
->
name
,
gdp
->
disk_name
);
minor
=
devmap
->
devindex
%
DASD_PER_MAJOR
;
/* Set bdev and the device name. */
device
->
bdev
=
bdget
(
MKDEV
(
major
,
minor
<<
DASD_PARTN_BITS
));
strcpy
(
device
->
name
,
device
->
gdp
->
disk_name
);
/* Find a discipline for the device. */
rc
=
dasd_find_disc
(
device
);
...
...
@@ -302,14 +306,13 @@ dasd_state_new_to_known(dasd_device_t *device)
/* Add a proc directory and the dasd device entry to devfs. */
sprintf
(
buffer
,
"%04x"
,
device
->
devinfo
.
devno
);
dir
=
devfs_mk_dir
(
dasd_devfs_handle
,
buffer
,
device
);
gdp
->
de
=
dir
;
device
->
gdp
->
de
=
dir
;
if
(
devmap
->
features
&
DASD_FEATURE_READONLY
)
devfs_perm
=
S_IFBLK
|
S_IRUSR
;
else
devfs_perm
=
S_IFBLK
|
S_IRUSR
|
S_IWUSR
;
device
->
devfs_entry
=
devfs_register
(
dir
,
"device"
,
DEVFS_FL_DEFAULT
,
major
(
device
->
kdev
),
minor
(
device
->
kdev
),
major
,
minor
<<
DASD_PARTN_BITS
,
devfs_perm
,
&
dasd_device_operations
,
NULL
);
device
->
state
=
DASD_STATE_KNOWN
;
...
...
@@ -322,17 +325,25 @@ dasd_state_new_to_known(dasd_device_t *device)
static
inline
void
dasd_state_known_to_new
(
dasd_device_t
*
device
)
{
dasd_devmap_t
*
devmap
=
dasd_devmap_from_devno
(
device
->
devinfo
.
devno
);
struct
gendisk
*
gdp
=
dasd_gendisk_from_devindex
(
devmap
->
devindex
);
if
(
gdp
==
NULL
)
return
;
dasd_devmap_t
*
devmap
;
struct
block_device
*
bdev
;
int
minor
;
devmap
=
dasd_devmap_from_devno
(
device
->
devinfo
.
devno
);
minor
=
devmap
->
devindex
%
DASD_PER_MAJOR
;
/* Remove device entry and devfs directory. */
devfs_unregister
(
device
->
devfs_entry
);
devfs_unregister
(
gdp
->
de
);
devfs_unregister
(
device
->
gdp
->
de
);
/* Forget the discipline information. */
device
->
discipline
=
NULL
;
device
->
state
=
DASD_STATE_NEW
;
/* Forget the block device */
bdev
=
device
->
bdev
;
device
->
bdev
=
NULL
;
bdput
(
bdev
);
}
/*
...
...
@@ -418,6 +429,17 @@ dasd_state_accept_to_basic(dasd_device_t * device)
device
->
state
=
DASD_STATE_BASIC
;
}
/*
* get the kdev_t of a device
* FIXME: remove this when no longer needed
*/
static
inline
kdev_t
dasd_partition_to_kdev_t
(
dasd_device_t
*
device
,
unsigned
int
partition
)
{
return
to_kdev_t
(
device
->
bdev
->
bd_dev
+
partition
);
}
/*
* Setup block device.
*/
...
...
@@ -425,15 +447,12 @@ static inline int
dasd_state_accept_to_ready
(
dasd_device_t
*
device
)
{
dasd_devmap_t
*
devmap
;
int
major
,
minor
;
int
rc
,
i
;
devmap
=
dasd_devmap_from_devno
(
device
->
devinfo
.
devno
);
if
(
devmap
->
features
&
DASD_FEATURE_READONLY
)
{
major
=
major
(
device
->
kdev
);
minor
=
minor
(
device
->
kdev
);
for
(
i
=
0
;
i
<
(
1
<<
DASD_PARTN_BITS
);
i
++
)
set_device_ro
(
mk_kdev
(
major
,
minor
+
i
),
1
);
set_device_ro
(
dasd_partition_to_kdev_t
(
device
,
i
),
1
);
DEV_MESSAGE
(
KERN_WARNING
,
device
,
"%s"
,
"setting read-only mode "
);
}
...
...
@@ -1539,11 +1558,9 @@ __dasd_process_ccw_queue(dasd_device_t * device, struct list_head *final_queue)
goto
restart
;
}
/*
Dechain request from device request queue ...
*/
/*
Rechain request on device device request queue
*/
cqr
->
endclk
=
get_clock
();
list_del
(
&
cqr
->
list
);
/* ... and add it to list of final requests. */
list_add_tail
(
&
cqr
->
list
,
final_queue
);
list_move_tail
(
&
cqr
->
list
,
final_queue
);
}
}
...
...
@@ -1572,6 +1589,10 @@ __dasd_process_blk_queue(dasd_device_t * device)
dasd_ccw_req_t
*
cqr
;
int
nr_queued
;
/* No bdev, no queue. */
bdev
=
device
->
bdev
;
if
(
!
bdev
)
return
;
queue
=
device
->
request_queue
;
/* No queue ? Then there is nothing to do. */
if
(
queue
==
NULL
)
...
...
@@ -1594,9 +1615,6 @@ __dasd_process_blk_queue(dasd_device_t * device)
if
(
cqr
->
status
==
DASD_CQR_QUEUED
)
nr_queued
++
;
}
bdev
=
bdget
(
kdev_t_to_nr
(
device
->
kdev
));
if
(
!
bdev
)
return
;
while
(
!
blk_queue_plugged
(
queue
)
&&
!
blk_queue_empty
(
queue
)
&&
nr_queued
<
DASD_CHANQ_MAX_SIZE
)
{
...
...
@@ -1628,7 +1646,6 @@ __dasd_process_blk_queue(dasd_device_t * device)
dasd_profile_start
(
device
,
cqr
,
req
);
nr_queued
++
;
}
bdput
(
bdev
);
}
/*
...
...
@@ -1707,11 +1724,9 @@ dasd_flush_ccw_queue(dasd_device_t * device, int all)
__dasd_process_erp
(
device
,
cqr
);
continue
;
}
/*
Dechain request from device request queue ...
*/
/*
Rechain request on device request queue
*/
cqr
->
endclk
=
get_clock
();
list_del
(
&
cqr
->
list
);
/* ... and add it to list of flushed requests. */
list_add_tail
(
&
cqr
->
list
,
&
flush_queue
);
list_move_tail
(
&
cqr
->
list
,
&
flush_queue
);
}
spin_unlock_irq
(
get_irq_lock
(
device
->
devinfo
.
irq
));
/* Now call the callback function of flushed requests */
...
...
drivers/s390/block/dasd_devmap.c
View file @
fd791128
...
...
@@ -448,6 +448,15 @@ dasd_devmap_from_kdev(kdev_t kdev)
return
dasd_devmap_from_devindex
(
devindex
);
}
/*
* Find the devmap for a device corresponding to a block_device.
*/
dasd_devmap_t
*
dasd_devmap_from_bdev
(
struct
block_device
*
bdev
)
{
return
dasd_devmap_from_kdev
(
to_kdev_t
(
bdev
->
bd_dev
));
}
/*
* Find the device structure for device number devno. If it does not
* exists yet, allocate it. Increase the reference counter in the device
...
...
drivers/s390/block/dasd_diag.c
View file @
fd791128
...
...
@@ -21,6 +21,7 @@
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/hdreg.h>
/* HDIO_GETGEO */
#include <linux/bio.h>
#include <asm/dasd.h>
#include <asm/debug.h>
...
...
@@ -53,31 +54,6 @@ typedef struct dasd_diag_req_t {
diag_bio_t
bio
[
0
];
}
dasd_diag_req_t
;
static
__inline__
int
dia210
(
void
*
devchar
)
{
int
rc
;
__asm__
__volatile__
(
" diag %1,0,0x210
\n
"
"0: ipm %0
\n
"
" srl %0,28
\n
"
"1:
\n
"
".section .fixup,
\"
ax
\"\n
"
"2: lhi %0,3
\n
"
" bras 1,3f
\n
"
" .long 1b
\n
"
"3: l 1,0(1)
\n
"
" br 1
\n
"
".previous
\n
"
".section __ex_table,
\"
a
\"\n
"
" .align 4
\n
"
" .long 0b,2b
\n
"
".previous
\n
"
:
"=d"
(
rc
)
:
"d"
((
void
*
)
__pa
(
devchar
))
:
"1"
);
return
rc
;
}
static
__inline__
int
dia250
(
void
*
iob
,
int
cmd
)
{
...
...
@@ -155,7 +131,7 @@ dasd_start_diag(dasd_ccw_req_t * cqr)
private
->
iob
.
key
=
0
;
private
->
iob
.
flags
=
2
;
/* do asynchronous io */
private
->
iob
.
block_count
=
dreq
->
block_count
;
private
->
iob
.
interrupt_params
=
(
u32
)
cqr
;
private
->
iob
.
interrupt_params
=
(
u32
)
(
addr_t
)
cqr
;
private
->
iob
.
bio_list
=
__pa
(
dreq
->
bio
);
cqr
->
startclk
=
get_clock
();
...
...
@@ -196,21 +172,21 @@ dasd_ext_handler(struct pt_regs *regs, __u16 code)
ip
=
S390_lowcore
.
ext_params
;
cpu
=
smp_processor_id
();
irq_enter
(
cpu
,
-
1
);
irq_enter
();
if
(
!
ip
)
{
/* no intparm: unsolicited interrupt */
MESSAGE
(
KERN_DEBUG
,
"%s"
,
"caught unsolicited interrupt"
);
irq_exit
(
cpu
,
-
1
);
irq_exit
();
return
;
}
cqr
=
(
dasd_ccw_req_t
*
)
ip
;
cqr
=
(
dasd_ccw_req_t
*
)
(
addr_t
)
ip
;
device
=
(
dasd_device_t
*
)
cqr
->
device
;
if
(
strncmp
(
device
->
discipline
->
ebcname
,
(
char
*
)
&
cqr
->
magic
,
4
))
{
DEV_MESSAGE
(
KERN_WARNING
,
device
,
" magic number of dasd_ccw_req_t 0x%08X doesn't"
" match discipline 0x%08X"
,
cqr
->
magic
,
*
(
int
*
)
(
&
device
->
discipline
->
name
));
irq_exit
(
cpu
,
-
1
);
irq_exit
();
return
;
}
...
...
@@ -244,8 +220,7 @@ dasd_ext_handler(struct pt_regs *regs, __u16 code)
dasd_schedule_bh
(
device
);
spin_unlock_irqrestore
(
get_irq_lock
(
device
->
devinfo
.
irq
),
flags
);
irq_exit
(
cpu
,
-
1
);
irq_exit
();
}
static
int
...
...
@@ -273,7 +248,7 @@ dasd_diag_check_device(dasd_device_t *device)
rdc_data
->
dev_nr
=
device
->
devinfo
.
devno
;
rdc_data
->
rdc_len
=
sizeof
(
dasd_diag_characteristics_t
);
rc
=
dia
210
(
rdc_data
);
rc
=
dia
g210
((
diag210_t
*
)
rdc_data
);
if
(
rc
)
return
-
ENOTSUPP
;
...
...
drivers/s390/block/dasd_eckd.c
View file @
fd791128
...
...
@@ -29,6 +29,7 @@
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/hdreg.h>
/* HDIO_GETGEO */
#include <linux/bio.h>
#include <asm/debug.h>
#include <asm/idals.h>
...
...
@@ -69,7 +70,6 @@ typedef struct dasd_eckd_private_t {
attrib_data_t
attrib
;
/* e.g. cache operations */
}
dasd_eckd_private_t
;
#ifdef CONFIG_DASD_DYNAMIC
static
devreg_t
dasd_eckd_known_devices
[]
=
{
{
...
...
@@ -94,7 +94,6 @@ devreg_t dasd_eckd_known_devices[] = {
oper_func:
dasd_oper_handler
}
};
#endif
static
const
int
sizes_trk0
[]
=
{
28
,
148
,
84
};
#define LABEL_SIZE 140
...
...
@@ -1092,7 +1091,8 @@ dasd_eckd_fill_info(dasd_device_t * device, dasd_information2_t * info)
* Buils a channel programm to releases a prior reserved
* (see dasd_eckd_reserve) device.
*/
static
int
dasd_eckd_release
(
void
*
inp
,
int
no
,
long
args
)
static
int
dasd_eckd_release
(
struct
block_device
*
bdev
,
int
no
,
long
args
)
{
dasd_devmap_t
*
devmap
;
dasd_device_t
*
device
;
...
...
@@ -1101,7 +1101,7 @@ static int dasd_eckd_release(void *inp, int no, long args)
if
(
!
capable
(
CAP_SYS_ADMIN
))
return
-
EACCES
;
devmap
=
dasd_devmap_from_
kdev
(((
struct
inode
*
)
inp
)
->
i_r
dev
);
devmap
=
dasd_devmap_from_
bdev
(
b
dev
);
device
=
(
devmap
!=
NULL
)
?
dasd_get_device
(
devmap
)
:
ERR_PTR
(
-
ENODEV
);
if
(
IS_ERR
(
device
))
...
...
@@ -1134,7 +1134,8 @@ static int dasd_eckd_release(void *inp, int no, long args)
* 'timeout the request'. This leads to an terminate IO if
* the interrupt is outstanding for a certain time.
*/
static
int
dasd_eckd_reserve
(
void
*
inp
,
int
no
,
long
args
)
static
int
dasd_eckd_reserve
(
struct
block_device
*
bdev
,
int
no
,
long
args
)
{
dasd_devmap_t
*
devmap
;
dasd_device_t
*
device
;
...
...
@@ -1143,7 +1144,7 @@ static int dasd_eckd_reserve(void *inp, int no, long args)
if
(
!
capable
(
CAP_SYS_ADMIN
))
return
-
EACCES
;
devmap
=
dasd_devmap_from_
kdev
(((
struct
inode
*
)
inp
)
->
i_r
dev
);
devmap
=
dasd_devmap_from_
bdev
(
b
dev
);
device
=
(
devmap
!=
NULL
)
?
dasd_get_device
(
devmap
)
:
ERR_PTR
(
-
ENODEV
);
if
(
IS_ERR
(
device
))
...
...
@@ -1168,7 +1169,7 @@ static int dasd_eckd_reserve(void *inp, int no, long args)
if
(
rc
==
-
EIO
)
{
/* Request got an eror or has been timed out. */
dasd_eckd_release
(
inp
,
no
,
args
);
dasd_eckd_release
(
bdev
,
no
,
args
);
}
dasd_kfree_request
(
cqr
,
cqr
->
device
);
dasd_put_device
(
devmap
);
...
...
@@ -1180,7 +1181,8 @@ static int dasd_eckd_reserve(void *inp, int no, long args)
* Buils a channel programm to break a device's reservation.
* (unconditional reserve)
*/
static
int
dasd_eckd_steal_lock
(
void
*
inp
,
int
no
,
long
args
)
static
int
dasd_eckd_steal_lock
(
struct
block_device
*
bdev
,
int
no
,
long
args
)
{
dasd_devmap_t
*
devmap
;
dasd_device_t
*
device
;
...
...
@@ -1189,7 +1191,7 @@ static int dasd_eckd_steal_lock(void *inp, int no, long args)
if
(
!
capable
(
CAP_SYS_ADMIN
))
return
-
EACCES
;
devmap
=
dasd_devmap_from_
kdev
(((
struct
inode
*
)
inp
)
->
i_r
dev
);
devmap
=
dasd_devmap_from_
bdev
(
b
dev
);
device
=
(
devmap
!=
NULL
)
?
dasd_get_device
(
devmap
)
:
ERR_PTR
(
-
ENODEV
);
if
(
IS_ERR
(
device
))
...
...
@@ -1213,7 +1215,7 @@ static int dasd_eckd_steal_lock(void *inp, int no, long args)
if
(
rc
==
-
EIO
)
{
/* Request got an eror or has been timed out. */
dasd_eckd_release
(
inp
,
no
,
args
);
dasd_eckd_release
(
bdev
,
no
,
args
);
}
dasd_kfree_request
(
cqr
,
cqr
->
device
);
dasd_put_device
(
devmap
);
...
...
@@ -1223,7 +1225,8 @@ static int dasd_eckd_steal_lock(void *inp, int no, long args)
/*
* Read performance statistics
*/
static
int
dasd_eckd_performance
(
void
*
inp
,
int
no
,
long
args
)
static
int
dasd_eckd_performance
(
struct
block_device
*
bdev
,
int
no
,
long
args
)
{
dasd_devmap_t
*
devmap
;
dasd_device_t
*
device
;
...
...
@@ -1233,7 +1236,7 @@ static int dasd_eckd_performance(void *inp, int no, long args)
ccw1_t
*
ccw
;
int
rc
;
devmap
=
dasd_devmap_from_
kdev
(((
struct
inode
*
)
inp
)
->
i_r
dev
);
devmap
=
dasd_devmap_from_
bdev
(
b
dev
);
device
=
(
devmap
!=
NULL
)
?
dasd_get_device
(
devmap
)
:
ERR_PTR
(
-
ENODEV
);
if
(
IS_ERR
(
device
))
...
...
@@ -1292,7 +1295,8 @@ static int dasd_eckd_performance(void *inp, int no, long args)
* Set attributes (cache operations)
* Stores the attributes for cache operation to be used in Define Extend (DE).
*/
static
int
dasd_eckd_set_attrib
(
void
*
inp
,
int
no
,
long
args
)
static
int
dasd_eckd_set_attrib
(
struct
block_device
*
bdev
,
int
no
,
long
args
)
{
dasd_devmap_t
*
devmap
;
dasd_device_t
*
device
;
...
...
@@ -1304,7 +1308,7 @@ static int dasd_eckd_set_attrib(void *inp, int no, long args)
if
(
!
args
)
return
-
EINVAL
;
devmap
=
dasd_devmap_from_
kdev
(((
struct
inode
*
)
inp
)
->
i_r
dev
);
devmap
=
dasd_devmap_from_
bdev
(
b
dev
);
device
=
(
devmap
!=
NULL
)
?
dasd_get_device
(
devmap
)
:
ERR_PTR
(
-
ENODEV
);
if
(
IS_ERR
(
device
))
...
...
@@ -1452,10 +1456,8 @@ dasd_eckd_init(void)
ASCEBC
(
dasd_eckd_discipline
.
ebcname
,
4
);
dasd_discipline_add
(
&
dasd_eckd_discipline
);
#ifdef CONFIG_DASD_DYNAMIC
for
(
i
=
0
;
i
<
sizeof
(
dasd_eckd_known_devices
)
/
sizeof
(
devreg_t
);
i
++
)
s390_device_register
(
&
dasd_eckd_known_devices
[
i
]);
#endif
return
0
;
}
...
...
@@ -1464,10 +1466,8 @@ dasd_eckd_cleanup(void)
{
int
i
;
#ifdef CONFIG_DASD_DYNAMIC
for
(
i
=
0
;
i
<
sizeof
(
dasd_eckd_known_devices
)
/
sizeof
(
devreg_t
);
i
++
)
s390_device_unregister
(
&
dasd_eckd_known_devices
[
i
]);
#endif
/* CONFIG_DASD_DYNAMIC */
dasd_discipline_del
(
&
dasd_eckd_discipline
);
...
...
drivers/s390/block/dasd_fba.c
View file @
fd791128
...
...
@@ -16,6 +16,7 @@
#include <linux/slab.h>
#include <linux/hdreg.h>
/* HDIO_GETGEO */
#include <linux/bio.h>
#include <asm/idals.h>
#include <asm/ebcdic.h>
...
...
@@ -43,7 +44,6 @@ typedef struct dasd_fba_private_t {
dasd_fba_characteristics_t
rdc_data
;
}
dasd_fba_private_t
;
#ifdef CONFIG_DASD_DYNAMIC
static
devreg_t
dasd_fba_known_devices
[]
=
{
{
...
...
@@ -59,7 +59,6 @@ devreg_t dasd_fba_known_devices[] = {
oper_func:
dasd_oper_handler
}
};
#endif
static
inline
void
define_extent
(
ccw1_t
*
ccw
,
DE_fba_data_t
*
data
,
int
rw
,
...
...
@@ -417,10 +416,8 @@ dasd_fba_init(void)
ASCEBC
(
dasd_fba_discipline
.
ebcname
,
4
);
dasd_discipline_add
(
&
dasd_fba_discipline
);
#ifdef CONFIG_DASD_DYNAMIC
for
(
i
=
0
;
i
<
sizeof
(
dasd_fba_known_devices
)
/
sizeof
(
devreg_t
);
i
++
)
s390_device_register
(
&
dasd_fba_known_devices
[
i
]);
#endif
return
0
;
}
...
...
@@ -429,10 +426,8 @@ dasd_fba_cleanup(void)
{
int
i
;
#ifdef CONFIG_DASD_DYNAMIC
for
(
i
=
0
;
i
<
sizeof
(
dasd_fba_known_devices
)
/
sizeof
(
devreg_t
);
i
++
)
s390_device_unregister
(
&
dasd_fba_known_devices
[
i
]);
#endif
dasd_discipline_del
(
&
dasd_fba_discipline
);
}
...
...
drivers/s390/block/dasd_genhd.c
View file @
fd791128
...
...
@@ -33,7 +33,6 @@ static struct list_head dasd_major_info = LIST_HEAD_INIT(dasd_major_info);
struct
major_info
{
struct
list_head
list
;
int
major
;
struct
gendisk
disks
[
DASD_PER_MAJOR
];
};
/*
...
...
@@ -65,12 +64,8 @@ static int
dasd_register_major
(
int
major
)
{
struct
major_info
*
mi
;
int
new_major
,
rc
;
struct
list_head
*
l
;
int
index
;
int
i
;
int
new_major
;
rc
=
0
;
/* Allocate major info structure. */
mi
=
kmalloc
(
sizeof
(
struct
major_info
),
GFP_KERNEL
);
...
...
@@ -79,66 +74,39 @@ dasd_register_major(int major)
MESSAGE
(
KERN_WARNING
,
"%s"
,
"Cannot get memory to allocate another "
"major number"
);
rc
=
-
ENOMEM
;
goto
out_error
;
return
-
ENOMEM
;
}
/* Register block device. */
new_major
=
register_blkdev
(
major
,
"dasd"
,
&
dasd_device_operations
);
if
(
new_major
<
0
)
{
MESSAGE
(
KERN_WARNING
,
"Cannot register to major no %d, rc = %d"
,
major
,
rc
);
rc
=
new_major
;
goto
out_error
;
"Cannot register to major no %d, rc = %d"
,
major
,
new_major
);
kfree
(
mi
);
return
new_major
;
}
if
(
major
!=
0
)
new_major
=
major
;
/* Initialize major info structure. */
memset
(
mi
,
0
,
sizeof
(
struct
major_info
));
mi
->
major
=
new_major
;
for
(
i
=
0
;
i
<
DASD_PER_MAJOR
;
i
++
)
{
struct
gendisk
*
disk
=
mi
->
disks
+
i
;
disk
->
major
=
new_major
;
disk
->
first_minor
=
i
<<
DASD_PARTN_BITS
;
disk
->
minor_shift
=
DASD_PARTN_BITS
;
disk
->
fops
=
&
dasd_device_operations
;
disk
->
flags
=
GENHD_FL_DEVFS
;
}
/* Setup block device pointers for the new major. */
blk_dev
[
new_major
].
queue
=
dasd_get_queue
;
/* Insert the new major info structure into dasd_major_info list. */
spin_lock
(
&
dasd_major_lock
);
index
=
0
;
list_for_each
(
l
,
&
dasd_major_info
)
index
+=
DASD_PER_MAJOR
;
for
(
i
=
0
;
i
<
DASD_PER_MAJOR
;
i
++
,
index
++
)
{
name
=
mi
->
disks
[
i
].
disk_name
;
sprintf
(
name
,
"dasd"
);
name
+=
4
;
if
(
index
>
701
)
*
name
++
=
'a'
+
(((
index
-
702
)
/
676
)
%
26
);
if
(
index
>
25
)
*
name
++
=
'a'
+
(((
index
-
26
)
/
26
)
%
26
);
sprintf
(
name
,
"%c"
,
'a'
+
(
index
%
26
));
}
list_add_tail
(
&
mi
->
list
,
&
dasd_major_info
);
spin_unlock
(
&
dasd_major_lock
);
return
0
;
/* Something failed. Do the cleanup and return rc. */
out_error:
/* We rely on kfree to do the != NULL check. */
kfree
(
mi
);
return
rc
;
}
static
void
dasd_unregister_major
(
struct
major_info
*
mi
)
{
int
major
,
rc
;
int
rc
;
if
(
mi
==
NULL
)
return
;
...
...
@@ -149,99 +117,177 @@ dasd_unregister_major(struct major_info * mi)
spin_unlock
(
&
dasd_major_lock
);
/* Clear block device pointers. */
major
=
mi
->
major
;
blk_dev
[
major
].
queue
=
NULL
;
blk_dev
[
mi
->
major
].
queue
=
NULL
;
rc
=
unregister_blkdev
(
major
,
"dasd"
);
rc
=
unregister_blkdev
(
m
i
->
m
ajor
,
"dasd"
);
if
(
rc
<
0
)
MESSAGE
(
KERN_WARNING
,
"Cannot unregister from major no %d, rc = %d"
,
major
,
rc
);
m
i
->
m
ajor
,
rc
);
/* Free memory. */
kfree
(
mi
);
}
/*
* Dynamically allocate a new major for dasd devices.
* This one is needed for naming 18000+ possible dasd devices.
* dasda - dasdz : 26 devices
* dasdaa - dasdzz : 676 devices, added up = 702
* dasdaaa - dasdzzz : 17576 devices, added up = 18278
*/
int
dasd_
gendisk_new_major
(
void
)
dasd_
device_name
(
char
*
str
,
int
index
,
int
partition
)
{
int
rc
;
rc
=
dasd_register_major
(
0
);
if
(
rc
)
DBF_EXC
(
DBF_ALERT
,
"%s"
,
"out of major numbers!"
);
return
rc
;
int
len
;
if
(
partition
>
DASD_PARTN_MASK
)
return
-
EINVAL
;
len
=
sprintf
(
str
,
"dasd"
);
if
(
index
>
25
)
{
if
(
index
>
701
)
len
+=
sprintf
(
str
+
len
,
"%c"
,
'a'
+
(((
index
-
702
)
/
676
)
%
26
));
len
+=
sprintf
(
str
+
len
,
"%c"
,
'a'
+
(((
index
-
26
)
/
26
)
%
26
));
}
len
+=
sprintf
(
str
+
len
,
"%c"
,
'a'
+
(
index
%
26
));
if
(
partition
)
len
+=
sprintf
(
str
+
len
,
"%d"
,
partition
);
return
0
;
}
/*
*
Return pointer to gendisk structure by kdev
.
*
Allocate gendisk structure for devindex
.
*/
static
struct
gendisk
*
dasd_gendisk_by_dev
(
kdev_t
dev
)
struct
gendisk
*
dasd_gendisk_alloc
(
char
*
device_name
,
int
devindex
)
{
struct
list_head
*
l
;
struct
major_info
*
mi
;
struct
gendisk
*
gdp
;
int
major
=
major
(
dev
);
spin_lock
(
&
dasd_major_lock
);
gdp
=
NULL
;
list_for_each
(
l
,
&
dasd_major_info
)
{
mi
=
list_entry
(
l
,
struct
major_info
,
list
);
if
(
mi
->
major
==
major
)
{
gdp
=
&
mi
->
disks
[
minor
(
dev
)
>>
DASD_PARTN_BITS
];
struct
hd_struct
*
gd_part
;
int
index
,
len
,
rc
;
/* Make sure the major for this device exists. */
mi
=
NULL
;
while
(
1
)
{
spin_lock
(
&
dasd_major_lock
);
index
=
devindex
;
list_for_each
(
l
,
&
dasd_major_info
)
{
mi
=
list_entry
(
l
,
struct
major_info
,
list
);
if
(
index
<
DASD_PER_MAJOR
)
break
;
index
-=
DASD_PER_MAJOR
;
}
spin_unlock
(
&
dasd_major_lock
);
if
(
index
<
DASD_PER_MAJOR
)
break
;
rc
=
dasd_register_major
(
0
);
if
(
rc
)
{
DBF_EXC
(
DBF_ALERT
,
"%s"
,
"out of major numbers!"
);
return
ERR_PTR
(
rc
);
}
}
spin_unlock
(
&
dasd_major_lock
);
/* Allocate genhd structure and gendisk arrays. */
gdp
=
kmalloc
(
sizeof
(
struct
gendisk
),
GFP_KERNEL
);
gd_part
=
kmalloc
(
sizeof
(
struct
hd_struct
)
<<
DASD_PARTN_BITS
,
GFP_ATOMIC
);
/* Check if one of the allocations failed. */
if
(
gdp
==
NULL
||
gd_part
==
NULL
)
{
/* We rely on kfree to do the != NULL check. */
kfree
(
gd_part
);
kfree
(
gdp
);
return
ERR_PTR
(
-
ENOMEM
);
}
/* Initialize gendisk structure. */
memset
(
gdp
,
0
,
sizeof
(
struct
gendisk
));
memcpy
(
gdp
->
disk_name
,
device_name
,
16
);
gdp
->
major
=
mi
->
major
;
gdp
->
first_minor
=
index
<<
DASD_PARTN_BITS
;
gdp
->
minor_shift
=
DASD_PARTN_BITS
;
gdp
->
part
=
gd_part
;
gdp
->
fops
=
&
dasd_device_operations
;
/*
* Set device name.
* dasda - dasdz : 26 devices
* dasdaa - dasdzz : 676 devices, added up = 702
* dasdaaa - dasdzzz : 17576 devices, added up = 18278
*/
len
=
sprintf
(
device_name
,
"dasd"
);
if
(
devindex
>
25
)
{
if
(
devindex
>
701
)
len
+=
sprintf
(
device_name
+
len
,
"%c"
,
'a'
+
(((
devindex
-
702
)
/
676
)
%
26
));
len
+=
sprintf
(
device_name
+
len
,
"%c"
,
'a'
+
(((
devindex
-
26
)
/
26
)
%
26
));
}
len
+=
sprintf
(
device_name
+
len
,
"%c"
,
'a'
+
(
devindex
%
26
));
/* Initialize the gendisk arrays. */
memset
(
gd_part
,
0
,
sizeof
(
struct
hd_struct
)
<<
DASD_PARTN_BITS
);
return
gdp
;
}
/*
*
Return pointer to gendisk structure by
devindex.
*
Free gendisk structure for
devindex.
*/
struct
gendisk
*
dasd_gendisk_from_devindex
(
int
devindex
)
void
dasd_gendisk_free
(
struct
gendisk
*
gdp
)
{
/* Free memory. */
kfree
(
gdp
->
part
);
kfree
(
gdp
);
}
/*
* Return devindex of first device using a specific major number.
*/
int
dasd_gendisk_major_index
(
int
major
)
{
struct
list_head
*
l
;
struct
major_info
*
mi
;
struct
gendisk
*
gdp
;
int
devindex
,
rc
;
spin_lock
(
&
dasd_major_lock
);
gdp
=
NULL
;
rc
=
-
EINVAL
;
devindex
=
0
;
list_for_each
(
l
,
&
dasd_major_info
)
{
mi
=
list_entry
(
l
,
struct
major_info
,
list
);
if
(
devindex
<
DASD_PER_MAJOR
)
{
gdp
=
&
mi
->
disks
[
devindex
]
;
if
(
mi
->
major
==
major
)
{
rc
=
devindex
;
break
;
}
devindex
-
=
DASD_PER_MAJOR
;
devindex
+
=
DASD_PER_MAJOR
;
}
spin_unlock
(
&
dasd_major_lock
);
return
gdp
;
return
rc
;
}
/*
* Return
devindex of first device using a specifiy major number
.
* Return
major number for device with device index devindex
.
*/
int
dasd_gendisk_
major_index
(
int
major
)
int
dasd_gendisk_
index_major
(
int
devindex
)
{
struct
list_head
*
l
;
struct
major_info
*
mi
;
int
devindex
,
rc
;
int
rc
;
spin_lock
(
&
dasd_major_lock
);
rc
=
-
EINVAL
;
devindex
=
0
;
rc
=
-
ENODEV
;
list_for_each
(
l
,
&
dasd_major_info
)
{
mi
=
list_entry
(
l
,
struct
major_info
,
list
);
if
(
mi
->
major
==
major
)
{
rc
=
devindex
;
if
(
devindex
<
DASD_PER_MAJOR
)
{
rc
=
mi
->
major
;
break
;
}
devindex
+
=
DASD_PER_MAJOR
;
devindex
-
=
DASD_PER_MAJOR
;
}
spin_unlock
(
&
dasd_major_lock
);
return
rc
;
...
...
@@ -253,11 +299,9 @@ int dasd_gendisk_major_index(int major)
void
dasd_setup_partitions
(
dasd_device_t
*
device
)
{
struct
gendisk
*
disk
=
dasd_gendisk_by_dev
(
device
->
kdev
);
if
(
disk
==
NULL
)
return
;
set_capacity
(
disk
,
device
->
blocks
<<
device
->
s2b_shift
);
add_disk
(
disk
);
/* Make the disk known. */
set_capacity
(
device
->
gdp
,
device
->
blocks
<<
device
->
s2b_shift
);
add_disk
(
device
->
gdp
);
}
/*
...
...
@@ -267,13 +311,7 @@ dasd_setup_partitions(dasd_device_t * device)
void
dasd_destroy_partitions
(
dasd_device_t
*
device
)
{
struct
gendisk
*
disk
=
dasd_gendisk_by_dev
(
device
->
kdev
);
int
minor
,
i
;
if
(
disk
==
NULL
)
return
;
del_gendisk
(
disk
);
del_gendisk
(
device
->
gdp
);
}
int
...
...
@@ -294,6 +332,7 @@ void
dasd_gendisk_exit
(
void
)
{
struct
list_head
*
l
,
*
n
;
spin_lock
(
&
dasd_major_lock
);
list_for_each_safe
(
l
,
n
,
&
dasd_major_info
)
dasd_unregister_major
(
list_entry
(
l
,
struct
major_info
,
list
));
...
...
drivers/s390/block/dasd_int.h
View file @
fd791128
...
...
@@ -64,12 +64,12 @@
#include <asm/irq.h>
#include <asm/s390dyn.h>
#define CONFIG_DASD_DYNAMIC
/*
* SECTION: Type definitions
*/
typedef
int
(
*
dasd_ioctl_fn_t
)
(
void
*
inp
,
int
no
,
long
args
);
struct
dasd_device_t
;
typedef
int
(
*
dasd_ioctl_fn_t
)
(
struct
block_device
*
bdev
,
int
no
,
long
args
);
typedef
struct
{
struct
list_head
list
;
...
...
@@ -139,9 +139,8 @@ do { \
/* messages to be written via klogd and dbf */
#define DEV_MESSAGE(d_loglevel,d_device,d_string,d_args...)\
do { \
printk(d_loglevel PRINTK_HEADER " /dev/%-7s(%3d:%3d),%04x@%02x: " \
d_string "\n", d_device->name, \
major(d_device->kdev), minor(d_device->kdev), \
printk(d_loglevel PRINTK_HEADER " %s,%04x@%02x: " \
d_string "\n", bdevname(d_device->bdev), \
d_device->devinfo.devno, d_device->devinfo.irq, \
d_args); \
DBF_DEV_EVENT(DBF_ALERT, d_device, d_string, d_args); \
...
...
@@ -153,8 +152,6 @@ do { \
DBF_EVENT(DBF_ALERT, d_string, d_args); \
} while(0)
struct
dasd_device_t
;
typedef
struct
dasd_ccw_req_t
{
unsigned
int
magic
;
/* Eye catcher */
struct
list_head
list
;
/* list_head for request queueing. */
...
...
@@ -262,7 +259,8 @@ typedef struct dasd_discipline_t {
typedef
struct
dasd_device_t
{
/* Block device stuff. */
char
name
[
16
];
/* The device name in /dev. */
kdev_t
kdev
;
struct
block_device
*
bdev
;
struct
gendisk
*
gdp
;
devfs_handle_t
devfs_entry
;
request_queue_t
*
request_queue
;
spinlock_t
request_queue_lock
;
...
...
@@ -467,6 +465,7 @@ dasd_devmap_t *dasd_devmap_from_devno(int);
dasd_devmap_t
*
dasd_devmap_from_devindex
(
int
);
dasd_devmap_t
*
dasd_devmap_from_irq
(
int
);
dasd_devmap_t
*
dasd_devmap_from_kdev
(
kdev_t
);
dasd_devmap_t
*
dasd_devmap_from_bdev
(
struct
block_device
*
bdev
);
dasd_device_t
*
dasd_get_device
(
dasd_devmap_t
*
);
void
dasd_put_device
(
dasd_devmap_t
*
);
...
...
@@ -478,9 +477,10 @@ int dasd_add_range(int, int, int);
/* externals in dasd_gendisk.c */
int
dasd_gendisk_init
(
void
);
void
dasd_gendisk_exit
(
void
);
int
dasd_gendisk_new_major
(
void
);
int
dasd_gendisk_major_index
(
int
);
struct
gendisk
*
dasd_gendisk_from_devindex
(
int
);
int
dasd_gendisk_index_major
(
int
);
struct
gendisk
*
dasd_gendisk_alloc
(
char
*
,
int
);
void
dasd_gendisk_free
(
struct
gendisk
*
);
void
dasd_setup_partitions
(
dasd_device_t
*
);
void
dasd_destroy_partitions
(
dasd_device_t
*
);
...
...
drivers/s390/block/dasd_ioctl.c
View file @
fd791128
This diff is collapsed.
Click to expand it.
drivers/s390/block/dasd_proc.c
View file @
fd791128
...
...
@@ -15,6 +15,7 @@
#include <linux/config.h>
#include <linux/version.h>
#include <linux/ctype.h>
#include <linux/vmalloc.h>
#include <asm/debug.h>
#include <asm/irq.h>
...
...
@@ -123,7 +124,7 @@ dasd_devices_write(struct file *file, const char *user_buf,
}
features
=
dasd_feature_list
(
str
,
&
str
);
/* Negative numbers in from/to/features indicate errors */
if
(
from
<
0
||
to
<
0
||
features
<
0
)
if
(
from
<
0
||
to
<
0
||
f
rom
>
65546
||
to
>
65536
||
f
eatures
<
0
)
goto
out_error
;
if
(
add_or_set
==
0
)
{
...
...
@@ -152,10 +153,8 @@ static inline int
dasd_devices_print
(
dasd_devmap_t
*
devmap
,
char
*
str
)
{
dasd_device_t
*
device
;
struct
gendisk
*
gdp
;
char
buffer
[
7
];
char
*
substr
;
int
minor
;
int
m
ajor
,
m
inor
;
int
len
;
device
=
dasd_get_device
(
devmap
);
...
...
@@ -169,11 +168,11 @@ dasd_devices_print(dasd_devmap_t *devmap, char *str)
else
len
+=
sprintf
(
str
+
len
,
"(none)"
);
/* Print kdev. */
gdp
=
dasd_gendisk_from_devindex
(
devmap
->
devindex
);
minor
=
devmap
->
devindex
%
DASD_PER_MAJOR
;
len
+=
sprintf
(
str
+
len
,
" at (%3d:%3d)"
,
gdp
->
major
,
minor
);
major
=
MAJOR
(
device
->
bdev
->
bd_dev
);
minor
=
MINOR
(
device
->
bdev
->
bd_dev
)
;
len
+=
sprintf
(
str
+
len
,
" at (%3d:%3d)"
,
major
,
minor
);
/* Print device name. */
len
+=
sprintf
(
str
+
len
,
" is %-7s"
,
gdp
->
disk_
name
);
len
+=
sprintf
(
str
+
len
,
" is %-7s"
,
device
->
name
);
/* Print devices features. */
substr
=
(
devmap
->
features
&
DASD_FEATURE_READONLY
)
?
"(ro)"
:
" "
;
len
+=
sprintf
(
str
+
len
,
"%4s: "
,
substr
);
...
...
include/asm-s390/dasd.h
View file @
fd791128
...
...
@@ -13,6 +13,8 @@
* 12/06/01 DASD_API_VERSION 2 - binary compatible to 0 (new BIODASDINFO2)
* 01/23/02 DASD_API_VERSION 3 - added BIODASDPSRD (and BIODASDENAPAV) IOCTL
* 02/15/02 DASD_API_VERSION 4 - added BIODASDSATTR IOCTL
* ##/##/## DASD_API_VERSION 5 - added boxed dasd support TOBEDONE
* 21/06/02 DASD_API_VERSION 6 - fixed HDIO_GETGEO: geo.start is in sectors!
*
*/
...
...
@@ -22,7 +24,7 @@
#define DASD_IOCTL_LETTER 'D'
#define DASD_API_VERSION
4
#define DASD_API_VERSION
6
/*
* struct dasd_information2_t
...
...
include/asm-s390x/dasd.h
View file @
fd791128
...
...
@@ -13,6 +13,8 @@
* 12/06/01 DASD_API_VERSION 2 - binary compatible to 0 (new BIODASDINFO2)
* 01/23/02 DASD_API_VERSION 3 - added BIODASDPSRD (and BIODASDENAPAV) IOCTL
* 02/15/02 DASD_API_VERSION 4 - added BIODASDSATTR IOCTL
* ##/##/## DASD_API_VERSION 5 - added boxed dasd support TOBEDONE
* 21/06/02 DASD_API_VERSION 6 - fixed HDIO_GETGEO: geo.start is in sectors!
*
*/
...
...
@@ -22,7 +24,7 @@
#define DASD_IOCTL_LETTER 'D'
#define DASD_API_VERSION
4
#define DASD_API_VERSION
6
/*
* struct dasd_information2_t
...
...
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