1 /* $NetBSD: rf.c,v 1.37 2021/08/12 19:53:18 andvar Exp $ */ 2 /* 3 * Copyright (c) 2002 Jochen Kunz. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of Jochen Kunz may not be used to endorse or promote 15 * products derived from this software without specific prior 16 * written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY JOCHEN KUNZ 19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JOCHEN KUNZ 22 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 /* 32 TODO: 33 - Better LBN bound checking, block padding for SD disks. 34 - Formatting / "Set Density" 35 - Better error handling / detailed error reason reporting. 36 */ 37 38 #include <sys/cdefs.h> 39 __KERNEL_RCSID(0, "$NetBSD: rf.c,v 1.37 2021/08/12 19:53:18 andvar Exp $"); 40 41 /* autoconfig stuff */ 42 #include <sys/param.h> 43 #include <sys/device.h> 44 #include <sys/conf.h> 45 #include "locators.h" 46 #include "ioconf.h" 47 48 /* bus_space / bus_dma */ 49 #include <sys/bus.h> 50 51 /* UniBus / QBus specific stuff */ 52 #include <dev/qbus/ubavar.h> 53 54 /* disk interface */ 55 #include <sys/types.h> 56 #include <sys/disklabel.h> 57 #include <sys/disk.h> 58 59 /* general system data and functions */ 60 #include <sys/systm.h> 61 #include <sys/ioctl.h> 62 #include <sys/ioccom.h> 63 64 /* physio / buffer handling */ 65 #include <sys/buf.h> 66 #include <sys/bufq.h> 67 68 /* tsleep / sleep / wakeup */ 69 #include <sys/proc.h> 70 /* hz for above */ 71 #include <sys/kernel.h> 72 73 /* bit definitions for RX211 */ 74 #include <dev/qbus/rfreg.h> 75 76 77 #define RFS_DENS 0x0001 /* single or double density */ 78 #define RFS_AD 0x0002 /* density auto detect */ 79 #define RFS_NOTINIT 0x0000 /* not initialized */ 80 #define RFS_PROBING 0x0010 /* density detect / verify started */ 81 #define RFS_FBUF 0x0020 /* Fill Buffer */ 82 #define RFS_EBUF 0x0030 /* Empty Buffer */ 83 #define RFS_WSEC 0x0040 /* Write Sector */ 84 #define RFS_RSEC 0x0050 /* Read Sector */ 85 #define RFS_SMD 0x0060 /* Set Media Density */ 86 #define RFS_RSTAT 0x0070 /* Read Status */ 87 #define RFS_WDDS 0x0080 /* Write Deleted Data Sector */ 88 #define RFS_REC 0x0090 /* Read Error Code */ 89 #define RFS_IDLE 0x00a0 /* controller is idle */ 90 #define RFS_CMDS 0x00f0 /* command mask */ 91 #define RFS_OPEN_A 0x0100 /* partition a open */ 92 #define RFS_OPEN_B 0x0200 /* partition b open */ 93 #define RFS_OPEN_C 0x0400 /* partition c open */ 94 #define RFS_OPEN_MASK 0x0f00 /* mask for open partitions */ 95 #define RFS_OPEN_SHIFT 8 /* to shift 1 to get RFS_OPEN_A */ 96 #define RFS_SETCMD(rf, state) ((rf) = ((rf) & ~RFS_CMDS) | (state)) 97 98 99 100 /* autoconfig stuff */ 101 static int rfc_match(device_t, cfdata_t, void *); 102 static void rfc_attach(device_t, device_t, void *); 103 static int rf_match(device_t, cfdata_t, void *); 104 static void rf_attach(device_t, device_t, void *); 105 static int rf_print(void *, const char *); 106 107 /* device interface functions / interface to disk(9) */ 108 dev_type_open(rfopen); 109 dev_type_close(rfclose); 110 dev_type_read(rfread); 111 dev_type_write(rfwrite); 112 dev_type_ioctl(rfioctl); 113 dev_type_strategy(rfstrategy); 114 dev_type_dump(rfdump); 115 dev_type_size(rfsize); 116 117 118 /* Entries in block and character major device number switch table. */ 119 const struct bdevsw rf_bdevsw = { 120 .d_open = rfopen, 121 .d_close = rfclose, 122 .d_strategy = rfstrategy, 123 .d_ioctl = rfioctl, 124 .d_dump = rfdump, 125 .d_psize = rfsize, 126 .d_discard = nodiscard, 127 .d_flag = D_DISK 128 }; 129 130 const struct cdevsw rf_cdevsw = { 131 .d_open = rfopen, 132 .d_close = rfclose, 133 .d_read = rfread, 134 .d_write = rfwrite, 135 .d_ioctl = rfioctl, 136 .d_stop = nostop, 137 .d_tty = notty, 138 .d_poll = nopoll, 139 .d_mmap = nommap, 140 .d_kqfilter = nokqfilter, 141 .d_discard = nodiscard, 142 .d_flag = D_DISK 143 }; 144 145 146 147 struct rfc_softc { 148 device_t sc_dev; /* common device data */ 149 device_t sc_childs[2]; /* child devices */ 150 struct evcnt sc_intr_count; /* Interrupt counter for statistics */ 151 struct buf *sc_curbuf; /* buf that is currently in work */ 152 bus_space_tag_t sc_iot; /* bus_space I/O tag */ 153 bus_space_handle_t sc_ioh; /* bus_space I/O handle */ 154 bus_dma_tag_t sc_dmat; /* bus_dma DMA tag */ 155 bus_dmamap_t sc_dmam; /* bus_dma DMA map */ 156 void *sc_bufidx; /* current position in buffer data */ 157 int sc_curchild; /* child whos bufq is in work */ 158 int sc_bytesleft; /* bytes left to transfer */ 159 u_int8_t type; /* controller type, 1 or 2 */ 160 }; 161 162 163 164 CFATTACH_DECL_NEW( 165 rfc, 166 sizeof(struct rfc_softc), 167 rfc_match, 168 rfc_attach, 169 NULL, 170 NULL 171 ); 172 173 174 175 struct rf_softc { 176 device_t sc_dev; /* common device data */ 177 struct disk sc_disk; /* common disk device data */ 178 struct rfc_softc *sc_rfc; /* our parent */ 179 struct bufq_state *sc_bufq; /* queue of pending transfers */ 180 int sc_state; /* state of drive */ 181 u_int8_t sc_dnum; /* drive number, 0 or 1 */ 182 }; 183 184 185 186 CFATTACH_DECL_NEW( 187 rf, 188 sizeof(struct rf_softc), 189 rf_match, 190 rf_attach, 191 NULL, 192 NULL 193 ); 194 195 196 197 struct rfc_attach_args { 198 u_int8_t type; /* controller type, 1 or 2 */ 199 u_int8_t dnum; /* drive number, 0 or 1 */ 200 }; 201 202 203 204 const struct dkdriver rfdkdriver = { 205 .d_strategy = rfstrategy 206 }; 207 208 209 210 /* helper functions */ 211 int rfc_sendcmd(struct rfc_softc *, int, int, int); 212 struct rf_softc* get_new_buf( struct rfc_softc *); 213 static void rfc_intr(void *); 214 215 216 217 /* 218 * Issue a reset command to the controller and look for the bits in 219 * RX2CS and RX2ES. 220 * RX2CS_RX02 and / or RX2CS_DD can be set, 221 * RX2ES has to be set, all other bits must be 0 222 */ 223 int 224 rfc_match(device_t parent, cfdata_t match, void *aux) 225 { 226 struct uba_attach_args *ua = aux; 227 int i; 228 229 /* Issue reset command. */ 230 bus_space_write_2(ua->ua_iot, ua->ua_ioh, RX2CS, RX2CS_INIT); 231 /* Wait for the controller to become ready, that is when 232 * RX2CS_DONE, RX2ES_RDY and RX2ES_ID are set. */ 233 for (i = 0 ; i < 20 ; i++) { 234 if ((bus_space_read_2(ua->ua_iot, ua->ua_ioh, RX2CS) 235 & RX2CS_DONE) != 0 236 && (bus_space_read_2(ua->ua_iot, ua->ua_ioh, RX2ES) 237 & (RX2ES_RDY | RX2ES_ID)) != 0) 238 break; 239 DELAY(100000); /* wait 100ms */ 240 } 241 /* 242 * Give up if the timeout has elapsed 243 * and the controller is not ready. 244 */ 245 if (i >= 20) 246 return(0); 247 /* 248 * Issue a Read Status command with interrupt enabled. 249 * The uba(4) driver wants to catch the interrupt to get the 250 * interrupt vector and level of the device 251 */ 252 bus_space_write_2(ua->ua_iot, ua->ua_ioh, RX2CS, 253 RX2CS_RSTAT | RX2CS_IE); 254 /* 255 * Wait for command to finish, ignore errors and 256 * abort if the controller does not respond within the timeout 257 */ 258 for (i = 0 ; i < 20 ; i++) { 259 if ((bus_space_read_2(ua->ua_iot, ua->ua_ioh, RX2CS) 260 & (RX2CS_DONE | RX2CS_IE)) != 0 261 && (bus_space_read_2(ua->ua_iot, ua->ua_ioh, RX2ES) 262 & RX2ES_RDY) != 0 ) 263 return(1); 264 DELAY(100000); /* wait 100ms */ 265 } 266 return(0); 267 } 268 269 270 271 /* #define RX02_PROBE 1 */ 272 #ifdef RX02_PROBE 273 /* 274 * Probe the density of an inserted floppy disk. 275 * This is done by reading a sector from disk. 276 * Return -1 on error, 0 on SD and 1 on DD. 277 */ 278 int rfcprobedens(struct rfc_softc *, int); 279 int 280 rfcprobedens(struct rfc_softc *rfc_sc, int dnum) 281 { 282 int dens_flag; 283 int i; 284 285 dens_flag = 0; 286 do { 287 bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS, 288 RX2CS_RSEC | (dens_flag == 0 ? 0 : RX2CS_DD) 289 | (dnum == 0 ? 0 : RX2CS_US)); 290 /* 291 * Transfer request set? 292 * Wait 50us, the controller needs this time to setle 293 */ 294 DELAY(50); 295 if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS) 296 & RX2CS_TR) == 0) { 297 printf("%s: did not respond to Read Sector CMD(1)\n", 298 device_xname(rfc_sc->sc_dev)); 299 return(-1); 300 } 301 bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2SA, 1); 302 /* Wait 50us, the controller needs this time to setle */ 303 DELAY(50); 304 if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS) 305 & RX2CS_TR) == 0) { 306 printf("%s: did not respond to Read Sector CMD(2)\n", 307 device_xname(rfc_sc->sc_dev)); 308 return(-1); 309 } 310 bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2TA, 1); 311 /* Wait for the command to finish */ 312 for (i = 0 ; i < 200 ; i++) { 313 if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, 314 RX2CS) & RX2CS_DONE) != 0) 315 break; 316 DELAY(10000); /* wait 10ms */ 317 } 318 if (i >= 200) { 319 printf("%s: did not respond to Read Sector CMD(3)\n", 320 device_xname(rfc_sc->sc_dev)); 321 return(-1); 322 } 323 if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS) 324 & RX2CS_ERR) == 0) 325 return(dens_flag); 326 } while (rfc_sc->type == 2 && dens_flag++ == 0); 327 return(-1); 328 } 329 #endif /* RX02_PROBE */ 330 331 332 333 void 334 rfc_attach(device_t parent, device_t self, void *aux) 335 { 336 struct rfc_softc *rfc_sc = device_private(self); 337 struct uba_attach_args *ua = aux; 338 struct rfc_attach_args rfc_aa; 339 int i; 340 341 rfc_sc->sc_dev = self; 342 rfc_sc->sc_iot = ua->ua_iot; 343 rfc_sc->sc_ioh = ua->ua_ioh; 344 rfc_sc->sc_dmat = ua->ua_dmat; 345 rfc_sc->sc_curbuf = NULL; 346 /* Tell the QBus busdriver about our interrupt handler. */ 347 uba_intr_establish(ua->ua_icookie, ua->ua_cvec, rfc_intr, rfc_sc, 348 &rfc_sc->sc_intr_count); 349 /* Attach to the interrupt counter, see evcnt(9) */ 350 evcnt_attach_dynamic(&rfc_sc->sc_intr_count, EVCNT_TYPE_INTR, 351 ua->ua_evcnt, device_xname(rfc_sc->sc_dev), "intr"); 352 /* get a bus_dma(9) handle */ 353 i = bus_dmamap_create(rfc_sc->sc_dmat, RX2_BYTE_DD, 1, RX2_BYTE_DD, 0, 354 BUS_DMA_ALLOCNOW, &rfc_sc->sc_dmam); 355 if (i != 0) { 356 printf("rfc_attach: Error creating bus dma map: %d\n", i); 357 return; 358 } 359 360 /* Issue reset command. */ 361 bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS, RX2CS_INIT); 362 /* 363 * Wait for the controller to become ready, that is when 364 * RX2CS_DONE, RX2ES_RDY and RX2ES_ID are set. 365 */ 366 for (i = 0 ; i < 20 ; i++) { 367 if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS) 368 & RX2CS_DONE) != 0 369 && (bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2ES) 370 & (RX2ES_RDY | RX2ES_ID)) != 0) 371 break; 372 DELAY(100000); /* wait 100ms */ 373 } 374 /* 375 * Give up if the timeout has elapsed 376 * and the controller is not ready. 377 */ 378 if (i >= 20) { 379 printf(": did not respond to INIT CMD\n"); 380 return; 381 } 382 /* Is ths a RX01 or a RX02? */ 383 if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS) 384 & RX2CS_RX02) != 0) { 385 rfc_sc->type = 2; 386 rfc_aa.type = 2; 387 } else { 388 rfc_sc->type = 1; 389 rfc_aa.type = 1; 390 } 391 printf(": RX0%d\n", rfc_sc->type); 392 393 #ifndef RX02_PROBE 394 /* 395 * Both disk drives and the controller are one physical unit. 396 * If we found the controller, there will be both disk drives. 397 * So attach them. 398 */ 399 rfc_aa.dnum = 0; 400 rfc_sc->sc_childs[0] = config_found(rfc_sc->sc_dev, &rfc_aa, rf_print, 401 CFARGS_NONE); 402 rfc_aa.dnum = 1; 403 rfc_sc->sc_childs[1] = config_found(rfc_sc->sc_dev, &rfc_aa, rf_print, 404 CFARGS_NONE); 405 #else /* RX02_PROBE */ 406 /* 407 * There are clones of the DEC RX system with standard shugart 408 * interface. In this case we can not be sure that there are 409 * both disk drives. So we want to do a detection of attached 410 * drives. This is done by reading a sector from disk. This means 411 * that there must be a formatted disk in the drive at boot time. 412 * This is bad, but I did not find another way to detect the 413 * (non)existence of a floppy drive. 414 */ 415 if (rfcprobedens(rfc_sc, 0) >= 0) { 416 rfc_aa.dnum = 0; 417 rfc_sc->sc_childs[0] = config_found(rfc_sc->sc_dev, &rfc_aa, 418 rf_print, CFARGS_NONE); 419 } else 420 rfc_sc->sc_childs[0] = NULL; 421 if (rfcprobedens(rfc_sc, 1) >= 0) { 422 rfc_aa.dnum = 1; 423 rfc_sc->sc_childs[1] = config_found(rfc_sc->sc_dev, &rfc_aa, 424 rf_print, CFARGS_NONE); 425 } else 426 rfc_sc->sc_childs[1] = NULL; 427 #endif /* RX02_PROBE */ 428 return; 429 } 430 431 432 433 int 434 rf_match(device_t parent, cfdata_t match, void *aux) 435 { 436 struct rfc_attach_args *rfc_aa = aux; 437 438 /* 439 * Only attach if the locator is wildcarded or 440 * if the specified locator addresses the current device. 441 */ 442 if (match->cf_loc[RFCCF_DRIVE] == RFCCF_DRIVE_DEFAULT || 443 match->cf_loc[RFCCF_DRIVE] == rfc_aa->dnum) 444 return(1); 445 return(0); 446 } 447 448 449 450 void 451 rf_attach(device_t parent, device_t self, void *aux) 452 { 453 struct rf_softc *rf_sc = device_private(self); 454 struct rfc_softc *rfc_sc = device_private(parent); 455 struct rfc_attach_args *rfc_aa = (struct rfc_attach_args *)aux; 456 struct disklabel *dl; 457 458 rf_sc->sc_dev = self; 459 rf_sc->sc_rfc = rfc_sc; 460 rf_sc->sc_dnum = rfc_aa->dnum; 461 rf_sc->sc_state = 0; 462 disk_init(&rf_sc->sc_disk, device_xname(rf_sc->sc_dev), &rfdkdriver); 463 disk_attach(&rf_sc->sc_disk); 464 dl = rf_sc->sc_disk.dk_label; 465 dl->d_type = DKTYPE_FLOPPY; /* drive type */ 466 dl->d_magic = DISKMAGIC; /* the magic number */ 467 dl->d_magic2 = DISKMAGIC; 468 dl->d_typename[0] = 'R'; 469 dl->d_typename[1] = 'X'; 470 dl->d_typename[2] = '0'; 471 dl->d_typename[3] = rfc_sc->type == 1 ? '1' : '2'; /* type name */ 472 dl->d_typename[4] = '\0'; 473 dl->d_secsize = DEV_BSIZE; /* bytes per sector */ 474 /* 475 * Fill in some values to have an initialized data structure. Some 476 * values will be reset by rfopen() depending on the actual density. 477 */ 478 dl->d_nsectors = RX2_SECTORS; /* sectors per track */ 479 dl->d_ntracks = 1; /* tracks per cylinder */ 480 dl->d_ncylinders = RX2_TRACKS; /* cylinders per unit */ 481 dl->d_secpercyl = RX2_SECTORS; /* sectors per cylinder */ 482 dl->d_secperunit = RX2_SECTORS * RX2_TRACKS; /* sectors per unit */ 483 dl->d_rpm = 360; /* rotational speed */ 484 dl->d_interleave = 1; /* hardware sector interleave */ 485 /* number of partitions in following */ 486 dl->d_npartitions = MAXPARTITIONS; 487 dl->d_bbsize = 0; /* size of boot area at sn0, bytes */ 488 dl->d_sbsize = 0; /* max size of fs superblock, bytes */ 489 /* number of sectors in partition */ 490 dl->d_partitions[0].p_size = 501; 491 dl->d_partitions[0].p_offset = 0; /* starting sector */ 492 dl->d_partitions[0].p_fsize = 0; /* fs basic fragment size */ 493 dl->d_partitions[0].p_fstype = 0; /* fs type */ 494 dl->d_partitions[0].p_frag = 0; /* fs fragments per block */ 495 dl->d_partitions[1].p_size = RX2_SECTORS * RX2_TRACKS / 2; 496 dl->d_partitions[1].p_offset = 0; /* starting sector */ 497 dl->d_partitions[1].p_fsize = 0; /* fs basic fragment size */ 498 dl->d_partitions[1].p_fstype = 0; /* fs type */ 499 dl->d_partitions[1].p_frag = 0; /* fs fragments per block */ 500 dl->d_partitions[2].p_size = RX2_SECTORS * RX2_TRACKS; 501 dl->d_partitions[2].p_offset = 0; /* starting sector */ 502 dl->d_partitions[2].p_fsize = 0; /* fs basic fragment size */ 503 dl->d_partitions[2].p_fstype = 0; /* fs type */ 504 dl->d_partitions[2].p_frag = 0; /* fs fragments per block */ 505 bufq_alloc(&rf_sc->sc_bufq, "disksort", BUFQ_SORT_CYLINDER); 506 printf("\n"); 507 return; 508 } 509 510 511 512 int 513 rf_print(void *aux, const char *name) 514 { 515 struct rfc_attach_args *rfc_aa = aux; 516 517 if (name != NULL) 518 aprint_normal("RX0%d at %s", rfc_aa->type, name); 519 aprint_normal(" drive %d", rfc_aa->dnum); 520 return(UNCONF); 521 } 522 523 524 525 /* Send a command to the controller */ 526 int 527 rfc_sendcmd(struct rfc_softc *rfc_sc, int cmd, int data1, int data2) 528 { 529 530 /* Write command to CSR. */ 531 bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS, cmd); 532 /* Wait 50us, the controller needs this time to setle. */ 533 DELAY(50); 534 /* Write parameter 1 to DBR */ 535 if ((cmd & RX2CS_MASK) != RX2CS_RSTAT) { 536 /* Transfer request set? */ 537 if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS) 538 & RX2CS_TR) == 0) { 539 printf("%s: did not respond to CMD %x (1)\n", 540 device_xname(rfc_sc->sc_dev), cmd); 541 return(-1); 542 } 543 bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2DB, 544 data1); 545 } 546 /* Write parameter 2 to DBR */ 547 if ((cmd & RX2CS_MASK) <= RX2CS_RSEC || 548 (cmd & RX2CS_MASK) == RX2CS_WDDS) { 549 /* Wait 50us, the controller needs this time to setle. */ 550 DELAY(50); 551 /* Transfer request set? */ 552 if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2CS) 553 & RX2CS_TR) == 0) { 554 printf("%s: did not respond to CMD %x (2)\n", 555 device_xname(rfc_sc->sc_dev), cmd); 556 return(-1); 557 } 558 bus_space_write_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, RX2DB, 559 data2); 560 } 561 return(1); 562 } 563 564 565 566 void 567 rfstrategy(struct buf *buf) 568 { 569 struct rf_softc *rf_sc; 570 struct rfc_softc *rfc_sc; 571 int s; 572 573 if ((rf_sc = device_lookup_private(&rf_cd, DISKUNIT(buf->b_dev))) == NULL) { 574 buf->b_error = ENXIO; 575 biodone(buf); 576 return; 577 } 578 rfc_sc = rf_sc->sc_rfc; 579 /* We are going to operate on a non-open dev? PANIC! */ 580 if ((rf_sc->sc_state & (1 << (DISKPART(buf->b_dev) + RFS_OPEN_SHIFT))) 581 == 0) 582 panic("rfstrategy: can not operate on non-open drive %s " 583 "partition %"PRIu32, device_xname(rf_sc->sc_dev), 584 DISKPART(buf->b_dev)); 585 if (buf->b_bcount == 0) { 586 biodone(buf); 587 return; 588 } 589 /* 590 * bufq_put() operates on b_rawblkno. rfstrategy() gets 591 * only b_blkno that is partition relative. As a floppy does not 592 * have partitions b_rawblkno == b_blkno. 593 */ 594 buf->b_rawblkno = buf->b_blkno; 595 /* 596 * from sys/kern/subr_disk.c: 597 * Seek sort for disks. We depend on the driver which calls us using 598 * b_resid as the current cylinder number. 599 */ 600 s = splbio(); 601 if (rfc_sc->sc_curbuf == NULL) { 602 rfc_sc->sc_curchild = rf_sc->sc_dnum; 603 rfc_sc->sc_curbuf = buf; 604 rfc_sc->sc_bufidx = buf->b_data; 605 rfc_sc->sc_bytesleft = buf->b_bcount; 606 rfc_intr(rfc_sc); 607 } else { 608 buf->b_resid = buf->b_blkno / RX2_SECTORS; 609 bufq_put(rf_sc->sc_bufq, buf); 610 buf->b_resid = 0; 611 } 612 splx(s); 613 } 614 615 /* 616 * Look if there is another buffer in the bufferqueue of this drive 617 * and start to process it if there is one. 618 * If the bufferqueue is empty, look at the bufferqueue of the other drive 619 * that is attached to this controller. 620 * Start processing the bufferqueue of the other drive if it isn't empty. 621 * Return a pointer to the softc structure of the drive that is now 622 * ready to process a buffer or NULL if there is no buffer in either queues. 623 */ 624 struct rf_softc* 625 get_new_buf( struct rfc_softc *rfc_sc) 626 { 627 struct rf_softc *rf_sc; 628 struct rf_softc *other_drive; 629 630 rf_sc = device_private(rfc_sc->sc_childs[rfc_sc->sc_curchild]); 631 rfc_sc->sc_curbuf = bufq_get(rf_sc->sc_bufq); 632 if (rfc_sc->sc_curbuf != NULL) { 633 rfc_sc->sc_bufidx = rfc_sc->sc_curbuf->b_data; 634 rfc_sc->sc_bytesleft = rfc_sc->sc_curbuf->b_bcount; 635 } else { 636 RFS_SETCMD(rf_sc->sc_state, RFS_IDLE); 637 other_drive = device_private( 638 rfc_sc->sc_childs[ rfc_sc->sc_curchild == 0 ? 1 : 0]); 639 if (other_drive != NULL 640 && bufq_peek(other_drive->sc_bufq) != NULL) { 641 rfc_sc->sc_curchild = rfc_sc->sc_curchild == 0 ? 1 : 0; 642 rf_sc = other_drive; 643 rfc_sc->sc_curbuf = bufq_get(rf_sc->sc_bufq); 644 rfc_sc->sc_bufidx = rfc_sc->sc_curbuf->b_data; 645 rfc_sc->sc_bytesleft = rfc_sc->sc_curbuf->b_bcount; 646 } else 647 return(NULL); 648 } 649 return(rf_sc); 650 } 651 652 653 654 void 655 rfc_intr(void *intarg) 656 { 657 struct rfc_softc *rfc_sc = intarg; 658 struct rf_softc *rf_sc; 659 int i; 660 661 rf_sc = device_private(rfc_sc->sc_childs[rfc_sc->sc_curchild]); 662 for (;;) { 663 /* 664 * First clean up from previous command... 665 */ 666 switch (rf_sc->sc_state & RFS_CMDS) { 667 case RFS_PROBING: /* density detect / verify started */ 668 disk_unbusy(&rf_sc->sc_disk, 0, 1); 669 if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, 670 RX2CS) & RX2CS_ERR) == 0) { 671 RFS_SETCMD(rf_sc->sc_state, RFS_IDLE); 672 wakeup(rf_sc); 673 } else { 674 if (rfc_sc->type == 2 675 && (rf_sc->sc_state & RFS_DENS) == 0 676 && (rf_sc->sc_state & RFS_AD) != 0) { 677 /* retry at DD */ 678 rf_sc->sc_state |= RFS_DENS; 679 disk_busy(&rf_sc->sc_disk); 680 if (rfc_sendcmd(rfc_sc, RX2CS_RSEC 681 | RX2CS_IE | RX2CS_DD | 682 (rf_sc->sc_dnum == 0 ? 0 : 683 RX2CS_US), 1, 1) < 0) { 684 disk_unbusy(&rf_sc->sc_disk, 685 0, 1); 686 RFS_SETCMD(rf_sc->sc_state, 687 RFS_NOTINIT); 688 wakeup(rf_sc); 689 } 690 } else { 691 printf("%s: density error.\n", 692 device_xname(rf_sc->sc_dev)); 693 RFS_SETCMD(rf_sc->sc_state,RFS_NOTINIT); 694 wakeup(rf_sc); 695 } 696 } 697 return; 698 case RFS_IDLE: /* controller is idle */ 699 if (rfc_sc->sc_curbuf->b_bcount 700 % ((rf_sc->sc_state & RFS_DENS) == 0 701 ? RX2_BYTE_SD : RX2_BYTE_DD) != 0) { 702 /* 703 * can only handle blocks that are a multiple 704 * of the physical block size 705 */ 706 rfc_sc->sc_curbuf->b_error = EIO; 707 } 708 RFS_SETCMD(rf_sc->sc_state, (rfc_sc->sc_curbuf->b_flags 709 & B_READ) != 0 ? RFS_RSEC : RFS_FBUF); 710 break; 711 case RFS_RSEC: /* Read Sector */ 712 disk_unbusy(&rf_sc->sc_disk, 0, 1); 713 /* check for errors */ 714 if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, 715 RX2CS) & RX2CS_ERR) != 0) { 716 /* should do more verbose error reporting */ 717 printf("rfc_intr: Error reading secotr: %x\n", 718 bus_space_read_2(rfc_sc->sc_iot, 719 rfc_sc->sc_ioh, RX2ES) ); 720 rfc_sc->sc_curbuf->b_error = EIO; 721 } 722 RFS_SETCMD(rf_sc->sc_state, RFS_EBUF); 723 break; 724 case RFS_WSEC: /* Write Sector */ 725 i = (rf_sc->sc_state & RFS_DENS) == 0 726 ? RX2_BYTE_SD : RX2_BYTE_DD; 727 disk_unbusy(&rf_sc->sc_disk, i, 0); 728 /* check for errors */ 729 if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, 730 RX2CS) & RX2CS_ERR) != 0) { 731 /* should do more verbose error reporting */ 732 printf("rfc_intr: Error writing secotr: %x\n", 733 bus_space_read_2(rfc_sc->sc_iot, 734 rfc_sc->sc_ioh, RX2ES) ); 735 rfc_sc->sc_curbuf->b_error = EIO; 736 break; 737 } 738 if (rfc_sc->sc_bytesleft > i) { 739 rfc_sc->sc_bytesleft -= i; 740 rfc_sc->sc_bufidx = 741 (char *)rfc_sc->sc_bufidx + i; 742 } else { 743 biodone(rfc_sc->sc_curbuf); 744 rf_sc = get_new_buf( rfc_sc); 745 if (rf_sc == NULL) 746 return; 747 } 748 RFS_SETCMD(rf_sc->sc_state, 749 (rfc_sc->sc_curbuf->b_flags & B_READ) != 0 750 ? RFS_RSEC : RFS_FBUF); 751 break; 752 case RFS_FBUF: /* Fill Buffer */ 753 disk_unbusy(&rf_sc->sc_disk, 0, 0); 754 bus_dmamap_unload(rfc_sc->sc_dmat, rfc_sc->sc_dmam); 755 /* check for errors */ 756 if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, 757 RX2CS) & RX2CS_ERR) != 0) { 758 /* should do more verbose error reporting */ 759 printf("rfc_intr: Error while DMA: %x\n", 760 bus_space_read_2(rfc_sc->sc_iot, 761 rfc_sc->sc_ioh, RX2ES)); 762 rfc_sc->sc_curbuf->b_error = EIO; 763 } 764 RFS_SETCMD(rf_sc->sc_state, RFS_WSEC); 765 break; 766 case RFS_EBUF: /* Empty Buffer */ 767 i = (rf_sc->sc_state & RFS_DENS) == 0 768 ? RX2_BYTE_SD : RX2_BYTE_DD; 769 disk_unbusy(&rf_sc->sc_disk, i, 1); 770 bus_dmamap_unload(rfc_sc->sc_dmat, rfc_sc->sc_dmam); 771 /* check for errors */ 772 if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh, 773 RX2CS) & RX2CS_ERR) != 0) { 774 /* should do more verbose error reporting */ 775 printf("rfc_intr: Error while DMA: %x\n", 776 bus_space_read_2(rfc_sc->sc_iot, 777 rfc_sc->sc_ioh, RX2ES)); 778 rfc_sc->sc_curbuf->b_error = EIO; 779 break; 780 } 781 if (rfc_sc->sc_bytesleft > i) { 782 rfc_sc->sc_bytesleft -= i; 783 rfc_sc->sc_bufidx = 784 (char *)rfc_sc->sc_bufidx + i; 785 } else { 786 biodone(rfc_sc->sc_curbuf); 787 rf_sc = get_new_buf( rfc_sc); 788 if (rf_sc == NULL) 789 return; 790 } 791 RFS_SETCMD(rf_sc->sc_state, 792 (rfc_sc->sc_curbuf->b_flags & B_READ) != 0 793 ? RFS_RSEC : RFS_FBUF); 794 break; 795 case RFS_NOTINIT: /* Device is not open */ 796 case RFS_SMD: /* Set Media Density */ 797 case RFS_RSTAT: /* Read Status */ 798 case RFS_WDDS: /* Write Deleted Data Sector */ 799 case RFS_REC: /* Read Error Code */ 800 default: 801 panic("Impossible state in rfc_intr(1): 0x%x\n", 802 rf_sc->sc_state & RFS_CMDS); 803 } 804 805 if (rfc_sc->sc_curbuf->b_error != 0) { 806 /* 807 * An error occurred while processing this buffer. 808 * Finish it and try to get a new buffer to process. 809 * Return if there are no buffers in the queues. 810 * This loops until the queues are empty or a new 811 * action was successfully scheduled. 812 */ 813 rfc_sc->sc_curbuf->b_resid = rfc_sc->sc_bytesleft; 814 rfc_sc->sc_curbuf->b_error = EIO; 815 biodone(rfc_sc->sc_curbuf); 816 rf_sc = get_new_buf( rfc_sc); 817 if (rf_sc == NULL) 818 return; 819 continue; 820 } 821 822 /* 823 * ... then initiate next command. 824 */ 825 switch (rf_sc->sc_state & RFS_CMDS) { 826 case RFS_EBUF: /* Empty Buffer */ 827 i = bus_dmamap_load(rfc_sc->sc_dmat, rfc_sc->sc_dmam, 828 rfc_sc->sc_bufidx, (rf_sc->sc_state & RFS_DENS) == 0 829 ? RX2_BYTE_SD : RX2_BYTE_DD, 830 rfc_sc->sc_curbuf->b_proc, BUS_DMA_NOWAIT); 831 if (i != 0) { 832 printf("rfc_intr: Error loading dmamap: %d\n", 833 i); 834 rfc_sc->sc_curbuf->b_error = EIO; 835 break; 836 } 837 disk_busy(&rf_sc->sc_disk); 838 if (rfc_sendcmd(rfc_sc, RX2CS_EBUF | RX2CS_IE 839 | ((rf_sc->sc_state & RFS_DENS) == 0 ? 0 : RX2CS_DD) 840 | (rf_sc->sc_dnum == 0 ? 0 : RX2CS_US) 841 | ((rfc_sc->sc_dmam->dm_segs[0].ds_addr 842 & 0x30000) >>4), ((rf_sc->sc_state & RFS_DENS) == 0 843 ? RX2_BYTE_SD : RX2_BYTE_DD) / 2, 844 rfc_sc->sc_dmam->dm_segs[0].ds_addr & 0xffff) < 0) { 845 disk_unbusy(&rf_sc->sc_disk, 0, 1); 846 rfc_sc->sc_curbuf->b_error = EIO; 847 bus_dmamap_unload(rfc_sc->sc_dmat, 848 rfc_sc->sc_dmam); 849 } 850 break; 851 case RFS_FBUF: /* Fill Buffer */ 852 i = bus_dmamap_load(rfc_sc->sc_dmat, rfc_sc->sc_dmam, 853 rfc_sc->sc_bufidx, (rf_sc->sc_state & RFS_DENS) == 0 854 ? RX2_BYTE_SD : RX2_BYTE_DD, 855 rfc_sc->sc_curbuf->b_proc, BUS_DMA_NOWAIT); 856 if (i != 0) { 857 printf("rfc_intr: Error loading dmamap: %d\n", 858 i); 859 rfc_sc->sc_curbuf->b_error = EIO; 860 break; 861 } 862 disk_busy(&rf_sc->sc_disk); 863 if (rfc_sendcmd(rfc_sc, RX2CS_FBUF | RX2CS_IE 864 | ((rf_sc->sc_state & RFS_DENS) == 0 ? 0 : RX2CS_DD) 865 | (rf_sc->sc_dnum == 0 ? 0 : RX2CS_US) 866 | ((rfc_sc->sc_dmam->dm_segs[0].ds_addr 867 & 0x30000)>>4), ((rf_sc->sc_state & RFS_DENS) == 0 868 ? RX2_BYTE_SD : RX2_BYTE_DD) / 2, 869 rfc_sc->sc_dmam->dm_segs[0].ds_addr & 0xffff) < 0) { 870 disk_unbusy(&rf_sc->sc_disk, 0, 0); 871 rfc_sc->sc_curbuf->b_error = EIO; 872 bus_dmamap_unload(rfc_sc->sc_dmat, 873 rfc_sc->sc_dmam); 874 } 875 break; 876 case RFS_WSEC: /* Write Sector */ 877 i = (rfc_sc->sc_curbuf->b_bcount - rfc_sc->sc_bytesleft 878 + rfc_sc->sc_curbuf->b_blkno * DEV_BSIZE) / 879 ((rf_sc->sc_state & RFS_DENS) == 0 880 ? RX2_BYTE_SD : RX2_BYTE_DD); 881 if (i > RX2_TRACKS * RX2_SECTORS) { 882 rfc_sc->sc_curbuf->b_error = EIO; 883 break; 884 } 885 disk_busy(&rf_sc->sc_disk); 886 if (rfc_sendcmd(rfc_sc, RX2CS_WSEC | RX2CS_IE 887 | (rf_sc->sc_dnum == 0 ? 0 : RX2CS_US) 888 | ((rf_sc->sc_state& RFS_DENS) == 0 ? 0 : RX2CS_DD), 889 i % RX2_SECTORS + 1, i / RX2_SECTORS) < 0) { 890 disk_unbusy(&rf_sc->sc_disk, 0, 0); 891 rfc_sc->sc_curbuf->b_error = EIO; 892 } 893 break; 894 case RFS_RSEC: /* Read Sector */ 895 i = (rfc_sc->sc_curbuf->b_bcount - rfc_sc->sc_bytesleft 896 + rfc_sc->sc_curbuf->b_blkno * DEV_BSIZE) / 897 ((rf_sc->sc_state & RFS_DENS) == 0 898 ? RX2_BYTE_SD : RX2_BYTE_DD); 899 if (i > RX2_TRACKS * RX2_SECTORS) { 900 rfc_sc->sc_curbuf->b_error = EIO; 901 break; 902 } 903 disk_busy(&rf_sc->sc_disk); 904 if (rfc_sendcmd(rfc_sc, RX2CS_RSEC | RX2CS_IE 905 | (rf_sc->sc_dnum == 0 ? 0 : RX2CS_US) 906 | ((rf_sc->sc_state& RFS_DENS) == 0 ? 0 : RX2CS_DD), 907 i % RX2_SECTORS + 1, i / RX2_SECTORS) < 0) { 908 disk_unbusy(&rf_sc->sc_disk, 0, 1); 909 rfc_sc->sc_curbuf->b_error = EIO; 910 } 911 break; 912 case RFS_NOTINIT: /* Device is not open */ 913 case RFS_PROBING: /* density detect / verify started */ 914 case RFS_IDLE: /* controller is idle */ 915 case RFS_SMD: /* Set Media Density */ 916 case RFS_RSTAT: /* Read Status */ 917 case RFS_WDDS: /* Write Deleted Data Sector */ 918 case RFS_REC: /* Read Error Code */ 919 default: 920 panic("Impossible state in rfc_intr(2): 0x%x\n", 921 rf_sc->sc_state & RFS_CMDS); 922 } 923 924 if (rfc_sc->sc_curbuf->b_error != 0) { 925 /* 926 * An error occurred while processing this buffer. 927 * Finish it and try to get a new buffer to process. 928 * Return if there are no buffers in the queues. 929 * This loops until the queues are empty or a new 930 * action was successfully scheduled. 931 */ 932 rfc_sc->sc_curbuf->b_resid = rfc_sc->sc_bytesleft; 933 rfc_sc->sc_curbuf->b_error = EIO; 934 biodone(rfc_sc->sc_curbuf); 935 rf_sc = get_new_buf( rfc_sc); 936 if (rf_sc == NULL) 937 return; 938 continue; 939 } 940 break; 941 } 942 return; 943 } 944 945 946 947 int 948 rfdump(dev_t dev, daddr_t blkno, void *va, size_t size) 949 { 950 951 /* A 0.5MB floppy is much to small to take a system dump... */ 952 return(ENXIO); 953 } 954 955 956 957 int 958 rfsize(dev_t dev) 959 { 960 961 return(-1); 962 } 963 964 965 966 int 967 rfopen(dev_t dev, int oflags, int devtype, struct lwp *l) 968 { 969 struct rf_softc *rf_sc; 970 struct rfc_softc *rfc_sc; 971 struct disklabel *dl; 972 973 if ((rf_sc = device_lookup_private(&rf_cd, DISKUNIT(dev))) == NULL) 974 return ENXIO; 975 976 rfc_sc = rf_sc->sc_rfc; 977 dl = rf_sc->sc_disk.dk_label; 978 switch (DISKPART(dev)) { 979 case 0: /* Part. a is single density. */ 980 /* opening in single and double density is senseless */ 981 if ((rf_sc->sc_state & RFS_OPEN_B) != 0 ) 982 return(ENXIO); 983 rf_sc->sc_state &= ~RFS_DENS; 984 rf_sc->sc_state &= ~RFS_AD; 985 rf_sc->sc_state |= RFS_OPEN_A; 986 break; 987 case 1: /* Part. b is double density. */ 988 /* 989 * Opening a single density only drive in double 990 * density or simultaneous opening in single and 991 * double density is senseless. 992 */ 993 if (rfc_sc->type == 1 994 || (rf_sc->sc_state & RFS_OPEN_A) != 0 ) 995 return(ENXIO); 996 rf_sc->sc_state |= RFS_DENS; 997 rf_sc->sc_state &= ~RFS_AD; 998 rf_sc->sc_state |= RFS_OPEN_B; 999 break; 1000 case 2: /* Part. c is auto density. */ 1001 rf_sc->sc_state |= RFS_AD; 1002 rf_sc->sc_state |= RFS_OPEN_C; 1003 break; 1004 default: 1005 return(ENXIO); 1006 break; 1007 } 1008 if ((rf_sc->sc_state & RFS_CMDS) == RFS_NOTINIT) { 1009 rfc_sc->sc_curchild = rf_sc->sc_dnum; 1010 /* 1011 * Controller is idle and density is not detected. 1012 * Start a density probe by issuing a read sector command 1013 * and sleep until the density probe finished. 1014 * Due to this it is impossible to open unformatted media. 1015 * As the RX02/02 is not able to format its own media, 1016 * media must be purchased preformatted. fsck DEC marketing! 1017 */ 1018 RFS_SETCMD(rf_sc->sc_state, RFS_PROBING); 1019 disk_busy(&rf_sc->sc_disk); 1020 if (rfc_sendcmd(rfc_sc, RX2CS_RSEC | RX2CS_IE 1021 | (rf_sc->sc_dnum == 0 ? 0 : RX2CS_US) 1022 | ((rf_sc->sc_state & RFS_DENS) == 0 ? 0 : RX2CS_DD), 1023 1, 1) < 0) { 1024 rf_sc->sc_state = 0; 1025 return(ENXIO); 1026 } 1027 /* wait max. 2 sec for density probe to finish */ 1028 if (tsleep(rf_sc, PRIBIO | PCATCH, "density probe", 2 * hz) 1029 != 0 || (rf_sc->sc_state & RFS_CMDS) == RFS_NOTINIT) { 1030 /* timeout elapsed and / or something went wrong */ 1031 rf_sc->sc_state = 0; 1032 return(ENXIO); 1033 } 1034 } 1035 /* disklabel. We use different fake geometries for SD and DD. */ 1036 if ((rf_sc->sc_state & RFS_DENS) == 0) { 1037 dl->d_nsectors = 10; /* sectors per track */ 1038 dl->d_secpercyl = 10; /* sectors per cylinder */ 1039 dl->d_ncylinders = 50; /* cylinders per unit */ 1040 dl->d_secperunit = 501; /* sectors per unit */ 1041 /* number of sectors in partition */ 1042 dl->d_partitions[2].p_size = 500; 1043 } else { 1044 dl->d_nsectors = RX2_SECTORS / 2; /* sectors per track */ 1045 dl->d_secpercyl = RX2_SECTORS / 2; /* sectors per cylinder */ 1046 dl->d_ncylinders = RX2_TRACKS; /* cylinders per unit */ 1047 /* sectors per unit */ 1048 dl->d_secperunit = RX2_SECTORS * RX2_TRACKS / 2; 1049 /* number of sectors in partition */ 1050 dl->d_partitions[2].p_size = RX2_SECTORS * RX2_TRACKS / 2; 1051 } 1052 return(0); 1053 } 1054 1055 1056 1057 int 1058 rfclose(dev_t dev, int fflag, int devtype, struct lwp *l) 1059 { 1060 struct rf_softc *rf_sc = device_lookup_private(&rf_cd, DISKUNIT(dev)); 1061 1062 if ((rf_sc->sc_state & 1 << (DISKPART(dev) + RFS_OPEN_SHIFT)) == 0) 1063 panic("rfclose: can not close non-open drive %s " 1064 "partition %"PRIu32, device_xname(rf_sc->sc_dev), DISKPART(dev)); 1065 else 1066 rf_sc->sc_state &= ~(1 << (DISKPART(dev) + RFS_OPEN_SHIFT)); 1067 if ((rf_sc->sc_state & RFS_OPEN_MASK) == 0) 1068 rf_sc->sc_state = 0; 1069 return(0); 1070 } 1071 1072 1073 1074 int 1075 rfread(dev_t dev, struct uio *uio, int ioflag) 1076 { 1077 1078 return(physio(rfstrategy, NULL, dev, B_READ, minphys, uio)); 1079 } 1080 1081 1082 1083 int 1084 rfwrite(dev_t dev, struct uio *uio, int ioflag) 1085 { 1086 1087 return(physio(rfstrategy, NULL, dev, B_WRITE, minphys, uio)); 1088 } 1089 1090 1091 1092 int 1093 rfioctl(dev_t dev, u_long cmd, void *data, int fflag, struct lwp *l) 1094 { 1095 struct rf_softc *rf_sc = device_lookup_private(&rf_cd, DISKUNIT(dev)); 1096 int error; 1097 1098 /* We are going to operate on a non-open dev? PANIC! */ 1099 if ((rf_sc->sc_state & 1 << (DISKPART(dev) + RFS_OPEN_SHIFT)) == 0) 1100 panic("rfioctl: can not operate on non-open drive %s " 1101 "partition %"PRIu32, device_xname(rf_sc->sc_dev), DISKPART(dev)); 1102 error = disk_ioctl(&rf_sc->sc_disk, dev, cmd, data, fflag, l); 1103 if (error != EPASSTHROUGH) 1104 return error; 1105 1106 switch (cmd) { 1107 /* get and set disklabel; DIOCGPARTINFO used internally */ 1108 case DIOCSDINFO: /* set */ 1109 return(0); 1110 case DIOCWDINFO: /* set, update disk */ 1111 return(0); 1112 /* do format operation, read or write */ 1113 case DIOCRFORMAT: 1114 break; 1115 case DIOCWFORMAT: 1116 break; 1117 1118 case DIOCSSTEP: /* set step rate */ 1119 break; 1120 case DIOCSRETRIES: /* set # of retries */ 1121 break; 1122 case DIOCKLABEL: /* keep/drop label on close? */ 1123 break; 1124 case DIOCWLABEL: /* write en/disable label */ 1125 break; 1126 1127 /* case DIOCSBAD: / * set kernel dkbad */ 1128 break; /* */ 1129 case DIOCEJECT: /* eject removable disk */ 1130 break; 1131 case ODIOCEJECT: /* eject removable disk */ 1132 break; 1133 case DIOCLOCK: /* lock/unlock pack */ 1134 break; 1135 1136 /* get default label, clear label */ 1137 case DIOCGDEFLABEL: 1138 break; 1139 case DIOCCLRLABEL: 1140 break; 1141 default: 1142 return(ENOTTY); 1143 } 1144 1145 return(ENOTTY); 1146 } 1147