Re: [V2 PATCH 05/10] added media specific (MS) TCP drivers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Nov 10, 2014 at 06:09:36PM -0800, Stephanie Wallick wrote:
> +static int ma_open;

Why do you need this variable?

> +/**
> + * This function is used to open the device file in order to read/write
> + * from/to it.
> + *
> + * @inode:	Struct with various information that is passed in when this
> + *		function is called. We don't need to use it for our purposes.
> + * @file:	The file to be opened.
> + */
> +static int mausb_open(struct inode *inode, struct file *file)
> +{
> +	if (ma_open)
> +		return -EBUSY;
> +	ma_open++;

Racy :(

> +	try_module_get(THIS_MODULE);

Even more racy, _NEVER_ make this type of call, it's _ALWAYS_ wrong.

And totally not even needed at all, if you set up your file structure
properly.

> +
> +	return 0;
> +}
> +
> +/**
> + * This function is used to close the device file.
> + *
> + * @inode:	Struct with various information that is passed in when this
> + *		function is called. We don't need to use it for our purposes.
> + * @file:	The file to be closed.
> + */
> +static int mausb_release(struct inode *inode, struct file *file)
> +{
> +	ma_open--;

Again, racy, and pointless, why are you doing this?

> +	module_put(THIS_MODULE);

And again, broken and racy :(

> +	return 0;
> +}
> +
> +
> +/**
> + * This function is used to execute ioctl commands, determined by ioctl_func.
> + *
> + * @file:	  The device file. We don't use it directly, but it's passed in.
> + * @ioctl_func:	  This value determines which ioctl function will be used.
> + * @ioctl_buffer: This buffer is used to transfer data to/from the device.
> + */
> +long mausb_ioctl(struct file *file, unsigned int ioctl_func,
> +		unsigned long ioctl_buffer)
> +{
> +	char message[BUFFER];
> +	int ret, value;
> +	unsigned long int long_value;
> +	char __user *msg = (char *)ioctl_buffer;
> +	char *response;
> +
> +	switch (ioctl_func) {
> +	case IOCTL_GET_VRSN:
> +		ret = copy_to_user(msg, DRIVER_VERSION, strlen(DRIVER_VERSION));
> +		break;

This should be a sysfs file.  Why even care about the version?


> +	case IOCTL_GET_NAME:
> +		ret = copy_to_user(msg, MAUSB_NAME, strlen(MAUSB_NAME));
> +		break;

Why?

> +	case IOCTL_GADGET_C:
> +		ret = gadget_connection(1);
> +		if (ret >= 0)
> +			response = MAUSB_GADGET_C_SUCCESS;
> +		else
> +			response = MAUSB_GADGET_C_FAIL;
> +
> +		ret = copy_to_user(msg, response, strlen(response));
> +		break;

Can't this be a sysfs file?

> +	case IOCTL_GADGET_D:
> +		ret = gadget_connection(0);
> +		if (ret >= 0)
> +			response = MAUSB_GADGET_D_SUCCESS;
> +		else
> +			response = MAUSB_GADGET_D_FAIL;
> +
> +		ret = copy_to_user(msg, response, strlen(response));
> +		break;

Same here.


> +	case IOCTL_SET_PORT:
> +		ret = strncpy_from_user(message, msg, BUFFER);
> +		if (ret < 0)
> +			break;
> +		ret = kstrtoint(msg, 0, &value);
> +		if (ret != 0)
> +			break;
> +
> +		ret = set_port_no(value);
> +		sprintf(message, "PORT NUMBER:%d, Returned %i\n", value,
> +			ret);

That looks like a debug message.

> +		ret = copy_to_user(msg, message, strlen(message));
> +		break;

That really looks like a sysfs file.


> +	case IOCTL_SET_IP:
> +		ret = strncpy_from_user(message, msg, BUFFER);
> +		if (ret < 0)
> +			break;
> +		ret = kstrtoul(message, 0, &long_value);
> +		if (ret != 0)
> +			break;
> +
> +		ret = set_ip_addr(long_value);
> +		sprintf(message, "IP ADDRESS:%lx, returned %i\n",
> +			long_value, ret);

That looks like a debug message :(

> +		ret = copy_to_user(msg, message, strlen(message));
> +		break;

again sysfs file?


> +	case IOCTL_SET_MAC:
> +		{
> +			u8 mac[6];
> +			int i;
> +			ret = copy_from_user(mac, msg, 6);
> +			if (ret) {
> +				pr_err("copy_from_user failed\n");
> +				break;
> +			}
> +			for (i = 0; i < ETH_ALEN; i++)
> +				pr_info("mac[%d]=0x%x\n", i, mac[i]);
> +			ret = set_mac_addr(mac);
> +			if (ret)
> +				pr_err("unable to set MAC addr\n");
> +
> +			break;
> +		}

And again, sysfs file.

What about any other ioctl?  You forgot to return an invalid number.

> +	}
> +
> +	/* failure */
> +	if (ret < 0)
> +		return ret;

You could have just returned a stack value here :(


> +
> +	/* success */
> +	return 0;

No need for the comments, this is a pretty common kernel idiom,
especially when all 6 lines get reduced to a single 'return ret;' line :)


> +}
> +
> +/**
> + * This struct creates links with our implementations of various entry point
> + * functions.
> + */
> +const struct file_operations fops = {
> +	.open = mausb_open,
> +	.release = mausb_release,
> +	.unlocked_ioctl = mausb_ioctl
> +};

Any reason you didn't set the file_operations module owner here?  (hint,
do that and you will never need the crazy try_module_get() crazy
above...)

> +
> +/**
> + * Registers a character device using our device file. This function is called
> + * in the mausb_hcd_init function.
> + */
> +int reg_chrdev()

()???


> +{
> +	int ret;
> +
> +#ifdef MAUSB_PRINT_IOCTL_MAGIC

please no.


> +
> +	printk(KERN_DEBUG "Printing IOCTL magic numbers:\n");
> +	printk(KERN_DEBUG "IOCTL_SET_MSG        = %u\n", IOCTL_SET_MSG);
> +	printk(KERN_DEBUG "IOCTL_GET_MSG        = %u\n", IOCTL_GET_MSG);
> +	printk(KERN_DEBUG "IOCTL_GET_VRSN       = %u\n", IOCTL_GET_VRSN);
> +	printk(KERN_DEBUG "IOCTL_GET_NAME       = %u\n", IOCTL_GET_NAME);
> +	printk(KERN_DEBUG "IOCTL_GADGET_C       = %u\n", IOCTL_GADGET_C);
> +	printk(KERN_DEBUG "IOCTL_GADGET_D       = %u\n", IOCTL_GADGET_D);
> +	printk(KERN_DEBUG "IOCTL_MED_DELAY      = %u\n", IOCTL_MED_DELAY);
> +	printk(KERN_DEBUG "IOCTL_SET_IP         = %u\n", IOCTL_SET_IP);
> +	printk(KERN_DEBUG "IOCTL_SET_PORT       = %u\n", IOCTL_SET_PORT);
> +	printk(KERN_DEBUG "IOCTL_SET_IP_DECIMAL = %u\n", IOCTL_SET_IP_DECIMAL);
> +	printk(KERN_DEBUG "IOCTL_SET_MAC        = %u\n", IOCTL_SET_MAC);
> +
> +#endif
> +
> +	ret = register_chrdev(MAJOR_NUM, MAUSB_NAME, &fops);
> +
> +	if (ret < 0)
> +		printk(KERN_ALERT "Registering mausb failed with %d\n", ret);
> +	else
> +		printk(KERN_INFO "%s registeration complete. Major device"
> +			" number %d.\n", MAUSB_NAME, MAJOR_NUM);
> +
> +	return ret;
> +}
> +
> +/**
> + * Unregisters the character device when the hcd is unregistered. As hinted,
> + * this function is called in the mausb_hcd_exit function.
> + */
> +void unreg_chrdev()

That's a _very_ bold global function name you just chose for this, and
the previous function :(


> +{
> +	unregister_chrdev(MAJOR_NUM, MAUSB_NAME);
> +}
> diff --git a/drivers/staging/mausb/drivers/mausb_ioctl.h b/drivers/staging/mausb/drivers/mausb_ioctl.h
> new file mode 100644
> index 0000000..4126ade
> --- /dev/null
> +++ b/drivers/staging/mausb/drivers/mausb_ioctl.h
> @@ -0,0 +1,101 @@
> +/* Name:         mausb_ioctl.h
> + * Description:  header file for MA USB ioctl functions
> + *
> + * This file is provided under a dual BSD/GPLv2 license.  When using or
> + * redistributing this file, you may do so under either license.
> + *
> + * GPL LICENSE SUMMARY
> + *
> + * Copyright(c) 2014 Intel Corporation.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of version 2 of the GNU General Public License as published
> + * by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful, but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * General Public License for more details.
> + *
> + * Contact Information:
> + * Sean Stalley, sean.stalley@xxxxxxxxx
> + * Stephanie Wallick, stephanie.s.wallick@xxxxxxxxx
> + * 2111 NE 25th Avenue
> + * Hillsboro, Oregon 97124
> + *
> + * BSD LICENSE
> + *
> + * Copyright(c) 2014 Intel Corporation.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + *
> +    * Redistributions of source code must retain the above copyright
> +      notice, this list of conditions and the following disclaimer.
> +    * Redistributions in binary form must reproduce the above copyright
> +      notice, this list of conditions and the following disclaimer in
> +      the documentation and/or other materials provided with the
> +      distribution.
> +    * Neither the name of Intel Corporation nor the names of its
> +      contributors may be used to endorse or promote products derived
> +      from this software without specific prior written permission.
> +
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#ifndef MAUSB_IOCTL_H
> +#define MAUSB_IOCTL_H
> +
> +#define BUFFER 80

Why 80?  Why not 8000?  Why any number at all?

> +#define DRIVER_VERSION "Alpha 0.0.25"

Why is this even needed?

> +#define MAJOR_NUM 100

You can't just steal another driver's major number, that's not allowed
at all, and again, something I can never even accept into the staging
tree.

Why need a reserved major at all?

> +/* These define the ioctl functions that can be used. */
> +#define IOCTL_GET_VRSN _IOR(MAJOR_NUM, 0, char *)
> +#define IOCTL_GET_NAME _IOR(MAJOR_NUM, 1, char *)
> +#define IOCTL_GADGET_C _IOR(MAJOR_NUM, 2, char *)
> +#define IOCTL_GADGET_D _IOR(MAJOR_NUM, 3, char *)
> +#define IOCTL_SET_IP   _IOR(MAJOR_NUM, 4, char *)
> +#define IOCTL_SET_PORT _IOR(MAJOR_NUM, 5, char *)
> +#define IOCTL_SET_MAC  _IOR(MAJOR_NUM, 6, char *)

These are not all _IOR() ioctls, look at the code implementing them!

> +/* This is the location where the device file will be created. It is used to
> + * read/write to in order to communicate to and from the device. */
> +#define DEVICE_FILE_NAME "/dev/mausb"

Never used, don't put that in a kernel file.


> +
> +/* MAC address length */
> +#define ETH_ALEN 6
> +
> +/* Responses to IOCTL calls */
> +#define MAUSB_GADGET_C_SUCCESS	"gadget connect process complete"
> +#define MAUSB_GADGET_C_FAIL	"gadget connect process failed"
> +#define MAUSB_GADGET_D_SUCCESS	"gadget disconnect process complete"
> +#define MAUSB_GADGET_D_FAIL	"gadget disconnect process failed"

ioctls returning text strings?  Next thing you will want i18n versions
of them...

> +int mausb_transfer_packet(struct ms_pkt *pkt,
> +	struct mausb_pkt_transfer *transfer)
> +{
> +	return transfer->transfer_packet(pkt, transfer->context);
> +}
> +EXPORT_SYMBOL(mausb_transfer_packet);

EXPORT_SYMBOL_GPL() for USB stuff please.

I'm not reviewing further, sorry.

thanks,

greg k-h
_______________________________________________
devel mailing list
devel@xxxxxxxxxxxxxxxxxxxxxx
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel




[Index of Archives]     [Linux Driver Backports]     [DMA Engine]     [Linux GPIO]     [Linux SPI]     [Video for Linux]     [Linux USB Devel]     [Linux Coverity]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux