1167 EC_MASTER_ERR(master, "Failed to allocate %u bytes" |
1168 EC_MASTER_ERR(master, "Failed to allocate %u bytes" |
1168 " for register data.\n", data.length); |
1169 " for register data.\n", data.length); |
1169 return -ENOMEM; |
1170 return -ENOMEM; |
1170 } |
1171 } |
1171 |
1172 |
1172 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
1173 request = kmalloc(sizeof(*request), GFP_KERNEL); |
1173 return -EINTR; |
1174 if (!request) |
1174 |
1175 return -ENOMEM; |
|
1176 kref_init(&request->refcount); |
|
1177 |
|
1178 // init register request |
|
1179 INIT_LIST_HEAD(&request->list); |
|
1180 request->dir = EC_DIR_INPUT; |
|
1181 request->data = contents; // now "owned" by request, see ec_master_reg_request_release |
|
1182 request->offset = data.offset; |
|
1183 request->length = data.length; |
|
1184 |
|
1185 if (ec_mutex_lock_interruptible(&master->master_mutex)) { |
|
1186 kref_put(&request->refcount,ec_master_reg_request_release); |
|
1187 return -EINTR; |
|
1188 } |
1175 if (!(slave = ec_master_find_slave( |
1189 if (!(slave = ec_master_find_slave( |
1176 master, 0, data.slave_position))) { |
1190 master, 0, data.slave_position))) { |
1177 ec_mutex_unlock(&master->master_mutex); |
1191 ec_mutex_unlock(&master->master_mutex); |
1178 EC_MASTER_ERR(master, "Slave %u does not exist!\n", |
1192 EC_MASTER_ERR(master, "Slave %u does not exist!\n", |
1179 data.slave_position); |
1193 data.slave_position); |
1180 return -EINVAL; |
1194 kref_put(&request->refcount,ec_master_reg_request_release); |
1181 } |
1195 return -EINVAL; |
1182 |
1196 } |
1183 // init register request |
1197 |
1184 INIT_LIST_HEAD(&request.list); |
1198 request->slave = slave; |
1185 request.slave = slave; |
1199 request->state = EC_INT_REQUEST_QUEUED; |
1186 request.dir = EC_DIR_INPUT; |
|
1187 request.data = contents; |
|
1188 request.offset = data.offset; |
|
1189 request.length = data.length; |
|
1190 request.state = EC_INT_REQUEST_QUEUED; |
|
1191 |
1200 |
1192 // schedule request. |
1201 // schedule request. |
1193 list_add_tail(&request.list, &master->reg_requests); |
1202 list_add_tail(&request->list, &master->reg_requests); |
|
1203 kref_get(&request->refcount); |
1194 |
1204 |
1195 ec_mutex_unlock(&master->master_mutex); |
1205 ec_mutex_unlock(&master->master_mutex); |
1196 |
1206 |
1197 // wait for processing through FSM |
1207 // wait for processing through FSM |
1198 if (wait_event_interruptible(master->reg_queue, |
1208 if (wait_event_interruptible(master->reg_queue, |
1199 request.state != EC_INT_REQUEST_QUEUED)) { |
1209 ((request->state == EC_INT_REQUEST_SUCCESS) || (request->state == EC_INT_REQUEST_FAILURE)))) { |
1200 // interrupted by signal |
1210 // interrupted by signal |
1201 ec_mutex_lock(&master->master_mutex); |
1211 kref_put(&request->refcount,ec_master_reg_request_release); |
1202 if (request.state == EC_INT_REQUEST_QUEUED) { |
1212 return -EINTR; |
1203 // abort request |
1213 } |
1204 list_del(&request.list); |
1214 |
1205 ec_mutex_unlock(&master->master_mutex); |
1215 if (request->state == EC_INT_REQUEST_SUCCESS) { |
1206 kfree(contents); |
1216 if (copy_to_user((void __user *) data.data, request->data, data.length)) { |
1207 return -EINTR; |
1217 kref_put(&request->refcount,ec_master_reg_request_release); |
|
1218 return -EFAULT; |
1208 } |
1219 } |
1209 ec_mutex_unlock(&master->master_mutex); |
1220 } |
1210 } |
1221 retval = request->state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO; |
1211 |
1222 |
1212 // wait until master FSM has finished processing |
1223 kref_put(&request->refcount,ec_master_reg_request_release); |
1213 wait_event(master->reg_queue, request.state != EC_INT_REQUEST_BUSY); |
1224 return retval; |
1214 |
|
1215 if (request.state == EC_INT_REQUEST_SUCCESS) { |
|
1216 if (copy_to_user((void __user *) data.data, contents, data.length)) |
|
1217 return -EFAULT; |
|
1218 } |
|
1219 kfree(contents); |
|
1220 |
|
1221 return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO; |
|
1222 } |
1225 } |
1223 |
1226 |
1224 /*****************************************************************************/ |
1227 /*****************************************************************************/ |
1225 |
1228 |
1226 /** Write a slave's registers. |
1229 /** Write a slave's registers. |
1251 if (copy_from_user(contents, (void __user *) data.data, data.length)) { |
1255 if (copy_from_user(contents, (void __user *) data.data, data.length)) { |
1252 kfree(contents); |
1256 kfree(contents); |
1253 return -EFAULT; |
1257 return -EFAULT; |
1254 } |
1258 } |
1255 |
1259 |
1256 if (ec_mutex_lock_interruptible(&master->master_mutex)) |
1260 request = kmalloc(sizeof(*request), GFP_KERNEL); |
1257 return -EINTR; |
1261 if (!request) |
|
1262 return -ENOMEM; |
|
1263 kref_init(&request->refcount); |
|
1264 // init register request |
|
1265 INIT_LIST_HEAD(&request->list); |
|
1266 request->dir = EC_DIR_OUTPUT; |
|
1267 request->data = contents; // now "owned" by request, see ec_master_reg_request_release |
|
1268 request->offset = data.offset; |
|
1269 request->length = data.length; |
|
1270 |
|
1271 if (ec_mutex_lock_interruptible(&master->master_mutex)) { |
|
1272 kref_put(&request->refcount,ec_master_reg_request_release); |
|
1273 return -EINTR; |
|
1274 } |
1258 |
1275 |
1259 if (!(slave = ec_master_find_slave( |
1276 if (!(slave = ec_master_find_slave( |
1260 master, 0, data.slave_position))) { |
1277 master, 0, data.slave_position))) { |
1261 ec_mutex_unlock(&master->master_mutex); |
1278 ec_mutex_unlock(&master->master_mutex); |
1262 EC_MASTER_ERR(master, "Slave %u does not exist!\n", |
1279 EC_MASTER_ERR(master, "Slave %u does not exist!\n", |
1263 data.slave_position); |
1280 data.slave_position); |
1264 kfree(contents); |
1281 kref_put(&request->refcount,ec_master_reg_request_release); |
1265 return -EINVAL; |
1282 return -EINVAL; |
1266 } |
1283 } |
1267 |
1284 |
1268 // init register request |
1285 request->slave = slave; |
1269 INIT_LIST_HEAD(&request.list); |
1286 request->state = EC_INT_REQUEST_QUEUED; |
1270 request.slave = slave; |
|
1271 request.dir = EC_DIR_OUTPUT; |
|
1272 request.data = contents; |
|
1273 request.offset = data.offset; |
|
1274 request.length = data.length; |
|
1275 request.state = EC_INT_REQUEST_QUEUED; |
|
1276 |
1287 |
1277 // schedule request. |
1288 // schedule request. |
1278 list_add_tail(&request.list, &master->reg_requests); |
1289 list_add_tail(&request->list, &master->reg_requests); |
|
1290 kref_get(&request->refcount); |
1279 |
1291 |
1280 ec_mutex_unlock(&master->master_mutex); |
1292 ec_mutex_unlock(&master->master_mutex); |
1281 |
1293 |
1282 // wait for processing through FSM |
1294 // wait for processing through FSM |
1283 if (wait_event_interruptible(master->reg_queue, |
1295 if (wait_event_interruptible(master->reg_queue, |
1284 request.state != EC_INT_REQUEST_QUEUED)) { |
1296 ((request->state == EC_INT_REQUEST_SUCCESS) || (request->state == EC_INT_REQUEST_FAILURE)))) { |
1285 // interrupted by signal |
1297 // interrupted by signal |
1286 ec_mutex_lock(&master->master_mutex); |
1298 kref_put(&request->refcount,ec_master_reg_request_release); |
1287 if (request.state == EC_INT_REQUEST_QUEUED) { |
1299 return -EINTR; |
1288 // abort request |
1300 } |
1289 list_del(&request.list); |
1301 |
1290 ec_mutex_unlock(&master->master_mutex); |
1302 retval = request->state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO; |
1291 kfree(contents); |
1303 kref_put(&request->refcount,ec_master_reg_request_release); |
1292 return -EINTR; |
1304 return retval; |
1293 } |
1305 |
1294 ec_mutex_unlock(&master->master_mutex); |
|
1295 } |
|
1296 |
|
1297 // wait until master FSM has finished processing |
|
1298 wait_event(master->reg_queue, request.state != EC_INT_REQUEST_BUSY); |
|
1299 |
|
1300 kfree(contents); |
|
1301 |
|
1302 return request.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO; |
|
1303 } |
1306 } |
1304 |
1307 |
1305 /*****************************************************************************/ |
1308 /*****************************************************************************/ |
1306 |
1309 |
1307 /** Get slave configuration information. |
1310 /** Get slave configuration information. |