1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * This driver supports FTDI FT232R USB-to-serial adapters. It is a 29 * device-specific driver (DSD) working with the USB generic serial 30 * driver (GSD) usbser. 31 * 32 * It implements the USB-to-serial device-specific driver interface (DSDI) 33 * which is exported by GSD. The DSDI is defined by ds_ops_t structure. 34 * 35 * Also may work with the older FTDI 8U232AM devices. 36 */ 37 38 #include <sys/types.h> 39 #include <sys/param.h> 40 #include <sys/stream.h> 41 #include <sys/conf.h> 42 #include <sys/ddi.h> 43 #include <sys/sunddi.h> 44 45 #include <sys/usb/clients/usbser/usbser.h> 46 #include <sys/usb/clients/usbser/usbftdi/uftdi_var.h> 47 48 static void *usbser_uftdi_statep; /* soft state handle for usbser */ 49 50 extern ds_ops_t uftdi_ds_ops; /* DSD operations */ 51 52 static int 53 usbser_uftdi_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, 54 void **result) 55 { 56 return (usbser_getinfo(dip, infocmd, arg, result, usbser_uftdi_statep)); 57 } 58 59 60 static int 61 usbser_uftdi_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 62 { 63 return (usbser_attach(dip, cmd, usbser_uftdi_statep, &uftdi_ds_ops)); 64 } 65 66 67 static int 68 usbser_uftdi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 69 { 70 return (usbser_detach(dip, cmd, usbser_uftdi_statep)); 71 } 72 73 74 static int 75 usbser_uftdi_open(queue_t *rq, dev_t *dev, int flag, int sflag, cred_t *cr) 76 { 77 return (usbser_open(rq, dev, flag, sflag, cr, usbser_uftdi_statep)); 78 } 79 80 /* 81 * Several linked data structures to tie it together .. 82 */ 83 struct module_info uftdi_modinfo = { 84 0, /* module id */ 85 "uftdi", /* module name */ 86 USBSER_MIN_PKTSZ, /* min pkt size */ 87 USBSER_MAX_PKTSZ, /* max pkt size */ 88 USBSER_HIWAT, /* hi watermark */ 89 USBSER_LOWAT /* low watermark */ 90 }; 91 92 static struct qinit uftdi_rinit = { 93 putq, 94 usbser_rsrv, 95 usbser_uftdi_open, 96 usbser_close, 97 NULL, 98 &uftdi_modinfo, 99 }; 100 101 static struct qinit uftdi_winit = { 102 usbser_wput, 103 usbser_wsrv, 104 NULL, 105 NULL, 106 NULL, 107 &uftdi_modinfo, 108 }; 109 110 static struct streamtab uftdi_str_info = { 111 &uftdi_rinit, 112 &uftdi_winit, 113 }; 114 115 static struct cb_ops uftdi_cb_ops = { 116 nodev, /* cb_open */ 117 nodev, /* cb_close */ 118 nodev, /* cb_strategy */ 119 nodev, /* cb_print */ 120 nodev, /* cb_dump */ 121 nodev, /* cb_read */ 122 nodev, /* cb_write */ 123 nodev, /* cb_ioctl */ 124 nodev, /* cb_devmap */ 125 nodev, /* cb_mmap */ 126 nodev, /* cb_segmap */ 127 nochpoll, /* cb_chpoll */ 128 ddi_prop_op, /* cb_prop_op */ 129 &uftdi_str_info, /* cb_stream */ 130 (int)(D_64BIT | D_NEW | D_MP | D_HOTPLUG) /* cb_flag */ 131 }; 132 133 static struct dev_ops uftdi_ops = { 134 DEVO_REV, /* devo_rev */ 135 0, /* devo_refcnt */ 136 usbser_uftdi_getinfo, 137 nulldev, /* devo_identify */ 138 nulldev, /* devo_probe */ 139 usbser_uftdi_attach, 140 usbser_uftdi_detach, 141 nodev, /* devo_reset */ 142 &uftdi_cb_ops, 143 (struct bus_ops *)NULL, /* devo_bus_ops */ 144 usbser_power, /* devo_power */ 145 ddi_quiesce_not_needed 146 }; 147 148 static struct modldrv modldrv = { 149 &mod_driverops, 150 "FTDI FT232R USB UART driver", 151 &uftdi_ops, 152 }; 153 154 static struct modlinkage modlinkage = { 155 MODREV_1, 156 &modldrv 157 }; 158 159 int 160 _init(void) 161 { 162 int error; 163 164 if ((error = mod_install(&modlinkage)) != 0) 165 return (error); 166 if ((error = ddi_soft_state_init(&usbser_uftdi_statep, 167 usbser_soft_state_size(), 1)) != 0) 168 (void) mod_remove(&modlinkage); 169 return (error); 170 } 171 172 173 int 174 _fini(void) 175 { 176 int error; 177 178 if ((error = mod_remove(&modlinkage)) == 0) 179 ddi_soft_state_fini(&usbser_uftdi_statep); 180 return (error); 181 } 182 183 184 int 185 _info(struct modinfo *modinfop) 186 { 187 return (mod_info(&modlinkage, modinfop)); 188 } 189