1 /* @(#)readcap.c	1.158 09/07/10 Copyright 1995-2009 J. Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static	UConst char sccsid[] =
5 	"@(#)readcap.c	1.158 09/07/10 Copyright 1995-2009 J. Schilling";
6 #endif
7 /*
8  *	SCSI command functions for read capacity
9  *
10  *	Copyright (c) 1995-2009 J. Schilling
11  */
12 /*
13  * The contents of this file are subject to the terms of the
14  * Common Development and Distribution License, Version 1.0 only
15  * (the "License").  You may not use this file except in compliance
16  * with the License.
17  *
18  * See the file CDDL.Schily.txt in this distribution for details.
19  * A copy of the CDDL is also available via the Internet at
20  * http://www.opensource.org/licenses/cddl1.txt
21  *
22  * When distributing Covered Code, include this CDDL HEADER in each
23  * file and include the License file CDDL.Schily.txt from this distribution.
24  */
25 
26 #include <schily/stdio.h>
27 #include <schily/standard.h>
28 
29 #include <schily/utypes.h>
30 #include <schily/btorder.h>
31 #include <schily/intcvt.h>
32 #include <schily/schily.h>
33 
34 #include <scg/scgcmd.h>
35 #include <scg/scsidefs.h>
36 #include <scg/scsireg.h>
37 #include <scg/scsitransp.h>
38 
39 #include "libscgcmd.h"
40 
41 EXPORT	int	read_capacity	__PR((SCSI *scgp));
42 EXPORT	void	print_capacity	__PR((SCSI *scgp, FILE *f));
43 
44 
45 EXPORT int
read_capacity(scgp)46 read_capacity(scgp)
47 	SCSI	*scgp;
48 {
49 	register struct	scg_cmd	*scmd = scgp->scmd;
50 
51 	fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
52 	scmd->addr = (caddr_t)scgp->cap;
53 	scmd->size = sizeof (struct scsi_capacity);
54 	scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;
55 	scmd->cdb_len = SC_G1_CDBLEN;
56 	scmd->sense_len = CCS_SENSE_LEN;
57 	scmd->cdb.g1_cdb.cmd = 0x25;	/* Read Capacity */
58 	scmd->cdb.g1_cdb.lun = scg_lun(scgp);
59 	g1_cdblen(&scmd->cdb.g1_cdb, 0); /* Full Media */
60 
61 	scgp->cmdname = "read capacity";
62 
63 	if (scg_cmd(scgp) < 0) {
64 		return (-1);
65 	} else {
66 		long	cbsize;
67 		long	cbaddr;
68 
69 		/*
70 		 * c_bsize & c_baddr are signed Int32_t
71 		 * so we use signed int conversion here.
72 		 */
73 		cbsize = a_to_4_byte(&scgp->cap->c_bsize);
74 		cbaddr = a_to_4_byte(&scgp->cap->c_baddr);
75 		scgp->cap->c_bsize = cbsize;
76 		scgp->cap->c_baddr = cbaddr;
77 	}
78 	return (0);
79 }
80 
81 EXPORT void
print_capacity(scgp,f)82 print_capacity(scgp, f)
83 	SCSI	*scgp;
84 	FILE	*f;
85 {
86 	long	kb;
87 	long	mb;
88 	long	prmb;
89 	double	dkb;
90 
91 	dkb =  (scgp->cap->c_baddr+1.0) * (scgp->cap->c_bsize/1024.0);
92 	kb = dkb;
93 	mb = dkb / 1024.0;
94 	prmb = dkb / 1000.0 * 1.024;
95 	fprintf(f, "Capacity: %ld Blocks = %ld kBytes = %ld MBytes = %ld prMB\n",
96 		(long)scgp->cap->c_baddr+1, kb, mb, prmb);
97 	fprintf(f, "Sectorsize: %ld Bytes\n", (long)scgp->cap->c_bsize);
98 }
99