1 /* @(#)acb4000.c	1.26 09/07/13 Copyright 1989-2009 J. Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static	UConst char sccsid[] =
5 	"@(#)acb4000.c	1.26 09/07/13 Copyright 1989-2009 J. Schilling";
6 #endif
7 /*
8  *	Routines for ADAPTEC 40xx & 5000 series.
9  *
10  *	Copyright (c) 1989-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/param.h>	/* Include various defs needed with some OS */
28 #include <schily/standard.h>
29 #include <schily/schily.h>
30 
31 #include <scg/scgcmd.h>
32 #include <scg/scsireg.h>
33 #include <scg/scsidefs.h>
34 #include <scg/scsitransp.h>
35 
36 #include "scsicmds.h"
37 #include "fmt.h"
38 
39 EXPORT	int	acbdev 			__PR((SCSI *scgp));
40 EXPORT	BOOL	get_acb4000defaults	__PR((SCSI *scgp, struct disk *));
41 EXPORT	BOOL	set_acb4000params	__PR((SCSI *scgp, struct disk *));
42 
43 EXPORT int
acbdev(scgp)44 acbdev(scgp)
45 	SCSI	*scgp;
46 {
47 	struct scsi_mode_data	md;
48 	long	blocksize;
49 	long	sectorcnt;
50 
51 	fillbytes((caddr_t)&md, sizeof (md), '\0');
52 
53 	if (mode_sense(scgp, (u_char *)&md, 24, 0, 0) < 0)
54 		return (scgp->dev);
55 
56 	blocksize = a_to_u_3_byte(md.blockdesc.lblen);
57 	sectorcnt = md.pagex.acb.sect_per_trk;
58 if (scgp->silent < 2)
59 printf("blocksize: %ld sectorcnt: %ld\n", blocksize, sectorcnt);
60 
61 	/*
62 	 * Wenn 'blocksize' und 'sectorcnt'
63 	 * auf ihren Defaultwerten sind, dann l��t sich der
64 	 * Typ des Kontrollers nicht bestimmen.
65 	 */
66 	if (blocksize == 256 && sectorcnt == 32)
67 		return (scgp->dev);
68 
69 	if (blocksize * sectorcnt > 10416) /* 5MB/s / 60rps / 8bit/Byte */
70 		return (DEV_ACB4070);
71 
72 	if (md.pagex.acb.hard_sec && (scgp->dev == DEV_ACB40X0 || scgp->dev == DEV_ACB4000))
73 		return (DEV_ACB4010);
74 
75 	return (DEV_ACB4000);
76 }
77 
78 EXPORT BOOL
get_acb4000defaults(scgp,dp)79 get_acb4000defaults(scgp, dp)
80 	SCSI		*scgp;
81 	struct disk	*dp;
82 {
83 	struct scsi_mode_data	md;
84 	long	tmp;
85 
86 	fillbytes((caddr_t)&md, sizeof (md), '\0');
87 
88 	(void) test_unit_ready(scgp);
89 	if (mode_sense(scgp, (u_char *)&md, 24, 0, 0) < 0)
90 		return (FALSE);
91 
92 	tmp = a_to_u_3_byte(md.blockdesc.lblen);
93 	if (dp->secsize < 0 && tmp != 0)
94 		dp->secsize = tmp;
95 
96 	tmp = a_to_u_2_byte(md.pagex.acb.ncyl);
97 	if (dp->pcyl < 0 && tmp != 0)
98 		dp->pcyl = tmp;
99 	if (dp->lpcyl < 0 && tmp != 0)
100 		dp->lpcyl = tmp;
101 
102 	tmp = md.pagex.acb.nhead;
103 	if (dp->nhead < 0 && tmp != 0)
104 		dp->nhead = tmp;
105 
106 	tmp = a_to_u_2_byte(md.pagex.acb.start_red_wcurrent);
107 	if (dp->reduced_curr < 0 && tmp != 0)
108 		dp->reduced_curr = tmp;
109 
110 	tmp = a_to_u_2_byte(md.pagex.acb.start_precomp);
111 	if (dp->write_precomp < 0 && tmp != 0)
112 		dp->write_precomp = tmp;
113 
114 	tmp = md.pagex.acb.step_rate;
115 	if (dp->step_rate < 0 && tmp != 0)
116 		dp->step_rate = tmp;
117 
118 	tmp = md.pagex.acb.sect_per_trk;
119 	if (dp->spt < 0 && tmp != 0)
120 		dp->spt = tmp;
121 
122 	return (TRUE);
123 }
124 
125 EXPORT BOOL
set_acb4000params(scgp,dp)126 set_acb4000params(scgp, dp)
127 	SCSI		*scgp;
128 	struct disk	*dp;
129 {
130 	struct scsi_mode_data	md;
131 	int	mode_len = 24;
132 
133 	fillbytes((caddr_t)&md, sizeof (md), '\0');
134 
135 	(void) test_unit_ready(scgp);
136 	if (mode_sense(scgp, (u_char *)&md, mode_len, 0, 0) < 0)
137 		return (FALSE);
138 
139 	i_to_3_byte(md.blockdesc.nlblock, 0);
140 	i_to_3_byte(md.blockdesc.lblen, dp->secsize);
141 /*#ifdef	notneeded*/
142 	/*
143 	 * Listformat mu� laut Handbuch bei softsektorierten Festplatten
144 	 * auf '1', in allen anderen F�llen auf '2' gesetzt werden.
145 	 *
146 	 * Es scheint aber nur die Anzahl der Bytes zu steuern, die bei
147 	 * einem MODE_SELECT entgegengenommen werden.
148 	 * Da wir �ber die korrekten Daten von MODE_SENSE verf�gen,
149 	 * k�nnen wir auf diese Unterscheidung verzichten.
150 	 */
151 	if (md.pagex.acb.fixed_media == 1 && md.pagex.acb.hard_sec == 0) {
152 		md.pagex.acb.listformat = 1;
153 		mode_len = 22;
154 	} else {
155 		md.pagex.acb.listformat = 2;
156 	}
157 /*#endif*/
158 	i_to_2_byte(md.pagex.acb.ncyl, dp->pcyl);
159 	md.pagex.acb.nhead = dp->nhead;
160 	i_to_2_byte(md.pagex.acb.start_red_wcurrent, dp->reduced_curr);
161 	i_to_2_byte(md.pagex.acb.start_precomp, dp->write_precomp);
162 	md.pagex.acb.landing_zone = 0;
163 	md.pagex.acb.step_rate = dp->step_rate;
164 	md.pagex.acb.sect_per_trk = dp->spt;
165 
166 	if (mode_select(scgp, (u_char *)&md, mode_len, 0, 0) < 0)
167 		return (FALSE);
168 	return (TRUE);
169 }
170