浏览代码

mca: add integrated device bus matching

The MCA bus has a few "integrated" functions, which are effectively virtual
slots on the bus.  The problem is that these special functions don't have
dedicated pos IDs, so we have to manufacture ids for them outside the pos
space ...  and these ids can't be matched by the standard matching function,
so add a special registration that requests a list of pos ids or a particular
integrated function.

Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
James Bottomley 18 年之前
父节点
当前提交
8813d1c00c
共有 3 个文件被更改,包括 31 次插入10 次删除
  1. 16 10
      drivers/mca/mca-bus.c
  2. 13 0
      drivers/mca/mca-driver.c
  3. 2 0
      include/linux/mca.h

+ 16 - 10
drivers/mca/mca-bus.c

@@ -48,18 +48,24 @@ static int mca_bus_match (struct device *dev, struct device_driver *drv)
 	struct mca_device *mca_dev = to_mca_device (dev);
 	struct mca_device *mca_dev = to_mca_device (dev);
 	struct mca_driver *mca_drv = to_mca_driver (drv);
 	struct mca_driver *mca_drv = to_mca_driver (drv);
 	const unsigned short *mca_ids = mca_drv->id_table;
 	const unsigned short *mca_ids = mca_drv->id_table;
-	int i;
-
-	if (!mca_ids)
-		return 0;
-
-	for(i = 0; mca_ids[i]; i++) {
-		if (mca_ids[i] == mca_dev->pos_id) {
-			mca_dev->index = i;
-			return 1;
+	int i = 0;
+
+	if (mca_ids) {
+		for(i = 0; mca_ids[i]; i++) {
+			if (mca_ids[i] == mca_dev->pos_id) {
+				mca_dev->index = i;
+				return 1;
+			}
 		}
 		}
 	}
 	}
-
+	/* If the integrated id is present, treat it as though it were an
+	 * additional id in the id_table (it can't be because by definition,
+	 * integrated id's overflow a short */
+	if (mca_drv->integrated_id && mca_dev->pos_id ==
+	    mca_drv->integrated_id) {
+		mca_dev->index = i;
+		return 1;
+	}
 	return 0;
 	return 0;
 }
 }
 
 

+ 13 - 0
drivers/mca/mca-driver.c

@@ -36,12 +36,25 @@ int mca_register_driver(struct mca_driver *mca_drv)
 		mca_drv->driver.bus = &mca_bus_type;
 		mca_drv->driver.bus = &mca_bus_type;
 		if ((r = driver_register(&mca_drv->driver)) < 0)
 		if ((r = driver_register(&mca_drv->driver)) < 0)
 			return r;
 			return r;
+		mca_drv->integrated_id = 0;
 	}
 	}
 
 
 	return 0;
 	return 0;
 }
 }
 EXPORT_SYMBOL(mca_register_driver);
 EXPORT_SYMBOL(mca_register_driver);
 
 
+int mca_register_driver_integrated(struct mca_driver *mca_driver,
+				   int integrated_id)
+{
+	int r = mca_register_driver(mca_driver);
+
+	if (!r)
+		mca_driver->integrated_id = integrated_id;
+
+	return r;
+}
+EXPORT_SYMBOL(mca_register_driver_integrated);
+
 void mca_unregister_driver(struct mca_driver *mca_drv)
 void mca_unregister_driver(struct mca_driver *mca_drv)
 {
 {
 	if (MCA_bus)
 	if (MCA_bus)

+ 2 - 0
include/linux/mca.h

@@ -94,6 +94,7 @@ struct mca_bus {
 struct mca_driver {
 struct mca_driver {
 	const short		*id_table;
 	const short		*id_table;
 	void			*driver_data;
 	void			*driver_data;
+	int			integrated_id;
 	struct device_driver	driver;
 	struct device_driver	driver;
 };
 };
 #define to_mca_driver(mdriver) container_of(mdriver, struct mca_driver, driver)
 #define to_mca_driver(mdriver) container_of(mdriver, struct mca_driver, driver)
@@ -125,6 +126,7 @@ extern enum MCA_AdapterStatus mca_device_status(struct mca_device *mca_dev);
 extern struct bus_type mca_bus_type;
 extern struct bus_type mca_bus_type;
 
 
 extern int mca_register_driver(struct mca_driver *drv);
 extern int mca_register_driver(struct mca_driver *drv);
+extern int mca_register_driver_integrated(struct mca_driver *, int);
 extern void mca_unregister_driver(struct mca_driver *drv);
 extern void mca_unregister_driver(struct mca_driver *drv);
 
 
 /* WARNING: only called by the boot time device setup */
 /* WARNING: only called by the boot time device setup */