Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 135590
b: refs/heads/master
c: b44b0ab
h: refs/heads/master
v: v3
  • Loading branch information
Stefan Weinhuber authored and Martin Schwidefsky committed Mar 26, 2009
1 parent 03b0ccb commit fcdbb25
Show file tree
Hide file tree
Showing 9 changed files with 172 additions and 100 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: f9a28f7bc5225af476f8d4bb669038da8801b7c4
refs/heads/master: b44b0ab3bac16356f03e94b1b49ba9305710c445
10 changes: 5 additions & 5 deletions trunk/arch/s390/include/asm/dasd.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,15 +162,15 @@ typedef struct dasd_profile_info_t {
unsigned int dasd_io_nr_req[32]; /* histogram of # of requests in chanq */
} dasd_profile_info_t;

/*
/*
* struct format_data_t
* represents all data necessary to format a dasd
*/
typedef struct format_data_t {
int start_unit; /* from track */
int stop_unit; /* to track */
int blksize; /* sectorsize */
int intensity;
unsigned int start_unit; /* from track */
unsigned int stop_unit; /* to track */
unsigned int blksize; /* sectorsize */
unsigned int intensity;
} format_data_t;

/*
Expand Down
16 changes: 14 additions & 2 deletions trunk/arch/s390/include/asm/vtoc.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ struct vtoc_labeldate
__u16 day;
} __attribute__ ((packed));

struct vtoc_volume_label
struct vtoc_volume_label_cdl
{
char volkey[4]; /* volume key = volume label */
char vollbl[4]; /* volume label */
Expand All @@ -56,6 +56,14 @@ struct vtoc_volume_label
char res3[29]; /* reserved */
} __attribute__ ((packed));

struct vtoc_volume_label_ldl {
char vollbl[4]; /* volume label */
char volid[6]; /* volume identifier */
char res3[69]; /* reserved */
char ldl_version; /* version number, valid for ldl format */
__u64 formatted_blocks; /* valid when ldl_version >= f2 */
} __attribute__ ((packed));

struct vtoc_extent
{
__u8 typeind; /* extent type indicator */
Expand Down Expand Up @@ -140,7 +148,11 @@ struct vtoc_format4_label
char res2[10]; /* reserved */
__u8 DS4EFLVL; /* extended free-space management level */
struct vtoc_cchhb DS4EFPTR; /* pointer to extended free-space info */
char res3[9]; /* reserved */
char res3; /* reserved */
__u32 DS4DCYL; /* number of logical cyls */
char res4[2]; /* reserved */
__u8 DS4DEVF2; /* device flags */
char res5; /* reserved */
} __attribute__ ((packed));

struct vtoc_ds5ext
Expand Down
126 changes: 69 additions & 57 deletions trunk/drivers/s390/block/dasd_eckd.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,14 @@ recs_per_track(struct dasd_eckd_characteristics * rdc,
return 0;
}

static void set_ch_t(struct ch_t *geo, __u32 cyl, __u8 head)
{
geo->cyl = (__u16) cyl;
geo->head = cyl >> 16;
geo->head <<= 4;
geo->head |= head;
}

static int
check_XRC (struct ccw1 *de_ccw,
struct DE_eckd_data *data,
Expand Down Expand Up @@ -186,11 +194,12 @@ check_XRC (struct ccw1 *de_ccw,
}

static int
define_extent(struct ccw1 * ccw, struct DE_eckd_data * data, int trk,
int totrk, int cmd, struct dasd_device * device)
define_extent(struct ccw1 *ccw, struct DE_eckd_data *data, unsigned int trk,
unsigned int totrk, int cmd, struct dasd_device *device)
{
struct dasd_eckd_private *private;
struct ch_t geo, beg, end;
u32 begcyl, endcyl;
u16 heads, beghead, endhead;
int rc = 0;

private = (struct dasd_eckd_private *) device->private;
Expand Down Expand Up @@ -248,27 +257,24 @@ define_extent(struct ccw1 * ccw, struct DE_eckd_data * data, int trk,
&& !(private->uses_cdl && trk < 2))
data->ga_extended |= 0x40; /* Regular Data Format Mode */

geo.cyl = private->rdc_data.no_cyl;
geo.head = private->rdc_data.trk_per_cyl;
beg.cyl = trk / geo.head;
beg.head = trk % geo.head;
end.cyl = totrk / geo.head;
end.head = totrk % geo.head;
heads = private->rdc_data.trk_per_cyl;
begcyl = trk / heads;
beghead = trk % heads;
endcyl = totrk / heads;
endhead = totrk % heads;

/* check for sequential prestage - enhance cylinder range */
if (data->attributes.operation == DASD_SEQ_PRESTAGE ||
data->attributes.operation == DASD_SEQ_ACCESS) {

if (end.cyl + private->attrib.nr_cyl < geo.cyl)
end.cyl += private->attrib.nr_cyl;
if (endcyl + private->attrib.nr_cyl < private->real_cyl)
endcyl += private->attrib.nr_cyl;
else
end.cyl = (geo.cyl - 1);
endcyl = (private->real_cyl - 1);
}

data->beg_ext.cyl = beg.cyl;
data->beg_ext.head = beg.head;
data->end_ext.cyl = end.cyl;
data->end_ext.head = end.head;
set_ch_t(&data->beg_ext, begcyl, beghead);
set_ch_t(&data->end_ext, endcyl, endhead);
return rc;
}

Expand All @@ -294,13 +300,14 @@ static int check_XRC_on_prefix(struct PFX_eckd_data *pfxdata,
return rc;
}

static int prefix(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata, int trk,
int totrk, int cmd, struct dasd_device *basedev,
struct dasd_device *startdev)
static int prefix(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata,
unsigned int trk, unsigned int totrk, int cmd,
struct dasd_device *basedev, struct dasd_device *startdev)
{
struct dasd_eckd_private *basepriv, *startpriv;
struct DE_eckd_data *data;
struct ch_t geo, beg, end;
u32 begcyl, endcyl;
u16 heads, beghead, endhead;
int rc = 0;

basepriv = (struct dasd_eckd_private *) basedev->private;
Expand Down Expand Up @@ -374,33 +381,30 @@ static int prefix(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata, int trk,
&& !(basepriv->uses_cdl && trk < 2))
data->ga_extended |= 0x40; /* Regular Data Format Mode */

geo.cyl = basepriv->rdc_data.no_cyl;
geo.head = basepriv->rdc_data.trk_per_cyl;
beg.cyl = trk / geo.head;
beg.head = trk % geo.head;
end.cyl = totrk / geo.head;
end.head = totrk % geo.head;
heads = basepriv->rdc_data.trk_per_cyl;
begcyl = trk / heads;
beghead = trk % heads;
endcyl = totrk / heads;
endhead = totrk % heads;

/* check for sequential prestage - enhance cylinder range */
if (data->attributes.operation == DASD_SEQ_PRESTAGE ||
data->attributes.operation == DASD_SEQ_ACCESS) {

if (end.cyl + basepriv->attrib.nr_cyl < geo.cyl)
end.cyl += basepriv->attrib.nr_cyl;
if (endcyl + basepriv->attrib.nr_cyl < basepriv->real_cyl)
endcyl += basepriv->attrib.nr_cyl;
else
end.cyl = (geo.cyl - 1);
endcyl = (basepriv->real_cyl - 1);
}

data->beg_ext.cyl = beg.cyl;
data->beg_ext.head = beg.head;
data->end_ext.cyl = end.cyl;
data->end_ext.head = end.head;
set_ch_t(&data->beg_ext, begcyl, beghead);
set_ch_t(&data->end_ext, endcyl, endhead);
return rc;
}

static void
locate_record(struct ccw1 *ccw, struct LO_eckd_data *data, int trk,
int rec_on_trk, int no_rec, int cmd,
locate_record(struct ccw1 *ccw, struct LO_eckd_data *data, unsigned int trk,
unsigned int rec_on_trk, int no_rec, int cmd,
struct dasd_device * device, int reclen)
{
struct dasd_eckd_private *private;
Expand Down Expand Up @@ -493,10 +497,11 @@ locate_record(struct ccw1 *ccw, struct LO_eckd_data *data, int trk,
default:
DEV_MESSAGE(KERN_ERR, device, "unknown opcode 0x%x", cmd);
}
data->seek_addr.cyl = data->search_arg.cyl =
trk / private->rdc_data.trk_per_cyl;
data->seek_addr.head = data->search_arg.head =
trk % private->rdc_data.trk_per_cyl;
set_ch_t(&data->seek_addr,
trk / private->rdc_data.trk_per_cyl,
trk % private->rdc_data.trk_per_cyl);
data->search_arg.cyl = data->seek_addr.cyl;
data->search_arg.head = data->seek_addr.head;
data->search_arg.record = rec_on_trk;
}

Expand Down Expand Up @@ -1002,13 +1007,20 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
"rc=%d", rc);
goto out_err3;
}
/* find the vaild cylinder size */
if (private->rdc_data.no_cyl == LV_COMPAT_CYL &&
private->rdc_data.long_no_cyl)
private->real_cyl = private->rdc_data.long_no_cyl;
else
private->real_cyl = private->rdc_data.no_cyl;

DEV_MESSAGE(KERN_INFO, device,
"%04X/%02X(CU:%04X/%02X) Cyl:%d Head:%d Sec:%d",
private->rdc_data.dev_type,
private->rdc_data.dev_model,
private->rdc_data.cu_type,
private->rdc_data.cu_model.model,
private->rdc_data.no_cyl,
private->real_cyl,
private->rdc_data.trk_per_cyl,
private->rdc_data.sec_per_trk);
return 0;
Expand Down Expand Up @@ -1157,8 +1169,6 @@ dasd_eckd_end_analysis(struct dasd_block *block)
}

private->uses_cdl = 1;
/* Calculate number of blocks/records per track. */
blk_per_trk = recs_per_track(&private->rdc_data, 0, block->bp_block);
/* Check Track 0 for Compatible Disk Layout */
count_area = NULL;
for (i = 0; i < 3; i++) {
Expand Down Expand Up @@ -1200,14 +1210,14 @@ dasd_eckd_end_analysis(struct dasd_block *block)
block->s2b_shift++;

blk_per_trk = recs_per_track(&private->rdc_data, 0, block->bp_block);
block->blocks = (private->rdc_data.no_cyl *
block->blocks = (private->real_cyl *
private->rdc_data.trk_per_cyl *
blk_per_trk);

DEV_MESSAGE(KERN_INFO, device,
"(%dkB blks): %dkB at %dkB/trk %s",
(block->bp_block >> 10),
((private->rdc_data.no_cyl *
((private->real_cyl *
private->rdc_data.trk_per_cyl *
blk_per_trk * (block->bp_block >> 9)) >> 1),
((blk_per_trk * block->bp_block) >> 10),
Expand Down Expand Up @@ -1262,32 +1272,34 @@ dasd_eckd_format_device(struct dasd_device * device,
struct eckd_count *ect;
struct ccw1 *ccw;
void *data;
int rpt, cyl, head;
int rpt;
struct ch_t address;
int cplength, datasize;
int i;
int intensity = 0;
int r0_perm;

private = (struct dasd_eckd_private *) device->private;
rpt = recs_per_track(&private->rdc_data, 0, fdata->blksize);
cyl = fdata->start_unit / private->rdc_data.trk_per_cyl;
head = fdata->start_unit % private->rdc_data.trk_per_cyl;
set_ch_t(&address,
fdata->start_unit / private->rdc_data.trk_per_cyl,
fdata->start_unit % private->rdc_data.trk_per_cyl);

/* Sanity checks. */
if (fdata->start_unit >=
(private->rdc_data.no_cyl * private->rdc_data.trk_per_cyl)) {
DEV_MESSAGE(KERN_INFO, device, "Track no %d too big!",
(private->real_cyl * private->rdc_data.trk_per_cyl)) {
DEV_MESSAGE(KERN_INFO, device, "Track no %u too big!",
fdata->start_unit);
return ERR_PTR(-EINVAL);
}
if (fdata->start_unit > fdata->stop_unit) {
DEV_MESSAGE(KERN_INFO, device, "Track %d reached! ending.",
DEV_MESSAGE(KERN_INFO, device, "Track %u reached! ending.",
fdata->start_unit);
return ERR_PTR(-EINVAL);
}
if (dasd_check_blocksize(fdata->blksize) != 0) {
DEV_MESSAGE(KERN_WARNING, device,
"Invalid blocksize %d...terminating!",
"Invalid blocksize %u...terminating!",
fdata->blksize);
return ERR_PTR(-EINVAL);
}
Expand Down Expand Up @@ -1389,8 +1401,8 @@ dasd_eckd_format_device(struct dasd_device * device,
if (intensity & 0x01) { /* write record zero */
ect = (struct eckd_count *) data;
data += sizeof(struct eckd_count);
ect->cyl = cyl;
ect->head = head;
ect->cyl = address.cyl;
ect->head = address.head;
ect->record = 0;
ect->kl = 0;
ect->dl = 8;
Expand All @@ -1404,8 +1416,8 @@ dasd_eckd_format_device(struct dasd_device * device,
if ((intensity & ~0x08) & 0x04) { /* erase track */
ect = (struct eckd_count *) data;
data += sizeof(struct eckd_count);
ect->cyl = cyl;
ect->head = head;
ect->cyl = address.cyl;
ect->head = address.head;
ect->record = 1;
ect->kl = 0;
ect->dl = 0;
Expand All @@ -1418,8 +1430,8 @@ dasd_eckd_format_device(struct dasd_device * device,
for (i = 0; i < rpt; i++) {
ect = (struct eckd_count *) data;
data += sizeof(struct eckd_count);
ect->cyl = cyl;
ect->head = head;
ect->cyl = address.cyl;
ect->head = address.head;
ect->record = i + 1;
ect->kl = 0;
ect->dl = fdata->blksize;
Expand Down
9 changes: 8 additions & 1 deletion trunk/drivers/s390/block/dasd_eckd.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@
#define PSF_ORDER_PRSSD 0x18
#define PSF_ORDER_SSC 0x1D

/*
* Size that is reportet for large volumes in the old 16-bit no_cyl field
*/
#define LV_COMPAT_CYL 0xFFFE

/*****************************************************************************
* SECTION: Type Definitions
****************************************************************************/
Expand Down Expand Up @@ -228,7 +233,8 @@ struct dasd_eckd_characteristics {
__u8 factor7;
__u8 factor8;
__u8 reserved2[3];
__u8 reserved3[10];
__u8 reserved3[6];
__u32 long_no_cyl;
} __attribute__ ((packed));

/* elements of the configuration data */
Expand Down Expand Up @@ -406,6 +412,7 @@ struct dasd_eckd_private {
int uses_cdl;
struct attrib_data_t attrib; /* e.g. cache operations */
struct dasd_rssd_features features;
u32 real_cyl;

/* alias managemnet */
struct dasd_uid uid;
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/s390/block/dasd_int.h
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ struct dasd_block {
struct block_device *bdev;
atomic_t open_count;

unsigned long blocks; /* size of volume in blocks */
unsigned long long blocks; /* size of volume in blocks */
unsigned int bp_block; /* bytes per block */
unsigned int s2b_shift; /* log2 (bp_block/512) */

Expand Down
4 changes: 2 additions & 2 deletions trunk/drivers/s390/block/dasd_ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ static int dasd_format(struct dasd_block *block, struct format_data_t *fdata)
}

DBF_DEV_EVENT(DBF_NOTICE, base,
"formatting units %d to %d (%d B blocks) flags %d",
"formatting units %u to %u (%u B blocks) flags %u",
fdata->start_unit,
fdata->stop_unit, fdata->blksize, fdata->intensity);

Expand All @@ -170,7 +170,7 @@ static int dasd_format(struct dasd_block *block, struct format_data_t *fdata)
if (rc) {
if (rc != -ERESTARTSYS)
DEV_MESSAGE(KERN_ERR, base,
" Formatting of unit %d failed "
" Formatting of unit %u failed "
"with rc = %d",
fdata->start_unit, rc);
return rc;
Expand Down
Loading

0 comments on commit fcdbb25

Please sign in to comment.