Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 064922a8 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (40 commits)
  [SCSI] jazz_esp, sgiwd93, sni_53c710, sun3x_esp: fix platform driver hotplug/coldplug
  [SCSI] aic7xxx: add const
  [SCSI] aic7xxx: add static
  [SCSI] aic7xxx: Update _shipped files
  [SCSI] aic7xxx: teach aicasm to not emit unused debug code/data
  [SCSI] qla2xxx: Update version number to 8.02.01-k2.
  [SCSI] qla2xxx: Correct regression in relogin code.
  [SCSI] qla2xxx: Correct misc. endian and byte-ordering issues.
  [SCSI] qla2xxx: make qla2x00_issue_iocb_timeout() static
  [SCSI] qla2xxx: qla_os.c, make 2 functions static
  [SCSI] qla2xxx: Re-register FDMI information after a LIP.
  [SCSI] qla2xxx: Correct SRB usage-after-completion/free issues.
  [SCSI] qla2xxx: Correct ISP84XX verify-chip response handling.
  [SCSI] qla2xxx: Wakeup DPC thread to process any deferred-work requests.
  [SCSI] qla2xxx: Collapse RISC-RAM retrieval code during a firmware-dump.
  [SCSI] m68k: new mac_esp scsi driver
  [SCSI] zfcp: Add some statistics provided by the FCP adapter to the sysfs
  [SCSI] zfcp: Print some messages only during ERP
  [SCSI] zfcp: Wait for free SBAL during exchange config
  [SCSI] scsi_transport_fc: fc_user_scan correction
  ...
parents 42cadc86 ecc1241e
Loading
Loading
Loading
Loading
+29 −14
Original line number Diff line number Diff line
@@ -699,14 +699,26 @@ static struct bsg_device *bsg_alloc_device(void)
	return bd;
}

static void bsg_kref_release_function(struct kref *kref)
{
	struct bsg_class_device *bcd =
		container_of(kref, struct bsg_class_device, ref);

	if (bcd->release)
		bcd->release(bcd->parent);

	put_device(bcd->parent);
}

static int bsg_put_device(struct bsg_device *bd)
{
	int ret = 0;
	struct device *dev = bd->queue->bsg_dev.dev;
	int ret = 0, do_free;
	struct request_queue *q = bd->queue;

	mutex_lock(&bsg_mutex);

	if (!atomic_dec_and_test(&bd->ref_count))
	do_free = atomic_dec_and_test(&bd->ref_count);
	if (!do_free)
		goto out;

	dprintk("%s: tearing down\n", bd->name);
@@ -723,12 +735,13 @@ static int bsg_put_device(struct bsg_device *bd)
	 */
	ret = bsg_complete_all_commands(bd);

	blk_put_queue(bd->queue);
	hlist_del(&bd->dev_list);
	kfree(bd);
out:
	mutex_unlock(&bsg_mutex);
	put_device(dev);
	kref_put(&q->bsg_dev.ref, bsg_kref_release_function);
	if (do_free)
		blk_put_queue(q);
	return ret;
}

@@ -796,7 +809,7 @@ static struct bsg_device *bsg_get_device(struct inode *inode, struct file *file)
	mutex_lock(&bsg_mutex);
	bcd = idr_find(&bsg_minor_idr, iminor(inode));
	if (bcd)
		get_device(bcd->dev);
		kref_get(&bcd->ref);
	mutex_unlock(&bsg_mutex);

	if (!bcd)
@@ -808,7 +821,7 @@ static struct bsg_device *bsg_get_device(struct inode *inode, struct file *file)

	bd = bsg_add_device(inode, bcd->queue, file);
	if (IS_ERR(bd))
		put_device(bcd->dev);
		kref_put(&bcd->ref, bsg_kref_release_function);

	return bd;
}
@@ -947,14 +960,14 @@ void bsg_unregister_queue(struct request_queue *q)
	idr_remove(&bsg_minor_idr, bcd->minor);
	sysfs_remove_link(&q->kobj, "bsg");
	device_unregister(bcd->class_dev);
	put_device(bcd->dev);
	bcd->class_dev = NULL;
	kref_put(&bcd->ref, bsg_kref_release_function);
	mutex_unlock(&bsg_mutex);
}
EXPORT_SYMBOL_GPL(bsg_unregister_queue);

int bsg_register_queue(struct request_queue *q, struct device *gdev,
		       const char *name)
int bsg_register_queue(struct request_queue *q, struct device *parent,
		       const char *name, void (*release)(struct device *))
{
	struct bsg_class_device *bcd;
	dev_t dev;
@@ -965,7 +978,7 @@ int bsg_register_queue(struct request_queue *q, struct device *gdev,
	if (name)
		devname = name;
	else
		devname = gdev->bus_id;
		devname = parent->bus_id;

	/*
	 * we need a proper transport to send commands, not a stacked device
@@ -996,9 +1009,11 @@ int bsg_register_queue(struct request_queue *q, struct device *gdev,

	bcd->minor = minor;
	bcd->queue = q;
	bcd->dev = get_device(gdev);
	bcd->parent = get_device(parent);
	bcd->release = release;
	kref_init(&bcd->ref);
	dev = MKDEV(bsg_major, bcd->minor);
	class_dev = device_create(bsg_class, gdev, dev, "%s", devname);
	class_dev = device_create(bsg_class, parent, dev, "%s", devname);
	if (IS_ERR(class_dev)) {
		ret = PTR_ERR(class_dev);
		goto put_dev;
@@ -1017,7 +1032,7 @@ int bsg_register_queue(struct request_queue *q, struct device *gdev,
unregister_class_dev:
	device_unregister(class_dev);
put_dev:
	put_device(gdev);
	put_device(parent);
remove_idr:
	idr_remove(&bsg_minor_idr, minor);
unlock:
+71 −29
Original line number Diff line number Diff line
@@ -31,7 +31,6 @@
static LIST_HEAD(container_list);
static DEFINE_MUTEX(container_list_lock);
static struct class enclosure_class;
static struct class enclosure_component_class;

/**
 * enclosure_find - find an enclosure given a device
@@ -166,6 +165,40 @@ void enclosure_unregister(struct enclosure_device *edev)
}
EXPORT_SYMBOL_GPL(enclosure_unregister);

#define ENCLOSURE_NAME_SIZE	64

static void enclosure_link_name(struct enclosure_component *cdev, char *name)
{
	strcpy(name, "enclosure_device:");
	strcat(name, cdev->cdev.bus_id);
}

static void enclosure_remove_links(struct enclosure_component *cdev)
{
	char name[ENCLOSURE_NAME_SIZE];

	enclosure_link_name(cdev, name);
	sysfs_remove_link(&cdev->dev->kobj, name);
	sysfs_remove_link(&cdev->cdev.kobj, "device");
}

static int enclosure_add_links(struct enclosure_component *cdev)
{
	int error;
	char name[ENCLOSURE_NAME_SIZE];

	error = sysfs_create_link(&cdev->cdev.kobj, &cdev->dev->kobj, "device");
	if (error)
		return error;

	enclosure_link_name(cdev, name);
	error = sysfs_create_link(&cdev->dev->kobj, &cdev->cdev.kobj, name);
	if (error)
		sysfs_remove_link(&cdev->cdev.kobj, "device");

	return error;
}

static void enclosure_release(struct device *cdev)
{
	struct enclosure_device *edev = to_enclosure_device(cdev);
@@ -178,10 +211,15 @@ static void enclosure_component_release(struct device *dev)
{
	struct enclosure_component *cdev = to_enclosure_component(dev);

	if (cdev->dev) {
		enclosure_remove_links(cdev);
		put_device(cdev->dev);
	}
	put_device(dev->parent);
}

static struct attribute_group *enclosure_groups[];

/**
 * enclosure_component_register - add a particular component to an enclosure
 * @edev:	the enclosure to add the component
@@ -217,12 +255,14 @@ enclosure_component_register(struct enclosure_device *edev,
	ecomp->number = number;
	cdev = &ecomp->cdev;
	cdev->parent = get_device(&edev->edev);
	cdev->class = &enclosure_component_class;
	if (name)
		snprintf(cdev->bus_id, BUS_ID_SIZE, "%s", name);
	else
		snprintf(cdev->bus_id, BUS_ID_SIZE, "%u", number);

	cdev->release = enclosure_component_release;
	cdev->groups = enclosure_groups;

	err = device_register(cdev);
	if (err)
		ERR_PTR(err);
@@ -255,10 +295,12 @@ int enclosure_add_device(struct enclosure_device *edev, int component,

	cdev = &edev->component[component];

	device_del(&cdev->cdev);
	if (cdev->dev)
		enclosure_remove_links(cdev);

	put_device(cdev->dev);
	cdev->dev = get_device(dev);
	return device_add(&cdev->cdev);
	return enclosure_add_links(cdev);
}
EXPORT_SYMBOL_GPL(enclosure_add_device);

@@ -442,24 +484,32 @@ static ssize_t get_component_type(struct device *cdev,
}


static struct device_attribute enclosure_component_attrs[] = {
	__ATTR(fault, S_IRUGO | S_IWUSR, get_component_fault,
	       set_component_fault),
	__ATTR(status, S_IRUGO | S_IWUSR, get_component_status,
	       set_component_status),
	__ATTR(active, S_IRUGO | S_IWUSR, get_component_active,
	       set_component_active),
	__ATTR(locate, S_IRUGO | S_IWUSR, get_component_locate,
	       set_component_locate),
	__ATTR(type, S_IRUGO, get_component_type, NULL),
	__ATTR_NULL
static DEVICE_ATTR(fault, S_IRUGO | S_IWUSR, get_component_fault,
		    set_component_fault);
static DEVICE_ATTR(status, S_IRUGO | S_IWUSR, get_component_status,
		   set_component_status);
static DEVICE_ATTR(active, S_IRUGO | S_IWUSR, get_component_active,
		   set_component_active);
static DEVICE_ATTR(locate, S_IRUGO | S_IWUSR, get_component_locate,
		   set_component_locate);
static DEVICE_ATTR(type, S_IRUGO, get_component_type, NULL);

static struct attribute *enclosure_component_attrs[] = {
	&dev_attr_fault.attr,
	&dev_attr_status.attr,
	&dev_attr_active.attr,
	&dev_attr_locate.attr,
	&dev_attr_type.attr,
	NULL
};

static struct class enclosure_component_class =  {
	.name			= "enclosure_component",
	.owner			= THIS_MODULE,
	.dev_attrs	= enclosure_component_attrs,
	.dev_release		= enclosure_component_release,
static struct attribute_group enclosure_group = {
	.attrs = enclosure_component_attrs,
};

static struct attribute_group *enclosure_groups[] = {
	&enclosure_group,
	NULL
};

static int __init enclosure_init(void)
@@ -469,20 +519,12 @@ static int __init enclosure_init(void)
	err = class_register(&enclosure_class);
	if (err)
		return err;
	err = class_register(&enclosure_component_class);
	if (err)
		goto err_out;

	return 0;
 err_out:
	class_unregister(&enclosure_class);

	return err;
}

static void __exit enclosure_exit(void)
{
	class_unregister(&enclosure_component_class);
	class_unregister(&enclosure_class);
}

+21 −18
Original line number Diff line number Diff line
@@ -1927,7 +1927,8 @@ zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *adapter,

	/* setup new FSF request */
	retval = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_CONFIG_DATA,
				     0, NULL, &lock_flags, &fsf_req);
				     ZFCP_WAIT_FOR_SBAL, NULL, &lock_flags,
				     &fsf_req);
	if (retval) {
		ZFCP_LOG_INFO("error: Could not create exchange configuration "
			      "data request for adapter %s.\n",
@@ -2035,10 +2036,10 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok)
		       min(FC_SERIAL_NUMBER_SIZE, 17));
	}

	if (fsf_req->erp_action)
		ZFCP_LOG_NORMAL("The adapter %s reported the following "
				"characteristics:\n"
			"WWNN 0x%016Lx, "
			"WWPN 0x%016Lx, "
				"WWNN 0x%016Lx, WWPN 0x%016Lx, "
				"S_ID 0x%06x,\n"
				"adapter version 0x%x, "
				"LIC version 0x%x, "
@@ -2114,8 +2115,10 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req)
			zfcp_erp_adapter_shutdown(adapter, 0, 127, fsf_req);
			return -EIO;
		case FC_PORTTYPE_NPORT:
			if (fsf_req->erp_action)
				ZFCP_LOG_NORMAL("Switched fabric fibrechannel "
					"network detected at adapter %s.\n",
						"network detected at adapter "
						"%s.\n",
					zfcp_get_busid_by_adapter(adapter));
			break;
		default:
+16 −2
Original line number Diff line number Diff line
@@ -213,6 +213,7 @@
#define FSF_FEATURE_HBAAPI_MANAGEMENT           0x00000010
#define FSF_FEATURE_ELS_CT_CHAINED_SBALS        0x00000020
#define FSF_FEATURE_UPDATE_ALERT		0x00000100
#define FSF_FEATURE_MEASUREMENT_DATA		0x00000200

/* host connection features */
#define FSF_FEATURE_NPIV_MODE			0x00000001
@@ -340,6 +341,15 @@ struct fsf_qtcb_prefix {
	u8  res1[20];
} __attribute__ ((packed));

struct fsf_statistics_info {
	u64 input_req;
	u64 output_req;
	u64 control_req;
	u64 input_mb;
	u64 output_mb;
	u64 seconds_act;
} __attribute__ ((packed));

union fsf_status_qual {
	u8  byte[FSF_STATUS_QUALIFIER_SIZE];
	u16 halfword[FSF_STATUS_QUALIFIER_SIZE / sizeof (u16)];
@@ -436,7 +446,8 @@ struct fsf_qtcb_bottom_config {
	u32 hardware_version;
	u8 serial_number[32];
	struct fsf_nport_serv_param plogi_payload;
	u8 res4[160];
	struct fsf_statistics_info stat_info;
	u8 res4[112];
} __attribute__ ((packed));

struct fsf_qtcb_bottom_port {
@@ -469,7 +480,10 @@ struct fsf_qtcb_bottom_port {
	u64 control_requests;
	u64 input_mb;		/* where 1 MByte == 1.000.000 Bytes */
	u64 output_mb;		/* where 1 MByte == 1.000.000 Bytes */
	u8 res2[256];
	u8 cp_util;
	u8 cb_util;
	u8 a_util;
	u8 res2[253];
} __attribute__ ((packed));

union fsf_qtcb_bottom {
+114 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ static struct zfcp_unit *zfcp_unit_lookup(struct zfcp_adapter *, int,
					  unsigned int, unsigned int);

static struct device_attribute *zfcp_sysfs_sdev_attrs[];
static struct device_attribute *zfcp_a_stats_attrs[];

struct zfcp_data zfcp_data = {
	.scsi_host_template = {
@@ -61,6 +62,7 @@ struct zfcp_data zfcp_data = {
		.use_clustering		= 1,
		.sdev_attrs		= zfcp_sysfs_sdev_attrs,
		.max_sectors		= ZFCP_MAX_SECTORS,
		.shost_attrs		= zfcp_a_stats_attrs,
	},
	.driver_version = ZFCP_VERSION,
};
@@ -809,4 +811,116 @@ static struct device_attribute *zfcp_sysfs_sdev_attrs[] = {
	NULL
};

static ssize_t zfcp_sysfs_adapter_util_show(struct device *dev,
					    struct device_attribute *attr,
					    char *buf)
{
	struct Scsi_Host *scsi_host = dev_to_shost(dev);
	struct fsf_qtcb_bottom_port *qtcb_port;
	int retval;
	struct zfcp_adapter *adapter;

	adapter = (struct zfcp_adapter *) scsi_host->hostdata[0];
	if (!(adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA))
		return -EOPNOTSUPP;

	qtcb_port = kzalloc(sizeof(struct fsf_qtcb_bottom_port), GFP_KERNEL);
	if (!qtcb_port)
		return -ENOMEM;

	retval = zfcp_fsf_exchange_port_data_sync(adapter, qtcb_port);
	if (!retval)
		retval = sprintf(buf, "%u %u %u\n", qtcb_port->cp_util,
				 qtcb_port->cb_util, qtcb_port->a_util);
	kfree(qtcb_port);
	return retval;
}

static int zfcp_sysfs_adapter_ex_config(struct device *dev,
					struct fsf_statistics_info *stat_inf)
{
	int retval;
	struct fsf_qtcb_bottom_config *qtcb_config;
	struct Scsi_Host *scsi_host = dev_to_shost(dev);
	struct zfcp_adapter *adapter;

	adapter = (struct zfcp_adapter *) scsi_host->hostdata[0];
	if (!(adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA))
		return -EOPNOTSUPP;

	qtcb_config = kzalloc(sizeof(struct fsf_qtcb_bottom_config),
			       GFP_KERNEL);
	if (!qtcb_config)
		return -ENOMEM;

	retval = zfcp_fsf_exchange_config_data_sync(adapter, qtcb_config);
	if (!retval)
		*stat_inf = qtcb_config->stat_info;

	kfree(qtcb_config);
	return retval;
}

static ssize_t zfcp_sysfs_adapter_request_show(struct device *dev,
					       struct device_attribute *attr,
					       char *buf)
{
	struct fsf_statistics_info stat_info;
	int retval;

	retval = zfcp_sysfs_adapter_ex_config(dev, &stat_info);
	if (retval)
		return retval;

	return sprintf(buf, "%llu %llu %llu\n",
		       (unsigned long long) stat_info.input_req,
		       (unsigned long long) stat_info.output_req,
		       (unsigned long long) stat_info.control_req);
}

static ssize_t zfcp_sysfs_adapter_mb_show(struct device *dev,
					  struct device_attribute *attr,
					  char *buf)
{
	struct fsf_statistics_info stat_info;
	int retval;

	retval = zfcp_sysfs_adapter_ex_config(dev, &stat_info);
	if (retval)
		return retval;

	return sprintf(buf, "%llu %llu\n",
		       (unsigned long long) stat_info.input_mb,
		       (unsigned long long) stat_info.output_mb);
}

static ssize_t zfcp_sysfs_adapter_sec_active_show(struct device *dev,
						  struct device_attribute *attr,
						  char *buf)
{
	struct fsf_statistics_info stat_info;
	int retval;

	retval = zfcp_sysfs_adapter_ex_config(dev, &stat_info);
	if (retval)
		return retval;

	return sprintf(buf, "%llu\n",
		       (unsigned long long) stat_info.seconds_act);
}

static DEVICE_ATTR(utilization, S_IRUGO, zfcp_sysfs_adapter_util_show, NULL);
static DEVICE_ATTR(requests, S_IRUGO, zfcp_sysfs_adapter_request_show, NULL);
static DEVICE_ATTR(megabytes, S_IRUGO, zfcp_sysfs_adapter_mb_show, NULL);
static DEVICE_ATTR(seconds_active, S_IRUGO,
		   zfcp_sysfs_adapter_sec_active_show, NULL);

static struct device_attribute *zfcp_a_stats_attrs[] = {
	&dev_attr_utilization,
	&dev_attr_requests,
	&dev_attr_megabytes,
	&dev_attr_seconds_active,
	NULL
};

#undef ZFCP_LOG_AREA
Loading