17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate * with the License.
87c478bd9Sstevel@tonic-gate *
97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate * and limitations under the License.
137c478bd9Sstevel@tonic-gate *
147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate *
207c478bd9Sstevel@tonic-gate * CDDL HEADER END
217c478bd9Sstevel@tonic-gate */
227c478bd9Sstevel@tonic-gate /*
237c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
247c478bd9Sstevel@tonic-gate * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate */
267c478bd9Sstevel@tonic-gate
277c478bd9Sstevel@tonic-gate /*
287c478bd9Sstevel@tonic-gate * s_generic.c :
297c478bd9Sstevel@tonic-gate * This file contains generic SCSI related functions for scsi plug-in
307c478bd9Sstevel@tonic-gate * for libsm.so.
317c478bd9Sstevel@tonic-gate */
327c478bd9Sstevel@tonic-gate
337c478bd9Sstevel@tonic-gate
347c478bd9Sstevel@tonic-gate #include <sys/types.h>
357c478bd9Sstevel@tonic-gate #include <sys/stat.h>
367c478bd9Sstevel@tonic-gate #include <sys/ioctl.h>
377c478bd9Sstevel@tonic-gate #include <unistd.h>
387c478bd9Sstevel@tonic-gate #include <sys/shm.h>
397c478bd9Sstevel@tonic-gate #include <sys/mman.h>
407c478bd9Sstevel@tonic-gate #include <sys/smedia.h>
417c478bd9Sstevel@tonic-gate #include "../../../library/inc/rmedia.h"
427c478bd9Sstevel@tonic-gate #include <smserver.h>
437c478bd9Sstevel@tonic-gate #include <dirent.h>
447c478bd9Sstevel@tonic-gate #include <fcntl.h>
457c478bd9Sstevel@tonic-gate #include <sys/scsi/scsi.h>
467c478bd9Sstevel@tonic-gate #include <strings.h>
477c478bd9Sstevel@tonic-gate #include "../../../library/common/l_defines.h"
487c478bd9Sstevel@tonic-gate
497c478bd9Sstevel@tonic-gate
507c478bd9Sstevel@tonic-gate static int32_t remap_shared_buf(rmedia_handle_t *, size_t, char *);
517c478bd9Sstevel@tonic-gate
527c478bd9Sstevel@tonic-gate #define W_E_MASK 0x80
537c478bd9Sstevel@tonic-gate #define BUF_SIZE_MULTIPLE 0x2000
547c478bd9Sstevel@tonic-gate
557c478bd9Sstevel@tonic-gate int32_t
_m_get_media_info(rmedia_handle_t * handle,void * ip)567c478bd9Sstevel@tonic-gate _m_get_media_info(rmedia_handle_t *handle, void *ip)
577c478bd9Sstevel@tonic-gate {
587c478bd9Sstevel@tonic-gate smmedium_prop_t *medinfo = ip;
597c478bd9Sstevel@tonic-gate int32_t ret_val;
607c478bd9Sstevel@tonic-gate smedia_reqget_medium_property_t reqget_medium_property;
617c478bd9Sstevel@tonic-gate smedia_retget_medium_property_t *retget_medium_property;
627c478bd9Sstevel@tonic-gate smedia_reterror_t *reterror;
637c478bd9Sstevel@tonic-gate door_arg_t door_args;
647c478bd9Sstevel@tonic-gate char rbuf[sizeof (smedia_services_t) + sizeof (door_desc_t)];
657c478bd9Sstevel@tonic-gate
667c478bd9Sstevel@tonic-gate DPRINTF("get_media_info called.\n");
677c478bd9Sstevel@tonic-gate /* Check for valid handle */
687c478bd9Sstevel@tonic-gate if (handle == NULL) {
697c478bd9Sstevel@tonic-gate DPRINTF("Null Handle\n");
707c478bd9Sstevel@tonic-gate errno = EINVAL;
717c478bd9Sstevel@tonic-gate return (-1);
727c478bd9Sstevel@tonic-gate }
737c478bd9Sstevel@tonic-gate if (handle->sm_signature != (int32_t)LIBSMEDIA_SIGNATURE) {
747c478bd9Sstevel@tonic-gate DPRINTF("Invalid signature in handle.\n");
75*100ea781SToomas Soome DPRINTF2("Signature expected=0x%x, found=0x%x\n",
767c478bd9Sstevel@tonic-gate LIBSMEDIA_SIGNATURE, handle->sm_signature);
777c478bd9Sstevel@tonic-gate DPRINTF1("fd=%d\n", handle->sm_fd);
787c478bd9Sstevel@tonic-gate errno = EINVAL;
797c478bd9Sstevel@tonic-gate return (-1);
807c478bd9Sstevel@tonic-gate }
817c478bd9Sstevel@tonic-gate (void) memset((void *) medinfo, 0, sizeof (smmedium_prop_t));
827c478bd9Sstevel@tonic-gate
837c478bd9Sstevel@tonic-gate reqget_medium_property.cnum = SMEDIA_CNUM_GET_MEDIUM_PROPERTY;
847c478bd9Sstevel@tonic-gate door_args.data_ptr = (char *)&reqget_medium_property;
857c478bd9Sstevel@tonic-gate door_args.data_size = sizeof (smedia_services_t);
867c478bd9Sstevel@tonic-gate door_args.desc_ptr = NULL;
877c478bd9Sstevel@tonic-gate door_args.desc_num = 0;
887c478bd9Sstevel@tonic-gate door_args.rbuf = rbuf;
897c478bd9Sstevel@tonic-gate door_args.rsize = sizeof (rbuf);
907c478bd9Sstevel@tonic-gate
917c478bd9Sstevel@tonic-gate ret_val = door_call(handle->sm_door, &door_args);
927c478bd9Sstevel@tonic-gate if (ret_val < 0) {
937c478bd9Sstevel@tonic-gate perror("door_call");
947c478bd9Sstevel@tonic-gate return (-1);
957c478bd9Sstevel@tonic-gate }
967c478bd9Sstevel@tonic-gate retget_medium_property =
977c478bd9Sstevel@tonic-gate (smedia_retget_medium_property_t *)((void *)door_args.data_ptr);
987c478bd9Sstevel@tonic-gate reterror = (smedia_reterror_t *)((void *)door_args.data_ptr);
997c478bd9Sstevel@tonic-gate if (reterror->cnum == SMEDIA_CNUM_ERROR) {
1007c478bd9Sstevel@tonic-gate DPRINTF1(
1017c478bd9Sstevel@tonic-gate "Error in get_medium_property. errnum = 0x%x \n", reterror->errnum);
1027c478bd9Sstevel@tonic-gate errno = reterror->errnum;
1037c478bd9Sstevel@tonic-gate return (-1);
1047c478bd9Sstevel@tonic-gate }
1057c478bd9Sstevel@tonic-gate
1067c478bd9Sstevel@tonic-gate *medinfo = retget_medium_property->smprop;
1077c478bd9Sstevel@tonic-gate
1087c478bd9Sstevel@tonic-gate return (0);
1097c478bd9Sstevel@tonic-gate }
1107c478bd9Sstevel@tonic-gate
1117c478bd9Sstevel@tonic-gate int32_t
_m_get_device_info(rmedia_handle_t * handle,void * ip)1127c478bd9Sstevel@tonic-gate _m_get_device_info(rmedia_handle_t *handle, void *ip)
1137c478bd9Sstevel@tonic-gate {
1147c478bd9Sstevel@tonic-gate struct smdevice_info *dev_info = ip;
1157c478bd9Sstevel@tonic-gate int32_t ret_val;
1167c478bd9Sstevel@tonic-gate smedia_reqget_device_info_t reqget_device_info;
1177c478bd9Sstevel@tonic-gate smedia_retget_device_info_t *retget_device_info;
1187c478bd9Sstevel@tonic-gate smedia_reterror_t *reterror;
1197c478bd9Sstevel@tonic-gate door_arg_t door_args;
1207c478bd9Sstevel@tonic-gate char rbuf[sizeof (smedia_services_t) + sizeof (door_desc_t)];
1217c478bd9Sstevel@tonic-gate char *vendor_name, *product_name, *fw_version;
1227c478bd9Sstevel@tonic-gate
1237c478bd9Sstevel@tonic-gate /* Check for valid handle */
1247c478bd9Sstevel@tonic-gate if (handle == NULL) {
1257c478bd9Sstevel@tonic-gate DPRINTF("Null Handle\n");
1267c478bd9Sstevel@tonic-gate errno = EINVAL;
1277c478bd9Sstevel@tonic-gate return (-1);
1287c478bd9Sstevel@tonic-gate }
1297c478bd9Sstevel@tonic-gate if (handle->sm_signature != LIBSMEDIA_SIGNATURE) {
1307c478bd9Sstevel@tonic-gate DPRINTF("Invalid signature in handle.\n");
1317c478bd9Sstevel@tonic-gate errno = EINVAL;
1327c478bd9Sstevel@tonic-gate return (-1);
1337c478bd9Sstevel@tonic-gate }
1347c478bd9Sstevel@tonic-gate
1357c478bd9Sstevel@tonic-gate vendor_name = (char *)malloc(9);
1367c478bd9Sstevel@tonic-gate if (vendor_name == NULL) {
1377c478bd9Sstevel@tonic-gate if (!errno)
1387c478bd9Sstevel@tonic-gate errno = ENOMEM;
1397c478bd9Sstevel@tonic-gate return (-1);
1407c478bd9Sstevel@tonic-gate }
1417c478bd9Sstevel@tonic-gate product_name = (char *)malloc(17);
1427c478bd9Sstevel@tonic-gate if (product_name == NULL) {
1437c478bd9Sstevel@tonic-gate free(vendor_name);
1447c478bd9Sstevel@tonic-gate if (!errno)
1457c478bd9Sstevel@tonic-gate errno = ENOMEM;
1467c478bd9Sstevel@tonic-gate return (-1);
1477c478bd9Sstevel@tonic-gate }
1487c478bd9Sstevel@tonic-gate
1497c478bd9Sstevel@tonic-gate fw_version = (char *)malloc(18);
1507c478bd9Sstevel@tonic-gate if (fw_version == NULL) {
1517c478bd9Sstevel@tonic-gate free(vendor_name);
1527c478bd9Sstevel@tonic-gate free(product_name);
1537c478bd9Sstevel@tonic-gate if (!errno)
1547c478bd9Sstevel@tonic-gate errno = ENOMEM;
1557c478bd9Sstevel@tonic-gate return (-1);
1567c478bd9Sstevel@tonic-gate }
1577c478bd9Sstevel@tonic-gate reqget_device_info.cnum = SMEDIA_CNUM_GET_DEVICE_INFO;
1587c478bd9Sstevel@tonic-gate door_args.data_ptr = (char *)&reqget_device_info;
1597c478bd9Sstevel@tonic-gate door_args.data_size = sizeof (smedia_services_t);
1607c478bd9Sstevel@tonic-gate door_args.desc_ptr = NULL;
1617c478bd9Sstevel@tonic-gate door_args.desc_num = 0;
1627c478bd9Sstevel@tonic-gate door_args.rbuf = rbuf;
1637c478bd9Sstevel@tonic-gate door_args.rsize = sizeof (rbuf);
1647c478bd9Sstevel@tonic-gate
1657c478bd9Sstevel@tonic-gate ret_val = door_call(handle->sm_door, &door_args);
1667c478bd9Sstevel@tonic-gate if (ret_val < 0) {
1677c478bd9Sstevel@tonic-gate perror("door_call");
1687c478bd9Sstevel@tonic-gate free(vendor_name);
1697c478bd9Sstevel@tonic-gate free(product_name);
1707c478bd9Sstevel@tonic-gate free(fw_version);
1717c478bd9Sstevel@tonic-gate return (-1);
1727c478bd9Sstevel@tonic-gate }
1737c478bd9Sstevel@tonic-gate retget_device_info = (smedia_retget_device_info_t *)
1747c478bd9Sstevel@tonic-gate ((void *)door_args.data_ptr);
1757c478bd9Sstevel@tonic-gate reterror = (smedia_reterror_t *)((void *)door_args.data_ptr);
1767c478bd9Sstevel@tonic-gate if (reterror->cnum == SMEDIA_CNUM_ERROR) {
177*100ea781SToomas Soome DPRINTF1("Error in get_device_info. errnum = 0x%x \n",
178*100ea781SToomas Soome reterror->errnum);
1797c478bd9Sstevel@tonic-gate errno = reterror->errnum;
1807c478bd9Sstevel@tonic-gate free(vendor_name);
1817c478bd9Sstevel@tonic-gate free(product_name);
1827c478bd9Sstevel@tonic-gate free(fw_version);
1837c478bd9Sstevel@tonic-gate return (-1);
1847c478bd9Sstevel@tonic-gate }
1857c478bd9Sstevel@tonic-gate
1867c478bd9Sstevel@tonic-gate dev_info->sm_vendor_name = vendor_name;
1877c478bd9Sstevel@tonic-gate dev_info->sm_product_name = product_name;
1887c478bd9Sstevel@tonic-gate dev_info->sm_firmware_version = fw_version;
1897c478bd9Sstevel@tonic-gate
1907c478bd9Sstevel@tonic-gate
1917c478bd9Sstevel@tonic-gate (void) strlcpy(dev_info->sm_vendor_name,
1927c478bd9Sstevel@tonic-gate retget_device_info->sm_vendor_name, 8);
1937c478bd9Sstevel@tonic-gate dev_info->sm_vendor_name[8] = 0;
1947c478bd9Sstevel@tonic-gate (void) strlcpy(dev_info->sm_product_name,
1957c478bd9Sstevel@tonic-gate retget_device_info->sm_product_name, 16);
1967c478bd9Sstevel@tonic-gate dev_info->sm_product_name[16] = 0;
1977c478bd9Sstevel@tonic-gate (void) strlcpy(dev_info->sm_firmware_version,
1987c478bd9Sstevel@tonic-gate retget_device_info->sm_firmware_version, 17);
1997c478bd9Sstevel@tonic-gate dev_info->sm_firmware_version[17] = 0;
2007c478bd9Sstevel@tonic-gate
2017c478bd9Sstevel@tonic-gate dev_info->sm_interface_type = retget_device_info->sm_interface_type;
2027c478bd9Sstevel@tonic-gate
2037c478bd9Sstevel@tonic-gate #ifdef DEBUG
2047c478bd9Sstevel@tonic-gate DPRINTF1("Vendor name = %s\n", dev_info->sm_vendor_name);
2057c478bd9Sstevel@tonic-gate DPRINTF1("product name = %s\n", dev_info->sm_product_name);
2067c478bd9Sstevel@tonic-gate DPRINTF1("Firmware revision = %s\n", dev_info->sm_firmware_version);
2077c478bd9Sstevel@tonic-gate #endif /* DEBUG */
2087c478bd9Sstevel@tonic-gate
2097c478bd9Sstevel@tonic-gate return (0);
2107c478bd9Sstevel@tonic-gate }
2117c478bd9Sstevel@tonic-gate
2127c478bd9Sstevel@tonic-gate int32_t
_m_free_device_info(rmedia_handle_t * handle,void * ip)2137c478bd9Sstevel@tonic-gate _m_free_device_info(rmedia_handle_t *handle, void *ip)
2147c478bd9Sstevel@tonic-gate {
2157c478bd9Sstevel@tonic-gate struct smdevice_info *dev_info = ip;
2167c478bd9Sstevel@tonic-gate
2177c478bd9Sstevel@tonic-gate /* Check for valid handle */
2187c478bd9Sstevel@tonic-gate if (handle == NULL) {
2197c478bd9Sstevel@tonic-gate DPRINTF("Null Handle\n");
2207c478bd9Sstevel@tonic-gate errno = EINVAL;
2217c478bd9Sstevel@tonic-gate return (-1);
2227c478bd9Sstevel@tonic-gate }
2237c478bd9Sstevel@tonic-gate if (handle->sm_signature != LIBSMEDIA_SIGNATURE) {
2247c478bd9Sstevel@tonic-gate DPRINTF("Invalid signature in handle.\n");
2257c478bd9Sstevel@tonic-gate errno = EINVAL;
2267c478bd9Sstevel@tonic-gate return (-1);
2277c478bd9Sstevel@tonic-gate }
2287c478bd9Sstevel@tonic-gate
2297c478bd9Sstevel@tonic-gate free(dev_info->sm_vendor_name);
2307c478bd9Sstevel@tonic-gate free(dev_info->sm_product_name);
2317c478bd9Sstevel@tonic-gate free(dev_info->sm_firmware_version);
2327c478bd9Sstevel@tonic-gate return (0);
2337c478bd9Sstevel@tonic-gate }
2347c478bd9Sstevel@tonic-gate
2357c478bd9Sstevel@tonic-gate int32_t
_m_raw_write(rmedia_handle_t * handle,void * i_p)2367c478bd9Sstevel@tonic-gate _m_raw_write(rmedia_handle_t *handle, void *i_p)
2377c478bd9Sstevel@tonic-gate {
2387c478bd9Sstevel@tonic-gate int32_t ret_val;
2397c478bd9Sstevel@tonic-gate struct raw_params *r_p = (struct raw_params *)i_p;
2407c478bd9Sstevel@tonic-gate smedia_reqraw_write_t reqraw_write;
2417c478bd9Sstevel@tonic-gate smedia_retraw_write_t *retraw_write;
2427c478bd9Sstevel@tonic-gate smedia_reterror_t *reterror;
2437c478bd9Sstevel@tonic-gate door_arg_t door_args;
2447c478bd9Sstevel@tonic-gate char rbuf[sizeof (smedia_services_t) + sizeof (door_desc_t)];
2457c478bd9Sstevel@tonic-gate
2467c478bd9Sstevel@tonic-gate /* Check for valid handle */
2477c478bd9Sstevel@tonic-gate if (handle == NULL) {
2487c478bd9Sstevel@tonic-gate DPRINTF("Null Handle\n");
2497c478bd9Sstevel@tonic-gate errno = EINVAL;
2507c478bd9Sstevel@tonic-gate return (-1);
2517c478bd9Sstevel@tonic-gate }
2527c478bd9Sstevel@tonic-gate if (handle->sm_signature != LIBSMEDIA_SIGNATURE) {
2537c478bd9Sstevel@tonic-gate DPRINTF("Invalid signature in handle.\n");
2547c478bd9Sstevel@tonic-gate errno = EINVAL;
2557c478bd9Sstevel@tonic-gate return (-1);
2567c478bd9Sstevel@tonic-gate }
2577c478bd9Sstevel@tonic-gate (void) mutex_lock(&handle->sm_bufmutex);
2587c478bd9Sstevel@tonic-gate ret_val = remap_shared_buf(handle, r_p->size, r_p->buffer);
2597c478bd9Sstevel@tonic-gate if (ret_val != 0) goto error;
2607c478bd9Sstevel@tonic-gate reqraw_write.cnum = SMEDIA_CNUM_RAW_WRITE;
2617c478bd9Sstevel@tonic-gate reqraw_write.blockno = r_p->offset;
2627c478bd9Sstevel@tonic-gate reqraw_write.nbytes = r_p->size;
2637c478bd9Sstevel@tonic-gate bcopy(r_p->buffer, handle->sm_buf, r_p->size);
2647c478bd9Sstevel@tonic-gate door_args.data_ptr = (char *)&reqraw_write;
2657c478bd9Sstevel@tonic-gate door_args.data_size = sizeof (reqraw_write);
2667c478bd9Sstevel@tonic-gate door_args.desc_ptr = NULL;
2677c478bd9Sstevel@tonic-gate door_args.desc_num = 0;
2687c478bd9Sstevel@tonic-gate door_args.rbuf = rbuf;
2697c478bd9Sstevel@tonic-gate door_args.rsize = sizeof (rbuf);
2707c478bd9Sstevel@tonic-gate
2717c478bd9Sstevel@tonic-gate ret_val = door_call(handle->sm_door, &door_args);
2727c478bd9Sstevel@tonic-gate if (ret_val < 0) {
2737c478bd9Sstevel@tonic-gate perror("door_call");
2747c478bd9Sstevel@tonic-gate goto error;
2757c478bd9Sstevel@tonic-gate }
2767c478bd9Sstevel@tonic-gate retraw_write = (smedia_retraw_write_t *)((void *)door_args.data_ptr);
2777c478bd9Sstevel@tonic-gate reterror = (smedia_reterror_t *)((void *)door_args.data_ptr);
2787c478bd9Sstevel@tonic-gate if (reterror->cnum == SMEDIA_CNUM_ERROR) {
279*100ea781SToomas Soome DPRINTF3("Error in raw write. errnum = 0x%x "
280*100ea781SToomas Soome "blk_num = 0x%x(%d)\n", reterror->errnum, r_p->offset,
281*100ea781SToomas Soome r_p->offset);
2827c478bd9Sstevel@tonic-gate errno = reterror->errnum;
2837c478bd9Sstevel@tonic-gate goto error;
2847c478bd9Sstevel@tonic-gate }
2857c478bd9Sstevel@tonic-gate (void) mutex_unlock(&handle->sm_bufmutex);
2867c478bd9Sstevel@tonic-gate return (retraw_write->nbytes);
2877c478bd9Sstevel@tonic-gate
2887c478bd9Sstevel@tonic-gate error:
2897c478bd9Sstevel@tonic-gate (void) mutex_unlock(&handle->sm_bufmutex);
2907c478bd9Sstevel@tonic-gate return (-1);
2917c478bd9Sstevel@tonic-gate }
2927c478bd9Sstevel@tonic-gate
2937c478bd9Sstevel@tonic-gate size_t
_m_raw_read(rmedia_handle_t * handle,void * i_p)2947c478bd9Sstevel@tonic-gate _m_raw_read(rmedia_handle_t *handle, void *i_p)
2957c478bd9Sstevel@tonic-gate {
2967c478bd9Sstevel@tonic-gate struct raw_params *r_p = (struct raw_params *)i_p;
2977c478bd9Sstevel@tonic-gate int32_t ret_val, bytes_read;
2987c478bd9Sstevel@tonic-gate smedia_reqraw_read_t reqraw_read;
2997c478bd9Sstevel@tonic-gate smedia_retraw_read_t *retraw_read;
3007c478bd9Sstevel@tonic-gate smedia_reterror_t *reterror;
3017c478bd9Sstevel@tonic-gate door_arg_t door_args;
3027c478bd9Sstevel@tonic-gate char rbuf[sizeof (smedia_services_t) + sizeof (door_desc_t)];
3037c478bd9Sstevel@tonic-gate
3047c478bd9Sstevel@tonic-gate /* Check for valid handle */
3057c478bd9Sstevel@tonic-gate if (handle == NULL) {
3067c478bd9Sstevel@tonic-gate DPRINTF("Null Handle\n");
3077c478bd9Sstevel@tonic-gate errno = EINVAL;
3087c478bd9Sstevel@tonic-gate return (size_t)(-1);
3097c478bd9Sstevel@tonic-gate }
3107c478bd9Sstevel@tonic-gate if (handle->sm_signature != LIBSMEDIA_SIGNATURE) {
3117c478bd9Sstevel@tonic-gate DPRINTF("Invalid signature in handle.\n");
3127c478bd9Sstevel@tonic-gate return (size_t)(-1);
3137c478bd9Sstevel@tonic-gate }
3147c478bd9Sstevel@tonic-gate /*
3157c478bd9Sstevel@tonic-gate * Check if another thread is doing an IO with same handle.
3167c478bd9Sstevel@tonic-gate * In that case ww block here.
3177c478bd9Sstevel@tonic-gate */
3187c478bd9Sstevel@tonic-gate (void) mutex_lock(&handle->sm_bufmutex);
3197c478bd9Sstevel@tonic-gate ret_val = remap_shared_buf(handle, r_p->size, r_p->buffer);
3207c478bd9Sstevel@tonic-gate if (ret_val != 0) goto error;
3217c478bd9Sstevel@tonic-gate
3227c478bd9Sstevel@tonic-gate reqraw_read.cnum = SMEDIA_CNUM_RAW_READ;
3237c478bd9Sstevel@tonic-gate reqraw_read.blockno = r_p->offset;
3247c478bd9Sstevel@tonic-gate reqraw_read.nbytes = r_p->size;
3257c478bd9Sstevel@tonic-gate door_args.data_ptr = (char *)&reqraw_read;
3267c478bd9Sstevel@tonic-gate door_args.data_size = sizeof (smedia_services_t);
3277c478bd9Sstevel@tonic-gate door_args.desc_ptr = NULL;
3287c478bd9Sstevel@tonic-gate door_args.desc_num = 0;
3297c478bd9Sstevel@tonic-gate door_args.rbuf = rbuf;
3307c478bd9Sstevel@tonic-gate door_args.rsize = sizeof (rbuf);
3317c478bd9Sstevel@tonic-gate
3327c478bd9Sstevel@tonic-gate ret_val = door_call(handle->sm_door, &door_args);
3337c478bd9Sstevel@tonic-gate if (ret_val < 0) {
3347c478bd9Sstevel@tonic-gate perror("door_call");
3357c478bd9Sstevel@tonic-gate goto error;
3367c478bd9Sstevel@tonic-gate }
3377c478bd9Sstevel@tonic-gate retraw_read = (smedia_retraw_read_t *)((void *)door_args.data_ptr);
3387c478bd9Sstevel@tonic-gate reterror = (smedia_reterror_t *)((void *)door_args.data_ptr);
3397c478bd9Sstevel@tonic-gate if (reterror->cnum == SMEDIA_CNUM_ERROR) {
3407c478bd9Sstevel@tonic-gate /*
3417c478bd9Sstevel@tonic-gate * free(rbuf);
3427c478bd9Sstevel@tonic-gate */
343*100ea781SToomas Soome DPRINTF3("Error in raw read. errnum = 0x%x "
344*100ea781SToomas Soome "blk_num = 0x%x(%d)\n", reterror->errnum, r_p->offset,
345*100ea781SToomas Soome r_p->offset);
3467c478bd9Sstevel@tonic-gate errno = reterror->errnum;
3477c478bd9Sstevel@tonic-gate goto error;
3487c478bd9Sstevel@tonic-gate }
3497c478bd9Sstevel@tonic-gate (void) memcpy(r_p->buffer, handle->sm_buf, retraw_read->nbytes);
3507c478bd9Sstevel@tonic-gate bytes_read = retraw_read->nbytes;
3517c478bd9Sstevel@tonic-gate (void) mutex_unlock(&handle->sm_bufmutex);
3527c478bd9Sstevel@tonic-gate return (bytes_read);
3537c478bd9Sstevel@tonic-gate
3547c478bd9Sstevel@tonic-gate error:
3557c478bd9Sstevel@tonic-gate (void) mutex_unlock(&handle->sm_bufmutex);
3567c478bd9Sstevel@tonic-gate return (size_t)(-1);
3577c478bd9Sstevel@tonic-gate
3587c478bd9Sstevel@tonic-gate }
3597c478bd9Sstevel@tonic-gate
3607c478bd9Sstevel@tonic-gate size_t
_m_media_format(rmedia_handle_t * handle,void * ip)3617c478bd9Sstevel@tonic-gate _m_media_format(rmedia_handle_t *handle, void *ip)
3627c478bd9Sstevel@tonic-gate {
3637c478bd9Sstevel@tonic-gate int32_t ret_val;
3647c478bd9Sstevel@tonic-gate struct format_flags *ffl = (struct format_flags *)ip;
3657c478bd9Sstevel@tonic-gate smedia_reqformat_t reqformat;
3667c478bd9Sstevel@tonic-gate smedia_reterror_t *reterror;
3677c478bd9Sstevel@tonic-gate door_arg_t door_args;
3687c478bd9Sstevel@tonic-gate char rbuf[sizeof (smedia_services_t) + sizeof (door_desc_t)];
3697c478bd9Sstevel@tonic-gate
3707c478bd9Sstevel@tonic-gate /* Check for valid handle */
3717c478bd9Sstevel@tonic-gate if (handle == NULL) {
3727c478bd9Sstevel@tonic-gate DPRINTF("Null Handle\n");
3737c478bd9Sstevel@tonic-gate errno = EINVAL;
3747c478bd9Sstevel@tonic-gate return (size_t)(-1);
3757c478bd9Sstevel@tonic-gate }
3767c478bd9Sstevel@tonic-gate if (handle->sm_signature != LIBSMEDIA_SIGNATURE) {
3777c478bd9Sstevel@tonic-gate DPRINTF("Invalid signature in handle.\n");
3787c478bd9Sstevel@tonic-gate errno = EINVAL;
3797c478bd9Sstevel@tonic-gate return (size_t)(-1);
3807c478bd9Sstevel@tonic-gate }
3817c478bd9Sstevel@tonic-gate reqformat.cnum = SMEDIA_CNUM_FORMAT;
3827c478bd9Sstevel@tonic-gate reqformat.flavor = ffl->flavor;
3837c478bd9Sstevel@tonic-gate reqformat.mode = ffl->mode;
3847c478bd9Sstevel@tonic-gate door_args.data_ptr = (char *)&reqformat;
3857c478bd9Sstevel@tonic-gate door_args.data_size = sizeof (smedia_services_t);
3867c478bd9Sstevel@tonic-gate door_args.desc_ptr = NULL;
3877c478bd9Sstevel@tonic-gate door_args.desc_num = 0;
3887c478bd9Sstevel@tonic-gate door_args.rbuf = rbuf;
3897c478bd9Sstevel@tonic-gate door_args.rsize = sizeof (rbuf);
3907c478bd9Sstevel@tonic-gate
3917c478bd9Sstevel@tonic-gate ret_val = door_call(handle->sm_door, &door_args);
3927c478bd9Sstevel@tonic-gate if (ret_val < 0) {
3937c478bd9Sstevel@tonic-gate perror("door_call");
3947c478bd9Sstevel@tonic-gate return (size_t)(-1);
3957c478bd9Sstevel@tonic-gate }
3967c478bd9Sstevel@tonic-gate reterror = (smedia_reterror_t *)((void *)door_args.data_ptr);
3977c478bd9Sstevel@tonic-gate if (reterror->cnum == SMEDIA_CNUM_ERROR) {
3987c478bd9Sstevel@tonic-gate DPRINTF1("Error in format. errnum = 0x%x \n", reterror->errnum);
3997c478bd9Sstevel@tonic-gate errno = reterror->errnum;
4007c478bd9Sstevel@tonic-gate return (size_t)(-1);
4017c478bd9Sstevel@tonic-gate }
4027c478bd9Sstevel@tonic-gate return (0);
4037c478bd9Sstevel@tonic-gate }
4047c478bd9Sstevel@tonic-gate
4057c478bd9Sstevel@tonic-gate int32_t
_m_get_media_status(rmedia_handle_t * handle,void * ip)4067c478bd9Sstevel@tonic-gate _m_get_media_status(rmedia_handle_t *handle, void *ip)
4077c478bd9Sstevel@tonic-gate {
4087c478bd9Sstevel@tonic-gate smwp_state_t *wp = ip;
4097c478bd9Sstevel@tonic-gate int32_t ret_val;
4107c478bd9Sstevel@tonic-gate smedia_reqget_protection_status_t reqget_protection_status;
4117c478bd9Sstevel@tonic-gate smedia_retget_protection_status_t *retget_protection_status;
4127c478bd9Sstevel@tonic-gate smedia_reterror_t *reterror;
4137c478bd9Sstevel@tonic-gate door_arg_t door_args;
4147c478bd9Sstevel@tonic-gate char rbuf[sizeof (smedia_services_t) + sizeof (door_desc_t)];
4157c478bd9Sstevel@tonic-gate
4167c478bd9Sstevel@tonic-gate /* Check for valid handle */
4177c478bd9Sstevel@tonic-gate if (handle == NULL) {
4187c478bd9Sstevel@tonic-gate DPRINTF("Null Handle\n");
4197c478bd9Sstevel@tonic-gate errno = EINVAL;
4207c478bd9Sstevel@tonic-gate return (-1);
4217c478bd9Sstevel@tonic-gate }
4227c478bd9Sstevel@tonic-gate if (handle->sm_signature != LIBSMEDIA_SIGNATURE) {
4237c478bd9Sstevel@tonic-gate DPRINTF("Invalid signature in handle.\n");
4247c478bd9Sstevel@tonic-gate errno = EINVAL;
4257c478bd9Sstevel@tonic-gate return (-1);
4267c478bd9Sstevel@tonic-gate }
4277c478bd9Sstevel@tonic-gate reqget_protection_status.cnum = SMEDIA_CNUM_GET_PROTECTION_STATUS;
4287c478bd9Sstevel@tonic-gate door_args.data_ptr = (char *)&reqget_protection_status;
4297c478bd9Sstevel@tonic-gate door_args.data_size = sizeof (smedia_services_t);
4307c478bd9Sstevel@tonic-gate door_args.desc_ptr = NULL;
4317c478bd9Sstevel@tonic-gate door_args.desc_num = 0;
4327c478bd9Sstevel@tonic-gate door_args.rbuf = rbuf;
4337c478bd9Sstevel@tonic-gate door_args.rsize = sizeof (rbuf);
4347c478bd9Sstevel@tonic-gate
4357c478bd9Sstevel@tonic-gate ret_val = door_call(handle->sm_door, &door_args);
4367c478bd9Sstevel@tonic-gate if (ret_val < 0) {
4377c478bd9Sstevel@tonic-gate perror("door_call");
4387c478bd9Sstevel@tonic-gate return (-1);
4397c478bd9Sstevel@tonic-gate }
440*100ea781SToomas Soome retget_protection_status = (smedia_retget_protection_status_t *)
4417c478bd9Sstevel@tonic-gate ((void *)door_args.data_ptr);
4427c478bd9Sstevel@tonic-gate reterror = (smedia_reterror_t *)((void *)door_args.data_ptr);
4437c478bd9Sstevel@tonic-gate if (reterror->cnum == SMEDIA_CNUM_ERROR) {
444*100ea781SToomas Soome DPRINTF1("Error in get_protection-status. errnum = 0x%x \n",
445*100ea781SToomas Soome reterror->errnum);
4467c478bd9Sstevel@tonic-gate errno = reterror->errnum;
4477c478bd9Sstevel@tonic-gate return (-1);
4487c478bd9Sstevel@tonic-gate }
4497c478bd9Sstevel@tonic-gate (void) memcpy((char *)wp, (char *)&retget_protection_status->prot_state,
4507c478bd9Sstevel@tonic-gate sizeof (smwp_state_t));
4517c478bd9Sstevel@tonic-gate return (0);
4527c478bd9Sstevel@tonic-gate }
4537c478bd9Sstevel@tonic-gate
4547c478bd9Sstevel@tonic-gate int32_t
_m_set_media_status(rmedia_handle_t * handle,void * ip)455*100ea781SToomas Soome _m_set_media_status(rmedia_handle_t *handle, void *ip)
456*100ea781SToomas Soome {
4577c478bd9Sstevel@tonic-gate
4587c478bd9Sstevel@tonic-gate smwp_state_t *wp = ip;
4597c478bd9Sstevel@tonic-gate int32_t ret_val;
4607c478bd9Sstevel@tonic-gate smedia_reqset_protection_status_t reqset_protection_status;
4617c478bd9Sstevel@tonic-gate smedia_reterror_t *reterror;
4627c478bd9Sstevel@tonic-gate door_arg_t door_args;
4637c478bd9Sstevel@tonic-gate char rbuf[sizeof (smedia_services_t) + sizeof (door_desc_t)];
4647c478bd9Sstevel@tonic-gate
4657c478bd9Sstevel@tonic-gate /* Check for valid handle */
4667c478bd9Sstevel@tonic-gate if (handle == NULL) {
4677c478bd9Sstevel@tonic-gate DPRINTF("Null Handle\n");
4687c478bd9Sstevel@tonic-gate errno = EINVAL;
4697c478bd9Sstevel@tonic-gate return (-1);
4707c478bd9Sstevel@tonic-gate }
4717c478bd9Sstevel@tonic-gate if (handle->sm_signature != LIBSMEDIA_SIGNATURE) {
4727c478bd9Sstevel@tonic-gate DPRINTF("Invalid signature in handle.\n");
4737c478bd9Sstevel@tonic-gate errno = EINVAL;
4747c478bd9Sstevel@tonic-gate return (-1);
4757c478bd9Sstevel@tonic-gate }
4767c478bd9Sstevel@tonic-gate reqset_protection_status.cnum = SMEDIA_CNUM_SET_PROTECTION_STATUS;
4777c478bd9Sstevel@tonic-gate reqset_protection_status.prot_state = *wp;
4787c478bd9Sstevel@tonic-gate door_args.data_ptr = (char *)&reqset_protection_status;
4797c478bd9Sstevel@tonic-gate door_args.data_size = sizeof (smedia_services_t);
4807c478bd9Sstevel@tonic-gate door_args.desc_ptr = NULL;
4817c478bd9Sstevel@tonic-gate door_args.desc_num = 0;
4827c478bd9Sstevel@tonic-gate door_args.rbuf = rbuf;
4837c478bd9Sstevel@tonic-gate door_args.rsize = sizeof (rbuf);
4847c478bd9Sstevel@tonic-gate
4857c478bd9Sstevel@tonic-gate ret_val = door_call(handle->sm_door, &door_args);
4867c478bd9Sstevel@tonic-gate if (ret_val < 0) {
4877c478bd9Sstevel@tonic-gate perror("door_call");
4887c478bd9Sstevel@tonic-gate return (-1);
4897c478bd9Sstevel@tonic-gate }
4907c478bd9Sstevel@tonic-gate reterror = (smedia_reterror_t *)((void *)door_args.data_ptr);
4917c478bd9Sstevel@tonic-gate if (reterror->cnum == SMEDIA_CNUM_ERROR) {
4927c478bd9Sstevel@tonic-gate DPRINTF1(
4937c478bd9Sstevel@tonic-gate "Error in set_protection-status. errnum = 0x%x \n", reterror->errnum);
4947c478bd9Sstevel@tonic-gate errno = reterror->errnum;
4957c478bd9Sstevel@tonic-gate return (-1);
4967c478bd9Sstevel@tonic-gate }
4977c478bd9Sstevel@tonic-gate return (0);
4987c478bd9Sstevel@tonic-gate }
4997c478bd9Sstevel@tonic-gate
5007c478bd9Sstevel@tonic-gate int32_t
_m_reassign_block(rmedia_handle_t * handle,void * ip)5017c478bd9Sstevel@tonic-gate _m_reassign_block(rmedia_handle_t *handle, void *ip)
5027c478bd9Sstevel@tonic-gate {
5037c478bd9Sstevel@tonic-gate uint32_t block;
5047c478bd9Sstevel@tonic-gate diskaddr_t *blockp = (diskaddr_t *)ip;
5057c478bd9Sstevel@tonic-gate int32_t ret_val;
5067c478bd9Sstevel@tonic-gate smedia_reqreassign_block_t reqreassign_block;
5077c478bd9Sstevel@tonic-gate smedia_reterror_t *reterror;
5087c478bd9Sstevel@tonic-gate door_arg_t door_args;
5097c478bd9Sstevel@tonic-gate char rbuf[sizeof (smedia_services_t) + sizeof (door_desc_t)];
5107c478bd9Sstevel@tonic-gate
5117c478bd9Sstevel@tonic-gate /* Check for valid handle */
5127c478bd9Sstevel@tonic-gate if (handle == NULL) {
5137c478bd9Sstevel@tonic-gate DPRINTF("Null Handle\n");
5147c478bd9Sstevel@tonic-gate errno = EINVAL;
5157c478bd9Sstevel@tonic-gate return (-1);
5167c478bd9Sstevel@tonic-gate }
5177c478bd9Sstevel@tonic-gate if (handle->sm_signature != LIBSMEDIA_SIGNATURE) {
5187c478bd9Sstevel@tonic-gate DPRINTF("Invalid signature in handle.\n");
5197c478bd9Sstevel@tonic-gate errno = EINVAL;
5207c478bd9Sstevel@tonic-gate return (-1);
5217c478bd9Sstevel@tonic-gate }
5227c478bd9Sstevel@tonic-gate block = *blockp;
5237c478bd9Sstevel@tonic-gate DPRINTF1("reassign block %d\n", block);
5247c478bd9Sstevel@tonic-gate reqreassign_block.cnum = SMEDIA_CNUM_REASSIGN_BLOCK;
5257c478bd9Sstevel@tonic-gate reqreassign_block.blockno = block;
5267c478bd9Sstevel@tonic-gate door_args.data_ptr = (char *)&reqreassign_block;
5277c478bd9Sstevel@tonic-gate door_args.data_size = sizeof (smedia_services_t);
5287c478bd9Sstevel@tonic-gate door_args.desc_ptr = NULL;
5297c478bd9Sstevel@tonic-gate door_args.desc_num = 0;
5307c478bd9Sstevel@tonic-gate door_args.rbuf = rbuf;
5317c478bd9Sstevel@tonic-gate door_args.rsize = sizeof (rbuf);
5327c478bd9Sstevel@tonic-gate
5337c478bd9Sstevel@tonic-gate ret_val = door_call(handle->sm_door, &door_args);
5347c478bd9Sstevel@tonic-gate if (ret_val < 0) {
5357c478bd9Sstevel@tonic-gate perror("door_call");
5367c478bd9Sstevel@tonic-gate return (-1);
5377c478bd9Sstevel@tonic-gate }
5387c478bd9Sstevel@tonic-gate reterror = (smedia_reterror_t *)((void *)door_args.data_ptr);
5397c478bd9Sstevel@tonic-gate if (reterror->cnum == SMEDIA_CNUM_ERROR) {
540*100ea781SToomas Soome DPRINTF2("Error in reassign_block. block = 0x%x "
541*100ea781SToomas Soome "errnum = 0x%x \n", block, reterror->errnum);
5427c478bd9Sstevel@tonic-gate errno = reterror->errnum;
5437c478bd9Sstevel@tonic-gate return (-1);
5447c478bd9Sstevel@tonic-gate }
5457c478bd9Sstevel@tonic-gate return (0);
5467c478bd9Sstevel@tonic-gate }
5477c478bd9Sstevel@tonic-gate
5487c478bd9Sstevel@tonic-gate /* ARGSUSED1 */
5497c478bd9Sstevel@tonic-gate int32_t
_m_eject(rmedia_handle_t * handle,void * ip)5507c478bd9Sstevel@tonic-gate _m_eject(rmedia_handle_t *handle, void *ip)
5517c478bd9Sstevel@tonic-gate {
5527c478bd9Sstevel@tonic-gate int32_t fd;
5537c478bd9Sstevel@tonic-gate
5547c478bd9Sstevel@tonic-gate /* Check for valid handle */
5557c478bd9Sstevel@tonic-gate if (handle == NULL) {
5567c478bd9Sstevel@tonic-gate DPRINTF("Null Handle\n");
5577c478bd9Sstevel@tonic-gate errno = EINVAL;
5587c478bd9Sstevel@tonic-gate return (-1);
5597c478bd9Sstevel@tonic-gate }
5607c478bd9Sstevel@tonic-gate if (handle->sm_signature != LIBSMEDIA_SIGNATURE) {
5617c478bd9Sstevel@tonic-gate DPRINTF("Invalid signature in handle.\n");
5627c478bd9Sstevel@tonic-gate errno = EINVAL;
5637c478bd9Sstevel@tonic-gate return (-1);
5647c478bd9Sstevel@tonic-gate }
5657c478bd9Sstevel@tonic-gate fd = handle->sm_fd;
5667c478bd9Sstevel@tonic-gate return (ioctl(fd, DKIOCEJECT));
5677c478bd9Sstevel@tonic-gate }
5687c478bd9Sstevel@tonic-gate
5697c478bd9Sstevel@tonic-gate int32_t
_m_device_type(ushort_t ctype,ushort_t mtype)5707c478bd9Sstevel@tonic-gate _m_device_type(ushort_t ctype, ushort_t mtype)
5717c478bd9Sstevel@tonic-gate {
5727c478bd9Sstevel@tonic-gate if ((ctype == DKC_SCSI_CCS) ||
5737c478bd9Sstevel@tonic-gate (ctype == DKC_MD21) ||
5747c478bd9Sstevel@tonic-gate (ctype == DKC_CDROM)) {
5757c478bd9Sstevel@tonic-gate if (mtype == 0)
5767c478bd9Sstevel@tonic-gate return (0);
5777c478bd9Sstevel@tonic-gate }
5787c478bd9Sstevel@tonic-gate return (-1);
5797c478bd9Sstevel@tonic-gate }
5807c478bd9Sstevel@tonic-gate
5817c478bd9Sstevel@tonic-gate int32_t
_m_version_no(void)5827c478bd9Sstevel@tonic-gate _m_version_no(void)
5837c478bd9Sstevel@tonic-gate {
5847c478bd9Sstevel@tonic-gate return (SM_SCSI_VERSION_1);
5857c478bd9Sstevel@tonic-gate }
5867c478bd9Sstevel@tonic-gate
5877c478bd9Sstevel@tonic-gate int32_t
_m_check_format_status(rmedia_handle_t * handle,void * ip)5887c478bd9Sstevel@tonic-gate _m_check_format_status(rmedia_handle_t *handle, void *ip)
5897c478bd9Sstevel@tonic-gate {
5907c478bd9Sstevel@tonic-gate int32_t ret_val;
5917c478bd9Sstevel@tonic-gate smedia_reqcheck_format_status_t reqcheck_format_status;
5927c478bd9Sstevel@tonic-gate smedia_retcheck_format_status_t *retcheck_format_status;
5937c478bd9Sstevel@tonic-gate smedia_reterror_t *reterror;
5947c478bd9Sstevel@tonic-gate door_arg_t door_args;
5957c478bd9Sstevel@tonic-gate char rbuf[sizeof (smedia_services_t) + sizeof (door_desc_t)];
5967c478bd9Sstevel@tonic-gate #ifdef lint
5977c478bd9Sstevel@tonic-gate ip = ip;
5987c478bd9Sstevel@tonic-gate #endif
5997c478bd9Sstevel@tonic-gate
6007c478bd9Sstevel@tonic-gate /* Check for valid handle */
6017c478bd9Sstevel@tonic-gate if (handle == NULL) {
6027c478bd9Sstevel@tonic-gate DPRINTF("Null Handle\n");
6037c478bd9Sstevel@tonic-gate errno = EINVAL;
6047c478bd9Sstevel@tonic-gate return (-1);
6057c478bd9Sstevel@tonic-gate }
6067c478bd9Sstevel@tonic-gate if (handle->sm_signature != LIBSMEDIA_SIGNATURE) {
6077c478bd9Sstevel@tonic-gate DPRINTF("Invalid signature in handle.\n");
6087c478bd9Sstevel@tonic-gate errno = EINVAL;
6097c478bd9Sstevel@tonic-gate return (-1);
6107c478bd9Sstevel@tonic-gate }
6117c478bd9Sstevel@tonic-gate reqcheck_format_status.cnum = SMEDIA_CNUM_CHECK_FORMAT_STATUS;
6127c478bd9Sstevel@tonic-gate door_args.data_ptr = (char *)&reqcheck_format_status;
6137c478bd9Sstevel@tonic-gate door_args.data_size = sizeof (smedia_services_t);
6147c478bd9Sstevel@tonic-gate door_args.desc_ptr = NULL;
6157c478bd9Sstevel@tonic-gate door_args.desc_num = 0;
6167c478bd9Sstevel@tonic-gate door_args.rbuf = rbuf;
6177c478bd9Sstevel@tonic-gate door_args.rsize = sizeof (rbuf);
6187c478bd9Sstevel@tonic-gate
6197c478bd9Sstevel@tonic-gate ret_val = door_call(handle->sm_door, &door_args);
6207c478bd9Sstevel@tonic-gate if (ret_val < 0) {
6217c478bd9Sstevel@tonic-gate perror("door_call");
6227c478bd9Sstevel@tonic-gate return (-1);
6237c478bd9Sstevel@tonic-gate }
6247c478bd9Sstevel@tonic-gate retcheck_format_status =
6257c478bd9Sstevel@tonic-gate (smedia_retcheck_format_status_t *)((void *)door_args.data_ptr);
6267c478bd9Sstevel@tonic-gate reterror = (smedia_reterror_t *)((void *)door_args.data_ptr);
6277c478bd9Sstevel@tonic-gate if (reterror->cnum == SMEDIA_CNUM_ERROR) {
628*100ea781SToomas Soome DPRINTF1("Error in check_format_status. errnum = 0x%x \n",
629*100ea781SToomas Soome reterror->errnum);
6307c478bd9Sstevel@tonic-gate errno = reterror->errnum;
6317c478bd9Sstevel@tonic-gate return (-1);
6327c478bd9Sstevel@tonic-gate }
6337c478bd9Sstevel@tonic-gate return (retcheck_format_status->percent_complete);
6347c478bd9Sstevel@tonic-gate }
6357c478bd9Sstevel@tonic-gate
6367c478bd9Sstevel@tonic-gate int32_t
_m_uscsi_cmd(rmedia_handle_t * handle,struct uscsi_cmd * ucmd)6377c478bd9Sstevel@tonic-gate _m_uscsi_cmd(rmedia_handle_t *handle, struct uscsi_cmd *ucmd)
6387c478bd9Sstevel@tonic-gate {
6397c478bd9Sstevel@tonic-gate int32_t ret_val;
6407c478bd9Sstevel@tonic-gate smedia_requscsi_cmd_t requscsi_cmd;
6417c478bd9Sstevel@tonic-gate smedia_retuscsi_cmd_t *retuscsi_cmd;
6427c478bd9Sstevel@tonic-gate smedia_reterror_t *reterror;
6437c478bd9Sstevel@tonic-gate door_arg_t door_args;
6447c478bd9Sstevel@tonic-gate char rbuf[sizeof (smedia_services_t) + sizeof (door_desc_t)];
6457c478bd9Sstevel@tonic-gate
6467c478bd9Sstevel@tonic-gate /* Check for valid handle */
6477c478bd9Sstevel@tonic-gate if (handle == NULL) {
6487c478bd9Sstevel@tonic-gate DPRINTF("Null Handle\n");
6497c478bd9Sstevel@tonic-gate errno = EINVAL;
6507c478bd9Sstevel@tonic-gate return (-1);
6517c478bd9Sstevel@tonic-gate }
6527c478bd9Sstevel@tonic-gate if (handle->sm_signature != LIBSMEDIA_SIGNATURE) {
6537c478bd9Sstevel@tonic-gate DPRINTF("Invalid signature in handle.\n");
6547c478bd9Sstevel@tonic-gate errno = EINVAL;
6557c478bd9Sstevel@tonic-gate return (-1);
6567c478bd9Sstevel@tonic-gate }
6577c478bd9Sstevel@tonic-gate /*
6587c478bd9Sstevel@tonic-gate * We will be validating the user supplied buffer lengths and
6597c478bd9Sstevel@tonic-gate * buffer pointers.
6607c478bd9Sstevel@tonic-gate */
6617c478bd9Sstevel@tonic-gate if (ucmd->uscsi_cdblen > MAX_CDB_LEN) {
6627c478bd9Sstevel@tonic-gate DPRINTF("Invalid cdblen specified.\n");
6637c478bd9Sstevel@tonic-gate errno = EINVAL;
6647c478bd9Sstevel@tonic-gate return (-1);
6657c478bd9Sstevel@tonic-gate }
6667c478bd9Sstevel@tonic-gate if ((ucmd->uscsi_flags & USCSI_RQENABLE) &&
6677c478bd9Sstevel@tonic-gate (ucmd->uscsi_rqlen > MAX_RQ_LEN)) {
6687c478bd9Sstevel@tonic-gate DPRINTF("Invalid rqlen specified.\n");
6697c478bd9Sstevel@tonic-gate errno = EINVAL;
6707c478bd9Sstevel@tonic-gate return (-1);
6717c478bd9Sstevel@tonic-gate }
6727c478bd9Sstevel@tonic-gate if (ucmd->uscsi_cdb == NULL) {
6737c478bd9Sstevel@tonic-gate DPRINTF("cdb buffer is NULL.\n");
6747c478bd9Sstevel@tonic-gate errno = EINVAL;
6757c478bd9Sstevel@tonic-gate return (-1);
6767c478bd9Sstevel@tonic-gate }
6777c478bd9Sstevel@tonic-gate if ((ucmd->uscsi_buflen) && (ucmd->uscsi_bufaddr == NULL)) {
6787c478bd9Sstevel@tonic-gate DPRINTF("bufaddr is NULL.\n");
6797c478bd9Sstevel@tonic-gate errno = EINVAL;
6807c478bd9Sstevel@tonic-gate return (-1);
6817c478bd9Sstevel@tonic-gate }
6827c478bd9Sstevel@tonic-gate if ((ucmd->uscsi_flags & USCSI_RQENABLE) &&
6837c478bd9Sstevel@tonic-gate (ucmd->uscsi_rqbuf == NULL)) {
6847c478bd9Sstevel@tonic-gate DPRINTF("rqbuf is NULL.\n");
6857c478bd9Sstevel@tonic-gate errno = EINVAL;
6867c478bd9Sstevel@tonic-gate return (-1);
6877c478bd9Sstevel@tonic-gate }
6887c478bd9Sstevel@tonic-gate /*
6897c478bd9Sstevel@tonic-gate * Check if another thread is doing an IO with same handle.
6907c478bd9Sstevel@tonic-gate * In that case we block here.
6917c478bd9Sstevel@tonic-gate */
6927c478bd9Sstevel@tonic-gate (void) mutex_lock(&handle->sm_bufmutex);
6937c478bd9Sstevel@tonic-gate ret_val = remap_shared_buf(handle, ucmd->uscsi_buflen,
6947c478bd9Sstevel@tonic-gate ucmd->uscsi_bufaddr);
6957c478bd9Sstevel@tonic-gate if (ret_val != 0) {
6967c478bd9Sstevel@tonic-gate DPRINTF("remap of shared buf failed.\n");
6977c478bd9Sstevel@tonic-gate goto error;
6987c478bd9Sstevel@tonic-gate }
6997c478bd9Sstevel@tonic-gate
7007c478bd9Sstevel@tonic-gate requscsi_cmd.cnum = SMEDIA_CNUM_USCSI_CMD;
7017c478bd9Sstevel@tonic-gate requscsi_cmd.uscsi_flags = ucmd->uscsi_flags;
7027c478bd9Sstevel@tonic-gate requscsi_cmd.uscsi_timeout = ucmd->uscsi_timeout;
7037c478bd9Sstevel@tonic-gate requscsi_cmd.uscsi_buflen = ucmd->uscsi_buflen;
7047c478bd9Sstevel@tonic-gate requscsi_cmd.uscsi_cdblen = ucmd->uscsi_cdblen;
7057c478bd9Sstevel@tonic-gate requscsi_cmd.uscsi_rqlen = ucmd->uscsi_rqlen;
7067c478bd9Sstevel@tonic-gate
7077c478bd9Sstevel@tonic-gate /*
7087c478bd9Sstevel@tonic-gate * The uscsi_buflen has been validated in the call to
7097c478bd9Sstevel@tonic-gate * remap_shared_buf() done earlier.
7107c478bd9Sstevel@tonic-gate */
7117c478bd9Sstevel@tonic-gate /* Check for write */
7127c478bd9Sstevel@tonic-gate if (!(ucmd->uscsi_flags & USCSI_READ)) {
7137c478bd9Sstevel@tonic-gate bcopy(ucmd->uscsi_bufaddr, handle->sm_buf, ucmd->uscsi_buflen);
7147c478bd9Sstevel@tonic-gate }
7157c478bd9Sstevel@tonic-gate
7167c478bd9Sstevel@tonic-gate bcopy(ucmd->uscsi_cdb, requscsi_cmd.uscsi_cdb, ucmd->uscsi_cdblen);
7177c478bd9Sstevel@tonic-gate
7187c478bd9Sstevel@tonic-gate door_args.data_ptr = (char *)&requscsi_cmd;
7197c478bd9Sstevel@tonic-gate door_args.data_size = sizeof (smedia_services_t);
7207c478bd9Sstevel@tonic-gate door_args.desc_ptr = NULL;
7217c478bd9Sstevel@tonic-gate door_args.desc_num = 0;
7227c478bd9Sstevel@tonic-gate door_args.rbuf = rbuf;
7237c478bd9Sstevel@tonic-gate door_args.rsize = sizeof (rbuf);
7247c478bd9Sstevel@tonic-gate
7257c478bd9Sstevel@tonic-gate ret_val = door_call(handle->sm_door, &door_args);
7267c478bd9Sstevel@tonic-gate if (ret_val < 0) {
7277c478bd9Sstevel@tonic-gate perror("door_call");
7287c478bd9Sstevel@tonic-gate goto error;
7297c478bd9Sstevel@tonic-gate }
7307c478bd9Sstevel@tonic-gate retuscsi_cmd = (smedia_retuscsi_cmd_t *)((void *)door_args.data_ptr);
7317c478bd9Sstevel@tonic-gate reterror = (smedia_reterror_t *)((void *)door_args.data_ptr);
7327c478bd9Sstevel@tonic-gate if (reterror->cnum == SMEDIA_CNUM_ERROR) {
7337c478bd9Sstevel@tonic-gate DPRINTF1(
7347c478bd9Sstevel@tonic-gate "Error in uscsi cmd. errnum = 0x%x\n", reterror->errnum);
7357c478bd9Sstevel@tonic-gate errno = reterror->errnum;
7367c478bd9Sstevel@tonic-gate goto error;
7377c478bd9Sstevel@tonic-gate }
7387c478bd9Sstevel@tonic-gate ucmd->uscsi_status = retuscsi_cmd->uscsi_status;
7397c478bd9Sstevel@tonic-gate ucmd->uscsi_resid = retuscsi_cmd->uscsi_resid;
7407c478bd9Sstevel@tonic-gate ucmd->uscsi_rqstatus = retuscsi_cmd->uscsi_rqstatus;
7417c478bd9Sstevel@tonic-gate ucmd->uscsi_rqresid = retuscsi_cmd->uscsi_rqresid;
7427c478bd9Sstevel@tonic-gate if ((ucmd->uscsi_flags & USCSI_RQENABLE) &&
7437c478bd9Sstevel@tonic-gate (ucmd->uscsi_rqbuf != NULL)) {
744*100ea781SToomas Soome bcopy(retuscsi_cmd->uscsi_rqbuf, ucmd->uscsi_rqbuf,
745*100ea781SToomas Soome ucmd->uscsi_rqlen);
7467c478bd9Sstevel@tonic-gate }
7477c478bd9Sstevel@tonic-gate errno = retuscsi_cmd->uscsi_errno;
7487c478bd9Sstevel@tonic-gate if (errno) {
7497c478bd9Sstevel@tonic-gate goto error;
7507c478bd9Sstevel@tonic-gate }
7517c478bd9Sstevel@tonic-gate
7527c478bd9Sstevel@tonic-gate if (ucmd->uscsi_resid > ucmd->uscsi_buflen) {
7537c478bd9Sstevel@tonic-gate /*
7547c478bd9Sstevel@tonic-gate * Invalid resid value. return error.
7557c478bd9Sstevel@tonic-gate */
7567c478bd9Sstevel@tonic-gate errno = EINVAL;
7577c478bd9Sstevel@tonic-gate goto error;
7587c478bd9Sstevel@tonic-gate }
7597c478bd9Sstevel@tonic-gate if (ucmd->uscsi_flags & USCSI_READ) {
7607c478bd9Sstevel@tonic-gate (void) memcpy(ucmd->uscsi_bufaddr,
761*100ea781SToomas Soome handle->sm_buf, ucmd->uscsi_buflen - ucmd->uscsi_resid);
7627c478bd9Sstevel@tonic-gate }
7637c478bd9Sstevel@tonic-gate (void) mutex_unlock(&handle->sm_bufmutex);
7647c478bd9Sstevel@tonic-gate #ifdef DEBUG
7657c478bd9Sstevel@tonic-gate if (retuscsi_cmd->uscsi_retval || ucmd->uscsi_status)
7667c478bd9Sstevel@tonic-gate DPRINTF2("Error in uscsi_cmd: retval=0x%x uscsi_status=0x%x\n",
7677c478bd9Sstevel@tonic-gate retuscsi_cmd->uscsi_retval, ucmd->uscsi_status);
7687c478bd9Sstevel@tonic-gate #endif
7697c478bd9Sstevel@tonic-gate return (retuscsi_cmd->uscsi_retval);
7707c478bd9Sstevel@tonic-gate error:
7717c478bd9Sstevel@tonic-gate (void) mutex_unlock(&handle->sm_bufmutex);
7727c478bd9Sstevel@tonic-gate return (-1);
7737c478bd9Sstevel@tonic-gate }
7747c478bd9Sstevel@tonic-gate
7757c478bd9Sstevel@tonic-gate int32_t
remap_shared_buf(rmedia_handle_t * handle,size_t buf_size,char * buffer)7767c478bd9Sstevel@tonic-gate remap_shared_buf(rmedia_handle_t *handle, size_t buf_size, char *buffer)
7777c478bd9Sstevel@tonic-gate {
7787c478bd9Sstevel@tonic-gate char rbuf[sizeof (smedia_services_t) + sizeof (door_desc_t)];
7797c478bd9Sstevel@tonic-gate char fname[128];
7807c478bd9Sstevel@tonic-gate smedia_reqset_shfd_t reqset_shfd;
7817c478bd9Sstevel@tonic-gate smedia_reterror_t *reterror;
7827c478bd9Sstevel@tonic-gate int ret_val, fd;
7837c478bd9Sstevel@tonic-gate door_arg_t door_args;
7847c478bd9Sstevel@tonic-gate door_desc_t ddesc[2];
7857c478bd9Sstevel@tonic-gate char *fbuf;
7867c478bd9Sstevel@tonic-gate size_t shared_bufsize;
7877c478bd9Sstevel@tonic-gate off_t file_size, ret;
7887c478bd9Sstevel@tonic-gate
7897c478bd9Sstevel@tonic-gate if (handle->sm_bufsize >= buf_size)
7907c478bd9Sstevel@tonic-gate return (0);
7917c478bd9Sstevel@tonic-gate shared_bufsize = ((buf_size + BUF_SIZE_MULTIPLE - 1)/BUF_SIZE_MULTIPLE)
7927c478bd9Sstevel@tonic-gate * BUF_SIZE_MULTIPLE;
7937c478bd9Sstevel@tonic-gate if (handle->sm_buffd != -1) {
7947c478bd9Sstevel@tonic-gate /* extend the file and re-map */
7957c478bd9Sstevel@tonic-gate fd = handle->sm_buffd;
7967c478bd9Sstevel@tonic-gate ret_val = munmap(handle->sm_buf, handle->sm_bufsize);
7977c478bd9Sstevel@tonic-gate if (ret_val != 0) {
7987c478bd9Sstevel@tonic-gate DPRINTF1("remap:munmap failed. errno = 0x%x\n", errno);
7997c478bd9Sstevel@tonic-gate (void) close(fd);
8007c478bd9Sstevel@tonic-gate handle->sm_buf = NULL;
8017c478bd9Sstevel@tonic-gate handle->sm_bufsize = 0;
8027c478bd9Sstevel@tonic-gate handle->sm_buffd = -1;
8037c478bd9Sstevel@tonic-gate return (errno);
8047c478bd9Sstevel@tonic-gate }
8057c478bd9Sstevel@tonic-gate file_size = lseek(fd, 0, SEEK_END);
8067c478bd9Sstevel@tonic-gate if (file_size == -1) {
8077c478bd9Sstevel@tonic-gate DPRINTF1("remap:lseek failed. errno = 0x%x\n", errno);
8087c478bd9Sstevel@tonic-gate return (errno);
8097c478bd9Sstevel@tonic-gate }
8107c478bd9Sstevel@tonic-gate handle->sm_buf = NULL;
8117c478bd9Sstevel@tonic-gate handle->sm_bufsize = 0;
8127c478bd9Sstevel@tonic-gate handle->sm_buffd = -1;
8137c478bd9Sstevel@tonic-gate } else {
8147c478bd9Sstevel@tonic-gate /* create a new file and mapping */
8157c478bd9Sstevel@tonic-gate (void) sprintf(fname, "/tmp/libsmedia_mmaped_file_XXXXXX");
8167c478bd9Sstevel@tonic-gate fd = mkstemp(fname);
8177c478bd9Sstevel@tonic-gate if (fd == -1) {
8187c478bd9Sstevel@tonic-gate DPRINTF1("remap:mktemp failed. errno = 0x%x\n", errno);
8197c478bd9Sstevel@tonic-gate return (errno);
8207c478bd9Sstevel@tonic-gate }
8217c478bd9Sstevel@tonic-gate ret_val = unlink(fname);
8227c478bd9Sstevel@tonic-gate if (ret_val == -1) {
8237c478bd9Sstevel@tonic-gate DPRINTF1("remap:unlink failed. errno = 0x%x\n", errno);
8247c478bd9Sstevel@tonic-gate (void) close(fd);
8257c478bd9Sstevel@tonic-gate return (errno);
8267c478bd9Sstevel@tonic-gate }
8277c478bd9Sstevel@tonic-gate file_size = 0;
8287c478bd9Sstevel@tonic-gate }
8297c478bd9Sstevel@tonic-gate /* Need to start at the beginning of the file when enlarging */
8307c478bd9Sstevel@tonic-gate ret = lseek(fd, 0, SEEK_SET);
8317c478bd9Sstevel@tonic-gate if (ret == -1) {
8327c478bd9Sstevel@tonic-gate DPRINTF1("remap:lseek failed. errno = 0x%x\n", errno);
8337c478bd9Sstevel@tonic-gate return (errno);
8347c478bd9Sstevel@tonic-gate }
8357c478bd9Sstevel@tonic-gate while (file_size < shared_bufsize) {
8367c478bd9Sstevel@tonic-gate ret_val = write(fd, buffer, buf_size);
8377c478bd9Sstevel@tonic-gate if (ret_val != buf_size) {
8387c478bd9Sstevel@tonic-gate DPRINTF1("remap:write failed. errno = 0x%x\n", errno);
8397c478bd9Sstevel@tonic-gate (void) close(fd);
8407c478bd9Sstevel@tonic-gate return (errno);
8417c478bd9Sstevel@tonic-gate }
8427c478bd9Sstevel@tonic-gate file_size += buf_size;
8437c478bd9Sstevel@tonic-gate }
844*100ea781SToomas Soome fbuf = mmap(NULL, shared_bufsize, PROT_READ | PROT_WRITE,
8457c478bd9Sstevel@tonic-gate MAP_SHARED, fd, 0);
8467c478bd9Sstevel@tonic-gate if (fbuf == (char *)-1) {
8477c478bd9Sstevel@tonic-gate perror("mmap failed");
8487c478bd9Sstevel@tonic-gate (void) close(fd);
8497c478bd9Sstevel@tonic-gate return (errno);
8507c478bd9Sstevel@tonic-gate }
8517c478bd9Sstevel@tonic-gate
8527c478bd9Sstevel@tonic-gate reqset_shfd.cnum = SMEDIA_CNUM_SET_SHFD;
8537c478bd9Sstevel@tonic-gate reqset_shfd.fdbuf_len = shared_bufsize;
8547c478bd9Sstevel@tonic-gate ddesc[0].d_data.d_desc.d_descriptor = fd;
8557c478bd9Sstevel@tonic-gate ddesc[0].d_attributes = DOOR_DESCRIPTOR;
8567c478bd9Sstevel@tonic-gate door_args.data_ptr = (char *)&reqset_shfd;
8577c478bd9Sstevel@tonic-gate door_args.data_size = sizeof (reqset_shfd);
8587c478bd9Sstevel@tonic-gate door_args.desc_ptr = &ddesc[0];
8597c478bd9Sstevel@tonic-gate door_args.desc_num = 1;
8607c478bd9Sstevel@tonic-gate door_args.rbuf = rbuf;
8617c478bd9Sstevel@tonic-gate door_args.rsize = sizeof (rbuf);
8627c478bd9Sstevel@tonic-gate
8637c478bd9Sstevel@tonic-gate ret_val = door_call(handle->sm_door, &door_args);
8647c478bd9Sstevel@tonic-gate if (ret_val < 0) {
8657c478bd9Sstevel@tonic-gate perror("door_call");
8667c478bd9Sstevel@tonic-gate (void) close(fd);
8677c478bd9Sstevel@tonic-gate return (-1);
8687c478bd9Sstevel@tonic-gate }
8697c478bd9Sstevel@tonic-gate reterror = (smedia_reterror_t *)((void *)door_args.data_ptr);
8707c478bd9Sstevel@tonic-gate if (reterror->cnum == SMEDIA_CNUM_ERROR) {
8717c478bd9Sstevel@tonic-gate DPRINTF1("Error in set shfd. errnum = 0x%x\n",
8727c478bd9Sstevel@tonic-gate reterror->errnum);
8737c478bd9Sstevel@tonic-gate errno = reterror->errnum;
8747c478bd9Sstevel@tonic-gate (void) close(fd);
8757c478bd9Sstevel@tonic-gate return (errno);
8767c478bd9Sstevel@tonic-gate }
8777c478bd9Sstevel@tonic-gate handle->sm_buffd = fd;
8787c478bd9Sstevel@tonic-gate handle->sm_buf = fbuf;
8797c478bd9Sstevel@tonic-gate handle->sm_bufsize = shared_bufsize;
8807c478bd9Sstevel@tonic-gate DPRINTF("Returned successful from remap shared buf routine.\n");
8817c478bd9Sstevel@tonic-gate return (0);
8827c478bd9Sstevel@tonic-gate }
883