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