281 if (fid.fid_outsz > FM_IOC_OUT_MAXBUFSZ)
282 return (EINVAL);
283
284 /*
285 * Copy in and unpack the input nvlist.
286 */
287 if (fid.fid_insz != 0 && fid.fid_inbuf != (caddr_t)0) {
288 buf = kmem_alloc(fid.fid_insz, KM_SLEEP);
289 if (ddi_copyin(fid.fid_inbuf, buf, fid.fid_insz, flag) != 0) {
290 kmem_free(buf, fid.fid_insz);
291 return (EFAULT);
292 }
293 err = nvlist_unpack(buf, fid.fid_insz, &invl, KM_SLEEP);
294 kmem_free(buf, fid.fid_insz);
295 if (err != 0)
296 return (err);
297 }
298
299 err = subr->func(cmd, invl, &onvl);
300
301 if (invl != NULL)
302 nvlist_free(invl);
303
304 if (err != 0) {
305 if (onvl != NULL)
306 nvlist_free(onvl);
307 return (err);
308 }
309
310 /*
311 * If the output nvlist contains any data, pack it and copyout.
312 */
313 if (onvl != NULL) {
314 size_t sz;
315
316 if ((err = nvlist_size(onvl, &sz, NV_ENCODE_NATIVE)) != 0) {
317 nvlist_free(onvl);
318 return (err);
319 }
320 if (sz > fid.fid_outsz) {
321 nvlist_free(onvl);
322 return (ENAMETOOLONG);
323 }
324
325 buf = kmem_alloc(sz, KM_SLEEP);
408 for (p = fm_versions; p->interface != NULL; p++)
409 (void) nvlist_add_uint32(fm_vers_nvl, p->interface,
410 p->version);
411 }
412
413 return (ret);
414 }
415
416 int
417 _info(struct modinfo *modinfop)
418 {
419 return (mod_info(&modlinkage, modinfop));
420 }
421
422 int
423 _fini(void)
424 {
425 int ret;
426
427 if ((ret = mod_remove(&modlinkage)) == 0) {
428 if (fm_vers_nvl != NULL)
429 nvlist_free(fm_vers_nvl);
430 }
431
432 return (ret);
433 }
|
281 if (fid.fid_outsz > FM_IOC_OUT_MAXBUFSZ)
282 return (EINVAL);
283
284 /*
285 * Copy in and unpack the input nvlist.
286 */
287 if (fid.fid_insz != 0 && fid.fid_inbuf != (caddr_t)0) {
288 buf = kmem_alloc(fid.fid_insz, KM_SLEEP);
289 if (ddi_copyin(fid.fid_inbuf, buf, fid.fid_insz, flag) != 0) {
290 kmem_free(buf, fid.fid_insz);
291 return (EFAULT);
292 }
293 err = nvlist_unpack(buf, fid.fid_insz, &invl, KM_SLEEP);
294 kmem_free(buf, fid.fid_insz);
295 if (err != 0)
296 return (err);
297 }
298
299 err = subr->func(cmd, invl, &onvl);
300
301 nvlist_free(invl);
302
303 if (err != 0) {
304 nvlist_free(onvl);
305 return (err);
306 }
307
308 /*
309 * If the output nvlist contains any data, pack it and copyout.
310 */
311 if (onvl != NULL) {
312 size_t sz;
313
314 if ((err = nvlist_size(onvl, &sz, NV_ENCODE_NATIVE)) != 0) {
315 nvlist_free(onvl);
316 return (err);
317 }
318 if (sz > fid.fid_outsz) {
319 nvlist_free(onvl);
320 return (ENAMETOOLONG);
321 }
322
323 buf = kmem_alloc(sz, KM_SLEEP);
406 for (p = fm_versions; p->interface != NULL; p++)
407 (void) nvlist_add_uint32(fm_vers_nvl, p->interface,
408 p->version);
409 }
410
411 return (ret);
412 }
413
414 int
415 _info(struct modinfo *modinfop)
416 {
417 return (mod_info(&modlinkage, modinfop));
418 }
419
420 int
421 _fini(void)
422 {
423 int ret;
424
425 if ((ret = mod_remove(&modlinkage)) == 0) {
426 nvlist_free(fm_vers_nvl);
427 }
428
429 return (ret);
430 }
|