libexplain  1.4.D001
libexplain/iocontrol/hdio_drive_taskfile.c
Go to the documentation of this file.
00001 /*
00002  * libexplain - Explain errno values returned by libc functions
00003  * Copyright (C) 2009-2011, 2013 Peter Miller
00004  *
00005  * This program is free software; you can redistribute it and/or modify it
00006  * under the terms of the GNU Lesser General Public License as published by
00007  * the Free Software Foundation; either version 3 of the License, or (at your
00008  * option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,but WITHOUT
00011  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
00013  * for more details.
00014  *
00015  * You should have received a copy of the GNU Lesser General Public License
00016  * along with this program. If not, see <http://www.gnu.org/licenses/>.
00017  */
00018 
00019 #include <libexplain/ac/sys/ioctl.h>
00020 #include <libexplain/ac/errno.h>
00021 #include <libexplain/ac/linux/hdreg.h>
00022 
00023 #include <libexplain/buffer/dac.h>
00024 #include <libexplain/buffer/einval.h>
00025 #include <libexplain/buffer/efault.h>
00026 #include <libexplain/buffer/ide_task_request_t.h>
00027 #include <libexplain/capability.h>
00028 #include <libexplain/iocontrol/generic.h>
00029 #include <libexplain/iocontrol/hdio_drive_taskfile.h>
00030 #include <libexplain/is_efault.h>
00031 
00032 #ifdef HDIO_DRIVE_TASKFILE
00033 
00034 
00035 static void
00036 print_data(const explain_iocontrol_t *p, explain_string_buffer_t *sb, int
00037     errnum, int fildes, int request, const void *data)
00038 {
00039     (void)p;
00040     (void)errnum;
00041     (void)fildes;
00042     (void)request;
00043     explain_buffer_ide_task_request_t(sb, data);
00044 }
00045 
00046 
00047 static void
00048 print_explanation(const explain_iocontrol_t *p, explain_string_buffer_t *sb, int
00049     errnum, int fildes, int request, const void *data)
00050 {
00051     switch (errnum)
00052     {
00053     case EACCES:
00054         /* you need both CAP_SYS_ADMIN and CAP_SYS_RAWIO */
00055         if (!explain_capability_sys_admin())
00056         {
00057             explain_buffer_dac_sys_admin(sb);
00058             break;
00059         }
00060         if (!explain_capability_sys_rawio())
00061         {
00062             explain_buffer_dac_sys_rawio(sb);
00063             break;
00064         }
00065         goto generic;
00066 
00067     case EINVAL:
00068         {
00069             const ide_task_request_t *req_task = data;
00070             if (req_task->in_size > 65536)
00071             {
00072                 explain_buffer_einval_too_large(sb, "data->in_size");
00073                 explain_string_buffer_printf
00074                 (
00075                     sb,
00076                     " (%lu > %lu)",
00077                     (unsigned long)req_task->in_size,
00078                     65536uL
00079                 );
00080                 break;
00081             }
00082             if (req_task->out_size > 65536)
00083             {
00084                 explain_buffer_einval_too_large(sb, "data->out_size");
00085                 explain_string_buffer_printf
00086                 (
00087                     sb,
00088                     " (%lu > %lu)",
00089                     (unsigned long)req_task->out_size,
00090                     65536uL
00091                 );
00092                 break;
00093             }
00094         }
00095         goto generic;
00096 
00097     case EFAULT:
00098         if (explain_is_efault_pointer(data, sizeof(ide_task_request_t)))
00099         {
00100             explain_buffer_efault(sb, "data");
00101             break;
00102         }
00103         {
00104             const unsigned char *buf = data;
00105             const ide_task_request_t *req_task = data;
00106             if
00107             (
00108                 req_task->out_size
00109             &&
00110                 explain_is_efault_pointer
00111                 (
00112                     buf + sizeof(ide_task_request_t),
00113                     req_task->out_size
00114                 )
00115             )
00116             {
00117                 explain_buffer_efault(sb, "data+outbuf");
00118                 break;
00119             }
00120             if
00121             (
00122                 req_task->in_size
00123             &&
00124                 explain_is_efault_pointer
00125                 (
00126                     buf + sizeof(ide_task_request_t),
00127                     req_task->in_size
00128                 )
00129             )
00130             {
00131                 explain_buffer_efault(sb, "data+inbuf");
00132                 break;
00133             }
00134         }
00135         goto generic;
00136 
00137     case ENOMEM:
00138         goto generic;
00139 
00140     default:
00141         generic:
00142         explain_iocontrol_generic_print_explanation
00143         (
00144             p,
00145             sb,
00146             errnum,
00147             fildes,
00148             request,
00149             data
00150         );
00151         break;
00152     }
00153 }
00154 
00155 
00156 const explain_iocontrol_t explain_iocontrol_hdio_drive_taskfile =
00157 {
00158     "HDIO_DRIVE_TASKFILE", /* name */
00159     HDIO_DRIVE_TASKFILE, /* value */
00160     0, /* disambiguate */
00161     0, /* print_name */
00162     print_data,
00163     print_explanation,
00164     0, /* print_data_returned */
00165     sizeof(ide_task_request_t), /* data_size */
00166     "ide_task_request_t *", /* data_type */
00167     IOCONTROL_FLAG_SIZE_DOES_NOT_AGREE, /* flags */
00168     __FILE__,
00169     __LINE__,
00170 };
00171 
00172 #else /* ndef HDIO_DRIVE_TASKFILE */
00173 
00174 const explain_iocontrol_t explain_iocontrol_hdio_drive_taskfile =
00175 {
00176     0, /* name */
00177     0, /* value */
00178     0, /* disambiguate */
00179     0, /* print_name */
00180     0, /* print_data */
00181     0, /* print_explanation */
00182     0, /* print_data_returned */
00183     0, /* data_size */
00184     0, /* data_type */
00185     0, /* flags */
00186     __FILE__,
00187     __LINE__,
00188 };
00189 
00190 #endif /* HDIO_DRIVE_TASKFILE */
00191 
00192 
00193 /* vim: set ts=8 sw=4 et : */