Index: stable/11/stand/efi/boot1/boot1.c =================================================================== --- stable/11/stand/efi/boot1/boot1.c (revision 332155) +++ stable/11/stand/efi/boot1/boot1.c (revision 332156) @@ -1,588 +1,590 @@ /*- * Copyright (c) 1998 Robert Nordier * All rights reserved. * Copyright (c) 2001 Robert Drehmel * All rights reserved. * Copyright (c) 2014 Nathan Whitehorn * All rights reserved. * Copyright (c) 2015 Eric McCorkle * All rights reserved. * * Redistribution and use in source and binary forms are freely * permitted provided that the above copyright notice and this * paragraph and the following disclaimer are duplicated in all * such forms. * * This software is provided "AS IS" and without any express or * implied warranties, including, without limitation, the implied * warranties of merchantability and fitness for a particular * purpose. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include "boot_module.h" #include "paths.h" static void efi_panic(EFI_STATUS s, const char *fmt, ...) __dead2 __printflike(2, 3); static const boot_module_t *boot_modules[] = { #ifdef EFI_ZFS_BOOT &zfs_module, #endif #ifdef EFI_UFS_BOOT &ufs_module #endif }; #define NUM_BOOT_MODULES nitems(boot_modules) /* The initial number of handles used to query EFI for partitions. */ #define NUM_HANDLES_INIT 24 static EFI_GUID BlockIoProtocolGUID = BLOCK_IO_PROTOCOL; static EFI_GUID DevicePathGUID = DEVICE_PATH_PROTOCOL; static EFI_GUID LoadedImageGUID = LOADED_IMAGE_PROTOCOL; static EFI_GUID ConsoleControlGUID = EFI_CONSOLE_CONTROL_PROTOCOL_GUID; /* * Provide Malloc / Free backed by EFIs AllocatePool / FreePool which ensures * memory is correctly aligned avoiding EFI_INVALID_PARAMETER returns from * EFI methods. */ void * Malloc(size_t len, const char *file __unused, int line __unused) { void *out; if (BS->AllocatePool(EfiLoaderData, len, &out) == EFI_SUCCESS) return (out); return (NULL); } void Free(void *buf, const char *file __unused, int line __unused) { if (buf != NULL) (void)BS->FreePool(buf); } /* * nodes_match returns TRUE if the imgpath isn't NULL and the nodes match, * FALSE otherwise. */ static BOOLEAN nodes_match(EFI_DEVICE_PATH *imgpath, EFI_DEVICE_PATH *devpath) { size_t len; if (imgpath == NULL || imgpath->Type != devpath->Type || imgpath->SubType != devpath->SubType) return (FALSE); len = DevicePathNodeLength(imgpath); if (len != DevicePathNodeLength(devpath)) return (FALSE); return (memcmp(imgpath, devpath, (size_t)len) == 0); } /* * device_paths_match returns TRUE if the imgpath isn't NULL and all nodes * in imgpath and devpath match up to their respective occurrences of a * media node, FALSE otherwise. */ static BOOLEAN device_paths_match(EFI_DEVICE_PATH *imgpath, EFI_DEVICE_PATH *devpath) { if (imgpath == NULL) return (FALSE); while (!IsDevicePathEnd(imgpath) && !IsDevicePathEnd(devpath)) { if (IsDevicePathType(imgpath, MEDIA_DEVICE_PATH) && IsDevicePathType(devpath, MEDIA_DEVICE_PATH)) return (TRUE); if (!nodes_match(imgpath, devpath)) return (FALSE); imgpath = NextDevicePathNode(imgpath); devpath = NextDevicePathNode(devpath); } return (FALSE); } /* * devpath_last returns the last non-path end node in devpath. */ static EFI_DEVICE_PATH * devpath_last(EFI_DEVICE_PATH *devpath) { while (!IsDevicePathEnd(NextDevicePathNode(devpath))) devpath = NextDevicePathNode(devpath); return (devpath); } /* * load_loader attempts to load the loader image data. * * It tries each module and its respective devices, identified by mod->probe, * in order until a successful load occurs at which point it returns EFI_SUCCESS * and EFI_NOT_FOUND otherwise. * * Only devices which have preferred matching the preferred parameter are tried. */ static EFI_STATUS load_loader(const boot_module_t **modp, dev_info_t **devinfop, void **bufp, size_t *bufsize, BOOLEAN preferred) { UINTN i; dev_info_t *dev; const boot_module_t *mod; for (i = 0; i < NUM_BOOT_MODULES; i++) { mod = boot_modules[i]; for (dev = mod->devices(); dev != NULL; dev = dev->next) { if (dev->preferred != preferred) continue; if (mod->load(PATH_LOADER_EFI, dev, bufp, bufsize) == EFI_SUCCESS) { *devinfop = dev; *modp = mod; return (EFI_SUCCESS); } } } return (EFI_NOT_FOUND); } /* * try_boot only returns if it fails to load the loader. If it succeeds * it simply boots, otherwise it returns the status of last EFI call. */ static EFI_STATUS try_boot(void) { size_t bufsize, loadersize, cmdsize; void *buf, *loaderbuf; char *cmd; dev_info_t *dev; const boot_module_t *mod; EFI_HANDLE loaderhandle; EFI_LOADED_IMAGE *loaded_image; EFI_STATUS status; status = load_loader(&mod, &dev, &loaderbuf, &loadersize, TRUE); if (status != EFI_SUCCESS) { status = load_loader(&mod, &dev, &loaderbuf, &loadersize, FALSE); if (status != EFI_SUCCESS) { printf("Failed to load '%s'\n", PATH_LOADER_EFI); return (status); } } /* * Read in and parse the command line from /boot.config or /boot/config, * if present. We'll pass it the next stage via a simple ASCII * string. loader.efi has a hack for ASCII strings, so we'll use that to * keep the size down here. We only try to read the alternate file if * we get EFI_NOT_FOUND because all other errors mean that the boot_module * had troubles with the filesystem. We could return early, but we'll let * loading the actual kernel sort all that out. Since these files are * optional, we don't report errors in trying to read them. */ cmd = NULL; cmdsize = 0; status = mod->load(PATH_DOTCONFIG, dev, &buf, &bufsize); if (status == EFI_NOT_FOUND) status = mod->load(PATH_CONFIG, dev, &buf, &bufsize); if (status == EFI_SUCCESS) { cmdsize = bufsize + 1; cmd = malloc(cmdsize); if (cmd == NULL) goto errout; memcpy(cmd, buf, bufsize); cmd[bufsize] = '\0'; free(buf); buf = NULL; } if ((status = BS->LoadImage(TRUE, IH, devpath_last(dev->devpath), loaderbuf, loadersize, &loaderhandle)) != EFI_SUCCESS) { printf("Failed to load image provided by %s, size: %zu, (%lu)\n", mod->name, loadersize, EFI_ERROR_CODE(status)); goto errout; } if ((status = BS->HandleProtocol(loaderhandle, &LoadedImageGUID, (VOID**)&loaded_image)) != EFI_SUCCESS) { printf("Failed to query LoadedImage provided by %s (%lu)\n", mod->name, EFI_ERROR_CODE(status)); goto errout; } if (cmd != NULL) printf(" command args: %s\n", cmd); loaded_image->DeviceHandle = dev->devhandle; loaded_image->LoadOptionsSize = cmdsize; loaded_image->LoadOptions = cmd; DPRINTF("Starting '%s' in 5 seconds...", PATH_LOADER_EFI); DSTALL(1000000); DPRINTF("."); DSTALL(1000000); DPRINTF("."); DSTALL(1000000); DPRINTF("."); DSTALL(1000000); DPRINTF("."); DSTALL(1000000); DPRINTF(".\n"); if ((status = BS->StartImage(loaderhandle, NULL, NULL)) != EFI_SUCCESS) { printf("Failed to start image provided by %s (%lu)\n", mod->name, EFI_ERROR_CODE(status)); loaded_image->LoadOptionsSize = 0; loaded_image->LoadOptions = NULL; } errout: if (cmd != NULL) free(cmd); if (buf != NULL) free(buf); if (loaderbuf != NULL) free(loaderbuf); return (status); } /* * probe_handle determines if the passed handle represents a logical partition * if it does it uses each module in order to probe it and if successful it * returns EFI_SUCCESS. */ static EFI_STATUS probe_handle(EFI_HANDLE h, EFI_DEVICE_PATH *imgpath, BOOLEAN *preferred) { dev_info_t *devinfo; EFI_BLOCK_IO *blkio; EFI_DEVICE_PATH *devpath; EFI_STATUS status; UINTN i; /* Figure out if we're dealing with an actual partition. */ status = BS->HandleProtocol(h, &DevicePathGUID, (void **)&devpath); if (status == EFI_UNSUPPORTED) return (status); if (status != EFI_SUCCESS) { DPRINTF("\nFailed to query DevicePath (%lu)\n", EFI_ERROR_CODE(status)); return (status); } #ifdef EFI_DEBUG { CHAR16 *text = efi_devpath_name(devpath); DPRINTF("probing: %S\n", text); efi_free_devpath_name(text); } #endif status = BS->HandleProtocol(h, &BlockIoProtocolGUID, (void **)&blkio); if (status == EFI_UNSUPPORTED) return (status); if (status != EFI_SUCCESS) { DPRINTF("\nFailed to query BlockIoProtocol (%lu)\n", EFI_ERROR_CODE(status)); return (status); } if (!blkio->Media->LogicalPartition) return (EFI_UNSUPPORTED); *preferred = device_paths_match(imgpath, devpath); /* Run through each module, see if it can load this partition */ for (i = 0; i < NUM_BOOT_MODULES; i++) { devinfo = malloc(sizeof(*devinfo)); if (devinfo == NULL) { DPRINTF("\nFailed to allocate devinfo\n"); continue; } devinfo->dev = blkio; devinfo->devpath = devpath; devinfo->devhandle = h; devinfo->devdata = NULL; devinfo->preferred = *preferred; devinfo->next = NULL; status = boot_modules[i]->probe(devinfo); if (status == EFI_SUCCESS) return (EFI_SUCCESS); free(devinfo); } return (EFI_UNSUPPORTED); } /* * probe_handle_status calls probe_handle and outputs the returned status * of the call. */ static void probe_handle_status(EFI_HANDLE h, EFI_DEVICE_PATH *imgpath) { EFI_STATUS status; BOOLEAN preferred; preferred = FALSE; status = probe_handle(h, imgpath, &preferred); DPRINTF("probe: "); switch (status) { case EFI_UNSUPPORTED: printf("."); DPRINTF(" not supported\n"); break; case EFI_SUCCESS: if (preferred) { printf("%c", '*'); DPRINTF(" supported (preferred)\n"); } else { printf("%c", '+'); DPRINTF(" supported\n"); } break; default: printf("x"); DPRINTF(" error (%lu)\n", EFI_ERROR_CODE(status)); break; } DSTALL(500000); } EFI_STATUS efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE *Xsystab) { EFI_HANDLE *handles; EFI_LOADED_IMAGE *img; EFI_DEVICE_PATH *imgpath; EFI_STATUS status; EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl = NULL; SIMPLE_TEXT_OUTPUT_INTERFACE *conout = NULL; UINTN i, max_dim, best_mode, cols, rows, hsize, nhandles; CHAR16 *text; UINT16 boot_current; size_t sz; UINT16 boot_order[100]; /* Basic initialization*/ ST = Xsystab; IH = Ximage; BS = ST->BootServices; RS = ST->RuntimeServices; /* Set up the console, so printf works. */ status = BS->LocateProtocol(&ConsoleControlGUID, NULL, (VOID **)&ConsoleControl); if (status == EFI_SUCCESS) (void)ConsoleControl->SetMode(ConsoleControl, EfiConsoleControlScreenText); /* * Reset the console and find the best text mode. */ conout = ST->ConOut; conout->Reset(conout, TRUE); max_dim = best_mode = 0; for (i = 0; ; i++) { status = conout->QueryMode(conout, i, &cols, &rows); if (EFI_ERROR(status)) break; if (cols * rows > max_dim) { max_dim = cols * rows; best_mode = i; } } if (max_dim > 0) conout->SetMode(conout, best_mode); conout->EnableCursor(conout, TRUE); conout->ClearScreen(conout); printf("\n>> FreeBSD EFI boot block\n"); printf(" Loader path: %s\n\n", PATH_LOADER_EFI); printf(" Initializing modules:"); for (i = 0; i < NUM_BOOT_MODULES; i++) { printf(" %s", boot_modules[i]->name); if (boot_modules[i]->init != NULL) boot_modules[i]->init(); } putchar('\n'); /* Determine the devpath of our image so we can prefer it. */ status = BS->HandleProtocol(IH, &LoadedImageGUID, (VOID**)&img); imgpath = NULL; if (status == EFI_SUCCESS) { text = efi_devpath_name(img->FilePath); if (text != NULL) { printf(" Load Path: %S\n", text); efi_setenv_freebsd_wcs("Boot1Path", text); efi_free_devpath_name(text); } status = BS->HandleProtocol(img->DeviceHandle, &DevicePathGUID, (void **)&imgpath); if (status != EFI_SUCCESS) { DPRINTF("Failed to get image DevicePath (%lu)\n", EFI_ERROR_CODE(status)); } else { text = efi_devpath_name(imgpath); if (text != NULL) { printf(" Load Device: %S\n", text); efi_setenv_freebsd_wcs("Boot1Dev", text); efi_free_devpath_name(text); } } } boot_current = 0; sz = sizeof(boot_current); - efi_global_getenv("BootCurrent", &boot_current, &sz); - printf(" BootCurrent: %04x\n", boot_current); + if (efi_global_getenv("BootCurrent", &boot_current, &sz) == EFI_SUCCESS) { + printf(" BootCurrent: %04x\n", boot_current); - sz = sizeof(boot_order); - efi_global_getenv("BootOrder", &boot_order, &sz); - printf(" BootOrder:"); - for (i = 0; i < sz / sizeof(boot_order[0]); i++) - printf(" %04x%s", boot_order[i], - boot_order[i] == boot_current ? "[*]" : ""); - printf("\n"); + sz = sizeof(boot_order); + if (efi_global_getenv("BootOrder", &boot_order, &sz) == EFI_SUCCESS) { + printf(" BootOrder:"); + for (i = 0; i < sz / sizeof(boot_order[0]); i++) + printf(" %04x%s", boot_order[i], + boot_order[i] == boot_current ? "[*]" : ""); + printf("\n"); + } + } #ifdef TEST_FAILURE /* * For testing failover scenarios, it's nice to be able to fail fast. * Define TEST_FAILURE to create a boot1.efi that always fails after * reporting the boot manager protocol details. */ BS->Exit(IH, EFI_OUT_OF_RESOURCES, 0, NULL); #endif /* Get all the device handles */ hsize = (UINTN)NUM_HANDLES_INIT * sizeof(EFI_HANDLE); handles = malloc(hsize); if (handles == NULL) printf("Failed to allocate %d handles\n", NUM_HANDLES_INIT); status = BS->LocateHandle(ByProtocol, &BlockIoProtocolGUID, NULL, &hsize, handles); switch (status) { case EFI_SUCCESS: break; case EFI_BUFFER_TOO_SMALL: free(handles); handles = malloc(hsize); if (handles == NULL) efi_panic(EFI_OUT_OF_RESOURCES, "Failed to allocate %d handles\n", NUM_HANDLES_INIT); status = BS->LocateHandle(ByProtocol, &BlockIoProtocolGUID, NULL, &hsize, handles); if (status != EFI_SUCCESS) efi_panic(status, "Failed to get device handles\n"); break; default: efi_panic(status, "Failed to get device handles\n"); break; } /* Scan all partitions, probing with all modules. */ nhandles = hsize / sizeof(*handles); printf(" Probing %zu block devices...", nhandles); DPRINTF("\n"); for (i = 0; i < nhandles; i++) probe_handle_status(handles[i], imgpath); printf(" done\n"); /* Status summary. */ for (i = 0; i < NUM_BOOT_MODULES; i++) { printf(" "); boot_modules[i]->status(); } try_boot(); /* If we get here, we're out of luck... */ efi_panic(EFI_LOAD_ERROR, "No bootable partitions found!"); } /* * add_device adds a device to the passed devinfo list. */ void add_device(dev_info_t **devinfop, dev_info_t *devinfo) { dev_info_t *dev; if (*devinfop == NULL) { *devinfop = devinfo; return; } for (dev = *devinfop; dev->next != NULL; dev = dev->next) ; dev->next = devinfo; } /* * OK. We totally give up. Exit back to EFI with a sensible status so * it can try the next option on the list. */ static void efi_panic(EFI_STATUS s, const char *fmt, ...) { va_list ap; printf("panic: "); va_start(ap, fmt); vprintf(fmt, ap); va_end(ap); printf("\n"); BS->Exit(IH, s, 0, NULL); } void putchar(int c) { CHAR16 buf[2]; if (c == '\n') { buf[0] = '\r'; buf[1] = 0; ST->ConOut->OutputString(ST->ConOut, buf); } buf[0] = c; buf[1] = 0; ST->ConOut->OutputString(ST->ConOut, buf); } Index: stable/11/stand/efi/include/efi.h =================================================================== --- stable/11/stand/efi/include/efi.h (revision 332155) +++ stable/11/stand/efi/include/efi.h (revision 332156) @@ -1,65 +1,63 @@ /* $FreeBSD$ */ /*++ Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved This software and associated documentation (if any) is furnished under a license and may only be used or copied in accordance with the terms of the license. Except as permitted by such license, no part of this software or documentation may be reproduced, stored in a retrieval system, or transmitted in any form or by any means without the express written consent of Intel Corporation. Module Name: efi.h Abstract: Public EFI header files Revision History --*/ // // Build flags on input // EFI32 // EFI_DEBUG - Enable debugging code // EFI_NT_EMULATOR - Building for running under NT // #ifndef _EFI_INCLUDE_ #define _EFI_INCLUDE_ #define EFI_FIRMWARE_VENDOR L"INTEL" #define EFI_FIRMWARE_MAJOR_REVISION 14 #define EFI_FIRMWARE_MINOR_REVISION 62 #define EFI_FIRMWARE_REVISION ((EFI_FIRMWARE_MAJOR_REVISION <<16) | (EFI_FIRMWARE_MINOR_REVISION)) #include "efibind.h" #include "efidef.h" #include "efidevp.h" #include "efiprot.h" #include "eficon.h" #include "efiser.h" #include "efi_nii.h" #include "efipxebc.h" #include "efinet.h" #include "efiapi.h" #include "efifs.h" #include "efierr.h" #include "efigop.h" /* * FreeBSD UUID */ #define FREEBSD_BOOT_VAR_GUID \ { 0xCFEE69AD, 0xA0DE, 0x47A9, {0x93, 0xA8, 0xF6, 0x31, 0x06, 0xF8, 0xAE, 0x99} } -#define UEFI_BOOT_VAR_GUID \ - { 0x8be4df61, 0x93ca, 0x11d2, {0xaa, 0x0d, 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c} } #endif Index: stable/11/stand/efi/libefi/efienv.c =================================================================== --- stable/11/stand/efi/libefi/efienv.c (revision 332155) +++ stable/11/stand/efi/libefi/efienv.c (revision 332156) @@ -1,87 +1,87 @@ /*- * Copyright (c) 2018 Netflix, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include static EFI_GUID FreeBSDBootVarGUID = FREEBSD_BOOT_VAR_GUID; -static EFI_GUID GlobalBootVarGUID = UEFI_BOOT_VAR_GUID; +static EFI_GUID GlobalBootVarGUID = EFI_GLOBAL_VARIABLE; EFI_STATUS efi_getenv(EFI_GUID *g, const char *v, void *data, size_t *len) { size_t ul; CHAR16 *uv; UINT32 attr; UINTN dl; EFI_STATUS rv; uv = NULL; if (utf8_to_ucs2(v, &uv, &ul) != 0) return (EFI_OUT_OF_RESOURCES); dl = *len; rv = RS->GetVariable(uv, g, &attr, &dl, data); if (rv == EFI_SUCCESS) *len = dl; free(uv); return (rv); } EFI_STATUS efi_global_getenv(const char *v, void *data, size_t *len) { return (efi_getenv(&GlobalBootVarGUID, v, data, len)); } EFI_STATUS efi_freebsd_getenv(const char *v, void *data, size_t *len) { return (efi_getenv(&FreeBSDBootVarGUID, v, data, len)); } EFI_STATUS efi_setenv_freebsd_wcs(const char *varname, CHAR16 *valstr) { CHAR16 *var = NULL; size_t len; EFI_STATUS rv; if (utf8_to_ucs2(varname, &var, &len) != 0) return (EFI_OUT_OF_RESOURCES); rv = RS->SetVariable(var, &FreeBSDBootVarGUID, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, (ucs2len(valstr) + 1) * sizeof(efi_char), valstr); free(var); return (rv); } Index: stable/11/stand/efi/libefi/efinet.c =================================================================== --- stable/11/stand/efi/libefi/efinet.c (revision 332155) +++ stable/11/stand/efi/libefi/efinet.c (revision 332156) @@ -1,390 +1,388 @@ /*- * Copyright (c) 2001 Doug Rabson * Copyright (c) 2002, 2006 Marcel Moolenaar * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include static EFI_GUID sn_guid = EFI_SIMPLE_NETWORK_PROTOCOL; static void efinet_end(struct netif *); static ssize_t efinet_get(struct iodesc *, void **, time_t); static void efinet_init(struct iodesc *, void *); static int efinet_match(struct netif *, void *); static int efinet_probe(struct netif *, void *); static ssize_t efinet_put(struct iodesc *, void *, size_t); struct netif_driver efinetif = { .netif_bname = "efinet", .netif_match = efinet_match, .netif_probe = efinet_probe, .netif_init = efinet_init, .netif_get = efinet_get, .netif_put = efinet_put, .netif_end = efinet_end, .netif_ifs = NULL, .netif_nifs = 0 }; #ifdef EFINET_DEBUG static void dump_mode(EFI_SIMPLE_NETWORK_MODE *mode) { int i; printf("State = %x\n", mode->State); printf("HwAddressSize = %u\n", mode->HwAddressSize); printf("MediaHeaderSize = %u\n", mode->MediaHeaderSize); printf("MaxPacketSize = %u\n", mode->MaxPacketSize); printf("NvRamSize = %u\n", mode->NvRamSize); printf("NvRamAccessSize = %u\n", mode->NvRamAccessSize); printf("ReceiveFilterMask = %x\n", mode->ReceiveFilterMask); printf("ReceiveFilterSetting = %u\n", mode->ReceiveFilterSetting); printf("MaxMCastFilterCount = %u\n", mode->MaxMCastFilterCount); printf("MCastFilterCount = %u\n", mode->MCastFilterCount); printf("MCastFilter = {"); for (i = 0; i < mode->MCastFilterCount; i++) printf(" %s", ether_sprintf(mode->MCastFilter[i].Addr)); printf(" }\n"); printf("CurrentAddress = %s\n", ether_sprintf(mode->CurrentAddress.Addr)); printf("BroadcastAddress = %s\n", ether_sprintf(mode->BroadcastAddress.Addr)); printf("PermanentAddress = %s\n", ether_sprintf(mode->PermanentAddress.Addr)); printf("IfType = %u\n", mode->IfType); printf("MacAddressChangeable = %d\n", mode->MacAddressChangeable); printf("MultipleTxSupported = %d\n", mode->MultipleTxSupported); printf("MediaPresentSupported = %d\n", mode->MediaPresentSupported); printf("MediaPresent = %d\n", mode->MediaPresent); } #endif static int efinet_match(struct netif *nif, void *machdep_hint) { struct devdesc *dev = machdep_hint; if (dev->d_unit == nif->nif_unit) return (1); return(0); } static int efinet_probe(struct netif *nif, void *machdep_hint) { return (0); } static ssize_t efinet_put(struct iodesc *desc, void *pkt, size_t len) { struct netif *nif = desc->io_netif; EFI_SIMPLE_NETWORK *net; EFI_STATUS status; void *buf; net = nif->nif_devdata; if (net == NULL) return (-1); status = net->Transmit(net, 0, len, pkt, NULL, NULL, NULL); if (status != EFI_SUCCESS) return (-1); /* Wait for the buffer to be transmitted */ do { buf = NULL; /* XXX Is this needed? */ status = net->GetStatus(net, NULL, &buf); /* * XXX EFI1.1 and the E1000 card returns a different * address than we gave. Sigh. */ } while (status == EFI_SUCCESS && buf == NULL); /* XXX How do we deal with status != EFI_SUCCESS now? */ return ((status == EFI_SUCCESS) ? len : -1); } static ssize_t efinet_get(struct iodesc *desc, void **pkt, time_t timeout) { struct netif *nif = desc->io_netif; EFI_SIMPLE_NETWORK *net; EFI_STATUS status; UINTN bufsz; time_t t; char *buf, *ptr; ssize_t ret = -1; net = nif->nif_devdata; if (net == NULL) return (ret); bufsz = net->Mode->MaxPacketSize + ETHER_HDR_LEN + ETHER_CRC_LEN; buf = malloc(bufsz + ETHER_ALIGN); if (buf == NULL) return (ret); ptr = buf + ETHER_ALIGN; t = getsecs(); while ((getsecs() - t) < timeout) { status = net->Receive(net, NULL, &bufsz, ptr, NULL, NULL, NULL); if (status == EFI_SUCCESS) { *pkt = buf; ret = (ssize_t)bufsz; break; } if (status != EFI_NOT_READY) break; } if (ret == -1) free(buf); return (ret); } static void efinet_init(struct iodesc *desc, void *machdep_hint) { struct netif *nif = desc->io_netif; EFI_SIMPLE_NETWORK *net; EFI_HANDLE h; EFI_STATUS status; UINT32 mask; if (nif->nif_driver->netif_ifs[nif->nif_unit].dif_unit < 0) { printf("Invalid network interface %d\n", nif->nif_unit); return; } h = nif->nif_driver->netif_ifs[nif->nif_unit].dif_private; status = BS->HandleProtocol(h, &sn_guid, (VOID **)&nif->nif_devdata); if (status != EFI_SUCCESS) { printf("net%d: cannot fetch interface data (status=%lu)\n", nif->nif_unit, EFI_ERROR_CODE(status)); return; } net = nif->nif_devdata; if (net->Mode->State == EfiSimpleNetworkStopped) { status = net->Start(net); if (status != EFI_SUCCESS) { printf("net%d: cannot start interface (status=%lu)\n", nif->nif_unit, EFI_ERROR_CODE(status)); return; } } if (net->Mode->State != EfiSimpleNetworkInitialized) { status = net->Initialize(net, 0, 0); if (status != EFI_SUCCESS) { printf("net%d: cannot init. interface (status=%lu)\n", nif->nif_unit, EFI_ERROR_CODE(status)); return; } } mask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST; status = net->ReceiveFilters(net, mask, 0, FALSE, 0, NULL); - if (status != EFI_SUCCESS) { + if (status != EFI_SUCCESS) printf("net%d: cannot set rx. filters (status=%lu)\n", nif->nif_unit, EFI_ERROR_CODE(status)); - return; - } #ifdef EFINET_DEBUG dump_mode(net->Mode); #endif bcopy(net->Mode->CurrentAddress.Addr, desc->myea, 6); desc->xid = 1; } static void efinet_end(struct netif *nif) { EFI_SIMPLE_NETWORK *net = nif->nif_devdata; if (net == NULL) return; net->Shutdown(net); } static int efinet_dev_init(void); static int efinet_dev_print(int); struct devsw efinet_dev = { .dv_name = "net", .dv_type = DEVT_NET, .dv_init = efinet_dev_init, .dv_strategy = NULL, /* Will be set in efinet_dev_init */ .dv_open = NULL, /* Will be set in efinet_dev_init */ .dv_close = NULL, /* Will be set in efinet_dev_init */ .dv_ioctl = noioctl, .dv_print = efinet_dev_print, .dv_cleanup = NULL }; static int efinet_dev_init() { struct netif_dif *dif; struct netif_stats *stats; EFI_DEVICE_PATH *devpath, *node; EFI_SIMPLE_NETWORK *net; EFI_HANDLE *handles, *handles2; EFI_STATUS status; UINTN sz; int err, i, nifs; extern struct devsw netdev; sz = 0; handles = NULL; status = BS->LocateHandle(ByProtocol, &sn_guid, NULL, &sz, NULL); if (status == EFI_BUFFER_TOO_SMALL) { handles = (EFI_HANDLE *)malloc(sz); status = BS->LocateHandle(ByProtocol, &sn_guid, NULL, &sz, handles); if (EFI_ERROR(status)) free(handles); } if (EFI_ERROR(status)) return (efi_status_to_errno(status)); handles2 = (EFI_HANDLE *)malloc(sz); if (handles2 == NULL) { free(handles); return (ENOMEM); } nifs = 0; for (i = 0; i < sz / sizeof(EFI_HANDLE); i++) { devpath = efi_lookup_devpath(handles[i]); if (devpath == NULL) continue; if ((node = efi_devpath_last_node(devpath)) == NULL) continue; if (DevicePathType(node) != MESSAGING_DEVICE_PATH || DevicePathSubType(node) != MSG_MAC_ADDR_DP) continue; /* * Open the network device in exclusive mode. Without this * we will be racing with the UEFI network stack. It will * pull packets off the network leading to lost packets. */ status = BS->OpenProtocol(handles[i], &sn_guid, (void **)&net, IH, NULL, EFI_OPEN_PROTOCOL_EXCLUSIVE); if (status != EFI_SUCCESS) { printf("Unable to open network interface %d for " "exclusive access: %lu\n", i, EFI_ERROR_CODE(status)); } handles2[nifs] = handles[i]; nifs++; } free(handles); if (nifs == 0) { err = ENOENT; goto done; } err = efi_register_handles(&efinet_dev, handles2, NULL, nifs); if (err != 0) goto done; efinetif.netif_ifs = calloc(nifs, sizeof(struct netif_dif)); stats = calloc(nifs, sizeof(struct netif_stats)); if (efinetif.netif_ifs == NULL || stats == NULL) { free(efinetif.netif_ifs); free(stats); efinetif.netif_ifs = NULL; err = ENOMEM; goto done; } efinetif.netif_nifs = nifs; for (i = 0; i < nifs; i++) { dif = &efinetif.netif_ifs[i]; dif->dif_unit = i; dif->dif_nsel = 1; dif->dif_stats = &stats[i]; dif->dif_private = handles2[i]; } efinet_dev.dv_open = netdev.dv_open; efinet_dev.dv_close = netdev.dv_close; efinet_dev.dv_strategy = netdev.dv_strategy; done: free(handles2); return (err); } static int efinet_dev_print(int verbose) { CHAR16 *text; EFI_HANDLE h; int unit, ret = 0; printf("%s devices:", efinet_dev.dv_name); if ((ret = pager_output("\n")) != 0) return (ret); for (unit = 0, h = efi_find_handle(&efinet_dev, 0); h != NULL; h = efi_find_handle(&efinet_dev, ++unit)) { printf(" %s%d:", efinet_dev.dv_name, unit); if (verbose) { text = efi_devpath_name(efi_lookup_devpath(h)); if (text != NULL) { printf(" %S", text); efi_free_devpath_name(text); } } if ((ret = pager_output("\n")) != 0) break; } return (ret); } Index: stable/11/stand/i386/libfirewire/fwohcireg.h =================================================================== --- stable/11/stand/i386/libfirewire/fwohcireg.h (revision 332155) +++ stable/11/stand/i386/libfirewire/fwohcireg.h (nonexistent) @@ -1,369 +0,0 @@ -/* - * Copyright (c) 2003 Hidetoshi Shimokawa - * Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the acknowledgement as bellow: - * - * This product includes software developed by K. Kobayashi and H. Shimokawa - * - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - * - */ -#define PCI_CBMEM PCIR_BAR(0) - -#define FW_VENDORID_NATSEMI 0x100B -#define FW_VENDORID_NEC 0x1033 -#define FW_VENDORID_SIS 0x1039 -#define FW_VENDORID_TI 0x104c -#define FW_VENDORID_SONY 0x104d -#define FW_VENDORID_VIA 0x1106 -#define FW_VENDORID_RICOH 0x1180 -#define FW_VENDORID_APPLE 0x106b -#define FW_VENDORID_LUCENT 0x11c1 -#define FW_VENDORID_INTEL 0x8086 -#define FW_VENDORID_ADAPTEC 0x9004 - -#define FW_DEVICE_CS4210 (0x000f << 16) -#define FW_DEVICE_UPD861 (0x0063 << 16) -#define FW_DEVICE_UPD871 (0x00ce << 16) -#define FW_DEVICE_UPD72870 (0x00cd << 16) -#define FW_DEVICE_UPD72873 (0x00e7 << 16) -#define FW_DEVICE_UPD72874 (0x00f2 << 16) -#define FW_DEVICE_TITSB22 (0x8009 << 16) -#define FW_DEVICE_TITSB23 (0x8019 << 16) -#define FW_DEVICE_TITSB26 (0x8020 << 16) -#define FW_DEVICE_TITSB43 (0x8021 << 16) -#define FW_DEVICE_TITSB43A (0x8023 << 16) -#define FW_DEVICE_TITSB43AB23 (0x8024 << 16) -#define FW_DEVICE_TITSB82AA2 (0x8025 << 16) -#define FW_DEVICE_TITSB43AB21 (0x8026 << 16) -#define FW_DEVICE_TIPCI4410A (0x8017 << 16) -#define FW_DEVICE_TIPCI4450 (0x8011 << 16) -#define FW_DEVICE_TIPCI4451 (0x8027 << 16) -#define FW_DEVICE_CXD1947 (0x8009 << 16) -#define FW_DEVICE_CXD3222 (0x8039 << 16) -#define FW_DEVICE_VT6306 (0x3044 << 16) -#define FW_DEVICE_R5C551 (0x0551 << 16) -#define FW_DEVICE_R5C552 (0x0552 << 16) -#define FW_DEVICE_PANGEA (0x0030 << 16) -#define FW_DEVICE_UNINORTH (0x0031 << 16) -#define FW_DEVICE_AIC5800 (0x5800 << 16) -#define FW_DEVICE_FW322 (0x5811 << 16) -#define FW_DEVICE_7007 (0x7007 << 16) -#define FW_DEVICE_82372FB (0x7605 << 16) - -#define PCI_INTERFACE_OHCI 0x10 - -#define FW_OHCI_BASE_REG 0x10 - -#define OHCI_DMA_ITCH 0x20 -#define OHCI_DMA_IRCH 0x20 - -#define OHCI_MAX_DMA_CH (0x4 + OHCI_DMA_ITCH + OHCI_DMA_IRCH) - - -typedef uint32_t fwohcireg_t; - -/* for PCI */ -#if BYTE_ORDER == BIG_ENDIAN -#define FWOHCI_DMA_WRITE(x, y) ((x) = htole32(y)) -#define FWOHCI_DMA_READ(x) le32toh(x) -#define FWOHCI_DMA_SET(x, y) ((x) |= htole32(y)) -#define FWOHCI_DMA_CLEAR(x, y) ((x) &= htole32(~(y))) -#else -#define FWOHCI_DMA_WRITE(x, y) ((x) = (y)) -#define FWOHCI_DMA_READ(x) (x) -#define FWOHCI_DMA_SET(x, y) ((x) |= (y)) -#define FWOHCI_DMA_CLEAR(x, y) ((x) &= ~(y)) -#endif - -struct fwohcidb { - union { - struct { - uint32_t cmd; - uint32_t addr; - uint32_t depend; - uint32_t res; - } desc; - uint32_t immed[4]; - } db; -#define OHCI_STATUS_SHIFT 16 -#define OHCI_COUNT_MASK 0xffff -#define OHCI_OUTPUT_MORE (0 << 28) -#define OHCI_OUTPUT_LAST (1 << 28) -#define OHCI_INPUT_MORE (2 << 28) -#define OHCI_INPUT_LAST (3 << 28) -#define OHCI_STORE_QUAD (4 << 28) -#define OHCI_LOAD_QUAD (5 << 28) -#define OHCI_NOP (6 << 28) -#define OHCI_STOP (7 << 28) -#define OHCI_STORE (8 << 28) -#define OHCI_CMD_MASK (0xf << 28) - -#define OHCI_UPDATE (1 << 27) - -#define OHCI_KEY_ST0 (0 << 24) -#define OHCI_KEY_ST1 (1 << 24) -#define OHCI_KEY_ST2 (2 << 24) -#define OHCI_KEY_ST3 (3 << 24) -#define OHCI_KEY_REGS (5 << 24) -#define OHCI_KEY_SYS (6 << 24) -#define OHCI_KEY_DEVICE (7 << 24) -#define OHCI_KEY_MASK (7 << 24) - -#define OHCI_INTERRUPT_NEVER (0 << 20) -#define OHCI_INTERRUPT_TRUE (1 << 20) -#define OHCI_INTERRUPT_FALSE (2 << 20) -#define OHCI_INTERRUPT_ALWAYS (3 << 20) - -#define OHCI_BRANCH_NEVER (0 << 18) -#define OHCI_BRANCH_TRUE (1 << 18) -#define OHCI_BRANCH_FALSE (2 << 18) -#define OHCI_BRANCH_ALWAYS (3 << 18) -#define OHCI_BRANCH_MASK (3 << 18) - -#define OHCI_WAIT_NEVER (0 << 16) -#define OHCI_WAIT_TRUE (1 << 16) -#define OHCI_WAIT_FALSE (2 << 16) -#define OHCI_WAIT_ALWAYS (3 << 16) -}; - -#define OHCI_SPD_S100 0x4 -#define OHCI_SPD_S200 0x1 -#define OHCI_SPD_S400 0x2 - - -#define FWOHCIEV_NOSTAT 0 -#define FWOHCIEV_LONGP 2 -#define FWOHCIEV_MISSACK 3 -#define FWOHCIEV_UNDRRUN 4 -#define FWOHCIEV_OVRRUN 5 -#define FWOHCIEV_DESCERR 6 -#define FWOHCIEV_DTRDERR 7 -#define FWOHCIEV_DTWRERR 8 -#define FWOHCIEV_BUSRST 9 -#define FWOHCIEV_TIMEOUT 0xa -#define FWOHCIEV_TCODERR 0xb -#define FWOHCIEV_UNKNOWN 0xe -#define FWOHCIEV_FLUSHED 0xf -#define FWOHCIEV_ACKCOMPL 0x11 -#define FWOHCIEV_ACKPEND 0x12 -#define FWOHCIEV_ACKBSX 0x14 -#define FWOHCIEV_ACKBSA 0x15 -#define FWOHCIEV_ACKBSB 0x16 -#define FWOHCIEV_ACKTARD 0x1b -#define FWOHCIEV_ACKDERR 0x1d -#define FWOHCIEV_ACKTERR 0x1e - -#define FWOHCIEV_MASK 0x1f - -struct ohci_dma{ - fwohcireg_t cntl; - -#define OHCI_CNTL_CYCMATCH_S (0x1 << 31) - -#define OHCI_CNTL_BUFFIL (0x1 << 31) -#define OHCI_CNTL_ISOHDR (0x1 << 30) -#define OHCI_CNTL_CYCMATCH_R (0x1 << 29) -#define OHCI_CNTL_MULTICH (0x1 << 28) - -#define OHCI_CNTL_DMA_RUN (0x1 << 15) -#define OHCI_CNTL_DMA_WAKE (0x1 << 12) -#define OHCI_CNTL_DMA_DEAD (0x1 << 11) -#define OHCI_CNTL_DMA_ACTIVE (0x1 << 10) -#define OHCI_CNTL_DMA_BT (0x1 << 8) -#define OHCI_CNTL_DMA_BAD (0x1 << 7) -#define OHCI_CNTL_DMA_STAT (0xff) - - fwohcireg_t cntl_clr; - fwohcireg_t dummy0; - fwohcireg_t cmd; - fwohcireg_t match; - fwohcireg_t dummy1; - fwohcireg_t dummy2; - fwohcireg_t dummy3; -}; - -struct ohci_itdma{ - fwohcireg_t cntl; - fwohcireg_t cntl_clr; - fwohcireg_t dummy0; - fwohcireg_t cmd; -}; - -struct ohci_registers { - fwohcireg_t ver; /* Version No. 0x0 */ - fwohcireg_t guid; /* GUID_ROM No. 0x4 */ - fwohcireg_t retry; /* AT retries 0x8 */ -#define FWOHCI_RETRY 0x8 - fwohcireg_t csr_data; /* CSR data 0xc */ - fwohcireg_t csr_cmp; /* CSR compare 0x10 */ - fwohcireg_t csr_cntl; /* CSR compare 0x14 */ - fwohcireg_t rom_hdr; /* config ROM ptr. 0x18 */ - fwohcireg_t bus_id; /* BUS_ID 0x1c */ - fwohcireg_t bus_opt; /* BUS option 0x20 */ -#define FWOHCIGUID_H 0x24 -#define FWOHCIGUID_L 0x28 - fwohcireg_t guid_hi; /* GUID hi 0x24 */ - fwohcireg_t guid_lo; /* GUID lo 0x28 */ - fwohcireg_t dummy0[2]; /* dummy 0x2c-0x30 */ - fwohcireg_t config_rom; /* config ROM map 0x34 */ - fwohcireg_t post_wr_lo; /* post write addr lo 0x38 */ - fwohcireg_t post_wr_hi; /* post write addr hi 0x3c */ - fwohcireg_t vendor; /* vendor ID 0x40 */ - fwohcireg_t dummy1[3]; /* dummy 0x44-0x4c */ - fwohcireg_t hcc_cntl_set; /* HCC control set 0x50 */ - fwohcireg_t hcc_cntl_clr; /* HCC control clr 0x54 */ -#define OHCI_HCC_BIBIV (1U << 31) /* BIBimage Valid */ -#define OHCI_HCC_BIGEND (1 << 30) /* noByteSwapData */ -#define OHCI_HCC_PRPHY (1 << 23) /* programPhyEnable */ -#define OHCI_HCC_PHYEN (1 << 22) /* aPhyEnhanceEnable */ -#define OHCI_HCC_LPS (1 << 19) /* LPS */ -#define OHCI_HCC_POSTWR (1 << 18) /* postedWriteEnable */ -#define OHCI_HCC_LINKEN (1 << 17) /* linkEnable */ -#define OHCI_HCC_RESET (1 << 16) /* softReset */ - fwohcireg_t dummy2[2]; /* dummy 0x58-0x5c */ - fwohcireg_t dummy3[1]; /* dummy 0x60 */ - fwohcireg_t sid_buf; /* self id buffer 0x64 */ - fwohcireg_t sid_cnt; /* self id count 0x68 */ - fwohcireg_t dummy4[1]; /* dummy 0x6c */ - fwohcireg_t ir_mask_hi_set; /* ir mask hi set 0x70 */ - fwohcireg_t ir_mask_hi_clr; /* ir mask hi set 0x74 */ - fwohcireg_t ir_mask_lo_set; /* ir mask hi set 0x78 */ - fwohcireg_t ir_mask_lo_clr; /* ir mask hi set 0x7c */ -#define FWOHCI_INTSTAT 0x80 -#define FWOHCI_INTSTATCLR 0x84 -#define FWOHCI_INTMASK 0x88 -#define FWOHCI_INTMASKCLR 0x8c - fwohcireg_t int_stat; /* 0x80 */ - fwohcireg_t int_clear; /* 0x84 */ - fwohcireg_t int_mask; /* 0x88 */ - fwohcireg_t int_mask_clear; /* 0x8c */ - fwohcireg_t it_int_stat; /* 0x90 */ - fwohcireg_t it_int_clear; /* 0x94 */ - fwohcireg_t it_int_mask; /* 0x98 */ - fwohcireg_t it_mask_clear; /* 0x9c */ - fwohcireg_t ir_int_stat; /* 0xa0 */ - fwohcireg_t ir_int_clear; /* 0xa4 */ - fwohcireg_t ir_int_mask; /* 0xa8 */ - fwohcireg_t ir_mask_clear; /* 0xac */ - fwohcireg_t dummy5[11]; /* dummy 0xb0-d8 */ - fwohcireg_t fairness; /* fairness control 0xdc */ - fwohcireg_t link_cntl; /* Chip control 0xe0*/ - fwohcireg_t link_cntl_clr; /* Chip control clear 0xe4*/ -#define FWOHCI_NODEID 0xe8 - fwohcireg_t node; /* Node ID 0xe8 */ -#define OHCI_NODE_VALID (1U << 31) -#define OHCI_NODE_ROOT (1 << 30) - -#define OHCI_ASYSRCBUS 1 - - fwohcireg_t phy_access; /* PHY cntl 0xec */ -#define PHYDEV_RDDONE (1<<31) -#define PHYDEV_RDCMD (1<<15) -#define PHYDEV_WRCMD (1<<14) -#define PHYDEV_REGADDR 8 -#define PHYDEV_WRDATA 0 -#define PHYDEV_RDADDR 24 -#define PHYDEV_RDDATA 16 - - fwohcireg_t cycle_timer; /* Cycle Timer 0xf0 */ - fwohcireg_t dummy6[3]; /* dummy 0xf4-fc */ - fwohcireg_t areq_hi; /* Async req. filter hi 0x100 */ - fwohcireg_t areq_hi_clr; /* Async req. filter hi 0x104 */ - fwohcireg_t areq_lo; /* Async req. filter lo 0x108 */ - fwohcireg_t areq_lo_clr; /* Async req. filter lo 0x10c */ - fwohcireg_t preq_hi; /* Async req. filter hi 0x110 */ - fwohcireg_t preq_hi_clr; /* Async req. filter hi 0x114 */ - fwohcireg_t preq_lo; /* Async req. filter lo 0x118 */ - fwohcireg_t preq_lo_clr; /* Async req. filter lo 0x11c */ - - fwohcireg_t pys_upper; /* Physical Upper bound 0x120 */ - - fwohcireg_t dummy7[23]; /* dummy 0x124-0x17c */ - - /* 0x180, 0x184, 0x188, 0x18c */ - /* 0x190, 0x194, 0x198, 0x19c */ - /* 0x1a0, 0x1a4, 0x1a8, 0x1ac */ - /* 0x1b0, 0x1b4, 0x1b8, 0x1bc */ - /* 0x1c0, 0x1c4, 0x1c8, 0x1cc */ - /* 0x1d0, 0x1d4, 0x1d8, 0x1dc */ - /* 0x1e0, 0x1e4, 0x1e8, 0x1ec */ - /* 0x1f0, 0x1f4, 0x1f8, 0x1fc */ - struct ohci_dma dma_ch[0x4]; - - /* 0x200, 0x204, 0x208, 0x20c */ - /* 0x210, 0x204, 0x208, 0x20c */ - struct ohci_itdma dma_itch[0x20]; - - /* 0x400, 0x404, 0x408, 0x40c */ - /* 0x410, 0x404, 0x408, 0x40c */ - struct ohci_dma dma_irch[0x20]; -}; - -#define OHCI_CNTL_CYCSRC (0x1 << 22) -#define OHCI_CNTL_CYCMTR (0x1 << 21) -#define OHCI_CNTL_CYCTIMER (0x1 << 20) -#define OHCI_CNTL_PHYPKT (0x1 << 10) -#define OHCI_CNTL_SID (0x1 << 9) - -#define OHCI_INT_DMA_ATRQ (0x1 << 0) -#define OHCI_INT_DMA_ATRS (0x1 << 1) -#define OHCI_INT_DMA_ARRQ (0x1 << 2) -#define OHCI_INT_DMA_ARRS (0x1 << 3) -#define OHCI_INT_DMA_PRRQ (0x1 << 4) -#define OHCI_INT_DMA_PRRS (0x1 << 5) -#define OHCI_INT_DMA_IT (0x1 << 6) -#define OHCI_INT_DMA_IR (0x1 << 7) -#define OHCI_INT_PW_ERR (0x1 << 8) -#define OHCI_INT_LR_ERR (0x1 << 9) - -#define OHCI_INT_PHY_SID (0x1 << 16) -#define OHCI_INT_PHY_BUS_R (0x1 << 17) - -#define OHCI_INT_REG_FAIL (0x1 << 18) - -#define OHCI_INT_PHY_INT (0x1 << 19) -#define OHCI_INT_CYC_START (0x1 << 20) -#define OHCI_INT_CYC_64SECOND (0x1 << 21) -#define OHCI_INT_CYC_LOST (0x1 << 22) -#define OHCI_INT_CYC_ERR (0x1 << 23) - -#define OHCI_INT_ERR (0x1 << 24) -#define OHCI_INT_CYC_LONG (0x1 << 25) -#define OHCI_INT_PHY_REG (0x1 << 26) - -#define OHCI_INT_EN (0x1 << 31) - -#define IP_CHANNELS 0x0234 -#define FWOHCI_MAXREC 2048 - -#define OHCI_ISORA 0x02 -#define OHCI_ISORB 0x04 - -#define FWOHCITCODE_PHY 0xe Property changes on: stable/11/stand/i386/libfirewire/fwohcireg.h ___________________________________________________________________ Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Index: stable/11/stand/i386/libfirewire/firewire.c =================================================================== --- stable/11/stand/i386/libfirewire/firewire.c (revision 332155) +++ stable/11/stand/i386/libfirewire/firewire.c (revision 332156) @@ -1,484 +1,485 @@ /*- * Copyright (c) 2004 Hidetoshi Shimokawa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); /* * FireWire disk device handling. * */ #include #include #include #include #include #include +#include #include "fwohci.h" #include /* XXX */ #define BIT4x2(x,y) uint8_t y:4, x:4 #define BIT16x2(x,y) uint32_t y:16, x:16 #define _KERNEL #include extern uint32_t dcons_paddr; extern struct console dconsole; struct crom_src_buf { struct crom_src src; struct crom_chunk root; struct crom_chunk vendor; struct crom_chunk hw; /* for dcons */ struct crom_chunk unit; struct crom_chunk spec; struct crom_chunk ver; }; static int fw_init(void); static int fw_strategy(void *devdata, int flag, daddr_t dblk, size_t size, char *buf, size_t *rsize); static int fw_open(struct open_file *f, ...); static int fw_close(struct open_file *f); static int fw_print(int verbose); static void fw_cleanup(void); void fw_enable(void); struct devsw fwohci = { "FW1394", /* 7 chars at most */ DEVT_NET, fw_init, fw_strategy, fw_open, fw_close, noioctl, fw_print, fw_cleanup }; static struct fwohci_softc fwinfo[MAX_OHCI]; static int fw_initialized = 0; static void fw_probe(int index, struct fwohci_softc *sc) { int err; sc->state = FWOHCI_STATE_INIT; err = biospci_find_devclass( 0x0c0010 /* Serial:FireWire:OHCI */, index /* index */, &sc->locator); if (err != 0) { sc->state = FWOHCI_STATE_DEAD; return; } biospci_write_config(sc->locator, 0x4 /* command */, 0x6 /* enable bus master and memory mapped I/O */, BIOSPCI_16BITS); biospci_read_config(sc->locator, 0x00 /*devid*/, BIOSPCI_32BITS, &sc->devid); biospci_read_config(sc->locator, 0x10 /*base_addr*/, BIOSPCI_32BITS, &sc->base_addr); sc->handle = (uint32_t)PTOV(sc->base_addr); sc->bus_id = OREAD(sc, OHCI_BUS_ID); return; } static int fw_init(void) { int i, avail; struct fwohci_softc *sc; if (fw_initialized) return (0); avail = 0; for (i = 0; i < MAX_OHCI; i ++) { sc = &fwinfo[i]; fw_probe(i, sc); if (sc->state == FWOHCI_STATE_DEAD) break; avail ++; break; } fw_initialized = 1; return (0); } /* * Print information about OHCI chips */ static int fw_print(int verbose) { char line[80]; int i, ret = 0; struct fwohci_softc *sc; printf("%s devices:", fwohci.dv_name); if ((ret = pager_output("\n")) != 0) return (ret); for (i = 0; i < MAX_OHCI; i ++) { sc = &fwinfo[i]; if (sc->state == FWOHCI_STATE_DEAD) break; snprintf(line, sizeof(line), "%d: locator=0x%04x devid=0x%08x" " base_addr=0x%08x handle=0x%08x bus_id=0x%08x\n", i, sc->locator, sc->devid, sc->base_addr, sc->handle, sc->bus_id); ret = pager_output(line); if (ret != 0) break; } return (ret); } static int fw_open(struct open_file *f, ...) { #if 0 va_list ap; struct i386_devdesc *dev; struct open_disk *od; int error; va_start(ap, f); dev = va_arg(ap, struct i386_devdesc *); va_end(ap); #endif return (ENXIO); } static int fw_close(struct open_file *f) { return (0); } static void fw_cleanup() { struct dcons_buf *db; /* invalidate dcons buffer */ if (dcons_paddr) { db = (struct dcons_buf *)PTOV(dcons_paddr); db->magic = 0; } } static int fw_strategy(void *devdata, int rw, daddr_t dblk, size_t size, char *buf, size_t *rsize) { return (EIO); } static void fw_init_crom(struct fwohci_softc *sc) { struct crom_src *src; printf("fw_init_crom\n"); sc->crom_src_buf = (struct crom_src_buf *) malloc(sizeof(struct crom_src_buf)); if (sc->crom_src_buf == NULL) return; src = &sc->crom_src_buf->src; bzero(src, sizeof(struct crom_src)); /* BUS info sample */ src->hdr.info_len = 4; src->businfo.bus_name = CSR_BUS_NAME_IEEE1394; src->businfo.irmc = 1; src->businfo.cmc = 1; src->businfo.isc = 1; src->businfo.bmc = 1; src->businfo.pmc = 0; src->businfo.cyc_clk_acc = 100; src->businfo.max_rec = sc->maxrec; src->businfo.max_rom = MAXROM_4; #define FW_GENERATION_CHANGEABLE 2 src->businfo.generation = FW_GENERATION_CHANGEABLE; src->businfo.link_spd = sc->speed; src->businfo.eui64.hi = sc->eui.hi; src->businfo.eui64.lo = sc->eui.lo; STAILQ_INIT(&src->chunk_list); sc->crom_src = src; sc->crom_root = &sc->crom_src_buf->root; } static void fw_reset_crom(struct fwohci_softc *sc) { struct crom_src_buf *buf; struct crom_src *src; struct crom_chunk *root; printf("fw_reset\n"); if (sc->crom_src_buf == NULL) fw_init_crom(sc); buf = sc->crom_src_buf; src = sc->crom_src; root = sc->crom_root; STAILQ_INIT(&src->chunk_list); bzero(root, sizeof(struct crom_chunk)); crom_add_chunk(src, NULL, root, 0); crom_add_entry(root, CSRKEY_NCAP, 0x0083c0); /* XXX */ /* private company_id */ crom_add_entry(root, CSRKEY_VENDOR, CSRVAL_VENDOR_PRIVATE); #ifdef __DragonFly__ crom_add_simple_text(src, root, &buf->vendor, "DragonFly Project"); #else crom_add_simple_text(src, root, &buf->vendor, "FreeBSD Project"); #endif } #define ADDR_HI(x) (((x) >> 24) & 0xffffff) #define ADDR_LO(x) ((x) & 0xffffff) static void dcons_crom(struct fwohci_softc *sc) { struct crom_src_buf *buf; struct crom_src *src; struct crom_chunk *root; buf = sc->crom_src_buf; src = sc->crom_src; root = sc->crom_root; bzero(&buf->unit, sizeof(struct crom_chunk)); crom_add_chunk(src, root, &buf->unit, CROM_UDIR); crom_add_entry(&buf->unit, CSRKEY_SPEC, CSRVAL_VENDOR_PRIVATE); crom_add_simple_text(src, &buf->unit, &buf->spec, "FreeBSD"); crom_add_entry(&buf->unit, CSRKEY_VER, DCONS_CSR_VAL_VER); crom_add_simple_text(src, &buf->unit, &buf->ver, "dcons"); crom_add_entry(&buf->unit, DCONS_CSR_KEY_HI, ADDR_HI(dcons_paddr)); crom_add_entry(&buf->unit, DCONS_CSR_KEY_LO, ADDR_LO(dcons_paddr)); } void fw_crom(struct fwohci_softc *sc) { struct crom_src *src; void *newrom; fw_reset_crom(sc); dcons_crom(sc); newrom = malloc(CROMSIZE); src = &sc->crom_src_buf->src; crom_load(src, (uint32_t *)newrom, CROMSIZE); if (bcmp(newrom, sc->config_rom, CROMSIZE) != 0) { /* Bump generation and reload. */ src->businfo.generation++; /* Handle generation count wraps. */ if (src->businfo.generation < 2) src->businfo.generation = 2; /* Recalculate CRC to account for generation change. */ crom_load(src, (uint32_t *)newrom, CROMSIZE); bcopy(newrom, (void *)sc->config_rom, CROMSIZE); } free(newrom); } static int fw_busreset(struct fwohci_softc *sc) { int count; if (sc->state < FWOHCI_STATE_ENABLED) { printf("fwohci not enabled\n"); return(CMD_OK); } fw_crom(sc); fwohci_ibr(sc); count = 0; while (sc->state< FWOHCI_STATE_NORMAL) { fwohci_poll(sc); count ++; if (count > 1000) { printf("give up to wait bus initialize\n"); return (-1); } } printf("poll count = %d\n", count); return (0); } void fw_enable(void) { struct fwohci_softc *sc; int i; if (fw_initialized == 0) fw_init(); for (i = 0; i < MAX_OHCI; i ++) { sc = &fwinfo[i]; if (sc->state != FWOHCI_STATE_INIT) break; sc->config_rom = (uint32_t *) (((uint32_t)sc->config_rom_buf + (CROMSIZE - 1)) & ~(CROMSIZE - 1)); #if 0 printf("configrom: %08p %08p\n", sc->config_rom_buf, sc->config_rom); #endif if (fwohci_init(sc, 0) == 0) { sc->state = FWOHCI_STATE_ENABLED; fw_busreset(sc); } else sc->state = FWOHCI_STATE_DEAD; } } void fw_poll(void) { struct fwohci_softc *sc; int i; if (fw_initialized == 0) return; for (i = 0; i < MAX_OHCI; i ++) { sc = &fwinfo[i]; if (sc->state < FWOHCI_STATE_ENABLED) break; fwohci_poll(sc); } } #if 0 /* for debug */ static int fw_busreset_cmd(int argc, char *argv[]) { struct fwohci_softc *sc; int i; for (i = 0; i < MAX_OHCI; i ++) { sc = &fwinfo[i]; if (sc->state < FWOHCI_STATE_INIT) break; fw_busreset(sc); } return(CMD_OK); } static int fw_poll_cmd(int argc, char *argv[]) { fw_poll(); return(CMD_OK); } static int fw_enable_cmd(int argc, char *argv[]) { fw_print(0); fw_enable(); return(CMD_OK); } static int dcons_enable(int argc, char *argv[]) { dconsole.c_init(0); fw_enable(); dconsole.c_flags |= C_ACTIVEIN | C_ACTIVEOUT; return(CMD_OK); } static int dcons_read(int argc, char *argv[]) { char c; while (dconsole.c_ready()) { c = dconsole.c_in(); printf("%c", c); } printf("\r\n"); return(CMD_OK); } static int dcons_write(int argc, char *argv[]) { int len, i; if (argc < 2) return(CMD_OK); len = strlen(argv[1]); for (i = 0; i < len; i ++) dconsole.c_out(argv[1][i]); dconsole.c_out('\r'); dconsole.c_out('\n'); return(CMD_OK); } COMMAND_SET(firewire, "firewire", "enable firewire", fw_enable_cmd); COMMAND_SET(fwbusreset, "fwbusreset", "firewire busreset", fw_busreset_cmd); COMMAND_SET(fwpoll, "fwpoll", "firewire poll", fw_poll_cmd); COMMAND_SET(dcons, "dcons", "enable dcons", dcons_enable); COMMAND_SET(dread, "dread", "read from dcons", dcons_read); COMMAND_SET(dwrite, "dwrite", "write to dcons", dcons_write); #endif Index: stable/11/stand/i386/libfirewire/fwohci.c =================================================================== --- stable/11/stand/i386/libfirewire/fwohci.c (revision 332155) +++ stable/11/stand/i386/libfirewire/fwohci.c (revision 332156) @@ -1,479 +1,474 @@ /* * Copyright (c) 2003 Hidetoshi Shimokawa * Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the acknowledgement as bellow: * * This product includes software developed by K. Kobayashi and H. Shimokawa * * 4. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD$ * */ #include #include #include +#include #include "fwohci.h" -#include "fwohcireg.h" +#include #include static uint32_t fwphy_wrdata ( struct fwohci_softc *, uint32_t, uint32_t); static uint32_t fwphy_rddata ( struct fwohci_softc *, uint32_t); int firewire_debug=0; #if 0 #define device_printf(a, x, ...) printf("FW1394: " x, ## __VA_ARGS__) #else #define device_printf(a, x, ...) #endif #define device_t int #define DELAY(x) delay(x) #define MAX_SPEED 3 #define MAXREC(x) (2 << (x)) char *linkspeed[] = { "S100", "S200", "S400", "S800", "S1600", "S3200", "undef", "undef" }; - -#define FW_EUI64_BYTE(eui, x) \ - ((((x)<4)? \ - ((eui)->hi >> (8*(3-(x)))): \ - ((eui)->lo >> (8*(7-(x)))) \ - ) & 0xff) /* * Communication with PHY device */ static uint32_t fwphy_wrdata( struct fwohci_softc *sc, uint32_t addr, uint32_t data) { uint32_t fun; addr &= 0xf; data &= 0xff; fun = (PHYDEV_WRCMD | (addr << PHYDEV_REGADDR) | (data << PHYDEV_WRDATA)); OWRITE(sc, OHCI_PHYACCESS, fun); DELAY(100); return(fwphy_rddata( sc, addr)); } static uint32_t fwphy_rddata(struct fwohci_softc *sc, u_int addr) { uint32_t fun, stat; u_int i, retry = 0; addr &= 0xf; #define MAX_RETRY 100 again: OWRITE(sc, FWOHCI_INTSTATCLR, OHCI_INT_REG_FAIL); fun = PHYDEV_RDCMD | (addr << PHYDEV_REGADDR); OWRITE(sc, OHCI_PHYACCESS, fun); for ( i = 0 ; i < MAX_RETRY ; i ++ ){ fun = OREAD(sc, OHCI_PHYACCESS); if ((fun & PHYDEV_RDCMD) == 0 && (fun & PHYDEV_RDDONE) != 0) break; DELAY(100); } if(i >= MAX_RETRY) { if (firewire_debug) device_printf(sc->fc.dev, "phy read failed(1).\n"); if (++retry < MAX_RETRY) { DELAY(100); goto again; } } /* Make sure that SCLK is started */ stat = OREAD(sc, FWOHCI_INTSTAT); if ((stat & OHCI_INT_REG_FAIL) != 0 || ((fun >> PHYDEV_REGADDR) & 0xf) != addr) { if (firewire_debug) device_printf(sc->fc.dev, "phy read failed(2).\n"); if (++retry < MAX_RETRY) { DELAY(100); goto again; } } if (firewire_debug || retry >= MAX_RETRY) device_printf(sc->fc.dev, "fwphy_rddata: 0x%x loop=%d, retry=%d\n", addr, i, retry); #undef MAX_RETRY return((fun >> PHYDEV_RDDATA )& 0xff); } static int fwohci_probe_phy(struct fwohci_softc *sc, device_t dev) { uint32_t reg, reg2; int e1394a = 1; int nport, speed; /* * probe PHY parameters * 0. to prove PHY version, whether compliance of 1394a. * 1. to probe maximum speed supported by the PHY and * number of port supported by core-logic. * It is not actually available port on your PC . */ OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_LPS); DELAY(500); reg = fwphy_rddata(sc, FW_PHY_SPD_REG); if((reg >> 5) != 7 ){ nport = reg & FW_PHY_NP; speed = reg & FW_PHY_SPD >> 6; if (speed > MAX_SPEED) { device_printf(dev, "invalid speed %d (fixed to %d).\n", speed, MAX_SPEED); speed = MAX_SPEED; } device_printf(dev, "Phy 1394 only %s, %d ports.\n", linkspeed[speed], nport); }else{ reg2 = fwphy_rddata(sc, FW_PHY_ESPD_REG); nport = reg & FW_PHY_NP; speed = (reg2 & FW_PHY_ESPD) >> 5; if (speed > MAX_SPEED) { device_printf(dev, "invalid speed %d (fixed to %d).\n", speed, MAX_SPEED); speed = MAX_SPEED; } device_printf(dev, "Phy 1394a available %s, %d ports.\n", linkspeed[speed], nport); /* check programPhyEnable */ reg2 = fwphy_rddata(sc, 5); #if 0 if (e1394a && (OREAD(sc, OHCI_HCCCTL) & OHCI_HCC_PRPHY)) { #else /* XXX force to enable 1394a */ if (e1394a) { #endif if (firewire_debug) device_printf(dev, "Enable 1394a Enhancements\n"); /* enable EAA EMC */ reg2 |= 0x03; /* set aPhyEnhanceEnable */ OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_PHYEN); OWRITE(sc, OHCI_HCCCTLCLR, OHCI_HCC_PRPHY); } else { /* for safe */ reg2 &= ~0x83; } reg2 = fwphy_wrdata(sc, 5, reg2); } sc->speed = speed; reg = fwphy_rddata(sc, FW_PHY_SPD_REG); if((reg >> 5) == 7 ){ reg = fwphy_rddata(sc, 4); reg |= 1 << 6; fwphy_wrdata(sc, 4, reg); reg = fwphy_rddata(sc, 4); } return 0; } void fwohci_reset(struct fwohci_softc *sc, device_t dev) { int i, max_rec, speed; uint32_t reg, reg2; /* Disable interrupts */ OWRITE(sc, FWOHCI_INTMASKCLR, ~0); /* FLUSH FIFO and reset Transmitter/Receiver */ OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_RESET); if (firewire_debug) device_printf(dev, "resetting OHCI..."); i = 0; while(OREAD(sc, OHCI_HCCCTL) & OHCI_HCC_RESET) { if (i++ > 100) break; DELAY(1000); } if (firewire_debug) printf("done (loop=%d)\n", i); /* Probe phy */ fwohci_probe_phy(sc, dev); /* Probe link */ reg = OREAD(sc, OHCI_BUS_OPT); reg2 = reg | OHCI_BUSFNC; max_rec = (reg & 0x0000f000) >> 12; speed = (reg & 0x00000007); device_printf(dev, "Link %s, max_rec %d bytes.\n", linkspeed[speed], MAXREC(max_rec)); /* XXX fix max_rec */ sc->maxrec = sc->speed + 8; if (max_rec != sc->maxrec) { reg2 = (reg2 & 0xffff0fff) | (sc->maxrec << 12); device_printf(dev, "max_rec %d -> %d\n", MAXREC(max_rec), MAXREC(sc->maxrec)); } if (firewire_debug) device_printf(dev, "BUS_OPT 0x%x -> 0x%x\n", reg, reg2); OWRITE(sc, OHCI_BUS_OPT, reg2); /* Initialize registers */ OWRITE(sc, OHCI_CROMHDR, sc->config_rom[0]); OWRITE(sc, OHCI_CROMPTR, VTOP(sc->config_rom)); #if 0 OWRITE(sc, OHCI_SID_BUF, sc->sid_dma.bus_addr); #endif OWRITE(sc, OHCI_HCCCTLCLR, OHCI_HCC_BIGEND); OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_POSTWR); #if 0 OWRITE(sc, OHCI_LNKCTL, OHCI_CNTL_SID); #endif /* Enable link */ OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_LINKEN); } int fwohci_init(struct fwohci_softc *sc, device_t dev) { int i, mver; uint32_t reg; uint8_t ui[8]; /* OHCI version */ reg = OREAD(sc, OHCI_VERSION); mver = (reg >> 16) & 0xff; device_printf(dev, "OHCI version %x.%x (ROM=%d)\n", mver, reg & 0xff, (reg>>24) & 1); if (mver < 1 || mver > 9) { device_printf(dev, "invalid OHCI version\n"); return (ENXIO); } /* Available Isochronous DMA channel probe */ OWRITE(sc, OHCI_IT_MASK, 0xffffffff); OWRITE(sc, OHCI_IR_MASK, 0xffffffff); reg = OREAD(sc, OHCI_IT_MASK) & OREAD(sc, OHCI_IR_MASK); OWRITE(sc, OHCI_IT_MASKCLR, 0xffffffff); OWRITE(sc, OHCI_IR_MASKCLR, 0xffffffff); for (i = 0; i < 0x20; i++) if ((reg & (1 << i)) == 0) break; device_printf(dev, "No. of Isochronous channels is %d.\n", i); if (i == 0) return (ENXIO); #if 0 /* SID receive buffer must align 2^11 */ #define OHCI_SIDSIZE (1 << 11) sc->sid_buf = fwdma_malloc(&sc->fc, OHCI_SIDSIZE, OHCI_SIDSIZE, &sc->sid_dma, BUS_DMA_WAITOK); if (sc->sid_buf == NULL) { device_printf(dev, "sid_buf alloc failed."); return ENOMEM; } #endif sc->eui.hi = OREAD(sc, FWOHCIGUID_H); sc->eui.lo = OREAD(sc, FWOHCIGUID_L); for( i = 0 ; i < 8 ; i ++) ui[i] = FW_EUI64_BYTE(&sc->eui,i); device_printf(dev, "EUI64 %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", ui[0], ui[1], ui[2], ui[3], ui[4], ui[5], ui[6], ui[7]); fwohci_reset(sc, dev); return 0; } void fwohci_ibr(struct fwohci_softc *sc) { uint32_t fun; device_printf(sc->dev, "Initiate bus reset\n"); /* * Make sure our cached values from the config rom are * initialised. */ OWRITE(sc, OHCI_CROMHDR, ntohl(sc->config_rom[0])); OWRITE(sc, OHCI_BUS_OPT, ntohl(sc->config_rom[2])); /* * Set root hold-off bit so that non cyclemaster capable node * shouldn't became the root node. */ #if 1 fun = fwphy_rddata(sc, FW_PHY_IBR_REG); fun |= FW_PHY_IBR; fun = fwphy_wrdata(sc, FW_PHY_IBR_REG, fun); #else /* Short bus reset */ fun = fwphy_rddata(sc, FW_PHY_ISBR_REG); fun |= FW_PHY_ISBR; fun = fwphy_wrdata(sc, FW_PHY_ISBR_REG, fun); #endif } void fwohci_sid(struct fwohci_softc *sc) { uint32_t node_id; int plen; node_id = OREAD(sc, FWOHCI_NODEID); if (!(node_id & OHCI_NODE_VALID)) { #if 0 printf("Bus reset failure\n"); #endif return; } /* Enable bus reset interrupt */ OWRITE(sc, FWOHCI_INTMASK, OHCI_INT_PHY_BUS_R); /* Allow async. request to us */ OWRITE(sc, OHCI_AREQHI, 1 << 31); /* XXX insecure ?? */ OWRITE(sc, OHCI_PREQHI, 0x7fffffff); OWRITE(sc, OHCI_PREQLO, 0xffffffff); OWRITE(sc, OHCI_PREQUPPER, 0x10000); /* Set ATRetries register */ OWRITE(sc, OHCI_ATRETRY, 1<<(13+16) | 0xfff); /* ** Checking whether the node is root or not. If root, turn on ** cycle master. */ plen = OREAD(sc, OHCI_SID_CNT); device_printf(fc->dev, "node_id=0x%08x, gen=%d, ", node_id, (plen >> 16) & 0xff); if (node_id & OHCI_NODE_ROOT) { device_printf(sc->dev, "CYCLEMASTER mode\n"); OWRITE(sc, OHCI_LNKCTL, OHCI_CNTL_CYCMTR | OHCI_CNTL_CYCTIMER); } else { device_printf(sc->dev, "non CYCLEMASTER mode\n"); OWRITE(sc, OHCI_LNKCTLCLR, OHCI_CNTL_CYCMTR); OWRITE(sc, OHCI_LNKCTL, OHCI_CNTL_CYCTIMER); } if (plen & OHCI_SID_ERR) { device_printf(fc->dev, "SID Error\n"); return; } device_printf(sc->dev, "bus reset phase done\n"); sc->state = FWOHCI_STATE_NORMAL; } static void fwohci_intr_body(struct fwohci_softc *sc, uint32_t stat, int count) { #undef OHCI_DEBUG #ifdef OHCI_DEBUG #if 0 if(stat & OREAD(sc, FWOHCI_INTMASK)) #else if (1) #endif device_printf(fc->dev, "INTERRUPT < %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s> 0x%08x, 0x%08x\n", stat & OHCI_INT_EN ? "DMA_EN ":"", stat & OHCI_INT_PHY_REG ? "PHY_REG ":"", stat & OHCI_INT_CYC_LONG ? "CYC_LONG ":"", stat & OHCI_INT_ERR ? "INT_ERR ":"", stat & OHCI_INT_CYC_ERR ? "CYC_ERR ":"", stat & OHCI_INT_CYC_LOST ? "CYC_LOST ":"", stat & OHCI_INT_CYC_64SECOND ? "CYC_64SECOND ":"", stat & OHCI_INT_CYC_START ? "CYC_START ":"", stat & OHCI_INT_PHY_INT ? "PHY_INT ":"", stat & OHCI_INT_PHY_BUS_R ? "BUS_RESET ":"", stat & OHCI_INT_PHY_SID ? "SID ":"", stat & OHCI_INT_LR_ERR ? "DMA_LR_ERR ":"", stat & OHCI_INT_PW_ERR ? "DMA_PW_ERR ":"", stat & OHCI_INT_DMA_IR ? "DMA_IR ":"", stat & OHCI_INT_DMA_IT ? "DMA_IT " :"", stat & OHCI_INT_DMA_PRRS ? "DMA_PRRS " :"", stat & OHCI_INT_DMA_PRRQ ? "DMA_PRRQ " :"", stat & OHCI_INT_DMA_ARRS ? "DMA_ARRS " :"", stat & OHCI_INT_DMA_ARRQ ? "DMA_ARRQ " :"", stat & OHCI_INT_DMA_ATRS ? "DMA_ATRS " :"", stat & OHCI_INT_DMA_ATRQ ? "DMA_ATRQ " :"", stat, OREAD(sc, FWOHCI_INTMASK) ); #endif /* Bus reset */ if(stat & OHCI_INT_PHY_BUS_R ){ device_printf(fc->dev, "BUS reset\n"); if (sc->state == FWOHCI_STATE_BUSRESET) goto busresetout; sc->state = FWOHCI_STATE_BUSRESET; /* Disable bus reset interrupt until sid recv. */ OWRITE(sc, FWOHCI_INTMASKCLR, OHCI_INT_PHY_BUS_R); OWRITE(sc, FWOHCI_INTMASKCLR, OHCI_INT_CYC_LOST); OWRITE(sc, OHCI_LNKCTLCLR, OHCI_CNTL_CYCSRC); OWRITE(sc, OHCI_CROMHDR, ntohl(sc->config_rom[0])); OWRITE(sc, OHCI_BUS_OPT, ntohl(sc->config_rom[2])); } else if (sc->state == FWOHCI_STATE_BUSRESET) { fwohci_sid(sc); } busresetout: return; } static uint32_t fwochi_check_stat(struct fwohci_softc *sc) { uint32_t stat; stat = OREAD(sc, FWOHCI_INTSTAT); if (stat == 0xffffffff) { device_printf(sc->fc.dev, "device physically ejected?\n"); return(stat); } if (stat) OWRITE(sc, FWOHCI_INTSTATCLR, stat); return(stat); } void fwohci_poll(struct fwohci_softc *sc) { uint32_t stat; stat = fwochi_check_stat(sc); if (stat != 0xffffffff) fwohci_intr_body(sc, stat, 1); } Index: stable/11/stand/i386/libfirewire/fwohci.h =================================================================== --- stable/11/stand/i386/libfirewire/fwohci.h (revision 332155) +++ stable/11/stand/i386/libfirewire/fwohci.h (revision 332156) @@ -1,162 +1,158 @@ /* * Copyright (c) 2007 Hidetoshi Shimokawa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the acknowledgement as bellow: * * This product includes software developed by K. Kobayashi and H. Shimokawa * * 4. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD$ * */ #define MAX_OHCI 5 #define CROMSIZE 0x400 -struct fw_eui64 { - uint32_t hi, lo; -}; - struct fwohci_softc { uint32_t locator; uint32_t devid; uint32_t base_addr; uint32_t bus_id; uint32_t handle; int32_t state; struct crom_src_buf *crom_src_buf; struct crom_src *crom_src; struct crom_chunk *crom_root; struct fw_eui64 eui; int speed; int maxrec; uint32_t *config_rom; char config_rom_buf[CROMSIZE*2]; /* double size for alignment */ }; int fwohci_init(struct fwohci_softc *, int); void fwohci_ibr(struct fwohci_softc *); void fwohci_poll(struct fwohci_softc *); #define FWOHCI_STATE_DEAD (-1) #define FWOHCI_STATE_INIT 0 #define FWOHCI_STATE_ENABLED 1 #define FWOHCI_STATE_BUSRESET 2 #define FWOHCI_STATE_NORMAL 3 #define OREAD(f, o) (*(volatile uint32_t *)((f)->handle + (o))) #define OWRITE(f, o, v) (*(volatile uint32_t *)((f)->handle + (o)) = (v)) #define OHCI_VERSION 0x00 #define OHCI_ATRETRY 0x08 #define OHCI_CROMHDR 0x18 #define OHCI_BUS_ID 0x1c #define OHCI_BUS_OPT 0x20 #define OHCI_BUSIRMC (1U << 31) #define OHCI_BUSCMC (1 << 30) #define OHCI_BUSISC (1 << 29) #define OHCI_BUSBMC (1 << 28) #define OHCI_BUSPMC (1 << 27) #define OHCI_BUSFNC OHCI_BUSIRMC | OHCI_BUSCMC | OHCI_BUSISC |\ OHCI_BUSBMC | OHCI_BUSPMC #define OHCI_EUID_HI 0x24 #define OHCI_EUID_LO 0x28 #define OHCI_CROMPTR 0x34 #define OHCI_HCCCTL 0x50 #define OHCI_HCCCTLCLR 0x54 #define OHCI_AREQHI 0x100 #define OHCI_AREQHICLR 0x104 #define OHCI_AREQLO 0x108 #define OHCI_AREQLOCLR 0x10c #define OHCI_PREQHI 0x110 #define OHCI_PREQHICLR 0x114 #define OHCI_PREQLO 0x118 #define OHCI_PREQLOCLR 0x11c #define OHCI_PREQUPPER 0x120 #define OHCI_SID_BUF 0x64 #define OHCI_SID_CNT 0x68 #define OHCI_SID_ERR (1U << 31) #define OHCI_SID_CNT_MASK 0xffc #define OHCI_IT_STAT 0x90 #define OHCI_IT_STATCLR 0x94 #define OHCI_IT_MASK 0x98 #define OHCI_IT_MASKCLR 0x9c #define OHCI_IR_STAT 0xa0 #define OHCI_IR_STATCLR 0xa4 #define OHCI_IR_MASK 0xa8 #define OHCI_IR_MASKCLR 0xac #define OHCI_LNKCTL 0xe0 #define OHCI_LNKCTLCLR 0xe4 #define OHCI_PHYACCESS 0xec #define OHCI_CYCLETIMER 0xf0 #define OHCI_DMACTL(off) (off) #define OHCI_DMACTLCLR(off) (off + 4) #define OHCI_DMACMD(off) (off + 0xc) #define OHCI_DMAMATCH(off) (off + 0x10) #define OHCI_ATQOFF 0x180 #define OHCI_ATQCTL OHCI_ATQOFF #define OHCI_ATQCTLCLR (OHCI_ATQOFF + 4) #define OHCI_ATQCMD (OHCI_ATQOFF + 0xc) #define OHCI_ATQMATCH (OHCI_ATQOFF + 0x10) #define OHCI_ATSOFF 0x1a0 #define OHCI_ATSCTL OHCI_ATSOFF #define OHCI_ATSCTLCLR (OHCI_ATSOFF + 4) #define OHCI_ATSCMD (OHCI_ATSOFF + 0xc) #define OHCI_ATSMATCH (OHCI_ATSOFF + 0x10) #define OHCI_ARQOFF 0x1c0 #define OHCI_ARQCTL OHCI_ARQOFF #define OHCI_ARQCTLCLR (OHCI_ARQOFF + 4) #define OHCI_ARQCMD (OHCI_ARQOFF + 0xc) #define OHCI_ARQMATCH (OHCI_ARQOFF + 0x10) #define OHCI_ARSOFF 0x1e0 #define OHCI_ARSCTL OHCI_ARSOFF #define OHCI_ARSCTLCLR (OHCI_ARSOFF + 4) #define OHCI_ARSCMD (OHCI_ARSOFF + 0xc) #define OHCI_ARSMATCH (OHCI_ARSOFF + 0x10) #define OHCI_ITOFF(CH) (0x200 + 0x10 * (CH)) #define OHCI_ITCTL(CH) (OHCI_ITOFF(CH)) #define OHCI_ITCTLCLR(CH) (OHCI_ITOFF(CH) + 4) #define OHCI_ITCMD(CH) (OHCI_ITOFF(CH) + 0xc) #define OHCI_IROFF(CH) (0x400 + 0x20 * (CH)) #define OHCI_IRCTL(CH) (OHCI_IROFF(CH)) #define OHCI_IRCTLCLR(CH) (OHCI_IROFF(CH) + 4) #define OHCI_IRCMD(CH) (OHCI_IROFF(CH) + 0xc) #define OHCI_IRMATCH(CH) (OHCI_IROFF(CH) + 0x10) Index: stable/11/sys/dev/firewire/fwohci_pci.c =================================================================== --- stable/11/sys/dev/firewire/fwohci_pci.c (revision 332155) +++ stable/11/sys/dev/firewire/fwohci_pci.c (revision 332156) @@ -1,484 +1,484 @@ /*- * Copyright (c) 2003 Hidetoshi Shimokawa * Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the acknowledgement as bellow: * * This product includes software developed by K. Kobayashi and H. SHimokawa * * 4. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #define BOUNCE_BUFFER_TEST 0 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static int fwohci_pci_attach(device_t self); static int fwohci_pci_detach(device_t self); /* * The probe routine. */ static int fwohci_pci_probe(device_t dev) { uint32_t id; id = pci_get_devid(dev); if (id == (FW_VENDORID_NATSEMI | FW_DEVICE_CS4210)) { device_set_desc(dev, "National Semiconductor CS4210"); return BUS_PROBE_DEFAULT; } if (id == (FW_VENDORID_NEC | FW_DEVICE_UPD861)) { device_set_desc(dev, "NEC uPD72861"); return BUS_PROBE_DEFAULT; } if (id == (FW_VENDORID_NEC | FW_DEVICE_UPD871)) { device_set_desc(dev, "NEC uPD72871/2"); return BUS_PROBE_DEFAULT; } if (id == (FW_VENDORID_NEC | FW_DEVICE_UPD72870)) { device_set_desc(dev, "NEC uPD72870"); return BUS_PROBE_DEFAULT; } if (id == (FW_VENDORID_NEC | FW_DEVICE_UPD72873)) { device_set_desc(dev, "NEC uPD72873"); return BUS_PROBE_DEFAULT; } if (id == (FW_VENDORID_NEC | FW_DEVICE_UPD72874)) { device_set_desc(dev, "NEC uPD72874"); return BUS_PROBE_DEFAULT; } if (id == (FW_VENDORID_SIS | FW_DEVICE_7007)) { /* It has no real identifier, using device id. */ device_set_desc(dev, "SiS 7007"); return BUS_PROBE_DEFAULT; } if (id == (FW_VENDORID_TI | FW_DEVICE_TITSB22)) { device_set_desc(dev, "Texas Instruments TSB12LV22"); return BUS_PROBE_DEFAULT; } if (id == (FW_VENDORID_TI | FW_DEVICE_TITSB23)) { device_set_desc(dev, "Texas Instruments TSB12LV23"); return BUS_PROBE_DEFAULT; } if (id == (FW_VENDORID_TI | FW_DEVICE_TITSB26)) { device_set_desc(dev, "Texas Instruments TSB12LV26"); return BUS_PROBE_DEFAULT; } if (id == (FW_VENDORID_TI | FW_DEVICE_TITSB43)) { device_set_desc(dev, "Texas Instruments TSB43AA22"); return BUS_PROBE_DEFAULT; } if (id == (FW_VENDORID_TI | FW_DEVICE_TITSB43A)) { device_set_desc(dev, "Texas Instruments TSB43AB22/A"); return BUS_PROBE_DEFAULT; } if (id == (FW_VENDORID_TI | FW_DEVICE_TITSB43AB21)) { device_set_desc(dev, "Texas Instruments TSB43AB21/A/AI/A-EP"); return BUS_PROBE_DEFAULT; } if (id == (FW_VENDORID_TI | FW_DEVICE_TITSB43AB23)) { device_set_desc(dev, "Texas Instruments TSB43AB23"); return BUS_PROBE_DEFAULT; } if (id == (FW_VENDORID_TI | FW_DEVICE_TITSB82AA2)) { device_set_desc(dev, "Texas Instruments TSB82AA2"); return BUS_PROBE_DEFAULT; } if (id == (FW_VENDORID_TI | FW_DEVICE_TIPCI4450)) { device_set_desc(dev, "Texas Instruments PCI4450"); return BUS_PROBE_DEFAULT; } if (id == (FW_VENDORID_TI | FW_DEVICE_TIPCI4410A)) { device_set_desc(dev, "Texas Instruments PCI4410A"); return BUS_PROBE_DEFAULT; } if (id == (FW_VENDORID_TI | FW_DEVICE_TIPCI4451)) { device_set_desc(dev, "Texas Instruments PCI4451"); return BUS_PROBE_DEFAULT; } if (id == (FW_VENDORID_SONY | FW_DEVICE_CXD1947)) { device_printf(dev, "Sony i.LINK (CXD1947) not supported\n"); return ENXIO; } if (id == (FW_VENDORID_SONY | FW_DEVICE_CXD3222)) { device_set_desc(dev, "Sony i.LINK (CXD3222)"); return BUS_PROBE_DEFAULT; } if (id == (FW_VENDORID_VIA | FW_DEVICE_VT6306)) { device_set_desc(dev, "VIA Fire II (VT6306)"); return BUS_PROBE_DEFAULT; } if (id == (FW_VENDORID_RICOH | FW_DEVICE_R5C551)) { device_set_desc(dev, "Ricoh R5C551"); return BUS_PROBE_DEFAULT; } if (id == (FW_VENDORID_RICOH | FW_DEVICE_R5C552)) { device_set_desc(dev, "Ricoh R5C552"); return BUS_PROBE_DEFAULT; } if (id == (FW_VENDORID_APPLE | FW_DEVICE_PANGEA)) { device_set_desc(dev, "Apple Pangea"); return BUS_PROBE_DEFAULT; } - if (id == (FW_VENDORID_APPLE | FW_DEVICE_UNINORTH)) { - device_set_desc(dev, "Apple UniNorth"); + if (id == (FW_VENDORID_APPLE | FW_DEVICE_UNINORTH2)) { + device_set_desc(dev, "Apple UniNorth 2"); return BUS_PROBE_DEFAULT; } if (id == (FW_VENDORID_LUCENT | FW_DEVICE_FW322)) { device_set_desc(dev, "Lucent FW322/323"); return BUS_PROBE_DEFAULT; } if (id == (FW_VENDORID_INTEL | FW_DEVICE_82372FB)) { device_set_desc(dev, "Intel 82372FB"); return BUS_PROBE_DEFAULT; } if (id == (FW_VENDORID_ADAPTEC | FW_DEVICE_AIC5800)) { device_set_desc(dev, "Adaptec AHA-894x/AIC-5800"); return BUS_PROBE_DEFAULT; } if (id == (FW_VENDORID_SUN | FW_DEVICE_PCIO2FW)) { device_set_desc(dev, "Sun PCIO-2"); return BUS_PROBE_DEFAULT; } if (pci_get_class(dev) == PCIC_SERIALBUS && pci_get_subclass(dev) == PCIS_SERIALBUS_FW && pci_get_progif(dev) == PCI_INTERFACE_OHCI) { if (bootverbose) device_printf(dev, "vendor=%x, dev=%x\n", pci_get_vendor(dev), pci_get_device(dev)); device_set_desc(dev, "1394 Open Host Controller Interface"); return BUS_PROBE_DEFAULT; } return ENXIO; } static int fwohci_pci_init(device_t self) { int olatency, latency, ocache_line, cache_line; uint16_t cmd; cmd = pci_read_config(self, PCIR_COMMAND, 2); cmd |= PCIM_CMD_BUSMASTEREN | PCIM_CMD_MWRICEN; #if 1 /* for broken hardware */ cmd &= ~PCIM_CMD_MWRICEN; #endif pci_write_config(self, PCIR_COMMAND, cmd, 2); /* * Some Sun PCIO-2 FireWire controllers have their intpin register * bogusly set to 0, although it should be 3. Correct that. */ if (pci_get_devid(self) == (FW_VENDORID_SUN | FW_DEVICE_PCIO2FW) && pci_get_intpin(self) == 0) pci_set_intpin(self, 3); latency = olatency = pci_read_config(self, PCIR_LATTIMER, 1); #define DEF_LATENCY 0x20 if (olatency < DEF_LATENCY) { latency = DEF_LATENCY; pci_write_config(self, PCIR_LATTIMER, latency, 1); } cache_line = ocache_line = pci_read_config(self, PCIR_CACHELNSZ, 1); #define DEF_CACHE_LINE 8 if (ocache_line < DEF_CACHE_LINE) { cache_line = DEF_CACHE_LINE; pci_write_config(self, PCIR_CACHELNSZ, cache_line, 1); } if (firewire_debug) { device_printf(self, "latency timer %d -> %d.\n", olatency, latency); device_printf(self, "cache size %d -> %d.\n", ocache_line, cache_line); } return 0; } static int fwohci_pci_attach(device_t self) { fwohci_softc_t *sc = device_get_softc(self); int err; int rid; #if 0 if (bootverbose) firewire_debug = bootverbose; #endif mtx_init(FW_GMTX(&sc->fc), "firewire", NULL, MTX_DEF); fwohci_pci_init(self); rid = PCI_CBMEM; sc->bsr = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (!sc->bsr) { device_printf(self, "Could not map memory\n"); return ENXIO; } sc->bst = rman_get_bustag(sc->bsr); sc->bsh = rman_get_bushandle(sc->bsr); rid = 0; sc->irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE); if (sc->irq_res == NULL) { device_printf(self, "Could not allocate irq\n"); fwohci_pci_detach(self); return ENXIO; } err = bus_setup_intr(self, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE, NULL, (driver_intr_t *) fwohci_intr, sc, &sc->ih); if (err) { device_printf(self, "Could not setup irq, %d\n", err); fwohci_pci_detach(self); return ENXIO; } err = bus_dma_tag_create( /*parent*/bus_get_dma_tag(self), /*alignment*/1, /*boundary*/0, #if BOUNCE_BUFFER_TEST /*lowaddr*/BUS_SPACE_MAXADDR_24BIT, #else /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, #endif /*highaddr*/BUS_SPACE_MAXADDR, /*filter*/NULL, /*filterarg*/NULL, /*maxsize*/0x100000, /*nsegments*/0x20, /*maxsegsz*/0x8000, /*flags*/BUS_DMA_ALLOCNOW, /*lockfunc*/busdma_lock_mutex, /*lockarg*/FW_GMTX(&sc->fc), &sc->fc.dmat); if (err != 0) { device_printf(self, "fwohci_pci_attach: Could not allocate DMA " "tag - error %d\n", err); fwohci_pci_detach(self); return (ENOMEM); } err = fwohci_init(sc, self); if (err != 0) { device_printf(self, "fwohci_init failed with err=%d\n", err); fwohci_pci_detach(self); return EIO; } /* probe and attach a child device(firewire) */ bus_generic_probe(self); bus_generic_attach(self); return 0; } static int fwohci_pci_detach(device_t self) { fwohci_softc_t *sc = device_get_softc(self); int s; s = splfw(); if (sc->bsr) fwohci_stop(sc, self); bus_generic_detach(self); if (sc->fc.bdev) { device_delete_child(self, sc->fc.bdev); sc->fc.bdev = NULL; } /* disable interrupts that might have been switched on */ if (sc->bst && sc->bsh) bus_space_write_4(sc->bst, sc->bsh, FWOHCI_INTMASKCLR, OHCI_INT_EN); if (sc->irq_res) { int err; if (sc->ih) { err = bus_teardown_intr(self, sc->irq_res, sc->ih); if (err) device_printf(self, "Could not tear down irq, %d\n", err); sc->ih = NULL; } bus_release_resource(self, SYS_RES_IRQ, 0, sc->irq_res); sc->irq_res = NULL; } if (sc->bsr) { bus_release_resource(self, SYS_RES_MEMORY, PCI_CBMEM, sc->bsr); sc->bsr = NULL; sc->bst = 0; sc->bsh = 0; } fwohci_detach(sc, self); mtx_destroy(FW_GMTX(&sc->fc)); splx(s); return 0; } static int fwohci_pci_suspend(device_t dev) { fwohci_softc_t *sc = device_get_softc(dev); int err; device_printf(dev, "fwohci_pci_suspend\n"); err = bus_generic_suspend(dev); if (err) return err; fwohci_stop(sc, dev); return 0; } static int fwohci_pci_resume(device_t dev) { fwohci_softc_t *sc = device_get_softc(dev); fwohci_pci_init(dev); fwohci_resume(sc, dev); return 0; } static int fwohci_pci_shutdown(device_t dev) { fwohci_softc_t *sc = device_get_softc(dev); bus_generic_shutdown(dev); fwohci_stop(sc, dev); return 0; } static device_t fwohci_pci_add_child(device_t dev, u_int order, const char *name, int unit) { struct fwohci_softc *sc; device_t child; int err = 0; sc = (struct fwohci_softc *)device_get_softc(dev); child = device_add_child(dev, name, unit); if (child == NULL) return (child); sc->fc.bdev = child; device_set_ivars(child, &sc->fc); err = device_probe_and_attach(child); if (err) { device_printf(dev, "probe_and_attach failed with err=%d\n", err); fwohci_pci_detach(dev); device_delete_child(dev, child); return NULL; } /* XXX * Clear the bus reset event flag to start transactions even when * interrupt is disabled during the boot process. */ if (cold) { int s; DELAY(250); /* 2 cycles */ s = splfw(); fwohci_poll(&sc->fc, 0, -1); splx(s); } return (child); } static device_method_t fwohci_methods[] = { /* Device interface */ DEVMETHOD(device_probe, fwohci_pci_probe), DEVMETHOD(device_attach, fwohci_pci_attach), DEVMETHOD(device_detach, fwohci_pci_detach), DEVMETHOD(device_suspend, fwohci_pci_suspend), DEVMETHOD(device_resume, fwohci_pci_resume), DEVMETHOD(device_shutdown, fwohci_pci_shutdown), /* Bus interface */ DEVMETHOD(bus_add_child, fwohci_pci_add_child), DEVMETHOD_END }; static driver_t fwohci_driver = { "fwohci", fwohci_methods, sizeof(fwohci_softc_t), }; static devclass_t fwohci_devclass; #ifdef FWOHCI_MODULE MODULE_DEPEND(fwohci, firewire, 1, 1, 1); #endif DRIVER_MODULE(fwohci, pci, fwohci_driver, fwohci_devclass, 0, 0); Index: stable/11/sys/dev/firewire/fwohcireg.h =================================================================== --- stable/11/sys/dev/firewire/fwohcireg.h (revision 332155) +++ stable/11/sys/dev/firewire/fwohcireg.h (revision 332156) @@ -1,448 +1,450 @@ /*- * Copyright (c) 2003 Hidetoshi Shimokawa * Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the acknowledgement as bellow: * * This product includes software developed by K. Kobayashi and H. Shimokawa * * 4. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD$ * */ #define PCI_CBMEM PCIR_BAR(0) #define FW_VENDORID_NATSEMI 0x100B #define FW_VENDORID_NEC 0x1033 #define FW_VENDORID_SIS 0x1039 #define FW_VENDORID_TI 0x104c #define FW_VENDORID_SONY 0x104d #define FW_VENDORID_VIA 0x1106 #define FW_VENDORID_RICOH 0x1180 #define FW_VENDORID_APPLE 0x106b #define FW_VENDORID_LUCENT 0x11c1 #define FW_VENDORID_INTEL 0x8086 #define FW_VENDORID_ADAPTEC 0x9004 #define FW_VENDORID_SUN 0x108e #define FW_DEVICE_CS4210 (0x000f << 16) #define FW_DEVICE_UPD861 (0x0063 << 16) #define FW_DEVICE_UPD871 (0x00ce << 16) #define FW_DEVICE_UPD72870 (0x00cd << 16) #define FW_DEVICE_UPD72873 (0x00e7 << 16) #define FW_DEVICE_UPD72874 (0x00f2 << 16) #define FW_DEVICE_TITSB22 (0x8009 << 16) #define FW_DEVICE_TITSB23 (0x8019 << 16) #define FW_DEVICE_TITSB26 (0x8020 << 16) #define FW_DEVICE_TITSB43 (0x8021 << 16) #define FW_DEVICE_TITSB43A (0x8023 << 16) #define FW_DEVICE_TITSB43AB23 (0x8024 << 16) #define FW_DEVICE_TITSB82AA2 (0x8025 << 16) #define FW_DEVICE_TITSB43AB21 (0x8026 << 16) #define FW_DEVICE_TIPCI4410A (0x8017 << 16) #define FW_DEVICE_TIPCI4450 (0x8011 << 16) #define FW_DEVICE_TIPCI4451 (0x8027 << 16) #define FW_DEVICE_CXD1947 (0x8009 << 16) #define FW_DEVICE_CXD3222 (0x8039 << 16) #define FW_DEVICE_VT6306 (0x3044 << 16) #define FW_DEVICE_R5C551 (0x0551 << 16) #define FW_DEVICE_R5C552 (0x0552 << 16) #define FW_DEVICE_PANGEA (0x0030 << 16) -#define FW_DEVICE_UNINORTH (0x0031 << 16) +#define FW_DEVICE_UNINORTH2 (0x0031 << 16) #define FW_DEVICE_AIC5800 (0x5800 << 16) #define FW_DEVICE_FW322 (0x5811 << 16) #define FW_DEVICE_7007 (0x7007 << 16) #define FW_DEVICE_82372FB (0x7605 << 16) #define FW_DEVICE_PCIO2FW (0x1102 << 16) #define PCI_INTERFACE_OHCI 0x10 #define FW_OHCI_BASE_REG 0x10 #define OHCI_DMA_ITCH 0x20 #define OHCI_DMA_IRCH 0x20 #define OHCI_MAX_DMA_CH (0x4 + OHCI_DMA_ITCH + OHCI_DMA_IRCH) typedef uint32_t fwohcireg_t; /* for PCI */ #if BYTE_ORDER == BIG_ENDIAN #define FWOHCI_DMA_WRITE(x, y) ((x) = htole32(y)) #define FWOHCI_DMA_READ(x) le32toh(x) #define FWOHCI_DMA_SET(x, y) ((x) |= htole32(y)) #define FWOHCI_DMA_CLEAR(x, y) ((x) &= htole32(~(y))) #else #define FWOHCI_DMA_WRITE(x, y) ((x) = (y)) #define FWOHCI_DMA_READ(x) (x) #define FWOHCI_DMA_SET(x, y) ((x) |= (y)) #define FWOHCI_DMA_CLEAR(x, y) ((x) &= ~(y)) #endif struct fwohcidb { union { struct { uint32_t cmd; uint32_t addr; uint32_t depend; uint32_t res; } desc; uint32_t immed[4]; } db; #define OHCI_STATUS_SHIFT 16 #define OHCI_COUNT_MASK 0xffff #define OHCI_OUTPUT_MORE (0 << 28) #define OHCI_OUTPUT_LAST (1 << 28) #define OHCI_INPUT_MORE (2 << 28) #define OHCI_INPUT_LAST (3 << 28) #define OHCI_STORE_QUAD (4 << 28) #define OHCI_LOAD_QUAD (5 << 28) #define OHCI_NOP (6 << 28) #define OHCI_STOP (7 << 28) #define OHCI_STORE (8 << 28) #define OHCI_CMD_MASK (0xf << 28) #define OHCI_UPDATE (1 << 27) #define OHCI_KEY_ST0 (0 << 24) #define OHCI_KEY_ST1 (1 << 24) #define OHCI_KEY_ST2 (2 << 24) #define OHCI_KEY_ST3 (3 << 24) #define OHCI_KEY_REGS (5 << 24) #define OHCI_KEY_SYS (6 << 24) #define OHCI_KEY_DEVICE (7 << 24) #define OHCI_KEY_MASK (7 << 24) #define OHCI_INTERRUPT_NEVER (0 << 20) #define OHCI_INTERRUPT_TRUE (1 << 20) #define OHCI_INTERRUPT_FALSE (2 << 20) #define OHCI_INTERRUPT_ALWAYS (3 << 20) #define OHCI_BRANCH_NEVER (0 << 18) #define OHCI_BRANCH_TRUE (1 << 18) #define OHCI_BRANCH_FALSE (2 << 18) #define OHCI_BRANCH_ALWAYS (3 << 18) #define OHCI_BRANCH_MASK (3 << 18) #define OHCI_WAIT_NEVER (0 << 16) #define OHCI_WAIT_TRUE (1 << 16) #define OHCI_WAIT_FALSE (2 << 16) #define OHCI_WAIT_ALWAYS (3 << 16) }; #define OHCI_SPD_S100 0x4 #define OHCI_SPD_S200 0x1 #define OHCI_SPD_S400 0x2 #define FWOHCIEV_NOSTAT 0 #define FWOHCIEV_LONGP 2 #define FWOHCIEV_MISSACK 3 #define FWOHCIEV_UNDRRUN 4 #define FWOHCIEV_OVRRUN 5 #define FWOHCIEV_DESCERR 6 #define FWOHCIEV_DTRDERR 7 #define FWOHCIEV_DTWRERR 8 #define FWOHCIEV_BUSRST 9 #define FWOHCIEV_TIMEOUT 0xa #define FWOHCIEV_TCODERR 0xb #define FWOHCIEV_UNKNOWN 0xe #define FWOHCIEV_FLUSHED 0xf #define FWOHCIEV_ACKCOMPL 0x11 #define FWOHCIEV_ACKPEND 0x12 #define FWOHCIEV_ACKBSX 0x14 #define FWOHCIEV_ACKBSA 0x15 #define FWOHCIEV_ACKBSB 0x16 #define FWOHCIEV_ACKTARD 0x1b #define FWOHCIEV_ACKDERR 0x1d #define FWOHCIEV_ACKTERR 0x1e #define FWOHCIEV_MASK 0x1f struct ohci_dma { fwohcireg_t cntl; #define OHCI_CNTL_CYCMATCH_S (0x1 << 31) #define OHCI_CNTL_BUFFIL (0x1 << 31) #define OHCI_CNTL_ISOHDR (0x1 << 30) #define OHCI_CNTL_CYCMATCH_R (0x1 << 29) #define OHCI_CNTL_MULTICH (0x1 << 28) #define OHCI_CNTL_DMA_RUN (0x1 << 15) #define OHCI_CNTL_DMA_WAKE (0x1 << 12) #define OHCI_CNTL_DMA_DEAD (0x1 << 11) #define OHCI_CNTL_DMA_ACTIVE (0x1 << 10) #define OHCI_CNTL_DMA_BT (0x1 << 8) #define OHCI_CNTL_DMA_BAD (0x1 << 7) #define OHCI_CNTL_DMA_STAT (0xff) fwohcireg_t cntl_clr; fwohcireg_t dummy0; fwohcireg_t cmd; fwohcireg_t match; fwohcireg_t dummy1; fwohcireg_t dummy2; fwohcireg_t dummy3; }; struct ohci_itdma { fwohcireg_t cntl; fwohcireg_t cntl_clr; fwohcireg_t dummy0; fwohcireg_t cmd; }; struct ohci_registers { fwohcireg_t ver; /* Version No. 0x0 */ fwohcireg_t guid; /* GUID_ROM No. 0x4 */ fwohcireg_t retry; /* AT retries 0x8 */ #define FWOHCI_RETRY 0x8 fwohcireg_t csr_data; /* CSR data 0xc */ fwohcireg_t csr_cmp; /* CSR compare 0x10 */ fwohcireg_t csr_cntl; /* CSR compare 0x14 */ fwohcireg_t rom_hdr; /* config ROM ptr. 0x18 */ fwohcireg_t bus_id; /* BUS_ID 0x1c */ fwohcireg_t bus_opt; /* BUS option 0x20 */ #define FWOHCIGUID_H 0x24 #define FWOHCIGUID_L 0x28 fwohcireg_t guid_hi; /* GUID hi 0x24 */ fwohcireg_t guid_lo; /* GUID lo 0x28 */ fwohcireg_t dummy0[2]; /* dummy 0x2c-0x30 */ fwohcireg_t config_rom; /* config ROM map 0x34 */ fwohcireg_t post_wr_lo; /* post write addr lo 0x38 */ fwohcireg_t post_wr_hi; /* post write addr hi 0x3c */ fwohcireg_t vendor; /* vendor ID 0x40 */ fwohcireg_t dummy1[3]; /* dummy 0x44-0x4c */ fwohcireg_t hcc_cntl_set; /* HCC control set 0x50 */ fwohcireg_t hcc_cntl_clr; /* HCC control clr 0x54 */ #define OHCI_HCC_BIBIV (1U << 31) /* BIBimage Valid */ #define OHCI_HCC_BIGEND (1 << 30) /* noByteSwapData */ #define OHCI_HCC_PRPHY (1 << 23) /* programPhyEnable */ #define OHCI_HCC_PHYEN (1 << 22) /* aPhyEnhanceEnable */ #define OHCI_HCC_LPS (1 << 19) /* LPS */ #define OHCI_HCC_POSTWR (1 << 18) /* postedWriteEnable */ #define OHCI_HCC_LINKEN (1 << 17) /* linkEnable */ #define OHCI_HCC_RESET (1 << 16) /* softReset */ fwohcireg_t dummy2[2]; /* dummy 0x58-0x5c */ fwohcireg_t dummy3[1]; /* dummy 0x60 */ fwohcireg_t sid_buf; /* self id buffer 0x64 */ fwohcireg_t sid_cnt; /* self id count 0x68 */ fwohcireg_t dummy4[1]; /* dummy 0x6c */ fwohcireg_t ir_mask_hi_set; /* ir mask hi set 0x70 */ fwohcireg_t ir_mask_hi_clr; /* ir mask hi set 0x74 */ fwohcireg_t ir_mask_lo_set; /* ir mask hi set 0x78 */ fwohcireg_t ir_mask_lo_clr; /* ir mask hi set 0x7c */ #define FWOHCI_INTSTAT 0x80 #define FWOHCI_INTSTATCLR 0x84 #define FWOHCI_INTMASK 0x88 #define FWOHCI_INTMASKCLR 0x8c fwohcireg_t int_stat; /* 0x80 */ fwohcireg_t int_clear; /* 0x84 */ fwohcireg_t int_mask; /* 0x88 */ fwohcireg_t int_mask_clear; /* 0x8c */ fwohcireg_t it_int_stat; /* 0x90 */ fwohcireg_t it_int_clear; /* 0x94 */ fwohcireg_t it_int_mask; /* 0x98 */ fwohcireg_t it_mask_clear; /* 0x9c */ fwohcireg_t ir_int_stat; /* 0xa0 */ fwohcireg_t ir_int_clear; /* 0xa4 */ fwohcireg_t ir_int_mask; /* 0xa8 */ fwohcireg_t ir_mask_clear; /* 0xac */ fwohcireg_t dummy5[11]; /* dummy 0xb0-d8 */ fwohcireg_t fairness; /* fairness control 0xdc */ fwohcireg_t link_cntl; /* Chip control 0xe0*/ fwohcireg_t link_cntl_clr; /* Chip control clear 0xe4*/ #define FWOHCI_NODEID 0xe8 fwohcireg_t node; /* Node ID 0xe8 */ #define OHCI_NODE_VALID (1U << 31) #define OHCI_NODE_ROOT (1 << 30) #define OHCI_ASYSRCBUS 1 fwohcireg_t phy_access; /* PHY cntl 0xec */ #define PHYDEV_RDDONE (1<<31) #define PHYDEV_RDCMD (1<<15) #define PHYDEV_WRCMD (1<<14) #define PHYDEV_REGADDR 8 #define PHYDEV_WRDATA 0 #define PHYDEV_RDADDR 24 #define PHYDEV_RDDATA 16 fwohcireg_t cycle_timer; /* Cycle Timer 0xf0 */ fwohcireg_t dummy6[3]; /* dummy 0xf4-fc */ fwohcireg_t areq_hi; /* Async req. filter hi 0x100 */ fwohcireg_t areq_hi_clr; /* Async req. filter hi 0x104 */ fwohcireg_t areq_lo; /* Async req. filter lo 0x108 */ fwohcireg_t areq_lo_clr; /* Async req. filter lo 0x10c */ fwohcireg_t preq_hi; /* Async req. filter hi 0x110 */ fwohcireg_t preq_hi_clr; /* Async req. filter hi 0x114 */ fwohcireg_t preq_lo; /* Async req. filter lo 0x118 */ fwohcireg_t preq_lo_clr; /* Async req. filter lo 0x11c */ fwohcireg_t pys_upper; /* Physical Upper bound 0x120 */ fwohcireg_t dummy7[23]; /* dummy 0x124-0x17c */ /* 0x180, 0x184, 0x188, 0x18c */ /* 0x190, 0x194, 0x198, 0x19c */ /* 0x1a0, 0x1a4, 0x1a8, 0x1ac */ /* 0x1b0, 0x1b4, 0x1b8, 0x1bc */ /* 0x1c0, 0x1c4, 0x1c8, 0x1cc */ /* 0x1d0, 0x1d4, 0x1d8, 0x1dc */ /* 0x1e0, 0x1e4, 0x1e8, 0x1ec */ /* 0x1f0, 0x1f4, 0x1f8, 0x1fc */ struct ohci_dma dma_ch[0x4]; /* 0x200, 0x204, 0x208, 0x20c */ /* 0x210, 0x204, 0x208, 0x20c */ struct ohci_itdma dma_itch[0x20]; /* 0x400, 0x404, 0x408, 0x40c */ /* 0x410, 0x404, 0x408, 0x40c */ struct ohci_dma dma_irch[0x20]; }; +#ifndef _STANDALONE struct fwohcidb_tr { STAILQ_ENTRY(fwohcidb_tr) link; struct fw_xfer *xfer; struct fwohcidb *db; bus_dmamap_t dma_map; caddr_t buf; bus_addr_t bus_addr; int dbcnt; }; +#endif /* * OHCI info structure. */ struct fwohci_txpkthdr { union { uint32_t ld[4]; struct { #if BYTE_ORDER == BIG_ENDIAN uint32_t spd:16, /* XXX include reserved field */ :8, tcode:4, :4; #else uint32_t :4, tcode:4, :8, spd:16; /* XXX include reserved fields */ #endif }common; struct { #if BYTE_ORDER == BIG_ENDIAN uint32_t :8, srcbus:1, :4, spd:3, tlrt:8, tcode:4, :4; #else uint32_t :4, tcode:4, tlrt:8, spd:3, :4, srcbus:1, :8; #endif BIT16x2(dst, ); } asycomm; struct { #if BYTE_ORDER == BIG_ENDIAN uint32_t :13, spd:3, chtag:8, tcode:4, sy:4; #else uint32_t sy:4, tcode:4, chtag:8, spd:3, :13; #endif BIT16x2(len, ); } stream; } mode; }; struct fwohci_trailer { #if BYTE_ORDER == BIG_ENDIAN uint32_t stat:16, time:16; #else uint32_t time:16, stat:16; #endif }; #define OHCI_CNTL_CYCSRC (0x1 << 22) #define OHCI_CNTL_CYCMTR (0x1 << 21) #define OHCI_CNTL_CYCTIMER (0x1 << 20) #define OHCI_CNTL_PHYPKT (0x1 << 10) #define OHCI_CNTL_SID (0x1 << 9) /* * defined in OHCI 1.1 * chapter 6.1 */ #define OHCI_INT_DMA_ATRQ (0x1 << 0) #define OHCI_INT_DMA_ATRS (0x1 << 1) #define OHCI_INT_DMA_ARRQ (0x1 << 2) #define OHCI_INT_DMA_ARRS (0x1 << 3) #define OHCI_INT_DMA_PRRQ (0x1 << 4) #define OHCI_INT_DMA_PRRS (0x1 << 5) #define OHCI_INT_DMA_IT (0x1 << 6) #define OHCI_INT_DMA_IR (0x1 << 7) #define OHCI_INT_PW_ERR (0x1 << 8) #define OHCI_INT_LR_ERR (0x1 << 9) #define OHCI_INT_PHY_SID (0x1 << 16) #define OHCI_INT_PHY_BUS_R (0x1 << 17) #define OHCI_INT_REG_FAIL (0x1 << 18) #define OHCI_INT_PHY_INT (0x1 << 19) #define OHCI_INT_CYC_START (0x1 << 20) #define OHCI_INT_CYC_64SECOND (0x1 << 21) #define OHCI_INT_CYC_LOST (0x1 << 22) #define OHCI_INT_CYC_ERR (0x1 << 23) #define OHCI_INT_ERR (0x1 << 24) #define OHCI_INT_CYC_LONG (0x1 << 25) #define OHCI_INT_PHY_REG (0x1 << 26) #define OHCI_INT_EN (0x1 << 31) #define IP_CHANNELS 0x0234 #define FWOHCI_MAXREC 2048 #define OHCI_ISORA 0x02 #define OHCI_ISORB 0x04 #define FWOHCITCODE_PHY 0xe Index: stable/11 =================================================================== --- stable/11 (revision 332155) +++ stable/11 (revision 332156) Property changes on: stable/11 ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /head:r330970,331067,331767,331852,331858