+=over 4
+
+=item C<volume_header>
+
+if any header data was read from the volume, it is represented here. The
+header's type may be F_WEIRD if the header was not recognized by Amanda.
+
+=item C<volume_label>
+
+if read_label read the header successfully, then volume_label contains the
+label
+
+=item C<volume_time>
+
+smililarly, if read_label read the header successfully, then volume_time
+contains the timestamp from the header
+
+=back
+
+=head3 start
+
+ $succss = $dev->start($ACCESS_WRITE, $label, $timestamp);
+
+Start starts the device and prepares it for the use described by its second
+parameter. This function can be called regardless of whether C<read_label> has
+already been called.
+
+If the access mode is C<$ACCESS_WRITE>, then the label and timestamp must be
+supplied (although leaving the timestamp undef will use the current time), and
+they will be used to write a new volume header. Otherwise, these parameters
+should be undef.
+
+On completion, start leaves the device's C<access_mode>, C<volume_label> and
+C<volume_time> member variables set, by reading the tape header if necessary.
+Note that in mode C<$ACCESS_APPEND>, the C<file> member variable is not set
+until after C<start_file> has been called.
+
+=head3 start_file
+
+ $success = $dev->start_file($header);
+
+This method prepares the device to write data into a file, beginning by writing
+the supplied header to the volume. On successful completion, the device's
+C<file> is set to the current file number, C<block> is zero, and C<in_file> is
+true. If the volume is out of space, the C<is_eom> member is set to true and
+the method returns false with status C<DEVICE_STATUS_VOLUME_ERROR>.
+
+=head3 write_block
+
+ # (not available from Perl)
+ success = device_write_block(dev, blocksize, buf);
+
+This method writes a single block of data to the volume. It is only available
+from C -- Perl code should not be handling raw data, as it is far too slow.
+Use the transfer architecture (L<Amanda::Xfer>) for that purpose.
+
+The C<blocksize> must be the device's block size, unless
+this is a short write. A short write must be the last block
+of a file. Some devices will zero-pad a short write to a full
+blocksize. This method returns false on error. If the volume is
+out of space, C<is_eom> is set and the method returns false with
+status C<DEVICE_STATUS_VOLUME_ERROR>. Note that not all devices can
+differentiate an EOM condition from other errors; these devices will
+set C<is_eom> whenever the situation is ambiguous.
+
+This function ensures that C<block> is correct on exit. Even in an
+error condition, it does not finish the current file for the caller.
+
+=head3 write_from_fd (DEPRECATED)
+
+ my $qfd = Amanda::Device::queue_fd_t->new(fileno($fh));
+ if (!$dev->write_from_fd($fd)) {
+ print STDERR $qfd->{errmsg}, "\n" if ($qfd->{errmsg});
+ print STDERR $dev->status_or_error(), "\n" if ($dev->status());
+ }
+
+This method reads from the given file descriptor until EOF, writing the data to
+a Device file which should already be started, and not returning until the
+operation is complete. The file is not automatically finished. This method is
+deprecated; the better solution is to use the transfer architecture
+(L<Amanda::Xfer>).
+
+This is a virtual method, but the default implementation in the Device class
+uses C<write_block>, so there is no need for subclasses to override it.
+
+=head3 finish_file
+
+ $success = $dev->finish_file();
+
+Once an entire file has been written, finish_file performs any
+cleanup required on the volume, such as writing filemarks. On exit,
+C<in_file> is false. If the device runs out of space while finishing
+(e.g., the filemark does not fit), then this method returns false
+with status C<DEVICE_STATUS_VOLUME_ERROR> and C<is_eom> is set.
+
+This function should not be used while reading -- instead, just seek
+to the next file.
+
+=head3 seek_file
+
+ $header = $dev->seek_file($fileno);
+
+In C<$ACCESS_READ>, C<seek_file> sets up the device to read from file
+C<$fileno>. This function is not available in C<$ACCESS_WRITE> and
+C<$ACCESS_APPEND>. It returns the header from the requested file on success, or
+undef on error.
+
+If the requested file doesn't exist, as might happen when a volume has had
+files recycled, then C<seek_file> will seek to the next file that does exist. The
+file this function selected is indicated by the C<file> member variable on exit.
+If the requested file number is exactly one more than the last valid file, this
+function returns a C<$F_TAPEEND> header.
+
+As an example, on a volume with only files 1 and 3:
+
+ $dev->seek_file(1) returns header for file 1, $dev->file == 1
+ $dev->seek_file(2) returns header for file 3, $dev->file == 3
+ $dev->seek_file(3) returns header for file 3, $dev->file == 3
+ $dev->seek_file(4) returns a tapend header, $dev->file == 4
+ $dev->seek_file(5) returns NULL/undef
+
+On exit, C<is_eof> is false, C<in_file> is true unless no file was found (tapeend or NULL), C<file> is the discovered file, and C<block> is zero.
+
+=head3 seek_block
+
+ $success = $dev->seek_block($block);
+
+After seeking to a file, the caller can optionally seek to a particular block
+in the file. This function will set C<block> appropriately. Note that it may
+not be possible to detect EOF, so this function may fail to set C<is_eof> even
+though a subsequent C<read_block> will return no data.
+
+=head3 read_block
+
+ # (not available from Perl)
+ bytes_read = device_read_block(dev, buffer, *blocksize);
+
+This method is the complement of C<write_block>, and reads the next block from
+the device, or returns -1 on error. Pass a buffer and its size. If the buffer
+is not big enough, no read is performed, the parameter C<blocksize> is set to
+the required blocksize, and the method returns 0. As a special case, passing a
+C<NULL> buffer and C<*blocksize == 0> is treated as a request for the required block
+size. It is not an error to pass a buffer that is too large (and, in fact, this
+is precisely the effect of setting the C<read_block_size> configuration
+parameter).
+
+On EOF, this method returns -1, but sets C<is_eof> and leaves the device's
+status set to C<$DEVICE_STATUS_SUCCESS>. Some devices may be able to detect EOF
+while reading the last block, and will set C<is_eof> at that time. Others must
+wait for the next read to fail. It is never an error to call C<read_block>
+after an EOF, so there is no need to check C<is_eof> except when C<read_block>
+returns -1.
+
+=head3 read_to_fd (DEPRECATED)
+
+ queue_fd_t *qfd = queue_fd_new(fd, NULL);
+ my $qfd = Amanda::Device::queue_fd_t->new(fileno($fh));
+ if (!$dev->read_to_fd($fd)) {
+ print STDERR $qfd->{errmsg}, "\n" if ($qfd->{errmsg});
+ print STDERR $dev->status_or_error(), "\n" if ($dev->status());
+ }
+
+This method reads the current file from the device and writes to the given file
+descriptor, not returning until the operation is complete. This method is
+deprecated; new uses of devices use the transfer architecture
+(L<Amanda::Xfer>).
+
+This is a virtual method, but the default implementation in the Device class
+uses C<read_block>, so there is no need for subclasses to override it.
+
+=head3 finish
+
+ $success = $dev->finish();
+
+This undoes the effects of start, returning the device to a neutral state
+(C<$ACCESS_NULL>). It will also release any resources acquired by
+C<read_label>, even if C<start> was not called. After C<finish>, it is not an
+error to call C<start> again, even with a different mode.
+
+=head3 recycle_file
+
+ $success = $dev->recycle_file(fileno);
+
+On devices that support it, this removes the indicated file from the volume,
+presumably freeing its space to be used for other files. File numbers of
+existing files will not change, so this operation may leave "holes" in the
+sequence of file numbers. See C<seek_file> to see how this is handled.
+
+This method cannot be called while in a file, nor while in C<$ACCESS_READ>
+mode.
+
+=head3 erase
+
+ $success = $dev->erase(fileno);
+
+On devices that support it, this erases all data from the volume, presumably
+freeing the space. This method must be called before start and after finish --
+that is, while the device is in a neutral state (C<$ACCESS_NULL>). You can
+detect whether or not this operation is supported using the C<full_deletion>
+property.
+
+=head3 eject
+
+ $success = $dev->eject();
+
+On devices that support it, this eject the volume. This method can be called
+before start and after finish.
+
+=head3 directtcp_supported
+
+ $supp = $dev->directtcp_supported();
+
+This method returns TRUE if the DirectTCP-related methods (C<listen>,
+C<accept>, C<write_from_connection>, and C<read_to_connection>) are implemented
+by this device.
+
+=head3 listen
+
+ $addrs = $dev->listen($for_writing);
+
+The C<listen> method starts the device listening for an incoming DirectTCP
+connection. The method returns a set of IP:PORT pairs to which a TCP
+connection can be made. The boolean C<for_writing> is TRUE if
+this connection will be used to write to the device.
+
+This method can be called at any time, but between the time C<listen> is called
+and when C<accept> returns, no other methods of the device should be called.
+
+The return value might look like:
+
+ $addrs = [ [ "127.0.0.1", 9382 ] ]
+
+In C, the memory for these addresses remains the responsibility of the device,
+and will remain unchanged until C<accept> returns.
+
+=head3 accept
+
+ $conn = $dev->accept();
+
+This method accepts a connection to one of the addresses returned by C<listen>,
+returning an established DirectTCPConnection object (see below). It returns
+C<undef> on failure. Note that this method may block indefinitely if no
+connection ever occurs. The C implementation returns an already-referenced
+connection object, so the caller should call C<g_object_unref> when the
+connection is no longer needed.
+
+=head3 use_connection
+
+ my $ok = $dev->use_connection($conn);
+
+Call this method to use a DirectTCPConnection object created with another
+device. The method must be called before the device is started (so
+C<access_mode> is C<$ACCESS_NULL>), as some devices cannot support switching
+connections without rewinding. Any subsequent C<read_from_connection> or
+C<write_to_connection> calls will use this connection.
+
+=head3 write_from_connection
+
+ ($ok, $actual_size) = $dev->write_from_connection($size);
+
+This method reads data from the DirectTCPConnection specified with
+C<use_connection> or returned from C<accept> and writes it to the volume. It
+writes at most C<$size> bytes, and returns the number of bytes written in
+C<$actual_size>. On error, C<$ok> is false.
+
+When an EOF is received over the connection, signalling the end of the data
+stream, then this method returns without error (C<$ok> is true), with
+C<$actual_size> indicating the number of bytes written to the device (which may
+be zero). In this case, the C<is_eof> attribute is true on return.
+
+Similarly, when the device encounters logical EOM in this method, it returns
+the total bytes transferred in C<$actual_size>, with C<$ok> true, and the
+C<is_eom> attribute true. No data is lost. If writes continue until physical
+EOM, data may be lost.
+
+=head3 read_to_connection
+
+ ($ok, $actual_size) = $dev->read_to_connection($size);
+
+This method is similar to C<write_from_connection> but the data flows in the
+opposite direction. It reads at most C<$size> bytes, and returns the total
+number of bytes read in C<$actual_size>.
+
+When the method encounters an EOF, it stops early and returns successfully with
+the number of bytes actually read (which may be zero).
+
+=head3 property_get
+
+Get a property value, where the property is specified by name. See "Properties", above.
+
+=head3 property_set
+
+Set a simple property value. See "Properties", above.
+
+=head3 property_set_ex
+
+Set a property value with surety and source. See "Properties", above.
+
+=head2 CONSTANTS
+
+This module defines a large number of constant scalars. These constants are
+available from the package namespace (e.g., C<$Amanda::Device::ACCESS_WRITE>),
+or imported with the C<:constant> import tag.
+
+=head2 DirectTCPConnection objects
+
+The C<accept> method returns an object to represent the ongoing DirectTCP
+connection. This object is mostly useful as a "token" to be passed to
+C<write_from_connection> and C<read_to_connection>. In particular, a
+connection created by one device can be used with another device; this is how
+DirectTCP dumps are spanned over multiple volumes.
+
+The class does have one critical method, though:
+
+ $conn->close();
+
+This method closes the connection, releasing all resources allocated to it. It
+can be called at any time, whether the remote side has closed the connection
+already or not.