Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 26299
b: refs/heads/master
c: 3d05259
h: refs/heads/master
i:
  26297: 1434ecd
  26295: ab0bb17
v: v3
  • Loading branch information
Horst Hummel authored and Linus Torvalds committed Apr 28, 2006
1 parent b325cae commit dd480c0
Show file tree
Hide file tree
Showing 5 changed files with 192 additions and 21 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: 58268b97f679108d32a882a7fc029585da801975
refs/heads/master: 3d052595423b4432f4d599c1aeb1949ac0da7314
102 changes: 102 additions & 0 deletions trunk/drivers/s390/block/dasd_devmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ struct dasd_devmap {
unsigned int devindex;
unsigned short features;
struct dasd_device *device;
struct dasd_uid uid;
};

/*
Expand Down Expand Up @@ -716,6 +717,68 @@ dasd_discipline_show(struct device *dev, struct device_attribute *attr, char *bu

static DEVICE_ATTR(discipline, 0444, dasd_discipline_show, NULL);

static ssize_t
dasd_alias_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct dasd_devmap *devmap;
int alias;

devmap = dasd_find_busid(dev->bus_id);
spin_lock(&dasd_devmap_lock);
if (!IS_ERR(devmap))
alias = devmap->uid.alias;
else
alias = 0;
spin_unlock(&dasd_devmap_lock);

return sprintf(buf, alias ? "1\n" : "0\n");
}

static DEVICE_ATTR(alias, 0444, dasd_alias_show, NULL);

static ssize_t
dasd_vendor_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct dasd_devmap *devmap;
char *vendor;

devmap = dasd_find_busid(dev->bus_id);
spin_lock(&dasd_devmap_lock);
if (!IS_ERR(devmap) && strlen(devmap->uid.vendor) > 0)
vendor = devmap->uid.vendor;
else
vendor = "";
spin_unlock(&dasd_devmap_lock);

return snprintf(buf, PAGE_SIZE, "%s\n", vendor);
}

static DEVICE_ATTR(vendor, 0444, dasd_vendor_show, NULL);

#define UID_STRLEN ( /* vendor */ 3 + 1 + /* serial */ 14 + 1 +\
/* SSID */ 4 + 1 + /* unit addr */ 2 + 1)

static ssize_t
dasd_uid_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct dasd_devmap *devmap;
char uid[UID_STRLEN];

devmap = dasd_find_busid(dev->bus_id);
spin_lock(&dasd_devmap_lock);
if (!IS_ERR(devmap) && strlen(devmap->uid.vendor) > 0)
snprintf(uid, sizeof(uid), "%s.%s.%04x.%02x",
devmap->uid.vendor, devmap->uid.serial,
devmap->uid.ssid, devmap->uid.unit_addr);
else
uid[0] = 0;
spin_unlock(&dasd_devmap_lock);

return snprintf(buf, PAGE_SIZE, "%s\n", uid);
}

static DEVICE_ATTR(uid, 0444, dasd_uid_show, NULL);

/*
* extended error-reporting
*/
Expand Down Expand Up @@ -759,6 +822,9 @@ static DEVICE_ATTR(eer_enabled, 0644, dasd_eer_show, dasd_eer_store);
static struct attribute * dasd_attrs[] = {
&dev_attr_readonly.attr,
&dev_attr_discipline.attr,
&dev_attr_alias.attr,
&dev_attr_vendor.attr,
&dev_attr_uid.attr,
&dev_attr_use_diag.attr,
&dev_attr_eer_enabled.attr,
NULL,
Expand All @@ -768,6 +834,42 @@ static struct attribute_group dasd_attr_group = {
.attrs = dasd_attrs,
};


/*
* Return copy of the device unique identifier.
*/
int
dasd_get_uid(struct ccw_device *cdev, struct dasd_uid *uid)
{
struct dasd_devmap *devmap;

devmap = dasd_find_busid(cdev->dev.bus_id);
if (IS_ERR(devmap))
return PTR_ERR(devmap);
spin_lock(&dasd_devmap_lock);
*uid = devmap->uid;
spin_unlock(&dasd_devmap_lock);
return 0;
}

/*
* Register the given device unique identifier into devmap struct.
*/
int
dasd_set_uid(struct ccw_device *cdev, struct dasd_uid *uid)
{
struct dasd_devmap *devmap;

devmap = dasd_find_busid(cdev->dev.bus_id);
if (IS_ERR(devmap))
return PTR_ERR(devmap);
spin_lock(&dasd_devmap_lock);
devmap->uid = *uid;
spin_unlock(&dasd_devmap_lock);
return 0;
}
EXPORT_SYMBOL(dasd_set_uid);

/*
* Return value of the specified feature.
*/
Expand Down
51 changes: 49 additions & 2 deletions trunk/drivers/s390/block/dasd_eckd.c
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,39 @@ dasd_eckd_cdl_reclen(int recid)
return LABEL_SIZE;
}

/*
* Generate device unique id that specifies the physical device.
*/
static int
dasd_eckd_generate_uid(struct dasd_device *device, struct dasd_uid *uid)
{
struct dasd_eckd_private *private;
struct dasd_eckd_confdata *confdata;

private = (struct dasd_eckd_private *) device->private;
if (!private)
return -ENODEV;
confdata = &private->conf_data;
if (!confdata)
return -ENODEV;

memset(uid, 0, sizeof(struct dasd_uid));
strncpy(uid->vendor, confdata->ned1.HDA_manufacturer,
sizeof(uid->vendor) - 1);
EBCASC(uid->vendor, sizeof(uid->vendor) - 1);
strncpy(uid->serial, confdata->ned1.HDA_location,
sizeof(uid->serial) - 1);
EBCASC(uid->serial, sizeof(uid->serial) - 1);
uid->ssid = confdata->neq.subsystemID;
if (confdata->ned2.sneq.flags == 0x40) {
uid->alias = 1;
uid->unit_addr = confdata->ned2.sneq.base_unit_addr;
} else
uid->unit_addr = confdata->ned1.unit_addr;

return 0;
}

static int
dasd_eckd_read_conf(struct dasd_device *device)
{
Expand Down Expand Up @@ -507,11 +540,15 @@ dasd_eckd_read_conf(struct dasd_device *device)
return 0;
}


/*
* Check device characteristics.
* If the device is accessible using ECKD discipline, the device is enabled.
*/
static int
dasd_eckd_check_characteristics(struct dasd_device *device)
{
struct dasd_eckd_private *private;
struct dasd_uid uid;
void *rdc_data;
int rc;

Expand All @@ -536,6 +573,7 @@ dasd_eckd_check_characteristics(struct dasd_device *device)

/* Read Device Characteristics */
rdc_data = (void *) &(private->rdc_data);
memset(rdc_data, 0, sizeof(rdc_data));
rc = read_dev_chars(device->cdev, &rdc_data, 64);
if (rc) {
DEV_MESSAGE(KERN_WARNING, device,
Expand All @@ -556,8 +594,17 @@ dasd_eckd_check_characteristics(struct dasd_device *device)

/* Read Configuration Data */
rc = dasd_eckd_read_conf (device);
return rc;
if (rc)
return rc;

/* Generate device unique id and register in devmap */
rc = dasd_eckd_generate_uid(device, &uid);
if (rc)
return rc;

rc = dasd_set_uid(device->cdev, &uid);

return rc;
}

static struct dasd_ccw_req *
Expand Down
46 changes: 28 additions & 18 deletions trunk/drivers/s390/block/dasd_eckd.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,26 +228,36 @@ struct dasd_eckd_confdata {
unsigned char HDA_manufacturer[3];
unsigned char HDA_location[2];
unsigned char HDA_seqno[12];
__u16 ID;
__u8 ID;
__u8 unit_addr;
} __attribute__ ((packed)) ned1;
struct {
union {
struct {
unsigned char identifier:2;
unsigned char token_id:1;
unsigned char sno_valid:1;
unsigned char subst_sno:1;
unsigned char recNED:1;
unsigned char emuNED:1;
unsigned char reserved:1;
} __attribute__ ((packed)) flags;
__u8 descriptor;
__u8 reserved[2];
unsigned char dev_type[6];
unsigned char dev_model[3];
unsigned char DASD_manufacturer[3];
unsigned char DASD_location[2];
unsigned char DASD_seqno[12];
__u16 ID;
struct {
unsigned char identifier:2;
unsigned char token_id:1;
unsigned char sno_valid:1;
unsigned char subst_sno:1;
unsigned char recNED:1;
unsigned char emuNED:1;
unsigned char reserved:1;
} __attribute__ ((packed)) flags;
__u8 descriptor;
__u8 reserved[2];
unsigned char dev_type[6];
unsigned char dev_model[3];
unsigned char DASD_manufacturer[3];
unsigned char DASD_location[2];
unsigned char DASD_seqno[12];
__u16 ID;
} __attribute__ ((packed)) ned;
struct {
unsigned char flags; /* byte 0 */
unsigned char res2[7]; /* byte 1- 7 */
unsigned char sua_flags; /* byte 8 */
__u8 base_unit_addr; /* byte 9 */
unsigned char res3[22]; /* byte 10-31 */
} __attribute__ ((packed)) sneq;
} __attribute__ ((packed)) ned2;
struct {
struct {
Expand Down
12 changes: 12 additions & 0 deletions trunk/drivers/s390/block/dasd_int.h
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,16 @@ struct dasd_discipline {

extern struct dasd_discipline *dasd_diag_discipline_pointer;

/*
* Unique identifier for dasd device.
*/
struct dasd_uid {
__u8 alias;
char vendor[4];
char serial[15];
__u16 ssid;
__u8 unit_addr;
};

/*
* Notification numbers for extended error reporting notifications:
Expand Down Expand Up @@ -516,6 +526,8 @@ void dasd_devmap_exit(void);
struct dasd_device *dasd_create_device(struct ccw_device *);
void dasd_delete_device(struct dasd_device *);

int dasd_get_uid(struct ccw_device *, struct dasd_uid *);
int dasd_set_uid(struct ccw_device *, struct dasd_uid *);
int dasd_get_feature(struct ccw_device *, int);
int dasd_set_feature(struct ccw_device *, int, int);

Expand Down

0 comments on commit dd480c0

Please sign in to comment.