Commit 86cb69b7 authored by Martin Schwidefsky's avatar Martin Schwidefsky Committed by Linus Torvalds

[PATCH] s390 (3/7): dasd driver.

 - Remove dynamic allocation of major numbers. Just use static major 94.
 - Use bus_id instead of device number where possible.
 - Don't check open_count in dasd_generic_set_offline.
parent 748f7f37
......@@ -7,7 +7,7 @@
* Bugreports.to..: <Linux390@de.ibm.com>
* (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001
*
* $Revision: 1.110 $
* $Revision: 1.114 $
*/
#include <linux/config.h>
......@@ -1142,8 +1142,8 @@ __dasd_process_blk_queue(struct dasd_device * device)
req = elv_next_request(queue);
if (device->ro_flag && rq_data_dir(req) == WRITE) {
DBF_EVENT(DBF_ERR,
"(%04x) Rejecting write request %p",
_ccw_device_get_device_number(device->cdev),
"(%s) Rejecting write request %p",
device->cdev->dev.bus_id,
req);
blkdev_dequeue_request(req);
dasd_end_request(req, 0);
......@@ -1154,8 +1154,8 @@ __dasd_process_blk_queue(struct dasd_device * device)
if (PTR_ERR(cqr) == -ENOMEM)
break; /* terminate request queue loop */
DBF_EVENT(DBF_ERR,
"(%04x) CCW creation failed on request %p",
_ccw_device_get_device_number(device->cdev),
"(%s) CCW creation failed on request %p",
device->cdev->dev.bus_id,
req);
blkdev_dequeue_request(req);
dasd_end_request(req, 0);
......@@ -1728,12 +1728,10 @@ int
dasd_generic_probe (struct ccw_device *cdev,
struct dasd_discipline *discipline)
{
int devno;
int ret = 0;
devno = _ccw_device_get_device_number(cdev);
if (dasd_autodetect
&& (ret = dasd_add_range(devno, devno, DASD_FEATURE_DEFAULT))) {
if (dasd_autodetect &&
(ret = dasd_add_busid(cdev->dev.bus_id, DASD_FEATURE_DEFAULT))) {
printk (KERN_WARNING
"dasd_generic_probe: cannot autodetect %s\n",
cdev->dev.bus_id);
......@@ -1830,12 +1828,6 @@ dasd_generic_set_offline (struct ccw_device *cdev)
struct dasd_device *device;
device = cdev->dev.driver_data;
if (atomic_read(&device->open_count) > 0) {
printk (KERN_WARNING "Can't offline dasd device with open"
" count = %i.\n",
atomic_read(&device->open_count));
return -EBUSY;
}
dasd_set_target_state(device, DASD_STATE_NEW);
dasd_delete_device(device);
......@@ -1854,7 +1846,6 @@ dasd_generic_auto_online (struct ccw_driver *dasd_discipline_driver)
struct device_driver *drv;
struct device *d, *dev;
struct ccw_device *cdev;
int devno;
drv = get_driver(&dasd_discipline_driver->driver);
down_read(&drv->bus->subsys.rwsem);
......@@ -1864,8 +1855,7 @@ dasd_generic_auto_online (struct ccw_driver *dasd_discipline_driver)
if (!dev)
continue;
cdev = to_ccwdev(dev);
devno = _ccw_device_get_device_number(cdev);
if (dasd_autodetect || dasd_devno_in_range(devno) == 0)
if (dasd_autodetect || dasd_busid_known(cdev->dev.bus_id) == 0)
ccw_device_set_online(cdev);
put_device(dev);
}
......@@ -1934,31 +1924,6 @@ dasd_use_diag_store(struct device *dev, const char *buf, size_t count)
static
DEVICE_ATTR(use_diag, 0644, dasd_use_diag_show, dasd_use_diag_store);
#if 0
/* this file shows the same information as /proc/dasd/devices using
* an inaccaptable interface */
/* TODO: Split this up into smaller files! */
static ssize_t
dasd_devices_show(struct device *dev, char *buf)
{
struct dasd_device *device;
dasd_devmap_t *devmap;
devmap = NULL;
device = dev->driver_data;
if (device)
devmap = dasd_devmap_from_devno(device->devno);
if (!devmap)
return sprintf(buf, "unused\n");
return min ((size_t) dasd_devices_print(devmap, buf), PAGE_SIZE);
}
static DEVICE_ATTR(dasd, 0444, dasd_devices_show, 0);
#endif
static ssize_t
dasd_discipline_show(struct device *dev, char *buf)
{
......@@ -1973,7 +1938,6 @@ dasd_discipline_show(struct device *dev, char *buf)
static DEVICE_ATTR(discipline, 0444, dasd_discipline_show, NULL);
static struct attribute * dasd_attrs[] = {
//&dev_attr_dasd.attr,
&dev_attr_readonly.attr,
&dev_attr_discipline.attr,
&dev_attr_use_diag.attr,
......
This diff is collapsed.
......@@ -7,9 +7,9 @@
* Bugreports.to..: <Linux390@de.ibm.com>
* (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001
*
* Dealing with devices registered to multiple major numbers.
* gendisk related functions for the dasd driver.
*
* $Revision: 1.38 $
* $Revision: 1.41 $
*/
#include <linux/config.h>
......@@ -24,116 +24,26 @@
#include "dasd_int.h"
static spinlock_t dasd_major_lock = SPIN_LOCK_UNLOCKED;
static struct list_head dasd_major_info = LIST_HEAD_INIT(dasd_major_info);
struct major_info {
struct list_head list;
int major;
};
/*
* Register major number for the dasd driver. Call with DASD_MAJOR to
* setup the static dasd device major 94 or with 0 to allocated a major
* dynamically.
*/
static int
dasd_register_major(int major)
{
struct major_info *mi;
int new_major;
/* Allocate major info structure. */
mi = kmalloc(sizeof(struct major_info), GFP_KERNEL);
/* Check if one of the allocations failed. */
if (mi == NULL) {
MESSAGE(KERN_WARNING, "%s",
"Cannot get memory to allocate another "
"major number");
return -ENOMEM;
}
/* Register block device. */
new_major = register_blkdev(major, "dasd");
if (new_major < 0) {
kfree(mi);
return new_major;
}
if (major != 0)
new_major = major;
/* Initialize major info structure. */
mi->major = new_major;
/* Insert the new major info structure into dasd_major_info list. */
spin_lock(&dasd_major_lock);
list_add_tail(&mi->list, &dasd_major_info);
spin_unlock(&dasd_major_lock);
return 0;
}
static void
dasd_unregister_major(struct major_info * mi)
{
int rc;
if (mi == NULL)
return;
/* Delete the major info from dasd_major_info. */
spin_lock(&dasd_major_lock);
list_del(&mi->list);
spin_unlock(&dasd_major_lock);
rc = unregister_blkdev(mi->major, "dasd");
if (rc < 0)
MESSAGE(KERN_WARNING,
"Cannot unregister from major no %d, rc = %d",
mi->major, rc);
/* Free memory. */
kfree(mi);
}
/*
* Allocate and register gendisk structure for device.
*/
int
dasd_gendisk_alloc(struct dasd_device *device)
{
struct major_info *mi;
struct gendisk *gdp;
int index, len, rc;
/* Make sure the major for this device exists. */
mi = NULL;
while (1) {
spin_lock(&dasd_major_lock);
index = device->devindex;
list_for_each_entry(mi, &dasd_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 rc;
}
}
int len;
/* Make sure the minor for this device exists. */
if (device->devindex >= DASD_PER_MAJOR)
return -EBUSY;
gdp = alloc_disk(1 << DASD_PARTN_BITS);
if (!gdp)
return -ENOMEM;
/* Initialize gendisk structure. */
gdp->major = mi->major;
gdp->first_minor = index << DASD_PARTN_BITS;
gdp->major = DASD_MAJOR;
gdp->first_minor = device->devindex << DASD_PARTN_BITS;
gdp->fops = &dasd_device_operations;
gdp->driverfs_dev = &device->cdev->dev;
......@@ -153,8 +63,7 @@ dasd_gendisk_alloc(struct dasd_device *device)
}
len += sprintf(gdp->disk_name + len, "%c", 'a'+(device->devindex%26));
sprintf(gdp->devfs_name, "dasd/%04x",
_ccw_device_get_device_number(device->cdev));
sprintf(gdp->devfs_name, "dasd/%s", device->cdev->dev.bus_id);
if (device->ro_flag)
set_disk_ro(gdp, 1);
......@@ -173,6 +82,7 @@ void
dasd_gendisk_free(struct dasd_device *device)
{
del_gendisk(device->gdp);
device->gdp->queue = 0;
put_disk(device->gdp);
device->gdp = 0;
}
......@@ -221,7 +131,7 @@ dasd_gendisk_init(void)
int rc;
/* Register to static dasd major 94 */
rc = dasd_register_major(DASD_MAJOR);
rc = register_blkdev(DASD_MAJOR, "dasd");
if (rc != 0) {
MESSAGE(KERN_WARNING,
"Couldn't register successfully to "
......@@ -234,10 +144,5 @@ dasd_gendisk_init(void)
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));
spin_unlock(&dasd_major_lock);
unregister_blkdev(DASD_MAJOR, "dasd");
}
......@@ -6,7 +6,7 @@
* Bugreports.to..: <Linux390@de.ibm.com>
* (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
*
* $Revision: 1.45 $
* $Revision: 1.48 $
*/
#ifndef DASD_INT_H
......@@ -15,7 +15,7 @@
#ifdef __KERNEL__
/* we keep old device allocation scheme; IOW, minors are still in 0..255 */
#define DASD_PER_MAJOR ( 1U<<(8-DASD_PARTN_BITS))
#define DASD_PER_MAJOR (1U << (MINORBITS - DASD_PARTN_BITS))
#define DASD_PARTN_MASK ((1 << DASD_PARTN_BITS) - 1)
/*
......@@ -477,8 +477,8 @@ void dasd_delete_device(struct dasd_device *);
struct dasd_device *dasd_device_from_devindex(int);
int dasd_parse(void);
int dasd_add_range(int, int, int);
int dasd_devno_in_range(int);
int dasd_add_busid(char *, int);
int dasd_busid_known(char *);
/* externals in dasd_gendisk.c */
int dasd_gendisk_init(void);
......
......@@ -9,7 +9,7 @@
*
* /proc interface for the dasd driver.
*
* $Revision: 1.22 $
* $Revision: 1.23 $
*/
#include <linux/config.h>
......@@ -59,7 +59,7 @@ dasd_devices_show(struct seq_file *m, void *v)
if (IS_ERR(device))
return 0;
/* Print device number. */
seq_printf(m, "%04x", _ccw_device_get_device_number(device->cdev));
seq_printf(m, "%s", device->cdev->dev.bus_id);
/* Print discipline string. */
if (device != NULL && device->discipline != NULL)
seq_printf(m, "(%s)", device->discipline->name);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment