text:
Birch Fabrics
Cloud9 Fabrics
Cottage Industrialist
Daisy Janie
Harmony Art
ink & spindle
Swanky Swell
I think Umbrella Prints fabrics are fun, playful, contemporary, yet down-to-earth. They would all certainly fit in at my home.
Thanks! They look yummy, and clean, and colorful and wonderful!
I'm going to follow your blog as well!
FABULOUS!! Love the Elephants!!! :) Thanks for joining in the fun! Another new "follower" here!
vibrant, fun, funky and colorful. You have something for every personality, and to suit any decor. A great selection....
micaela6955 at msn dot com
I have loved your fabrics for AGES and your elephant is one my fave fabrics ever! I would describe your fabrics as modern, graphic and elegant, and best of all, Aussie made!
sharp, colorful, fun....unique!
Modern, Fresh, and Fun!
Your fabrics look intriguing, fun, and just plain lovely. I'll have to check them out in person so I can think of some better descriptive words. Found you via Betz White. Thanks for the chance.
Wow! What a lovely giveaway~ I think your fabrics are bright, bold, enticing, and pure delicious!
Thanks for the chance~
Umbrella Prints fabrics are simple and elegant with a surprising bit of levity. They are just my style!
jennifereladd at yahoo dot com
delicious, fun, vibrant and lovely. I want them all, I wish had the cash to buy them by the roll!
I would have to say - bold, modern, fresh. But I can go on and on....
Love your work - New follower. :)
first time i've seen umbrella prints and my first thoughts were gorgeous and unique. i love them.
Fun. Striking. Fresh. Modern. Bold.
The prints are so lovely! They are fresh, fun, and modern! Love them! Thanks for the giveaway!
Delicious, refreshing, soothing. Thanks for the great giveaway.
I love the whimsy touch in the prints. Especially the elephants!!
Contemporary designs with eye-catching color!
Thanks for entering me!
yummy, fresh, bold, fun, unique....love them!
I would describe your fabrics as fresh and fun, perfect for all your projects
Fun, fantastic, artsy, contemporary, just great!
Colors and patterns and texture, oh my!
i love the texture! it's beautiful and raw and real.
Great Designs - clean, modern, fabulous!
colourful, fun, funky, delicious, modern, and hopefully mine???? LOVE them. : )
I love this fabrics and follow & love your blog!!
your fabric is energetic and whimsical and yet earthy and of course, organic!
just my style!
They are fabrics that inspire creativity. I find them alive with color, energy and song.
Umbrella Prints Fabrics are fun, funky, modern, and give me so much inspiration!
Are all about gorgeous colour!
Love your elephants print, and earth day!!!
Wow--they look like they have great texture.
Love the linen-ish texture and the fun prints.
Fresh, bright, beautiufl colors, modern "down to earth"
modern, fun, and funky!
Bold colors, modern designs, and elegant & rich textures.
Thanks for the great giveaway!
Fun, fabulous, and beautiful.
I love the bold colors and the contemporary look of your fabrics.
modern, colorful and funky - I love them and the heavily textured fabrics are really pretty!
I-N-S-P-I-R-A-T-I-O-N-A-L! Walking to the beach to shell forage today and a beautiful warm autumn day in Pt. Lincoln, South Australia. What a better way to spend Earth Day. I would make a beautiful shoulder bag with these fabrics! Pam x
"Modern nature" is how I would describe them.
Fabric that adds style in an approachable way. I'm hooked.
Umbrella Prints fabrics are very colorful and fun! They're unique but gorgeous. They seem very modern, also bold. Energetic seems to fit too. (: I'll be following your blog as well, glad I found this giveaway! I found plenty of great blogs worth following!
All the adjectives have been used ... multiple times. Your fabrics are every one of them. They are fresh and yummy and fabulous and funky and unique and just plain beautiful.
Your fabrics are so lively and vibrant! I love the colors!
earthy, beautiful, vibrant, delightful. and darnit but those elephants are so cute! love these fabrics, thanks for the chance!
I'd say clean and fresh and smile-inducing! :)
Umbrella Prints are earthy and gorgeous and remind me of my year living in Kenya with the elephants and monkeys!
Umbrella fabrics are hip, edgy, fresh, modern, and fun. I love the fabrics' crispness and lightness. Perfect for summer!
All I know is that I would love to touch each and every one of them! They are really a fabric lover's dream come true! Thanks for sharing!
Sunshine watermelon and sprinklers! These fabrics remind me of lawn chairs and picnic blankets from my childhood, with their great texture and large fun patterns.
GUYS! I'm so glad to have found you through this comp. I think your designs look clean, fresh with a slightly nordic come retro feel. TOTALLY.
Your fabrics have a homemade, home spun look to them. Very comfy! Love them all!
Your fabrics are fresh and original! Thanks for the chance to win. And Happy Earth Day!!
earthy, bright, colorful, organic, new spin on nature, modern but classic, lovely with a sense of humor.
Thank you for the chance to win such a generous giveaway! Your prints are absolutely beautiful. The word that comes to mind immediately when I look at your fabric is CHEERFUL! They just make me happy!
great colours, simple but interesting designs which leave so many options for their use. love them.
So glad I found you! These look fresh and yummy! Elephants? Too fun!! So many ideas are swirling in my head now of what to make. Hope I win some!
Beautiful- count me in please!
FRESH! Thanks for the giveaway!
Wow..Umbrella Prints fabrics jumped out at me in that montage. Fresh, beautifully coloured and fantastic texture.
And no doubt even better in real life!
Fresh, bright, clean, modern, whimsical. I like how many of the patterns are scrolling and expansive.
Umbrella Prints are so unique, fun, beautiful,colorful and organic.
yum! they are all so deliciously bold!
Fresh vintage.Not my grandma's retro!
Bright, bold, and fun!
These fabrics look homespun with delightful muted colours. Beautiful!
Bright, beautiful and modern!!
Happy Earth Day!
Umbrella prints are just screaming to me: new bed accessories!
Bright and soft and wonderful :)
Graphic, earthy, and well-balanced, with a lot of fun thrown in.
Modern, natural and funky.
bright, exciting but not overly busy. Also, responsible!
I think "fresh" when I see that splash of orange, and also a bit "earthy" when I see more of the earth-tones. Great prints!
Umbrella prints are vibrant and bold but soothing, almost whimsical (but certainly not silly), with clean lines and fresh designs.
Texture is the first word that jumps out. Both in pattern and actual material. Also graphic. So modern and fresh.
sophisticated whimsy!
beadsinthebelfry at gmail dot com
i would say natural earth and vibrent at the same time very calm and clean jfleuriel(at)coa(dot)com
Bold, Modern, in the Bloomsbury sense, positively edible!
I think they are fun and creative, very modern too.
Umbrella Prints have the three C's they are colorful, clean, and contemporary love them!
I find your fabric collection really creative, modern and super fun! :)
Umbrella Prints have the three C's they are colorful, clean, and contemporary love them!
They are very earthy in colours and texture! How fitting for earth day :)
Interesting and unique - love the how the texture and the design work together!
I'm so glad that I've discovered you. These fabrics are wonderful.
Umbrella prints are bold, organic and fresh.
Beautiful and modern!
Umbrella prints are fun, funky and fabulous. Happy Earth Day!
I think Umbrella Prints look modern and bold and mature.
I think Umbrella Prints are fantastic, modern, fun & funky, full of texture, organic, YUMMY & DELICIOUS!!! :D
Always love your colours, so fresh, bright, contemporary!!
Umbrella prints fabrics are textured, warm, inviting bundles of comfort!
A rich mixture of joy and modernity.
Graphic and bold, yet sweet and charming! Thanks for the giveaway!
Umbrella prints are like having a rainbow of sunshine in your life.
fun,unique and fabulous!!
Unbrella prints are bold and fun and unusual to boot!
Umbrella Prints are fantastic fabrics that will make every project a joy to complete and they are Earth Friendly!
Fresh, simple and colorful!
I love them!
Umbrella Prints is: an absolute pleasure-to work with, to look at, to support!
Ooooooooooo I would love these so much!
bohemian chic.
Umbrella prints are bold, colorful and fun!
They have a vintage feeling to them, like the best of old times, but in a fresh new version. I really like them!
Looking at Umbrella Prints fabrics, which I've just discovered thanks ( to Daisy Janie, feels a lot like being tickled behind the ear (where creative inspiration lives) with a peacock feather :D
Just WOW!
umbrella prints fabrics es.. diversion- color- actual- original- y ecologico!!
me encantan sus diseños!
ojala tenga suerte!
rocio de cordoba argentina
innocent, but sophisticated. does that make any sense? i´ve had the bird in paradise in my favorites list on etsy for so long. amazing!
These fabrics look so yummy! They're natural, colourful, fun, playful and also inspirational :)
Happy Earth Day! And thanks for the chance to participate!!!
Fresh, cute, funky, organic - I love them!
i would have to say contemporary, & always in such beautiful colour shades
I love the texture of the umbrella prints, the patterns give me a sense of calm and freshness. They remind me of my childhood. Happy earth day to all!
Fun cute textured organic fabric that can't wait to be used in a million ways!
stasigh at gmail dot com
Umbrella fabrics are colourful and vibrant yet with that clean touch that is so hard to get.
Uh, so happy to have found you - this fabric is just so special!
Natural luxury! Casual and chick. Modern retro - and YUMMY colours :)
Thanks for the generous give-away! Umbrella Print: colourful, funky and fun. Happy Earth Day to you!
That is the best word for me, totally can not believe that you have remained undiscovered to me for so long {until now}. What a natural, playful, friendly range of fabrics that you offer.
Umbrella prints are vibrant, bright, bold and fun!
I love the elephants!
I would descrive it as... warm, colorful, with a little neo-retro twist. Does that make sense? Thanks for the great giveaway (a good occasion to discover new favorite etsy shop, too :)).
Happy Earth Day to you,
Happy Earth Day to you,
Happy Earth Day dear planet,
Happy Earth Day to you!
Your fabrics look natural, textured, funky and fun! Lovely!
Clean, modern, fresh, yet welcoming, cute and cozy. Which is to say, perfect. I just discovered you, and have to say I can't think of anything I wouldn't want to make in your fabrics. Thanks!
They are a tangible happiness!
a bundle of deliciousness.
I would love to just look at them for a while as I imagine the many wonders I could make them into. Probably a modern quilt to show off the wonderful prints and colours - I'd have to keep it cos I'd never want to give it away!
Such lovely fabrics, like the backyards of the world.
They are colorful and so nice.
I would love to be able to describe the drape, which I'm guessing is pretty terrific just from what I'm seeing. The colors and texture make me thinking "relaxing".
They are fun, colorful, bright and adorable!
Thanks for the chance.
eli_green22 at yahoo dot com dot br
Umbrella prints are soft in color and print, yet eye catching. They look like a perfect linen for napkins or a table cloth. The pattern is simple, perfectly simple, yet unique, perfectly unique.
Umbrella Prints are soft, full of texture and harken back to my grandmothers house. Umbrella Prints are all good things.
umbrella prints are graphically detailed with a timeless whimsy. they're really delightful! thanks!
I love love love your prints! I think they are the right amount of earthy, edgy and sweet.
Hmm,very Aussie - colourful, quirky, somewhat relaxed and a bit cheeky - love them!
Umbrella Prints Fabrics are earthy, textural, Bright, Happy and Unique. Love them!
Earthy Retro with a smile! Happy Earth Day!!
Umbrella Prints are full of fun and not icky stuff!
Contemporary colors and patterns, all rich in texture.
These umbrella prints remind me of summer and the beach. They are really nice!
Earthy. Fun. Happy!
I would love to win, they are gorgeous! Thanks much for the freebie and for going organic for the earth! LOVE THE PRINTS!
Umbrella prints remind me of fruit on ice cream, spring, and color palettes in beautiful photos from gorgeous home mags. Umbrella Prints make me long to create, so wonderful!
Thank you for the opportunity to tell you how great I think they are! (and the opportunity to win some?!!)
UP are fresh and unique, some with a seemingly stencil-like quality of a piece of art!
i love this idea! also your modular kits are great!
its already been said but in one word....FRESH.... thats what comes to mind.
Pinkalicious! I like the blues and greens, too--but the pink makes me so happy!
Definitely modern and fresh! I love the bright colors along side the natural tan color, beautiful!
The beauty of the thread shines through the ink - they look like they were meant for each other.
clean and cheerful! far from drab
distinctive. fun. cheerful. original.
I would describe your fabric as down to earth! I love them!!!!!!!
Thanks so much for the chance to win!
Funky Fresh! Love the fabrics.
Definitely fun.
Fresh, youthful and relaxing. There is something calming about them. Thanks for the giveaway!
oh my, I've been admiring your fabrics for some time now - I'm dying to make a quilt out of them!! They're fun, playful, modern and best of all... distinctive! Love them!
Thanks for the great giveaway (fingers crossed!!)
Playfully earthy!
Modern and Fun! Thanks for taking part in such an amazing giveaway. Happy Earth Day!!!
Everytime I look at your prints and colours, they remind me so much of my lovely lovely holiday in Australia. The colours and the unique play of prints - that's Australia to me.
Whimsical, yet sophisticated.
I love them all!
fun, imaginative, colorful, fresh...all around beautiful and inspiring fabric.
The fabrics are all in earth colours, and the designs remind me of Art Deco and Art Nouveau designs, all swirly and flowing, definitely worthy of the label "organic".
Umbrella Prints fabrics are colorful and unique. Thanks for the chance!
umbrella prints are beyond awesome! Colorful, fun & modern. love them!
Whimsical and modern, yet with a touch of nostalgia. Lovely!
These look like linen, yummy!
The first word that comes to mind when I look at the gorgeous colors and the weave of the fabric is: natural. It has a relaxed, natural look that just makes me want to touch it. :)
beautiful visual texture! clean, they make me feel special just looking at them!
Fun Colorful and bold. Great giveaway. Thanks for the chance to win.
Thanks for this opportunity!! I love all Umbrella Prints fabrics cause are fun, playful, colorful and vibrant. Like me :D
i have been a fan of umbrella prints for some time. they are spunky, modern, ecologically responsible, and desirable! thanks for the opportunity!
they are really vibrant and funky - I love them
Funky & interesting! I love different prints and they are so cool!
Modern, fun and colorful!
beautiful, bright, comfortable
Vibrant, fun, colorful, and natural.
Umbrella Print Fabrics are beautiful, unique, vibrant...
Vibrant, organic pieces of artwork designed to beautifully enhance our everyday lives...
Fresh, modern, FUN
Ooh! They are so raw and rich, earthy, luscious and fun!!
I love these prints! They are very modern, but earthy. I love the texture. So glad I found your blog!
Awesomely graphic, classic and bold with the right touch of whimsy.
Whimsical, yet earthy. Love them all!
i've been a fan of vintage printed linens from the 1940s-60s, and your prints remind me of these...with a modern spin, ofc. They're lovely and unusual.
Earthy is the first word that came to my mind.
I'd call them bold, edgy & fun! Love them
Unique and inspiring. They also look like they would feel wonderful on the skin!
Vibrant, fun, warm, inviting and full of crafting possibilities!
Fun and kind of rustic, with lots of great colors.
eco-chic and delish! i want!
Modern graphic with a bit of retro touch!
vibrant, natural and cute, with a dash of sass!
Casual, friendly and cheerful!
Natural - part of nature! Great fabrics!!!
Modern, playful, responsible.
craftytofu at yahoo
Umbrella Prints fabric is...exactly what I have been looking for! Each fabric is so bright and graphic. Any of the prints would work in my house.
yr fabrics make me want to TOUCH them. texture, ahhh.
I think Umbrella prints are gorgeous fabrics with an organic sensibility (in a design sense as well as ecological). I bought the kit to make the flip dolls some time ago and I saved every little precious scrap (which I later used to make my daughter potholders for her play kitchen).
Graphic, bold, colorful, AMAZING!!!!
The hand drawn feel of these fabrics is incredible, really special. And what a great palate! Happy Earth Day!
Fresh and cheerful. A way of brightening up my day!
graphic! love them all :]
I love your fabrics, they are down-to-earth yet modern and colorful.
I describe umbrella fabrics is happy, cheerful, and spring. They are so very fun!


text:
BERLIN- Stephen Decatur's boys' varsity soccer team won its first Bayside Conference championship in a decade this week, blanking Kent Island, 2-0, on Monday in the title game at Washington College.
Last week, the Seahawks had their hopes of a perfect season dashed when they fell to Bennett, 2-1, in the regular season finale. The anguish was short-lived, however, as the Seahawks had already wrapped up the Bayside South title and a trip to the conference championship game.
On Monday, Decatur got on the board early when Sunny Aroh scored with just 10 minutes into the game on an unsettled situation in front of the Buccaneers' net after a throw-in. The score remained 1-0 throughout the rest of the first half although the Seahawks continued to apply pressure on the offensive end.
With just under 20 minutes left in the game, Decatur's Erik Geiser got the Seahawks back on the scoreboard when he took a pass from Jason Stitely and got through a line of Kent Island defenders before firing a shot to the far post from the perimeter. Geiser's goal gave Decatur a 2-0 lead, which is all the Seahawks would need to finish off the Buccaneers for the conference title.
The Bayside championship was the first for the Seahawks since 2002. That team went on to win the state championship, a feat the 2011 team hopes to match this year. The Seahawks earned a number-one seed in the Class 3A-East tournament when the brackets were announced this week.

subset: commoncrawl


text:
Internals of NDIS driver for VirtIO based network adapter
Internals of NDIS driver for VIRTIO based network adapter
This document contains implementation notes of Windows network adapter driver of VirtIO network device.
Abbreviations in the document
- LSO, a.k.a. GSO, a.k.a. TSO – Large, Global, Transmit segment offload – the same thing in context of Windows driver.
- OOB – out-of-band packet data; set of structures, associated with packet
- SG – scatter-gather
- MTU – maximal transfer unit
- MSS – maximal segment size
- CS – checksum
- MDL – memory descriptor list
- WL – waiting list
- DUT – device under test
NDIS driver features
Basic networking operations
The NetKVM driver supports non-serialized data sending and receiving. Multiple send operations are supported by driver and not required to be serialized by NDIS (Logo requirements). For send operation scatter-gather mode is a default, it can be disabled by configuration to force copy mode to preallocated buffers. In receive operations the driver can indicate up to NDIS as many packets as VirtIO device can receive without waiting for NDIS to free receive buffers. The default MTU reported by driver to NDIS is 1514 bytes, i.e. NDIS sends without LSO packets up to MTU, the driver can not indicate reception of packets bigger than MTU. MTU can be changed through the device properties in device manager. For bidirectional data channel to/from device, the driver initializes 2 VirtIO queues (transmit and receive). VirtIO queues contain memory blocks for SG entry only (physical address + size), all the data buffers, where the physical address points to, are not related to VirtIO. Buffers, required for VirtIO headers and network data (when necessary) and OS-specific object, required for data indication, are allocated by the driver additionally during initialization.
Checksum offload
NDIS driver can declare following types of TX checksum offload
- IP checksum. NDIS does not initialize IP header checksum, device/driver fill it.
- TCP checksum. NDIS initializes TCP header checksum with "pseudo header checksum" value (pseudo header does not exist in the packet, checksum calculated on virtual structure), the device/driver finish it
- Support IP options and TCP options when calculating checksum.
- UDP checksum – exactly as TCP without options.
- IP and TCP checksum for IPV6.
NDIS driver may implement also support of RX checksum offload (ability to verify IP/TCP checksum in incoming packets) – this feature is not supported in NetKVM. The NetKVM driver has implementation of all the CS offloads for IPV4, it works functionally. It is very helpful during development and diagnostic; some of these mechanisms used for LSO also. But the implementation does not pass corner cases of NDIS tests and disabled in the configuration by default.
Large segment offload
In LSO operation the NDIS provides packet that usually (not always) bigger than MTU; driver/device shall divide it into several smaller fragments before sending to other side. Each fragment, except of last one must contain MSS bytes of TCP data. During fragmentation, the device shall properly populate IP and TCP headers including IP and most of TCP options and fill all the necessary checksums. The NetKVM driver implements LSO offload for IPV4 with maximal packet size of almost 64K before offloading. Note that at least in current implementation the LSO requires scatter-gather for operation, as packets bigger than MTU can not be placed into pre-allocated buffers.
Priority and VLAN tagging
The NetKVM driver on its lower edge supports both Regular Ethernet header of 14 bytes and Ethernet type II header of 18 bytes. The second one includes Priority/VLAN tag (32 bits) with 16-bit field of Priority and VLAN. Ethernet type II header can not be indicated up to NDIS; NDIS also does not provide this tag in outgoing packets. Instead Priority and VLAN data reside in OOB block of NDIS packet(s) and populating this tag in outgoing packets is the responsibility of the driver. It is responsible also for removal of this tag from incoming packets (if present) and place Priority data into OOB block. The driver also checks the VLAN value and ignores incoming packets addressed to VLAN different than one configured for the specific instance of the driver.
Connect detection
Typically, the VirtIO network device driver always indicates connection to the network. During manual WHQL tests the test operator is required to remove the network cable from the socket. The VirtIO network device implementation in QEMU indicates up to the driver connection status, which allows the driver to indicate up to NDIS connect/disconnect events. When disconnected, the driver suspends its send operation and fails to send packets.
Filtering of incoming packets
Filtering is required feature of network adapter under Windows. The NetKVM driver maintains NDIS-managed filter mask, controlling which packets the driver shall indicate and which shall drop. This filter can allow one or more of:
- Unicast packets (to device own MAC address)
- Multicast packets (to one of multicast addresses configured from NDIS)
- All multicast packets (to any multicast addresses)
- Broadcast packets
- All packets
For each incoming packet the driver analyses the destination MAC address and takes decision based on current filter mask. The buffer of the packet is available – it is one of buffers allocated by the driver during initialization.
NDIS miniport required to support statistics for send and receive operations: number of successfully/unsuccessfully send/received bytes/packets per kind of packet (unicast, multicast, broadcast). Main consumer of this statistic information is NDIS test.
Sources files
Common files
Files under Common | Functionality |
ndis56common.h ethernetutils.h |
All the common mechanisms and flow: system-independent initialization and cleanup, receive and transmit processing, interactions with VirtIO library |
ParaNdis-Oid.c | Implementation of system-independent part of OID requests |
kdebugprint.h |
Debug printouts implementation |
sw-offload.c | All the procedures related to IP packets parsing and checksum calculation using software |
osdep.h | Common header for VirtIO |
IONetDescriptor.h | VirtIO header definition – must be aligned with one used by device (QEMU) |
quverp.h | Header used for resource generation (visible on file properties) |
NDIS5-specific files
Files under WXP | Functionality |
ParaNdis5-Driver.c | Implementation of NDIS5 driver part |
ParaNdis5.h |
NDIS5-specific implementation of procedure required by common part |
ParaNdis5-Oid.c | NDIS5-specific implementation of OID |
netkvm.inf | INF file for XP/2003 |
NDIS6-specific files
Files under WLH | Functionality |
ParaNdis6-Driver.c | Implementation of NDIS5 driver part |
ParaNdis6.h |
NDIS6-specific implementation of procedure required by common part |
ParaNdis6-Oid.c | NDIS6-specific implementation of OID |
netkvm.inf | INF file for Vista/2008 |
Flows and operation
Configurable parameters
Upon initialization the driver retrieves configurable parameters from the adapter registry setting. It checks for each one of parameters the validity of retrieved value (for that the driver contains for each parameter default value, minimal and maximal value) and initializes the adapter according to this configuration. The goal of validity check is preventing of unexpected behavior of the driver during NDIS tests, where the test procedure writes registry with random and invalid values and then starts the adapter (the driver can fail initialization, but can not cause crashes or stop responding). See "List of configurable parameters" below for complete list.
Initialization of the driver and device instance
Driver initialization always starts from system-dependent implementation of DriverEntry procedure. In it the driver registers set of callback procedures to implement per-adapter operation
- initialization
- packets sending
- returning of received packets
- OID support
- pausing and resuming (for NDIS6)
- restart
- halting
This initialization happens only once. For each PCI device created by QEMU, the registered initialization procedure is called to allocate and prepare per-device context in the driver. There is no dependency between different devices, supported by the same driver; they do not have any common resources. Upon adapter initialization, the system-dependent procedure
- Allocates storage for device context
- Does minimal registration of the device instance (just to allow further access to configuration interface and hardware resources)
- Retrieves configurable parameters
- Uses allocated hardware resources (IO ports) to access the device and retrieve its features (host features) and MAC address, configured by QEMU command-line (can be overwritten by NDIS)
- Initializes the device context according to retrieved configuration and device features
- Allocates and initializes VirtIO library objects
- Allocates and initializes pre-allocated descriptors, data blocks and binds necessary system-dependent objects to them (according to configurable parameters and device capabilities and features)
- Enables necessary features in the device (guest features)
- Enables the interrupt streaming from the device (using interface with device)
Some mechanisms required by driver during initialization have different implementation for NDIS5 and NDIS6:
- Virtual memory allocation
- Obtaining configuration handle to retrieve configurable parameters
- Physical memory allocation and deallocation
- Allocation and freeing of NDIS object to indicate received data
- Configuring of interrupt handler and handler of DPC procedure
- Registering of DMA capabilities (to be able receiving hardware addresses of transmitted buffers)
Initialization process combines system-independent and system-dependent code in order to minimize code duplication and use system-dependent code only when required. NDIS6 driver has advanced initialization process, including report of initial settings (under NDIS5 the NDIS needs to query many driver parameters via OID requests immediately after initialization).
Initialization and clean up of VIRTIO object
Upon initialization, the driver creates two queue objects in VirtIO library – one for RX, one for TX. The VirtIO library retrieves available number of blocks from the device and allocates storage for required number of blocks. These two objects used for all the functional operation after startup. TODO: VirtIO library in its internal code uses non-NDIS calls for allocation of physical memory and translation between physical and virtual addresses. In general, these calls are illegal, but currently the WHQL procedure that verifies calls made from NDIS driver, does not produce error on that. Upon device shutdown (disable or remove) operation, the driver deletes these objects using VirtIO library call. Special case is driver support for power management events (see in "Power management").
Guest-Host negotiable parameters
Host features do not receive any acknowledge from guest when they do not affect driver-to-device interface. Support for mergeable buffer does, so it is activated only when the driver enables the same feature in guest features set (using PCI part of VirtIO library interface).
Feature | Mask in HOST features | Mask in GUEST features |
Checksum calculation by device | VIRTIO_NET_F_CSUM | Not required |
LSO support by device | VIRTIO_NET_F_GUEST_TSO4 | Not required |
Mergeable RX buffers | VIRTIO_NET_F_MRG_RXBUF | VIRTIO_NET_F_MRG_RXBUF |
Generation of connect / disconnect events | VIRTIO_NET_F_STATUS | No required |
Interrupt processing
System-dependent procedure of interrupt handling pass control to common interrupt handling procedure and reads the interrupt status bit mask from VirtIO device (read operation clears the status in the device): currently there are two bits of status, when bit 1 indicates connect detection and bit 0 indicates any other VirtIO event (ability to read data from TX queue or freed buffers in TX queue). Common interrupt handling procedure serves two main tasks: sending and receiving, by call to system-dependent implementation of ParaNdis_ProcessTx and common procedure ParaNdis_ProcessRxPath.
Sending data
Initialization of transmit path
For send operation, the driver pre-allocates following resources:
- Descriptors for TX blocks, suitable for linked list. Initial number of TX descriptors is defined in configuration and cut down if related VirtIO queue may accommodate less blocks than configured.
- Buffer in physical memory for VirtIO header for each descriptor
- Buffer in physical memory of (MTU + 4) bytes for each descriptor. This buffer able to accommodate packet, transmitted by copy with possible population of priority tag
Each TX transaction with VirtIO requires at least 2 physical blocks: header of 10 bytes (12 when using mergeable buffers) and one or more data blocks. So, if TX queue of VirtIO has capacity 256 blocks, the driver prepares 128 descriptors with two attached memory blocks each. The driver sets the limit of hardware blocks it has to 256. The data block attached to descriptor may be used or not used for each specific transaction. The VirtIO header is always in use.
Configurable parameters, related to transmit path:
- Number of buffers to use. Can be set less than half or VirtIO capacity. If set to more, will be cut.
- Using of scatter-gather
- Checksum offload support
- LSO offload support; if SG not set – ignored
There are also OS-manageable parameters for LSO and checksum offload (at least testing software verifies their functionality – they are used in NDIS6). Their names start from "*" and they can be used to set initial state of offload features upon driver startup.
Common principles
The driver receives packets for sending on its standard NDIS procedure, dependent on NDIS version. Upon call from NDIS for packet sending this procedure is responsible for:
- allocate and initialize per-packet send entry with preliminary check of ability to deal with packet
- ensure the packet has its physical buffers ready (automatically happens in NDIS5 only)
- queue packet (or send entry) into internal list
- call main body to process the list
Upon interrupt from VirtIO device the activated DPC procedure
- calls main body to process the list
Main body procedure:
- calls common procedure to retrieves from VirtIO device previously submitted blocks which may be already transmitted
- if some buffers are released by VirtIO device, they are prepared for further completion
- processes the list of packets to send
- prepares transfer parameters for current packet
- how many physical buffer the packet contains
- length of the data
- offload requirements (checksum, LSO)
- priority tagging
- calls common mechanism for packet submission while it is possible
- packet may be submitted
- packet may be failed
- packet may be delayed if we can send it but now currently (no room)
- packets successfully submitted may be moved to waiting list for further completion
- failed packets may be moved to waiting list for further completion
- break from sending loop when there is no room for sending
- process waiting list, complete finished packets, free system resources related to the operation
There are two possible paths of data transmission: using copying to preallocated buffers from packet data in virtual memory and using immediate hardware addresses (SG table) provided per packet by the system. For very short packets which require padding to minimal size, the driver must use copy. It also uses copy operation, when configured to run without SG support or when it supports software version of TCP or IP checksum offload and it is required for specific packet. For other packets it uses SG table, including those where LSO required; in this last case the driver receives packets with wrong IP checksum and it must set it properly before pass it to the device. When the packet is transmitted using SG table but priority/VLAN tags are to be inserted or IP checksum shall be fixed, the driver partially replaces the data in the outgoing packet with modified copy of the data in preallocated data buffer (the original packet is not touched, of course). Depending on which physical buffers included in the packet, the driver may ignore one or more packet's hardware buffers fully or partially. Instead of submitting original buffers from the packet, the driver copies required starting part of the data from the packet to own buffer (attached to VirtIO descriptor), makes all the required modifications in it and submits to VirtIO array of buffers starting from its own buffer (see ParaNdis_PacketMapper and ParaNdis_PacketCopier).
In order to decide whether the packet can be transmitted now or must wait for room, the driver needs to know:
- is there one available descriptor (for one or more buffers to transmit)
- how many available hardware buffers we have in VirtIO for SG elements
- how many hardware buffers will require packet we currently transmit
During the operation of packet mapping before transfer, the driver calculates number of physical buffers required to transmit the packet. For copy operation this number is two (VirtIO device header and preallocated buffer for data payload).
For SG operation, before it processes the packet, the driver makes worst case estimation of required number of hardware buffers as number of hardware fragments in packet + one always (for VirtIO header) + one conditional (for case priority tag shall be populated or LSO required and IP header must be fixed).
When in case of copy operation the driver could report the completion of send operation immediately, it is impossible when it uses SG with system-owned physical buffers. The driver takes decision how to transfer this specific packet on per-packet basis, so it uses common completion scheme: the packet reported as completed when VirtIO returns buffers, submitted for this packet.
This also ensures the order of packets completion to NDIS is the same as order they were sent (NDIS5 is sensitive to it). The opaque data value, provided to VirtIO library upon add_buf operation and returned upon get_buf operation is a pointer to per-packet send entry, allocated by driver and containing all the information required to complete the packet and free the resources allocated for it. Structure of this entry differs between NDIS5 and NDIS6 implementations.
The driver always keeps the number or available hardware buffers in VirtIO, decrementing it on each successful add_buf operation and incrementing it on each successful get_buf operation using the number of hardware buffers kept in per-packet send entry.
All the members of adapter context structure related to sending path are protected by Send Lock. All the functional calls to upstream Send Queue of VirtIO library (get_buf, add_buf, kick) must be protected by the same lock object. Note that TX packets completion must be executed without holding spinlocks in both NDIS5 and NDIS6 (the reason is that completion when holding spinlock may cause deadlock, for ex., if NDIS will immediately call send operation). See also Synchronization.
Related procedures:
File | Procedure | Responsibility | |
1 | ParaNdis-Common.c | ParaNdis_DoSubmitPacket | Decide which mechanism to use for sending.
Call 2 or 5 to prepare the data. Call add_buf to submit. Return final status of operation |
2 | ParaNdis_DoCopyPacketData | Obtain descriptor and buffer for data copy, call 6 to copy data | |
3 | ParaNdis_VirtIONetReleaseTransmitBuffers | Call get_buf to retrieve data. Return available descriptor to the pool. Track number of available descriptor and buffers. Call 7 to do packet dependent operations | |
Implementation (NDIS version dependent) | |||
4 | ParaNdisX-Impl.c | ParaNdis_ProcessTx | Main body.
Process packets list, call 1 to submit, finish processing depending on result |
5 | ParaNdis_PacketMapper | Process packet and create final list of SG elements. If required, replace it partially using mechanism in 6.
Make all the preparations for LSO. | |
6 | ParaNdis_PacketCopier | Process packet and copy data to provided buffer. If needed, populate priority tag. | |
7 | ParaNdis_OnTransmitBufferReleased | Label packet as ready for further completion. |
NDIS miniport is required to support statistics for send operations: number of successfully/unsuccessfully sent bytes/packets per kind of packet (unicast, multicast and broadcast), i.e. in any case the driver needs to preview the packet's header. The same ParaNdis_PacketCopier procedure does the job to copy only Ethernet header out of packet for preview.
Sending data in NDIS5 scheme
The driver receives array of NDIS_PACKET structures, each of them describes single packet to be sent. Each NDIS_PACKET contains chain of NDIS_BUFFER structures, describing packet's fragments in virtual memory. Each of these fragments may contain more than one part in physical memory.
It traverses the chain of NDIS_BUFFER structures in order to access their data for copying in ParaNdis_PacketCopier.
The driver obtains per-packet information from packet's OOB block
- SG list of fragments in physical memory (in ParaNdis_PacketMapper)
- Priority tagging requirements
- Offload requirements for LSO (TcpLargeSendPacketInfo)
- Offload requirements for checksum (TcpIpChecksumPacketInfo)
On entry to "Send" procedure the driver allocates Send Entry (tSendEntry structure) for each packet and in further processing maintains Send Queue and its WL as lists of Send Entries.
When the packet processed by ParaNdis_DoSubmitPacket, the packets, that are not delayed, moved to WL. Failed packets are labeled as if they transmit buffer was released. WL is processed on each exit from main TX procedure; finished packets are completed, attached resources (send entry) freed.
Sending data in NDIS6 scheme
The driver receives list of NET_BUFFER_LIST structures; each NET_BUFFER_LIST contains chain of NET_BUFFER structures, when each NET_BUFFER represents packet. Each NET_BUFFER contains list of MDL structures, when each MDL is list of fragments in virtual memory.
The driver shall report completion using list of same NET_BUFFER_LIST structures, although it can group them as it wants, keeping the data and set of NET_BUFFER untouched. The status is also reported per NET_BUFFER_LIST, OOB data is also bound to it. Sending packets, the driver needs to track completion of packets and complete the NET_BUFFER_LIST when the last packed from it is finished.
Due to this reason the driver allocates one structure (tNetBufferListEntry) per NET_BUFFER_LIST and one structure (tNetBufferEntry, starting from list entry) per buffer. The Send Queue contains NET_BUFFER_LIST elements, when each tNetBufferListEntry includes list of its tNetBufferEntry elements.
Unlike NDIS5, in NDIS6 the packet initially does not disclose its hardware addresses. In order to know them, the driver must initiate mapping operation per packet and only in callback procedure it receives SG list of the packet. The mapping request (NdisMAllocateNetBufferSGList) must be issued on DPC level and the callback may be called synchronously or asynchronously. In the last case, the order on which the callback is called for different packets in not guaranteed, at least this is not documented. Thus, the driver hardly can start processing of NET_BUFFER_LIST until all the packets from it are mapped.
ParaNdis6_Send procedure received the list of NET_BUFFER_LIST and
- For each NET_BUFFER_LIST allocates tNetBufferListEntry and initialize in it all the list-wide parameters
- Writes tNetBufferListEntry into Scratch field of NET_BUFFER_LIST
- For each NET_BUFFER in the NET_BUFFER_LIST allocates tNetBufferEntry
- tNetBufferListEntry contains linked list of its tNetBufferEntry structures
- each tNetBufferEntry keeps pointer to its NET_BUFFER_LIST
- for each tNetBufferEntry request mapping
- if mapping fails for one or more of tNetBufferEntry, call callback directly with empty set of addresses
Upon callback with hardware addresses available
- keep addresses in tNetBufferEntry (later we need to free them)
- increment number of mapped buffers belong parent tNetBufferListEntry
- when all the buffers are mapped
- insert parent NET_BUFFER_LIST into Send Queue
- start main body of TX operation (ParaNdis_ProcessTx)
Inside main body of TX operation the driver peeks the packet list at the head of the Send Queue, retrieves from it next packet to send and tries to submit it.
If the packet successfully submitted (as described in common part), the non-empty tNetBufferListEntry is processed again, empty tNetBufferListEntry moved to WL. If the packet is failed, the packet completion procedure is called immediately.
When the packet is completed by VirtIO (or failed), the packet completion procedure labels it as finished and increments number of finished packets in tNetBufferListEntry and frees resources associated with specific tNetBufferEntry.
The main body of TX exits its loop when all the packets are submitted or when the next packet is delayed (no VirtIO buffers for it). Then the procedure checks its WL and completes each NET_BUFFER_LIST in it who have all their packets completed.
Canceling packets in process
NDIS may request canceling of packets in process, providing Cancel ID, which is saved in OOB block.
For NDIS5, this is ID of the packet and it is simple to find it in Send Queue and complete.
For NDIS6, this is ID of NET_BUFFER_LIST which may have some of its packets in process. So, if the NET_BUFFER_LIST is not started yet, it will be completed; if it is in process, it will not be cancelled.
Checksum offload
The NetKVM driver includes implementation of all the TX CS offloads for IPV4 (IP + options, TCP + options, UDP) and it works functionally. CS offload can work with SW emulation and can use host support (when host declares on host features bit mask that it is able to do it, setting VIRTIO_NET_F_CSUM).
It is very helpful during development and diagnostic; some of these mechanisms used for LSO also.
There are 3 problems:
- IP and TCP or IP and UDP can be enabled together when hardware CS used. VirtIO header is TCP checksum oriented. Possible it can do IP CS, but not together with TCP.
- The implementation does not pass corner cases of NDIS test: the test sends packets with invalid IP checksum and invalid TCP checksum, the driver required in OOB NOT to fix the CS, the test expects to receive identical packets on the second side, the host does not deliver them
- There is no performance improvement due to CS support.
The checksum offload is controlled by configuration and disabled by default. Implementation of SW emulation is in sw-offload.c.
All the procedures work with data block starting from the beginning of IP header. First of all they parse header (at least IP + good to have basic header of TCP) to understand the kind of packet and save result of parting in tTcpIpPacketParsingResult structure (actually 32-bit bit mask).
Then, when possible and requested, procedures verify and/or calculate required type of checksum. The exact required modification or verification of checksum is set on parameter bit mask for procedure.
See following procedures:
- ParaNdis_CheckSumCalculate (parses and calculates)
- ParaNdis_CheckSumVerify (parses, calculates and modifies or leaves as is)
- ParaNdis_ReviewIPPacket (parses only)
The driver always receives the offset of IP header in OID parameters when the NDIS configures the miniport for offload task. Currently we declare support only for one encapsulation (802.3) and the offset is always 14 bytes.
Note that the packet data must be in contiguous buffer in virtual space in order to process the packet data. As the traversal of all the data blocks in the packet is already implemented in ParaNdis_PacketCopier procedures, it is used by any procedure also for getting of starting part of the packet for preview.
Large TCP segments offload
The NetKVM driver implements LSO for IPV4 only. This feature depends on host ability, indicated by VIRTIO_NET_F_HOST_TSO4. When NDIS sends packets with request for LSO in OOB it does not set TCP and IP checksums.
There is one issue with the LSO at the moment:
- If the driver does not fix the IP checksum in LSO packet, the host does not deliver packets
The driver sets limit of block size that can be submitted to 0xF000. NDIS during tests uses different sizes of packet and sets the MSS value to different values from 536 bytes; sometimes the host generates splash of more than 100 packets, so the test may fail if some other traffic present on the tap.
In functional environment, the system usually sets MSS to maximal possible value (1460 if IP and TCP are without options).
The LSO mechanism uses the same IP header offset value as checksum offload; it is set by NDIS when it enables any of offload capabilities. Additionally, in NDIS6 the driver receives (for each NET_BUFFER_LIST) the offset of TCP header in the outgoing packet.
When using LSO, the driver shall calculate and write into OOB (TcpLargeSendPacketInfo) the summary length of all the transmitted packets. It is not documented how exactly the driver shall calculate this value, only a criterion is that NDIS tests pass; the driver calculates these numbers differently for NDIS5 and NDIS6.
Priority and VLAN tagging
Priority and VLAN information are combined in the same tag and the functionality of Priority verified under NDIS test (verified using VirtIO adapter in pair with VirtIO and also in pair with e1000 adapter).
In general, selected VLAN to operate shall be provided by operation system on the configuration setting of the driver, the driver needs to populate this value in the outgoing tag.
However, VLAN functionality does not have any test case under NDIS test suite and currently not verified.
Corner cases
Small packets
One of requirement to network adapter (mentioned in Logo requirements) is padding of outgoing packets that have length less than 60 bytes with zeroes up to 60 bytes. Due to this requirement, the driver always use copy for such short packets and does the padding (in ParaNdis_PacketCopier).
Spurious data in packets
The driver must be careful parsing chain of fragments related to each packet provided for transmission. Each packet has declared length of the data; the buffers chain may continue after this valid area, following buffers are not-valid. The driver must ignore them and never touch.
In NDIS6 unused area may be present also before used data area; this unused area present in the packet's SG list received by driver, and it must check where the used data starts and take it in account preparing the packet for submission.
Effect of mergeable buffers
Support for mergeable RX buffers change the format of VirtIO header used when the driver communicates with VirtIO network device. This change affects also TX path; during initialization the driver allocates bigger area for VirtIO header.
Receiving data
Initialization of receive path
During initialization the driver creates VirtIO queue which is automatically sized according to size of the queue in the device. The driver must provide physical buffers to place the received data as well as the structure for tracking buffers (descriptors).
In order to be able to communicate with NDIS core and provide received packets, the driver must have a pool of NDIS objects for such indication.
- For NDIS5 the driver indicates array of NDIS_PACKET structures, each one may have one or more NDIS_BUFFER structures attached
- For NDIS6 the driver indicate one or more NET_BUFFER_LIST structures; each one has single NET_BUFFER structure attached (may have more than one); each NET_BUFFER contains one MDL describing buffer in virtual memory (may contain more than one MDL)
Thus, for any packet the driver receives, it needs to have contiguous buffer with known physical and virtual addresses and
- For NDIS5 – NDIS_PACKET with attached NDIS_BUFFER describing physical buffer
- For NDIS6 - NET_BUFFER_LIST structure with NET_BUFFER attached with MDL physical buffer
The driver uses configuration parameter of initial number of RX buffers to prepare. Using this number it preallocates these system-dependent objects (one per buffer) and pool objects for them and uses them when required.
Then the driver starts preparing descriptor structures (listable control blocks) for receiving. The driver maintains list of descriptors that are waiting for data in VirtIO queue (NetReceiveBuffers) and list of descriptors that were indicated to NDIS and must be returned to the driver (NetReceiveBuffersWaiting). The driver prepares descriptors one-by-one:
- Allocates descriptor for RX buffer
- Allocates physical buffer for VirtIO header (10 bytes)
- Allocates physical buffer for packet data (1514 bytes + 4 for possible priority tag)
- Saves these buffers (physical address, virtual address and size) in the descriptor
- Calls system-dependent implementation of ParaNdis_BindBufferToPacket to allocate required system-dependent object (MDL for NDIS6, NDIS_BUFFER for NDIS5) to describe the buffer for packet data
- Uses add_buf to pass these 2 buffers (header and data) to VirtIO for further receiving
- When the VirtIO can not add more buffers, the driver stops the loop – it will work with as many buffers as VirtIO supports
- The descriptor added to list of buffers that VirtIO currently owns (NetReceiveBuffers)
There is small change for initialization when mergeable RX buffer supported:
- Separate physical buffer for VirtIO header not used
- Physical buffer for packet data (1514 bytes + 4 for possible priority tag + 12 bytes header)
- Uses add_buf to pass 1 buffer (header with data) to VirtIO for further receiving
The driver can indicate packets one by one (as arrays of 1 element or as list of one NET_BUFFER_LIST element), but batch indication (as array of packets or list of many elements) significantly improves the performance. For that, during initialization the driver allocates storage for array of pointers to use it during batch indication.
Main procedure for receive ParaNdis_ProcessRxPath retrieves all the available buffers from VirtIO RX queue and starts from check of packet type; virtual address of the buffer was saved in the descriptor during initialization. It checks the destination address of the packet and decides using current packet filter mask whether the packet shall be indicated up to networks stack or dropped. For packet to be indicated it calls system-dependent implementation of ParaNdis_IndicateReceivedPacket, which can indicate the packet or just prepare it for further indication in batch of packets; ParaNdis_IndicateReceivedPacket allocates from prepared pools required objects and retrieves from the descriptor already prepared object, describing the buffer, and returns system-dependent object for indication (NDIS_PACKET or NET_BUFFER_LIST). When the batch is full, system-dependent procedure ParaNdis_IndicateReceivedBatch finally does the indication. The size of batch defined during initialization – it can include all the buffers of VirtIO, but during the loop the procedure, in general, may retrieve more buffers than VirtIO contains, as some buffers may be returned by NDIS, put back to VirtIO and returned back to the driver.
The procedure of indication must be called without holding spinlock, as the returning of buffers from NDIS to the driver may happen synchronously or asynchronously.
When indicating packets, the driver keeps in NDIS_PACKET or NET_BUFFER_LIST the address of the buffer's descriptor for easy post-processing upon returning.
Additional responsibility of ParaNdis_IndicateReceivedPacket is removal of priority tag if it present in incoming packet and populating priority/VLAN data in packet's OOB. Currently this procedure is not optimal – it removes the tag by moving data inside the buffer; it can be optimized later.
Packets, filtered out by filter mask, are returned to VirtIO immediately.
All the variables and objects related to RX path are protected by Receive Lock. All the operations with VirtIO RX queue are protected the same way from simultaneous add_buf, get_buf, kick, restart operations.
Returning buffers
NDIS returns packets one-by-one in NDIS5 or as list of NET_BUFFER_LIST structures in NDIS6; in both cases all the objects are reinitialized and returned to their pools, and the descriptor, ready for reuse, added to the VirtIO queue using common procedure ParaNdis_VirtIONetReuseRecvBuffer (also protected by Receive Lock).
Pausing of operation
NDIS6 defines required procedures in miniport used for pausing and resuming of adapter's operation. It uses pausing before start binding or unbinding of protocol drivers to/from driver's stack and also when initializes adapter and shuts it down. Pause procedure must stop send and receive operations, return to NDIS all the buffers the miniport has in TX path and receive from NDIS all the miniport buffers which were indicated.
Although NDIS5 does not require such operations, the driver uses them for both NDIS5 and NDIS6 for consistent implementation of transitions during initialization, halting, reset, power off and power on.
Both TX and RX paths maintain State variable, which may be tri-state Enabled/Disabled/Pausing (tSendReceiveState). Transition from Disabled to Enabled is simple and synchronous; transition from Enabled to Disabled is asynchronous, with possible intermediate Pausing state when the RX path waits to returning of all the packets, indicated to NDIS, and TX path waits for completion of all the packets which sending is in process.
When asynchronous pausing started, sending and receiving of new packets are suppressed and callback procedures set to indicate end of transition and provide indication to NDIS when applicable.
Triggers to check whether the transition to paused state is finished is the moment when
- (RX path) reusing RX buffers and passing them to VirtIO (when there are no waiting buffers, the suspend of RX paths done)
- (TX path) main TX procedure, called from interrupt DPC when VirtIO indicates that sending of some submitted buffers is finished.
Reset operation implemented the same way – "reset" procedure pauses RX and TX path, then does "reset" of internal state and device and restarts RX and TX.
Power off and power on procedures also includes pause (suspend) and resume as steps of execution.
Connect detection
Connect detection starts from device implementation in QEMU, which maintain connection state and generates state change events upon change from monitor's command line. Driver recognizes these events, when reads interrupt status and passes it on context variable to DPC procedure.
When connect detection bit in interrupt status set (bit 1), the driver in the DPC rereads connect status from configuration array of the device (the configuration array contains MAC address and connect status) via IO space of PCI device and sends indication to NDIS about change in connection state. The exact implementation of connect / disconnect indication depends on NDIS version and uses system-dependent procedure ParaNdis_IndicateConnect.
When connect status in the miniport is "not connected", the procedure responsible for packets sending, immediately completes any new packet with status of failure; packets that already queues for sending will be completed as usual. Processing of interrupts and DPC continues; any packet, received in not connected state, returned to VirtIO queue without indication.
- To set the link status through QEMU nonitor, type set_link <nic>.<instance number> <up | down>
OID support
The implementation of OID support in NDIS5 and NDIS6 is slightly different, although the approach is the same and there are many OID with nearly identical implementation in both systems.
NDIS5 defines Get and Set methods for OID, NDIS6 defines many types but actually in use also Get and Set (Get Statistics method is actually Get, other are optional).
For both, on each OID call the driver receives exchange buffer and its input and output size; the driver needs to indicate number of bytes it read or written on successful completion; on failure due to too small buffer the driver indicates proper size of buffer required for the operation.
This allows splitting of OID support implementation to system-dependent and system-independent part where entry points are system dependent and the implementation for many OID is common.
OID call executes on IRQL that may be PASSIVE or DISPATCH, so the driver must or complete the OID immediately or fail it immediately. In other rare cases the driver completes OID asynchronously using scheduled work items or special indications.
Each system-dependent implementation contains table of structures defining all the supported OID operations, each table entry includes
- OID code (32-bit value)
- Bit mask describing operations valid for this OID (get, set, get via statistics, conversion of 64-bit to 32-bit when applicable)
- Procedure to call when Set operation requested
- Logging level upon entry, completion or error
Registered procedure first retrieves from the table OID entry for received OID, initializes temporary descriptor for the request in system-independent format (which contain input/output buffer, their sizes etc.) and passes the request to suitable procedure:
- For Set request – to "Set" processing routine specified in the OID table
- For Get (Query) request –to system-dependent procedure, which processed OID codes supported only for specific system; in default case it calls common procedure for system-independent processing of the rest of OID
Starting operation for "Set" request and final operation for "Get" request, including checking of buffer sizes and transfer of the data are implemented in system-independent procedures (ParaNdis_OidSetCopy, ParaNdis_OidQueryCopy) to avoid multiple checks in each OID specific procedure.
General-purpose OID
Many OID requests are directly related to fields of device context and actually copy data to/from buffers with exact buffer size validation and minimal processing, as:
- Connection speed and connection status
- MTU size
- Estimated free buffer space
- Packet filter bit mask
- MAC addresses, current and permanent
- List of multicast addresses
- List of Wakeup patterns
- Data transfer statistics
Offload OID
OID requests, related to offload control, are different in NDIS5 and NDIS6 and do not have too much common points.
After device instance initialization NDIS queries the offload capabilities of the driver/device, providing buffer that the driver fills by concatenation of NDIS_TASK_OFFLOAD structures, each of ones describe capabilities of the device to support specific kind of task offload (checksum, LSO, security etc). In "Set" request for offload OID, the NDIS passes to the driver list of NDIS_TASK_OFFLOAD structures, describing configuration of offload features which the driver shall enable. This configuration always contain encapsulation setting (one of those the driver supports) and placement of IP header in data buffers of packets which will be sent (non-IP packets are out of interest, for them offload will never be required).
Empty set of tasks to offload effectively disables offload capabilities for the driver.
Using configuration parameters some or all offload task can be masked from reports and left disabled.
Initial set of possible kinds of offload tasks (capabilities) and initial set of enabled offload tasks (configuration) the driver retrieves from configuration parameters and reports to NDIS during its initialization sequence (via NdisMSetMiniportAttributes).
The NDIS sends to driver mandatory offload parameters (encapsulation, IP header offset) on dedicated OID call and, if needed, changes configuration of specific offload tasks in following OID requests, passing NDIS_OFFLOAD structure. Historically, the driver required to support different versions of offload tasks formats (V1 and V2), where V2 includes also IPV6 related fields.
When there is some change in offload configuration, caused by "Set" request sent to the driver, it reports its new offload configuration via status indication mechanism, passing NDIS_OFFLOAD structure filled with values, reflecting changes of the current configuration. Exact meaning of field values in NDIS_OFFLOAD structure varies depending on exact flow where the structure is used – in NDIS-to-driver "Set" request or in driver-to-NDIS status indication.
Statistics OID
In NDIS5 each statistics entry implemented using its own OID; in NDIS6 the miniport driver can return also single structure (NDIS_STATISTICS_INFO) including all the statistics; for simplicity, NDIS5 implementation of the driver keeps its statistics entry in the same structure in which NDIS6 implementation returns statistics information.
Power management OID
Power management starts from Set OID request for OID_PNP_SET_POWER, providing target device state (D0 or D3, these states implied, other must be declared in PCI properties, if supported).
These requests can never be completed synchronously, so the driver in both NDIS5 and NDIS6 return STATUS_PENDING and uses system-specific ways to schedule work item which is executed on PASSIVE IRQL. From callback procedure of work item the driver calls common implementation of power transition - ParaNdis_PowerOff and ParaNdis_PowerOn; then indicates that the OID processing is completed.
Note that system power transition (standby or hibernation) will be blocked until the driver completes OID_PNP_SET_POWER (or will wait long time for completion, on timeout will produce BSOD). This OID for D3 can not be failed (in best case this will abort system transition to low power state); in general, the driver never shall fail power management OID requests.
Power management implementation
In general, the state of hardware devices in system hibernation state (S4) is very close to power-off. During transition to S0 system state the VirtIO device will be full reinitialized. During system transition to sleep (S3) state some device context may persist. From driver's point of view there is no difference between system transition to S4 and S3, in both cases the device goes to D3.
The NDIS driver during initialization can declare legacy behavior and ask for halt on transition to low power device state (NDIS_MINIPORT_ATTRIBUTES_NO_HALT_ON_SUSPEND flag declares support for power management), having on D0 to D3 transition the same flow as if the device was disabled. Unfortunately, testing software does not like such a behavior, so the driver must simulate extended support for power management.
Declaring support for power management, the driver receives SET_POWER OID requests on system transitions and in both cases of system state transition (S3 and S4), it keeps its internal state, including buffers allocated in VirtIO library and physical buffers allocated during initialization.
Complete re-initialization on power-on transition is not a good choice, as (especially in NDIS6) the driver required to allocate physical memory during initialization and not on power-transition; failure to allocate physical memory on power-on transition will be unsuitable.
In order to prevent misunderstanding, the driver on each power-off device transition (D0 to D3) resets the device (by writing 0 to status register) and on power-on transition (D3 to D0) initializes it from scratch using the same set of already allocated buffers in VirtIO library and the same set of physical buffers allocated during initialization. For that, in the implementation of VirtIO library
- the shutdown method of the VirtIO queue is fixed to bring the queue to its initial state
- added high level method to PCI device API to renew the queue using existing buffers and just rewrite required addresses to registers of VirtIO device
Finally, the power-off sequence starts from Pause operation (suspend RX and TX and wait until all the blocks are returned to their owners). Then the driver shuts down both VirtIO queues, completely stopping the transfer, and resets the device by writing 0 to status register.
On power-on sequence the driver renews VirtIO queues and restarts send and receive paths.
The driver implements formal support for wake-up capabilities via wake-up patterns and/or magic packets; currently there is no support for this feature in QEMU and the goal of this implementation is only formal compatibility with requirements of WHQL testing procedures.
Reset command
For consistency, the same flow that the driver uses for device power-off and power-on during system power transition, it uses to implement reset command.
The trigger for reset is NDIS call to miniport reset procedure, registered by the driver. NDIS can call it when it wants (especially during tests), but in normal usage there are two reasons to receive reset command:
- Very long delay in completion of OID request
- Two positive responses to miniport "Check for hang" procedure
The driver never does it, so reset command mainly initiated by test cases (NDIS tests). Upon reset command, the driver acts like it received sequence "power-off, power-on".
Halt command (adapter's shutdown)
Upon Halt command, the driver frees all the resources, allocated for device instance and leaves the device in inactive state, not able to generate interrupts and ready for next initialization.
Implementation of device reset in Halt flow is similar to device reset.
Note that device reset sequence, to clean up device QEMU context, includes also writing 0 to register of guest features.
To initiate Halt command, disable the device in the device manager manually or do it using "devcon" tool from WDK.
Synchronization mechanisms
Synchronization goals
Under different flows, processing requests from NDIS as well as events from device, the driver must protect fields of its context from simultaneous modification from different contexts. Guidelines are simple
- Flow running on IRQL= PASSIVE may be preempted by DPC even on the same processor
- Flow running on IRQL= DISPATCH may be preempted by interrupt even on the same processor
- Flow running on any IRQL may run at the same time and conflict with any flow on different processor
The source code of VirtIO library has the same potential hazards as the source code of the driver itself; VirtIO library does not include any synchronization mechanisms and caller of any procedure do it on its own responsibility.
Each method of VirtIO queue, callable from external code, modifies internal state of this queue; so each access to VirtIO queue must be protected.
Synchronization objects
The driver uses modest set of synchronization means
- DPC spin lock acquired on DPC entry and release on DPC exit
- SendLock spinlock acquired when accessing variables related to TX path
- ReceiveLock spinlock acquired when accessing variables related to RX path
The driver also uses interlocked access to specific variables to provide synchronization of their modification regardless context where they are modified and interrupt synchronization to protect very limited set of variables from simultaneous modification from interrupt procedure and other contexts.
Additional point of synchronization (more precise, IRQL forcing) is request for TX packet mapping when NDIS6 send packets to miniport. NdisMAllocateNetBufferSGList must be called on IRQL=DISPATCH, but we can achieve it acquiring SendLock as we do with all the TX variables, as it can immediately call mapping callback, causing deadlock. In order to force IRQL=DISPATCH we initialize temporary spinlock on the stack and acquire it before call NDIS for buffers mapping and immediately release. Even if NDIS will call us from any NDIS call initiated by TX path now, it will not cause deadlock and will acquire another temporary spinlock.
SendLock and ReceiveLock actually both use the same spinlock object – it depends on define "UNIFY_LOCKS" and can be modified by compilation, no side-effects expected, as TX path and RX path does not have any common variables.
NDIS requirements
Some NDIS calls according to documentation may not be called with spinlocks held. Only reason for that could be a possibility that from this call the NDIS will call some driver's procedure and this may cause deadlock - attempt to acquire the same spinlock twice from the same processor or attempt to acquire two spinlocks on two difference processor in different order.
The calls are
- Indication of received packet to NDIS
- Completion of send packets
- Status indications
Strictly speaking, we violate this requirement.
In driver's DPC procedure, implementing deferred processing of interrupt raised by device, we acquire DPC spinlock and hold it until DPC is finished. We do not expect any side-effects from it, as this lock is not a part of any flow initiated by NDIS during packets sending or receiving.
This DPC lock serves two goals:
- Ensure in Halt or procedure that there is no DPC in process and any other DPC will not be processed when we free buffers and descriptors. It is possible to write this code without using
- Ensure that when we are in DPC process, another DPC on another CPU will not run. With traditional hardware this is simple – device interrupts are disabled in IRQ handler and enabled in DPC. The VirtIO clears interrupt status on read operation and immediately after that may raise another IRQ, possible directed to another processor.
Compilation and linking
Build process uses "build" utility from WDK. The build process uses "dirs" file in current directory and in leach directory listed in "dirs" file to define tree of directories to process; in each directory build uses "sources" file to define sources and targets in it; syntax of "sources" is similar to one of make file for "nmake" utility (although "sources" file is not a make file; real make file present in each directory and only includes WDK make file).
A batch file "buildAll" sets up the environment for each target OS, creates make files and "dirs" files and runs "build" utility. When driver's binary file generated, the batch calls procedure for signing and packaging.
Signing and packaging
Providing driver package (CAT file) and signing it at least with development time certificate is only way to achieve smooth driver installation (for completely smooth the driver must be signed by logo certificate). For that, the build process includes these steps – it generates CAT file from INF file (using INF2CAT utility from latest DDK 6001 or using signability utility from earlier DDK) and signs it using development certificate, generated especially for this project. Only goal is to make build process complete and produce ready-to-use package for immediate testing.
In order to sign the package with different certificate, the certificate file (and password) can be changed in build environment.
The signed package also can be signed again with different certificate (previous signature will be removed).
In addition to signing, in Vista OS family the operating system must be configured to allow installation of drivers with test signature (see below).
Creation of ISO image with driver installation is a good practice for testing: under any operating system drivers from CD driver can be always installed automatically or using simple installer, which may not work when the driver package is kept on hard disk.
The developer during testing often tends replacing the kernel driver binary with just compiled version. Overwriting of only kernel driver binary does not work on Vista 64 OS family, the driver must be installed. Additionally, some tests from Logo kit may reinstall the driver and return it to originally installed version. Having driver installed is always better than patching it in place.
Minimal subset of testing tools:
- Network performance tools
- IPERF, for short transfers use –n count, for specific NIC use -B
- Driver Verifier (verifier.exe), set it to at least netkvm.sys + ndis.sys (activating verifier on the driver significantly reduces the performance)
- NDIS test from WLK kit
- NDISTEST (a.k.a. 6.0)
- NDISTEST.NET (a.k.a. 6.5)
- WDK tools
- Devcon
- Plug-and-Play test
- Power test (for Vista)
- Sleeper (for automatic power management under XP)
Both offline NDIS (6.0 and 6.5) tests define DUT, support adapter and optional message adapter. Message adapter is mandatory for client-server test, when 2 VM used: one as server with one or two support adapters (usually VirtIO) and one message adapter (Intel); another one is client with one VirtIO under test, optional VirtIO as support adapter and Intel as message adapter.
Some of NDIS tests require only one adapter (DUT) – they do not require second VM at all; some require two adapters (DUT and local or remote support adapter).
NDIS test on single machine
Preliminary sanity test could be done on single VM in client mode with 2 NETKVM adapters, one is DUT and another one is support (without message adapter). Almost all the functional tests can run without problems in this configuration and detect problems in driver flows.
Recommended configuration for single VM tests includes 3 adapters: 2 NETKVM + one Intel E1000 with updated drivers from Intel support site.
It is recommended to run tests related to sending and receiving packets with priority tags twice, selecting NetKVM and Intel as support adapter.
NDIS test on two machines
NDIS test runs on one VM in server mode (requires 2 or 3 adapters – one as message device and another one or two as support devices) and on another VM in client mode (requires at least 2 adapters – one DUT and one as message device).
This setting is recommended for tests involving power management and also for MPE tests (multi-path execution).
Note that MPE test may produce failures and BSOD when the machine under test has small amount of RAM (at least 640M recommended), other tests do not use too much memory and able to run with 256-384 MB.
The NetKVM driver implements simple scheme of logging and the main tool for collecting logging information is Debug View.
In order to avoid limitations of debugging output of Vista, instead of DbgPrint the driver uses vDbgPrintEx with mask that enabled by default and not filtered.
Debug level is controlled from adapter parameters (Device manager – Properties - Advanced), but changes global variable in the driver and affects all the devices supported by the driver. Typically, with default debug level, the driver produces logging information only during initialization and shutdown
WPP support
If ENABLE_EVENT_TRACING defined in Common\common.mak, the logging mechanism changed to WPP. In order to collect logging information, WDK utilities (as TraceView) shall be used and PDB file (or TMF file, containing WPP-specific information) required to translate unreadable log to readable. TMF file can be produced from PDB file using tracefmt utility from WDK. The process of activating verbose logging is very uneasy comparing to one using Debug View.
Analysis of crash dump
In order to debug the driver when it (or system) stops responding, it is easy to use manual generation of crash dump using keyboard (the system must be configured to allow it, see [1] ).
Parsing the crash dump using WinDbg, in addition to regular commands use NDIS extension commands:
- "!ndiskd.miniports" gives a list of existing adapters. Use miniport address for details about specific adapter.
- "!ndiskd.miniport <address of miniport>" gives details for any specific miniport.
After adapter context retrieved using the last command, use "Watch" of this value with casting to (PARANDIS_ADAPTER *) to examine internal fields of per-adapter context (PDB file required).
Interrupt recovery
In earlier versions of KVM with Vista there was a problem of interrupt activation from host to guest. The code in Vista driver still contains parameter "Interrupt recovery", enabled by default. It starts 15 ms timer which acts instead of hardware interrupt. When it detects a real interrupt activity, it stops running. With this workaround, the VM had fewer cases without interrupt streaming; and even if the guest VM does not receive interrupts, the miniport still can function, receives IP address etc.
Timed connect indication
In earlier versions of KVM/QEMU the connect/disconnect indication from the host to VM was not implemented. It was useful during testing during development to delay the connect indication and do not immediately upon driver startup. This workaround is controller by "Connect after" parameter (by default disabled now).
List of configurable parameters
The following list controls the trace logging ability of the driver.
- To gather the trace log please use DebugView (http://technet.microsoft.com/en-us/sysinternals/bb896647) utility or connect kernel debugger to guest (http://www.linux-kvm.org/page/WindowsGuestDrivers/GuestDebugging).
- In Windows Vista and up follow those instructions to enable debug prints on OS level as well: http://www.osronline.com/article.cfm?article=295
Friendly name | Old name | Type | Default | Description |
Logging.Enable | Logging enabled | Boolean | 1 | Setting to 0 suppresses all the debug printouts |
Logging.Level | Logging level | Integer | 0 | Debug level, increment increases verbosity. 0: Errors only. 1-2 Configuration. 3-4: Packet flow. 5-6: Interrupt and DPC level trace. Warning! Using high debug level will slow down the VM. |
Logging.Statistics(sec) | Log statistics period | Integer | 0 | Setting to N provides periodical statistics printout each N seconds |
Initial parameters
The following list controls NetLKVM driver initial parametes
Friendly name | Old name | Type | Default | Description |
Assign MAC | Mac Address | String | NA | Set locally administered MAC address for the paravirtualized NIC. Keep in mind that this address must have locally administered group bit set: http://standards.ieee.org/develop/regauth/tut/macgrp.pdf . If invalid MAC address provided, the driver will reject its assignment but the GUI might still reflect invalid MAC address. |
Init.ConnectionRate(Mb) | Connection Rate | Integer | Windows XP and 2003: 1000. Windows 2008 and up: 10000. | Connection rate to indicate (10/100/1G/10G). In Windows XP\Win2003 reported connection rate is limitted to 1G. Please keep in mind that this is a cosmetic value and has no actual effect on the performance of the NIC. |
Init.Do802.1PQ | 802.1PQ | Boolean | 1 | Enable support of Priority/VLAN tags population and removal |
Init.UseMergedBuffers | Use mergeable buffers | Boolean | 1 | 0 suppressed using mergeable RX buffers (even if the host supports) |
Init.UsePublishEvents | NA | Boolean | 1 | 0 suppressed using published events (even if the host supports) |
Init.MTUSize | MTU size | Integer | 1500 | MTU size can be set between 500 and 65500 in steps of one. |
Init.IndirectTx | NA | Tri-state | Disable | Enable - enable indirect ring descriptors usage; Disabled - disable indirect ring descriptors usage; Enable* - conditional enabling of the feature, currently same as enable. |
Init.MaxTxBuffers | Initial Tx buffers | Integer | 1024 | Indicate how much TX ring descriptors the driver will allocate. Possible values: 16, 32, 64, 128, 256, 512, 1024. |
Init.MaxRxBuffers | Initial Rx buffers | Integer | 256 | Indicate how much RX ring descriptors the driver will allocate. Possible values: 16, 32, 64, 128, 256, 512, 1024. |
Offload.Tx.Checksum | Offload Tx TCP checksum | List box | TCP/UDP | Enable TX checksum offloading. TCP/UDP - TCP and UDP checksum offload. TCP - TCP only. Disable - TX checksum offload is disabled. |
Offload.Tx.LSO | Offload Tx LSO | Boolean | 1 | Enable TX TCP Large Segment Offload |
Offload.Rx.Checksum | NA | List box | Disabled | Enable RX checksum offloading. Disable - disabled. All - TCP\UDP and IP. TCP\UDP - TCP and UDP checksum offload. TCP - TCP only checksum offload. |
Test and debug parameters
The parameters in the following list should be used only by the support\engineers or for internal research.
Friendly name | Old Name | Type | Default | Description |
TestOnly.DelayConnect(ms) | Connect after | Integer (milliseconds) | 0 | Delay connect indication on startup |
TestOnly.DPCChecking | DPC Checking | Tri-state | 0 | If not 0, each hang test verifies activity of DPC and acts as if the DPC was spawned; if 2, also clears the device interrupt status |
TestOnly.Scatter-Gather | Enable Scatter-Gather | Boolean | 1 | 0 disables SG functionality and all the dependent capabilities |
TestOnly.InterruptRecovery | Interrupt Recovery | Boolean | 1 | Interrupt recovery for Vista and up. In earlier versions of KVM with Vista there was a problem of interrupt activation from host to guest. The code in Vista driver still contains parameter "Interrupt recovery", enabled by default. It starts 15 ms timer which acts instead of hardware interrupt. When it detects a real interrupt activity, it stops running. With this workaround, the VM had fewer cases without interrupt streaming; and even if the guest VM does not receive interrupts, the miniport still can function, receives IP address etc. |
TestOnly.PacketFilter | Enable Packet Filter | Boolean | 1 | Enables packet filtering |
TestOnly.BatchReceive | Batch Receive | Boolean | 1 | Indicate batch of packets rather than one-by-one |
TestOnly.Promiscuous | Promiscuous mode | Boolean | 0 | Enables or disables promiscuous mode. |
TestOnly.AnalyzeIPPackets | Analyze IP packets | Boolean | 0 | Turns on verification of checksum fields of some outgoing IP packets and printing it out (for debugging purposes) |
TestOnly.RXThrottle | Handled RX packers in DPC | Integer | 1000 | Number of receive packets that are handled in one DPC. |
TestOnly.UseSwTxChecksum | Hardware checksumming | Boolean | 0 | If enabled checksuming will be done in the driver. |


text:
The 1991 disney adaptation of Beauty and the Beast, we see several references to technology that seems out of place with the setting, including rifles and steam powered machines. It makes it hard for me to try and judge when the film would be set.
Is there any official answer, on when the film is mean to be set?


text:
Saturday morning I woke up about 7:30am. I got a good solid 6 hours of sleep and apparently that's all I needed! Anna was still asleep so I got dressed and went down to the gym. The Bally's gym was SO NICE! One of the best hotel gyms I've used (The Monte Carlo being my other favorite). They had half a dozen treadmills, about 7 ellipticals, some stair-masters, exercise bikes and TONS of weight machines and free weights.
I was one of three people in the gym that early. My friend Debby and the people she went to Vegas with were on their way to Red Rock Canyon for a hike (which sounded awesome to me). I warmed up on the elliptical, did some body weight exercises (burpees, jumping jacks, crunches, etc) went through the weight machines, did some free weight stuff and finished up with a half mile run on the treadmill.
My legs were tired from all the walking we did on Friday. I knew I should take it easy with the lower body cardio because we were going to do even more walking on Saturday. I got a fantastic workout in, burned some calories and then checked out the spa that guests could use. They had a body temperature hot tub, a hot hot tub, a dry sauna, a steam room with eucalyptus and then your typical spa services. The men's and women's spas were separate and there were a bunch of ladies in there waiting for massages. I told Anna that we should make good use of it (especially since we were paying $20 per night for the "resort fee" to use it) but sadly we ran out of time and didn't get to it.
I got cleaned up and then Anna and I went out in search of breakfast. I was staving! We walked over to Paris (which is right next to Bally's) and the fancy Parisian outdoor cafe was packed! The line just to get to the hostess to get on a wait list was at least 20 people deep. We decided to keep walking. Next door was something called The Sugar Factory and they also had a huge outdoor patio.
While we waited we sat at their bar and got some coffee and Bloody Mary's. 😀 Their coffee was AMAZING!!! The best coffee I've ever had. We asked the bartender, waiter, waitress and no one seemed to know what brand of coffee they served. I was disappointed because I totally would have bought some if I knew what it was! Their Bloody Mary's were fantastically spicy. They used a spicy infused vodka in the bloody mix. The salt was huge, flavorful crystals that clung to the glass, there was a hint of lime and cucumber in the drink and there was a cucumber and olive garnish. So tasty.
It took about 20 minutes and then we got our table outside. There was a gorgeous breeze and it was about 70 degrees so far. We were across the street from the Bellagio. It was a peaceful, relaxing time as we lounged on the patio. It was hard to decide what to get. I REALLY wanted the carrot cake pancakes but I knew the cream cheese frosting would just be too much sugar first thing in the morning. The blueberry pancakes sounded great and let's be honest, so did the Fat Elvis Waffle (ok not really).
I decided to go for the croissant sandwich. It was ham and cheese and came with crispy potatoes (that were exceptional). The sandwich was big and honestly half would have been the perfect portion. The croissant was heavenly–flaky, buttery and perfect. Dang, I want another!
After breakfast we walked over to the Bellagio and caught the bus to Mandalay Bay. We walked around the gardens, checked out their AMAZING pool (it was packed!) that had a lazy floating river, and then went to see the Shark Aquarium (which was kind of expensive so we skipped it). Then we saw MICHAEL JACKSON!! Woot!!! The street performer was great! He sounded, looked and danced just like the real thing. It was great getting a picture!
We meandered down to The Luxor and then decided to take a gambling resting break in New York New York. Our feet, legs and calves were aching. I could have used a massage. 🙂
We decided to hop on the bus back to Bally's (our poor feet). Thankfully our bus pass was still valid! I have to admit, we stopped for more $2 tacos at Bally's (they were that good) and then went down to the pool. We stayed out fairly long and the sun was hot hot hot! It was around 88 degrees on Saturday. It felt like heaven. For months I've been craving that exact thing–sitting poolside in the sun with a cool drink and a book.
After the pool we got cleaned up and dolled up and we were ready for the night! First we did some gambling at the Bellagio and got lucky! It was nice! We had an hour to kill before meeting up with my friend Debby and her party at Excalibur for Thunder From Down Under!! Debby goes every single time she's in Vegas and talks about it all the time so I said, sure why not? It could be fun. We liked the movie Magic Mike. 😀
It was a huge auditorium packed full of women of all ages. There were a ton of brides-to-be with the veil and tiaras. There were a bunch of girls there for birthdays. There was this one girl that was called onto the stage because it was her 21st birthday and her mom had brought her! Awesome! Debby and her family were sitting over on the other side of the room and Anna and I were at a table with a bunch of adorable little old ladies that were doing Jello Shots. LOL!!! My friend Debby:
Hell ya we did Jello Shots! It's been like 10 years since I had them. Haha! So the show…It was totally awesome. It was worth the money for the ticket and the guys definitely looked great–just like the photos. Afterward we could get pictures with the guys. 😀 We all got a free pass to a nightclub in the Luxor and free drinks til midnight but the line to get in was kind of long and I was starting to get tired (and blisters on my feet). Debby and her people ended up dancing til 2am! Anna and I walked back to our hotel, enjoying the nightly sights on the way.
Why I decided to book us a flight so freaking early on Sunday morning is beyond me. UGH. Coffee was needed. We had a few minutes to hit the tables before leaving and we both left winners! I got a hit on #29 and won $35 buckaroos. I was happy to leave after winning. Debby had rented a car (a bright blue mustang convertible) and she kindly offered to take us to the airport. It was so AWESOME riding through Vegas in a convertible! One of the highlights for sure.
Our flight was super turbulent — like the first hour of the flight I felt like I was going to barf and then die–and that sucked. The winds had started late Saturday night and Sunday was just as windy. I guess that was the cause of the turbulence. Dang it was not comfortable and I spent most of Sunday feeling nauseated. I was glad to be home and on LAND. Bella gave me lots of kisses, Fat Kitty gave me lots of love nibbles and it was so good to see Michael again.
I had a fantastic weekend. Everything was great and it was SO good to spend time with Anna. We were travel buddies for a really long time and then she moved to Morocco for the Peace Corp and was gone for about 4 or 5 years. We were still in sporadic contact (email and phone calls) but not seeing her for a long time made us drift apart a bit. It was nice to reconnect. And lay by the pool. And drink some umbrella drinks. 😀


text:
Apart from grep and regular expressions, there's a good deal of pattern matching that you can do directly in the shell, without having to use an external program.
As you already know, the asterisk (*) and the question mark (?) match any string or any single character, respectively. Quote these special characters to match them literally:
cathy ~> touch "*" cathy ~> ls "*" *
But you can also use the square braces to match any enclosed character or range of characters, if pairs of characters are separated by a hyphen. An example:
cathy ~> ls -ld [a-cx-z]* drwxr-xr-x 2 cathy cathy 4096 Jul 20 2002 app-defaults/ drwxrwxr-x 4 cathy cathy 4096 May 25 2002 arabic/ drwxrwxr-x 2 cathy cathy 4096 Mar 4 18:30 bin/ drwxr-xr-x 7 cathy cathy 4096 Sep 2 2001 crossover/ drwxrwxr-x 3 cathy cathy 4096 Mar 22 2002 xml/
This lists all files in cathy's home directory, starting with "a", "b", "c", "x", "y" or "z".
If the first character within the braces is "!" or "^", any character not enclosed will be matched. To match the dash ("-"), include it as the first or last character in the set. The sorting depends on the current locale and of the value of the LC_COLLATE variable, if it is set. Mind that other locales might interpret "[a-cx-z]" as "[aBbCcXxYyZz]" if sorting is done in dictionary order. If you want to be sure to have the traditional interpretation of ranges, force this behavior by setting LC_COLLATE or LC_ALL to "C".
Character classes can be specified within the square braces, using the syntax [:CLASS:], where CLASS is defined in the POSIX standard and has one of the values
"alnum", "alpha", "ascii", "blank", "cntrl", "digit", "graph", "lower", "print", "punct", "space", "upper", "word" or "xdigit".
Some examples:
cathy ~> ls -ld [[:digit:]]* drwxrwxr-x 2 cathy cathy 4096 Apr 20 13:45 2/ cathy ~> ls -ld [[:upper:]]* drwxrwxr-- 3 cathy cathy 4096 Sep 30 2001 Nautilus/ drwxrwxr-x 4 cathy cathy 4096 Jul 11 2002 OpenOffice.org1.0/ -rw-rw-r-- 1 cathy cathy 997376 Apr 18 15:39 Schedule.sdc
When the extglob shell option is enabled (using the shopt built-in), several extended pattern matching operators are recognized. Read more in the Bash info pages, section Basic shell features->Shell Expansions->Filename Expansion->Pattern Matching.


text:
Exploratour - Evolution of the Solar System
This page is the start of the tour of the Evolution of the Solar System. The navigation button for the tour can be found at the top of the page. With a subject like the evolution of the solar system, there are a lot of things to discuss; the initial formation of the Sun, the 9 planets, various interesting moons, and their evolution from the dawn of time through where they are today. Because of the size of the subject, the tour has been broken into three segments. This is the first segment, and will present the solar nebula and the forming Sun and planets. You can skip ahead if you like by using the links at the bottom of this page. To proceed with the tour, just press the forward link (F) on the button at the top of the page.
This is page 1 of 60