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>

authored by Jim Radford and committed by Greg Kroah-Hartman 12bdbe03 d9a7ecac

+35 -44
+35 -44
drivers/usb/serial/ftdi_sio.c
··· 597 static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id *id); 598 static int ftdi_sio_attach (struct usb_serial *serial); 599 static void ftdi_shutdown (struct usb_serial *serial); 600 static int ftdi_open (struct usb_serial_port *port, struct file *filp); 601 static void ftdi_close (struct usb_serial_port *port, struct file *filp); 602 static int ftdi_write (struct usb_serial_port *port, const unsigned char *buf, int count); ··· 633 .num_bulk_out = 1, 634 .num_ports = 1, 635 .probe = ftdi_sio_probe, 636 .open = ftdi_open, 637 .close = ftdi_close, 638 .throttle = ftdi_throttle, ··· 1037 { 1038 struct usb_serial_port *port = to_usb_serial_port(dev); 1039 struct ftdi_private *priv = usb_get_serial_port_data(port); 1040 - struct usb_device *udev; 1041 unsigned short latency = 0; 1042 int rv = 0; 1043 1044 - udev = to_usb_device(dev); 1045 1046 dbg("%s",__FUNCTION__); 1047 ··· 1064 { 1065 struct usb_serial_port *port = to_usb_serial_port(dev); 1066 struct ftdi_private *priv = usb_get_serial_port_data(port); 1067 - struct usb_device *udev; 1068 char buf[1]; 1069 int v = simple_strtoul(valbuf, NULL, 10); 1070 int rv = 0; 1071 - 1072 - udev = to_usb_device(dev); 1073 1074 dbg("%s: setting latency timer = %i", __FUNCTION__, v); 1075 ··· 1093 { 1094 struct usb_serial_port *port = to_usb_serial_port(dev); 1095 struct ftdi_private *priv = usb_get_serial_port_data(port); 1096 - struct usb_device *udev; 1097 char buf[1]; 1098 int v = simple_strtoul(valbuf, NULL, 10); 1099 int rv = 0; 1100 - 1101 - udev = to_usb_device(dev); 1102 1103 dbg("%s: setting event char = %i", __FUNCTION__, v); 1104 ··· 1118 static DEVICE_ATTR(latency_timer, S_IWUSR | S_IRUGO, show_latency_timer, store_latency_timer); 1119 static DEVICE_ATTR(event_char, S_IWUSR, NULL, store_event_char); 1120 1121 - static int create_sysfs_attrs(struct usb_serial *serial) 1122 { 1123 - struct ftdi_private *priv; 1124 - struct usb_device *udev; 1125 int retval = 0; 1126 1127 dbg("%s",__FUNCTION__); 1128 - 1129 - priv = usb_get_serial_port_data(serial->port[0]); 1130 - udev = serial->dev; 1131 1132 /* XXX I've no idea if the original SIO supports the event_char 1133 * sysfs parameter, so I'm playing it safe. */ 1134 if (priv->chip_type != SIO) { 1135 dbg("sysfs attributes for %s", ftdi_chip_name[priv->chip_type]); 1136 - retval = device_create_file(&udev->dev, &dev_attr_event_char); 1137 if ((!retval) && 1138 (priv->chip_type == FT232BM || priv->chip_type == FT2232C)) { 1139 - retval = device_create_file(&udev->dev, 1140 &dev_attr_latency_timer); 1141 } 1142 } 1143 return retval; 1144 } 1145 1146 - static void remove_sysfs_attrs(struct usb_serial *serial) 1147 { 1148 - struct ftdi_private *priv; 1149 - struct usb_device *udev; 1150 1151 dbg("%s",__FUNCTION__); 1152 1153 - priv = usb_get_serial_port_data(serial->port[0]); 1154 - udev = serial->dev; 1155 - 1156 /* XXX see create_sysfs_attrs */ 1157 if (priv->chip_type != SIO) { 1158 - device_remove_file(&udev->dev, &dev_attr_event_char); 1159 if (priv->chip_type == FT232BM || priv->chip_type == FT2232C) { 1160 - device_remove_file(&udev->dev, &dev_attr_latency_timer); 1161 } 1162 } 1163 ··· 1169 return (0); 1170 } 1171 1172 - /* attach subroutine */ 1173 - static int ftdi_sio_attach (struct usb_serial *serial) 1174 { 1175 - struct usb_serial_port *port = serial->port[0]; 1176 struct ftdi_private *priv; 1177 - struct ftdi_sio_quirk *quirk; 1178 - int retval; 1179 1180 dbg("%s",__FUNCTION__); 1181 ··· 1211 kfree(port->bulk_out_buffer); 1212 port->bulk_out_buffer = NULL; 1213 1214 - usb_set_serial_port_data(serial->port[0], priv); 1215 1216 - ftdi_determine_type (serial->port[0]); 1217 - retval = create_sysfs_attrs(serial); 1218 - if (retval) 1219 - dev_err(&serial->dev->dev, "Error creating sysfs files, " 1220 - "continuing\n"); 1221 1222 /* Check for device requiring special set up. */ 1223 - quirk = (struct ftdi_sio_quirk *)usb_get_serial_data(serial); 1224 - if (quirk && quirk->setup) { 1225 quirk->setup(serial); 1226 - } 1227 1228 return 0; 1229 } /* ftdi_sio_attach */ ··· 1269 * calls __serial_close for each open of the port 1270 * shutdown is called then (ie ftdi_shutdown) 1271 */ 1272 - 1273 - 1274 static void ftdi_shutdown (struct usb_serial *serial) 1275 - { /* ftdi_shutdown */ 1276 1277 - struct usb_serial_port *port = serial->port[0]; 1278 struct ftdi_private *priv = usb_get_serial_port_data(port); 1279 1280 dbg("%s", __FUNCTION__); 1281 1282 - remove_sysfs_attrs(serial); 1283 1284 /* all open ports are closed at this point 1285 * (by usbserial.c:__serial_close, which calls ftdi_close) ··· 1290 usb_set_serial_port_data(port, NULL); 1291 kfree(priv); 1292 } 1293 - } /* ftdi_shutdown */ 1294 1295 1296 static int ftdi_open (struct usb_serial_port *port, struct file *filp) 1297 { /* ftdi_open */
··· 597 static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id *id); 598 static int ftdi_sio_attach (struct usb_serial *serial); 599 static void ftdi_shutdown (struct usb_serial *serial); 600 + static int ftdi_sio_port_probe (struct usb_serial_port *port); 601 + static int ftdi_sio_port_remove (struct usb_serial_port *port); 602 static int ftdi_open (struct usb_serial_port *port, struct file *filp); 603 static void ftdi_close (struct usb_serial_port *port, struct file *filp); 604 static int ftdi_write (struct usb_serial_port *port, const unsigned char *buf, int count); ··· 631 .num_bulk_out = 1, 632 .num_ports = 1, 633 .probe = ftdi_sio_probe, 634 + .port_probe = ftdi_sio_port_probe, 635 + .port_remove = ftdi_sio_port_remove, 636 .open = ftdi_open, 637 .close = ftdi_close, 638 .throttle = ftdi_throttle, ··· 1033 { 1034 struct usb_serial_port *port = to_usb_serial_port(dev); 1035 struct ftdi_private *priv = usb_get_serial_port_data(port); 1036 + struct usb_device *udev = port->serial->dev; 1037 unsigned short latency = 0; 1038 int rv = 0; 1039 1040 1041 dbg("%s",__FUNCTION__); 1042 ··· 1061 { 1062 struct usb_serial_port *port = to_usb_serial_port(dev); 1063 struct ftdi_private *priv = usb_get_serial_port_data(port); 1064 + struct usb_device *udev = port->serial->dev; 1065 char buf[1]; 1066 int v = simple_strtoul(valbuf, NULL, 10); 1067 int rv = 0; 1068 1069 dbg("%s: setting latency timer = %i", __FUNCTION__, v); 1070 ··· 1092 { 1093 struct usb_serial_port *port = to_usb_serial_port(dev); 1094 struct ftdi_private *priv = usb_get_serial_port_data(port); 1095 + struct usb_device *udev = port->serial->dev; 1096 char buf[1]; 1097 int v = simple_strtoul(valbuf, NULL, 10); 1098 int rv = 0; 1099 1100 dbg("%s: setting event char = %i", __FUNCTION__, v); 1101 ··· 1119 static DEVICE_ATTR(latency_timer, S_IWUSR | S_IRUGO, show_latency_timer, store_latency_timer); 1120 static DEVICE_ATTR(event_char, S_IWUSR, NULL, store_event_char); 1121 1122 + static int create_sysfs_attrs(struct usb_serial_port *port) 1123 { 1124 + struct ftdi_private *priv = usb_get_serial_port_data(port); 1125 int retval = 0; 1126 1127 dbg("%s",__FUNCTION__); 1128 1129 /* XXX I've no idea if the original SIO supports the event_char 1130 * sysfs parameter, so I'm playing it safe. */ 1131 if (priv->chip_type != SIO) { 1132 dbg("sysfs attributes for %s", ftdi_chip_name[priv->chip_type]); 1133 + retval = device_create_file(&port->dev, &dev_attr_event_char); 1134 if ((!retval) && 1135 (priv->chip_type == FT232BM || priv->chip_type == FT2232C)) { 1136 + retval = device_create_file(&port->dev, 1137 &dev_attr_latency_timer); 1138 } 1139 } 1140 return retval; 1141 } 1142 1143 + static void remove_sysfs_attrs(struct usb_serial_port *port) 1144 { 1145 + struct ftdi_private *priv = usb_get_serial_port_data(port); 1146 1147 dbg("%s",__FUNCTION__); 1148 1149 /* XXX see create_sysfs_attrs */ 1150 if (priv->chip_type != SIO) { 1151 + device_remove_file(&port->dev, &dev_attr_event_char); 1152 if (priv->chip_type == FT232BM || priv->chip_type == FT2232C) { 1153 + device_remove_file(&port->dev, &dev_attr_latency_timer); 1154 } 1155 } 1156 ··· 1178 return (0); 1179 } 1180 1181 + static int ftdi_sio_port_probe(struct usb_serial_port *port) 1182 { 1183 struct ftdi_private *priv; 1184 1185 dbg("%s",__FUNCTION__); 1186 ··· 1224 kfree(port->bulk_out_buffer); 1225 port->bulk_out_buffer = NULL; 1226 1227 + usb_set_serial_port_data(port, priv); 1228 1229 + ftdi_determine_type (port); 1230 + create_sysfs_attrs(port); 1231 + return 0; 1232 + } 1233 1234 + /* attach subroutine */ 1235 + static int ftdi_sio_attach (struct usb_serial *serial) 1236 + { 1237 /* Check for device requiring special set up. */ 1238 + struct ftdi_sio_quirk *quirk = usb_get_serial_data(serial); 1239 + 1240 + if (quirk && quirk->setup) 1241 quirk->setup(serial); 1242 1243 return 0; 1244 } /* ftdi_sio_attach */ ··· 1280 * calls __serial_close for each open of the port 1281 * shutdown is called then (ie ftdi_shutdown) 1282 */ 1283 static void ftdi_shutdown (struct usb_serial *serial) 1284 + { 1285 + dbg("%s", __FUNCTION__); 1286 + } 1287 1288 + static int ftdi_sio_port_remove(struct usb_serial_port *port) 1289 + { 1290 struct ftdi_private *priv = usb_get_serial_port_data(port); 1291 1292 dbg("%s", __FUNCTION__); 1293 1294 + remove_sysfs_attrs(port); 1295 1296 /* all open ports are closed at this point 1297 * (by usbserial.c:__serial_close, which calls ftdi_close) ··· 1300 usb_set_serial_port_data(port, NULL); 1301 kfree(priv); 1302 } 1303 1304 + return 0; 1305 + } 1306 1307 static int ftdi_open (struct usb_serial_port *port, struct file *filp) 1308 { /* ftdi_open */