aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorJim Radford <radford@blackbean.org>2007-02-28 13:10:50 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2007-03-09 22:52:24 -0500
commit12bdbe03c8db7139de1de5c622cb0609d259cece (patch)
tree8d3938e4ddee18c9a23eac12750ad50ec7f46118 /drivers/usb
parentd9a7ecacac5f8274d2afce09aadcf37bdb42b93a (diff)
USB: ftdi_sio: use port_probe / port_remove thereby fixing access to the latency_timer
Convert all the port specific code in attach / shutdown to use the new port_probe / port_register callbacks from device_register / device_unregister allowing adding the sysfs attributes to be added at the correct time and to the serial port device itself, instead of to the unadorned usb device, avoiding a NULL dereference. Signed-off-by: Jim Radford <radford@blackbean.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/serial/ftdi_sio.c79
1 files changed, 35 insertions, 44 deletions
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 07884e0803b9..ada4e6c6f9cc 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -597,6 +597,8 @@ struct ftdi_private {
597static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id *id); 597static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id *id);
598static int ftdi_sio_attach (struct usb_serial *serial); 598static int ftdi_sio_attach (struct usb_serial *serial);
599static void ftdi_shutdown (struct usb_serial *serial); 599static void ftdi_shutdown (struct usb_serial *serial);
600static int ftdi_sio_port_probe (struct usb_serial_port *port);
601static int ftdi_sio_port_remove (struct usb_serial_port *port);
600static int ftdi_open (struct usb_serial_port *port, struct file *filp); 602static int ftdi_open (struct usb_serial_port *port, struct file *filp);
601static void ftdi_close (struct usb_serial_port *port, struct file *filp); 603static void ftdi_close (struct usb_serial_port *port, struct file *filp);
602static int ftdi_write (struct usb_serial_port *port, const unsigned char *buf, int count); 604static int ftdi_write (struct usb_serial_port *port, const unsigned char *buf, int count);
@@ -631,6 +633,8 @@ static struct usb_serial_driver ftdi_sio_device = {
631 .num_bulk_out = 1, 633 .num_bulk_out = 1,
632 .num_ports = 1, 634 .num_ports = 1,
633 .probe = ftdi_sio_probe, 635 .probe = ftdi_sio_probe,
636 .port_probe = ftdi_sio_port_probe,
637 .port_remove = ftdi_sio_port_remove,
634 .open = ftdi_open, 638 .open = ftdi_open,
635 .close = ftdi_close, 639 .close = ftdi_close,
636 .throttle = ftdi_throttle, 640 .throttle = ftdi_throttle,
@@ -1033,11 +1037,10 @@ static ssize_t show_latency_timer(struct device *dev, struct device_attribute *a
1033{ 1037{
1034 struct usb_serial_port *port = to_usb_serial_port(dev); 1038 struct usb_serial_port *port = to_usb_serial_port(dev);
1035 struct ftdi_private *priv = usb_get_serial_port_data(port); 1039 struct ftdi_private *priv = usb_get_serial_port_data(port);
1036 struct usb_device *udev; 1040 struct usb_device *udev = port->serial->dev;
1037 unsigned short latency = 0; 1041 unsigned short latency = 0;
1038 int rv = 0; 1042 int rv = 0;
1039 1043
1040 udev = to_usb_device(dev);
1041 1044
1042 dbg("%s",__FUNCTION__); 1045 dbg("%s",__FUNCTION__);
1043 1046
@@ -1061,13 +1064,11 @@ static ssize_t store_latency_timer(struct device *dev, struct device_attribute *
1061{ 1064{
1062 struct usb_serial_port *port = to_usb_serial_port(dev); 1065 struct usb_serial_port *port = to_usb_serial_port(dev);
1063 struct ftdi_private *priv = usb_get_serial_port_data(port); 1066 struct ftdi_private *priv = usb_get_serial_port_data(port);
1064 struct usb_device *udev; 1067 struct usb_device *udev = port->serial->dev;
1065 char buf[1]; 1068 char buf[1];
1066 int v = simple_strtoul(valbuf, NULL, 10); 1069 int v = simple_strtoul(valbuf, NULL, 10);
1067 int rv = 0; 1070 int rv = 0;
1068 1071
1069 udev = to_usb_device(dev);
1070
1071 dbg("%s: setting latency timer = %i", __FUNCTION__, v); 1072 dbg("%s: setting latency timer = %i", __FUNCTION__, v);
1072 1073
1073 rv = usb_control_msg(udev, 1074 rv = usb_control_msg(udev,
@@ -1092,13 +1093,11 @@ static ssize_t store_event_char(struct device *dev, struct device_attribute *att
1092{ 1093{
1093 struct usb_serial_port *port = to_usb_serial_port(dev); 1094 struct usb_serial_port *port = to_usb_serial_port(dev);
1094 struct ftdi_private *priv = usb_get_serial_port_data(port); 1095 struct ftdi_private *priv = usb_get_serial_port_data(port);
1095 struct usb_device *udev; 1096 struct usb_device *udev = port->serial->dev;
1096 char buf[1]; 1097 char buf[1];
1097 int v = simple_strtoul(valbuf, NULL, 10); 1098 int v = simple_strtoul(valbuf, NULL, 10);
1098 int rv = 0; 1099 int rv = 0;
1099 1100
1100 udev = to_usb_device(dev);
1101
1102 dbg("%s: setting event char = %i", __FUNCTION__, v); 1101 dbg("%s: setting event char = %i", __FUNCTION__, v);
1103 1102
1104 rv = usb_control_msg(udev, 1103 rv = usb_control_msg(udev,
@@ -1119,46 +1118,38 @@ static ssize_t store_event_char(struct device *dev, struct device_attribute *att
1119static DEVICE_ATTR(latency_timer, S_IWUSR | S_IRUGO, show_latency_timer, store_latency_timer); 1118static DEVICE_ATTR(latency_timer, S_IWUSR | S_IRUGO, show_latency_timer, store_latency_timer);
1120static DEVICE_ATTR(event_char, S_IWUSR, NULL, store_event_char); 1119static DEVICE_ATTR(event_char, S_IWUSR, NULL, store_event_char);
1121 1120
1122static int create_sysfs_attrs(struct usb_serial *serial) 1121static int create_sysfs_attrs(struct usb_serial_port *port)
1123{ 1122{
1124 struct ftdi_private *priv; 1123 struct ftdi_private *priv = usb_get_serial_port_data(port);
1125 struct usb_device *udev;
1126 int retval = 0; 1124 int retval = 0;
1127 1125
1128 dbg("%s",__FUNCTION__); 1126 dbg("%s",__FUNCTION__);
1129 1127
1130 priv = usb_get_serial_port_data(serial->port[0]);
1131 udev = serial->dev;
1132
1133 /* XXX I've no idea if the original SIO supports the event_char 1128 /* XXX I've no idea if the original SIO supports the event_char
1134 * sysfs parameter, so I'm playing it safe. */ 1129 * sysfs parameter, so I'm playing it safe. */
1135 if (priv->chip_type != SIO) { 1130 if (priv->chip_type != SIO) {
1136 dbg("sysfs attributes for %s", ftdi_chip_name[priv->chip_type]); 1131 dbg("sysfs attributes for %s", ftdi_chip_name[priv->chip_type]);
1137 retval = device_create_file(&udev->dev, &dev_attr_event_char); 1132 retval = device_create_file(&port->dev, &dev_attr_event_char);
1138 if ((!retval) && 1133 if ((!retval) &&
1139 (priv->chip_type == FT232BM || priv->chip_type == FT2232C)) { 1134 (priv->chip_type == FT232BM || priv->chip_type == FT2232C)) {
1140 retval = device_create_file(&udev->dev, 1135 retval = device_create_file(&port->dev,
1141 &dev_attr_latency_timer); 1136 &dev_attr_latency_timer);
1142 } 1137 }
1143 } 1138 }
1144 return retval; 1139 return retval;
1145} 1140}
1146 1141
1147static void remove_sysfs_attrs(struct usb_serial *serial) 1142static void remove_sysfs_attrs(struct usb_serial_port *port)
1148{ 1143{
1149 struct ftdi_private *priv; 1144 struct ftdi_private *priv = usb_get_serial_port_data(port);
1150 struct usb_device *udev;
1151 1145
1152 dbg("%s",__FUNCTION__); 1146 dbg("%s",__FUNCTION__);
1153 1147
1154 priv = usb_get_serial_port_data(serial->port[0]);
1155 udev = serial->dev;
1156
1157 /* XXX see create_sysfs_attrs */ 1148 /* XXX see create_sysfs_attrs */
1158 if (priv->chip_type != SIO) { 1149 if (priv->chip_type != SIO) {
1159 device_remove_file(&udev->dev, &dev_attr_event_char); 1150 device_remove_file(&port->dev, &dev_attr_event_char);
1160 if (priv->chip_type == FT232BM || priv->chip_type == FT2232C) { 1151 if (priv->chip_type == FT232BM || priv->chip_type == FT2232C) {
1161 device_remove_file(&udev->dev, &dev_attr_latency_timer); 1152 device_remove_file(&port->dev, &dev_attr_latency_timer);
1162 } 1153 }
1163 } 1154 }
1164 1155
@@ -1178,13 +1169,9 @@ static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id
1178 return (0); 1169 return (0);
1179} 1170}
1180 1171
1181/* attach subroutine */ 1172static int ftdi_sio_port_probe(struct usb_serial_port *port)
1182static int ftdi_sio_attach (struct usb_serial *serial)
1183{ 1173{
1184 struct usb_serial_port *port = serial->port[0];
1185 struct ftdi_private *priv; 1174 struct ftdi_private *priv;
1186 struct ftdi_sio_quirk *quirk;
1187 int retval;
1188 1175
1189 dbg("%s",__FUNCTION__); 1176 dbg("%s",__FUNCTION__);
1190 1177
@@ -1224,19 +1211,21 @@ static int ftdi_sio_attach (struct usb_serial *serial)
1224 kfree(port->bulk_out_buffer); 1211 kfree(port->bulk_out_buffer);
1225 port->bulk_out_buffer = NULL; 1212 port->bulk_out_buffer = NULL;
1226 1213
1227 usb_set_serial_port_data(serial->port[0], priv); 1214 usb_set_serial_port_data(port, priv);
1228 1215
1229 ftdi_determine_type (serial->port[0]); 1216 ftdi_determine_type (port);
1230 retval = create_sysfs_attrs(serial); 1217 create_sysfs_attrs(port);
1231 if (retval) 1218 return 0;
1232 dev_err(&serial->dev->dev, "Error creating sysfs files, " 1219}
1233 "continuing\n");
1234 1220
1221/* attach subroutine */
1222static int ftdi_sio_attach (struct usb_serial *serial)
1223{
1235 /* Check for device requiring special set up. */ 1224 /* Check for device requiring special set up. */
1236 quirk = (struct ftdi_sio_quirk *)usb_get_serial_data(serial); 1225 struct ftdi_sio_quirk *quirk = usb_get_serial_data(serial);
1237 if (quirk && quirk->setup) { 1226
1227 if (quirk && quirk->setup)
1238 quirk->setup(serial); 1228 quirk->setup(serial);
1239 }
1240 1229
1241 return 0; 1230 return 0;
1242} /* ftdi_sio_attach */ 1231} /* ftdi_sio_attach */
@@ -1280,17 +1269,18 @@ static void ftdi_HE_TIRA1_setup (struct usb_serial *serial)
1280 * calls __serial_close for each open of the port 1269 * calls __serial_close for each open of the port
1281 * shutdown is called then (ie ftdi_shutdown) 1270 * shutdown is called then (ie ftdi_shutdown)
1282 */ 1271 */
1283
1284
1285static void ftdi_shutdown (struct usb_serial *serial) 1272static void ftdi_shutdown (struct usb_serial *serial)
1286{ /* ftdi_shutdown */ 1273{
1274 dbg("%s", __FUNCTION__);
1275}
1287 1276
1288 struct usb_serial_port *port = serial->port[0]; 1277static int ftdi_sio_port_remove(struct usb_serial_port *port)
1278{
1289 struct ftdi_private *priv = usb_get_serial_port_data(port); 1279 struct ftdi_private *priv = usb_get_serial_port_data(port);
1290 1280
1291 dbg("%s", __FUNCTION__); 1281 dbg("%s", __FUNCTION__);
1292 1282
1293 remove_sysfs_attrs(serial); 1283 remove_sysfs_attrs(port);
1294 1284
1295 /* all open ports are closed at this point 1285 /* all open ports are closed at this point
1296 * (by usbserial.c:__serial_close, which calls ftdi_close) 1286 * (by usbserial.c:__serial_close, which calls ftdi_close)
@@ -1300,8 +1290,9 @@ static void ftdi_shutdown (struct usb_serial *serial)
1300 usb_set_serial_port_data(port, NULL); 1290 usb_set_serial_port_data(port, NULL);
1301 kfree(priv); 1291 kfree(priv);
1302 } 1292 }
1303} /* ftdi_shutdown */
1304 1293
1294 return 0;
1295}
1305 1296
1306static int ftdi_open (struct usb_serial_port *port, struct file *filp) 1297static int ftdi_open (struct usb_serial_port *port, struct file *filp)
1307{ /* ftdi_open */ 1298{ /* ftdi_open */