1/*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2011 Sandvine Incorporated. All rights reserved.
5 * Copyright (c) 2002-2011 Andre Albsmeier <andre@albsmeier.net>
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer,
13 *    without modification, immediately at the beginning of the file.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/*
31 * This software is derived from Andre Albsmeier's fwprog.c which contained
32 * the following note:
33 *
34 * Many thanks goes to Marc Frajola <marc@terasolutions.com> from
35 * TeraSolutions for the initial idea and his programme for upgrading
36 * the firmware of I*M DDYS drives.
37 */
38
39/*
40 * BEWARE:
41 *
42 * The fact that you see your favorite vendor listed below does not
43 * imply that your equipment won't break when you use this software
44 * with it. It only means that the firmware of at least one device type
45 * of each vendor listed has been programmed successfully using this code.
46 *
47 * The -s option simulates a download but does nothing apart from that.
48 * It can be used to check what chunk sizes would have been used with the
49 * specified device.
50 */
51
52#include <sys/types.h>
53#include <sys/stat.h>
54
55#include <err.h>
56#include <fcntl.h>
57#include <stdbool.h>
58#include <stdio.h>
59#include <stdlib.h>
60#include <string.h>
61#include <unistd.h>
62
63#include <cam/cam.h>
64#include <cam/scsi/scsi_all.h>
65#include <cam/scsi/scsi_pass.h>
66#include <cam/scsi/scsi_message.h>
67#include <camlib.h>
68
69#include "progress.h"
70
71#include "camcontrol.h"
72
73#define	WB_TIMEOUT 50000	/* 50 seconds */
74
75typedef enum {
76	VENDOR_HGST,
77	VENDOR_HITACHI,
78	VENDOR_HP,
79	VENDOR_IBM,
80	VENDOR_PLEXTOR,
81	VENDOR_QUALSTAR,
82	VENDOR_QUANTUM,
83	VENDOR_SAMSUNG,
84	VENDOR_SEAGATE,
85	VENDOR_SMART,
86	VENDOR_TOSHIBA,
87	VENDOR_ATA,
88	VENDOR_UNKNOWN
89} fw_vendor_t;
90
91/*
92 * FW_TUR_READY:     The drive must return good status for a test unit ready.
93 *
94 * FW_TUR_NOT_READY: The drive must return not ready status for a test unit
95 *		     ready.  You may want this in a removable media drive.
96 *
97 * FW_TUR_NA:	     It doesn't matter whether the drive is ready or not.
98 * 		     This may be the case for a removable media drive.
99 */
100typedef enum {
101	FW_TUR_NONE,
102	FW_TUR_READY,
103	FW_TUR_NOT_READY,
104	FW_TUR_NA
105} fw_tur_status;
106
107/*
108 * FW_TIMEOUT_DEFAULT:		Attempt to probe for a WRITE BUFFER timeout
109 *				value from the drive.  If we get an answer,
110 *				use the Recommended timeout.  Otherwise,
111 * 				use the default value from the table.
112 *
113 * FW_TIMEOUT_DEV_REPORTED:	The timeout value was probed directly from
114 *				the device.
115 *
116 * FW_TIMEOUT_NO_PROBE:		Do not ask the device for a WRITE BUFFER
117 * 				timeout value.  Use the device-specific
118 *				value.
119 *
120 * FW_TIMEOUT_USER_SPEC:	The user specified a timeout on the command
121 *				line with the -t option.  This overrides any
122 *				probe or default timeout.
123 */
124typedef enum {
125	FW_TIMEOUT_DEFAULT,
126	FW_TIMEOUT_DEV_REPORTED,
127	FW_TIMEOUT_NO_PROBE,
128	FW_TIMEOUT_USER_SPEC
129} fw_timeout_type;
130
131/*
132 * type: 		Enumeration for the particular vendor.
133 *
134 * pattern:		Pattern to match for the Vendor ID from the SCSI
135 *			Inquiry data.
136 *
137 * dev_type:		SCSI device type to match, or T_ANY to match any
138 *			device from the given vendor.  Note that if there
139 *			is a specific device type listed for a particular
140 *			vendor, it must be listed before a T_ANY entry.
141 *
142 * max_pkt_size:	Maximum packet size when talking to a device.  Note
143 *			that although large data sizes may be supported by
144 *			the target device, they may not be supported by the
145 *			OS or the controller.
146 *
147 * cdb_byte2:		This specifies byte 2 (byte 1 when counting from 0)
148 *			of the CDB.  This is generally the WRITE BUFFER mode.
149 *
150 * cdb_byte2_last:	This specifies byte 2 for the last chunk of the
151 *			download.
152 *
153 * inc_cdb_buffer_id:	Increment the buffer ID by 1 for each chunk sent
154 *			down to the drive.
155 *
156 * inc_cdb_offset:	Increment the offset field in the CDB with the byte
157 *			offset into the firmware file.
158 *
159 * tur_status:		Pay attention to whether the device is ready before
160 *			upgrading the firmware, or not.  See above for the
161 *			values.
162 */
163struct fw_vendor {
164	fw_vendor_t type;
165	const char *pattern;
166	int dev_type;
167	int max_pkt_size;
168	uint8_t cdb_byte2;
169	uint8_t cdb_byte2_last;
170	int inc_cdb_buffer_id;
171	int inc_cdb_offset;
172	fw_tur_status tur_status;
173	int timeout_ms;
174	fw_timeout_type timeout_type;
175};
176
177/*
178 * Vendor notes:
179 *
180 * HGST:     The packets need to be sent in multiples of 4K.
181 *
182 * IBM:      For LTO and TS drives, the buffer ID is ignored in mode 7 (and
183 * 	     some other modes).  It treats the request as a firmware download.
184 *           The offset (and therefore the length of each chunk sent) needs
185 *           to be a multiple of the offset boundary specified for firmware
186 *           (buffer ID 4) in the read buffer command.  At least for LTO-6,
187 *           that seems to be 0, but using a 32K chunk size should satisfy
188 *           most any alignment requirement.
189 *
190 * SmrtStor: Mode 5 is also supported, but since the firmware is 400KB or
191 *           so, we can't fit it in a single request in most cases.
192 */
193static struct fw_vendor vendors_list[] = {
194	{VENDOR_HGST,	 	"HGST",		T_DIRECT,
195	0x1000, 0x07, 0x07, 1, 0, FW_TUR_READY, WB_TIMEOUT, FW_TIMEOUT_DEFAULT},
196	{VENDOR_HITACHI, 	"HITACHI",	T_ANY,
197	0x8000, 0x05, 0x05, 1, 0, FW_TUR_READY, WB_TIMEOUT, FW_TIMEOUT_DEFAULT},
198	{VENDOR_HP,	 	"HP",		T_ANY,
199	0x8000, 0x07, 0x07, 0, 1, FW_TUR_READY, WB_TIMEOUT, FW_TIMEOUT_DEFAULT},
200	{VENDOR_IBM,		"IBM",		T_SEQUENTIAL,
201	0x8000, 0x07, 0x07, 0, 1, FW_TUR_NA, 300 * 1000, FW_TIMEOUT_DEFAULT},
202	{VENDOR_IBM,		"IBM",		T_ANY,
203	0x8000, 0x05, 0x05, 1, 0, FW_TUR_READY, WB_TIMEOUT, FW_TIMEOUT_DEFAULT},
204	{VENDOR_PLEXTOR,	"PLEXTOR",	T_ANY,
205	0x2000, 0x04, 0x05, 0, 1, FW_TUR_READY, WB_TIMEOUT, FW_TIMEOUT_DEFAULT},
206	{VENDOR_QUALSTAR,	"QUALSTAR",	T_ANY,
207	0x2030, 0x05, 0x05, 0, 0, FW_TUR_READY, WB_TIMEOUT, FW_TIMEOUT_DEFAULT},
208	{VENDOR_QUANTUM,	"QUANTUM",	T_ANY,
209	0x2000, 0x04, 0x05, 0, 1, FW_TUR_READY, WB_TIMEOUT, FW_TIMEOUT_DEFAULT},
210	{VENDOR_SAMSUNG,	"SAMSUNG",	T_ANY,
211	0x8000, 0x07, 0x07, 0, 1, FW_TUR_READY, WB_TIMEOUT, FW_TIMEOUT_DEFAULT},
212	{VENDOR_SEAGATE,	"SEAGATE",	T_ANY,
213	0x8000, 0x07, 0x07, 0, 1, FW_TUR_READY, WB_TIMEOUT, FW_TIMEOUT_DEFAULT},
214	{VENDOR_SMART,		"SmrtStor",	T_DIRECT,
215	0x8000, 0x07, 0x07, 0, 1, FW_TUR_READY, WB_TIMEOUT, FW_TIMEOUT_DEFAULT},
216	{VENDOR_TOSHIBA,	"TOSHIBA",	T_DIRECT,
217	0x8000, 0x07, 0x07, 0, 1, FW_TUR_READY, WB_TIMEOUT, FW_TIMEOUT_DEFAULT},
218	{VENDOR_HGST,	 	"WD",		T_DIRECT,
219	0x1000, 0x07, 0x07, 1, 0, FW_TUR_READY, WB_TIMEOUT, FW_TIMEOUT_DEFAULT},
220	{VENDOR_HGST,	 	"WDC",		T_DIRECT,
221	0x1000, 0x07, 0x07, 1, 0, FW_TUR_READY, WB_TIMEOUT, FW_TIMEOUT_DEFAULT},
222
223	/*
224	 * We match any ATA device.  This is really just a placeholder,
225	 * since we won't actually send a WRITE BUFFER with any of the
226	 * listed parameters.  If a SATA device is behind a SAS controller,
227	 * the SCSI to ATA translation code (at least for LSI) doesn't
228	 * generally translate a SCSI WRITE BUFFER into an ATA DOWNLOAD
229	 * MICROCODE command.  So, we use the SCSI ATA PASS_THROUGH command
230	 * to send the ATA DOWNLOAD MICROCODE command instead.
231	 */
232	{VENDOR_ATA,		"ATA",		T_ANY,
233	 0x8000, 0x07, 0x07, 0, 1, FW_TUR_READY, WB_TIMEOUT,
234	 FW_TIMEOUT_NO_PROBE},
235	{VENDOR_UNKNOWN,	NULL,		T_ANY,
236	0x0000, 0x00, 0x00, 0, 0, FW_TUR_NONE, WB_TIMEOUT, FW_TIMEOUT_DEFAULT}
237};
238
239struct fw_timeout_desc {
240	fw_timeout_type timeout_type;
241	const char *timeout_desc;
242};
243
244static const struct fw_timeout_desc fw_timeout_desc_table[] = {
245	{ FW_TIMEOUT_DEFAULT, "the default" },
246	{ FW_TIMEOUT_DEV_REPORTED, "recommended by this particular device" },
247	{ FW_TIMEOUT_NO_PROBE, "the default" },
248	{ FW_TIMEOUT_USER_SPEC, "what was specified on the command line" }
249};
250
251#ifndef ATA_DOWNLOAD_MICROCODE
252#define ATA_DOWNLOAD_MICROCODE	0x92
253#endif
254
255#define USE_OFFSETS_FEATURE	0x3
256
257#ifndef LOW_SECTOR_SIZE
258#define LOW_SECTOR_SIZE		512
259#endif
260
261#define ATA_MAKE_LBA(o, p)	\
262	((((((o) / LOW_SECTOR_SIZE) >> 8) & 0xff) << 16) | \
263	  ((((o) / LOW_SECTOR_SIZE) & 0xff) << 8) | \
264	  ((((p) / LOW_SECTOR_SIZE) >> 8) & 0xff))
265
266#define ATA_MAKE_SECTORS(p)	(((p) / 512) & 0xff)
267
268#ifndef UNKNOWN_MAX_PKT_SIZE
269#define UNKNOWN_MAX_PKT_SIZE	0x8000
270#endif
271
272static struct fw_vendor *fw_get_vendor(struct cam_device *cam_dev,
273				       struct ata_params *ident_buf);
274static int fw_get_timeout(struct cam_device *cam_dev, struct fw_vendor *vp,
275			  int task_attr, int retry_count, int timeout);
276static int fw_validate_ibm(struct cam_device *dev, int retry_count,
277			   int timeout, int fd, char *buf,
278			    const char *fw_img_path, int quiet);
279static char *fw_read_img(struct cam_device *dev, int retry_count,
280			 int timeout, int quiet, const char *fw_img_path,
281			 struct fw_vendor *vp, int *num_bytes);
282static int fw_check_device_ready(struct cam_device *dev,
283				 camcontrol_devtype devtype,
284				 struct fw_vendor *vp, int printerrors,
285				 int timeout);
286static int fw_download_img(struct cam_device *cam_dev,
287			   struct fw_vendor *vp, char *buf, int img_size,
288			   int sim_mode, int printerrors, int quiet,
289			   int retry_count, int timeout, const char */*name*/,
290			   camcontrol_devtype devtype);
291
292/*
293 * Find entry in vendors list that belongs to
294 * the vendor of given cam device.
295 */
296static struct fw_vendor *
297fw_get_vendor(struct cam_device *cam_dev, struct ata_params *ident_buf)
298{
299	char vendor[42];
300	struct fw_vendor *vp;
301
302	if (cam_dev == NULL)
303		return (NULL);
304
305	if (ident_buf != NULL) {
306		cam_strvis((u_char *)vendor, ident_buf->model,
307		    sizeof(ident_buf->model), sizeof(vendor));
308		for (vp = vendors_list; vp->pattern != NULL; vp++) {
309			if (vp->type == VENDOR_ATA)
310				return (vp);
311		}
312	} else {
313		cam_strvis((u_char *)vendor, (u_char *)cam_dev->inq_data.vendor,
314		    sizeof(cam_dev->inq_data.vendor), sizeof(vendor));
315	}
316	for (vp = vendors_list; vp->pattern != NULL; vp++) {
317		if (!cam_strmatch((const u_char *)vendor,
318		    (const u_char *)vp->pattern, strlen(vendor))) {
319			if ((vp->dev_type == T_ANY)
320			 || (vp->dev_type == SID_TYPE(&cam_dev->inq_data)))
321				break;
322		}
323	}
324	return (vp);
325}
326
327static int
328fw_get_timeout(struct cam_device *cam_dev, struct fw_vendor *vp,
329	       int task_attr, int retry_count, int timeout)
330{
331	struct scsi_report_supported_opcodes_one *one;
332	struct scsi_report_supported_opcodes_timeout *td;
333	uint8_t *buf = NULL;
334	uint32_t fill_len = 0, cdb_len = 0, rec_timeout = 0;
335	int retval = 0;
336
337	/*
338	 * If the user has specified a timeout on the command line, we let
339	 * him override any default or probed value.
340	 */
341	if (timeout != 0) {
342		vp->timeout_type = FW_TIMEOUT_USER_SPEC;
343		vp->timeout_ms = timeout;
344		goto bailout;
345	}
346
347	/*
348	 * Check to see whether we should probe for a timeout for this
349	 * device.
350	 */
351	if (vp->timeout_type == FW_TIMEOUT_NO_PROBE)
352		goto bailout;
353
354	retval = scsigetopcodes(/*device*/ cam_dev,
355				/*opcode_set*/ 1,
356				/*opcode*/ WRITE_BUFFER,
357				/*show_sa_errors*/ 1,
358				/*sa_set*/ 0,
359				/*service_action*/ 0,
360				/*timeout_desc*/ 1,
361				/*task_attr*/ task_attr,
362				/*retry_count*/ retry_count,
363				/*timeout*/ 10000,
364				/*verbose*/ 0,
365				/*fill_len*/ &fill_len,
366				/*data_ptr*/ &buf);
367	/*
368	 * It isn't an error if we can't get a timeout descriptor.  We just
369	 * continue on with the default timeout.
370	 */
371	if (retval != 0) {
372		retval = 0;
373		goto bailout;
374	}
375
376	/*
377	 * Even if the drive didn't return a SCSI error, if we don't have
378	 * enough data to contain the one opcode descriptor, the CDB
379	 * structure and a timeout descriptor, we don't have the timeout
380	 * value we're looking for.  So we'll just fall back to the
381	 * default value.
382	 */
383	if (fill_len < (sizeof(*one) + sizeof(struct scsi_write_buffer) +
384	    sizeof(*td)))
385		goto bailout;
386
387	one = (struct scsi_report_supported_opcodes_one *)buf;
388
389	/*
390	 * If the drive claims to not support the WRITE BUFFER command...
391	 * fall back to the default timeout value and let things fail on
392	 * the actual firmware download.
393	 */
394	if ((one->support & RSO_ONE_SUP_MASK) == RSO_ONE_SUP_NOT_SUP)
395		goto bailout;
396
397	cdb_len = scsi_2btoul(one->cdb_length);
398	td = (struct scsi_report_supported_opcodes_timeout *)
399	    &buf[sizeof(*one) + cdb_len];
400
401	rec_timeout = scsi_4btoul(td->recommended_time);
402	/*
403	 * If the recommended timeout is 0, then the device has probably
404	 * returned a bogus value.
405	 */
406	if (rec_timeout == 0)
407		goto bailout;
408
409	/* CAM timeouts are in ms */
410	rec_timeout *= 1000;
411
412	vp->timeout_ms = rec_timeout;
413	vp->timeout_type = FW_TIMEOUT_DEV_REPORTED;
414
415bailout:
416	return (retval);
417}
418
419#define	SVPD_IBM_FW_DESIGNATION		0x03
420
421/*
422 * IBM LTO and TS tape drives have an INQUIRY VPD page 0x3 with the following
423 * format:
424 */
425struct fw_ibm_tape_fw_designation {
426	uint8_t	device;
427	uint8_t page_code;
428	uint8_t reserved;
429	uint8_t length;
430	uint8_t ascii_length;
431	uint8_t reserved2[3];
432	uint8_t load_id[4];
433	uint8_t fw_rev[4];
434	uint8_t ptf_number[4];
435	uint8_t patch_number[4];
436	uint8_t ru_name[8];
437	uint8_t lib_seq_num[5];
438};
439
440/*
441 * The firmware for IBM tape drives has the following header format.  The
442 * load_id and ru_name in the header file should match what is returned in
443 * VPD page 0x3.
444 */
445struct fw_ibm_tape_fw_header {
446	uint8_t unspec[4];
447	uint8_t length[4];		/* Firmware and header! */
448	uint8_t load_id[4];
449	uint8_t fw_rev[4];
450	uint8_t reserved[8];
451	uint8_t ru_name[8];
452};
453
454static int
455fw_validate_ibm(struct cam_device *dev, int retry_count, int timeout, int fd,
456		char *buf, const char *fw_img_path, int quiet)
457{
458	union ccb *ccb;
459	struct fw_ibm_tape_fw_designation vpd_page;
460	struct fw_ibm_tape_fw_header *header;
461	char drive_rev[sizeof(vpd_page.fw_rev) + 1];
462	char file_rev[sizeof(vpd_page.fw_rev) + 1];
463	int retval = 1;
464
465	ccb = cam_getccb(dev);
466	if (ccb == NULL) {
467		warnx("couldn't allocate CCB");
468		goto bailout;
469	}
470
471	bzero(&vpd_page, sizeof(vpd_page));
472
473	scsi_inquiry(&ccb->csio,
474		     /*retries*/ retry_count,
475		     /*cbfcnp*/ NULL,
476		     /* tag_action */ MSG_SIMPLE_Q_TAG,
477		     /* inq_buf */ (uint8_t *)&vpd_page,
478		     /* inq_len */ sizeof(vpd_page),
479		     /* evpd */ 1,
480		     /* page_code */ SVPD_IBM_FW_DESIGNATION,
481		     /* sense_len */ SSD_FULL_SIZE,
482		     /* timeout */ timeout ? timeout : 5000);
483
484	/* Disable freezing the device queue */
485	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
486
487	if (retry_count != 0)
488		ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER;
489
490	if (cam_send_ccb(dev, ccb) < 0) {
491		warn("error getting firmware designation page");
492
493		cam_error_print(dev, ccb, CAM_ESF_ALL,
494				CAM_EPF_ALL, stderr);
495
496		cam_freeccb(ccb);
497		ccb = NULL;
498		goto bailout;
499	}
500
501	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
502		cam_error_print(dev, ccb, CAM_ESF_ALL,
503				CAM_EPF_ALL, stderr);
504		goto bailout;
505	}
506
507	/*
508	 * Read the firmware header only.
509	 */
510	if (read(fd, buf, sizeof(*header)) != sizeof(*header)) {
511		warn("unable to read %zu bytes from %s", sizeof(*header),
512		     fw_img_path);
513		goto bailout;
514	}
515
516	/* Rewind the file back to 0 for the full file read. */
517	if (lseek(fd, 0, SEEK_SET) == -1) {
518		warn("Unable to lseek");
519		goto bailout;
520	}
521
522	header = (struct fw_ibm_tape_fw_header *)buf;
523
524	bzero(drive_rev, sizeof(drive_rev));
525	bcopy(vpd_page.fw_rev, drive_rev, sizeof(vpd_page.fw_rev));
526	bzero(file_rev, sizeof(file_rev));
527	bcopy(header->fw_rev, file_rev, sizeof(header->fw_rev));
528
529	if (quiet == 0) {
530		fprintf(stdout, "Current Drive Firmware version: %s\n",
531			drive_rev);
532		fprintf(stdout, "Firmware File version: %s\n", file_rev);
533	}
534
535	/*
536	 * For IBM tape drives the load ID and RU name reported by the
537	 * drive should match what is in the firmware file.
538	 */
539	if (bcmp(vpd_page.load_id, header->load_id,
540		 MIN(sizeof(vpd_page.load_id), sizeof(header->load_id))) != 0) {
541		warnx("Drive Firmware load ID 0x%x does not match firmware "
542		      "file load ID 0x%x", scsi_4btoul(vpd_page.load_id),
543		      scsi_4btoul(header->load_id));
544		goto bailout;
545	}
546
547	if (bcmp(vpd_page.ru_name, header->ru_name,
548		 MIN(sizeof(vpd_page.ru_name), sizeof(header->ru_name))) != 0) {
549		warnx("Drive Firmware RU name 0x%jx does not match firmware "
550		      "file RU name 0x%jx",
551		      (uintmax_t)scsi_8btou64(vpd_page.ru_name),
552		      (uintmax_t)scsi_8btou64(header->ru_name));
553		goto bailout;
554	}
555	if (quiet == 0)
556		fprintf(stdout, "Firmware file is valid for this drive.\n");
557	retval = 0;
558bailout:
559	cam_freeccb(ccb);
560
561	return (retval);
562}
563
564/*
565 * Allocate a buffer and read fw image file into it
566 * from given path. Number of bytes read is stored
567 * in num_bytes.
568 */
569static char *
570fw_read_img(struct cam_device *dev, int retry_count, int timeout, int quiet,
571	    const char *fw_img_path, struct fw_vendor *vp, int *num_bytes)
572{
573	int fd;
574	struct stat stbuf;
575	char *buf;
576	off_t img_size;
577	int skip_bytes = 0;
578
579	if ((fd = open(fw_img_path, O_RDONLY)) < 0) {
580		warn("Could not open image file %s", fw_img_path);
581		return (NULL);
582	}
583	if (fstat(fd, &stbuf) < 0) {
584		warn("Could not stat image file %s", fw_img_path);
585		goto bailout1;
586	}
587	if ((img_size = stbuf.st_size) == 0) {
588		warnx("Zero length image file %s", fw_img_path);
589		goto bailout1;
590	}
591	if ((buf = malloc(img_size)) == NULL) {
592		warnx("Could not allocate buffer to read image file %s",
593		    fw_img_path);
594		goto bailout1;
595	}
596	/* Skip headers if applicable. */
597	switch (vp->type) {
598	case VENDOR_SEAGATE:
599		if (read(fd, buf, 16) != 16) {
600			warn("Could not read image file %s", fw_img_path);
601			goto bailout;
602		}
603		if (lseek(fd, 0, SEEK_SET) == -1) {
604			warn("Unable to lseek");
605			goto bailout;
606		}
607		if ((strncmp(buf, "SEAGATE,SEAGATE ", 16) == 0) ||
608		    (img_size % 512 == 80))
609			skip_bytes = 80;
610		break;
611	case VENDOR_QUALSTAR:
612		skip_bytes = img_size % 1030;
613		break;
614	case VENDOR_IBM: {
615		if (vp->dev_type != T_SEQUENTIAL)
616			break;
617		if (fw_validate_ibm(dev, retry_count, timeout, fd, buf,
618				    fw_img_path, quiet) != 0)
619			goto bailout;
620		break;
621	}
622	default:
623		break;
624	}
625	if (skip_bytes != 0) {
626		fprintf(stdout, "Skipping %d byte header.\n", skip_bytes);
627		if (lseek(fd, skip_bytes, SEEK_SET) == -1) {
628			warn("Could not lseek");
629			goto bailout;
630		}
631		img_size -= skip_bytes;
632	}
633	/* Read image into a buffer. */
634	if (read(fd, buf, img_size) != img_size) {
635		warn("Could not read image file %s", fw_img_path);
636		goto bailout;
637	}
638	*num_bytes = img_size;
639	close(fd);
640	return (buf);
641bailout:
642	free(buf);
643bailout1:
644	close(fd);
645	*num_bytes = 0;
646	return (NULL);
647}
648
649/*
650 * Returns 0 for "success", where success means that the device has met the
651 * requirement in the vendor structure for being ready or not ready when
652 * firmware is downloaded.
653 *
654 * Returns 1 for a failure to be ready to accept a firmware download.
655 * (e.g., a drive needs to be ready, but returns not ready)
656 *
657 * Returns -1 for any other failure.
658 */
659static int
660fw_check_device_ready(struct cam_device *dev, camcontrol_devtype devtype,
661		      struct fw_vendor *vp, int printerrors, int timeout)
662{
663	union ccb *ccb;
664	int retval = 0;
665	int16_t *ptr = NULL;
666	size_t dxfer_len = 0;
667
668	if ((ccb = cam_getccb(dev)) == NULL) {
669		warnx("Could not allocate CCB");
670		retval = -1;
671		goto bailout;
672	}
673
674	if (devtype != CC_DT_SCSI) {
675		dxfer_len = sizeof(struct ata_params);
676
677		ptr = (uint16_t *)malloc(dxfer_len);
678		if (ptr == NULL) {
679			warnx("can't malloc memory for identify");
680			retval = -1;
681			goto bailout;
682		}
683		bzero(ptr, dxfer_len);
684	}
685
686	switch (devtype) {
687	case CC_DT_SCSI:
688		scsi_test_unit_ready(&ccb->csio,
689				     /*retries*/ 0,
690				     /*cbfcnp*/ NULL,
691				     /*tag_action*/ MSG_SIMPLE_Q_TAG,
692		    		     /*sense_len*/ SSD_FULL_SIZE,
693				     /*timeout*/ 5000);
694		break;
695	case CC_DT_SATL:
696	case CC_DT_ATA: {
697		retval = build_ata_cmd(ccb,
698			     /*retries*/ 1,
699			     /*flags*/ CAM_DIR_IN,
700			     /*tag_action*/ MSG_SIMPLE_Q_TAG,
701			     /*protocol*/ AP_PROTO_PIO_IN,
702			     /*ata_flags*/ AP_FLAG_BYT_BLOK_BLOCKS |
703					   AP_FLAG_TLEN_SECT_CNT |
704					   AP_FLAG_TDIR_FROM_DEV,
705			     /*features*/ 0,
706			     /*sector_count*/ dxfer_len / 512,
707			     /*lba*/ 0,
708			     /*command*/ ATA_ATA_IDENTIFY,
709			     /*auxiliary*/ 0,
710			     /*data_ptr*/ (uint8_t *)ptr,
711			     /*dxfer_len*/ dxfer_len,
712			     /*cdb_storage*/ NULL,
713			     /*cdb_storage_len*/ 0,
714			     /*sense_len*/ SSD_FULL_SIZE,
715			     /*timeout*/ timeout ? timeout : 30 * 1000,
716			     /*is48bit*/ 0,
717			     /*devtype*/ devtype);
718		if (retval != 0) {
719			retval = -1;
720			warnx("%s: build_ata_cmd() failed, likely "
721			    "programmer error", __func__);
722			goto bailout;
723		}
724		break;
725	}
726	default:
727		warnx("Unknown disk type %d", devtype);
728		retval = -1;
729		goto bailout;
730		break; /*NOTREACHED*/
731	}
732
733	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
734
735	retval = cam_send_ccb(dev, ccb);
736	if (retval != 0) {
737		warn("error sending %s CCB", (devtype == CC_DT_SCSI) ?
738		     "Test Unit Ready" : "Identify");
739		retval = -1;
740		goto bailout;
741	}
742
743	if (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
744	 && (vp->tur_status == FW_TUR_READY)) {
745		warnx("Device is not ready");
746		if (printerrors)
747			cam_error_print(dev, ccb, CAM_ESF_ALL,
748			    CAM_EPF_ALL, stderr);
749		retval = 1;
750		goto bailout;
751	} else if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
752		&& (vp->tur_status == FW_TUR_NOT_READY)) {
753		warnx("Device cannot have media loaded when firmware is "
754		    "downloaded");
755		retval = 1;
756		goto bailout;
757	}
758bailout:
759	free(ptr);
760	cam_freeccb(ccb);
761
762	return (retval);
763}
764
765/*
766 * After the firmware is downloaded, we know the sense data has changed (or is
767 * likely to change since it contains the firmware version).  Rescan the target
768 * with a flag to tell the kernel it's OK. This allows us to continnue using the
769 * old periph/disk in the kernel, which is less disruptive. We rescan the target
770 * because multilun devices usually update all the luns after the first firmware
771 * download.
772 */
773static int
774fw_rescan_target(struct cam_device *dev, bool printerrors, bool sim_mode)
775{
776	union ccb ccb;
777	int fd;
778
779	printf("Rescanning target %d:%d:* to pick up new fw revision / parameters.\n",
780	    dev->path_id, dev->target_id);
781	if (sim_mode)
782		return (0);
783
784	/* Can only send XPT_SCAN_TGT via /dev/xpt, not pass device in *dev */
785	if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {
786		warnx("error opening transport layer device %s\n",
787		    XPT_DEVICE);
788		warn("%s", XPT_DEVICE);
789		return (1);
790	}
791
792	/* Rescan the target */
793	bzero(&ccb, sizeof(union ccb));
794	ccb.ccb_h.func_code = XPT_SCAN_TGT;
795	ccb.ccb_h.path_id = dev->path_id;
796	ccb.ccb_h.target_id = dev->target_id;
797	ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
798	ccb.crcn.flags = CAM_EXPECT_INQ_CHANGE;
799	ccb.ccb_h.pinfo.priority = 5;	/* run this at a low priority */
800
801	if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) {
802		warn("CAMIOCOMMAND XPT_SCAN_TGT ioctl failed");
803		close(fd);
804		return (1);
805	}
806	if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
807		warn("Can't send rescan lun");
808		if (printerrors)
809			cam_error_print(dev, &ccb, CAM_ESF_ALL, CAM_EPF_ALL,
810			    stderr);
811		close(fd);
812		return (1);
813	}
814	close(fd);
815	return (0);
816}
817
818/*
819 * Download firmware stored in buf to cam_dev. If simulation mode
820 * is enabled, only show what packet sizes would be sent to the
821 * device but do not sent any actual packets
822 */
823static int
824fw_download_img(struct cam_device *cam_dev, struct fw_vendor *vp,
825    char *buf, int img_size, int sim_mode, int printerrors, int quiet,
826    int retry_count, int timeout, const char *imgname,
827    camcontrol_devtype devtype)
828{
829	struct scsi_write_buffer cdb;
830	progress_t progress;
831	int size = 0;
832	union ccb *ccb = NULL;
833	int pkt_count = 0;
834	int max_pkt_size;
835	uint32_t pkt_size = 0;
836	char *pkt_ptr = buf;
837	uint32_t offset;
838	int last_pkt = 0;
839	int retval = 0;
840
841	/*
842	 * Check to see whether the device is ready to accept a firmware
843	 * download.
844	 */
845	retval = fw_check_device_ready(cam_dev, devtype, vp, printerrors,
846				       timeout);
847	if (retval != 0)
848		goto bailout;
849
850	if ((ccb = cam_getccb(cam_dev)) == NULL) {
851		warnx("Could not allocate CCB");
852		retval = 1;
853		goto bailout;
854	}
855
856	max_pkt_size = vp->max_pkt_size;
857	if (max_pkt_size == 0)
858		max_pkt_size = UNKNOWN_MAX_PKT_SIZE;
859
860	pkt_size = max_pkt_size;
861	progress_init(&progress, imgname, size = img_size);
862	/* Download single fw packets. */
863	do {
864		if (img_size <= max_pkt_size) {
865			last_pkt = 1;
866			pkt_size = img_size;
867		}
868		progress_update(&progress, size - img_size);
869		if (((sim_mode == 0) && (quiet == 0))
870		 || ((sim_mode != 0) && (printerrors == 0)))
871			progress_draw(&progress);
872		bzero(&cdb, sizeof(cdb));
873		switch (devtype) {
874		case CC_DT_SCSI:
875			cdb.opcode  = WRITE_BUFFER;
876			cdb.control = 0;
877			/* Parameter list length. */
878			scsi_ulto3b(pkt_size, &cdb.length[0]);
879			offset = vp->inc_cdb_offset ? (pkt_ptr - buf) : 0;
880			scsi_ulto3b(offset, &cdb.offset[0]);
881			cdb.byte2 = last_pkt ? vp->cdb_byte2_last :
882					       vp->cdb_byte2;
883			cdb.buffer_id = vp->inc_cdb_buffer_id ? pkt_count : 0;
884			/* Zero out payload of ccb union after ccb header. */
885			CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio);
886			/*
887			 * Copy previously constructed cdb into ccb_scsiio
888			 * struct.
889			 */
890			bcopy(&cdb, &ccb->csio.cdb_io.cdb_bytes[0],
891			    sizeof(struct scsi_write_buffer));
892			/* Fill rest of ccb_scsiio struct. */
893			cam_fill_csio(&ccb->csio,		/* ccb_scsiio*/
894			    retry_count,			/* retries*/
895			    NULL,				/* cbfcnp*/
896			    CAM_DIR_OUT | CAM_DEV_QFRZDIS,	/* flags*/
897			    CAM_TAG_ACTION_NONE,		/* tag_action*/
898			    (u_char *)pkt_ptr,			/* data_ptr*/
899			    pkt_size,				/* dxfer_len*/
900			    SSD_FULL_SIZE,			/* sense_len*/
901			    sizeof(struct scsi_write_buffer),	/* cdb_len*/
902			    timeout ? timeout : WB_TIMEOUT);	/* timeout*/
903			break;
904		case CC_DT_ATA:
905		case CC_DT_SATL: {
906			uint32_t	off;
907
908			off = (uint32_t)(pkt_ptr - buf);
909
910			retval = build_ata_cmd(ccb,
911			    /*retry_count*/ retry_count,
912			    /*flags*/ CAM_DIR_OUT | CAM_DEV_QFRZDIS,
913			    /*tag_action*/ CAM_TAG_ACTION_NONE,
914			    /*protocol*/ AP_PROTO_PIO_OUT,
915			    /*ata_flags*/ AP_FLAG_BYT_BLOK_BYTES |
916					  AP_FLAG_TLEN_SECT_CNT |
917					  AP_FLAG_TDIR_TO_DEV,
918			    /*features*/ USE_OFFSETS_FEATURE,
919			    /*sector_count*/ ATA_MAKE_SECTORS(pkt_size),
920			    /*lba*/ ATA_MAKE_LBA(off, pkt_size),
921			    /*command*/ ATA_DOWNLOAD_MICROCODE,
922			    /*auxiliary*/ 0,
923			    /*data_ptr*/ (uint8_t *)pkt_ptr,
924			    /*dxfer_len*/ pkt_size,
925			    /*cdb_storage*/ NULL,
926			    /*cdb_storage_len*/ 0,
927			    /*sense_len*/ SSD_FULL_SIZE,
928			    /*timeout*/ timeout ? timeout : WB_TIMEOUT,
929			    /*is48bit*/ 0,
930			    /*devtype*/ devtype);
931
932			if (retval != 0) {
933				warnx("%s: build_ata_cmd() failed, likely "
934				    "programmer error", __func__);
935				goto bailout;
936			}
937			break;
938		}
939		default:
940			warnx("Unknown device type %d", devtype);
941			retval = 1;
942			goto bailout;
943			break; /*NOTREACHED*/
944		}
945		if (!sim_mode) {
946			/* Execute the command. */
947			if (cam_send_ccb(cam_dev, ccb) < 0 ||
948			    (ccb->ccb_h.status & CAM_STATUS_MASK) !=
949			    CAM_REQ_CMP) {
950				warnx("Error writing image to device");
951				if (printerrors)
952					cam_error_print(cam_dev, ccb,
953					    CAM_ESF_ALL, CAM_EPF_ALL, stderr);
954				retval = 1;
955				goto bailout;
956			}
957		} else if (printerrors) {
958			cam_error_print(cam_dev, ccb, CAM_ESF_COMMAND, 0,
959			    stdout);
960		}
961
962		/* Prepare next round. */
963		pkt_count++;
964		pkt_ptr += pkt_size;
965		img_size -= pkt_size;
966	} while(!last_pkt);
967bailout:
968	if (quiet == 0)
969		progress_complete(&progress, size - img_size);
970	cam_freeccb(ccb);
971	if (retval == 0) {
972		fw_rescan_target(cam_dev, printerrors, sim_mode);
973	}
974	return (retval);
975}
976
977int
978fwdownload(struct cam_device *device, int argc, char **argv,
979    char *combinedopt, int printerrors, int task_attr, int retry_count,
980    int timeout)
981{
982	union ccb *ccb = NULL;
983	struct fw_vendor *vp;
984	char *fw_img_path = NULL;
985	struct ata_params *ident_buf = NULL;
986	camcontrol_devtype devtype;
987	char *buf = NULL;
988	int img_size;
989	int c;
990	int sim_mode = 0;
991	int confirmed = 0;
992	int quiet = 0;
993	int retval = 0;
994
995	while ((c = getopt(argc, argv, combinedopt)) != -1) {
996		switch (c) {
997		case 'f':
998			fw_img_path = optarg;
999			break;
1000		case 'q':
1001			quiet = 1;
1002			break;
1003		case 's':
1004			sim_mode = 1;
1005			break;
1006		case 'y':
1007			confirmed = 1;
1008			break;
1009		default:
1010			break;
1011		}
1012	}
1013
1014	if (fw_img_path == NULL)
1015		errx(1, "you must specify a firmware image file using -f "
1016		     "option");
1017
1018	retval = get_device_type(device, retry_count, timeout, printerrors,
1019				 &devtype);
1020	if (retval != 0)
1021		errx(1, "Unable to determine device type");
1022
1023	if ((devtype == CC_DT_ATA)
1024	 || (devtype == CC_DT_SATL)) {
1025		ccb = cam_getccb(device);
1026		if (ccb == NULL) {
1027			warnx("couldn't allocate CCB");
1028			retval = 1;
1029			goto bailout;
1030		}
1031
1032		if (ata_do_identify(device, retry_count, timeout, ccb,
1033		    		    &ident_buf) != 0) {
1034			retval = 1;
1035			goto bailout;
1036		}
1037	} else if (devtype != CC_DT_SCSI)
1038		errx(1, "Unsupported device type %d", devtype);
1039
1040	vp = fw_get_vendor(device, ident_buf);
1041	/*
1042	 * Bail out if we have an unknown vendor and this isn't an ATA
1043	 * disk.  For a SCSI disk, we have no chance of working properly
1044	 * with the default values in the VENDOR_UNKNOWN case.  For an ATA
1045	 * disk connected via an ATA transport, we may work for drives that
1046	 * support the ATA_DOWNLOAD_MICROCODE command.
1047	 */
1048	if (((vp == NULL)
1049	  || (vp->type == VENDOR_UNKNOWN))
1050	 && (devtype == CC_DT_SCSI))
1051		errx(1, "Unsupported device");
1052
1053	retval = fw_get_timeout(device, vp, task_attr, retry_count, timeout);
1054	if (retval != 0) {
1055		warnx("Unable to get a firmware download timeout value");
1056		goto bailout;
1057	}
1058
1059	buf = fw_read_img(device, retry_count, timeout, quiet, fw_img_path,
1060	    vp, &img_size);
1061	if (buf == NULL) {
1062		retval = 1;
1063		goto bailout;
1064	}
1065
1066	if (!confirmed) {
1067		fprintf(stdout, "You are about to download firmware image (%s)"
1068		    " into the following device:\n",
1069		    fw_img_path);
1070		if (devtype == CC_DT_SCSI) {
1071			if (scsidoinquiry(device, argc, argv, combinedopt,
1072					  MSG_SIMPLE_Q_TAG, 0, 5000) != 0) {
1073				warnx("Error sending inquiry");
1074				retval = 1;
1075				goto bailout;
1076			}
1077		} else {
1078			printf("%s%d: ", device->device_name,
1079			    device->dev_unit_num);
1080			ata_print_ident(ident_buf);
1081			camxferrate(device);
1082			free(ident_buf);
1083		}
1084		fprintf(stdout, "Using a timeout of %u ms, which is %s.\n",
1085			vp->timeout_ms,
1086			fw_timeout_desc_table[vp->timeout_type].timeout_desc);
1087		fprintf(stdout, "\nIt may damage your drive. ");
1088		if (!get_confirmation()) {
1089			retval = 1;
1090			goto bailout;
1091		}
1092	}
1093	if ((sim_mode != 0) && (quiet == 0))
1094		fprintf(stdout, "Running in simulation mode\n");
1095
1096	if (fw_download_img(device, vp, buf, img_size, sim_mode, printerrors,
1097	    quiet, retry_count, vp->timeout_ms, fw_img_path, devtype) != 0) {
1098		fprintf(stderr, "Firmware download failed\n");
1099		retval = 1;
1100		goto bailout;
1101	} else if (quiet == 0)
1102		fprintf(stdout, "Firmware download successful\n");
1103
1104bailout:
1105	cam_freeccb(ccb);
1106	free(buf);
1107	return (retval);
1108}
1109
1110