Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(7)

Delta Between Two Patch Sets: safte.c

Issue 4279046: SCSI DMA correctness
Left Patch Set: diff #2 Created 14 years ago
Right Patch Set: diff #7 Created 14 years ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « ch.c ('k') | scsi_base.c » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 /* $OpenBSD: safte.c,v 1.46 2010/09/27 19:49:43 thib Exp $ */ 1 /* $OpenBSD: safte.c,v 1.46 2010/09/27 19:49:43 thib Exp $ */
2 2
3 /* 3 /*
4 * Copyright (c) 2005 David Gwynne <dlg@openbsd.org> 4 * Copyright (c) 2005 David Gwynne <dlg@openbsd.org>
5 * 5 *
6 * Permission to use, copy, modify, and distribute this software for any 6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above 7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies. 8 * copyright notice and this permission notice appear in all copies.
9 * 9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */ 17 */
18 18
19 #include "bio.h" 19 #include "bio.h"
20 20
21 #include <sys/param.h> 21 #include <sys/param.h>
22 #include <sys/systm.h> 22 #include <sys/systm.h>
23 #include <sys/device.h> 23 #include <sys/device.h>
24 #include <sys/scsiio.h> 24 #include <sys/scsiio.h>
25 #include <sys/malloc.h> 25 #include <sys/malloc.h>
26 #include <sys/pool.h>
26 #include <sys/proc.h> 27 #include <sys/proc.h>
27 #include <sys/rwlock.h> 28 #include <sys/rwlock.h>
28 #include <sys/queue.h> 29 #include <sys/queue.h>
29 #include <sys/sensors.h> 30 #include <sys/sensors.h>
30 31
31 #if NBIO > 0 32 #if NBIO > 0
32 #include <dev/biovar.h> 33 #include <dev/biovar.h>
33 #endif 34 #endif
34 35
35 #include <scsi/scsi_all.h> 36 #include <scsi/scsi_all.h>
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 safte_match(struct device *parent, void *match, void *aux) 110 safte_match(struct device *parent, void *match, void *aux)
110 { 111 {
111 struct scsi_inquiry_data *inqbuf; 112 struct scsi_inquiry_data *inqbuf;
112 struct scsi_attach_args *sa = aux; 113 struct scsi_attach_args *sa = aux;
113 struct scsi_inquiry_data *inq = sa->sa_inqbuf; 114 struct scsi_inquiry_data *inq = sa->sa_inqbuf;
114 struct scsi_inquiry *cmd; 115 struct scsi_inquiry *cmd;
115 struct scsi_xfer *xs; 116 struct scsi_xfer *xs;
116 struct safte_inq *si; 117 struct safte_inq *si;
117 int error, flags = 0, length; 118 int error, flags = 0, length;
118 119
119 inqbuf = malloc(sizeof(*inqbuf), M_TEMP, M_WAITOK | M_ZERO);
120 si = (struct safte_inq *)&inqbuf->extra;
121 memset(inqbuf->extra, ' ', sizeof(inqbuf->extra));
122
123 if (inq == NULL) 120 if (inq == NULL)
124 return (0); 121 return (0);
125 122
126 /* match on dell enclosures */ 123 /* match on dell enclosures */
127 if ((inq->device & SID_TYPE) == T_PROCESSOR && 124 if ((inq->device & SID_TYPE) == T_PROCESSOR &&
128 SCSISPC(inq->version) == 3) 125 SCSISPC(inq->version) == 3)
129 return (2); 126 return (2);
130 127
131 » if ((inq->device & SID_TYPE) != T_PROCESSOR || 128 » if ((inq->device & SID_TYPE) != T_PROCESSOR ||
132 SCSISPC(inq->version) != 2 || 129 SCSISPC(inq->version) != 2 ||
133 (inq->response_format & SID_ANSII) != 2) 130 (inq->response_format & SID_ANSII) != 2)
134 return (0); 131 return (0);
135 132
136 length = inq->additional_length + SAFTE_EXTRA_OFFSET; 133 length = inq->additional_length + SAFTE_EXTRA_OFFSET;
137 if (length < SAFTE_INQ_LEN) 134 if (length < SAFTE_INQ_LEN)
138 return (0); 135 return (0);
139 » if (length > sizeof(inqbuf)) 136 » if (length > sizeof(*inqbuf))
140 » » length = sizeof(inqbuf); 137 » » length = sizeof(*inqbuf);
138
139 » inqbuf = dma_alloc(sizeof(*inqbuf), PR_NOWAIT | PR_ZERO);
140 » if (inqbuf == NULL)
141 » » return (0);
142
143 » memset(inqbuf->extra, ' ', sizeof(inqbuf->extra));
141 144
142 if (cold) 145 if (cold)
143 flags |= SCSI_AUTOCONF; 146 flags |= SCSI_AUTOCONF;
144 xs = scsi_xs_get(sa->sa_sc_link, flags | SCSI_DATA_IN); 147 xs = scsi_xs_get(sa->sa_sc_link, flags | SCSI_DATA_IN);
145 if (xs == NULL) 148 if (xs == NULL)
146 return (0); 149 return (0);
147 xs->cmdlen = sizeof(*cmd); 150 xs->cmdlen = sizeof(*cmd);
148 xs->data = (void *)inqbuf; 151 xs->data = (void *)inqbuf;
149 xs->datalen = length; 152 xs->datalen = length;
150 xs->retries = 2; 153 xs->retries = 2;
151 xs->timeout = 10000; 154 xs->timeout = 10000;
152 155
153 cmd = (struct scsi_inquiry *)xs->cmd; 156 cmd = (struct scsi_inquiry *)xs->cmd;
154 cmd->opcode = INQUIRY; 157 cmd->opcode = INQUIRY;
155 _lto2b(length, cmd->length); 158 _lto2b(length, cmd->length);
156 159
157 error = scsi_xs_sync(xs); 160 error = scsi_xs_sync(xs);
158 scsi_xs_put(xs); 161 scsi_xs_put(xs);
159 162
160 if (error) { 163 if (error) {
161 » » free(inqbuf, M_TEMP); 164 » » dma_free(inqbuf, sizeof(*inqbuf));
162 return (0); 165 return (0);
163 } 166 }
164 167
168 si = (struct safte_inq *)&inqbuf->extra;
165 if (memcmp(si->ident, SAFTE_IDENT, sizeof(si->ident)) == 0) { 169 if (memcmp(si->ident, SAFTE_IDENT, sizeof(si->ident)) == 0) {
166 » » free(inqbuf, M_TEMP); 170 » » dma_free(inqbuf, sizeof(*inqbuf));
167 return (2); 171 return (2);
168 } 172 }
169 173
170 » free(inqbuf, M_TEMP); 174 » dma_free(inqbuf, sizeof(*inqbuf));
171 return (0); 175 return (0);
172 } 176 }
173 177
174 void 178 void
175 safte_attach(struct device *parent, struct device *self, void *aux) 179 safte_attach(struct device *parent, struct device *self, void *aux)
176 { 180 {
177 struct safte_softc *sc = (struct safte_softc *)self; 181 struct safte_softc *sc = (struct safte_softc *)self;
178 struct scsi_attach_args *sa = aux; 182 struct scsi_attach_args *sa = aux;
179 int i = 0; 183 int i = 0;
180 184
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 bio_register(self, safte_ioctl) != 0) { 221 bio_register(self, safte_ioctl) != 0) {
218 printf("%s: unable to register ioctl with bio\n", DEVNAME(sc)); 222 printf("%s: unable to register ioctl with bio\n", DEVNAME(sc));
219 sc->sc_nslots = 0; 223 sc->sc_nslots = 0;
220 } else 224 } else
221 i++; 225 i++;
222 #endif 226 #endif
223 227
224 if (i) /* if we're doing something, then preinit encbuf and sensors */ 228 if (i) /* if we're doing something, then preinit encbuf and sensors */
225 safte_read_encstat(sc); 229 safte_read_encstat(sc);
226 else { 230 else {
227 » » free(sc->sc_encbuf, M_DEVBUF); 231 » » dma_free(sc->sc_encbuf, sc->sc_encbuflen);
228 sc->sc_encbuf = NULL; 232 sc->sc_encbuf = NULL;
229 } 233 }
230 } 234 }
231 235
232 int 236 int
233 safte_detach(struct device *self, int flags) 237 safte_detach(struct device *self, int flags)
234 { 238 {
235 struct safte_softc *sc = (struct safte_softc *)self; 239 struct safte_softc *sc = (struct safte_softc *)self;
236 int i; 240 int i;
237 241
238 rw_enter_write(&sc->sc_lock); 242 rw_enter_write(&sc->sc_lock);
239 243
240 #if NBIO > 0 244 #if NBIO > 0
241 if (sc->sc_nslots > 0) 245 if (sc->sc_nslots > 0)
242 bio_unregister(self); 246 bio_unregister(self);
243 #endif 247 #endif
244 248
245 if (sc->sc_nsensors > 0) { 249 if (sc->sc_nsensors > 0) {
246 sensordev_deinstall(&sc->sc_sensordev); 250 sensordev_deinstall(&sc->sc_sensordev);
247 sensor_task_unregister(sc->sc_sensortask); 251 sensor_task_unregister(sc->sc_sensortask);
248 252
249 for (i = 0; i < sc->sc_nsensors; i++) 253 for (i = 0; i < sc->sc_nsensors; i++)
250 sensor_detach(&sc->sc_sensordev,· 254 sensor_detach(&sc->sc_sensordev,·
251 &sc->sc_sensors[i].se_sensor); 255 &sc->sc_sensors[i].se_sensor);
252 free(sc->sc_sensors, M_DEVBUF); 256 free(sc->sc_sensors, M_DEVBUF);
253 } 257 }
254 258
255 if (sc->sc_encbuf != NULL) 259 if (sc->sc_encbuf != NULL)
256 » » free(sc->sc_encbuf, M_DEVBUF); 260 » » dma_free(sc->sc_encbuf, sc->sc_encbuflen);
257 261
258 rw_exit_write(&sc->sc_lock); 262 rw_exit_write(&sc->sc_lock);
259 263
260 return (0); 264 return (0);
261 } 265 }
262 266
263 int 267 int
264 safte_read_config(struct safte_softc *sc) 268 safte_read_config(struct safte_softc *sc)
265 { 269 {
266 » struct safte_config *config; 270 » struct safte_config *config = NULL;
267 struct safte_readbuf_cmd *cmd; 271 struct safte_readbuf_cmd *cmd;
268 struct safte_sensor *s; 272 struct safte_sensor *s;
269 struct scsi_xfer *xs; 273 struct scsi_xfer *xs;
270 » int error, flags = 0, i, j; 274 » int error = 0, flags = 0, i, j;
271 275
272 » config = malloc(sizeof(*config), M_TEMP, M_WAITOK); 276 » config = dma_alloc(sizeof(*config), PR_NOWAIT);
277 » if (config == NULL)
278 » » return (1);
273 279
274 if (cold) 280 if (cold)
275 flags |= SCSI_AUTOCONF; 281 flags |= SCSI_AUTOCONF;
276 xs = scsi_xs_get(sc->sc_link, flags | SCSI_DATA_IN | SCSI_SILENT); 282 xs = scsi_xs_get(sc->sc_link, flags | SCSI_DATA_IN | SCSI_SILENT);
277 » if (xs == NULL) 283 » if (xs == NULL) {
278 » » return (1); 284 » » error = 1;
285 » » goto done;
286 » }
279 xs->cmdlen = sizeof(*cmd); 287 xs->cmdlen = sizeof(*cmd);
280 xs->data = (void *)config; 288 xs->data = (void *)config;
281 xs->datalen = sizeof(*config); 289 xs->datalen = sizeof(*config);
282 xs->retries = 2; 290 xs->retries = 2;
283 xs->timeout = 30000; 291 xs->timeout = 30000;
284 292
285 cmd = (struct safte_readbuf_cmd *)xs->cmd; 293 cmd = (struct safte_readbuf_cmd *)xs->cmd;
286 cmd->opcode = READ_BUFFER; 294 cmd->opcode = READ_BUFFER;
287 cmd->flags |= SAFTE_RD_MODE; 295 cmd->flags |= SAFTE_RD_MODE;
288 cmd->bufferid = SAFTE_RD_CONFIG; 296 cmd->bufferid = SAFTE_RD_CONFIG;
289 cmd->length = htobe16(sizeof(*config)); 297 cmd->length = htobe16(sizeof(*config));
290 298
291 error = scsi_xs_sync(xs); 299 error = scsi_xs_sync(xs);
292 scsi_xs_put(xs); 300 scsi_xs_put(xs);
293 301
294 if (error != 0) { 302 if (error != 0) {
295 » » free(config, M_TEMP); 303 » » error = 1;
296 » » return (1); 304 » » goto done;
297 } 305 }
298 306
299 DPRINTF(("%s: nfans: %d npwrsup: %d nslots: %d doorlock: %d ntemps: %d" 307 DPRINTF(("%s: nfans: %d npwrsup: %d nslots: %d doorlock: %d ntemps: %d"
300 " alarm: %d celsius: %d ntherm: %d\n", DEVNAME(sc), config->nfans, 308 " alarm: %d celsius: %d ntherm: %d\n", DEVNAME(sc), config->nfans,
301 config->npwrsup, config->nslots, config->doorlock, config->ntemps, 309 config->npwrsup, config->nslots, config->doorlock, config->ntemps,
302 config->alarm, SAFTE_CFG_CELSIUS(config->therm), 310 config->alarm, SAFTE_CFG_CELSIUS(config->therm),
303 SAFTE_CFG_NTHERM(config->therm))); 311 SAFTE_CFG_NTHERM(config->therm)));
304 312
305 sc->sc_encbuflen = config->nfans * sizeof(u_int8_t) + /* fan status */ 313 sc->sc_encbuflen = config->nfans * sizeof(u_int8_t) + /* fan status */
306 config->npwrsup * sizeof(u_int8_t) + /* power supply status */ 314 config->npwrsup * sizeof(u_int8_t) + /* power supply status */
307 config->nslots * sizeof(u_int8_t) + /* device scsi id (lun) */ 315 config->nslots * sizeof(u_int8_t) + /* device scsi id (lun) */
308 sizeof(u_int8_t) + /* door lock status */ 316 sizeof(u_int8_t) + /* door lock status */
309 sizeof(u_int8_t) + /* speaker status */ 317 sizeof(u_int8_t) + /* speaker status */
310 config->ntemps * sizeof(u_int8_t) + /* temp sensors */ 318 config->ntemps * sizeof(u_int8_t) + /* temp sensors */
311 sizeof(u_int16_t); /* temp out of range sensors */ 319 sizeof(u_int16_t); /* temp out of range sensors */
312 320
313 » sc->sc_encbuf = malloc(sc->sc_encbuflen, M_DEVBUF, M_NOWAIT); 321 » sc->sc_encbuf = dma_alloc(sc->sc_encbuflen, PR_NOWAIT);
314 if (sc->sc_encbuf == NULL) { 322 if (sc->sc_encbuf == NULL) {
315 » » free(config, M_TEMP); 323 » » error = 1;
316 » » return (1); 324 » » goto done;
317 } 325 }
318 326
319 sc->sc_nsensors = config->nfans + config->npwrsup + config->ntemps +· 327 sc->sc_nsensors = config->nfans + config->npwrsup + config->ntemps +·
320 (config->doorlock ? 1 : 0) + (config->alarm ? 1 : 0); 328 (config->doorlock ? 1 : 0) + (config->alarm ? 1 : 0);
321 329
322 sc->sc_sensors = malloc(sc->sc_nsensors * sizeof(struct safte_sensor), 330 sc->sc_sensors = malloc(sc->sc_nsensors * sizeof(struct safte_sensor),
323 M_DEVBUF, M_NOWAIT | M_ZERO); 331 M_DEVBUF, M_NOWAIT | M_ZERO);
324 if (sc->sc_sensors == NULL) { 332 if (sc->sc_sensors == NULL) {
325 » » free(sc->sc_encbuf, M_DEVBUF); 333 » » dma_free(sc->sc_encbuf, sc->sc_encbuflen);
326 sc->sc_encbuf = NULL; 334 sc->sc_encbuf = NULL;
327 sc->sc_nsensors = 0; 335 sc->sc_nsensors = 0;
328 » » free(config, M_TEMP); 336 » » error = 1;
329 » » return (1); 337 » » goto done;
330 } 338 }
331 339
332 strlcpy(sc->sc_sensordev.xname, DEVNAME(sc), 340 strlcpy(sc->sc_sensordev.xname, DEVNAME(sc),
333 sizeof(sc->sc_sensordev.xname)); 341 sizeof(sc->sc_sensordev.xname));
334 342
335 s = sc->sc_sensors; 343 s = sc->sc_sensors;
336 344
337 for (i = 0; i < config->nfans; i++) { 345 for (i = 0; i < config->nfans; i++) {
338 s->se_type = SAFTE_T_FAN; 346 s->se_type = SAFTE_T_FAN;
339 s->se_field = (u_int8_t *)(sc->sc_encbuf + i); 347 s->se_field = (u_int8_t *)(sc->sc_encbuf + i);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 for (i = 0; i < config->ntemps; i++) { 401 for (i = 0; i < config->ntemps; i++) {
394 s->se_type = SAFTE_T_TEMP; 402 s->se_type = SAFTE_T_TEMP;
395 s->se_field = (u_int8_t *)(sc->sc_encbuf + j + i); 403 s->se_field = (u_int8_t *)(sc->sc_encbuf + j + i);
396 s->se_sensor.type = SENSOR_TEMP; 404 s->se_sensor.type = SENSOR_TEMP;
397 405
398 s++; 406 s++;
399 } 407 }
400 j += config->ntemps; 408 j += config->ntemps;
401 409
402 sc->sc_temperrs = (u_int8_t *)(sc->sc_encbuf + j); 410 sc->sc_temperrs = (u_int8_t *)(sc->sc_encbuf + j);
403 411 done:
404 » free(config, M_TEMP); 412 » dma_free(config, sizeof(*config));
405 » return (0); 413 » return (error);
406 } 414 }
407 415
408 void 416 void
409 safte_read_encstat(void *arg) 417 safte_read_encstat(void *arg)
410 { 418 {
411 struct safte_readbuf_cmd *cmd; 419 struct safte_readbuf_cmd *cmd;
412 struct safte_sensor *s; 420 struct safte_sensor *s;
413 struct safte_softc *sc = (struct safte_softc *)arg; 421 struct safte_softc *sc = (struct safte_softc *)arg;
414 struct scsi_xfer *xs; 422 struct scsi_xfer *xs;
415 int error, i, flags = 0; 423 int error, i, flags = 0;
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
588 rw_enter_read(&sc->sc_lock); 596 rw_enter_read(&sc->sc_lock);
589 for (slot = 0; slot < sc->sc_nslots; slot++) { 597 for (slot = 0; slot < sc->sc_nslots; slot++) {
590 if (sc->sc_slots[slot] == blink->bb_target) 598 if (sc->sc_slots[slot] == blink->bb_target)
591 break; 599 break;
592 } 600 }
593 rw_exit_read(&sc->sc_lock); 601 rw_exit_read(&sc->sc_lock);
594 602
595 if (slot >= sc->sc_nslots) 603 if (slot >= sc->sc_nslots)
596 return (ENODEV); 604 return (ENODEV);
597 605
598 » op = malloc(sizeof(*op), M_TEMP, M_WAITOK|M_ZERO); 606 » op = dma_alloc(sizeof(*op), PR_WAITOK | PR_ZERO);
599 607
600 op->opcode = SAFTE_WRITE_SLOTOP; 608 op->opcode = SAFTE_WRITE_SLOTOP;
601 op->slot = slot; 609 op->slot = slot;
602 op->flags |= wantblink ? SAFTE_SLOTOP_IDENTIFY : 0; 610 op->flags |= wantblink ? SAFTE_SLOTOP_IDENTIFY : 0;
603 611
604 if (cold) 612 if (cold)
605 flags |= SCSI_AUTOCONF; 613 flags |= SCSI_AUTOCONF;
606 xs = scsi_xs_get(sc->sc_link, flags | SCSI_DATA_OUT | SCSI_SILENT); 614 xs = scsi_xs_get(sc->sc_link, flags | SCSI_DATA_OUT | SCSI_SILENT);
607 if (xs == NULL) { 615 if (xs == NULL) {
608 » » free(op, M_TEMP); 616 » » dma_free(op, sizeof(*op));
609 return (ENOMEM); 617 return (ENOMEM);
610 } 618 }
611 xs->cmdlen = sizeof(*cmd); 619 xs->cmdlen = sizeof(*cmd);
612 xs->data = (void *)op; 620 xs->data = (void *)op;
613 xs->datalen = sizeof(*op); 621 xs->datalen = sizeof(*op);
614 xs->retries = 2;· 622 xs->retries = 2;·
615 xs->timeout = 30000; 623 xs->timeout = 30000;
616 624
617 cmd = (struct safte_writebuf_cmd *)xs->cmd; 625 cmd = (struct safte_writebuf_cmd *)xs->cmd;
618 cmd->opcode = WRITE_BUFFER; 626 cmd->opcode = WRITE_BUFFER;
619 cmd->flags |= SAFTE_WR_MODE; 627 cmd->flags |= SAFTE_WR_MODE;
620 cmd->length = htobe16(sizeof(struct safte_slotop)); 628 cmd->length = htobe16(sizeof(struct safte_slotop));
621 629
622 error = scsi_xs_sync(xs); 630 error = scsi_xs_sync(xs);
623 scsi_xs_put(xs); 631 scsi_xs_put(xs);
624 632
625 if (error != 0) { 633 if (error != 0) {
626 error = EIO; 634 error = EIO;
627 } 635 }
628 » free(op, M_TEMP); 636 » dma_free(op, sizeof(*op));
629 637
630 return (error); 638 return (error);
631 } 639 }
632 #endif /* NBIO > 0 */ 640 #endif /* NBIO > 0 */
633 641
634 int64_t 642 int64_t
635 safte_temp2uK(u_int8_t measured, int celsius) 643 safte_temp2uK(u_int8_t measured, int celsius)
636 { 644 {
637 int64_t temp; 645 int64_t temp;
638 646
639 temp = (int64_t)measured; 647 temp = (int64_t)measured;
640 temp += SAFTE_TEMP_OFFSET; 648 temp += SAFTE_TEMP_OFFSET;
641 temp *= 1000000; /* convert to micro (mu) degrees */ 649 temp *= 1000000; /* convert to micro (mu) degrees */
642 if (!celsius) 650 if (!celsius)
643 temp = ((temp - 32000000) * 5) / 9; /* convert to Celsius */ 651 temp = ((temp - 32000000) * 5) / 9; /* convert to Celsius */
644 652
645 temp += 273150000; /* convert to kelvin */ 653 temp += 273150000; /* convert to kelvin */
646 654
647 return (temp); 655 return (temp);
648 } 656 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b