diff options
Diffstat (limited to 'archive/sg_poll.c')
-rw-r--r-- | archive/sg_poll.c | 351 |
1 files changed, 0 insertions, 351 deletions
diff --git a/archive/sg_poll.c b/archive/sg_poll.c deleted file mode 100644 index e6fb28f8..00000000 --- a/archive/sg_poll.c +++ /dev/null @@ -1,351 +0,0 @@ -#define _GNU_SOURCE - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <signal.h> -#include <string.h> -#include <errno.h> -#include <sys/ioctl.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/poll.h> -#include <sys/ipc.h> -#include <sys/sem.h> -#include "sg_lib.h" -#include "sg_io_linux.h" - -/* Test code for D. Gilbert's extensions to the Linux OS SCSI generic ("sg") - device driver. -* Copyright (C) 1999-2001 D. Gilbert -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2, or (at your option) -* any later version. - - This program tests out asynchronous parts of the 'sg' device driver. - It only uses the SCSI read command on the 'sg' device. - This program performs unbalanced, non-polling "write-write-read" - sequences. Asynchronous notification is turned on and signals are - counted. Due to the imbalance, when the close() is executed there - are several packets still to be read() [some of which may not yet - be awaiting a read()]. This tests how the device driver cleans up - after an unexpected close(). - If the "-deb" flag is given then outputs state to console/log - (for all active sg devices). - - Version 0.76 20010112 -*/ - - -/* -6 byte commands [READ: 0x08, WRITE: 0x0a]: -[cmd ][had|lu][midAdd][lowAdd][count ][flags ] -10 byte commands [EREAD: 0x28, EWRITE: 0x2a, READ_CAPACITY 0x25]: -[cmd ][ |lu][hiAddr][hmAddr][lmAddr][lowAdd][ ][hiCnt ][lowCnt][flags ] -12 byte commands [LREAD: 0xd8, LWRITE: 0xda]: -[cmd ][ |lu][hiAddr][hmAddr][lmAddr][lowAdd][hiCnt ][hmCnt ][lmCnt ][lowCnt] - ... [ ][flags ] -*/ - -#if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED) - /* union semun is defined by including <sys/sem.h> */ -#else - /* according to X/OPEN we have to define it ourselves */ -union semun { - int val; /* value for SETVAL */ - struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */ - unsigned short int *array; /* array for GETALL, SETALL */ - struct seminfo *__buf; /* buffer for IPC_INFO */ -}; -#endif - -#ifdef O_ASYNC -#define MY_ASYNC O_ASYNC -#else -#define MY_ASYNC FASYNC -#endif - - -// #define SG_DEBUG - -#define OFF sizeof(struct sg_header) -// #define NUM_SECTORS 7777 -// #define NUM_SECTORS 577 -// #define NUM_SECTORS 97 -#define NUM_SECTORS 150 -#define BLOCK_SIZE 2048 - -volatile int hand_count = 0; -volatile int signo = 0; -volatile int poll_res = 0; -volatile short revents = 0; -volatile int sg_fd = 0; -int semset_id = 0; - -int do_poll() -{ - struct pollfd a_pollfd = {0, POLLIN | POLLOUT, 0}; - - a_pollfd.fd = sg_fd; - if ((poll_res = poll(&a_pollfd, 1, 0)) < 0) { - perror("poll error"); - return 0; - } - revents = a_pollfd.revents; - return (a_pollfd.revents & POLLIN) ? 1 : 0; -} - -void sg_sa_handler(int sig, siginfo_t *si, void * data) -{ - signo = sig; - if (SIGRTMIN != sig) - fprintf(stderr, "Unexpected signal, signum=%d\n", sig); - if (sg_fd != si->si_fd) - fprintf(stderr, "Unexpected fd, fd=%d\n", si->si_fd); - ++hand_count; - if (do_poll()) { - struct sembuf a_sembuf; - - a_sembuf.sem_num = 0; - a_sembuf.sem_op = 1; - a_sembuf.sem_flg = 0; - if (semop(semset_id, &a_sembuf, 1) < 0) - perror("semop(sh) error"); - } -} - -int main(int argc, char * argv[]) -{ - int flags; - int res; - int k; - unsigned char rdCmdBlk [10] = {0x28, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - unsigned char * rdBuff = malloc(OFF + sizeof(rdCmdBlk) + - (BLOCK_SIZE * NUM_SECTORS)); - unsigned char * rdBuff2 = malloc(OFF + sizeof(rdCmdBlk) + - (BLOCK_SIZE * NUM_SECTORS)); - int rdInLen = OFF + sizeof(rdCmdBlk); - int rdOutLen; - unsigned char * rdCmd = rdBuff + OFF; - unsigned char * rdCmd2 = rdBuff + OFF; - struct sg_header * rsghp = (struct sg_header *)rdBuff; - struct sg_header * rsghp2 = (struct sg_header *)rdBuff2; - int sectorNo = 10000; - int sectorNo2; - int numSectors = NUM_SECTORS; - const int times = 3; - struct sigaction s_action; - union semun a_semun; - struct sembuf a_sembuf; - struct sg_scsi_id sg_id; - char ebuff[256]; - int deb = 0; - char * file_name = 0; - - for (k = 1; k < argc; ++k) { - if (0 == memcmp("-deb", argv[k], 4)) - deb = 10; - else if (*argv[k] != '-') - file_name = argv[k]; - } - if (0 == file_name) { -printf("Usage: 'sg_poll [-deb] <generic_device>' eg: sg_poll /dev/sg0\n"); - return 1; - } - - semset_id = semget(IPC_PRIVATE, 1, IPC_CREAT | 0666); - if (-1 == semset_id) { - perror("semget error"); - return 1; - } - a_semun.val = 0; - res = semctl(semset_id, 0, SETVAL, a_semun); - if (-1 == res) { - perror("semctl(val) error"); - return 1; - } - - - sg_fd = open(file_name, O_RDWR | O_NONBLOCK); - if (sg_fd < 0) { - sprintf(ebuff, "sg_poll: open error on %s", file_name); - perror(ebuff); - return 1; - } - res = ioctl(sg_fd, SG_GET_SCSI_ID, &sg_id); - if (res < 0) { - /* perror("ioctl on generic device, error"); */ - printf("sg_poll: %s not a scsi generic device\n", file_name); - return 1; - } - printf("scsi%d, channel=%d, device=%d, lun=%d, scsi_type=%d\n", - sg_id.host_no, sg_id.channel, sg_id.scsi_id, sg_id.lun, - sg_id.scsi_type); - -#ifdef SG_DEBUG - ioctl(sg_fd, SG_SET_DEBUG, &deb); -#endif - res = ioctl(sg_fd, SG_GET_COMMAND_Q, &k); - if (res < 0) { - perror("SG_GET_COMMAND_Q ioctl error"); - return 1; - } - if (0 == k) { - k = 1; - res = ioctl(sg_fd, SG_SET_COMMAND_Q, &k); - if (res < 0) { - perror("SG_SET_COMMAND_Q ioctl error"); - return 1; - } - } - - s_action.sa_flags = SA_SIGINFO; - s_action.sa_sigaction = sg_sa_handler; - sigemptyset(&s_action.sa_mask); - res = sigaction(SIGRTMIN, &s_action, NULL); - if (res == -1) { - perror("sg_poll: sigaction error"); - return 1; - } - res = fcntl(sg_fd, F_SETOWN, getpid()); - if (res == -1) { - perror("sg_poll: fcntl(setown) error"); - return 1; - } - flags = fcntl(sg_fd, F_GETFL); - res = fcntl(sg_fd, F_SETFL, flags | MY_ASYNC); - if (res == -1) { - perror("sg_poll: fcntl(setfl) error"); - return 1; - } - fcntl(sg_fd, F_SETSIG, SIGRTMIN); - - do_poll(); - printf("pre-loop check, poll_res=%d, revents=%d\n", poll_res, (int)revents); - - - for (k = 0; k < times; ++k, sectorNo += numSectors) { - - rdOutLen = OFF + (BLOCK_SIZE * numSectors); - rsghp->pack_len = 999; /* don't care */ - rsghp->pack_id = k; - rsghp->reply_len = rdOutLen; - rsghp->twelve_byte = 0; - rsghp->result = 0; - memcpy(rdBuff + OFF, rdCmdBlk, sizeof(rdCmdBlk)); - rdCmd[3] = (unsigned char)((sectorNo >> 16) & 0xFF); - rdCmd[4] = (unsigned char)((sectorNo >> 8) & 0xFF); - rdCmd[5] = (unsigned char)(sectorNo & 0xFF); - rdCmd[7] = (unsigned char)((numSectors >> 8) & 0xff); - rdCmd[8] = (unsigned char)(numSectors & 0xff); - - res = write(sg_fd, rdBuff, rdInLen); - if (res < 0) { - perror("sg_poll: write (rd) error"); - return 1; - } - if (res < rdInLen) { - printf("sg_poll: wrote less (rd), ask=%d, got=%d", rdInLen, res); - return 1; - } - - rsghp2->pack_len = 888; /* don't care */ - rsghp2->pack_id = k + 100; - rsghp2->reply_len = rdOutLen; - rsghp2->twelve_byte = 0; - rsghp2->result = 0; - memcpy(rdBuff2 + OFF, rdCmdBlk, sizeof(rdCmdBlk)); - sectorNo2 = sectorNo + 6666; - rdCmd2[3] = (unsigned char)((sectorNo2 >> 16) & 0xFF); - rdCmd2[4] = (unsigned char)((sectorNo2 >> 8) & 0xFF); - rdCmd2[5] = (unsigned char)(sectorNo2 & 0xFF); - rdCmd2[7] = (unsigned char)((numSectors >> 8) & 0xff); - rdCmd2[8] = (unsigned char)(numSectors & 0xff); - -#if 1 - res = write(sg_fd, rdBuff2, rdInLen); - if (res < 0) { - perror("sg_poll: write2 (rd) error"); - return 1; - } - if (res < rdInLen) { - printf("sg_poll: wrote less (rd), ask=%d, got=%d", rdInLen, res); - return 1; - } -#endif - - do_poll(); - printf("pre-write pause, k=%d, " - "hand_count=%d, signo=%d, poll_res=%d, revents=%d\n", - k, hand_count, signo, poll_res, (int)revents); -#ifdef SG_DEBUG - ioctl(sg_fd, SG_SET_DEBUG, &deb); -#endif - system("cat /proc/scsi/sg/debug"); - - a_sembuf.sem_num = 0; - a_sembuf.sem_op = -1; - a_sembuf.sem_flg = 0; - while (semop(semset_id, &a_sembuf, 1) < 0) { - if (EINTR != errno) { - perror("semop(main) error"); - return 0; - } - } - /* pause(); */ - - printf("post-write pause, k=%d, " - "hand_count=%d, signo=%d, poll_res=%d, revents=%d\n", - k, hand_count, signo, poll_res, (int)revents); -#ifdef SG_DEBUG - ioctl(sg_fd, SG_SET_DEBUG, &deb); -#endif - - res = read(sg_fd, rdBuff, rdOutLen); - if (res < 0) { - perror("sg_poll: read (rd) error"); - return 1; - } - if (res < rdOutLen) { - printf("sg_poll: read less (rd), ask=%d, got=%d", rdOutLen, res); - return 1; - } - sg_chk_n_print("after read(rd)", rsghp->target_status, - rsghp->host_status, rsghp->driver_status, - rsghp->sense_buffer, SG_MAX_SENSE, 1); - - } - printf("\treq_len=%d, dma_count=%d\n", rsghp->reply_len, rsghp->pack_len); - -#ifdef SG_DEBUG - ioctl(sg_fd, SG_SET_DEBUG, &deb); -#endif - res = close(sg_fd); - if (res < 0) { - perror("sg_poll: close error"); - return 1; - } - - if (deb > 0) { - sg_fd = open(file_name, O_RDONLY); - if (sg_fd < 0) { - sprintf(ebuff, "sg_poll: open (2) error on %s", file_name); - perror(ebuff); - return 1; - } - res = ioctl(sg_fd, SG_SET_DEBUG, &deb); - if (res < 0) { - perror("ioctl (2) error"); - return 1; - } - res = close(sg_fd); - if (res < 0) { - perror("sg_poll: close (2) error"); - return 1; - } - } - - return 0; -} |