anchor.diff:  (defun rtl8168-worker (nic)
     (when (not (rtl8168-initialize nic))
       (return-from rtl8168-worker))
  -  (flet ((check-boot ()
  -           (when (not (eql (rtl8168-boot-id nic) (current-boot-id)))
  -             (return-from rtl8168-worker))))
  -    (loop
  -       ;; Wait for something to happen.
  -       (latch-wait (rtl8168-irq-latch nic))
  -       (latch-reset (rtl8168-irq-latch nic))
  -       (simple-irq-unmask (rtl8168-irq-handler nic))
  -       ;; Perform receive handling. Remove packets from the RX ring
  -       ;; until there are none left.
  -       (loop
  -          (let ((current (rtl8168-rx-current nic)))
  -            (with-pseudo-atomic ()
  -              (check-boot)
  -              ;; Acknowledge IRQ.
  -              (setf (rtl8168-reg/16 nic +rtl8168-register-ISR+) #b1111)
  -              (when (logbitp +rtl8168-descriptor-OWN+ (rtl8168-rx-desc-flags nic current))
  -                ;; Current descriptor owned by the NIC, no more packets to receive.
  -                ;; Break out of the RX loop.
  -                (return)))
  -            #+(or)(debug-print-line "RTL8168 receive on " current)
  -            ;; Receiving one packet.
  -            ;; Allocate a buffer. Can't be done while pseudo-atomic, hence the dropping in & out.
  -            (let ((buffer (make-array +rtl8168-mtu+ :element-type '(unsigned-byte 8))))
  -              (with-pseudo-atomic ()
  -                (check-boot)
  -                ;; Copy the packet into the receive buffer.
  -                (let ((address (+ (rtl8168-rx-bounce-virt nic)
  -                                  (* current (mezzano.supervisor::align-up +rtl8168-mtu+ 128)))))
  -                  (dotimes (i (min +rtl8168-mtu+
  -                                   (ldb (byte 16 +rtl8168-descriptor-Frame_Length+)
  -                                        (rtl8168-rx-desc-flags nic current))))
  -                    (setf (aref buffer i) (sys.int::memref-unsigned-byte-8 address i))))
  -                ;; Reset the descriptor.
  -                (setf (rtl8168-rx-desc-flags nic current) (logior (ash +rtl8168-mtu+ +rtl8168-descriptor-Frame_Length+)
  -                                                                  (ash 1 +rtl8168-descriptor-OWN+)
  -                                                                  (if (eql current (1- +rtl8168-n-rx-descriptors+))
  -                                                                      (ash 1 +rtl8168-descriptor-EOR+)
  -                                                                      0))
  -                      (rtl8168-rx-desc-vlan nic current) 0))
  -              (nic:device-received-packet (rtl8168-wrapper nic) buffer))
  -            ;; Advance Current.
  -            (setf (rtl8168-rx-current nic) (rem (1+ current) +rtl8168-n-rx-descriptors+))))
  -       ;; Transmit handling.
  -       ;; Recover free descriptors.
  -       (with-pseudo-atomic ()
  -         (check-boot)
  +  (macrolet ((with-rtl8168-access ((nic) &body body)
  +               `(sup:with-device-access ((rtl8168-boot-id ,nic)
  +                                         (return-from rtl8168-worker))
  +                  ,@body)))
  +    (unwind-protect
            (loop
  -            (when (eql (rtl8168-tx-current nic) (rtl8168-tx-tail nic))
  -              ;; All pending descriptors processed.
  -              (return))
  -            (when (logbitp +rtl8168-descriptor-OWN+ (rtl8168-tx-desc-flags nic (rtl8168-tx-tail nic)))
  -              ;; Reached the descriptor that the card is processing.
  -              #+(or)(debug-print-line "RTL8168 still processing " (rtl8168-tx-tail nic))
  -              (return))
  -            (decf (rtl8168-tx-used-count nic))
  -            (setf (rtl8168-tx-tail nic) (rem (1+ (rtl8168-tx-tail nic)) +rtl8168-n-tx-descriptors+))
  -            #+(or)(debug-print-line "RTL8168 transmitted packet on descriptor " (rtl8168-tx-tail nic))))
  -       ;; Send pending packets.
  -       (loop
  -          (when (eql (rtl8168-tx-used-count nic) +rtl8168-n-tx-descriptors+)
  -            ;; Don't transmit when there are no free descriptors.
  -            #+(or)(debug-print-line "RTL8168 not transmitting - no free descriptors.")
  -            (return))
  -          (let ((to-send (with-mutex ((rtl8168-lock nic))
  -                           (pop (rtl8168-tx-pending nic))))
  -                (current (rtl8168-tx-current nic)))
  -            (when (not to-send)
  -              (return))
  -            #+(or)(debug-print-line "RTL8168 transmitting packet " to-send " on descriptor " current)
  -            (with-pseudo-atomic ()
  -              (check-boot)
  -              ;; Copy packet to buffer.
  -              (let ((address (+ (rtl8168-tx-bounce-virt nic)
  -                                (* current (mezzano.supervisor::align-up +rtl8168-mtu+ 128)))))
  -                (dotimes (i (min +rtl8168-mtu+
  -                                 (length to-send)))
  -                  (setf (sys.int::memref-unsigned-byte-8 address i) (aref to-send i))))
  -              ;; Configure the descriptor.
  -              (setf (rtl8168-tx-desc-flags nic current) (logior (ash (min +rtl8168-mtu+ (length to-send))
  -                                                                     +rtl8168-descriptor-Frame_Length+)
  -                                                                (ash 1 +rtl8168-descriptor-OWN+)
  -                                                                (if (eql current (1- +rtl8168-n-tx-descriptors+))
  -                                                                    (ash 1 +rtl8168-descriptor-EOR+)
  -                                                                    0)
  -                                                                ;; This is the first & last segment.
  -                                                                (ash 1 +rtl8168-descriptor-FS+)
  -                                                                (ash 1 +rtl8168-descriptor-LS+))
  -                    (rtl8168-tx-desc-vlan nic current) 0)
  -              ;; Notify the card.
  -              (setf (rtl8168-reg/8 nic +rtl8168-register-TPPoll+) (ash 1 +rtl8168-TPPoll-NPQ+)))
  -            ;; One used.
  -            (incf (rtl8168-tx-used-count nic))
  -            ;; Advance current.
  -            (setf (rtl8168-tx-current nic) (rem (1+ current) +rtl8168-n-tx-descriptors+)))))))
  +            ;; Wait for something to happen.
  +            ;; Either an interrupt, a request to send, or the device's boot epoch expiring.
  +            (sync:wait-for-objects (rtl8168-irq-handler nic)
  +                                   (rtl8168-tx-mailbox nic)
  +                                   (rtl8168-boot-id nic))
  +            ;; Perform receive handling. Remove packets from the RX ring
  +            ;; until there are none left.
  +            (loop
  +               (let ((current (rtl8168-rx-current nic)))
  +                 (with-rtl8168-access (nic)
  +                   ;; Acknowledge IRQ.
  +                   (setf (rtl8168-reg/16 nic +rtl8168-register-ISR+) #b1111)
  +                   (when (logbitp +rtl8168-descriptor-OWN+ (rtl8168-rx-desc-flags nic current))
  +                     ;; Current descriptor owned by the NIC, no more packets to receive.
  +                     ;; Break out of the RX loop.
  +                     (return)))
  +                 #+(or)(debug-print-line "RTL8168 receive on " current)
  +                 ;; Receiving one packet.
  +                 ;; Allocate a buffer. Try to minimize the amount of work done in a device-access region, hence the dropping in and out.
  +                 (let ((buffer (make-array +rtl8168-mtu+ :element-type '(unsigned-byte 8))))
  +                   (with-rtl8168-access (nic)
  +                     ;; Copy the packet into the receive buffer.
  +                     (let ((address (+ (rtl8168-rx-bounce-virt nic)
  +                                       (* current (mezzano.supervisor::align-up +rtl8168-mtu+ 128)))))
  +                       (dotimes (i (min +rtl8168-mtu+
  +                                        (ldb (byte 16 +rtl8168-descriptor-Frame_Length+)
  +                                             (rtl8168-rx-desc-flags nic current))))
  +                         (setf (aref buffer i) (sys.int::memref-unsigned-byte-8 address i))))
  +                     ;; Reset the descriptor.
  +                     (setf (rtl8168-rx-desc-flags nic current) (logior (ash +rtl8168-mtu+ +rtl8168-descriptor-Frame_Length+)
  +                                                                       (ash 1 +rtl8168-descriptor-OWN+)
  +                                                                       (if (eql current (1- +rtl8168-n-rx-descriptors+))
  +                                                                           (ash 1 +rtl8168-descriptor-EOR+)
  +                                                                           0))
  +                           (rtl8168-rx-desc-vlan nic current) 0))
  +                   (nic:device-received-packet nic buffer))
  +                 ;; Advance Current.
  +                 (setf (rtl8168-rx-current nic) (rem (1+ current) +rtl8168-n-rx-descriptors+))))
  +            ;; Transmit handling.
  +            ;; Recover free descriptors.
  +            (with-rt8168-access (nic)
  +              (loop
  +                 (when (eql (rtl8168-tx-current nic) (rtl8168-tx-tail nic))
  +                   ;; All pending descriptors processed.
  +                   (return))
  +                 (when (logbitp +rtl8168-descriptor-OWN+ (rtl8168-tx-desc-flags nic (rtl8168-tx-tail nic)))
  +                   ;; Reached the descriptor that the card is processing.
  +                   #+(or)(debug-print-line "RTL8168 still processing " (rtl8168-tx-tail nic))
  +                   (return))
  +                 (decf (rtl8168-tx-used-count nic))
  +                 (setf (rtl8168-tx-tail nic) (rem (1+ (rtl8168-tx-tail nic)) +rtl8168-n-tx-descriptors+))
  +                 #+(or)(debug-print-line "RTL8168 transmitted packet on descriptor " (rtl8168-tx-tail nic))))
  +            ;; Send pending packets.
  +            (loop
  +               (when (eql (rtl8168-tx-used-count nic) +rtl8168-n-tx-descriptors+)
  +                 ;; Don't transmit when there are no free descriptors.
  +                 #+(or)(debug-print-line "RTL8168 not transmitting - no free descriptors.")
  +                 (return))
  +               (let ((to-send (sync:mailbox-receive (rtl8168-tx-mailbox nic) :wait-p nil))
  +                     (current (rtl8168-tx-current nic)))
  +                 (when (not to-send)
  +                   (return))
  +                 #+(or)(debug-print-line "RTL8168 transmitting packet " to-send " on descriptor " current)
  +                 (with-rt8168-access (nic)
  +                   ;; Copy packet to buffer.
  +                   (let ((address (+ (rtl8168-tx-bounce-virt nic)
  +                                     (* current (mezzano.supervisor::align-up +rtl8168-mtu+ 128)))))
  +                     (dotimes (i (min +rtl8168-mtu+
  +                                      (length to-send)))
  +                       (setf (sys.int::memref-unsigned-byte-8 address i) (aref to-send i))))
  +                   ;; Configure the descriptor.
  +                   (setf (rtl8168-tx-desc-flags nic current) (logior (ash (min +rtl8168-mtu+ (length to-send))
  +                                                                          +rtl8168-descriptor-Frame_Length+)
  +                                                                     (ash 1 +rtl8168-descriptor-OWN+)
  +                                                                     (if (eql current (1- +rtl8168-n-tx-descriptors+))
  +                                                                         (ash 1 +rtl8168-descriptor-EOR+)
  +                                                                         0)
  +                                                                     ;; This is the first & last segment.
  +                                                                     (ash 1 +rtl8168-descriptor-FS+)
  +                                                                     (ash 1 +rtl8168-descriptor-LS+))
  +                         (rtl8168-tx-desc-vlan nic current) 0)
  +                   ;; Notify the card.
  +                   (setf (rtl8168-reg/8 nic +rtl8168-register-TPPoll+) (ash 1 +rtl8168-TPPoll-NPQ+)))
  +                 ;; One used.
  +                 (incf (rtl8168-tx-used-count nic))
  +                 ;; Advance current.
  +                 (setf (rtl8168-tx-current nic) (rem (1+ current) +rtl8168-n-tx-descriptors+))))
  +            (simple-irq-unmask (rtl8168-irq-handler nic)))
  +      (nic:unregister-network-card nic))))
   
   (defun rtl8168-allocate-ring (name size)
     (let* ((descriptor-frame (or (mezzano.supervisor::allocate-physical-pages
  
positive.code:         (dotimes (i (length p))
            (setf (aref data offset) (aref p i))
            (incf offset))))
      (with-mutex ((rtl8168-lock nic))
        (setf (cdr cons) (rtl8168-tx-pending nic)
              (rtl8168-tx-pending nic) cons))
      (latch-trigger (rtl8168-irq-latch nic))))
  
  (defun rtl8168-stats (nic)
    (values 0
            0
            0
  
negative.code:                                                (* i (mezzano.supervisor::align-up +rtl8168-mtu+ 128)))))
      (setf (rtl8168-tx-used-count nic) 0
            (rtl8168-tx-current nic) 0
            (rtl8168-tx-tail nic) 0)
      ;; Reset the RX ring.
      (dotimes (i +rtl8168-n-rx-descriptors+)
        (setf (rtl8168-rx-desc-flags nic i) (logior (ash +rtl8168-mtu+ +rtl8168-descriptor-Frame_Length+)
  