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.
I noticed that you have not considered all my comments on earlier
revisions of this driver. Please make sure to address all issues raised.
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.
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).
+#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?
+#ifndef C_CMSPAR
+#define C_CMSPAR(tty) _C_FLAG((tty), CMSPAR)
+#endif
Drop this.
+/*
+ * 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.
+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).
+ /* 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.
+ bool reConfigure = false;
Again, please remove all CamelCase.
+ 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.
+ 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.
+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?
+ /* Save the configuration area idx as private data for attach() */
+ usb_set_serial_data(serial, (void *) setting_idx);
No space after casts.
+ 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.
+
+ 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.
+ 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.
+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().
+static int f81534_set_port_mode(struct usb_serial_port *port,
+ enum uart_mode eMode)
CamelCase
+static int f81534_setup_urbs(struct usb_serial *serial)
Rename f81534_setup_ports.
+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.
Please use a concise description here (e.g. "Fintek F81532/F81534")
here.