13f7d54a6SGarrett D'Amore /*
23f7d54a6SGarrett D'Amore  * CDDL HEADER START
33f7d54a6SGarrett D'Amore  *
43f7d54a6SGarrett D'Amore  * The contents of this file are subject to the terms of the
53f7d54a6SGarrett D'Amore  * Common Development and Distribution License (the "License").
63f7d54a6SGarrett D'Amore  * You may not use this file except in compliance with the License.
73f7d54a6SGarrett D'Amore  *
83f7d54a6SGarrett D'Amore  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
93f7d54a6SGarrett D'Amore  * or http://www.opensolaris.org/os/licensing.
103f7d54a6SGarrett D'Amore  * See the License for the specific language governing permissions
113f7d54a6SGarrett D'Amore  * and limitations under the License.
123f7d54a6SGarrett D'Amore  *
133f7d54a6SGarrett D'Amore  * When distributing Covered Code, include this CDDL HEADER in each
143f7d54a6SGarrett D'Amore  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
153f7d54a6SGarrett D'Amore  * If applicable, add the following below this CDDL HEADER, with the
163f7d54a6SGarrett D'Amore  * fields enclosed by brackets "[]" replaced with your own identifying
173f7d54a6SGarrett D'Amore  * information: Portions Copyright [yyyy] [name of copyright owner]
183f7d54a6SGarrett D'Amore  *
193f7d54a6SGarrett D'Amore  * CDDL HEADER END
203f7d54a6SGarrett D'Amore  */
213f7d54a6SGarrett D'Amore /*
223f7d54a6SGarrett D'Amore  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
233f7d54a6SGarrett D'Amore  */
243f7d54a6SGarrett D'Amore 
253f7d54a6SGarrett D'Amore /*
263f7d54a6SGarrett D'Amore  * b_generic.c :
273f7d54a6SGarrett D'Amore  *      This file contains the functions for generic block devices
28*430062b0SToomas Soome  *	for libsmedia.
293f7d54a6SGarrett D'Amore  */
303f7d54a6SGarrett D'Amore 
313f7d54a6SGarrett D'Amore #include <stdio.h>
323f7d54a6SGarrett D'Amore #include <unistd.h>
333f7d54a6SGarrett D'Amore #include <locale.h>
343f7d54a6SGarrett D'Amore #include <sys/types.h>
353f7d54a6SGarrett D'Amore #include <sys/param.h>
363f7d54a6SGarrett D'Amore #include <sys/dkio.h>
373f7d54a6SGarrett D'Amore #include <string.h>
383f7d54a6SGarrett D'Amore #include "../../../library/inc/smedia.h"
393f7d54a6SGarrett D'Amore #include "../../../library/inc/rmedia.h"
403f7d54a6SGarrett D'Amore #include "../../../library/common/l_defines.h"
413f7d54a6SGarrett D'Amore 
423f7d54a6SGarrett D'Amore #define	PERROR(string)	my_perror(gettext(string))
433f7d54a6SGarrett D'Amore 
443f7d54a6SGarrett D'Amore static void
my_perror(char * err_string)453f7d54a6SGarrett D'Amore my_perror(char *err_string)
463f7d54a6SGarrett D'Amore {
473f7d54a6SGarrett D'Amore 
483f7d54a6SGarrett D'Amore 	int error_no;
493f7d54a6SGarrett D'Amore 	if (errno == 0)
503f7d54a6SGarrett D'Amore 		return;
513f7d54a6SGarrett D'Amore 
523f7d54a6SGarrett D'Amore 	error_no = errno;
533f7d54a6SGarrett D'Amore 	(void) fprintf(stderr, gettext(err_string));
543f7d54a6SGarrett D'Amore 	(void) fprintf(stderr, gettext(" : "));
553f7d54a6SGarrett D'Amore 	errno = error_no;
563f7d54a6SGarrett D'Amore 	perror("");
573f7d54a6SGarrett D'Amore }
583f7d54a6SGarrett D'Amore 
593f7d54a6SGarrett D'Amore int32_t
_m_version_no(void)603f7d54a6SGarrett D'Amore _m_version_no(void)
613f7d54a6SGarrett D'Amore {
623f7d54a6SGarrett D'Amore 	return (SM_BLKDEV_VERSION_1);
633f7d54a6SGarrett D'Amore }
643f7d54a6SGarrett D'Amore 
653f7d54a6SGarrett D'Amore int32_t
_m_device_type(ushort_t ctype,ushort_t mtype)663f7d54a6SGarrett D'Amore _m_device_type(ushort_t ctype, ushort_t mtype)
673f7d54a6SGarrett D'Amore {
683f7d54a6SGarrett D'Amore 	if (ctype == DKC_BLKDEV) {
693f7d54a6SGarrett D'Amore 		if (mtype == 0)
703f7d54a6SGarrett D'Amore 			return (0);
713f7d54a6SGarrett D'Amore 	}
723f7d54a6SGarrett D'Amore 	return (-1);
733f7d54a6SGarrett D'Amore }
743f7d54a6SGarrett D'Amore 
753f7d54a6SGarrett D'Amore 
763f7d54a6SGarrett D'Amore int32_t
_m_get_media_info(rmedia_handle_t * handle,void * ip)773f7d54a6SGarrett D'Amore _m_get_media_info(rmedia_handle_t *handle, void *ip)
783f7d54a6SGarrett D'Amore {
793f7d54a6SGarrett D'Amore 	smmedium_prop_t *mp = (smmedium_prop_t *)ip;
803f7d54a6SGarrett D'Amore 	struct dk_geom		dkg;
813f7d54a6SGarrett D'Amore 	struct dk_minfo		minfo;
823f7d54a6SGarrett D'Amore 	enum dkio_state		state = DKIO_NONE;
833f7d54a6SGarrett D'Amore 	int			ret_val;
843f7d54a6SGarrett D'Amore 
853f7d54a6SGarrett D'Amore 	if (handle == NULL) {
863f7d54a6SGarrett D'Amore 		DPRINTF("Null Handle\n");
873f7d54a6SGarrett D'Amore 		errno = EINVAL;
883f7d54a6SGarrett D'Amore 		return (-1);
893f7d54a6SGarrett D'Amore 	}
903f7d54a6SGarrett D'Amore 	if (handle->sm_signature != (int32_t)LIBSMEDIA_SIGNATURE) {
913f7d54a6SGarrett D'Amore 		DPRINTF2("Signature expected=0x%x, found=0x%x\n",
923f7d54a6SGarrett D'Amore 		    LIBSMEDIA_SIGNATURE, handle->sm_signature);
933f7d54a6SGarrett D'Amore 		errno = EINVAL;
943f7d54a6SGarrett D'Amore 		return (-1);
953f7d54a6SGarrett D'Amore 	}
963f7d54a6SGarrett D'Amore 
973f7d54a6SGarrett D'Amore 	if (ioctl(handle->sm_fd, DKIOCSTATE, &state) < 0) {
983f7d54a6SGarrett D'Amore 		PERROR("DKIOCSTATE failed");
993f7d54a6SGarrett D'Amore 		return (-1);
1003f7d54a6SGarrett D'Amore 	}
1013f7d54a6SGarrett D'Amore 
1023f7d54a6SGarrett D'Amore 	if (state != DKIO_INSERTED) {
1033f7d54a6SGarrett D'Amore 		DPRINTF("No media.\n");
1043f7d54a6SGarrett D'Amore 		mp->sm_media_type = SM_NOT_PRESENT;
1053f7d54a6SGarrett D'Amore 		mp->sm_version = SMMEDIA_PROP_V_1;
1063f7d54a6SGarrett D'Amore 		return (0);
1073f7d54a6SGarrett D'Amore 
1083f7d54a6SGarrett D'Amore 	}
1093f7d54a6SGarrett D'Amore 
1103f7d54a6SGarrett D'Amore 	ret_val = ioctl(handle->sm_fd, DKIOCGMEDIAINFO, &minfo);
1113f7d54a6SGarrett D'Amore 	if (ret_val < 0) {
1123f7d54a6SGarrett D'Amore 		DPRINTF("DKIOCGMEDIAINFO ioctl failed");
1133f7d54a6SGarrett D'Amore 		return (ret_val);
1143f7d54a6SGarrett D'Amore 	}
1153f7d54a6SGarrett D'Amore 	ret_val = ioctl(handle->sm_fd, DKIOCGGEOM, &dkg);
1163f7d54a6SGarrett D'Amore 	if (ret_val < 0) {
1173f7d54a6SGarrett D'Amore 		DPRINTF("DKIOCGGEOM ioctl failed");
1183f7d54a6SGarrett D'Amore 		return (ret_val);
1193f7d54a6SGarrett D'Amore 	}
1203f7d54a6SGarrett D'Amore 
1213f7d54a6SGarrett D'Amore 	mp->sm_media_type = SM_BLOCK;
1223f7d54a6SGarrett D'Amore 	mp->sm_blocksize = minfo.dki_lbsize;
1233f7d54a6SGarrett D'Amore 	mp->sm_capacity = minfo.dki_capacity;
1243f7d54a6SGarrett D'Amore 	mp->sm_pcyl = dkg.dkg_pcyl;
1253f7d54a6SGarrett D'Amore 	mp->sm_nhead = dkg.dkg_nhead;
1263f7d54a6SGarrett D'Amore 	mp->sm_nsect = dkg.dkg_nsect;
1273f7d54a6SGarrett D'Amore 	return (0);
1283f7d54a6SGarrett D'Amore }
1293f7d54a6SGarrett D'Amore 
1303f7d54a6SGarrett D'Amore 
1313f7d54a6SGarrett D'Amore 
1323f7d54a6SGarrett D'Amore /* ARGSUSED0 */
1333f7d54a6SGarrett D'Amore 
1343f7d54a6SGarrett D'Amore int32_t
_m_get_device_info(rmedia_handle_t * handle,void * ip)1353f7d54a6SGarrett D'Amore _m_get_device_info(rmedia_handle_t *handle, void *ip)
1363f7d54a6SGarrett D'Amore {
1373f7d54a6SGarrett D'Amore 	smdevice_info_t *mp = (smdevice_info_t *)ip;
1383f7d54a6SGarrett D'Amore 	char *vendor_name, *product_name, *fw_version;
1393f7d54a6SGarrett D'Amore 
1403f7d54a6SGarrett D'Amore 	if (handle == NULL) {
1413f7d54a6SGarrett D'Amore 		DPRINTF("Null Handle\n");
1423f7d54a6SGarrett D'Amore 		errno = EINVAL;
1433f7d54a6SGarrett D'Amore 		return (-1);
1443f7d54a6SGarrett D'Amore 	}
1453f7d54a6SGarrett D'Amore 	if (handle->sm_signature != (int32_t)LIBSMEDIA_SIGNATURE) {
1463f7d54a6SGarrett D'Amore 		DPRINTF2("Signature expected=0x%x, found=0x%x\n",
1473f7d54a6SGarrett D'Amore 		    LIBSMEDIA_SIGNATURE, handle->sm_signature);
1483f7d54a6SGarrett D'Amore 		errno = EINVAL;
1493f7d54a6SGarrett D'Amore 		return (-1);
1503f7d54a6SGarrett D'Amore 	}
1513f7d54a6SGarrett D'Amore 	vendor_name = (char *)malloc(1);
1523f7d54a6SGarrett D'Amore 	if (vendor_name == NULL) {
153*430062b0SToomas Soome 		if (!errno)
154*430062b0SToomas Soome 			errno = ENOMEM;
1553f7d54a6SGarrett D'Amore 		return (-1);
1563f7d54a6SGarrett D'Amore 	}
1573f7d54a6SGarrett D'Amore 	product_name = (char *)malloc(1);
1583f7d54a6SGarrett D'Amore 	if (product_name == NULL) {
1593f7d54a6SGarrett D'Amore 		free(vendor_name);
1603f7d54a6SGarrett D'Amore 		if (!errno)
1613f7d54a6SGarrett D'Amore 			errno = ENOMEM;
1623f7d54a6SGarrett D'Amore 		return (-1);
1633f7d54a6SGarrett D'Amore 	}
1643f7d54a6SGarrett D'Amore 
1653f7d54a6SGarrett D'Amore 	fw_version = (char *)malloc(1);
1663f7d54a6SGarrett D'Amore 	if (fw_version == NULL) {
1673f7d54a6SGarrett D'Amore 		free(vendor_name);
1683f7d54a6SGarrett D'Amore 		free(product_name);
1693f7d54a6SGarrett D'Amore 			if (!errno)
1703f7d54a6SGarrett D'Amore 		errno = ENOMEM;
1713f7d54a6SGarrett D'Amore 		return (-1);
1723f7d54a6SGarrett D'Amore 	}
1733f7d54a6SGarrett D'Amore 
1743f7d54a6SGarrett D'Amore 	/* Note: we could potentially offer more here */
1753f7d54a6SGarrett D'Amore 	vendor_name[0] = 0;
1763f7d54a6SGarrett D'Amore 	product_name[0] = 0;
1773f7d54a6SGarrett D'Amore 	fw_version[0] = 0;
1783f7d54a6SGarrett D'Amore 	mp->sm_interface_type = IF_BLOCK;
1793f7d54a6SGarrett D'Amore 	mp->sm_vendor_name = vendor_name;
1803f7d54a6SGarrett D'Amore 	mp->sm_product_name = product_name;
1813f7d54a6SGarrett D'Amore 	mp->sm_firmware_version = fw_version;
1823f7d54a6SGarrett D'Amore 	return (0);
1833f7d54a6SGarrett D'Amore }
1843f7d54a6SGarrett D'Amore 
1853f7d54a6SGarrett D'Amore int32_t
_m_free_device_info(rmedia_handle_t * handle,void * ip)1863f7d54a6SGarrett D'Amore _m_free_device_info(rmedia_handle_t *handle, void *ip)
1873f7d54a6SGarrett D'Amore {
1883f7d54a6SGarrett D'Amore 	struct smdevice_info *dev_info = ip;
1893f7d54a6SGarrett D'Amore 
1903f7d54a6SGarrett D'Amore 	/* Check for valid handle */
1913f7d54a6SGarrett D'Amore 	if (handle == NULL) {
1923f7d54a6SGarrett D'Amore 		DPRINTF("Null Handle\n");
1933f7d54a6SGarrett D'Amore 		errno = EINVAL;
1943f7d54a6SGarrett D'Amore 		return (-1);
1953f7d54a6SGarrett D'Amore 	}
1963f7d54a6SGarrett D'Amore 	if (handle->sm_signature != LIBSMEDIA_SIGNATURE) {
1973f7d54a6SGarrett D'Amore 		DPRINTF("Invalid signature in handle.\n");
1983f7d54a6SGarrett D'Amore 		errno = EINVAL;
1993f7d54a6SGarrett D'Amore 		return (-1);
2003f7d54a6SGarrett D'Amore 	}
2013f7d54a6SGarrett D'Amore 
2023f7d54a6SGarrett D'Amore 	free(dev_info->sm_vendor_name);
2033f7d54a6SGarrett D'Amore 	free(dev_info->sm_product_name);
2043f7d54a6SGarrett D'Amore 	free(dev_info->sm_firmware_version);
2053f7d54a6SGarrett D'Amore 	return (0);
2063f7d54a6SGarrett D'Amore }
207