7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2011 Gary Mills
23 *
24 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
26 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
27 */
28
29 /*
30 * This file contains functions to implement automatic configuration
31 * of scsi disks.
32 */
33 #include "global.h"
34
35 #include <fcntl.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <strings.h>
39 #include <stdlib.h>
40 #include <ctype.h>
41
42 #include "misc.h"
43 #include "param.h"
44 #include "ctlr_scsi.h"
45 #include "auto_sense.h"
46 #include "partition.h"
193 int build_default_partition(struct dk_label *label,
194 int ctrl_type);
195 static struct disk_type *find_scsi_disk_type(
196 char *disk_name,
197 struct dk_label *label);
198 static struct disk_type *find_scsi_disk_by_name(
199 char *disk_name);
200 static struct ctlr_type *find_scsi_ctlr_type(void);
201 static struct ctlr_info *find_scsi_ctlr_info(
202 struct dk_cinfo *dkinfo);
203 static struct disk_type *new_scsi_disk_type(
204 int fd,
205 char *disk_name,
206 struct dk_label *label);
207 static struct disk_info *find_scsi_disk_info(
208 struct dk_cinfo *dkinfo);
209
210 static struct disk_type *new_direct_disk_type(int fd, char *disk_name,
211 struct dk_label *label);
212
213 static struct disk_info *find_direct_disk_info(struct dk_cinfo *dkinfo);
214 static int efi_ioctl(int fd, int cmd, dk_efi_t *dk_ioc);
215 static int auto_label_init(struct dk_label *label);
216 static struct ctlr_type *find_direct_ctlr_type(void);
217 static struct ctlr_info *find_direct_ctlr_info(struct dk_cinfo *dkinfo);
218 static struct disk_info *find_direct_disk_info(struct dk_cinfo *dkinfo);
219 static struct ctlr_type *find_vbd_ctlr_type(void);
220 static struct ctlr_info *find_vbd_ctlr_info(struct dk_cinfo *dkinfo);
221 static struct disk_info *find_vbd_disk_info(struct dk_cinfo *dkinfo);
222
223 static char *get_sun_disk_name(
224 char *disk_name,
225 struct scsi_inquiry *inquiry);
226 static char *strcopy(
227 char *dst,
228 char *src,
229 int n);
230 static int adjust_disk_geometry(diskaddr_t capacity, uint_t *cyl,
231 uint_t *nsect, uint_t *nhead);
232 static void compute_chs_values(diskaddr_t total_capacity,
233 diskaddr_t usable_capacity, uint_t *pcylp,
234 uint_t *nheadp, uint_t *nsectp);
235 #if defined(_SUNOS_VTOC_8)
236 static diskaddr_t square_box(
237 diskaddr_t capacity,
238 uint_t *dim1, uint_t lim1,
239 uint_t *dim2, uint_t lim2,
240 uint_t *dim3, uint_t lim3);
241 #endif /* defined(_SUNOS_VTOC_8) */
247 */
248 struct disk_type *
249 auto_efi_sense(int fd, struct efi_info *label)
250 {
251
252 struct dk_gpt *vtoc;
253 int i;
254
255 struct disk_type *disk, *dp;
256 struct disk_info *disk_info;
257 struct ctlr_info *ctlr;
258 struct dk_cinfo dkinfo;
259 struct partition_info *part;
260
261 if (ioctl(fd, DKIOCINFO, &dkinfo) == -1) {
262 if (option_msg && diag_msg) {
263 err_print("DKIOCINFO failed\n");
264 }
265 return (NULL);
266 }
267 if ((cur_ctype != NULL) && (cur_ctype->ctype_ctype == DKC_DIRECT)) {
268 ctlr = find_direct_ctlr_info(&dkinfo);
269 disk_info = find_direct_disk_info(&dkinfo);
270 } else if ((cur_ctype != NULL) && (cur_ctype->ctype_ctype == DKC_VBD)) {
271 ctlr = find_vbd_ctlr_info(&dkinfo);
272 disk_info = find_vbd_disk_info(&dkinfo);
273 } else {
274 ctlr = find_scsi_ctlr_info(&dkinfo);
275 disk_info = find_scsi_disk_info(&dkinfo);
276 }
277
278 /*
279 * get vendor, product, revision and capacity info.
280 */
281 if (get_disk_info(fd, label, disk_info) == -1) {
282 return ((struct disk_type *)NULL);
283 }
284 /*
285 * Now build the default partition table
286 */
287 if (efi_alloc_and_init(fd, EFI_NUMPAR, &vtoc) != 0) {
288 err_print("efi_alloc_and_init failed. \n");
289 return ((struct disk_type *)NULL);
290 }
291
292 label->e_parts = vtoc;
361
362 bzero(disk_info->v_volume, LEN_DKL_VVOL);
363 disk_info->disk_parts = part;
364 return (disk);
365 }
366
367 static int
368 efi_ioctl(int fd, int cmd, dk_efi_t *dk_ioc)
369 {
370 void *data = dk_ioc->dki_data;
371 int error;
372
373 dk_ioc->dki_data_64 = (uint64_t)(uintptr_t)data;
374 error = ioctl(fd, cmd, (void *)dk_ioc);
375 dk_ioc->dki_data = data;
376
377 return (error);
378 }
379
380 static struct ctlr_type *
381 find_direct_ctlr_type()
382 {
383 struct mctlr_list *mlp;
384
385 mlp = controlp;
386
387 while (mlp != NULL) {
388 if (mlp->ctlr_type->ctype_ctype == DKC_DIRECT) {
389 return (mlp->ctlr_type);
390 }
391 mlp = mlp->next;
392 }
393
394 impossible("no DIRECT controller type");
395
396 return ((struct ctlr_type *)NULL);
397 }
398
399 static struct ctlr_type *
400 find_vbd_ctlr_type()
401 {
402 struct mctlr_list *mlp;
403
404 mlp = controlp;
405
406 while (mlp != NULL) {
407 if (mlp->ctlr_type->ctype_ctype == DKC_VBD) {
408 return (mlp->ctlr_type);
409 }
410 mlp = mlp->next;
411 }
412
413 impossible("no VBD controller type");
414
415 return ((struct ctlr_type *)NULL);
416 }
417
418 static struct ctlr_info *
419 find_direct_ctlr_info(
420 struct dk_cinfo *dkinfo)
421 {
422 struct ctlr_info *ctlr;
423
424 if (dkinfo->dki_ctype != DKC_DIRECT)
425 return (NULL);
426
427 for (ctlr = ctlr_list; ctlr != NULL; ctlr = ctlr->ctlr_next) {
428 if (ctlr->ctlr_addr == dkinfo->dki_addr &&
429 ctlr->ctlr_space == dkinfo->dki_space &&
430 ctlr->ctlr_ctype->ctype_ctype == DKC_DIRECT) {
431 return (ctlr);
432 }
433 }
434
435 impossible("no DIRECT controller info");
436 /*NOTREACHED*/
437 }
438
439 static struct ctlr_info *
440 find_vbd_ctlr_info(
441 struct dk_cinfo *dkinfo)
442 {
443 struct ctlr_info *ctlr;
444
445 if (dkinfo->dki_ctype != DKC_VBD)
446 return (NULL);
447
448 for (ctlr = ctlr_list; ctlr != NULL; ctlr = ctlr->ctlr_next) {
449 if (ctlr->ctlr_addr == dkinfo->dki_addr &&
450 ctlr->ctlr_space == dkinfo->dki_space &&
451 ctlr->ctlr_ctype->ctype_ctype == DKC_VBD) {
452 return (ctlr);
453 }
454 }
455
456 impossible("no VBD controller info");
457 /*NOTREACHED*/
458 }
459
460 static struct disk_info *
461 find_direct_disk_info(
462 struct dk_cinfo *dkinfo)
463 {
464 struct disk_info *disk;
465 struct dk_cinfo *dp;
466
467 for (disk = disk_list; disk != NULL; disk = disk->disk_next) {
468 assert(dkinfo->dki_ctype == DKC_DIRECT);
469 dp = &disk->disk_dkinfo;
470 if (dp->dki_ctype == dkinfo->dki_ctype &&
471 dp->dki_cnum == dkinfo->dki_cnum &&
472 dp->dki_unit == dkinfo->dki_unit &&
473 strcmp(dp->dki_dname, dkinfo->dki_dname) == 0) {
474 return (disk);
475 }
476 }
477
478 impossible("No DIRECT disk info instance\n");
479 /*NOTREACHED*/
480 }
481
482 static struct disk_info *
483 find_vbd_disk_info(
484 struct dk_cinfo *dkinfo)
485 {
486 struct disk_info *disk;
487 struct dk_cinfo *dp;
488
489 for (disk = disk_list; disk != NULL; disk = disk->disk_next) {
490 assert(dkinfo->dki_ctype == DKC_VBD);
491 dp = &disk->disk_dkinfo;
492 if (dp->dki_ctype == dkinfo->dki_ctype &&
493 dp->dki_cnum == dkinfo->dki_cnum &&
494 dp->dki_unit == dkinfo->dki_unit &&
495 strcmp(dp->dki_dname, dkinfo->dki_dname) == 0) {
496 return (disk);
497 }
498 }
499
500 impossible("No VBD disk info instance\n");
501 /*NOTREACHED*/
502 }
503
504 /*
505 * To convert EFI to SMI labels, we need to get label geometry.
506 * Unfortunately at this time there is no good way to do so.
507 * DKIOCGGEOM will fail if disk is EFI labeled. So we hack around
508 * it and clear EFI label, do a DKIOCGGEOM and put the EFI label
509 * back on disk.
510 * This routine gets the label geometry and initializes the label
511 * It uses cur_file as opened device.
512 * returns 0 if succeeds or -1 if failed.
513 */
514 static int
515 auto_label_init(struct dk_label *label)
516 {
517 dk_efi_t dk_ioc;
518 dk_efi_t dk_ioc_back;
519 efi_gpt_t *data = NULL;
520 efi_gpt_t *databack = NULL;
521 struct dk_geom disk_geom;
674 struct ctlr_info *ctlr;
675 struct dk_cinfo dkinfo;
676 struct partition_info *part = NULL;
677 struct partition_info *pt;
678 struct disk_info *disk_info;
679 int i;
680
681 /*
682 * Get the disk controller info for this disk
683 */
684 if (ioctl(fd, DKIOCINFO, &dkinfo) == -1) {
685 if (option_msg && diag_msg) {
686 err_print("DKIOCINFO failed\n");
687 }
688 return (NULL);
689 }
690
691 /*
692 * Find the ctlr_info for this disk.
693 */
694 ctlr = find_direct_ctlr_info(&dkinfo);
695
696 /*
697 * Allocate a new disk type for the direct controller.
698 */
699 disk = (struct disk_type *)zalloc(sizeof (struct disk_type));
700
701 /*
702 * Find the disk_info instance for this disk.
703 */
704 disk_info = find_direct_disk_info(&dkinfo);
705
706 /*
707 * The controller and the disk should match.
708 */
709 assert(disk_info->disk_ctlr == ctlr);
710
711 /*
712 * Link the disk into the list of disks
713 */
714 dp = ctlr->ctlr_ctype->ctype_dlist;
715 if (dp == NULL) {
716 ctlr->ctlr_ctype->ctype_dlist = dp;
717 } else {
718 while (dp->dtype_next != NULL) {
719 dp = dp->dtype_next;
720 }
721 dp->dtype_next = disk;
722 }
723 disk->dtype_next = NULL;
724
1993 LEN_DKL_VVOL);
1994 part->vtoc = label->dkl_vtoc;
1995 } else {
1996 (void) memset(disk_info->v_volume, 0, LEN_DKL_VVOL);
1997 set_vtoc_defaults(part);
1998 }
1999
2000 /*
2001 * Link the disk to the partition map
2002 */
2003 disk_info->disk_parts = part;
2004
2005 return (disk);
2006 }
2007
2008
2009 /*
2010 * Delete a disk type from disk type list.
2011 */
2012 int
2013 delete_disk_type(
2014 struct disk_type *disk_type)
2015 {
2016 struct ctlr_type *ctlr;
2017 struct disk_type *dp, *disk;
2018
2019 if (cur_ctype->ctype_ctype == DKC_DIRECT)
2020 ctlr = find_direct_ctlr_type();
2021 else if (cur_ctype->ctype_ctype == DKC_VBD)
2022 ctlr = find_vbd_ctlr_type();
2023 else
2024 ctlr = find_scsi_ctlr_type();
2025 if (ctlr == NULL || ctlr->ctype_dlist == NULL) {
2026 return (-1);
2027 }
2028
2029 disk = ctlr->ctype_dlist;
2030 if (disk == disk_type) {
2031 ctlr->ctype_dlist = disk->dtype_next;
2032 if (cur_label == L_TYPE_EFI)
2033 free(disk->dtype_plist->etoc);
2034 free(disk->dtype_plist);
2035 free(disk->vendor);
2036 free(disk->product);
2037 free(disk->revision);
2038 free(disk);
2039 return (0);
2040 } else {
2041 for (dp = disk->dtype_next; dp != NULL;
2042 disk = disk->dtype_next, dp = dp->dtype_next) {
|
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2011 Gary Mills
23 *
24 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
26 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
27 * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
28 */
29
30 /*
31 * This file contains functions to implement automatic configuration
32 * of scsi disks.
33 */
34 #include "global.h"
35
36 #include <fcntl.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <strings.h>
40 #include <stdlib.h>
41 #include <ctype.h>
42
43 #include "misc.h"
44 #include "param.h"
45 #include "ctlr_scsi.h"
46 #include "auto_sense.h"
47 #include "partition.h"
194 int build_default_partition(struct dk_label *label,
195 int ctrl_type);
196 static struct disk_type *find_scsi_disk_type(
197 char *disk_name,
198 struct dk_label *label);
199 static struct disk_type *find_scsi_disk_by_name(
200 char *disk_name);
201 static struct ctlr_type *find_scsi_ctlr_type(void);
202 static struct ctlr_info *find_scsi_ctlr_info(
203 struct dk_cinfo *dkinfo);
204 static struct disk_type *new_scsi_disk_type(
205 int fd,
206 char *disk_name,
207 struct dk_label *label);
208 static struct disk_info *find_scsi_disk_info(
209 struct dk_cinfo *dkinfo);
210
211 static struct disk_type *new_direct_disk_type(int fd, char *disk_name,
212 struct dk_label *label);
213
214 static int efi_ioctl(int fd, int cmd, dk_efi_t *dk_ioc);
215 static int auto_label_init(struct dk_label *label);
216 static struct ctlr_type *find_ctlr_type(ushort_t);
217 static struct ctlr_info *find_ctlr_info(struct dk_cinfo *, ushort_t);
218 static struct disk_info *find_disk_info(struct dk_cinfo *, ushort_t);
219
220 static char *get_sun_disk_name(
221 char *disk_name,
222 struct scsi_inquiry *inquiry);
223 static char *strcopy(
224 char *dst,
225 char *src,
226 int n);
227 static int adjust_disk_geometry(diskaddr_t capacity, uint_t *cyl,
228 uint_t *nsect, uint_t *nhead);
229 static void compute_chs_values(diskaddr_t total_capacity,
230 diskaddr_t usable_capacity, uint_t *pcylp,
231 uint_t *nheadp, uint_t *nsectp);
232 #if defined(_SUNOS_VTOC_8)
233 static diskaddr_t square_box(
234 diskaddr_t capacity,
235 uint_t *dim1, uint_t lim1,
236 uint_t *dim2, uint_t lim2,
237 uint_t *dim3, uint_t lim3);
238 #endif /* defined(_SUNOS_VTOC_8) */
244 */
245 struct disk_type *
246 auto_efi_sense(int fd, struct efi_info *label)
247 {
248
249 struct dk_gpt *vtoc;
250 int i;
251
252 struct disk_type *disk, *dp;
253 struct disk_info *disk_info;
254 struct ctlr_info *ctlr;
255 struct dk_cinfo dkinfo;
256 struct partition_info *part;
257
258 if (ioctl(fd, DKIOCINFO, &dkinfo) == -1) {
259 if (option_msg && diag_msg) {
260 err_print("DKIOCINFO failed\n");
261 }
262 return (NULL);
263 }
264 if ((cur_ctype != NULL) && (cur_ctype->ctype_ctype == DKC_DIRECT ||
265 cur_ctype->ctype_ctype == DKC_VBD ||
266 cur_ctype->ctype_ctype == DKC_BLKDEV)) {
267 ctlr = find_ctlr_info(&dkinfo, cur_ctype->ctype_ctype);
268 disk_info = find_disk_info(&dkinfo, cur_ctype->ctype_ctype);
269 } else {
270 ctlr = find_scsi_ctlr_info(&dkinfo);
271 disk_info = find_scsi_disk_info(&dkinfo);
272 }
273
274 /*
275 * get vendor, product, revision and capacity info.
276 */
277 if (get_disk_info(fd, label, disk_info) == -1) {
278 return ((struct disk_type *)NULL);
279 }
280 /*
281 * Now build the default partition table
282 */
283 if (efi_alloc_and_init(fd, EFI_NUMPAR, &vtoc) != 0) {
284 err_print("efi_alloc_and_init failed. \n");
285 return ((struct disk_type *)NULL);
286 }
287
288 label->e_parts = vtoc;
357
358 bzero(disk_info->v_volume, LEN_DKL_VVOL);
359 disk_info->disk_parts = part;
360 return (disk);
361 }
362
363 static int
364 efi_ioctl(int fd, int cmd, dk_efi_t *dk_ioc)
365 {
366 void *data = dk_ioc->dki_data;
367 int error;
368
369 dk_ioc->dki_data_64 = (uint64_t)(uintptr_t)data;
370 error = ioctl(fd, cmd, (void *)dk_ioc);
371 dk_ioc->dki_data = data;
372
373 return (error);
374 }
375
376 static struct ctlr_type *
377 find_ctlr_type(ushort_t type)
378 {
379 struct mctlr_list *mlp;
380
381 assert(type == DKC_DIRECT ||
382 type == DKC_VBD ||
383 type == DKC_BLKDEV);
384
385 mlp = controlp;
386
387 while (mlp != NULL) {
388 if (mlp->ctlr_type->ctype_ctype == type) {
389 return (mlp->ctlr_type);
390 }
391 mlp = mlp->next;
392 }
393
394 impossible("no DIRECT/VBD/BLKDEV controller type");
395
396 return ((struct ctlr_type *)NULL);
397 }
398
399 static struct ctlr_info *
400 find_ctlr_info(struct dk_cinfo *dkinfo, ushort_t type)
401 {
402 struct ctlr_info *ctlr;
403
404 assert(type == DKC_DIRECT ||
405 type == DKC_VBD ||
406 type == DKC_BLKDEV);
407
408 for (ctlr = ctlr_list; ctlr != NULL; ctlr = ctlr->ctlr_next) {
409 if (ctlr->ctlr_addr == dkinfo->dki_addr &&
410 ctlr->ctlr_space == dkinfo->dki_space &&
411 ctlr->ctlr_ctype->ctype_ctype == dkinfo->dki_ctype) {
412 return (ctlr);
413 }
414 }
415
416 impossible("no DIRECT/VBD/BLKDEV controller info");
417 /*NOTREACHED*/
418 return ((struct ctlr_info *)NULL);
419 }
420
421 static struct disk_info *
422 find_disk_info(struct dk_cinfo *dkinfo, ushort_t type)
423 {
424 struct disk_info *disk;
425 struct dk_cinfo *dp;
426
427 assert(type == DKC_DIRECT ||
428 type == DKC_VBD ||
429 type == DKC_BLKDEV);
430
431 for (disk = disk_list; disk != NULL; disk = disk->disk_next) {
432 dp = &disk->disk_dkinfo;
433 if (dp->dki_ctype == dkinfo->dki_ctype &&
434 dp->dki_cnum == dkinfo->dki_cnum &&
435 dp->dki_unit == dkinfo->dki_unit &&
436 strcmp(dp->dki_dname, dkinfo->dki_dname) == 0) {
437 return (disk);
438 }
439 }
440
441 impossible("No DIRECT/VBD/BLKDEV disk info instance\n");
442 /*NOTREACHED*/
443 return ((struct disk_info *)NULL);
444 }
445
446 /*
447 * To convert EFI to SMI labels, we need to get label geometry.
448 * Unfortunately at this time there is no good way to do so.
449 * DKIOCGGEOM will fail if disk is EFI labeled. So we hack around
450 * it and clear EFI label, do a DKIOCGGEOM and put the EFI label
451 * back on disk.
452 * This routine gets the label geometry and initializes the label
453 * It uses cur_file as opened device.
454 * returns 0 if succeeds or -1 if failed.
455 */
456 static int
457 auto_label_init(struct dk_label *label)
458 {
459 dk_efi_t dk_ioc;
460 dk_efi_t dk_ioc_back;
461 efi_gpt_t *data = NULL;
462 efi_gpt_t *databack = NULL;
463 struct dk_geom disk_geom;
616 struct ctlr_info *ctlr;
617 struct dk_cinfo dkinfo;
618 struct partition_info *part = NULL;
619 struct partition_info *pt;
620 struct disk_info *disk_info;
621 int i;
622
623 /*
624 * Get the disk controller info for this disk
625 */
626 if (ioctl(fd, DKIOCINFO, &dkinfo) == -1) {
627 if (option_msg && diag_msg) {
628 err_print("DKIOCINFO failed\n");
629 }
630 return (NULL);
631 }
632
633 /*
634 * Find the ctlr_info for this disk.
635 */
636 ctlr = find_ctlr_info(&dkinfo, dkinfo.dki_ctype);
637
638 /*
639 * Allocate a new disk type for the direct controller.
640 */
641 disk = (struct disk_type *)zalloc(sizeof (struct disk_type));
642
643 /*
644 * Find the disk_info instance for this disk.
645 */
646 disk_info = find_disk_info(&dkinfo, dkinfo.dki_ctype);
647
648 /*
649 * The controller and the disk should match.
650 */
651 assert(disk_info->disk_ctlr == ctlr);
652
653 /*
654 * Link the disk into the list of disks
655 */
656 dp = ctlr->ctlr_ctype->ctype_dlist;
657 if (dp == NULL) {
658 ctlr->ctlr_ctype->ctype_dlist = dp;
659 } else {
660 while (dp->dtype_next != NULL) {
661 dp = dp->dtype_next;
662 }
663 dp->dtype_next = disk;
664 }
665 disk->dtype_next = NULL;
666
1935 LEN_DKL_VVOL);
1936 part->vtoc = label->dkl_vtoc;
1937 } else {
1938 (void) memset(disk_info->v_volume, 0, LEN_DKL_VVOL);
1939 set_vtoc_defaults(part);
1940 }
1941
1942 /*
1943 * Link the disk to the partition map
1944 */
1945 disk_info->disk_parts = part;
1946
1947 return (disk);
1948 }
1949
1950
1951 /*
1952 * Delete a disk type from disk type list.
1953 */
1954 int
1955 delete_disk_type(struct disk_type *disk_type)
1956 {
1957 struct ctlr_type *ctlr;
1958 struct disk_type *dp, *disk;
1959
1960 if (cur_ctype->ctype_ctype == DKC_DIRECT ||
1961 cur_ctype->ctype_ctype == DKC_VBD ||
1962 cur_ctype->ctype_ctype == DKC_BLKDEV)
1963 ctlr = find_ctlr_type(cur_ctype->ctype_ctype);
1964 else
1965 ctlr = find_scsi_ctlr_type();
1966 if (ctlr == NULL || ctlr->ctype_dlist == NULL) {
1967 return (-1);
1968 }
1969
1970 disk = ctlr->ctype_dlist;
1971 if (disk == disk_type) {
1972 ctlr->ctype_dlist = disk->dtype_next;
1973 if (cur_label == L_TYPE_EFI)
1974 free(disk->dtype_plist->etoc);
1975 free(disk->dtype_plist);
1976 free(disk->vendor);
1977 free(disk->product);
1978 free(disk->revision);
1979 free(disk);
1980 return (0);
1981 } else {
1982 for (dp = disk->dtype_next; dp != NULL;
1983 disk = disk->dtype_next, dp = dp->dtype_next) {
|