コード例 #1
0
static int usu_probe_thread(void *arg)
{
	int type = (unsigned long) arg;
	struct mod_status *st = &stat[type];
	int rc;
	unsigned long flags;

	mutex_lock(&usu_probe_mutex);
	rc = request_module(bias_names[type]);
	spin_lock_irqsave(&usu_lock, flags);
	if (rc == 0 && (st->fls & USU_MOD_FL_PRESENT) == 0) {
		
		printk(KERN_NOTICE "libusual: "
		    "modprobe for %s succeeded, but module is not present\n",
		    bias_names[type]);
	}
	st->fls &= ~USU_MOD_FL_THREAD;
	spin_unlock_irqrestore(&usu_lock, flags);
	mutex_unlock(&usu_probe_mutex);

	complete_and_exit(&usu_end_notify, 0);
}
コード例 #2
0
ファイル: soundcard.c プロジェクト: dzavalishin/oskit
static int sound_mixer_ioctl(int mixdev, unsigned int cmd, caddr_t arg)
{
 	if (mixdev < 0 || mixdev >= MAX_MIXER_DEV)
 		return -ENXIO;
 	/* Try to load the mixer... */
 	if (mixer_devs[mixdev] == NULL) {
 		char modname[20];
 		sprintf(modname, "mixer%d", mixdev);
 		request_module(modname);
 	}
 	if (mixdev >= num_mixers || !mixer_devs[mixdev])
 		return -ENXIO;
	if (cmd == SOUND_MIXER_INFO)
		return get_mixer_info(mixdev, arg);
	if (cmd == SOUND_OLD_MIXER_INFO)
		return get_old_mixer_info(mixdev, arg);
	if (_SIOC_DIR(cmd) & _SIOC_WRITE)
		mixer_devs[mixdev]->modify_counter++;
	if (!mixer_devs[mixdev]->ioctl)
		return -EINVAL;
	return mixer_devs[mixdev]->ioctl(mixdev, cmd, arg);
}
コード例 #3
0
ファイル: cx23885-cards.c プロジェクト: AppEngine/linux-2.6
int cx23885_ir_init(struct cx23885_dev *dev)
{
	switch (dev->board) {
	case CX23885_BOARD_HAUPPAUGE_HVR1250:
	case CX23885_BOARD_HAUPPAUGE_HVR1500:
	case CX23885_BOARD_HAUPPAUGE_HVR1500Q:
	case CX23885_BOARD_HAUPPAUGE_HVR1800:
	case CX23885_BOARD_HAUPPAUGE_HVR1200:
	case CX23885_BOARD_HAUPPAUGE_HVR1400:
	case CX23885_BOARD_HAUPPAUGE_HVR1270:
	case CX23885_BOARD_HAUPPAUGE_HVR1275:
	case CX23885_BOARD_HAUPPAUGE_HVR1255:
	case CX23885_BOARD_HAUPPAUGE_HVR1210:
		/* FIXME: Implement me */
		break;
	case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP:
		request_module("ir-kbd-i2c");
		break;
	}

	return 0;
}
コード例 #4
0
ファイル: daca.c プロジェクト: miettal/armadillo420_standard
/* exported */
int __init snd_pmac_daca_init(struct snd_pmac *chip)
{
	int i, err;
	struct pmac_daca *mix;

#ifdef CONFIG_KMOD
	request_module("i2c-powermac");
#endif /* CONFIG_KMOD */

	mix = kzalloc(sizeof(*mix), GFP_KERNEL);
	if (! mix)
		return -ENOMEM;
	chip->mixer_data = mix;
	chip->mixer_free = daca_cleanup;
	mix->amp_on = 1; /* default on */

	mix->i2c.addr = DACA_I2C_ADDR;
	mix->i2c.init_client = daca_init_client;
	mix->i2c.name = "DACA";
	if ((err = snd_pmac_keywest_init(&mix->i2c)) < 0)
		return err;

	/*
	 * build mixers
	 */
	strcpy(chip->card->mixername, "PowerMac DACA");

	for (i = 0; i < ARRAY_SIZE(daca_mixers); i++) {
		if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&daca_mixers[i], chip))) < 0)
			return err;
	}

#ifdef CONFIG_PM
	chip->resume = daca_resume;
#endif

	return 0;
}
コード例 #5
0
static int phone_open(struct inode *inode, struct file *file)
{
	unsigned int minor = iminor(inode);
	int err = 0;
	struct phone_device *p;
	const struct file_operations *old_fops, *new_fops = NULL;

	if (minor >= PHONE_NUM_DEVICES)
		return -ENODEV;

	mutex_lock(&phone_lock);
	p = phone_device[minor];
	if (p)
		new_fops = fops_get(p->f_op);
	if (!new_fops) {
		mutex_unlock(&phone_lock);
		request_module("char-major-%d-%d", PHONE_MAJOR, minor);
		mutex_lock(&phone_lock);
		p = phone_device[minor];
		if (p == NULL || (new_fops = fops_get(p->f_op)) == NULL)
		{
			err=-ENODEV;
			goto end;
		}
	}
	old_fops = file->f_op;
	file->f_op = new_fops;
	if (p->open)
		err = p->open(p, file);	
	if (err) {
		fops_put(file->f_op);
		file->f_op = fops_get(old_fops);
	}
	fops_put(old_fops);
end:
	mutex_unlock(&phone_lock);
	return err;
}
コード例 #6
0
ファイル: vfio_platform_common.c プロジェクト: DenisLug/mptcp
static void vfio_platform_get_reset(struct vfio_platform_device *vdev,
				    struct device *dev)
{
	const char *compat;
	int (*reset)(struct vfio_platform_device *);
	int ret, i;

	ret = device_property_read_string(dev, "compatible", &compat);
	if (ret)
		return;

	for (i = 0 ; i < ARRAY_SIZE(reset_lookup_table); i++) {
		if (!strcmp(reset_lookup_table[i].compat, compat)) {
			request_module(reset_lookup_table[i].module_name);
			reset = __symbol_get(
				reset_lookup_table[i].reset_function_name);
			if (reset) {
				vdev->reset = reset;
				return;
			}
		}
	}
}
コード例 #7
0
ファイル: pppox.c プロジェクト: johnny/CobraDroidBeta
static int pppox_create(struct net *net, struct socket *sock, int protocol)
{
	int rc = -EPROTOTYPE;

	if (net != &init_net)
		return -EAFNOSUPPORT;

	if (protocol < 0 || protocol > PX_MAX_PROTO)
		goto out;

	rc = -EPROTONOSUPPORT;
	if (!pppox_protos[protocol])
		request_module("pppox-proto-%d", protocol);
	if (!pppox_protos[protocol] ||
	    !try_module_get(pppox_protos[protocol]->owner))
		goto out;

	rc = pppox_protos[protocol]->create(net, sock);

	module_put(pppox_protos[protocol]->owner);
out:
	return rc;
}
コード例 #8
0
ファイル: linux-crypto.c プロジェクト: Xyratex/lustre-stable
/**
 * Register available hash functions
 *
 * \retval		0
 */
int cfs_crypto_register(void)
{
	request_module("crc32c");

	adler32 = cfs_crypto_adler32_register();

#ifdef HAVE_CRC32
	crc32 = cfs_crypto_crc32_register();
#endif
#ifdef HAVE_PCLMULQDQ
#ifdef NEED_CRC32_ACCEL
	crc32_pclmul = cfs_crypto_crc32_pclmul_register();
#endif
#ifdef NEED_CRC32C_ACCEL
	crc32c_pclmul = cfs_crypto_crc32c_pclmul_register();
#endif
#endif /* HAVE_PCLMULQDQ */

	/* check all algorithms and do performance test */
	cfs_crypto_test_hashes();

	return 0;
}
コード例 #9
0
struct v4l2_subdev *v4l2_spi_new_subdev(struct v4l2_device *v4l2_dev,
		struct spi_master *master, struct spi_board_info *info)
{
	struct v4l2_subdev *sd = NULL;
	struct spi_device *spi = NULL;

	BUG_ON(!v4l2_dev);

	if (info->modalias)
		request_module(info->modalias);

	spi = spi_new_device(master, info);

	if (spi == NULL || spi->dev.driver == NULL)
		goto error;

	if (!try_module_get(spi->dev.driver->owner))
		goto error;

	sd = spi_get_drvdata(spi);

	/* Register with the v4l2_device which increases the module's
	   use count as well. */
	if (v4l2_device_register_subdev(v4l2_dev, sd))
		sd = NULL;

	/* Decrease the module use count to match the first try_module_get. */
	module_put(spi->dev.driver->owner);

error:
	/* If we have a client but no subdev, then something went wrong and
	   we must unregister the client. */
	if (spi && sd == NULL)
		spi_unregister_device(spi);

	return sd;
}
コード例 #10
0
/*
	Return the function table of a device.
	Load the driver if needed.
*/
static struct file_operations * get_fops(
	unsigned int major,
	unsigned int minor,
	unsigned int maxdev,
	const char *mangle,		/* String to use to build the module name */
	struct device_struct tb[])
{
	struct file_operations *ret = NULL;

	if (major < maxdev){
#ifdef CONFIG_KMOD
		/*
		 * I do get request for device 0. I have no idea why. It happen
		 * at shutdown time for one. Without the following test, the
		 * kernel will happily trigger a request_module() which will
		 * trigger kmod and modprobe for nothing (since there
		 * is no device with major number == 0. And furthermore
		 * it locks the reboot process :-(
		 *
		 * Jacques Gelinas ([email protected])
		 *
		 * A. Haritsis <*****@*****.**>: fix for serial module
		 *  though we need the minor here to check if serial dev,
		 *  we pass only the normal major char dev to kmod 
		 *  as there is no other loadable dev on these majors
		 */
		if ((isa_tty_dev(major) && need_serial(major,minor)) ||
		    (major != 0 && !tb[major].fops)) {
			char name[20];
			sprintf(name, mangle, major);
			request_module(name);
		}
#endif
		ret = tb[major].fops;
	}
	return ret;
}
コード例 #11
0
ファイル: vport.c プロジェクト: JunoZhu/ovs
/**
 *	ovs_vport_add - add vport device (for kernel callers)
 *
 * @parms: Information about new vport.
 *
 * Creates a new vport with the specified configuration (which is dependent on
 * device type).  ovs_mutex must be held.
 */
struct vport *ovs_vport_add(const struct vport_parms *parms)
{
	struct vport_ops *ops;
	struct vport *vport;

	ops = ovs_vport_lookup(parms);
	if (ops) {
		struct hlist_head *bucket;

		if (!try_module_get(ops->owner))
			return ERR_PTR(-EAFNOSUPPORT);

		vport = ops->create(parms);
		if (IS_ERR(vport)) {
			module_put(ops->owner);
			return vport;
		}

		bucket = hash_bucket(ovs_dp_get_net(vport->dp),
				     ovs_vport_name(vport));
		hlist_add_head_rcu(&vport->hash_node, bucket);
		return vport;
	}

	/* Unlock to attempt module load and return -EAGAIN if load
	 * was successful as we need to restart the port addition
	 * workflow.
	 */
	ovs_unlock();
	request_module("vport-type-%d", parms->type);
	ovs_lock();

	if (!ovs_vport_lookup(parms))
		return ERR_PTR(-EAFNOSUPPORT);
	else
		return ERR_PTR(-EAGAIN);
}
コード例 #12
0
ファイル: pnfs.c プロジェクト: AbheekG/XIA-for-Linux
/*
 * Try to set the server's pnfs module to the pnfs layout type specified by id.
 * Currently only one pNFS layout driver per filesystem is supported.
 *
 * @id layout type. Zero (illegal layout type) indicates pNFS not in use.
 */
void
set_pnfs_layoutdriver(struct nfs_server *server, u32 id)
{
    struct pnfs_layoutdriver_type *ld_type = NULL;

    if (id == 0)
        goto out_no_driver;
    if (!(server->nfs_client->cl_exchange_flags &
            (EXCHGID4_FLAG_USE_NON_PNFS | EXCHGID4_FLAG_USE_PNFS_MDS))) {
        printk(KERN_ERR "%s: id %u cl_exchange_flags 0x%x\n", __func__,
               id, server->nfs_client->cl_exchange_flags);
        goto out_no_driver;
    }
    ld_type = find_pnfs_driver(id);
    if (!ld_type) {
        request_module("%s-%u", LAYOUT_NFSV4_1_MODULE_PREFIX, id);
        ld_type = find_pnfs_driver(id);
        if (!ld_type) {
            dprintk("%s: No pNFS module found for %u.\n",
                    __func__, id);
            goto out_no_driver;
        }
    }
    if (!try_module_get(ld_type->owner)) {
        dprintk("%s: Could not grab reference on module\n", __func__);
        goto out_no_driver;
    }
    server->pnfs_curr_ld = ld_type;

    dprintk("%s: pNFS module for %u set\n", __func__, id);
    return;

out_no_driver:
    dprintk("%s: Using NFSv4 I/O\n", __func__);
    server->pnfs_curr_ld = NULL;
}
コード例 #13
0
int parse_mtd_partitions(struct mtd_info *master, const char **types,
			 struct mtd_partition **pparts, unsigned long origin)
{
	struct mtd_part_parser *parser;
	int ret = 0;

	for ( ; ret <= 0 && *types; types++) {
		parser = get_partition_parser(*types);
		if (!parser && !request_module("%s", *types))
				parser = get_partition_parser(*types);
		if (!parser) {
			printk(KERN_NOTICE "%s partition parsing not available\n",
			       *types);
			continue;
		}
		ret = (*parser->parse_fn)(master, pparts, origin);
		if (ret > 0) {
			printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n",
			       ret, parser->name, master->name);
		}
		put_partition_parser(parser);
	}
	return ret;
}
コード例 #14
0
ファイル: fcal.c プロジェクト: JBTech/ralink_rt5350
/* Detect all FC Arbitrated Loops attached to the machine.
   fc4 module has done all the work for us... */
int __init fcal_detect(Scsi_Host_Template *tpnt)
{
	int nfcals = 0;
	fc_channel *fc;
	int fcalcount;
	int i;

	tpnt->proc_name = "fcal";
	fcalcount = 0;
	for_each_online_fc_channel(fc)
		if (fc->posmap)
			fcalcount++;
	FCALND(("%d channels online\n", fcalcount))
	if (!fcalcount) {
#if defined(MODULE) && defined(CONFIG_FC4_SOCAL_MODULE) && defined(CONFIG_KMOD)
		request_module("socal");
		
		for_each_online_fc_channel(fc)
			if (fc->posmap)
				fcalcount++;
		if (!fcalcount)
#endif
			return 0;
	}
コード例 #15
0
struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev,
		struct i2c_adapter *adapter, struct i2c_board_info *info,
		const unsigned short *probe_addrs)
{
	struct v4l2_subdev *sd = NULL;
	struct i2c_client *client;

	BUG_ON(!v4l2_dev);

	request_module(I2C_MODULE_PREFIX "%s", info->type);

	
	if (info->addr == 0 && probe_addrs)
		client = i2c_new_probed_device(adapter, info, probe_addrs,
					       NULL);
	else
		client = i2c_new_device(adapter, info);

	if (client == NULL || client->driver == NULL)
		goto error;

	
	if (!try_module_get(client->driver->driver.owner))
		goto error;
	sd = i2c_get_clientdata(client);

	if (v4l2_device_register_subdev(v4l2_dev, sd))
		sd = NULL;
	
	module_put(client->driver->driver.owner);

error:
	if (client && sd == NULL)
		i2c_unregister_device(client);
	return sd;
}
コード例 #16
0
static int __init wf_rm31_init(void)
{
	struct device_node *cpu;
	int i;

	if (!of_machine_is_compatible("RackMac3,1"))
		return -ENODEV;

	/* Count the number of CPU cores */
	nr_chips = 0;
	for (cpu = NULL; (cpu = of_find_node_by_type(cpu, "cpu")) != NULL; )
		++nr_chips;
	if (nr_chips > NR_CHIPS)
		nr_chips = NR_CHIPS;

	pr_info("windfarm: Initializing for desktop G5 with %d chips\n",
		nr_chips);

	/* Get MPU data for each CPU */
	for (i = 0; i < nr_chips; i++) {
		cpu_mpu_data[i] = wf_get_mpu(i);
		if (!cpu_mpu_data[i]) {
			pr_err("wf_rm31: Failed to find MPU data for CPU %d\n", i);
			return -ENXIO;
		}
	}

#ifdef MODULE
	request_module("windfarm_fcu_controls");
	request_module("windfarm_lm75_sensor");
	request_module("windfarm_lm87_sensor");
	request_module("windfarm_ad7417_sensor");
	request_module("windfarm_max6690_sensor");
	request_module("windfarm_cpufreq_clamp");
#endif /* MODULE */

	platform_driver_register(&wf_rm31_driver);
	return 0;
}
コード例 #17
0
static int em28xx_dvb_init(struct em28xx *dev)
{
	int result = 0, mfe_shared = 0;
	struct em28xx_dvb *dvb;

	if (dev->is_audio_only) {
		/* Shouldn't initialize IR for this interface */
		return 0;
	}

	if (!dev->board.has_dvb) {
		/* This device does not support the extension */
		return 0;
	}

	em28xx_info("Binding DVB extension\n");

	dvb = kzalloc(sizeof(struct em28xx_dvb), GFP_KERNEL);
	if (dvb == NULL) {
		em28xx_info("em28xx_dvb: memory allocation failed\n");
		return -ENOMEM;
	}
	dev->dvb = dvb;
	dvb->fe[0] = dvb->fe[1] = NULL;

	/* pre-allocate DVB usb transfer buffers */
	if (dev->dvb_xfer_bulk) {
		result = em28xx_alloc_urbs(dev, EM28XX_DIGITAL_MODE,
					   dev->dvb_xfer_bulk,
					   EM28XX_DVB_NUM_BUFS,
					   512,
					   EM28XX_DVB_BULK_PACKET_MULTIPLIER);
	} else {
		result = em28xx_alloc_urbs(dev, EM28XX_DIGITAL_MODE,
					   dev->dvb_xfer_bulk,
					   EM28XX_DVB_NUM_BUFS,
					   dev->dvb_max_pkt_size_isoc,
					   EM28XX_DVB_NUM_ISOC_PACKETS);
	}
	if (result) {
		em28xx_errdev("em28xx_dvb: failed to pre-allocate USB transfer buffers for DVB.\n");
		kfree(dvb);
		dev->dvb = NULL;
		return result;
	}

	mutex_lock(&dev->lock);
	em28xx_set_mode(dev, EM28XX_DIGITAL_MODE);
	/* init frontend */
	switch (dev->model) {
	case EM2874_BOARD_LEADERSHIP_ISDBT:
		dvb->fe[0] = dvb_attach(s921_attach,
				&sharp_isdbt, &dev->i2c_adap[dev->def_i2c_bus]);

		if (!dvb->fe[0]) {
			result = -EINVAL;
			goto out_free;
		}

		break;
	case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850:
	case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
	case EM2880_BOARD_PINNACLE_PCTV_HD_PRO:
	case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600:
		dvb->fe[0] = dvb_attach(lgdt330x_attach,
					   &em2880_lgdt3303_dev,
					   &dev->i2c_adap[dev->def_i2c_bus]);
		if (em28xx_attach_xc3028(0x61, dev) < 0) {
			result = -EINVAL;
			goto out_free;
		}
		break;
	case EM2880_BOARD_KWORLD_DVB_310U:
		dvb->fe[0] = dvb_attach(zl10353_attach,
					   &em28xx_zl10353_with_xc3028,
					   &dev->i2c_adap[dev->def_i2c_bus]);
		if (em28xx_attach_xc3028(0x61, dev) < 0) {
			result = -EINVAL;
			goto out_free;
		}
		break;
	case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
	case EM2882_BOARD_TERRATEC_HYBRID_XS:
	case EM2880_BOARD_EMPIRE_DUAL_TV:
		dvb->fe[0] = dvb_attach(zl10353_attach,
					   &em28xx_zl10353_xc3028_no_i2c_gate,
					   &dev->i2c_adap[dev->def_i2c_bus]);
		if (em28xx_attach_xc3028(0x61, dev) < 0) {
			result = -EINVAL;
			goto out_free;
		}
		break;
	case EM2880_BOARD_TERRATEC_HYBRID_XS:
	case EM2880_BOARD_TERRATEC_HYBRID_XS_FR:
	case EM2881_BOARD_PINNACLE_HYBRID_PRO:
	case EM2882_BOARD_DIKOM_DK300:
	case EM2882_BOARD_KWORLD_VS_DVBT:
		dvb->fe[0] = dvb_attach(zl10353_attach,
					   &em28xx_zl10353_xc3028_no_i2c_gate,
					   &dev->i2c_adap[dev->def_i2c_bus]);
		if (dvb->fe[0] == NULL) {
			/* This board could have either a zl10353 or a mt352.
			   If the chip id isn't for zl10353, try mt352 */
			dvb->fe[0] = dvb_attach(mt352_attach,
						   &terratec_xs_mt352_cfg,
						   &dev->i2c_adap[dev->def_i2c_bus]);
		}

		if (em28xx_attach_xc3028(0x61, dev) < 0) {
			result = -EINVAL;
			goto out_free;
		}
		break;
	case EM2870_BOARD_KWORLD_355U:
		dvb->fe[0] = dvb_attach(zl10353_attach,
					   &em28xx_zl10353_no_i2c_gate_dev,
					   &dev->i2c_adap[dev->def_i2c_bus]);
		if (dvb->fe[0] != NULL)
			dvb_attach(qt1010_attach, dvb->fe[0],
				   &dev->i2c_adap[dev->def_i2c_bus], &em28xx_qt1010_config);
		break;
	case EM2883_BOARD_KWORLD_HYBRID_330U:
	case EM2882_BOARD_EVGA_INDTUBE:
		dvb->fe[0] = dvb_attach(s5h1409_attach,
					   &em28xx_s5h1409_with_xc3028,
					   &dev->i2c_adap[dev->def_i2c_bus]);
		if (em28xx_attach_xc3028(0x61, dev) < 0) {
			result = -EINVAL;
			goto out_free;
		}
		break;
	case EM2882_BOARD_KWORLD_ATSC_315U:
		dvb->fe[0] = dvb_attach(lgdt330x_attach,
					   &em2880_lgdt3303_dev,
					   &dev->i2c_adap[dev->def_i2c_bus]);
		if (dvb->fe[0] != NULL) {
			if (!dvb_attach(simple_tuner_attach, dvb->fe[0],
				&dev->i2c_adap[dev->def_i2c_bus], 0x61, TUNER_THOMSON_DTT761X)) {
				result = -EINVAL;
				goto out_free;
			}
		}
		break;
	case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
	case EM2882_BOARD_PINNACLE_HYBRID_PRO_330E:
		dvb->fe[0] = dvb_attach(drxd_attach, &em28xx_drxd, NULL,
					   &dev->i2c_adap[dev->def_i2c_bus], &dev->udev->dev);
		if (em28xx_attach_xc3028(0x61, dev) < 0) {
			result = -EINVAL;
			goto out_free;
		}
		break;
	case EM2870_BOARD_REDDO_DVB_C_USB_BOX:
		/* Philips CU1216L NIM (Philips TDA10023 + Infineon TUA6034) */
		dvb->fe[0] = dvb_attach(tda10023_attach,
			&em28xx_tda10023_config,
			&dev->i2c_adap[dev->def_i2c_bus], 0x48);
		if (dvb->fe[0]) {
			if (!dvb_attach(simple_tuner_attach, dvb->fe[0],
				&dev->i2c_adap[dev->def_i2c_bus], 0x60, TUNER_PHILIPS_CU1216L)) {
				result = -EINVAL;
				goto out_free;
			}
		}
		break;
	case EM2870_BOARD_KWORLD_A340:
		dvb->fe[0] = dvb_attach(lgdt3305_attach,
					   &em2870_lgdt3304_dev,
					   &dev->i2c_adap[dev->def_i2c_bus]);
		if (!dvb->fe[0]) {
			result = -EINVAL;
			goto out_free;
		}
		if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
			&dev->i2c_adap[dev->def_i2c_bus],
			&kworld_a340_config)) {
				dvb_frontend_detach(dvb->fe[0]);
				result = -EINVAL;
				goto out_free;
		}
		break;
	case EM28174_BOARD_PCTV_290E:
		/* set default GPIO0 for LNA, used if GPIOLIB is undefined */
		dvb->lna_gpio = CXD2820R_GPIO_E | CXD2820R_GPIO_O |
				CXD2820R_GPIO_L;
		dvb->fe[0] = dvb_attach(cxd2820r_attach,
					&em28xx_cxd2820r_config,
					&dev->i2c_adap[dev->def_i2c_bus],
					&dvb->lna_gpio);
		if (dvb->fe[0]) {
			/* FE 0 attach tuner */
			if (!dvb_attach(tda18271_attach,
					dvb->fe[0],
					0x60,
					&dev->i2c_adap[dev->def_i2c_bus],
					&em28xx_cxd2820r_tda18271_config)) {

				dvb_frontend_detach(dvb->fe[0]);
				result = -EINVAL;
				goto out_free;
			}

#ifdef CONFIG_GPIOLIB
			/* enable LNA for DVB-T, DVB-T2 and DVB-C */
			result = gpio_request_one(dvb->lna_gpio,
					GPIOF_OUT_INIT_LOW, NULL);
			if (result)
				em28xx_errdev("gpio request failed %d\n",
						result);
			else
				gpio_free(dvb->lna_gpio);

			result = 0; /* continue even set LNA fails */
#endif
			dvb->fe[0]->ops.set_lna = em28xx_pctv_290e_set_lna;
		}

		break;
	case EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C:
	{
		struct xc5000_config cfg;
		hauppauge_hvr930c_init(dev);

		dvb->fe[0] = dvb_attach(drxk_attach,
					&hauppauge_930c_drxk, &dev->i2c_adap[dev->def_i2c_bus]);
		if (!dvb->fe[0]) {
			result = -EINVAL;
			goto out_free;
		}
		/* FIXME: do we need a pll semaphore? */
		dvb->fe[0]->sec_priv = dvb;
		sema_init(&dvb->pll_mutex, 1);
		dvb->gate_ctrl = dvb->fe[0]->ops.i2c_gate_ctrl;
		dvb->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl;

		/* Attach xc5000 */
		memset(&cfg, 0, sizeof(cfg));
		cfg.i2c_address  = 0x61;
		cfg.if_khz = 4000;

		if (dvb->fe[0]->ops.i2c_gate_ctrl)
			dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 1);
		if (!dvb_attach(xc5000_attach, dvb->fe[0], &dev->i2c_adap[dev->def_i2c_bus],
				&cfg)) {
			result = -EINVAL;
			goto out_free;
		}
		if (dvb->fe[0]->ops.i2c_gate_ctrl)
			dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 0);

		break;
	}
	case EM2884_BOARD_TERRATEC_H5:
		terratec_h5_init(dev);

		dvb->fe[0] = dvb_attach(drxk_attach, &terratec_h5_drxk, &dev->i2c_adap[dev->def_i2c_bus]);
		if (!dvb->fe[0]) {
			result = -EINVAL;
			goto out_free;
		}
		/* FIXME: do we need a pll semaphore? */
		dvb->fe[0]->sec_priv = dvb;
		sema_init(&dvb->pll_mutex, 1);
		dvb->gate_ctrl = dvb->fe[0]->ops.i2c_gate_ctrl;
		dvb->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl;

		/* Attach tda18271 to DVB-C frontend */
		if (dvb->fe[0]->ops.i2c_gate_ctrl)
			dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 1);
		if (!dvb_attach(tda18271c2dd_attach, dvb->fe[0], &dev->i2c_adap[dev->def_i2c_bus], 0x60)) {
			result = -EINVAL;
			goto out_free;
		}
		if (dvb->fe[0]->ops.i2c_gate_ctrl)
			dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 0);

		break;
	case EM2884_BOARD_C3TECH_DIGITAL_DUO:
		dvb->fe[0] = dvb_attach(mb86a20s_attach,
					   &c3tech_duo_mb86a20s_config,
					   &dev->i2c_adap[dev->def_i2c_bus]);
		if (dvb->fe[0] != NULL)
			dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
				   &dev->i2c_adap[dev->def_i2c_bus],
				   &c3tech_duo_tda18271_config);
		break;
	case EM28174_BOARD_PCTV_460E:
		/* attach demod */
		dvb->fe[0] = dvb_attach(tda10071_attach,
			&em28xx_tda10071_config, &dev->i2c_adap[dev->def_i2c_bus]);

		/* attach SEC */
		if (dvb->fe[0])
			dvb_attach(a8293_attach, dvb->fe[0], &dev->i2c_adap[dev->def_i2c_bus],
				&em28xx_a8293_config);
		break;
	case EM2874_BOARD_DELOCK_61959:
	case EM2874_BOARD_MAXMEDIA_UB425_TC:
		/* attach demodulator */
		dvb->fe[0] = dvb_attach(drxk_attach, &maxmedia_ub425_tc_drxk,
				&dev->i2c_adap[dev->def_i2c_bus]);

		if (dvb->fe[0]) {
			/* disable I2C-gate */
			dvb->fe[0]->ops.i2c_gate_ctrl = NULL;

			/* attach tuner */
			if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
					&dev->i2c_adap[dev->def_i2c_bus],
					&em28xx_cxd2820r_tda18271_config)) {
				dvb_frontend_detach(dvb->fe[0]);
				result = -EINVAL;
				goto out_free;
			}
		}
		break;
	case EM2884_BOARD_PCTV_510E:
	case EM2884_BOARD_PCTV_520E:
		pctv_520e_init(dev);

		/* attach demodulator */
		dvb->fe[0] = dvb_attach(drxk_attach, &pctv_520e_drxk,
				&dev->i2c_adap[dev->def_i2c_bus]);

		if (dvb->fe[0]) {
			/* attach tuner */
			if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
					&dev->i2c_adap[dev->def_i2c_bus],
					&em28xx_cxd2820r_tda18271_config)) {
				dvb_frontend_detach(dvb->fe[0]);
				result = -EINVAL;
				goto out_free;
			}
		}
		break;
	case EM2884_BOARD_CINERGY_HTC_STICK:
		terratec_htc_stick_init(dev);

		/* attach demodulator */
		dvb->fe[0] = dvb_attach(drxk_attach, &terratec_htc_stick_drxk,
					&dev->i2c_adap[dev->def_i2c_bus]);
		if (!dvb->fe[0]) {
			result = -EINVAL;
			goto out_free;
		}

		/* Attach the demodulator. */
		if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
				&dev->i2c_adap[dev->def_i2c_bus],
				&em28xx_cxd2820r_tda18271_config)) {
			result = -EINVAL;
			goto out_free;
		}
		break;
	case EM2884_BOARD_TERRATEC_HTC_USB_XS:
		terratec_htc_usb_xs_init(dev);

		/* attach demodulator */
		dvb->fe[0] = dvb_attach(drxk_attach, &terratec_htc_stick_drxk,
					&dev->i2c_adap[dev->def_i2c_bus]);
		if (!dvb->fe[0]) {
			result = -EINVAL;
			goto out_free;
		}

		/* Attach the demodulator. */
		if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
				&dev->i2c_adap[dev->def_i2c_bus],
				&em28xx_cxd2820r_tda18271_config)) {
			result = -EINVAL;
			goto out_free;
		}
		break;
	case EM2874_BOARD_KWORLD_UB435Q_V2:
		dvb->fe[0] = dvb_attach(lgdt3305_attach,
					&em2874_lgdt3305_dev,
					&dev->i2c_adap[dev->def_i2c_bus]);
		if (!dvb->fe[0]) {
			result = -EINVAL;
			goto out_free;
		}

		/* Attach the demodulator. */
		if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
				&dev->i2c_adap[dev->def_i2c_bus],
				&kworld_ub435q_v2_config)) {
			result = -EINVAL;
			goto out_free;
		}
		break;
	case EM2874_BOARD_KWORLD_UB435Q_V3:
		dvb->fe[0] = dvb_attach(lgdt3305_attach,
					&em2874_lgdt3305_nogate_dev,
					&dev->i2c_adap[dev->def_i2c_bus]);
		if (!dvb->fe[0]) {
			result = -EINVAL;
			goto out_free;
		}

		/* Attach the demodulator. */
		if (!dvb_attach(tda18212_attach, dvb->fe[0],
				&dev->i2c_adap[dev->def_i2c_bus],
				&kworld_ub435q_v3_config)) {
			result = -EINVAL;
			goto out_free;
		}
		break;
	case EM2874_BOARD_PCTV_HD_MINI_80E:
		dvb->fe[0] = dvb_attach(drx39xxj_attach, &dev->i2c_adap[dev->def_i2c_bus]);
		if (dvb->fe[0] != NULL) {
			dvb->fe[0] = dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
						&dev->i2c_adap[dev->def_i2c_bus],
						&pinnacle_80e_dvb_config);
			if (!dvb->fe[0]) {
				result = -EINVAL;
				goto out_free;
			}
		}
		break;
	case EM28178_BOARD_PCTV_461E:
		{
			/* demod I2C adapter */
			struct i2c_adapter *i2c_adapter;
			struct i2c_client *client;
			struct i2c_board_info info;
			struct m88ts2022_config m88ts2022_config = {
				.clock = 27000000,
			};
			memset(&info, 0, sizeof(struct i2c_board_info));

			/* attach demod */
			dvb->fe[0] = dvb_attach(m88ds3103_attach,
					&pctv_461e_m88ds3103_config,
					&dev->i2c_adap[dev->def_i2c_bus],
					&i2c_adapter);
			if (dvb->fe[0] == NULL) {
				result = -ENODEV;
				goto out_free;
			}

			/* attach tuner */
			m88ts2022_config.fe = dvb->fe[0];
			strlcpy(info.type, "m88ts2022", I2C_NAME_SIZE);
			info.addr = 0x60;
			info.platform_data = &m88ts2022_config;
			request_module("m88ts2022");
			client = i2c_new_device(i2c_adapter, &info);
			if (client == NULL || client->dev.driver == NULL) {
				dvb_frontend_detach(dvb->fe[0]);
				result = -ENODEV;
				goto out_free;
			}

			if (!try_module_get(client->dev.driver->owner)) {
				i2c_unregister_device(client);
				dvb_frontend_detach(dvb->fe[0]);
				result = -ENODEV;
				goto out_free;
			}

			/* delegate signal strength measurement to tuner */
			dvb->fe[0]->ops.read_signal_strength =
					dvb->fe[0]->ops.tuner_ops.get_rf_strength;

			/* attach SEC */
			if (!dvb_attach(a8293_attach, dvb->fe[0],
					&dev->i2c_adap[dev->def_i2c_bus],
					&em28xx_a8293_config)) {
				module_put(client->dev.driver->owner);
				i2c_unregister_device(client);
				dvb_frontend_detach(dvb->fe[0]);
				result = -ENODEV;
				goto out_free;
			}

			dvb->i2c_client_tuner = client;
		}
		break;
	case EM28178_BOARD_PCTV_292E:
		{
			struct i2c_adapter *adapter;
			struct i2c_client *client;
			struct i2c_board_info info;
			struct si2168_config si2168_config;
			struct si2157_config si2157_config;

			/* attach demod */
			si2168_config.i2c_adapter = &adapter;
			si2168_config.fe = &dvb->fe[0];
			memset(&info, 0, sizeof(struct i2c_board_info));
			strlcpy(info.type, "si2168", I2C_NAME_SIZE);
			info.addr = 0x64;
			info.platform_data = &si2168_config;
			request_module(info.type);
			client = i2c_new_device(&dev->i2c_adap[dev->def_i2c_bus], &info);
			if (client == NULL || client->dev.driver == NULL) {
				result = -ENODEV;
				goto out_free;
			}

			if (!try_module_get(client->dev.driver->owner)) {
				i2c_unregister_device(client);
				result = -ENODEV;
				goto out_free;
			}

			dvb->i2c_client_demod = client;

			/* attach tuner */
			memset(&si2157_config, 0, sizeof(si2157_config));
			si2157_config.fe = dvb->fe[0];
			memset(&info, 0, sizeof(struct i2c_board_info));
			strlcpy(info.type, "si2157", I2C_NAME_SIZE);
			info.addr = 0x60;
			info.platform_data = &si2157_config;
			request_module(info.type);
			client = i2c_new_device(adapter, &info);
			if (client == NULL || client->dev.driver == NULL) {
				module_put(dvb->i2c_client_demod->dev.driver->owner);
				i2c_unregister_device(dvb->i2c_client_demod);
				result = -ENODEV;
				goto out_free;
			}

			if (!try_module_get(client->dev.driver->owner)) {
				i2c_unregister_device(client);
				module_put(dvb->i2c_client_demod->dev.driver->owner);
				i2c_unregister_device(dvb->i2c_client_demod);
				result = -ENODEV;
				goto out_free;
			}

			dvb->i2c_client_tuner = client;
			dvb->fe[0]->ops.set_lna = em28xx_pctv_292e_set_lna;
		}
		break;
	default:
		em28xx_errdev("/2: The frontend of your DVB/ATSC card"
				" isn't supported yet\n");
		break;
	}
	if (NULL == dvb->fe[0]) {
		em28xx_errdev("/2: frontend initialization failed\n");
		result = -EINVAL;
		goto out_free;
	}
	/* define general-purpose callback pointer */
	dvb->fe[0]->callback = em28xx_tuner_callback;
	if (dvb->fe[1])
		dvb->fe[1]->callback = em28xx_tuner_callback;

	/* register everything */
	result = em28xx_register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev);

	if (result < 0)
		goto out_free;

	/* MFE lock */
	dvb->adapter.mfe_shared = mfe_shared;

	em28xx_info("DVB extension successfully initialized\n");

	kref_get(&dev->ref);

ret:
	em28xx_set_mode(dev, EM28XX_SUSPEND);
	mutex_unlock(&dev->lock);
	return result;

out_free:
	kfree(dvb);
	dev->dvb = NULL;
	goto ret;
}

static inline void prevent_sleep(struct dvb_frontend_ops *ops)
{
	ops->set_voltage = NULL;
	ops->sleep = NULL;
	ops->tuner_ops.sleep = NULL;
}
コード例 #18
0
ファイル: nfnetlink.c プロジェクト: Flipkart/linux
/* Process one complete nfnetlink message. */
static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
{
	struct net *net = sock_net(skb->sk);
	const struct nfnl_callback *nc;
	const struct nfnetlink_subsystem *ss;
	int type, err;

	/* All the messages must at least contain nfgenmsg */
	if (nlmsg_len(nlh) < sizeof(struct nfgenmsg))
		return 0;

	type = nlh->nlmsg_type;
replay:
	rcu_read_lock();
	ss = nfnetlink_get_subsys(type);
	if (!ss) {
#ifdef CONFIG_MODULES
		rcu_read_unlock();
		request_module("nfnetlink-subsys-%d", NFNL_SUBSYS_ID(type));
		rcu_read_lock();
		ss = nfnetlink_get_subsys(type);
		if (!ss)
#endif
		{
			rcu_read_unlock();
			return -EINVAL;
		}
	}

	nc = nfnetlink_find_client(type, ss);
	if (!nc) {
		rcu_read_unlock();
		return -EINVAL;
	}

	{
		int min_len = nlmsg_total_size(sizeof(struct nfgenmsg));
		u_int8_t cb_id = NFNL_MSG_TYPE(nlh->nlmsg_type);
		struct nlattr *cda[ss->cb[cb_id].attr_count + 1];
		struct nlattr *attr = (void *)nlh + min_len;
		int attrlen = nlh->nlmsg_len - min_len;
		__u8 subsys_id = NFNL_SUBSYS_ID(type);

		err = nla_parse(cda, ss->cb[cb_id].attr_count,
				attr, attrlen, ss->cb[cb_id].policy);
		if (err < 0) {
			rcu_read_unlock();
			return err;
		}

		if (nc->call_rcu) {
			err = nc->call_rcu(net->nfnl, skb, nlh,
					   (const struct nlattr **)cda);
			rcu_read_unlock();
		} else {
			rcu_read_unlock();
			nfnl_lock(subsys_id);
			if (rcu_dereference_protected(table[subsys_id].subsys,
				lockdep_is_held(&table[subsys_id].mutex)) != ss ||
			    nfnetlink_find_client(type, ss) != nc)
				err = -EAGAIN;
			else if (nc->call)
				err = nc->call(net->nfnl, skb, nlh,
						   (const struct nlattr **)cda);
			else
				err = -EINVAL;
			nfnl_unlock(subsys_id);
		}
		if (err == -EAGAIN)
			goto replay;
		return err;
	}
}
コード例 #19
0
ファイル: act_api.c プロジェクト: AiWinters/linux
struct tc_action *tcf_action_init_1(struct net *net, struct nlattr *nla,
				    struct nlattr *est, char *name, int ovr,
				    int bind)
{
	struct tc_action *a;
	struct tc_action_ops *a_o;
	char act_name[IFNAMSIZ];
	struct nlattr *tb[TCA_ACT_MAX + 1];
	struct nlattr *kind;
	int err;

	if (name == NULL) {
		err = nla_parse_nested(tb, TCA_ACT_MAX, nla, NULL);
		if (err < 0)
			goto err_out;
		err = -EINVAL;
		kind = tb[TCA_ACT_KIND];
		if (kind == NULL)
			goto err_out;
		if (nla_strlcpy(act_name, kind, IFNAMSIZ) >= IFNAMSIZ)
			goto err_out;
	} else {
		err = -EINVAL;
		if (strlcpy(act_name, name, IFNAMSIZ) >= IFNAMSIZ)
			goto err_out;
	}

	a_o = tc_lookup_action_n(act_name);
	if (a_o == NULL) {
#ifdef CONFIG_MODULES
		rtnl_unlock();
		request_module("act_%s", act_name);
		rtnl_lock();

		a_o = tc_lookup_action_n(act_name);

		/* We dropped the RTNL semaphore in order to
		 * perform the module load.  So, even if we
		 * succeeded in loading the module we have to
		 * tell the caller to replay the request.  We
		 * indicate this using -EAGAIN.
		 */
		if (a_o != NULL) {
			err = -EAGAIN;
			goto err_mod;
		}
#endif
		err = -ENOENT;
		goto err_out;
	}

	err = -ENOMEM;
	a = kzalloc(sizeof(*a), GFP_KERNEL);
	if (a == NULL)
		goto err_mod;

	/* backward compatibility for policer */
	if (name == NULL)
		err = a_o->init(net, tb[TCA_ACT_OPTIONS], est, a, ovr, bind);
	else
		err = a_o->init(net, nla, est, a, ovr, bind);
	if (err < 0)
		goto err_free;

	/* module count goes up only when brand new policy is created
	 * if it exists and is only bound to in a_o->init() then
	 * ACT_P_CREATED is not returned (a zero is).
	 */
	if (err != ACT_P_CREATED)
		module_put(a_o->owner);
	a->ops = a_o;

	return a;

err_free:
	kfree(a);
err_mod:
	module_put(a_o->owner);
err_out:
	return ERR_PTR(err);
}
コード例 #20
0
static void load_module(const char *name)
{
    request_module("dm-%s", name);
}
コード例 #21
0
/*
 * Establish a relationship between the specified key and cipher
 * and, if not a global key, allocate a hardware index from the
 * driver.  Note that we may be called for global keys but they
 * should have a key index already setup so the only work done
 * is to setup the cipher reference.
 *
 * This must be the first call applied to a key; all the other key
 * routines assume wk_cipher is setup.
 *
 * Locking must be handled by the caller using:
 *	ieee80211_key_update_begin(ic);
 *	ieee80211_key_update_end(ic);
 */
int
ieee80211_crypto_newkey(struct ieee80211com *ic,
	int cipher, struct ieee80211_key *key)
{
#define	N(a)	(sizeof(a) / sizeof(a[0]))
	const struct ieee80211_cipher *cip;
	void *keyctx;
	int oflags;

	/*
	 * Validate cipher and set reference to cipher routines.
	 */
	if (cipher >= IEEE80211_CIPHER_MAX) {
		IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO,
			("%s: invalid cipher %u\n", __func__, cipher));
		ic->ic_stats.is_crypto_badcipher++;
		return 0;
	}
	cip = ciphers[cipher];
	if (cip == NULL) {
		/*
		 * Auto-load cipher module if we have a well-known name
		 * for it.  It might be better to use string names rather
		 * than numbers and craft a module name based on the cipher
		 * name; e.g. wlan_cipher_<cipher-name>.
		 */
		if (cipher < N(cipher_modnames)) {
			IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO,
				("%s: unregistered cipher %u, load module %s\n",
				__func__, cipher, cipher_modnames[cipher]));
			request_module(cipher_modnames[cipher]);
			/*
			 * If cipher module loaded it should immediately
			 * call ieee80211_crypto_register which will fill
			 * in the entry in the ciphers array.
			 */
			cip = ciphers[cipher];
		}
		if (cip == NULL) {
			IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO,
				("%s: unable to load cipher %u, module %s\n",
				__func__, cipher,
				cipher < N(cipher_modnames) ?
					cipher_modnames[cipher] : "<unknown>"));
			ic->ic_stats.is_crypto_nocipher++;
			return 0;
		}
	}

	oflags = key->wk_flags;
	/*
	 * If the hardware does not support the cipher then
	 * fallback to a host-based implementation.
	 */
	key->wk_flags &= ~(IEEE80211_KEY_SWCRYPT|IEEE80211_KEY_SWMIC);
	if ((ic->ic_caps & (1<<cipher)) == 0) {
		IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO,
		    ("%s: no h/w support for cipher %s, falling back to s/w\n",
		    __func__, cip->ic_name));
		key->wk_flags |= IEEE80211_KEY_SWCRYPT;
	}
	/*
	 * Hardware TKIP with software MIC is an important
	 * combination; we handle it by flagging each key,
	 * the cipher modules honor it.
	 */
	if (cipher == IEEE80211_CIPHER_TKIP &&
	    (ic->ic_caps & IEEE80211_C_TKIPMIC) == 0) {
		IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO,
		    ("%s: no h/w support for TKIP MIC, falling back to s/w\n",
		    __func__));
		key->wk_flags |= IEEE80211_KEY_SWMIC;
	}

	/*
	 * Bind cipher to key instance.  Note we do this
	 * after checking the device capabilities so the
	 * cipher module can optimize space usage based on
	 * whether or not it needs to do the cipher work.
	 */
	if (key->wk_cipher != cip || key->wk_flags != oflags) {
again:
		keyctx = cip->ic_attach(ic, key);
		if (keyctx == NULL) {
			IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO,
				("%s: unable to attach cipher %s\n",
				__func__, cip->ic_name));
			key->wk_flags = oflags;	/* restore old flags */
			ic->ic_stats.is_crypto_attachfail++;
			return 0;
		}
		cipher_detach(key);
		key->wk_cipher = cip;		/* XXX refcnt? */
		key->wk_private = keyctx;
	}

	/*
	 * Ask the driver for a key index if we don't have one.
	 * Note that entries in the global key table always have
	 * an index; this means it's safe to call this routine
	 * for these entries just to setup the reference to the
	 * cipher template.  Note also that when using software
	 * crypto we also call the driver to give us a key index.
	 */
	if (key->wk_keyix == IEEE80211_KEYIX_NONE) {
		key->wk_keyix = dev_key_alloc(ic, key);
		if (key->wk_keyix == IEEE80211_KEYIX_NONE) {
			/*
			 * Driver has no room; fallback to doing crypto
			 * in the host.  We change the flags and start the
			 * procedure over.  If we get back here then there's
			 * no hope and we bail.  Note that this can leave
			 * the key in a inconsistent state if the caller
			 * continues to use it.
			 */
			if ((key->wk_flags & IEEE80211_KEY_SWCRYPT) == 0) {
				ic->ic_stats.is_crypto_swfallback++;
				IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO,
				    ("%s: no h/w resources for cipher %s, "
				    "falling back to s/w\n", __func__,
				    cip->ic_name));
				oflags = key->wk_flags;
				key->wk_flags |= IEEE80211_KEY_SWCRYPT;
				if (cipher == IEEE80211_CIPHER_TKIP)
					key->wk_flags |= IEEE80211_KEY_SWMIC;
				goto again;
			}
			ic->ic_stats.is_crypto_keyfail++;
			IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO,
			    ("%s: unable to setup cipher %s\n",
			    __func__, cip->ic_name));
			return 0;
		}
	}
	return 1;
#undef N
}
コード例 #22
0
/* Detect all SSAs attached to the machine.
   To be fast, do it on all online FC channels at the same time. */
__initfunc(int pluto_detect(Scsi_Host_Template *tpnt))
{
	int i, retry, nplutos;
	fc_channel *fc;
	Scsi_Device dev;

	tpnt->proc_dir = &proc_scsi_pluto;
	fcscount = 0;
	for_each_online_fc_channel(fc)
		fcscount++;
	PLND(("%d channels online\n", fcscount))
	if (!fcscount) {
#if defined(MODULE) && defined(CONFIG_FC4_SOC_MODULE) && defined(CONFIG_KMOD)
		request_module("soc");
		
		for_each_online_fc_channel(fc)
			fcscount++;
		if (!fcscount)
#endif
			return 0;
	}
	fcs = (struct ctrl_inquiry *) scsi_init_malloc (sizeof (struct ctrl_inquiry) * fcscount, GFP_DMA);
	if (!fcs) {
		printk ("PLUTO: Not enough memory to probe\n");
		return 0;
	}
	
	memset (fcs, 0, sizeof (struct ctrl_inquiry) * fcscount);
	memset (&dev, 0, sizeof(dev));
	atomic_set (&fcss, fcscount);
	fc_timer.function = pluto_detect_timeout;
	
	i = 0;
	for_each_online_fc_channel(fc) {
		Scsi_Cmnd *SCpnt;
		struct Scsi_Host *host;
		struct pluto *pluto;
		
		if (i == fcscount) break;
		
		PLD(("trying to find SSA\n"))

		/* If this is already registered to some other SCSI host, then it cannot be pluto */
		if (fc->scsi_name[0]) continue;
		memcpy (fc->scsi_name, "SSA", 4);
		
		fcs[i].fc = fc;
		
		fc->can_queue = PLUTO_CAN_QUEUE;
		fc->rsp_size = 64;
		fc->encode_addr = pluto_encode_addr;
		
		fc->fcp_register(fc, TYPE_SCSI_FCP, 0);
	
		SCpnt = &(fcs[i].cmd);
		host = &(fcs[i].host);
		pluto = (struct pluto *)host->hostdata;
		
		pluto->fc = fc;
	
		SCpnt->host = host;
		SCpnt->cmnd[0] = INQUIRY;
		SCpnt->cmnd[4] = 255;
		
		/* FC layer requires this, so that SCpnt->device->tagged_supported is initially 0 */
		SCpnt->device = &dev;
		
		SCpnt->cmd_len = COMMAND_SIZE(INQUIRY);
	
		SCpnt->request.rq_status = RQ_SCSI_BUSY;
		
		SCpnt->done = pluto_detect_done;
		SCpnt->bufflen = 256;
		SCpnt->buffer = fcs[i].inquiry;
		SCpnt->request_bufflen = 256;
		SCpnt->request_buffer = fcs[i].inquiry;
		PLD(("set up %d %08lx\n", i, (long)SCpnt))
		i++;
	}
	
	for (retry = 0; retry < 5; retry++) {
		for (i = 0; i < fcscount; i++) {
			if (!fcs[i].fc) break;
			if (fcs[i].cmd.request.rq_status != RQ_SCSI_DONE) {
				disable_irq(fcs[i].fc->irq);
				PLND(("queuecommand %d %d\n", retry, i))
				fcp_scsi_queuecommand (&(fcs[i].cmd), 
					pluto_detect_scsi_done);
				enable_irq(fcs[i].fc->irq);
			}
		}
	    
		fc_timer.expires = jiffies + 10 * HZ;
		add_timer(&fc_timer);
		
		down(&fc_sem);
		PLND(("Woken up\n"))
		if (!atomic_read(&fcss))
			break; /* All fc channels have answered us */
	}
	del_timer(&fc_timer);

	PLND(("Finished search\n"))
	for (i = 0, nplutos = 0; i < fcscount; i++) {
		Scsi_Cmnd *SCpnt;
		
		if (!(fc = fcs[i].fc)) break;
	
		SCpnt = &(fcs[i].cmd);
		
		/* Let FC mid-level free allocated resources */
		SCpnt->done (SCpnt);
		
		if (!SCpnt->result) {
			struct pluto_inquiry *inq;
			struct pluto *pluto;
			struct Scsi_Host *host;
			
			inq = (struct pluto_inquiry *)fcs[i].inquiry;

			if ((inq->dtype & 0x1f) == TYPE_PROCESSOR &&
			    !strncmp (inq->vendor_id, "SUN", 3) &&
			    !strncmp (inq->product_id, "SSA", 3)) {
				char *p;
				long *ages;
				
				ages = kmalloc (((inq->channels + 1) * inq->targets) * sizeof(long), GFP_KERNEL);
				if (!ages) continue;
				
				host = scsi_register (tpnt, sizeof (struct pluto));
				if (!host) panic ("Cannot register PLUTO host\n");
				
				nplutos++;
				
				if (fc->module) __MOD_INC_USE_COUNT(fc->module);
				
				pluto = (struct pluto *)host->hostdata;
				
				host->max_id = inq->targets;
				host->max_channel = inq->channels;
				host->irq = fc->irq;
				
				host->select_queue_depths = pluto_select_queue_depths;
				
				fc->channels = inq->channels + 1;
				fc->targets = inq->targets;
				fc->ages = ages;
				memset (ages, 0, ((inq->channels + 1) * inq->targets) * sizeof(long));
				
				pluto->fc = fc;
				memcpy (pluto->rev_str, inq->revision, 4);
				pluto->rev_str[4] = 0;
				p = strchr (pluto->rev_str, ' ');
				if (p) *p = 0;
				memcpy (pluto->fw_rev_str, inq->fw_revision, 4);
				pluto->fw_rev_str[4] = 0;
				p = strchr (pluto->fw_rev_str, ' ');
				if (p) *p = 0;
				memcpy (pluto->serial_str, inq->serial, 12);
				pluto->serial_str[12] = 0;
				p = strchr (pluto->serial_str, ' ');
				if (p) *p = 0;
				
				PLD(("Found SSA rev %s fw rev %s serial %s %dx%d\n", pluto->rev_str, pluto->fw_rev_str, pluto->serial_str, host->max_channel, host->max_id))
			} else
				fc->fcp_register(fc, TYPE_SCSI_FCP, 1);
		} else
コード例 #23
0
ファイル: cls_api.c プロジェクト: RobinSystems/linux-3.13
static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n)
{
	struct net *net = sock_net(skb->sk);
	struct nlattr *tca[TCA_MAX + 1];
	spinlock_t *root_lock;
	struct tcmsg *t;
	u32 protocol;
	u32 prio;
	u32 nprio;
	u32 parent;
	struct net_device *dev;
	struct Qdisc  *q;
	struct tcf_proto **back, **chain;
	struct tcf_proto *tp;
	const struct tcf_proto_ops *tp_ops;
	const struct Qdisc_class_ops *cops;
	unsigned long cl;
	unsigned long fh;
	int err;
	int tp_created = 0;

	if ((n->nlmsg_type != RTM_GETTFILTER) &&
	    !netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN))
		return -EPERM;

replay:
	err = nlmsg_parse(n, sizeof(*t), tca, TCA_MAX, NULL);
	if (err < 0)
		return err;

	t = nlmsg_data(n);
	protocol = TC_H_MIN(t->tcm_info);
	prio = TC_H_MAJ(t->tcm_info);
	nprio = prio;
	parent = t->tcm_parent;
	cl = 0;

	if (prio == 0) {
		/* If no priority is given, user wants we allocated it. */
		if (n->nlmsg_type != RTM_NEWTFILTER ||
		    !(n->nlmsg_flags & NLM_F_CREATE))
			return -ENOENT;
		prio = TC_H_MAKE(0x80000000U, 0U);
	}

	/* Find head of filter chain. */

	/* Find link */
	dev = __dev_get_by_index(net, t->tcm_ifindex);
	if (dev == NULL)
		return -ENODEV;

	/* Find qdisc */
	if (!parent) {
		q = dev->qdisc;
		parent = q->handle;
	} else {
		q = qdisc_lookup(dev, TC_H_MAJ(t->tcm_parent));
		if (q == NULL)
			return -EINVAL;
	}

	/* Is it classful? */
	cops = q->ops->cl_ops;
	if (!cops)
		return -EINVAL;

	if (cops->tcf_chain == NULL)
		return -EOPNOTSUPP;

	/* Do we search for filter, attached to class? */
	if (TC_H_MIN(parent)) {
		cl = cops->get(q, parent);
		if (cl == 0)
			return -ENOENT;
	}

	/* And the last stroke */
	chain = cops->tcf_chain(q, cl);
	err = -EINVAL;
	if (chain == NULL)
		goto errout;

	/* Check the chain for existence of proto-tcf with this priority */
	for (back = chain; (tp = *back) != NULL; back = &tp->next) {
		if (tp->prio >= prio) {
			if (tp->prio == prio) {
				if (!nprio ||
				    (tp->protocol != protocol && protocol))
					goto errout;
			} else
				tp = NULL;
			break;
		}
	}

	root_lock = qdisc_root_sleeping_lock(q);

	if (tp == NULL) {
		/* Proto-tcf does not exist, create new one */

		if (tca[TCA_KIND] == NULL || !protocol)
			goto errout;

		err = -ENOENT;
		if (n->nlmsg_type != RTM_NEWTFILTER ||
		    !(n->nlmsg_flags & NLM_F_CREATE))
			goto errout;


		/* Create new proto tcf */

		err = -ENOBUFS;
		tp = kzalloc(sizeof(*tp), GFP_KERNEL);
		if (tp == NULL)
			goto errout;
		err = -ENOENT;
		tp_ops = tcf_proto_lookup_ops(tca[TCA_KIND]);
		if (tp_ops == NULL) {
#ifdef CONFIG_MODULES
			struct nlattr *kind = tca[TCA_KIND];
			char name[IFNAMSIZ];

			if (kind != NULL &&
			    nla_strlcpy(name, kind, IFNAMSIZ) < IFNAMSIZ) {
				rtnl_unlock();
				request_module("cls_%s", name);
				rtnl_lock();
				tp_ops = tcf_proto_lookup_ops(kind);
				/* We dropped the RTNL semaphore in order to
				 * perform the module load.  So, even if we
				 * succeeded in loading the module we have to
				 * replay the request.  We indicate this using
				 * -EAGAIN.
				 */
				if (tp_ops != NULL) {
					module_put(tp_ops->owner);
					err = -EAGAIN;
				}
			}
#endif
			kfree(tp);
			goto errout;
		}
		tp->ops = tp_ops;
		tp->protocol = protocol;
		tp->prio = nprio ? : TC_H_MAJ(tcf_auto_prio(*back));
		tp->q = q;
		tp->classify = tp_ops->classify;
		tp->classid = parent;

		err = tp_ops->init(tp);
		if (err != 0) {
			module_put(tp_ops->owner);
			kfree(tp);
			goto errout;
		}

		tp_created = 1;

	} else if (tca[TCA_KIND] && nla_strcmp(tca[TCA_KIND], tp->ops->kind))
コード例 #24
0
ファイル: nf_log.c プロジェクト: AK101111/linux
void nf_logger_request_module(int pf, enum nf_log_type type)
{
	if (loggers[pf][type] == NULL)
		request_module("nf-logger-%u-%u", pf, type);
}
コード例 #25
0
static int mxb_probe(struct saa7146_dev* dev)
{
    struct mxb* mxb = NULL;
    int result;

    result = request_module("saa7115");
    if (result < 0) {
        printk("mxb: saa7111 i2c module not available.\n");
        return -ENODEV;
    }
    result = request_module("tea6420");
    if (result < 0) {
        printk("mxb: tea6420 i2c module not available.\n");
        return -ENODEV;
    }
    result = request_module("tea6415c");
    if (result < 0) {
        printk("mxb: tea6415c i2c module not available.\n");
        return -ENODEV;
    }
    result = request_module("tda9840");
    if (result < 0) {
        printk("mxb: tda9840 i2c module not available.\n");
        return -ENODEV;
    }
    result = request_module("tuner");
    if (result < 0) {
        printk("mxb: tuner i2c module not available.\n");
        return -ENODEV;
    }

    mxb = kzalloc(sizeof(struct mxb), GFP_KERNEL);
    if( NULL == mxb ) {
        DEB_D(("not enough kernel memory.\n"));
        return -ENOMEM;
    }

    mxb->i2c_adapter = (struct i2c_adapter) {
        .class = I2C_CLASS_TV_ANALOG,
    };

    snprintf(mxb->i2c_adapter.name, sizeof(mxb->i2c_adapter.name), "mxb%d", mxb_num);

    saa7146_i2c_adapter_prepare(dev, &mxb->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480);
    if(i2c_add_adapter(&mxb->i2c_adapter) < 0) {
        DEB_S(("cannot register i2c-device. skipping.\n"));
        kfree(mxb);
        return -EFAULT;
    }

    /* loop through all i2c-devices on the bus and look who is there */
    device_for_each_child(&mxb->i2c_adapter.dev, mxb, mxb_check_clients);

    /* check if all devices are present */
    if (!mxb->tea6420_1 || !mxb->tea6420_2 || !mxb->tea6415c ||
            !mxb->tda9840 || !mxb->saa7111a || !mxb->tuner) {
        printk("mxb: did not find all i2c devices. aborting\n");
        i2c_del_adapter(&mxb->i2c_adapter);
        kfree(mxb);
        return -ENODEV;
    }

    /* all devices are present, probe was successful */

    /* we store the pointer in our private data field */
    dev->ext_priv = mxb;

    return 0;
}

/* some init data for the saa7740, the so-called 'sound arena module'.
   there are no specs available, so we simply use some init values */
static struct {
    int	length;
    char	data[9];
} mxb_saa7740_init[] = {
    { 3, { 0x80, 0x00, 0x00 } },{ 3, { 0x80, 0x89, 0x00 } },
    { 3, { 0x80, 0xb0, 0x0a } },{ 3, { 0x00, 0x00, 0x00 } },
    { 3, { 0x49, 0x00, 0x00 } },{ 3, { 0x4a, 0x00, 0x00 } },
    { 3, { 0x4b, 0x00, 0x00 } },{ 3, { 0x4c, 0x00, 0x00 } },
    { 3, { 0x4d, 0x00, 0x00 } },{ 3, { 0x4e, 0x00, 0x00 } },
    { 3, { 0x4f, 0x00, 0x00 } },{ 3, { 0x50, 0x00, 0x00 } },
    { 3, { 0x51, 0x00, 0x00 } },{ 3, { 0x52, 0x00, 0x00 } },
    { 3, { 0x53, 0x00, 0x00 } },{ 3, { 0x54, 0x00, 0x00 } },
    { 3, { 0x55, 0x00, 0x00 } },{ 3, { 0x56, 0x00, 0x00 } },
    { 3, { 0x57, 0x00, 0x00 } },{ 3, { 0x58, 0x00, 0x00 } },
    { 3, { 0x59, 0x00, 0x00 } },{ 3, { 0x5a, 0x00, 0x00 } },
    { 3, { 0x5b, 0x00, 0x00 } },{ 3, { 0x5c, 0x00, 0x00 } },
    { 3, { 0x5d, 0x00, 0x00 } },{ 3, { 0x5e, 0x00, 0x00 } },
    { 3, { 0x5f, 0x00, 0x00 } },{ 3, { 0x60, 0x00, 0x00 } },
    { 3, { 0x61, 0x00, 0x00 } },{ 3, { 0x62, 0x00, 0x00 } },
    { 3, { 0x63, 0x00, 0x00 } },{ 3, { 0x64, 0x00, 0x00 } },
    { 3, { 0x65, 0x00, 0x00 } },{ 3, { 0x66, 0x00, 0x00 } },
    { 3, { 0x67, 0x00, 0x00 } },{ 3, { 0x68, 0x00, 0x00 } },
    { 3, { 0x69, 0x00, 0x00 } },{ 3, { 0x6a, 0x00, 0x00 } },
    { 3, { 0x6b, 0x00, 0x00 } },{ 3, { 0x6c, 0x00, 0x00 } },
    { 3, { 0x6d, 0x00, 0x00 } },{ 3, { 0x6e, 0x00, 0x00 } },
    { 3, { 0x6f, 0x00, 0x00 } },{ 3, { 0x70, 0x00, 0x00 } },
    { 3, { 0x71, 0x00, 0x00 } },{ 3, { 0x72, 0x00, 0x00 } },
    { 3, { 0x73, 0x00, 0x00 } },{ 3, { 0x74, 0x00, 0x00 } },
    { 3, { 0x75, 0x00, 0x00 } },{ 3, { 0x76, 0x00, 0x00 } },
    { 3, { 0x77, 0x00, 0x00 } },{ 3, { 0x41, 0x00, 0x42 } },
    { 3, { 0x42, 0x10, 0x42 } },{ 3, { 0x43, 0x20, 0x42 } },
    { 3, { 0x44, 0x30, 0x42 } },{ 3, { 0x45, 0x00, 0x01 } },
    { 3, { 0x46, 0x00, 0x01 } },{ 3, { 0x47, 0x00, 0x01 } },
    { 3, { 0x48, 0x00, 0x01 } },
    { 9, { 0x01, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } },
    { 9, { 0x21, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } },
    { 9, { 0x09, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } },
    { 9, { 0x29, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } },
    { 9, { 0x11, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } },
    { 9, { 0x31, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } },
    { 9, { 0x19, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } },
    { 9, { 0x39, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } },
    { 9, { 0x05, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } },
    { 9, { 0x25, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } },
    { 9, { 0x0d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } },
    { 9, { 0x2d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } },
    { 9, { 0x15, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } },
    { 9, { 0x35, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } },
    { 9, { 0x1d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } },
    { 9, { 0x3d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } },
    { 3, { 0x80, 0xb3, 0x0a } },
    {-1, { 0 } }
};

/* bring hardware to a sane state. this has to be done, just in case someone
   wants to capture from this device before it has been properly initialized.
   the capture engine would badly fail, because no valid signal arrives on the
   saa7146, thus leading to timeouts and stuff. */
static int mxb_init_done(struct saa7146_dev* dev)
{
    struct mxb* mxb = (struct mxb*)dev->ext_priv;
    struct i2c_msg msg;
    struct tuner_setup tun_setup;
    v4l2_std_id std = V4L2_STD_PAL_BG;
    struct v4l2_routing route;

    int i = 0, err = 0;
    struct tea6415c_multiplex vm;

    /* select video mode in saa7111a */
    mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_S_STD, &std);

    /* select tuner-output on saa7111a */
    i = 0;
    route.input = SAA7115_COMPOSITE0;
    route.output = SAA7111_FMT_CCIR | SAA7111_VBI_BYPASS;
    mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_VIDEO_ROUTING, &route);

    /* select a tuner type */
    tun_setup.mode_mask = T_ANALOG_TV;
    tun_setup.addr = ADDR_UNSET;
    tun_setup.type = TUNER_PHILIPS_PAL;
    mxb->tuner->driver->command(mxb->tuner, TUNER_SET_TYPE_ADDR, &tun_setup);
    /* tune in some frequency on tuner */
    mxb->cur_freq.tuner = 0;
    mxb->cur_freq.type = V4L2_TUNER_ANALOG_TV;
    mxb->cur_freq.frequency = freq;
    mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY,
                                &mxb->cur_freq);

    /* set a default video standard */
    mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);

    /* mute audio on tea6420s */
    mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH, &TEA6420_line[6][0]);
    mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH, &TEA6420_line[6][1]);
    mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH, &TEA6420_cd[6][0]);
    mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH, &TEA6420_cd[6][1]);

    /* switch to tuner-channel on tea6415c*/
    vm.out = 17;
    vm.in  = 3;
    mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm);

    /* select tuner-output on multicable on tea6415c*/
    vm.in  = 3;
    vm.out = 13;
    mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm);

    /* the rest for mxb */
    mxb->cur_input = 0;
    mxb->cur_mute = 1;

    mxb->cur_mode = V4L2_TUNER_MODE_STEREO;

    /* check if the saa7740 (aka 'sound arena module') is present
       on the mxb. if so, we must initialize it. due to lack of
       informations about the saa7740, the values were reverse
       engineered. */
    msg.addr = 0x1b;
    msg.flags = 0;
    msg.len = mxb_saa7740_init[0].length;
    msg.buf = &mxb_saa7740_init[0].data[0];

    err = i2c_transfer(&mxb->i2c_adapter, &msg, 1);
    if (err == 1) {
        /* the sound arena module is a pos, that's probably the reason
           philips refuses to hand out a datasheet for the saa7740...
           it seems to screw up the i2c bus, so we disable fast irq
           based i2c transactions here and rely on the slow and safe
           polling method ... */
        extension.flags &= ~SAA7146_USE_I2C_IRQ;
        for (i = 1; ; i++) {
            if (-1 == mxb_saa7740_init[i].length)
                break;

            msg.len = mxb_saa7740_init[i].length;
            msg.buf = &mxb_saa7740_init[i].data[0];
            err = i2c_transfer(&mxb->i2c_adapter, &msg, 1);
            if (err != 1) {
                DEB_D(("failed to initialize 'sound arena module'.\n"));
                goto err;
            }
        }
        INFO(("'sound arena module' detected.\n"));
    }
err:
    /* the rest for saa7146: you should definitely set some basic values
       for the input-port handling of the saa7146. */

    /* ext->saa has been filled by the core driver */

    /* some stuff is done via variables */
    saa7146_set_hps_source_and_sync(dev, input_port_selection[mxb->cur_input].hps_source,
                                    input_port_selection[mxb->cur_input].hps_sync);

    /* some stuff is done via direct write to the registers */

    /* this is ugly, but because of the fact that this is completely
       hardware dependend, it should be done directly... */
    saa7146_write(dev, DD1_STREAM_B,	0x00000000);
    saa7146_write(dev, DD1_INIT,		0x02000200);
    saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));

    return 0;
}

/* interrupt-handler. this gets called when irq_mask is != 0.
   it must clear the interrupt-bits in irq_mask it has handled */
/*
void mxb_irq_bh(struct saa7146_dev* dev, u32* irq_mask)
{
	struct mxb* mxb = (struct mxb*)dev->ext_priv;
}
*/

static struct saa7146_ext_vv vv_data;

/* this function only gets called when the probing was successful */
static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
{
    struct mxb *mxb = (struct mxb *)dev->ext_priv;

    DEB_EE(("dev:%p\n", dev));

    /* checking for i2c-devices can be omitted here, because we
       already did this in "mxb_vl42_probe" */

    saa7146_vv_init(dev, &vv_data);
    if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) {
        ERR(("cannot register capture v4l2 device. skipping.\n"));
        return -1;
    }

    /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
    if (MXB_BOARD_CAN_DO_VBI(dev)) {
        if (saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) {
            ERR(("cannot register vbi v4l2 device. skipping.\n"));
        }
    }

    i2c_use_client(mxb->tea6420_1);
    i2c_use_client(mxb->tea6420_2);
    i2c_use_client(mxb->tea6415c);
    i2c_use_client(mxb->tda9840);
    i2c_use_client(mxb->saa7111a);
    i2c_use_client(mxb->tuner);

    printk("mxb: found Multimedia eXtension Board #%d.\n", mxb_num);

    mxb_num++;
    mxb_init_done(dev);
    return 0;
}

static int mxb_detach(struct saa7146_dev *dev)
{
    struct mxb *mxb = (struct mxb *)dev->ext_priv;

    DEB_EE(("dev:%p\n", dev));

    i2c_release_client(mxb->tea6420_1);
    i2c_release_client(mxb->tea6420_2);
    i2c_release_client(mxb->tea6415c);
    i2c_release_client(mxb->tda9840);
    i2c_release_client(mxb->saa7111a);
    i2c_release_client(mxb->tuner);

    saa7146_unregister_device(&mxb->video_dev,dev);
    if (MXB_BOARD_CAN_DO_VBI(dev))
        saa7146_unregister_device(&mxb->vbi_dev, dev);
    saa7146_vv_release(dev);

    mxb_num--;

    i2c_del_adapter(&mxb->i2c_adapter);
    kfree(mxb);

    return 0;
}

static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
{
    struct saa7146_dev *dev = fh->dev;
    struct mxb *mxb = (struct mxb *)dev->ext_priv;
    struct saa7146_vv *vv = dev->vv_data;

    switch(cmd) {
    case VIDIOC_ENUMINPUT:
    {
        struct v4l2_input *i = arg;

        DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index));
        if (i->index < 0 || i->index >= MXB_INPUTS)
            return -EINVAL;
        memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input));
        return 0;
    }
    /* the saa7146 provides some controls (brightness, contrast, saturation)
       which gets registered *after* this function. because of this we have
       to return with a value != 0 even if the function succeded.. */
    case VIDIOC_QUERYCTRL:
    {
        struct v4l2_queryctrl *qc = arg;
        int i;

        for (i = MAXCONTROLS - 1; i >= 0; i--) {
            if (mxb_controls[i].id == qc->id) {
                *qc = mxb_controls[i];
                DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id));
                return 0;
            }
        }
        return -EAGAIN;
    }
    case VIDIOC_G_CTRL:
    {
        struct v4l2_control *vc = arg;
        int i;

        for (i = MAXCONTROLS - 1; i >= 0; i--) {
            if (mxb_controls[i].id == vc->id)
                break;
        }

        if (i < 0)
            return -EAGAIN;

        if (vc->id == V4L2_CID_AUDIO_MUTE) {
            vc->value = mxb->cur_mute;
            DEB_D(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value));
            return 0;
        }

        DEB_EE(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value));
        return 0;
    }

    case VIDIOC_S_CTRL:
    {
        struct v4l2_control *vc = arg;
        int i = 0;

        for (i = MAXCONTROLS - 1; i >= 0; i--) {
            if (mxb_controls[i].id == vc->id)
                break;
        }

        if (i < 0)
            return -EAGAIN;

        if (vc->id == V4L2_CID_AUDIO_MUTE) {
            mxb->cur_mute = vc->value;
            if (!vc->value) {
                /* switch the audio-source */
                mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH,
                                                &TEA6420_line[video_audio_connect[mxb->cur_input]][0]);
                mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH,
                                                &TEA6420_line[video_audio_connect[mxb->cur_input]][1]);
            } else {
                mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH,
                                                &TEA6420_line[6][0]);
                mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH,
                                                &TEA6420_line[6][1]);
            }
            DEB_EE(("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d.\n", vc->value));
        }
        return 0;
    }
    case VIDIOC_G_INPUT:
    {
        int *input = (int *)arg;
        *input = mxb->cur_input;

        DEB_EE(("VIDIOC_G_INPUT %d.\n", *input));
        return 0;
    }
    case VIDIOC_S_INPUT:
    {
        int input = *(int *)arg;
        struct tea6415c_multiplex vm;
        struct v4l2_routing route;
        int i = 0;

        DEB_EE(("VIDIOC_S_INPUT %d.\n", input));

        if (input < 0 || input >= MXB_INPUTS)
            return -EINVAL;

        mxb->cur_input = input;

        saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source,
                                        input_port_selection[input].hps_sync);

        /* prepare switching of tea6415c and saa7111a;
           have a look at the 'background'-file for further informations  */
        switch (input) {
        case TUNER:
            i = SAA7115_COMPOSITE0;
            vm.in  = 3;
            vm.out = 17;

            if (mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm)) {
                printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #1\n");
                return -EFAULT;
            }
            /* connect tuner-output always to multicable */
            vm.in  = 3;
            vm.out = 13;
            break;
        case AUX3_YC:
            /* nothing to be done here. aux3_yc is
               directly connected to the saa711a */
            i = SAA7115_SVIDEO1;
            break;
        case AUX3:
            /* nothing to be done here. aux3 is
               directly connected to the saa711a */
            i = SAA7115_COMPOSITE1;
            break;
        case AUX1:
            i = SAA7115_COMPOSITE0;
            vm.in  = 1;
            vm.out = 17;
            break;
        }

        /* switch video in tea6415c only if necessary */
        switch (input) {
        case TUNER:
        case AUX1:
            if (mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm)) {
                printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #3\n");
                return -EFAULT;
            }
            break;
        default:
            break;
        }

        /* switch video in saa7111a */
        route.input = i;
        route.output = 0;
        if (mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_VIDEO_ROUTING, &route))
            printk("VIDIOC_S_INPUT: could not address saa7111a #1.\n");

        /* switch the audio-source only if necessary */
        if( 0 == mxb->cur_mute ) {
            mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH,
                                            &TEA6420_line[video_audio_connect[input]][0]);
            mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH,
                                            &TEA6420_line[video_audio_connect[input]][1]);
        }

        return 0;
    }
    case VIDIOC_G_TUNER:
    {
        struct v4l2_tuner *t = arg;

        if (t->index) {
            DEB_D(("VIDIOC_G_TUNER: channel %d does not have a tuner attached.\n", t->index));
            return -EINVAL;
        }

        DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index));

        memset(t, 0, sizeof(*t));
        i2c_clients_command(&mxb->i2c_adapter, cmd, arg);

        strlcpy(t->name, "TV Tuner", sizeof(t->name));
        t->type = V4L2_TUNER_ANALOG_TV;
        t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | \
                        V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
        t->audmode = mxb->cur_mode;
        return 0;
    }
    case VIDIOC_S_TUNER:
    {
        struct v4l2_tuner *t = arg;

        if (t->index) {
            DEB_D(("VIDIOC_S_TUNER: channel %d does not have a tuner attached.\n",t->index));
            return -EINVAL;
        }

        mxb->cur_mode = t->audmode;
        i2c_clients_command(&mxb->i2c_adapter, cmd, arg);
        return 0;
    }
    case VIDIOC_G_FREQUENCY:
    {
        struct v4l2_frequency *f = arg;

        if (mxb->cur_input) {
            DEB_D(("VIDIOC_G_FREQ: channel %d does not have a tuner!\n",
                   mxb->cur_input));
            return -EINVAL;
        }

        *f = mxb->cur_freq;

        DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", mxb->cur_freq.frequency));
        return 0;
    }
    case VIDIOC_S_FREQUENCY:
    {
        struct v4l2_frequency *f = arg;

        if (f->tuner)
            return -EINVAL;

        if (V4L2_TUNER_ANALOG_TV != f->type)
            return -EINVAL;

        if (mxb->cur_input) {
            DEB_D(("VIDIOC_S_FREQ: channel %d does not have a tuner!\n", mxb->cur_input));
            return -EINVAL;
        }

        mxb->cur_freq = *f;
        DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n", mxb->cur_freq.frequency));

        /* tune in desired frequency */
        mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY, &mxb->cur_freq);

        /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */
        spin_lock(&dev->slock);
        vv->vbi_fieldcount = 0;
        spin_unlock(&dev->slock);

        return 0;
    }
    case MXB_S_AUDIO_CD:
    {
        int i = *(int*)arg;

        if (i < 0 || i >= MXB_AUDIOS) {
            DEB_D(("illegal argument to MXB_S_AUDIO_CD: i:%d.\n",i));
            return -EINVAL;
        }

        DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n",i));

        mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_cd[i][0]);
        mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_cd[i][1]);

        return 0;
    }
    case MXB_S_AUDIO_LINE:
    {
        int i = *(int*)arg;

        if (i < 0 || i >= MXB_AUDIOS) {
            DEB_D(("illegal argument to MXB_S_AUDIO_LINE: i:%d.\n",i));
            return -EINVAL;
        }

        DEB_EE(("MXB_S_AUDIO_LINE: i:%d.\n",i));
        mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[i][0]);
        mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[i][1]);

        return 0;
    }
    case VIDIOC_G_AUDIO:
    {
        struct v4l2_audio *a = arg;

        if (a->index < 0 || a->index > MXB_INPUTS) {
            DEB_D(("VIDIOC_G_AUDIO %d out of range.\n", a->index));
            return -EINVAL;
        }

        DEB_EE(("VIDIOC_G_AUDIO %d.\n", a->index));
        memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio));

        return 0;
    }
    case VIDIOC_S_AUDIO:
    {
        struct v4l2_audio *a = arg;

        DEB_D(("VIDIOC_S_AUDIO %d.\n", a->index));
        return 0;
    }
#ifdef CONFIG_VIDEO_ADV_DEBUG
    case VIDIOC_DBG_S_REGISTER:
    case VIDIOC_DBG_G_REGISTER:
        i2c_clients_command(&mxb->i2c_adapter, cmd, arg);
        return 0;
#endif
    default:
        /*
        		DEB2(printk("does not handle this ioctl.\n"));
        */
        return -ENOIOCTLCMD;
    }
    return 0;
}

static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standard)
{
    struct mxb *mxb = (struct mxb *)dev->ext_priv;
    int zero = 0;
    int one = 1;

    if (V4L2_STD_PAL_I == standard->id) {
        v4l2_std_id std = V4L2_STD_PAL_I;

        DEB_D(("VIDIOC_S_STD: setting mxb for PAL_I.\n"));
        /* set the 7146 gpio register -- I don't know what this does exactly */
        saa7146_write(dev, GPIO_CTRL, 0x00404050);
        /* unset the 7111 gpio register -- I don't know what this does exactly */
        mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_GPIO, &zero);
        mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);
    } else {
        v4l2_std_id std = V4L2_STD_PAL_BG;

        DEB_D(("VIDIOC_S_STD: setting mxb for PAL/NTSC/SECAM.\n"));
        /* set the 7146 gpio register -- I don't know what this does exactly */
        saa7146_write(dev, GPIO_CTRL, 0x00404050);
        /* set the 7111 gpio register -- I don't know what this does exactly */
        mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_GPIO, &one);
        mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);
    }
    return 0;
}

static struct saa7146_standard standard[] = {
    {
        .name	= "PAL-BG", 	.id	= V4L2_STD_PAL_BG,
        .v_offset	= 0x17,	.v_field 	= 288,
        .h_offset	= 0x14,	.h_pixels 	= 680,
        .v_max_out	= 576,	.h_max_out	= 768,
    }, {
        .name	= "PAL-I", 	.id	= V4L2_STD_PAL_I,
コード例 #26
0
ファイル: cls_api.c プロジェクト: iPodLinux/linux-2.6.7-ipod
static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
{
	struct rtattr **tca = arg;
	struct tcmsg *t = NLMSG_DATA(n);
	u32 protocol = TC_H_MIN(t->tcm_info);
	u32 prio = TC_H_MAJ(t->tcm_info);
	u32 nprio = prio;
	u32 parent = t->tcm_parent;
	struct net_device *dev;
	struct Qdisc  *q;
	struct tcf_proto **back, **chain;
	struct tcf_proto *tp = NULL;
	struct tcf_proto_ops *tp_ops;
	struct Qdisc_class_ops *cops;
	unsigned long cl = 0;
	unsigned long fh;
	int err;

	if (prio == 0) {
		/* If no priority is given, user wants we allocated it. */
		if (n->nlmsg_type != RTM_NEWTFILTER || !(n->nlmsg_flags&NLM_F_CREATE))
			return -ENOENT;
		prio = TC_H_MAKE(0x80000000U,0U);
	}

	/* Find head of filter chain. */

	/* Find link */
	if ((dev = __dev_get_by_index(t->tcm_ifindex)) == NULL)
		return -ENODEV;

	/* Find qdisc */
	if (!parent) {
		q = dev->qdisc_sleeping;
		parent = q->handle;
	} else if ((q = qdisc_lookup(dev, TC_H_MAJ(t->tcm_parent))) == NULL)
		return -EINVAL;

	/* Is it classful? */
	if ((cops = q->ops->cl_ops) == NULL)
		return -EINVAL;

	/* Do we search for filter, attached to class? */
	if (TC_H_MIN(parent)) {
		cl = cops->get(q, parent);
		if (cl == 0)
			return -ENOENT;
	}

	/* And the last stroke */
	chain = cops->tcf_chain(q, cl);
	err = -EINVAL;
	if (chain == NULL)
		goto errout;

	/* Check the chain for existence of proto-tcf with this priority */
	for (back = chain; (tp=*back) != NULL; back = &tp->next) {
		if (tp->prio >= prio) {
			if (tp->prio == prio) {
				if (!nprio || (tp->protocol != protocol && protocol))
					goto errout;
			} else
				tp = NULL;
			break;
		}
	}

	if (tp == NULL) {
		/* Proto-tcf does not exist, create new one */

		if (tca[TCA_KIND-1] == NULL || !protocol)
			goto errout;

		err = -ENOENT;
		if (n->nlmsg_type != RTM_NEWTFILTER || !(n->nlmsg_flags&NLM_F_CREATE))
			goto errout;


		/* Create new proto tcf */

		err = -ENOBUFS;
		if ((tp = kmalloc(sizeof(*tp), GFP_KERNEL)) == NULL)
			goto errout;
		tp_ops = tcf_proto_lookup_ops(tca[TCA_KIND-1]);
#ifdef CONFIG_KMOD
		if (tp_ops==NULL && tca[TCA_KIND-1] != NULL) {
			struct rtattr *kind = tca[TCA_KIND-1];

			if (RTA_PAYLOAD(kind) <= IFNAMSIZ) {
				request_module("cls_%s", (char*)RTA_DATA(kind));
				tp_ops = tcf_proto_lookup_ops(kind);
			}
		}
#endif
		if (tp_ops == NULL) {
			err = -EINVAL;
			kfree(tp);
			goto errout;
		}
		memset(tp, 0, sizeof(*tp));
		tp->ops = tp_ops;
		tp->protocol = protocol;
		tp->prio = nprio ? : tcf_auto_prio(*back);
		tp->q = q;
		tp->classify = tp_ops->classify;
		tp->classid = parent;
		err = -EBUSY;
		if (!try_module_get(tp_ops->owner) ||
		    (err = tp_ops->init(tp)) != 0) {
			kfree(tp);
			goto errout;
		}
		write_lock(&qdisc_tree_lock);
		spin_lock_bh(&dev->queue_lock);
		tp->next = *back;
		*back = tp;
		spin_unlock_bh(&dev->queue_lock);
		write_unlock(&qdisc_tree_lock);
	} else if (tca[TCA_KIND-1] && rtattr_strcmp(tca[TCA_KIND-1], tp->ops->kind))
コード例 #27
0
ファイル: rtl28xxu.c プロジェクト: kvaster/linux_media
static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap)
{
	int ret;
	struct dvb_usb_device *d = adap_to_d(adap);
	struct rtl28xxu_priv *priv = d_to_priv(d);
	struct dvb_frontend *fe = NULL;
	struct i2c_board_info info;
	struct i2c_client *client;

	dev_dbg(&d->udev->dev, "%s:\n", __func__);

	memset(&info, 0, sizeof(struct i2c_board_info));

	switch (priv->tuner) {
	case TUNER_RTL2832_FC0012:
		fe = dvb_attach(fc0012_attach, adap->fe[0],
			&d->i2c_adap, &rtl2832u_fc0012_config);

		/* since fc0012 includs reading the signal strength delegate
		 * that to the tuner driver */
		adap->fe[0]->ops.read_signal_strength =
				adap->fe[0]->ops.tuner_ops.get_rf_strength;

		/* attach SDR */
		dvb_attach_sdr(rtl2832_sdr_attach, adap->fe[0], &d->i2c_adap,
				&rtl28xxu_rtl2832_fc0012_config, NULL);
		break;
	case TUNER_RTL2832_FC0013:
		fe = dvb_attach(fc0013_attach, adap->fe[0],
			&d->i2c_adap, 0xc6>>1, 0, FC_XTAL_28_8_MHZ);

		/* fc0013 also supports signal strength reading */
		adap->fe[0]->ops.read_signal_strength =
				adap->fe[0]->ops.tuner_ops.get_rf_strength;

		/* attach SDR */
		dvb_attach_sdr(rtl2832_sdr_attach, adap->fe[0], &d->i2c_adap,
				&rtl28xxu_rtl2832_fc0013_config, NULL);
		break;
	case TUNER_RTL2832_E4000: {
			struct v4l2_subdev *sd;
			struct i2c_adapter *i2c_adap_internal =
					rtl2832_get_private_i2c_adapter(adap->fe[0]);
			struct e4000_config e4000_config = {
				.fe = adap->fe[0],
				.clock = 28800000,
			};

			strlcpy(info.type, "e4000", I2C_NAME_SIZE);
			info.addr = 0x64;
			info.platform_data = &e4000_config;

			request_module(info.type);
			client = i2c_new_device(priv->demod_i2c_adapter, &info);
			if (client == NULL || client->dev.driver == NULL)
				break;

			if (!try_module_get(client->dev.driver->owner)) {
				i2c_unregister_device(client);
				break;
			}

			priv->i2c_client_tuner = client;
			sd = i2c_get_clientdata(client);
			i2c_set_adapdata(i2c_adap_internal, d);

			/* attach SDR */
			dvb_attach_sdr(rtl2832_sdr_attach, adap->fe[0],
					i2c_adap_internal,
					&rtl28xxu_rtl2832_e4000_config, sd);
		}
		break;
	case TUNER_RTL2832_FC2580:
		fe = dvb_attach(fc2580_attach, adap->fe[0], &d->i2c_adap,
				&rtl2832u_fc2580_config);
		break;
	case TUNER_RTL2832_TUA9001:
		/* enable GPIO1 and GPIO4 as output */
		ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_DIR, 0x00, 0x12);
		if (ret)
			goto err;

		ret = rtl28xx_wr_reg_mask(d, SYS_GPIO_OUT_EN, 0x12, 0x12);
		if (ret)
			goto err;

		fe = dvb_attach(tua9001_attach, adap->fe[0], &d->i2c_adap,
				&rtl2832u_tua9001_config);
		break;
	case TUNER_RTL2832_R820T:
		fe = dvb_attach(r820t_attach, adap->fe[0], &d->i2c_adap,
				&rtl2832u_r820t_config);

		/* Use tuner to get the signal strength */
		adap->fe[0]->ops.read_signal_strength =
				adap->fe[0]->ops.tuner_ops.get_rf_strength;

		/* attach SDR */
		dvb_attach_sdr(rtl2832_sdr_attach, adap->fe[0], &d->i2c_adap,
				&rtl28xxu_rtl2832_r820t_config, NULL);
		break;
	case TUNER_RTL2832_R828D:
		fe = dvb_attach(r820t_attach, adap->fe[0],
				priv->demod_i2c_adapter,
				&rtl2832u_r828d_config);
		adap->fe[0]->ops.read_signal_strength =
				adap->fe[0]->ops.tuner_ops.get_rf_strength;

		if (adap->fe[1]) {
			fe = dvb_attach(r820t_attach, adap->fe[1],
					priv->demod_i2c_adapter,
					&rtl2832u_r828d_config);
			adap->fe[1]->ops.read_signal_strength =
					adap->fe[1]->ops.tuner_ops.get_rf_strength;
		}

		/* attach SDR */
		dvb_attach_sdr(rtl2832_sdr_attach, adap->fe[0], &d->i2c_adap,
				&rtl28xxu_rtl2832_r820t_config, NULL);
		break;
	default:
		dev_err(&d->udev->dev, "%s: unknown tuner=%d\n", KBUILD_MODNAME,
				priv->tuner);
	}

	if (fe == NULL && priv->i2c_client_tuner == NULL) {
		ret = -ENODEV;
		goto err;
	}

	return 0;
err:
	dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
	return ret;
}

static int rtl2832u_tuner_detach(struct dvb_usb_adapter *adap)
{
	struct dvb_usb_device *d = adap_to_d(adap);
	struct rtl28xxu_priv *priv = d_to_priv(d);
	struct i2c_client *client;

	dev_dbg(&d->udev->dev, "%s:\n", __func__);

	/* remove I2C tuner */
	client = priv->i2c_client_tuner;
	if (client) {
		module_put(client->dev.driver->owner);
		i2c_unregister_device(client);
	}

	return 0;
}

static int rtl28xxu_init(struct dvb_usb_device *d)
{
	int ret;
	u8 val;

	dev_dbg(&d->udev->dev, "%s:\n", __func__);

	/* init USB endpoints */
	ret = rtl28xx_rd_reg(d, USB_SYSCTL_0, &val);
	if (ret)
		goto err;

	/* enable DMA and Full Packet Mode*/
	val |= 0x09;
	ret = rtl28xx_wr_reg(d, USB_SYSCTL_0, val);
	if (ret)
		goto err;

	/* set EPA maximum packet size to 0x0200 */
	ret = rtl28xx_wr_regs(d, USB_EPA_MAXPKT, "\x00\x02\x00\x00", 4);
	if (ret)
		goto err;

	/* change EPA FIFO length */
	ret = rtl28xx_wr_regs(d, USB_EPA_FIFO_CFG, "\x14\x00\x00\x00", 4);
	if (ret)
		goto err;

	return ret;
err:
	dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
	return ret;
}
コード例 #28
0
ファイル: rtl28xxu.c プロジェクト: kvaster/linux_media
static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap)
{
	int ret;
	struct dvb_usb_device *d = adap_to_d(adap);
	struct rtl28xxu_priv *priv = d_to_priv(d);
	struct rtl2832_platform_data platform_data;
	const struct rtl2832_config *rtl2832_config;
	struct i2c_board_info board_info = {};
	struct i2c_client *client;

	dev_dbg(&d->udev->dev, "%s:\n", __func__);

	switch (priv->tuner) {
	case TUNER_RTL2832_FC0012:
		rtl2832_config = &rtl28xxu_rtl2832_fc0012_config;
		break;
	case TUNER_RTL2832_FC0013:
		rtl2832_config = &rtl28xxu_rtl2832_fc0013_config;
		break;
	case TUNER_RTL2832_FC2580:
		/* FIXME: do not abuse fc0012 settings */
		rtl2832_config = &rtl28xxu_rtl2832_fc0012_config;
		break;
	case TUNER_RTL2832_TUA9001:
		rtl2832_config = &rtl28xxu_rtl2832_tua9001_config;
		break;
	case TUNER_RTL2832_E4000:
		rtl2832_config = &rtl28xxu_rtl2832_e4000_config;
		break;
	case TUNER_RTL2832_R820T:
	case TUNER_RTL2832_R828D:
		rtl2832_config = &rtl28xxu_rtl2832_r820t_config;
		break;
	default:
		dev_err(&d->udev->dev, "%s: unknown tuner=%s\n",
				KBUILD_MODNAME, priv->tuner_name);
		ret = -ENODEV;
		goto err;
	}

	/* attach demodulator */
	platform_data.config = rtl2832_config;
	platform_data.dvb_frontend = &adap->fe[0];
	strlcpy(board_info.type, "rtl2832", I2C_NAME_SIZE);
	board_info.addr = 0x10;
	board_info.platform_data = &platform_data;
	request_module("%s", board_info.type);
	client = i2c_new_device(&d->i2c_adap, &board_info);
	if (client == NULL || client->dev.driver == NULL) {
		ret = -ENODEV;
		goto err;
	}

	if (!try_module_get(client->dev.driver->owner)) {
		i2c_unregister_device(client);
		ret = -ENODEV;
		goto err;
	}

	priv->i2c_client_demod = client;

	/* RTL2832 I2C repeater */
	priv->demod_i2c_adapter = rtl2832_get_i2c_adapter(adap->fe[0]);

	/* set fe callback */
	adap->fe[0]->callback = rtl2832u_frontend_callback;

	if (priv->slave_demod) {
		struct i2c_board_info info = {};

		/*
		 * We continue on reduced mode, without DVB-T2/C, using master
		 * demod, when slave demod fails.
		 */
		ret = 0;

		/* attach slave demodulator */
		if (priv->slave_demod == SLAVE_DEMOD_MN88472) {
			struct mn88472_config mn88472_config = {};

			mn88472_config.fe = &adap->fe[1];
			mn88472_config.i2c_wr_max = 22,
			strlcpy(info.type, "mn88472", I2C_NAME_SIZE);
			mn88472_config.xtal = 20500000;
			info.addr = 0x18;
			info.platform_data = &mn88472_config;
			request_module(info.type);
			client = i2c_new_device(priv->demod_i2c_adapter, &info);
			if (client == NULL || client->dev.driver == NULL) {
				priv->slave_demod = SLAVE_DEMOD_NONE;
				goto err_slave_demod_failed;
			}

			if (!try_module_get(client->dev.driver->owner)) {
				i2c_unregister_device(client);
				priv->slave_demod = SLAVE_DEMOD_NONE;
				goto err_slave_demod_failed;
			}

			priv->i2c_client_slave_demod = client;
		} else {
			struct mn88473_config mn88473_config = {};

			mn88473_config.fe = &adap->fe[1];
			mn88473_config.i2c_wr_max = 22,
			strlcpy(info.type, "mn88473", I2C_NAME_SIZE);
			info.addr = 0x18;
			info.platform_data = &mn88473_config;
			request_module(info.type);
			client = i2c_new_device(priv->demod_i2c_adapter, &info);
			if (client == NULL || client->dev.driver == NULL) {
				priv->slave_demod = SLAVE_DEMOD_NONE;
				goto err_slave_demod_failed;
			}

			if (!try_module_get(client->dev.driver->owner)) {
				i2c_unregister_device(client);
				priv->slave_demod = SLAVE_DEMOD_NONE;
				goto err_slave_demod_failed;
			}

			priv->i2c_client_slave_demod = client;
		}
	}

	return 0;
err_slave_demod_failed:
err:
	dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
	return ret;
}
コード例 #29
0
ファイル: cls_api.c プロジェクト: gnensis/linux-2.6.15
static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
{
	struct rtattr **tca;
	struct tcmsg *t;
	u32 protocol;
	u32 prio;
	u32 nprio;
	u32 parent;
	struct net_device *dev;
	struct Qdisc  *q;
	struct tcf_proto **back, **chain;
	struct tcf_proto *tp;
	struct tcf_proto_ops *tp_ops;
	struct Qdisc_class_ops *cops;
	unsigned long cl;
	unsigned long fh;
	int err;

replay:
	tca = arg;
	t = NLMSG_DATA(n);
	protocol = TC_H_MIN(t->tcm_info);
	prio = TC_H_MAJ(t->tcm_info);
	nprio = prio;
	parent = t->tcm_parent;
	cl = 0;

	if (prio == 0) {
		/* If no priority is given, user wants we allocated it. */
		if (n->nlmsg_type != RTM_NEWTFILTER || !(n->nlmsg_flags&NLM_F_CREATE))
			return -ENOENT;
		prio = TC_H_MAKE(0x80000000U,0U);
	}

	/* Find head of filter chain. */

	/* Find link */
	if ((dev = __dev_get_by_index(t->tcm_ifindex)) == NULL)
		return -ENODEV;

	/* Find qdisc */
	if (!parent) {
		q = dev->qdisc_sleeping;
		parent = q->handle;
	} else if ((q = qdisc_lookup(dev, TC_H_MAJ(t->tcm_parent))) == NULL)
		return -EINVAL;

	/* Is it classful? */
	if ((cops = q->ops->cl_ops) == NULL)
		return -EINVAL;

	/* Do we search for filter, attached to class? */
	if (TC_H_MIN(parent)) {
		cl = cops->get(q, parent);
		if (cl == 0)
			return -ENOENT;
	}

	/* And the last stroke */
	chain = cops->tcf_chain(q, cl);
	err = -EINVAL;
	if (chain == NULL)
		goto errout;

	/* Check the chain for existence of proto-tcf with this priority */
	for (back = chain; (tp=*back) != NULL; back = &tp->next) {
		if (tp->prio >= prio) {
			if (tp->prio == prio) {
				if (!nprio || (tp->protocol != protocol && protocol))
					goto errout;
			} else
				tp = NULL;
			break;
		}
	}

	if (tp == NULL) {
		/* Proto-tcf does not exist, create new one */

		if (tca[TCA_KIND-1] == NULL || !protocol)
			goto errout;

		err = -ENOENT;
		if (n->nlmsg_type != RTM_NEWTFILTER || !(n->nlmsg_flags&NLM_F_CREATE))
			goto errout;


		/* Create new proto tcf */

		err = -ENOBUFS;
		if ((tp = kmalloc(sizeof(*tp), GFP_KERNEL)) == NULL)
			goto errout;
		err = -EINVAL;
		tp_ops = tcf_proto_lookup_ops(tca[TCA_KIND-1]);
		if (tp_ops == NULL) {
#ifdef CONFIG_KMOD
			struct rtattr *kind = tca[TCA_KIND-1];
			char name[IFNAMSIZ];

			if (kind != NULL &&
			    rtattr_strlcpy(name, kind, IFNAMSIZ) < IFNAMSIZ) {
				rtnl_unlock();
				request_module("cls_%s", name);
				rtnl_lock();
				tp_ops = tcf_proto_lookup_ops(kind);
				/* We dropped the RTNL semaphore in order to
				 * perform the module load.  So, even if we
				 * succeeded in loading the module we have to
				 * replay the request.  We indicate this using
				 * -EAGAIN.
				 */
				if (tp_ops != NULL) {
					module_put(tp_ops->owner);
					err = -EAGAIN;
				}
			}
#endif
			kfree(tp);
			goto errout;
		}
		memset(tp, 0, sizeof(*tp));
		tp->ops = tp_ops;
		tp->protocol = protocol;
		tp->prio = nprio ? : tcf_auto_prio(*back);
		tp->q = q;
		tp->classify = tp_ops->classify;
		tp->classid = parent;
		if ((err = tp_ops->init(tp)) != 0) {
			module_put(tp_ops->owner);
			kfree(tp);
			goto errout;
		}

		qdisc_lock_tree(dev);
		tp->next = *back;
		*back = tp;
		qdisc_unlock_tree(dev);

	} else if (tca[TCA_KIND-1] && rtattr_strcmp(tca[TCA_KIND-1], tp->ops->kind))
コード例 #30
0
void of_register_spi_devices(struct spi_master *master, struct device_node *np)
{
	struct spi_device *spi;
	struct device_node *nc;
	const __be32 *prop;
	int rc;
	int len;

	for_each_child_of_node(np, nc) {
		/* Alloc an spi_device */
		spi = spi_alloc_device(master);
		if (!spi) {
			dev_err(&master->dev, "spi_device alloc error for %s\n",
				nc->full_name);
			spi_dev_put(spi);
			continue;
		}

		/* Select device driver */
		if (of_modalias_node(nc, spi->modalias,
				     sizeof(spi->modalias)) < 0) {
			dev_err(&master->dev, "cannot find modalias for %s\n",
				nc->full_name);
			spi_dev_put(spi);
			continue;
		}

		/* Device address */
		prop = of_get_property(nc, "reg", &len);
		if (!prop || len < sizeof(*prop)) {
			dev_err(&master->dev, "%s has no 'reg' property\n",
				nc->full_name);
			spi_dev_put(spi);
			continue;
		}
		spi->chip_select = be32_to_cpup(prop);

		/* Mode (clock phase/polarity/etc.) */
		if (of_find_property(nc, "spi-cpha", NULL))
			spi->mode |= SPI_CPHA;
		if (of_find_property(nc, "spi-cpol", NULL))
			spi->mode |= SPI_CPOL;
		if (of_find_property(nc, "spi-cs-high", NULL))
			spi->mode |= SPI_CS_HIGH;

		/* Device speed */
		prop = of_get_property(nc, "spi-max-frequency", &len);
		if (!prop || len < sizeof(*prop)) {
			dev_err(&master->dev, "%s has no 'spi-max-frequency' property\n",
				nc->full_name);
			spi_dev_put(spi);
			continue;
		}
		spi->max_speed_hz = be32_to_cpup(prop);

		/* IRQ */
		spi->irq = irq_of_parse_and_map(nc, 0);

		/* Store a pointer to the node in the device structure */
		of_node_get(nc);
		spi->dev.of_node = nc;

		/* Register the new device */
		request_module(spi->modalias);
		rc = spi_add_device(spi);
		if (rc) {
			dev_err(&master->dev, "spi_device register error %s\n",
				nc->full_name);
			spi_dev_put(spi);
		}

	}