VirtualBox

source: vbox/trunk/src/VBox/Devices/Storage/DrvSCSIHost.cpp@ 28258

Last change on this file since 28258 was 28258, checked in by vboxsync, 15 years ago

PDM critsects for drivers. Fixed critsect cleanup in failure path. Started on new transmit locking scheme (required for intnet buffer serialization).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 17.4 KB
Line 
1/* $Id: DrvSCSIHost.cpp 28258 2010-04-13 14:51:16Z vboxsync $ */
2/** @file
3 * VBox storage drivers: Host SCSI access driver.
4 */
5
6/*
7 * Copyright (C) 2006-2010 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22/*******************************************************************************
23* Header Files *
24*******************************************************************************/
25//#define DEBUG
26#define LOG_GROUP LOG_GROUP_DRV_SCSIHOST
27#include <VBox/pdmdrv.h>
28#include <VBox/pdmifs.h>
29#include <VBox/pdmthread.h>
30#include <VBox/scsi.h>
31#include <iprt/assert.h>
32#include <iprt/file.h>
33#include <iprt/mem.h>
34#include <iprt/req.h>
35#include <iprt/string.h>
36#include <iprt/uuid.h>
37
38#if defined(RT_OS_LINUX)
39# include <limits.h>
40# include <scsi/sg.h>
41# include <sys/ioctl.h>
42#endif
43
44#include "../Builtins.h"
45
46/**
47 * SCSI driver instance data.
48 *
49 * @implements PDMISCSICONNECTOR
50 */
51typedef struct DRVSCSIHOST
52{
53 /** Pointer driver instance. */
54 PPDMDRVINS pDrvIns;
55
56 /** Pointer to the SCSI port interface of the device above. */
57 PPDMISCSIPORT pDevScsiPort;
58 /** The SCSI connector interface . */
59 PDMISCSICONNECTOR ISCSIConnector;
60
61 /** PAth to the device file. */
62 char *pszDevicePath;
63 /** Handle to the device. */
64 RTFILE DeviceFile;
65
66 /** The dedicated I/O thread. */
67 PPDMTHREAD pAsyncIOThread;
68 /** Queue for passing the requests to the thread. */
69 PRTREQQUEUE pQueueRequests;
70} DRVSCSIHOST, *PDRVSCSIHOST;
71
72/** Converts a pointer to DRVSCSIHOST::ISCSIConnecotr to a PDRVSCSIHOST. */
73#define PDMISCSICONNECTOR_2_DRVSCSIHOST(pInterface) ( (PDRVSCSIHOST)((uintptr_t)pInterface - RT_OFFSETOF(DRVSCSIHOST, ISCSIConnector)) )
74
75#ifdef DEBUG
76/**
77 * Dumps a SCSI request structure for debugging purposes.
78 *
79 * @returns nothing.
80 * @param pRequest Pointer to the request to dump.
81 */
82static void drvscsihostDumpScsiRequest(PPDMSCSIREQUEST pRequest)
83{
84 Log(("Dump for pRequest=%#p Command: %s\n", pRequest, SCSICmdText(pRequest->pbCDB[0])));
85 Log(("cbCDB=%u\n", pRequest->cbCDB));
86 for (uint32_t i = 0; i < pRequest->cbCDB; i++)
87 Log(("pbCDB[%u]=%#x\n", i, pRequest->pbCDB[i]));
88 Log(("cbScatterGather=%u\n", pRequest->cbScatterGather));
89 Log(("cScatterGatherEntries=%u\n", pRequest->cScatterGatherEntries));
90 /* Print all scatter gather entries. */
91 for (uint32_t i = 0; i < pRequest->cScatterGatherEntries; i++)
92 {
93 Log(("ScatterGatherEntry[%u].cbSeg=%u\n", i, pRequest->paScatterGatherHead[i].cbSeg));
94 Log(("ScatterGatherEntry[%u].pvSeg=%#p\n", i, pRequest->paScatterGatherHead[i].pvSeg));
95 }
96 Log(("pvUser=%#p\n", pRequest->pvUser));
97}
98#endif
99
100/**
101 * Copy the content of a buffer to a scatter gather list
102 * copying only the amount of data which fits into the
103 * scatter gather list.
104 *
105 * @returns VBox status code.
106 * @param pRequest Pointer to the request which contains the S/G list entries.
107 * @param pvBuf Pointer to the buffer which should be copied.
108 * @param cbBuf Size of the buffer.
109 */
110static int drvscsihostScatterGatherListCopyFromBuffer(PPDMSCSIREQUEST pRequest, void *pvBuf, size_t cbBuf)
111{
112 unsigned cSGEntry = 0;
113 PRTSGSEG pSGEntry = &pRequest->paScatterGatherHead[cSGEntry];
114 uint8_t *pu8Buf = (uint8_t *)pvBuf;
115
116 while (cSGEntry < pRequest->cScatterGatherEntries)
117 {
118 size_t cbToCopy = (cbBuf < pSGEntry->cbSeg) ? cbBuf : pSGEntry->cbSeg;
119
120 memcpy(pSGEntry->pvSeg, pu8Buf, cbToCopy);
121
122 cbBuf -= cbToCopy;
123 /* We finished. */
124 if (!cbBuf)
125 break;
126
127 /* Advance the buffer. */
128 pu8Buf += cbToCopy;
129
130 /* Go to the next entry in the list. */
131 pSGEntry++;
132 cSGEntry++;
133 }
134
135 return VINF_SUCCESS;
136}
137
138/**
139 * Set the sense and advanced sense key in the buffer for error conditions.
140 *
141 * @returns nothing.
142 * @param pRequest Pointer to the request which contains the sense buffer.
143 * @param uSCSISenseKey The sense key to set.
144 * @param uSCSIASC The advanced sense key to set.
145 */
146DECLINLINE(void) drvscsiCmdError(PPDMSCSIREQUEST pRequest, uint8_t uSCSISenseKey, uint8_t uSCSIASC)
147{
148 AssertMsg(pRequest->cbSenseBuffer >= 2, ("Sense buffer is not big enough\n"));
149 AssertMsg(pRequest->pbSenseBuffer, ("Sense buffer pointer is NULL\n"));
150 pRequest->pbSenseBuffer[0] = uSCSISenseKey;
151 pRequest->pbSenseBuffer[1] = uSCSIASC;
152}
153
154/**
155 * Sets the sense key for a status good condition.
156 *
157 * @returns nothing.
158 * @param pRequest Pointer to the request which contains the sense buffer.
159 */
160DECLINLINE(void) drvscsihostCmdOk(PPDMSCSIREQUEST pRequest)
161{
162 AssertMsg(pRequest->cbSenseBuffer >= 2, ("Sense buffer is not big enough\n"));
163 AssertMsg(pRequest->pbSenseBuffer, ("Sense buffer pointer is NULL\n"));
164 pRequest->pbSenseBuffer[0] = SCSI_SENSE_NONE;
165 pRequest->pbSenseBuffer[1] = SCSI_ASC_NONE;
166}
167
168/**
169 * Returns the transfer direction of the given command
170 * in case the device does not provide this info.
171 *
172 * @returns transfer direction of the command.
173 * SCSIHOSTTXDIR_NONE if no data is transfered.
174 * SCSIHOSTTXDIR_FROM_DEVICE if the data is read from the device.
175 * SCSIHOSTTXDIR_TO_DEVICE if the data is written to the device.
176 * @param uCommand The command byte.
177 */
178static unsigned drvscsihostGetTransferDirectionFromCommand(uint8_t uCommand)
179{
180 switch (uCommand)
181 {
182 case SCSI_INQUIRY:
183 case SCSI_REPORT_LUNS:
184 case SCSI_MODE_SENSE_6:
185 case SCSI_READ_TOC_PMA_ATIP:
186 case SCSI_READ_CAPACITY:
187 case SCSI_MODE_SENSE_10:
188 case SCSI_GET_EVENT_STATUS_NOTIFICATION:
189 case SCSI_GET_CONFIGURATION:
190 case SCSI_READ_10:
191 case SCSI_READ_12:
192 case SCSI_READ_BUFFER:
193 case SCSI_READ_BUFFER_CAPACITY:
194 case SCSI_READ_DISC_INFORMATION:
195 case SCSI_READ_DVD_STRUCTURE:
196 case SCSI_READ_FORMAT_CAPACITIES:
197 case SCSI_READ_SUBCHANNEL:
198 case SCSI_READ_TRACK_INFORMATION:
199 case SCSI_READ_CD:
200 case SCSI_READ_CD_MSF:
201 return PDMSCSIREQUESTTXDIR_FROM_DEVICE;
202 case SCSI_TEST_UNIT_READY:
203 case SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL:
204 case SCSI_START_STOP_UNIT:
205 return PDMSCSIREQUESTTXDIR_NONE;
206 case SCSI_WRITE_10:
207 case SCSI_WRITE_12:
208 case SCSI_WRITE_BUFFER:
209 return PDMSCSIREQUESTTXDIR_TO_DEVICE;
210 default:
211 AssertMsgFailed(("Command not known %#x\n", uCommand));
212 }
213
214 /* We should never get here in debug mode. */
215 AssertMsgFailed(("Impossible to get here!!!\n"));
216 return PDMSCSIREQUESTTXDIR_NONE; /* to make compilers happy. */
217}
218
219static int drvscsihostProcessRequestOne(PDRVSCSIHOST pThis, PPDMSCSIREQUEST pRequest)
220{
221 int rc = VINF_SUCCESS;
222 unsigned uTxDir;
223
224 LogFlowFunc(("Entered\n"));
225
226#ifdef DEBUG
227 drvscsihostDumpScsiRequest(pRequest);
228#endif
229
230 /* We implement only one device. */
231 if (pRequest->uLogicalUnit != 0)
232 {
233 switch (pRequest->pbCDB[0])
234 {
235 case SCSI_INQUIRY:
236 {
237 SCSIINQUIRYDATA ScsiInquiryReply;
238
239 memset(&ScsiInquiryReply, 0, sizeof(ScsiInquiryReply));
240
241 ScsiInquiryReply.u5PeripheralDeviceType = SCSI_INQUIRY_DATA_PERIPHERAL_DEVICE_TYPE_UNKNOWN;
242 ScsiInquiryReply.u3PeripheralQualifier = SCSI_INQUIRY_DATA_PERIPHERAL_QUALIFIER_NOT_CONNECTED_NOT_SUPPORTED;
243 drvscsihostScatterGatherListCopyFromBuffer(pRequest, &ScsiInquiryReply, sizeof(SCSIINQUIRYDATA));
244 drvscsihostCmdOk(pRequest);
245 break;
246 }
247 default:
248 AssertMsgFailed(("Command not implemented for attached device\n"));
249 drvscsiCmdError(pRequest, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_NONE);
250 }
251 }
252 else
253 {
254#if defined(RT_OS_LINUX)
255 sg_io_hdr_t ScsiIoReq;
256 sg_iovec_t *paSG = NULL;
257
258 /* Setup SCSI request. */
259 memset(&ScsiIoReq, 0, sizeof(sg_io_hdr_t));
260 ScsiIoReq.interface_id = 'S';
261
262 if (pRequest->uDataDirection == PDMSCSIREQUESTTXDIR_UNKNOWN)
263 uTxDir = drvscsihostGetTransferDirectionFromCommand(pRequest->pbCDB[0]);
264 else
265 uTxDir = pRequest->uDataDirection;
266
267 if (uTxDir == PDMSCSIREQUESTTXDIR_NONE)
268 ScsiIoReq.dxfer_direction = SG_DXFER_NONE;
269 else if (uTxDir == PDMSCSIREQUESTTXDIR_TO_DEVICE)
270 ScsiIoReq.dxfer_direction = SG_DXFER_TO_DEV;
271 else if (uTxDir == PDMSCSIREQUESTTXDIR_FROM_DEVICE)
272 ScsiIoReq.dxfer_direction = SG_DXFER_FROM_DEV;
273 else
274 AssertMsgFailed(("Invalid transfer direction %u\n", uTxDir));
275
276 ScsiIoReq.cmd_len = pRequest->cbCDB;
277 ScsiIoReq.mx_sb_len = pRequest->cbSenseBuffer;
278 ScsiIoReq.dxfer_len = pRequest->cbScatterGather;
279
280 if (pRequest->cScatterGatherEntries > 0)
281 {
282 if (pRequest->cScatterGatherEntries == 1)
283 {
284 ScsiIoReq.iovec_count = 0;
285 ScsiIoReq.dxferp = pRequest->paScatterGatherHead[0].pvSeg;
286 }
287 else
288 {
289 ScsiIoReq.iovec_count = pRequest->cScatterGatherEntries;
290
291 paSG = (sg_iovec_t *)RTMemAllocZ(pRequest->cScatterGatherEntries * sizeof(sg_iovec_t));
292 AssertPtrReturn(paSG, VERR_NO_MEMORY);
293
294 for (unsigned i = 0; i < pRequest->cScatterGatherEntries; i++)
295 {
296 paSG[i].iov_base = pRequest->paScatterGatherHead[i].pvSeg;
297 paSG[i].iov_len = pRequest->paScatterGatherHead[i].cbSeg;
298 }
299 ScsiIoReq.dxferp = paSG;
300 }
301 }
302
303 ScsiIoReq.cmdp = pRequest->pbCDB;
304 ScsiIoReq.sbp = pRequest->pbSenseBuffer;
305 ScsiIoReq.timeout = UINT_MAX;
306 ScsiIoReq.flags |= SG_FLAG_DIRECT_IO;
307
308 /** Issue command. */
309 rc = ioctl(pThis->DeviceFile, SG_IO, &ScsiIoReq);
310 if (rc < 0)
311 {
312 AssertMsgFailed(("Ioctl failed with rc=%d\n", rc));
313 }
314
315 /* Request processed successfully. */
316 Log(("Command successfully processed\n"));
317 if (ScsiIoReq.iovec_count > 0)
318 RTMemFree(paSG);
319#endif
320 }
321 /* Notify device that request finished. */
322 rc = pThis->pDevScsiPort->pfnSCSIRequestCompleted(pThis->pDevScsiPort, pRequest, SCSI_STATUS_OK);
323 AssertMsgRC(rc, ("Notifying device above failed rc=%Rrc\n", rc));
324
325 return rc;
326
327}
328
329/**
330 * Request function to wakeup the thread.
331 *
332 * @returns VWRN_STATE_CHANGED.
333 */
334static int drvscsihostAsyncIOLoopWakeupFunc(void)
335{
336 return VWRN_STATE_CHANGED;
337}
338
339/**
340 * The thread function which processes the requests asynchronously.
341 *
342 * @returns VBox status code.
343 * @param pDrvIns Pointer to the device instance data.
344 * @param pThread Pointer to the thread instance data.
345 */
346static int drvscsihostAsyncIOLoop(PPDMDRVINS pDrvIns, PPDMTHREAD pThread)
347{
348 int rc = VINF_SUCCESS;
349 PDRVSCSIHOST pThis = PDMINS_2_DATA(pDrvIns, PDRVSCSIHOST);
350
351 LogFlowFunc(("Entering async IO loop.\n"));
352
353 if (pThread->enmState == PDMTHREADSTATE_INITIALIZING)
354 return VINF_SUCCESS;
355
356 while (pThread->enmState == PDMTHREADSTATE_RUNNING)
357 {
358 rc = RTReqProcess(pThis->pQueueRequests, RT_INDEFINITE_WAIT);
359 AssertMsg(rc == VWRN_STATE_CHANGED, ("Left RTReqProcess and error code is not VWRN_STATE_CHANGED rc=%Rrc\n", rc));
360 }
361
362 return VINF_SUCCESS;
363}
364
365static int drvscsihostAsyncIOLoopWakeup(PPDMDRVINS pDrvIns, PPDMTHREAD pThread)
366{
367 int rc;
368 PDRVSCSIHOST pThis = PDMINS_2_DATA(pDrvIns, PDRVSCSIHOST);
369 PRTREQ pReq;
370
371 AssertMsgReturn(pThis->pQueueRequests, ("pQueueRequests is NULL\n"), VERR_INVALID_STATE);
372
373 rc = RTReqCall(pThis->pQueueRequests, &pReq, 10000 /* 10 sec. */, (PFNRT)drvscsihostAsyncIOLoopWakeupFunc, 0);
374 AssertMsgRC(rc, ("Inserting request into queue failed rc=%Rrc\n"));
375
376 return rc;
377}
378
379/* -=-=-=-=- ISCSIConnector -=-=-=-=- */
380
381/** @copydoc PDMISCSICONNECTOR::pfnSCSIRequestSend. */
382static DECLCALLBACK(int) drvscsihostRequestSend(PPDMISCSICONNECTOR pInterface, PPDMSCSIREQUEST pSCSIRequest)
383{
384 int rc;
385 PDRVSCSIHOST pThis = PDMISCSICONNECTOR_2_DRVSCSIHOST(pInterface);
386 PRTREQ pReq;
387
388 AssertMsgReturn(pThis->pQueueRequests, ("pQueueRequests is NULL\n"), VERR_INVALID_STATE);
389
390 rc = RTReqCallEx(pThis->pQueueRequests, &pReq, 0, RTREQFLAGS_NO_WAIT, (PFNRT)drvscsihostProcessRequestOne, 2, pThis, pSCSIRequest);
391 AssertMsgReturn(RT_SUCCESS(rc), ("Inserting request into queue failed rc=%Rrc\n", rc), rc);
392
393 return VINF_SUCCESS;
394}
395
396/* -=-=-=-=- PDMIBASE -=-=-=-=- */
397
398/**
399 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
400 */
401static DECLCALLBACK(void *) drvscsihostQueryInterface(PPDMIBASE pInterface, const char *pszIID)
402{
403 PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
404 PDRVSCSIHOST pThis = PDMINS_2_DATA(pDrvIns, PDRVSCSIHOST);
405
406 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
407 PDMIBASE_RETURN_INTERFACE(pszIID, PDMISCSICONNECTOR, &pThis->ISCSIConnector);
408 return NULL;
409}
410
411/* -=-=-=-=- PDMDRVREG -=-=-=-=- */
412
413/**
414 * Destruct a driver instance.
415 *
416 * Most VM resources are freed by the VM. This callback is provided so that any non-VM
417 * resources can be freed correctly.
418 *
419 * @param pDrvIns The driver instance data.
420 */
421static DECLCALLBACK(void) drvscsihostDestruct(PPDMDRVINS pDrvIns)
422{
423 PDRVSCSIHOST pThis = PDMINS_2_DATA(pDrvIns, PDRVSCSIHOST);
424 PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
425
426 if (pThis->DeviceFile != NIL_RTFILE)
427 RTFileClose(pThis->DeviceFile);
428
429 if (pThis->pszDevicePath)
430 MMR3HeapFree(pThis->pszDevicePath);
431
432 if (pThis->pQueueRequests)
433 {
434 int rc = RTReqDestroyQueue(pThis->pQueueRequests);
435 AssertMsgRC(rc, ("Failed to destroy queue rc=%Rrc\n", rc));
436 }
437
438}
439
440/**
441 * Construct a block driver instance.
442 *
443 * @copydoc FNPDMDRVCONSTRUCT
444 */
445static DECLCALLBACK(int) drvscsihostConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
446{
447 PDRVSCSIHOST pThis = PDMINS_2_DATA(pDrvIns, PDRVSCSIHOST);
448 LogFlowFunc(("pDrvIns=%#p pCfg=%#p\n", pDrvIns, pCfg));
449 PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
450
451 /*
452 * Read the configuration.
453 */
454 if (!CFGMR3AreValuesValid(pCfg, "DevicePath\0"))
455 return PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES,
456 N_("Invalid configuration for host scsi access driver"));
457
458 /*
459 * Initialize interfaces.
460 */
461 pDrvIns->IBase.pfnQueryInterface = drvscsihostQueryInterface;
462 pThis->ISCSIConnector.pfnSCSIRequestSend = drvscsihostRequestSend;
463 pThis->pDrvIns = pDrvIns;
464 pThis->DeviceFile = NIL_RTFILE;
465
466 /* Query the SCSI port interface above. */
467 pThis->pDevScsiPort = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMISCSIPORT);
468 AssertMsgReturn(pThis->pDevScsiPort, ("Missing SCSI port interface above\n"), VERR_PDM_MISSING_INTERFACE);
469
470 /* Create request queue. */
471 int rc = RTReqCreateQueue(&pThis->pQueueRequests);
472 AssertMsgReturn(RT_SUCCESS(rc), ("Failed to create request queue rc=%Rrc\n"), rc);
473
474 /* Open the device. */
475 rc = CFGMR3QueryStringAlloc(pCfg, "DevicePath", &pThis->pszDevicePath);
476 if (RT_FAILURE(rc))
477 return PDMDRV_SET_ERROR(pDrvIns, rc,
478 N_("Configuration error: Failed to get the \"DevicePath\" value"));
479
480 rc = RTFileOpen(&pThis->DeviceFile, pThis->pszDevicePath, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
481 if (RT_FAILURE(rc))
482 return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS,
483 N_("DrvSCSIHost#%d: Failed to open device '%s'"), pDrvIns->iInstance, pThis->pszDevicePath);
484
485 /* Create I/O thread. */
486 rc = PDMDrvHlpThreadCreate(pDrvIns, &pThis->pAsyncIOThread, pThis, drvscsihostAsyncIOLoop,
487 drvscsihostAsyncIOLoopWakeup, 0, RTTHREADTYPE_IO, "SCSI async IO");
488 AssertMsgReturn(RT_SUCCESS(rc), ("Failed to create async I/O thread rc=%Rrc\n"), rc);
489
490 return VINF_SUCCESS;
491}
492
493/**
494 * SCSI driver registration record.
495 */
496const PDMDRVREG g_DrvSCSIHost =
497{
498 /* u32Version */
499 PDM_DRVREG_VERSION,
500 /* szName */
501 "SCSIHost",
502 /* szRCMod */
503 "",
504 /* szR0Mod */
505 "",
506 /* pszDescription */
507 "Host SCSI driver.",
508 /* fFlags */
509 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
510 /* fClass. */
511 PDM_DRVREG_CLASS_SCSI,
512 /* cMaxInstances */
513 ~0,
514 /* cbInstance */
515 sizeof(DRVSCSIHOST),
516 /* pfnConstruct */
517 drvscsihostConstruct,
518 /* pfnDestruct */
519 drvscsihostDestruct,
520 /* pfnRelocate */
521 NULL,
522 /* pfnIOCtl */
523 NULL,
524 /* pfnPowerOn */
525 NULL,
526 /* pfnReset */
527 NULL,
528 /* pfnSuspend */
529 NULL,
530 /* pfnResume */
531 NULL,
532 /* pfnAttach */
533 NULL,
534 /* pfnDetach */
535 NULL,
536 /* pfnPowerOff */
537 NULL,
538 /* pfnSoftReset */
539 NULL,
540 /* u32EndVersion */
541 PDM_DRVREG_VERSION
542};
543
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette