lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Date:	Mon, 11 Jan 2016 14:06:10 +0800
From:	Peter Hung <hpeter@...il.com>
To:	Johan Hovold <johan@...nel.org>
Cc:	gregkh@...uxfoundation.org, linux-usb@...r.kernel.org,
	linux-kernel@...r.kernel.org, tom_tsai@...tek.com.tw,
	peter_hong@...tek.com.tw,
	Peter Hung <hpeter+linux_kernel@...il.com>
Subject: Re: [PATCH V7 1/1] usb:serial: Add Fintek F81532/534 driver

Hi Johan,

Johan Hovold 於 2016/1/4 上午 02:58 寫道:
> On Wed, Dec 02, 2015 at 03:18:59PM +0800, Peter Hung wrote:
>> This driver is for Fintek F81532/F81534 USB to Serial Ports IC.
>
> Do you have a pointer to datasheets and/or information about these
> devices? Can't seem to find anything on Fintek's homepage.

F81532
https://drive.google.com/file/d/0B8vRwwYO7aMFOTRRMmhWQVNvajQ/view?usp=sharing

F81534
https://drive.google.com/file/d/0B8vRwwYO7aMFV29pQWJqbVBNc00/view?usp=sharing

> I noticed that you have not considered all my comments on earlier
> revisions of this driver. Please make sure to address all issues raised.

I'll recheck it again.


> We may need to come up with a generic interface for switching tranceiver
> modes as there are more drivers that could benefit from this. I think we
> should prevent mode switching for a port that is open as does not seem
> to make much sense.
>
> How about you drop mode-switching support completely for now (e.g.
> gpiolib and rs485-ioctl) and focus on getting the basic functionality
> right first?

> You could also consider extending you user-space tool and use that to
> switch modes (e.g. reprogram the device eeprom) through libudev, at
> least until a generic interface is in place.

Ok, we'll remove gpiolib & rs485-ioctl with next version and only remain
the initialization of gpio/mode control on attach() once.

Also we'll provide tools via libusb to modify the configuration data on
bitbucket.

> As for the basic design, you should use per-interface read and write
> urbs. Submit the read urb(s) when the first port is opened, and kill
> them when the last device is closed. Similarly for the write urbs,
> submit one when there's at least one port with data in its fifo that it
> non-busy (TX_EMPTY is set).

The method you mentioned is more make sense, but it'll changes the
driver tx flow and makes it more difficultly to maintain.

Could I preserve current flow? The current is 1 read-urb submits on
attach() & resume() and per-port write-urb submits on write() or
read-urb callback TX_EMPTY. The style is the same with "mxuport.c".


>> +#define F81534_CUSTOM_ADDRESS_START	0x2f00
>> +#define F81534_CUSTOM_TOTAL_SIZE	0x10
>> +#define F81534_CUSTOM_DATA_SIZE		0x10
>> +#define F81534_CUSTOM_MAX_IDX		\
>> +			(F81534_CUSTOM_TOTAL_SIZE/F81534_CUSTOM_DATA_SIZE)
>
> Do you really expect F81534_CUSTOM_MAX_IDX to be 1?

Yes, we'll remove the TOTAL_SIZE and set MAX_IDX = 1 with next version.

>> +#ifndef C_CMSPAR
>> +#define C_CMSPAR(tty)   _C_FLAG((tty), CMSPAR)
>> +#endif
>
> Drop this.

OK


>> +/*
>> + * The following magic numbers is F81532/534 output pin
>> + * register maps
>> + */
>> +static const struct io_map_value f81534_rs232_control = {
>> +	FINTEK_DEVICE_ID, F81534_NUM_PORT, uart_mode_rs232,
>> +	{
>> +	 /* please reference f81439 io port */
>
> I can't seem to find anything about a f81439 io port. Do you have a
> link?
>
> I believe I already asked you to describe the following function in a
> comment here.

On next version we'll add more documents with this section and
change it to "f81534_pin_control". It controls F81532/534 output pin.
The pin default value can be changed with user-space tools.


>> +static int f81534_read_data(struct usb_serial *usbserial, u32 address,
>> +				u32 size, unsigned char *buf)
>> +{
>> +	u32 read_size, count;
>> +	u32 block = 0;
>
> Please use size_t for the size, count and block variables (throughout).

OK.

>> +	/* someone is changing setting, pause TX */
>> +	updating_data = mutex_is_locked(&serial_priv->change_mode_mutex);
>> +	if (updating_data)
>> +		return 0;
>
> This cannot be done in a race-free way. You should just prevent mode
> changes while the port is open.

OK, we'll remove it next version.


>> +	bool reConfigure = false;
>
> Again, please remove all CamelCase.

OK.


>> +	if (status) {
>> +		dev_err(&port->dev,
>> +				"%s: f81534_write_data failed!! status:%d\n",
>
> Please remove all exclamation marks (!) from all error messages.
>
> Please also try to spell out what went wrong instead of relying on the
> function name, for example in this case:
>
> "failed to save configuration data: %d\n"
>
> Also add a space between the final colon (:) and the error code.

OK.


>> +	memcpy(&port_priv->f81534_gpio_chip, &f81534_gpio_chip_templete,
>> +			sizeof(f81534_gpio_chip_templete));
>> +
>> +	snprintf(name, max_name - 1, "%s-%d", IC_NAME, idx);
>
> The size includes the trailing NUL so use max_name only here.

OK, but this section will be removed next version.


>> +static int f81534_find_config_idx(struct usb_serial *serial, uintptr_t *index)
>> +{
>> +	int idx, status;
>> +	u8 custom_data;
>> +	int offset;
>> +
>> +	for (idx = F81534_CUSTOM_MAX_IDX - 1; idx >= 0; --idx) {
>
> Why go through all this trouble when F81534_CUSTOM_MAX_IDX is a constant
> defined as 1?

The define is for the historical, we original designed for a section to
store the data (about 0x100 / 0x10 = 0x10 set of data), but It makes
more difficulty for H/W design. So we reduce from 0x100 to 0x10,
only 1 set of data remained with MP IC.

I'll reduce the code for next version.


>> +	/* Save the configuration area idx as private data for attach() */
>> +	usb_set_serial_data(serial, (void *) setting_idx);
>
> No space after casts.

OK.


>> +		dev_info(&serial->dev->dev,
>> +				"%s: read configure from block:%d\n", __func__,
>> +				(int) setting_idx);
>> +	} else {
>> +		dev_info(&serial->dev->dev, "%s: read configure default\n",
>> +				__func__);
>> +	}
>
> Demote these info messages to debug level.

OK.


>> +
>> +	for (i = 0; i < F81534_NUM_PORT; ++i) {
>> +		/*
>> +		 * For older configuration use. We'll transform it to newer
>> +		 * setting after load it with final port probed.
>> +		 */
>> +		switch (setting[i]) {
>> +		case F81534_OLD_CONFIG_37:
>> +		case F81534_OLD_CONFIG_38:
>> +		case F81534_OLD_CONFIG_39:
>> +			++num_port;
>> +			break;
>> +		}
>> +	}
>
> Please explain what this old and new configuration style is and why you
> need it.
>
> Please also document the format of your configuration data.

We had 3 generation of F81532/534. All gen has an internal storage.

1st is pure USB-to-TTL RS232 IC and designed for 4 ports only, no any
internal data will used. All mode and gpio control should manually set
by AP or Driver and all storage space value are 0xff. The
f81534_calc_num_ports() will run to final we marked as "oldest version"
for this IC.

2nd is designed to match our transceivers(F81437/438/439). We'll save 
data in F81534_DEF_CONF_ADDRESS_START(0x3000) with 8bytes. The first
4bytes is transceiver type, value is only 0x37/0x38/0x39 to
represent F81437/438/439, and the following 4bytes are save mode & gpio
state, the last 4bytes will be limited by the first 4bytes transceiver
type. The f81534_calc_num_ports() will run to "older configuration"
with checking F81534_OLD_CONFIG_37/F81534_OLD_CONFIG_38
/F81534_OLD_CONFIG_39 section.

3rd is designed to more generic to use any transceiver and this is our
mass production type. We'll save data in F81534_CUSTOM_ADDRESS_START
(0x2f00) with 9bytes. The 1st byte is a indicater. If the token is not
F81534_CUSTOM_VALID_TOKEN(0xf0), the IC is 2nd gen type, the following
4bytes save port mode (0:RS232/1:RS485 Invert/2:RS485), and the last
4bytes save GPIO state(value from 0~7 to represent 3 GPIO output pin).
The f81534_calc_num_ports() will run to "new style" with checking
F81534_PORT_UNAVAILABLE section.

I'll add this document in code with next version.


>> +	if (num_port)
>> +		return num_port;
>> +
>> +	dev_err(&serial->dev->dev, "Read Failed!!, default 4 ports\n");
>
> If this is really an error you should bail out and return 0, otherwise
> use dev_dbg or possible _warn here.

OK, we'll change it as dev_warn().


>> +static void f81534_release(struct usb_serial *serial)
>> +{
>> +	struct f81534_serial_private *serial_priv =
>> +			usb_get_serial_data(serial);
>> +
>> +	kfree(serial_priv);
>> +}
>
> Please try to keep related function together. Place the release callback
> after f81534_attach().

OK.


>> +static int f81534_set_port_mode(struct usb_serial_port *port,
>> +		enum uart_mode eMode)
>
> CamelCase

OK.


>> +static int f81534_setup_urbs(struct usb_serial *serial)
>
> Rename f81534_setup_ports.

OK.

>> +static int f81534_write(struct tty_struct *tty,
>> +			struct usb_serial_port *port,
>> +			const unsigned char *buf, int count)
>> +{
>> +	int bytes_out, status;
>> +
>> +	if (!count)
>> +		return 0;
>> +
>> +	bytes_out = kfifo_in_locked(&port->write_fifo, buf, count,
>> +					&port->lock);
>> +
>> +	status = f81534_submit_writer(port, GFP_KERNEL);
>
> You must use GFP_ATOMIC here.

OK.

> Please use a concise description here (e.g. "Fintek F81532/F81534")
> here.
>

OK.

Thanks for your advices.
-- 
With Best Regards,
Peter Hung

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ