1/***********************license start*************** 2 * Copyright (c) 2003-2008 Cavium Networks (support@cavium.com). All rights 3 * reserved. 4 * 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are 8 * met: 9 * 10 * * Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * * Redistributions in binary form must reproduce the above 14 * copyright notice, this list of conditions and the following 15 * disclaimer in the documentation and/or other materials provided 16 * with the distribution. 17 * 18 * * Neither the name of Cavium Networks nor the names of 19 * its contributors may be used to endorse or promote products 20 * derived from this software without specific prior written 21 * permission. 22 * 23 * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" 24 * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS 25 * OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH 26 * RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY 27 * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT 28 * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES 29 * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR 30 * PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET 31 * POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT 32 * OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU. 33 * 34 * 35 * For any questions regarding licensing please contact marketing@caviumnetworks.com 36 * 37 ***********************license end**************************************/ 38 39/* 40 * octeon_ebt3000_cf.c 41 * 42 */ 43 44#include <sys/cdefs.h> 45__FBSDID("$FreeBSD$"); 46 47#include <sys/param.h> 48#include <sys/bio.h> 49#include <sys/systm.h> 50#include <sys/sysctl.h> 51#include <sys/ata.h> 52#include <sys/bus.h> 53#include <sys/kernel.h> 54#include <sys/module.h> 55#include <sys/rman.h> 56#include <sys/power.h> 57#include <sys/smp.h> 58#include <sys/time.h> 59#include <sys/timetc.h> 60#include <sys/malloc.h> 61 62#include <geom/geom.h> 63 64#include <machine/clock.h> 65#include <machine/locore.h> 66#include <machine/md_var.h> 67#include <machine/cpuregs.h> 68 69#include <mips/cavium/octeon_pcmap_regs.h> 70 71#include <contrib/octeon-sdk/cvmx.h> 72 73/* ATA Commands */ 74#define CMD_READ_SECTOR 0x20 75#define CMD_WRITE_SECTOR 0x30 76#define CMD_IDENTIFY 0xEC 77 78/* The ATA Task File */ 79#define TF_DATA 0x00 80#define TF_ERROR 0x01 81#define TF_PRECOMP 0x01 82#define TF_SECTOR_COUNT 0x02 83#define TF_SECTOR_NUMBER 0x03 84#define TF_CYL_LSB 0x04 85#define TF_CYL_MSB 0x05 86#define TF_DRV_HEAD 0x06 87#define TF_STATUS 0x07 88#define TF_COMMAND 0x07 89 90/* Status Register */ 91#define STATUS_BSY 0x80 /* Drive is busy */ 92#define STATUS_RDY 0x40 /* Drive is ready */ 93#define STATUS_DF 0x20 /* Device fault */ 94#define STATUS_DRQ 0x08 /* Data can be transferred */ 95 96/* Miscelaneous */ 97#define SECTOR_SIZE 512 98#define WAIT_DELAY 1000 99#define NR_TRIES 1000 100#define SWAP_SHORT(x) ((x << 8) | (x >> 8)) 101#define MODEL_STR_SIZE 40 102 103/* XXX */ 104extern cvmx_bootinfo_t *octeon_bootinfo; 105 106/* Globals */ 107/* 108 * There's three bus types supported by this driver. 109 * 110 * CF_8 -- Traditional PC Card IDE interface on an 8-bit wide bus. We assume 111 * the bool loader has configure attribute memory properly. We then access 112 * the device like old-school 8-bit IDE card (which is all a traditional PC Card 113 * interface really is). 114 * CF_16 -- Traditional PC Card IDE interface on a 16-bit wide bus. Registers on 115 * this bus are 16-bits wide too. When accessing registers in the task file, you 116 * have to do it in 16-bit chunks, and worry about masking out what you don't want 117 * or ORing together the traditional 8-bit values. We assume the bootloader does 118 * the right attribute memory initialization dance. 119 * CF_TRUE_IDE_8 - CF Card wired to True IDE mode. There's no Attribute memory 120 * space at all. Instead all the traditional 8-bit registers are there, but 121 * on a 16-bit bus where addr0 isn't wired. This means we need to read/write them 122 * 16-bit chunks, but only the lower 8 bits are valid. We do not (and can not) 123 * access this like CF_16 with the comingled registers. Yet we can't access 124 * this like CF_8 because of the register offset. Except the TF_DATA register 125 * appears to be full width? 126 */ 127void *base_addr; 128int bus_type; 129#define CF_8 1 /* 8-bit bus, no offsets - PC Card */ 130#define CF_16 2 /* 16-bit bus, registers shared - PC Card */ 131#define CF_TRUE_IDE_8 3 /* 16-bit bus, only lower 8-bits, TrueIDE */ 132const char *const cf_type[] = { 133 "impossible type", 134 "CF 8-bit", 135 "CF 16-bit", 136 "True IDE" 137}; 138 139/* Device softc */ 140struct cf_priv { 141 device_t dev; 142 struct drive_param *drive_param; 143 144 struct bio_queue_head cf_bq; 145 struct g_geom *cf_geom; 146 struct g_provider *cf_provider; 147 148}; 149 150/* Device parameters */ 151struct drive_param{ 152 union { 153 char buf[SECTOR_SIZE]; 154 struct ata_params driveid; 155 } u; 156 157 char model[MODEL_STR_SIZE]; 158 uint32_t nr_sectors; 159 uint16_t sector_size; 160 uint16_t heads; 161 uint16_t tracks; 162 uint16_t sec_track; 163 164} drive_param; 165 166/* GEOM class implementation */ 167static g_access_t cf_access; 168static g_start_t cf_start; 169static g_ioctl_t cf_ioctl; 170 171struct g_class g_cf_class = { 172 .name = "CF", 173 .version = G_VERSION, 174 .start = cf_start, 175 .access = cf_access, 176 .ioctl = cf_ioctl, 177}; 178 179DECLARE_GEOM_CLASS(g_cf_class, g_cf); 180 181/* Device methods */ 182static int cf_probe(device_t); 183static void cf_identify(driver_t *, device_t); 184static int cf_attach(device_t); 185static int cf_attach_geom(void *, int); 186 187/* ATA methods */ 188static int cf_cmd_identify(void); 189static int cf_cmd_write(uint32_t, uint32_t, void *); 190static int cf_cmd_read(uint32_t, uint32_t, void *); 191static int cf_wait_busy(void); 192static int cf_send_cmd(uint32_t, uint8_t); 193static void cf_attach_geom_proxy(void *arg, int flag); 194 195/* Miscelenous */ 196static void cf_swap_ascii(unsigned char[], char[]); 197 198 199/* ------------------------------------------------------------------- * 200 * cf_access() * 201 * ------------------------------------------------------------------- */ 202static int cf_access (struct g_provider *pp, int r, int w, int e) 203{ 204 205 pp->sectorsize = drive_param.sector_size; 206 pp->stripesize = drive_param.heads * drive_param.sec_track * drive_param.sector_size; 207 pp->mediasize = pp->stripesize * drive_param.tracks; 208 209 return (0); 210} 211 212 213/* ------------------------------------------------------------------- * 214 * cf_start() * 215 * ------------------------------------------------------------------- */ 216static void cf_start (struct bio *bp) 217{ 218 int error; 219 220 /* 221 * Handle actual I/O requests. The request is passed down through 222 * the bio struct. 223 */ 224 225 if(bp->bio_cmd & BIO_GETATTR) { 226 if (g_handleattr_int(bp, "GEOM::fwsectors", drive_param.sec_track)) 227 return; 228 if (g_handleattr_int(bp, "GEOM::fwheads", drive_param.heads)) 229 return; 230 g_io_deliver(bp, ENOIOCTL); 231 return; 232 } 233 234 if ((bp->bio_cmd & (BIO_READ | BIO_WRITE))) { 235 236 if (bp->bio_cmd & BIO_READ) { 237 error = cf_cmd_read(bp->bio_length / drive_param.sector_size, 238 bp->bio_offset / drive_param.sector_size, bp->bio_data); 239 } else if (bp->bio_cmd & BIO_WRITE) { 240 error = cf_cmd_write(bp->bio_length / drive_param.sector_size, 241 bp->bio_offset/drive_param.sector_size, bp->bio_data); 242 } else { 243 printf("%s: unrecognized bio_cmd %x.\n", __func__, bp->bio_cmd); 244 error = ENOTSUP; 245 } 246 247 if (error != 0) { 248 g_io_deliver(bp, error); 249 return; 250 } 251 252 bp->bio_resid = 0; 253 bp->bio_completed = bp->bio_length; 254 g_io_deliver(bp, 0); 255 } 256} 257 258 259static int cf_ioctl (struct g_provider *pp, u_long cmd, void *data, int fflag, struct thread *td) 260{ 261 return (0); 262} 263 264 265static uint8_t cf_inb_8(int port) 266{ 267 /* 268 * Traditional 8-bit PC Card/CF bus access. 269 */ 270 if (bus_type == CF_8) { 271 volatile uint8_t *task_file = (volatile uint8_t *)base_addr; 272 return task_file[port]; 273 } 274 275 /* 276 * True IDE access. lower 8 bits on a 16-bit bus (see above). 277 */ 278 volatile uint16_t *task_file = (volatile uint16_t *)base_addr; 279 return task_file[port] & 0xff; 280} 281 282static void cf_outb_8(int port, uint8_t val) 283{ 284 /* 285 * Traditional 8-bit PC Card/CF bus access. 286 */ 287 if (bus_type == CF_8) { 288 volatile uint8_t *task_file = (volatile uint8_t *)base_addr; 289 task_file[port] = val; 290 } 291 292 /* 293 * True IDE access. lower 8 bits on a 16-bit bus (see above). 294 */ 295 volatile uint16_t *task_file = (volatile uint16_t *)base_addr; 296 task_file[port] = val & 0xff; 297} 298 299static uint8_t cf_inb_16(int port) 300{ 301 volatile uint16_t *task_file = (volatile uint16_t *)base_addr; 302 uint16_t val = task_file[port / 2]; 303 if (port & 1) 304 return (val >> 8) & 0xff; 305 return val & 0xff; 306} 307 308static uint16_t cf_inw_16(int port) 309{ 310 volatile uint16_t *task_file = (volatile uint16_t *)base_addr; 311 uint16_t val = task_file[port / 2]; 312 return val; 313} 314 315static void cf_outw_16(int port, uint16_t val) 316{ 317 volatile uint16_t *task_file = (volatile uint16_t *)base_addr; 318 task_file[port / 2] = val; 319} 320 321/* ------------------------------------------------------------------- * 322 * cf_cmd_read() * 323 * ------------------------------------------------------------------- * 324 * 325 * Read nr_sectors from the device starting from start_sector. 326 */ 327static int cf_cmd_read (uint32_t nr_sectors, uint32_t start_sector, void *buf) 328{ 329 unsigned long lba; 330 uint32_t count; 331 uint16_t *ptr_16; 332 uint8_t *ptr_8; 333 int error; 334 335//#define OCTEON_VISUAL_CF_0 1 336#ifdef OCTEON_VISUAL_CF_0 337 octeon_led_write_char(0, 'R'); 338#endif 339 ptr_8 = (uint8_t*)buf; 340 ptr_16 = (uint16_t*)buf; 341 lba = start_sector; 342 343 344 while (nr_sectors--) { 345 error = cf_send_cmd(lba, CMD_READ_SECTOR); 346 if (error != 0) { 347 printf("%s: cf_send_cmd(CMD_READ_SECTOR) failed: %d\n", __func__, error); 348 return (error); 349 } 350 351 switch (bus_type) 352 { 353 case CF_8: 354 for (count = 0; count < SECTOR_SIZE; count++) { 355 *ptr_8++ = cf_inb_8(TF_DATA); 356 if ((count & 0xf) == 0) 357 (void)cf_inb_8(TF_STATUS); 358 } 359 break; 360 case CF_TRUE_IDE_8: 361 case CF_16: 362 default: 363 for (count = 0; count < SECTOR_SIZE; count+=2) { 364 uint16_t temp; 365 temp = cf_inw_16(TF_DATA); 366 *ptr_16++ = SWAP_SHORT(temp); 367 if ((count & 0xf) == 0) 368 (void)cf_inb_16(TF_STATUS); 369 } 370 break; 371 } 372 373 lba++; 374 } 375#ifdef OCTEON_VISUAL_CF_0 376 octeon_led_write_char(0, ' '); 377#endif 378 return (0); 379} 380 381 382/* ------------------------------------------------------------------- * 383 * cf_cmd_write() * 384 * ------------------------------------------------------------------- * 385 * 386 * Write nr_sectors to the device starting from start_sector. 387 */ 388static int cf_cmd_write (uint32_t nr_sectors, uint32_t start_sector, void *buf) 389{ 390 uint32_t lba; 391 uint32_t count; 392 uint16_t *ptr_16; 393 uint8_t *ptr_8; 394 int error; 395 396//#define OCTEON_VISUAL_CF_1 1 397#ifdef OCTEON_VISUAL_CF_1 398 octeon_led_write_char(1, 'W'); 399#endif 400 lba = start_sector; 401 ptr_8 = (uint8_t*)buf; 402 ptr_16 = (uint16_t*)buf; 403 404 while (nr_sectors--) { 405 error = cf_send_cmd(lba, CMD_WRITE_SECTOR); 406 if (error != 0) { 407 printf("%s: cf_send_cmd(CMD_WRITE_SECTOR) failed: %d\n", __func__, error); 408 return (error); 409 } 410 411 switch (bus_type) 412 { 413 case CF_8: 414 for (count = 0; count < SECTOR_SIZE; count++) { 415 cf_outb_8(TF_DATA, *ptr_8++); 416 if ((count & 0xf) == 0) 417 (void)cf_inb_8(TF_STATUS); 418 } 419 break; 420 case CF_TRUE_IDE_8: 421 case CF_16: 422 default: 423 for (count = 0; count < SECTOR_SIZE; count+=2) { 424 uint16_t temp = *ptr_16++; 425 cf_outw_16(TF_DATA, SWAP_SHORT(temp)); 426 if ((count & 0xf) == 0) 427 (void)cf_inb_16(TF_STATUS); 428 } 429 break; 430 } 431 432 lba++; 433 } 434#ifdef OCTEON_VISUAL_CF_1 435 octeon_led_write_char(1, ' '); 436#endif 437 return (0); 438} 439 440 441/* ------------------------------------------------------------------- * 442 * cf_cmd_identify() * 443 * ------------------------------------------------------------------- * 444 * 445 * Read parameters and other information from the drive and store 446 * it in the drive_param structure 447 * 448 */ 449static int cf_cmd_identify (void) 450{ 451 int count; 452 int error; 453 454 error = cf_send_cmd(0, CMD_IDENTIFY); 455 if (error != 0) { 456 printf("%s: identify failed: %d\n", __func__, error); 457 return (error); 458 } 459 switch (bus_type) 460 { 461 case CF_8: 462 for (count = 0; count < SECTOR_SIZE; count++) 463 drive_param.u.buf[count] = cf_inb_8(TF_DATA); 464 break; 465 case CF_TRUE_IDE_8: 466 case CF_16: 467 default: 468 for (count = 0; count < SECTOR_SIZE; count += 2) { 469 uint16_t temp; 470 temp = cf_inw_16(TF_DATA); 471 472 /* endianess will be swapped below */ 473 drive_param.u.buf[count] = (temp & 0xff); 474 drive_param.u.buf[count + 1] = (temp & 0xff00) >> 8; 475 } 476 break; 477 } 478 479 cf_swap_ascii(drive_param.u.driveid.model, drive_param.model); 480 481 drive_param.sector_size = 512; //= SWAP_SHORT (drive_param.u.driveid.sector_bytes); 482 drive_param.heads = SWAP_SHORT (drive_param.u.driveid.current_heads); 483 drive_param.tracks = SWAP_SHORT (drive_param.u.driveid.current_cylinders); 484 drive_param.sec_track = SWAP_SHORT (drive_param.u.driveid.current_sectors); 485 drive_param.nr_sectors = (uint32_t)SWAP_SHORT (drive_param.u.driveid.lba_size_1) | 486 ((uint32_t)SWAP_SHORT (drive_param.u.driveid.lba_size_2)); 487 printf("cf0: <%s> %lld sectors\n", drive_param.model, (long long)drive_param.nr_sectors); 488 489 return (0); 490} 491 492 493/* ------------------------------------------------------------------- * 494 * cf_send_cmd() * 495 * ------------------------------------------------------------------- * 496 * 497 * Send command to read/write one sector specified by lba. 498 * 499 */ 500static int cf_send_cmd (uint32_t lba, uint8_t cmd) 501{ 502 switch (bus_type) 503 { 504 case CF_8: 505 case CF_TRUE_IDE_8: 506 while (cf_inb_8(TF_STATUS) & STATUS_BSY) 507 DELAY(WAIT_DELAY); 508 cf_outb_8(TF_SECTOR_COUNT, 1); 509 cf_outb_8(TF_SECTOR_NUMBER, lba & 0xff); 510 cf_outb_8(TF_CYL_LSB, (lba >> 8) & 0xff); 511 cf_outb_8(TF_CYL_MSB, (lba >> 16) & 0xff); 512 cf_outb_8(TF_DRV_HEAD, ((lba >> 24) & 0xff) | 0xe0); 513 cf_outb_8(TF_COMMAND, cmd); 514 break; 515 case CF_16: 516 default: 517 while (cf_inb_16(TF_STATUS) & STATUS_BSY) 518 DELAY(WAIT_DELAY); 519 cf_outw_16(TF_SECTOR_COUNT, 1 | ((lba & 0xff) << 8)); 520 cf_outw_16(TF_CYL_LSB, ((lba >> 8) & 0xff) | (((lba >> 16) & 0xff) << 8)); 521 cf_outw_16(TF_DRV_HEAD, (((lba >> 24) & 0xff) | 0xe0) | (cmd << 8)); 522 break; 523 } 524 525 return (cf_wait_busy()); 526} 527 528/* ------------------------------------------------------------------- * 529 * cf_wait_busy() * 530 * ------------------------------------------------------------------- * 531 * 532 * Wait until the drive finishes a given command and data is 533 * ready to be transferred. This is done by repeatedly checking 534 * the BSY bit of the status register. When the controller is ready for 535 * data transfer, it clears the BSY bit and sets the DRQ bit. 536 * 537 * If the DF bit is ever set, we return error. 538 * 539 * This code originally spun on DRQ. If that behavior turns out to be 540 * necessary, a flag can be added or this function can be called 541 * repeatedly as long as it is returning ENXIO. 542 */ 543static int cf_wait_busy (void) 544{ 545 uint8_t status; 546 547//#define OCTEON_VISUAL_CF_2 1 548#ifdef OCTEON_VISUAL_CF_2 549 static int where0 = 0; 550 551 octeon_led_run_wheel(&where0, 2); 552#endif 553 554 switch (bus_type) 555 { 556 case CF_8: 557 case CF_TRUE_IDE_8: 558 status = cf_inb_8(TF_STATUS); 559 while ((status & STATUS_BSY) == STATUS_BSY) { 560 if ((status & STATUS_DF) != 0) { 561 printf("%s: device fault (status=%x)\n", __func__, status); 562 return (EIO); 563 } 564 DELAY(WAIT_DELAY); 565 status = cf_inb_8(TF_STATUS); 566 } 567 break; 568 case CF_16: 569 default: 570 status = cf_inb_16(TF_STATUS); 571 while ((status & STATUS_BSY) == STATUS_BSY) { 572 if ((status & STATUS_DF) != 0) { 573 printf("%s: device fault (status=%x)\n", __func__, status); 574 return (EIO); 575 } 576 DELAY(WAIT_DELAY); 577 status = cf_inb_16(TF_STATUS); 578 } 579 break; 580 } 581 if ((status & STATUS_DRQ) == 0) { 582 printf("%s: device not ready (status=%x)\n", __func__, status); 583 return (ENXIO); 584 } 585 586#ifdef OCTEON_VISUAL_CF_2 587 octeon_led_write_char(2, ' '); 588#endif 589 return (0); 590} 591 592/* ------------------------------------------------------------------- * 593 * cf_swap_ascii() * 594 * ------------------------------------------------------------------- * 595 * 596 * The ascii string returned by the controller specifying 597 * the model of the drive is byte-swaped. This routine 598 * corrects the byte ordering. 599 * 600 */ 601static void cf_swap_ascii (unsigned char str1[], char str2[]) 602{ 603 int i; 604 605 for(i = 0; i < MODEL_STR_SIZE; i++) 606 str2[i] = str1[i ^ 1]; 607} 608 609 610/* ------------------------------------------------------------------- * 611 * cf_probe() * 612 * ------------------------------------------------------------------- */ 613 614static int cf_probe (device_t dev) 615{ 616 if (octeon_is_simulation()) 617 return (ENXIO); 618 619 if (device_get_unit(dev) != 0) { 620 panic("can't attach more devices\n"); 621 } 622 623 device_set_desc(dev, "Octeon Compact Flash Driver"); 624 625 return (cf_cmd_identify()); 626} 627 628/* ------------------------------------------------------------------- * 629 * cf_identify() * 630 * ------------------------------------------------------------------- * 631 * 632 * Find the bootbus region for the CF to determine 633 * 16 or 8 bit and check to see if device is 634 * inserted. 635 * 636 */ 637typedef unsigned long long llu; 638static void cf_identify (driver_t *drv, device_t parent) 639{ 640 int bus_region; 641 int count = 0; 642 cvmx_mio_boot_reg_cfgx_t cfg; 643 644 if (octeon_is_simulation()) 645 return; 646 647 base_addr = cvmx_phys_to_ptr(octeon_bootinfo->compact_flash_common_base_addr); 648 649 for (bus_region = 0; bus_region < 8; bus_region++) 650 { 651 cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(bus_region)); 652 if (cfg.s.base == octeon_bootinfo->compact_flash_common_base_addr >> 16) 653 { 654 if (octeon_bootinfo->compact_flash_attribute_base_addr == 0) 655 bus_type = CF_TRUE_IDE_8; 656 else 657 bus_type = (cfg.s.width) ? CF_16 : CF_8; 658 printf("Compact flash found in bootbus region %d (%s).\n", bus_region, cf_type[bus_type]); 659 break; 660 } 661 } 662 663 switch (bus_type) 664 { 665 case CF_8: 666 case CF_TRUE_IDE_8: 667 /* Check if CF is inserted */ 668 while (cf_inb_8(TF_STATUS) & STATUS_BSY) { 669 if ((count++) == NR_TRIES ) { 670 printf("Compact Flash not present\n"); 671 return; 672 } 673 DELAY(WAIT_DELAY); 674 } 675 break; 676 case CF_16: 677 default: 678 /* Check if CF is inserted */ 679 while (cf_inb_16(TF_STATUS) & STATUS_BSY) { 680 if ((count++) == NR_TRIES ) { 681 printf("Compact Flash not present\n"); 682 return; 683 } 684 DELAY(WAIT_DELAY); 685 } 686 break; 687 } 688 689 BUS_ADD_CHILD(parent, 0, "cf", 0); 690} 691 692 693/* ------------------------------------------------------------------- * 694 * cf_attach_geom() * 695 * ------------------------------------------------------------------- */ 696 697static int cf_attach_geom (void *arg, int flag) 698{ 699 struct cf_priv *cf_priv; 700 701 cf_priv = (struct cf_priv *) arg; 702 cf_priv->cf_geom = g_new_geomf(&g_cf_class, "cf%d", device_get_unit(cf_priv->dev)); 703 cf_priv->cf_provider = g_new_providerf(cf_priv->cf_geom, cf_priv->cf_geom->name); 704 cf_priv->cf_geom->softc = cf_priv; 705 g_error_provider(cf_priv->cf_provider, 0); 706 707 return (0); 708} 709 710/* ------------------------------------------------------------------- * 711 * cf_attach_geom() * 712 * ------------------------------------------------------------------- */ 713static void cf_attach_geom_proxy (void *arg, int flag) 714{ 715 cf_attach_geom(arg, flag); 716} 717 718 719 720/* ------------------------------------------------------------------- * 721 * cf_attach() * 722 * ------------------------------------------------------------------- */ 723 724static int cf_attach (device_t dev) 725{ 726 struct cf_priv *cf_priv; 727 728 if (octeon_is_simulation()) 729 return (ENXIO); 730 731 cf_priv = device_get_softc(dev); 732 cf_priv->dev = dev; 733 cf_priv->drive_param = &drive_param; 734 735 g_post_event(cf_attach_geom_proxy, cf_priv, M_WAITOK, NULL); 736 bioq_init(&cf_priv->cf_bq); 737 738 return 0; 739} 740 741 742static device_method_t cf_methods[] = { 743 /* Device interface */ 744 DEVMETHOD(device_probe, cf_probe), 745 DEVMETHOD(device_identify, cf_identify), 746 DEVMETHOD(device_attach, cf_attach), 747 DEVMETHOD(device_detach, bus_generic_detach), 748 DEVMETHOD(device_shutdown, bus_generic_shutdown), 749 750 { 0, 0 } 751}; 752 753static driver_t cf_driver = { 754 "cf", 755 cf_methods, 756 sizeof(struct cf_priv) 757}; 758 759static devclass_t cf_devclass; 760 761DRIVER_MODULE(cf, nexus, cf_driver, cf_devclass, 0, 0); 762